Messages in this thread Patch in this message | | | Date | Fri, 11 Jun 2021 18:15:56 +0200 | From | Thomas Gleixner <> | Subject | [patch 33/41] x86/fpu: Move FXSAVE_LEAK quirk info __copy_kernel_to_fpregs() |
| |
copy_kernel_to_fpregs() restores all xfeatures but it is also the place where the AMD FXSAVE_LEAK bug is handled.
That prevents fpregs_restore_userregs() to limit the restored features, which is required to distangle PKRU and XSTATE handling and also for the upcoming supervisor state management.
Move the FXSAVE_LEAK quirk into __copy_kernel_to_fpregs() and deinline that function which has become rather fat.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- V4: New patch --- arch/x86/include/asm/fpu/internal.h | 25 +------------------------ arch/x86/kernel/fpu/core.c | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 24 deletions(-)
--- a/arch/x86/include/asm/fpu/internal.h +++ b/arch/x86/include/asm/fpu/internal.h @@ -399,33 +399,10 @@ static inline int xrstor_from_kernel_err extern void save_fpregs_to_fpstate(struct fpu *fpu); extern void copy_fpregs_to_fpstate(struct fpu *fpu); -static inline void __restore_fpregs_from_fpstate(union fpregs_state *fpstate, u64 mask) -{ - if (use_xsave()) { - xrstor_from_kernel(&fpstate->xsave, mask); - } else { - if (use_fxsr()) - fxrstor_from_kernel(&fpstate->fxsave); - else - frstor_from_kernel(&fpstate->fsave); - } -} +extern void __restore_fpregs_from_fpstate(union fpregs_state *fpstate, u64 mask); static inline void restore_fpregs_from_fpstate(union fpregs_state *fpstate) { - /* - * AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception is - * pending. Clear the x87 state here by setting it to fixed values. - * "m" is a random variable that should be in L1. - */ - if (unlikely(static_cpu_has_bug(X86_BUG_FXSAVE_LEAK))) { - asm volatile( - "fnclex\n\t" - "emms\n\t" - "fildl %P[addr]" /* set F?P to defined value */ - : : [addr] "m" (fpstate)); - } - __restore_fpregs_from_fpstate(fpstate, -1); } --- a/arch/x86/kernel/fpu/core.c +++ b/arch/x86/kernel/fpu/core.c @@ -145,6 +145,32 @@ void copy_fpregs_to_fpstate(struct fpu * restore_fpregs_from_fpstate(&fpu->state); } +void __restore_fpregs_from_fpstate(union fpregs_state *fpstate, u64 mask) +{ + /* + * AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception is + * pending. Clear the x87 state here by setting it to fixed values. + * "m" is a random variable that should be in L1. + */ + if (unlikely(static_cpu_has_bug(X86_BUG_FXSAVE_LEAK))) { + asm volatile( + "fnclex\n\t" + "emms\n\t" + "fildl %P[addr]" /* set F?P to defined value */ + : : [addr] "m" (fpstate)); + } + + if (use_xsave()) { + xrstor_from_kernel(&fpstate->xsave, mask); + } else { + if (use_fxsr()) + fxrstor_from_kernel(&fpstate->fxsave); + else + frstor_from_kernel(&fpstate->fsave); + } +} +EXPORT_SYMBOL_GPL(__restore_fpregs_from_fpstate); + void kernel_fpu_begin_mask(unsigned int kfpu_mask) { preempt_disable();
| |