Add capability to make the DEXCR act as a per-process SPR.

We do not yet have an interface for changing the values per task. We
also expect the kernel to use a single DEXCR value across all tasks
while in privileged state, so there is no need to synchronize after
changing it (the userspace aspects will synchronize upon returning to
userspace).

Signed-off-by: Benjamin Gray <bg...@linux.ibm.com>
---
 arch/powerpc/include/asm/processor.h     |  1 +
 arch/powerpc/kernel/process.c            | 10 ++++++++++
 arch/powerpc/kernel/ptrace/ptrace-view.c |  7 +------
 3 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/include/asm/processor.h 
b/arch/powerpc/include/asm/processor.h
index b2c51d337e60..882e31296ea6 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -260,6 +260,7 @@ struct thread_struct {
        unsigned long   sier2;
        unsigned long   sier3;
        unsigned long   hashkeyr;
+       unsigned long   dexcr;
 
 #endif
 };
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 9452a54d356c..d482c3fd81d7 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1185,6 +1185,9 @@ static inline void save_sprs(struct thread_struct *t)
 
        if (cpu_has_feature(CPU_FTR_DEXCR_NPHIE))
                t->hashkeyr = mfspr(SPRN_HASHKEYR);
+
+       if (cpu_has_feature(CPU_FTR_ARCH_31))
+               t->dexcr = mfspr(SPRN_DEXCR);
 #endif
 }
 
@@ -1267,6 +1270,10 @@ static inline void restore_sprs(struct thread_struct 
*old_thread,
        if (cpu_has_feature(CPU_FTR_DEXCR_NPHIE) &&
            old_thread->hashkeyr != new_thread->hashkeyr)
                mtspr(SPRN_HASHKEYR, new_thread->hashkeyr);
+
+       if (cpu_has_feature(CPU_FTR_ARCH_31) &&
+           old_thread->dexcr != new_thread->dexcr)
+               mtspr(SPRN_DEXCR, new_thread->dexcr);
 #endif
 
 }
@@ -1878,6 +1885,9 @@ int copy_thread(struct task_struct *p, const struct 
kernel_clone_args *args)
 #ifdef CONFIG_PPC_BOOK3S_64
        if (cpu_has_feature(CPU_FTR_DEXCR_NPHIE))
                p->thread.hashkeyr = current->thread.hashkeyr;
+
+       if (cpu_has_feature(CPU_FTR_ARCH_31))
+               p->thread.dexcr = mfspr(SPRN_DEXCR);
 #endif
        return 0;
 }
diff --git a/arch/powerpc/kernel/ptrace/ptrace-view.c 
b/arch/powerpc/kernel/ptrace/ptrace-view.c
index 584cf5c3df50..c1819e0a6684 100644
--- a/arch/powerpc/kernel/ptrace/ptrace-view.c
+++ b/arch/powerpc/kernel/ptrace/ptrace-view.c
@@ -469,12 +469,7 @@ static int dexcr_get(struct task_struct *target, const 
struct user_regset *regse
        if (!cpu_has_feature(CPU_FTR_ARCH_31))
                return -ENODEV;
 
-       /*
-        * The DEXCR is currently static across all CPUs, so we don't
-        * store the target's value anywhere, but the static value
-        * will also be correct.
-        */
-       membuf_store(&to, (u64)lower_32_bits(DEXCR_INIT));
+       membuf_store(&to, (u64)lower_32_bits(target->thread.dexcr));
 
        /*
         * Technically the HDEXCR is per-cpu, but a hypervisor can't reasonably
-- 
2.44.0

Reply via email to