Messages in this thread Patch in this message | | | From | ira.weiny@intel ... | Subject | [PATCH V10 13/44] x86/pkeys: Preserve the PKS MSR on context switch | Date | Tue, 19 Apr 2022 10:06:18 -0700 |
| |
From: Ira Weiny <ira.weiny@intel.com>
The PKS MSR (PKRS) is a per-logical-processor register. Unfortunately, the MSR is not managed by XSAVE. Therefore, software must save/restore the MSR value on context switch.
Allocate space in thread_struct to hold the saved MSR value. Ensure all tasks, including the init_task are properly initialized. Set the CPU PKRS value when a task is scheduled.
Co-developed-by: Fenghua Yu <fenghua.yu@intel.com> Signed-off-by: Fenghua Yu <fenghua.yu@intel.com> Signed-off-by: Ira Weiny <ira.weiny@intel.com>
--- Changes for V9 From Dave Hansen Clarify the commit message s/pks_saved_pkrs/pkrs/ s/pks_write_current/x86_pkrs_load/ Change x86_pkrs_load to take the next thread instead of 'current'
Changes for V8 From Thomas Ensure pkrs_write_current() does not suffer the overhead of preempt disable. Fix setting of initial value Remove flawed and broken create_initial_pkrs_value() in favor of a much simpler and robust macro default Update function names to be consistent.
s/pkrs_write_current/pks_write_current This is a more consistent name s/saved_pkrs/pks_saved_pkrs s/pkrs_init_value/PKS_INIT_VALUE Remove pks_init_task() This function was added mainly to avoid the header file issue. Adding pks-keys.h solved that and saves the complexity.
Changes for V7 Move definitions from asm/processor.h to asm/pks.h s/INIT_PKRS_VALUE/pkrs_init_value Change pks_init_task()/pks_sched_in() to functions s/pks_sched_in/pks_write_current to be used more generically later in the series --- arch/x86/include/asm/pks.h | 2 ++ arch/x86/include/asm/processor.h | 15 ++++++++++++++- arch/x86/kernel/process_64.c | 2 ++ arch/x86/mm/pkeys.c | 9 +++++++++ 4 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/arch/x86/include/asm/pks.h b/arch/x86/include/asm/pks.h index 8180fc59790b..a7bad7301783 100644 --- a/arch/x86/include/asm/pks.h +++ b/arch/x86/include/asm/pks.h @@ -5,10 +5,12 @@ #ifdef CONFIG_ARCH_ENABLE_SUPERVISOR_PKEYS void pks_setup(void); +void x86_pkrs_load(struct thread_struct *thread); #else /* !CONFIG_ARCH_ENABLE_SUPERVISOR_PKEYS */ static inline void pks_setup(void) { } +static inline void x86_pkrs_load(struct thread_struct *thread) { } #endif /* CONFIG_ARCH_ENABLE_SUPERVISOR_PKEYS */ diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 91d0f93a00c7..d52970816594 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -2,6 +2,8 @@ #ifndef _ASM_X86_PROCESSOR_H #define _ASM_X86_PROCESSOR_H +#include <linux/pks-keys.h> + #include <asm/processor-flags.h> /* Forward declaration, a strange C thing */ @@ -529,6 +531,10 @@ struct thread_struct { * PKRU is the hardware itself. */ u32 pkru; +#ifdef CONFIG_ARCH_ENABLE_SUPERVISOR_PKEYS + /* Saved Protection key register for supervisor mappings */ + u32 pkrs; +#endif /* Floating point and extended processor state */ struct fpu fpu; @@ -771,7 +777,14 @@ static inline void spin_lock_prefetch(const void *x) #define KSTK_ESP(task) (task_pt_regs(task)->sp) #else -#define INIT_THREAD { } + +#ifdef CONFIG_ARCH_ENABLE_SUPERVISOR_PKEYS +#define INIT_THREAD { \ + .pkrs = PKS_INIT_VALUE, \ +} +#else +#define INIT_THREAD { } +#endif extern unsigned long KSTK_ESP(struct task_struct *task); diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index e459253649be..5cfa1f8c8465 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -59,6 +59,7 @@ /* Not included via unistd.h */ #include <asm/unistd_32_ia32.h> #endif +#include <asm/pks.h> #include "process.h" @@ -612,6 +613,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) x86_fsgsbase_load(prev, next); x86_pkru_load(prev, next); + x86_pkrs_load(next); /* * Switch the PDA and FPU contexts. diff --git a/arch/x86/mm/pkeys.c b/arch/x86/mm/pkeys.c index 10521f1a292e..39e4c2cbc279 100644 --- a/arch/x86/mm/pkeys.c +++ b/arch/x86/mm/pkeys.c @@ -246,6 +246,15 @@ static inline void pks_write_pkrs(u32 new_pkrs) } } +/* x86_pkrs_load() - Update CPU with the incoming thread pkrs value */ +void x86_pkrs_load(struct thread_struct *thread) +{ + if (!cpu_feature_enabled(X86_FEATURE_PKS)) + return; + + pks_write_pkrs(thread->pkrs); +} + /* * PKS is independent of PKU and either or both may be supported on a CPU. * -- 2.35.1
| |