x86/fpu/xstate: Cleanup size calculations
The size calculations are partially unreadable gunk. Clean them up. No functional change. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Borislav Petkov <bp@suse.de> Link: https://lkml.kernel.org/r/20211014230739.241223689@linutronix.de
This commit is contained in:
parent
617473acdf
commit
cd9ae76174
@ -527,7 +527,7 @@ static void __init __xstate_dump_leaves(void)
|
|||||||
* that our software representation matches what the CPU
|
* that our software representation matches what the CPU
|
||||||
* tells us about the state's size.
|
* tells us about the state's size.
|
||||||
*/
|
*/
|
||||||
static void __init check_xstate_against_struct(int nr)
|
static bool __init check_xstate_against_struct(int nr)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Ask the CPU for the size of the state.
|
* Ask the CPU for the size of the state.
|
||||||
@ -557,7 +557,9 @@ static void __init check_xstate_against_struct(int nr)
|
|||||||
((nr >= XFEATURE_RSRVD_COMP_11) && (nr <= XFEATURE_LBR))) {
|
((nr >= XFEATURE_RSRVD_COMP_11) && (nr <= XFEATURE_LBR))) {
|
||||||
WARN_ONCE(1, "no structure for xstate: %d\n", nr);
|
WARN_ONCE(1, "no structure for xstate: %d\n", nr);
|
||||||
XSTATE_WARN_ON(1);
|
XSTATE_WARN_ON(1);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -569,38 +571,44 @@ static void __init check_xstate_against_struct(int nr)
|
|||||||
* covered by these checks. Only the size of the buffer for task->fpu
|
* covered by these checks. Only the size of the buffer for task->fpu
|
||||||
* is checked here.
|
* is checked here.
|
||||||
*/
|
*/
|
||||||
static void __init do_extra_xstate_size_checks(void)
|
static bool __init paranoid_xstate_size_valid(unsigned int kernel_size)
|
||||||
{
|
{
|
||||||
int paranoid_xstate_size = FXSAVE_SIZE + XSAVE_HDR_SIZE;
|
bool compacted = cpu_feature_enabled(X86_FEATURE_XSAVES);
|
||||||
|
unsigned int size = FXSAVE_SIZE + XSAVE_HDR_SIZE;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for_each_extended_xfeature(i, xfeatures_mask_all) {
|
for_each_extended_xfeature(i, xfeatures_mask_all) {
|
||||||
check_xstate_against_struct(i);
|
if (!check_xstate_against_struct(i))
|
||||||
|
return false;
|
||||||
/*
|
/*
|
||||||
* Supervisor state components can be managed only by
|
* Supervisor state components can be managed only by
|
||||||
* XSAVES.
|
* XSAVES.
|
||||||
*/
|
*/
|
||||||
if (!cpu_feature_enabled(X86_FEATURE_XSAVES))
|
if (!compacted && xfeature_is_supervisor(i)) {
|
||||||
XSTATE_WARN_ON(xfeature_is_supervisor(i));
|
XSTATE_WARN_ON(1);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Align from the end of the previous feature */
|
/* Align from the end of the previous feature */
|
||||||
if (xfeature_is_aligned(i))
|
if (xfeature_is_aligned(i))
|
||||||
paranoid_xstate_size = ALIGN(paranoid_xstate_size, 64);
|
size = ALIGN(size, 64);
|
||||||
/*
|
/*
|
||||||
* The offset of a given state in the non-compacted
|
* In compacted format the enabled features are packed,
|
||||||
* format is given to us in a CPUID leaf. We check
|
* i.e. disabled features do not occupy space.
|
||||||
* them for being ordered (increasing offsets) in
|
*
|
||||||
* setup_xstate_features(). XSAVES uses compacted format.
|
* In non-compacted format the offsets are fixed and
|
||||||
|
* disabled states still occupy space in the memory buffer.
|
||||||
*/
|
*/
|
||||||
if (!cpu_feature_enabled(X86_FEATURE_XSAVES))
|
if (!compacted)
|
||||||
paranoid_xstate_size = xfeature_uncompacted_offset(i);
|
size = xfeature_uncompacted_offset(i);
|
||||||
/*
|
/*
|
||||||
* The compacted-format offset always depends on where
|
* Add the feature size even for non-compacted format
|
||||||
* the previous state ended.
|
* to make the end result correct
|
||||||
*/
|
*/
|
||||||
paranoid_xstate_size += xfeature_size(i);
|
size += xfeature_size(i);
|
||||||
}
|
}
|
||||||
XSTATE_WARN_ON(paranoid_xstate_size != fpu_kernel_xstate_size);
|
XSTATE_WARN_ON(size != kernel_size);
|
||||||
|
return size == kernel_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -653,7 +661,7 @@ static unsigned int __init get_xsaves_size_no_independent(void)
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int __init get_xsave_size(void)
|
static unsigned int __init get_xsave_size_user(void)
|
||||||
{
|
{
|
||||||
unsigned int eax, ebx, ecx, edx;
|
unsigned int eax, ebx, ecx, edx;
|
||||||
/*
|
/*
|
||||||
@ -684,31 +692,33 @@ static bool __init is_supported_xstate_size(unsigned int test_xstate_size)
|
|||||||
static int __init init_xstate_size(void)
|
static int __init init_xstate_size(void)
|
||||||
{
|
{
|
||||||
/* Recompute the context size for enabled features: */
|
/* Recompute the context size for enabled features: */
|
||||||
unsigned int possible_xstate_size;
|
unsigned int user_size, kernel_size;
|
||||||
unsigned int xsave_size;
|
|
||||||
|
|
||||||
xsave_size = get_xsave_size();
|
/* Uncompacted user space size */
|
||||||
|
user_size = get_xsave_size_user();
|
||||||
|
|
||||||
if (boot_cpu_has(X86_FEATURE_XSAVES))
|
/*
|
||||||
possible_xstate_size = get_xsaves_size_no_independent();
|
* XSAVES kernel size includes supervisor states and
|
||||||
|
* uses compacted format.
|
||||||
|
*
|
||||||
|
* XSAVE does not support supervisor states so
|
||||||
|
* kernel and user size is identical.
|
||||||
|
*/
|
||||||
|
if (cpu_feature_enabled(X86_FEATURE_XSAVES))
|
||||||
|
kernel_size = get_xsaves_size_no_independent();
|
||||||
else
|
else
|
||||||
possible_xstate_size = xsave_size;
|
kernel_size = user_size;
|
||||||
|
|
||||||
/* Ensure we have the space to store all enabled: */
|
/* Ensure we have the space to store all enabled features. */
|
||||||
if (!is_supported_xstate_size(possible_xstate_size))
|
if (!is_supported_xstate_size(kernel_size))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/*
|
if (!paranoid_xstate_size_valid(kernel_size))
|
||||||
* The size is OK, we are definitely going to use xsave,
|
return -EINVAL;
|
||||||
* make it known to the world that we need more space.
|
|
||||||
*/
|
fpu_kernel_xstate_size = kernel_size;
|
||||||
fpu_kernel_xstate_size = possible_xstate_size;
|
fpu_user_xstate_size = user_size;
|
||||||
do_extra_xstate_size_checks();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* User space is always in standard format.
|
|
||||||
*/
|
|
||||||
fpu_user_xstate_size = xsave_size;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user