From: "Tseng-Hui (Frank) Lin" <thlin@linux.vnet.ibm.com>
To: linuxppc-dev@ozlabs.org
Subject: [PATCH] add icswx support
Date: Fri, 23 Apr 2010 17:04:35 -0500 [thread overview]
Message-ID: <1272060275.6329.13.camel@flin.austin.ibm.com> (raw)
Add Power7 icswx co-processor instruction support.
Signed-off-by: Sonny Rao <sonnyrao@linux.vnet.ibm.com>
Signed-off-by: Tseng-Hui (Frank) Lin <thlin@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/mmu-hash64.h | 3 +
arch/powerpc/include/asm/mmu_context.h | 4 ++
arch/powerpc/include/asm/reg.h | 3 +
arch/powerpc/mm/mmu_context_hash64.c | 79
++++++++++++++++++++++++++++++++
4 files changed, 89 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/include/asm/mmu-hash64.h
b/arch/powerpc/include/asm/mmu-hash64.h
index 2102b21..ba5727d 100644
--- a/arch/powerpc/include/asm/mmu-hash64.h
+++ b/arch/powerpc/include/asm/mmu-hash64.h
@@ -421,6 +421,9 @@ typedef struct {
#ifdef CONFIG_PPC_SUBPAGE_PROT
struct subpage_prot_table spt;
#endif /* CONFIG_PPC_SUBPAGE_PROT */
+ unsigned long acop;
+#define HASH64_MAX_PID (0xFFFF)
+ unsigned int pid;
} mm_context_t;
diff --git a/arch/powerpc/include/asm/mmu_context.h
b/arch/powerpc/include/asm/mmu_context.h
index 26383e0..d6c8841 100644
--- a/arch/powerpc/include/asm/mmu_context.h
+++ b/arch/powerpc/include/asm/mmu_context.h
@@ -78,6 +78,10 @@ static inline void switch_mm(struct mm_struct *prev,
struct mm_struct *next,
#define deactivate_mm(tsk,mm) do { } while (0)
+extern void switch_cop(struct mm_struct *next);
+extern int use_cop(unsigned long acop, struct task_struct *task);
+extern void disuse_cop(unsigned long acop, struct mm_struct *mm);
+
/*
* After we have set current->mm to a new value, this activates
* the context for the new mm so we see the new mappings.
diff --git a/arch/powerpc/include/asm/reg.h
b/arch/powerpc/include/asm/reg.h
index 5572e86..30503f8 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -516,6 +516,9 @@
#define SPRN_SIAR 780
#define SPRN_SDAR 781
+#define SPRN_ACOP 31
+#define SPRN_PID 48
+
#define SPRN_PA6T_MMCR0 795
#define PA6T_MMCR0_EN0 0x0000000000000001UL
#define PA6T_MMCR0_EN1 0x0000000000000002UL
diff --git a/arch/powerpc/mm/mmu_context_hash64.c
b/arch/powerpc/mm/mmu_context_hash64.c
index 2535828..d0a79f6 100644
--- a/arch/powerpc/mm/mmu_context_hash64.c
+++ b/arch/powerpc/mm/mmu_context_hash64.c
@@ -18,6 +18,7 @@
#include <linux/mm.h>
#include <linux/spinlock.h>
#include <linux/idr.h>
+#include <linux/percpu.h>
#include <linux/module.h>
#include <linux/gfp.h>
@@ -25,6 +26,82 @@
static DEFINE_SPINLOCK(mmu_context_lock);
static DEFINE_IDA(mmu_context_ida);
+static DEFINE_IDA(cop_ida);
+
+/* Lazy switch the ACOP register */
+static DEFINE_PER_CPU(unsigned long, acop_reg);
+
+void switch_cop(struct mm_struct *next)
+{
+ mtspr(SPRN_PID, next->context.pid);
+ if (next->context.pid &&
+ __get_cpu_var(acop_reg) != next->context.acop) {
+ mtspr(SPRN_ACOP, next->context.acop);
+ __get_cpu_var(acop_reg) = next->context.acop;
+ }
+}
+
+int use_cop(unsigned long acop, struct task_struct *task)
+{
+ int pid;
+ int err;
+ struct mm_struct *mm = get_task_mm(task);
+
+ if (!mm)
+ return -EINVAL;
+
+ if (!mm->context.pid) {
+ if (!ida_pre_get(&cop_ida, GFP_KERNEL))
+ return -ENOMEM;
+again:
+ spin_lock(&mmu_context_lock);
+ err = ida_get_new_above(&cop_ida, 1, &pid);
+ spin_unlock(&mmu_context_lock);
+
+ if (err == -EAGAIN)
+ goto again;
+ else if (err)
+ return err;
+
+ if (pid > HASH64_MAX_PID) {
+ spin_lock(&mmu_context_lock);
+ ida_remove(&cop_ida, pid);
+ spin_unlock(&mmu_context_lock);
+ return -EBUSY;
+ }
+ mm->context.pid = pid;
+ mtspr(SPRN_PID, mm->context.pid);
+ }
+ mm->context.acop |= acop;
+
+ get_cpu_var(acop_reg) = mm->context.acop;
+ mtspr(SPRN_ACOP, mm->context.acop);
+ put_cpu_var(acop_reg);
+
+ return mm->context.pid;
+}
+EXPORT_SYMBOL(use_cop);
+
+void disuse_cop(unsigned long acop, struct mm_struct *mm)
+{
+ if (WARN_ON(!mm))
+ return;
+
+ mm->context.acop &= ~acop;
+ if (!mm->context.acop) {
+ spin_lock(&mmu_context_lock);
+ ida_remove(&cop_ida, mm->context.pid);
+ spin_unlock(&mmu_context_lock);
+ mm->context.pid = 0;
+ mtspr(SPRN_PID, 0);
+ } else {
+ get_cpu_var(acop_reg) = mm->context.acop;
+ mtspr(SPRN_ACOP, mm->context.acop);
+ put_cpu_var(acop_reg);
+ }
+ mmput(mm);
+}
+EXPORT_SYMBOL(disuse_cop);
/*
* The proto-VSID space has 2^35 - 1 segments available for user
mappings.
@@ -94,6 +171,8 @@ EXPORT_SYMBOL_GPL(__destroy_context);
void destroy_context(struct mm_struct *mm)
{
__destroy_context(mm->context.id);
+ if (mm->context.pid)
+ ida_remove(&cop_ida, mm->context.pid);
subpage_prot_free(mm);
mm->context.id = NO_CONTEXT;
}
next reply other threads:[~2010-04-23 22:04 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-04-23 22:04 Tseng-Hui (Frank) Lin [this message]
2010-04-24 0:55 ` [PATCH] add icswx support Benjamin Herrenschmidt
2010-04-27 21:56 ` Tseng-Hui (Frank) Lin
2010-04-27 22:01 ` Benjamin Herrenschmidt
2010-04-30 13:35 ` Michael Ellerman
2010-04-29 17:11 ` Mike Kravetz
2010-04-29 22:50 ` Benjamin Herrenschmidt
2010-05-03 1:43 ` Olof Johansson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1272060275.6329.13.camel@flin.austin.ibm.com \
--to=thlin@linux.vnet.ibm.com \
--cc=linuxppc-dev@ozlabs.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).