Skip to content

Commit

Permalink
x86/fpu: Rename xfeatures_mask_user() to xfeatures_mask_uabi()
Browse files Browse the repository at this point in the history
Rename it so it's clear that this is about user ABI features which can
differ from the feature set which the kernel saves and restores because the
kernel handles e.g. PKRU differently. But the user ABI (ptrace, signal
frame) expects it to be there.

Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Borislav Petkov <[email protected]>
Reviewed-by: Borislav Petkov <[email protected]>
Link: https://lkml.kernel.org/r/[email protected]
  • Loading branch information
KAGA-KOKO authored and suryasaimadhu committed Jun 23, 2021
1 parent 1d9bffa commit 65e9521
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 17 deletions.
7 changes: 6 additions & 1 deletion arch/x86/include/asm/fpu/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,12 @@ static inline void os_xrstor(struct xregs_state *xstate, u64 mask)
*/
static inline int xsave_to_user_sigframe(struct xregs_state __user *buf)
{
u64 mask = xfeatures_mask_user();
/*
* Include the features which are not xsaved/rstored by the kernel
* internally, e.g. PKRU. That's user space ABI and also required
* to allow the signal handler to modify PKRU.
*/
u64 mask = xfeatures_mask_uabi();
u32 lmask = mask;
u32 hmask = mask >> 32;
int err;
Expand Down
6 changes: 5 additions & 1 deletion arch/x86/include/asm/fpu/xstate.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,11 @@ static inline u64 xfeatures_mask_supervisor(void)
return xfeatures_mask_all & XFEATURE_MASK_SUPERVISOR_SUPPORTED;
}

static inline u64 xfeatures_mask_user(void)
/*
* The xfeatures which are enabled in XCR0 and expected to be in ptrace
* buffers and signal frames.
*/
static inline u64 xfeatures_mask_uabi(void)
{
return xfeatures_mask_all & XFEATURE_MASK_USER_SUPPORTED;
}
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/kernel/fpu/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,7 @@ void fpu__clear_user_states(struct fpu *fpu)
}

/* Reset user states in registers. */
restore_fpregs_from_init_fpstate(xfeatures_mask_user());
restore_fpregs_from_init_fpstate(xfeatures_mask_uabi());

/*
* Now all FPU registers have their desired values. Inform the FPU
Expand Down
10 changes: 5 additions & 5 deletions arch/x86/kernel/fpu/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,14 +257,14 @@ static int copy_user_to_fpregs_zeroing(void __user *buf, u64 xbv, int fx_only)

if (use_xsave()) {
if (fx_only) {
init_bv = xfeatures_mask_user() & ~XFEATURE_MASK_FPSSE;
init_bv = xfeatures_mask_uabi() & ~XFEATURE_MASK_FPSSE;

r = fxrstor_from_user_sigframe(buf);
if (!r)
os_xrstor(&init_fpstate.xsave, init_bv);
return r;
} else {
init_bv = xfeatures_mask_user() & ~xbv;
init_bv = xfeatures_mask_uabi() & ~xbv;

r = xrstor_from_user_sigframe(buf, xbv);
if (!r && unlikely(init_bv))
Expand Down Expand Up @@ -420,7 +420,7 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size)
fpregs_unlock();

if (use_xsave() && !fx_only) {
u64 init_bv = xfeatures_mask_user() & ~user_xfeatures;
u64 init_bv = xfeatures_mask_uabi() & ~user_xfeatures;

ret = copy_sigframe_from_user_to_xstate(&fpu->state.xsave, buf_fx);
if (ret)
Expand Down Expand Up @@ -454,7 +454,7 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size)
if (use_xsave()) {
u64 init_bv;

init_bv = xfeatures_mask_user() & ~XFEATURE_MASK_FPSSE;
init_bv = xfeatures_mask_uabi() & ~XFEATURE_MASK_FPSSE;
os_xrstor(&init_fpstate.xsave, init_bv);
}

Expand Down Expand Up @@ -549,7 +549,7 @@ void fpu__init_prepare_fx_sw_frame(void)

fx_sw_reserved.magic1 = FP_XSTATE_MAGIC1;
fx_sw_reserved.extended_size = size;
fx_sw_reserved.xfeatures = xfeatures_mask_user();
fx_sw_reserved.xfeatures = xfeatures_mask_uabi();
fx_sw_reserved.xstate_size = fpu_user_xstate_size;

if (IS_ENABLED(CONFIG_IA32_EMULATION) ||
Expand Down
18 changes: 9 additions & 9 deletions arch/x86/kernel/fpu/xstate.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ void fpu__init_cpu_xstate(void)
* managed by XSAVE{C, OPT, S} and XRSTOR{S}. Only XSAVE user
* states can be set here.
*/
xsetbv(XCR_XFEATURE_ENABLED_MASK, xfeatures_mask_user());
xsetbv(XCR_XFEATURE_ENABLED_MASK, xfeatures_mask_uabi());

/*
* MSR_IA32_XSS sets supervisor states managed by XSAVES.
Expand Down Expand Up @@ -453,7 +453,7 @@ int xfeature_size(int xfeature_nr)
static int validate_user_xstate_header(const struct xstate_header *hdr)
{
/* No unknown or supervisor features may be set */
if (hdr->xfeatures & ~xfeatures_mask_user())
if (hdr->xfeatures & ~xfeatures_mask_uabi())
return -EINVAL;

/* Userspace must use the uncompacted format */
Expand Down Expand Up @@ -756,7 +756,7 @@ void __init fpu__init_system_xstate(void)
cpuid_count(XSTATE_CPUID, 1, &eax, &ebx, &ecx, &edx);
xfeatures_mask_all |= ecx + ((u64)edx << 32);

if ((xfeatures_mask_user() & XFEATURE_MASK_FPSSE) != XFEATURE_MASK_FPSSE) {
if ((xfeatures_mask_uabi() & XFEATURE_MASK_FPSSE) != XFEATURE_MASK_FPSSE) {
/*
* This indicates that something really unexpected happened
* with the enumeration. Disable XSAVE and try to continue
Expand Down Expand Up @@ -791,7 +791,7 @@ void __init fpu__init_system_xstate(void)
* Update info used for ptrace frames; use standard-format size and no
* supervisor xstates:
*/
update_regset_xstate_info(fpu_user_xstate_size, xfeatures_mask_user());
update_regset_xstate_info(fpu_user_xstate_size, xfeatures_mask_uabi());

fpu__init_prepare_fx_sw_frame();
setup_init_fpu_buf();
Expand Down Expand Up @@ -828,14 +828,14 @@ void fpu__resume_cpu(void)
/*
* Restore XCR0 on xsave capable CPUs:
*/
if (boot_cpu_has(X86_FEATURE_XSAVE))
xsetbv(XCR_XFEATURE_ENABLED_MASK, xfeatures_mask_user());
if (cpu_feature_enabled(X86_FEATURE_XSAVE))
xsetbv(XCR_XFEATURE_ENABLED_MASK, xfeatures_mask_uabi());

/*
* Restore IA32_XSS. The same CPUID bit enumerates support
* of XSAVES and MSR_IA32_XSS.
*/
if (boot_cpu_has(X86_FEATURE_XSAVES)) {
if (cpu_feature_enabled(X86_FEATURE_XSAVES)) {
wrmsrl(MSR_IA32_XSS, xfeatures_mask_supervisor() |
xfeatures_mask_independent());
}
Expand Down Expand Up @@ -993,7 +993,7 @@ void copy_xstate_to_uabi_buf(struct membuf to, struct xregs_state *xsave,
break;

case XSTATE_COPY_XSAVE:
header.xfeatures &= xfeatures_mask_user();
header.xfeatures &= xfeatures_mask_uabi();
break;
}

Expand Down Expand Up @@ -1038,7 +1038,7 @@ void copy_xstate_to_uabi_buf(struct membuf to, struct xregs_state *xsave,
* compacted init_fpstate. The gap tracking will zero this
* later.
*/
if (!(xfeatures_mask_user() & BIT_ULL(i)))
if (!(xfeatures_mask_uabi() & BIT_ULL(i)))
continue;

/*
Expand Down

0 comments on commit 65e9521

Please sign in to comment.