Re: [patch V2 45/52] x86/fpu: Dont restore PKRU in fpregs_restore_userspace()

From: Yu, Yu-cheng
Date: Tue Jun 15 2021 - 20:52:35 EST


On 6/14/2021 8:44 AM, Thomas Gleixner wrote:
switch_to(), flush_thread() write the task's PKRU value eagerly so the PKRU
value of current is always valid in the hardware.

That means there is no point in restoring PKRU on exit to user or when
reactivating the task's FPU registers in the signal frame setup path.

This allows to remove all the xstate buffer updates with PKRU values once
the PKRU state is stored in thread struct while a task is scheduled out.

Signed-off-by: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
---
arch/x86/include/asm/fpu/internal.h | 12 +++++++++++-
arch/x86/include/asm/fpu/xstate.h | 19 +++++++++++++++++++
arch/x86/kernel/fpu/core.c | 2 +-
3 files changed, 31 insertions(+), 2 deletions(-)

--- a/arch/x86/include/asm/fpu/internal.h
+++ b/arch/x86/include/asm/fpu/internal.h
@@ -455,7 +455,17 @@ static inline void fpregs_restore_userre
return;
if (!fpregs_state_valid(fpu, cpu)) {
- restore_fpregs_from_fpstate(&fpu->state);
+ /*
+ * This restores _all_ xstate which has not been
+ * established yet.
+ *
+ * If PKRU is enabled, then the PKRU value is already
+ * correct because it was either set in switch_to() or in
+ * flush_thread(). So it is excluded because it might be
+ * not up to date in current->thread.fpu.xsave state.
+ */
+ __restore_fpregs_from_fpstate(&fpu->state,
+ xfeatures_mask_restore_user());

This needs to be xfeatures_mask_restore_user() | xfeatures_mask_supervisor().

fpregs_activate(fpu);
fpu->last_cpu = cpu;
}

[...]