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

Yu, Yu-cheng
2021-06-16T00:52:35Z

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@linutronix.de>
> ---
> 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;
> } …