Merge branch 'x86-fpu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 FPU updates from Ingo Molnar: "Three changes: fix a race that can result in FPU corruption, plus two cleanups" * 'x86-fpu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/fpu: Deactivate FPU state after failure during state load x86/fpu/xstate: Make xfeature_is_supervisor()/xfeature_is_user() return bool x86/fpu/xstate: Fix small issues
This commit is contained in:
Коммит
4d6245ce8c
|
@ -352,6 +352,7 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size)
|
||||||
fpregs_unlock();
|
fpregs_unlock();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
fpregs_deactivate(fpu);
|
||||||
fpregs_unlock();
|
fpregs_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,6 +404,8 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size)
|
||||||
}
|
}
|
||||||
if (!ret)
|
if (!ret)
|
||||||
fpregs_mark_activate();
|
fpregs_mark_activate();
|
||||||
|
else
|
||||||
|
fpregs_deactivate(fpu);
|
||||||
fpregs_unlock();
|
fpregs_unlock();
|
||||||
|
|
||||||
err_out:
|
err_out:
|
||||||
|
|
|
@ -107,23 +107,20 @@ int cpu_has_xfeatures(u64 xfeatures_needed, const char **feature_name)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(cpu_has_xfeatures);
|
EXPORT_SYMBOL_GPL(cpu_has_xfeatures);
|
||||||
|
|
||||||
static int xfeature_is_supervisor(int xfeature_nr)
|
static bool xfeature_is_supervisor(int xfeature_nr)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* We currently do not support supervisor states, but if
|
* Extended State Enumeration Sub-leaves (EAX = 0DH, ECX = n, n > 1)
|
||||||
* we did, we could find out like this.
|
* returns ECX[0] set to (1) for a supervisor state, and cleared (0)
|
||||||
*
|
* for a user state.
|
||||||
* SDM says: If state component 'i' is a user state component,
|
|
||||||
* ECX[0] return 0; if state component i is a supervisor
|
|
||||||
* state component, ECX[0] returns 1.
|
|
||||||
*/
|
*/
|
||||||
u32 eax, ebx, ecx, edx;
|
u32 eax, ebx, ecx, edx;
|
||||||
|
|
||||||
cpuid_count(XSTATE_CPUID, xfeature_nr, &eax, &ebx, &ecx, &edx);
|
cpuid_count(XSTATE_CPUID, xfeature_nr, &eax, &ebx, &ecx, &edx);
|
||||||
return !!(ecx & 1);
|
return ecx & 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int xfeature_is_user(int xfeature_nr)
|
static bool xfeature_is_user(int xfeature_nr)
|
||||||
{
|
{
|
||||||
return !xfeature_is_supervisor(xfeature_nr);
|
return !xfeature_is_supervisor(xfeature_nr);
|
||||||
}
|
}
|
||||||
|
@ -419,7 +416,8 @@ static void __init setup_init_fpu_buf(void)
|
||||||
print_xstate_features();
|
print_xstate_features();
|
||||||
|
|
||||||
if (boot_cpu_has(X86_FEATURE_XSAVES))
|
if (boot_cpu_has(X86_FEATURE_XSAVES))
|
||||||
init_fpstate.xsave.header.xcomp_bv = (u64)1 << 63 | xfeatures_mask;
|
init_fpstate.xsave.header.xcomp_bv = XCOMP_BV_COMPACTED_FORMAT |
|
||||||
|
xfeatures_mask;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Init all the features state with header.xfeatures being 0x0
|
* Init all the features state with header.xfeatures being 0x0
|
||||||
|
|
Загрузка…
Ссылка в новой задаче