Message ID | 20190403164156.19645-20-bigeasy@linutronix.de (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [01/27] x86/fpu: Remove fpu->initialized usage in __fpu__restore_sig() | expand |
On 4/3/19 9:41 AM, Sebastian Andrzej Siewior wrote: > During the context switch the xstate is loaded which also includes the > PKRU value. > If xstate is restored on return to userland it is required that the > PKRU value in xstate is the same as the one in the CPU. All of the protection keys bits in here look ok to me. Thanks for the sustained work to get all those into shape. I know it's a special snowflake. Although I paid much closer attention to the PK bits, feel free to add: Reviewed-by: Dave Hansen <dave.hansen@intel.com> for the series.
On 2019-04-08 11:14:28 [-0700], Dave Hansen wrote: > On 4/3/19 9:41 AM, Sebastian Andrzej Siewior wrote: > > During the context switch the xstate is loaded which also includes the > > PKRU value. > > If xstate is restored on return to userland it is required that the > > PKRU value in xstate is the same as the one in the CPU. > > All of the protection keys bits in here look ok to me. Thanks for the > sustained work to get all those into shape. I know it's a special > snowflake. > Although I paid much closer attention to the PK bits, feel free to add: > > Reviewed-by: Dave Hansen <dave.hansen@intel.com> > > for the series. Thank you. Sebastian
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 1df90feeea5c6..58a3a68e1f114 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -23,6 +23,8 @@ #ifndef __ASSEMBLY__ #include <asm/x86_init.h> +#include <asm/fpu/xstate.h> +#include <asm/fpu/api.h> extern pgd_t early_top_pgt[PTRS_PER_PGD]; int __init __early_make_pgtable(unsigned long address, pmdval_t pmd); @@ -133,8 +135,22 @@ static inline u32 read_pkru(void) static inline void write_pkru(u32 pkru) { - if (boot_cpu_has(X86_FEATURE_OSPKE)) - __write_pkru(pkru); + struct pkru_state *pk; + + if (!boot_cpu_has(X86_FEATURE_OSPKE)) + return; + + pk = get_xsave_addr(¤t->thread.fpu.state.xsave, XFEATURE_PKRU); + /* + * The PKRU value in xstate needs to be in sync with the value that is + * written to the CPU. The FPU restore on return to userland would + * otherwise load the previous value again. + */ + fpregs_lock(); + if (pk) + pk->pkru = pkru; + __write_pkru(pkru); + fpregs_unlock(); } static inline int pte_young(pte_t pte)
During the context switch the xstate is loaded which also includes the PKRU value. If xstate is restored on return to userland it is required that the PKRU value in xstate is the same as the one in the CPU. Save the PKRU in xstate during modification. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- arch/x86/include/asm/pgtable.h | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-)