x86/cpuid: Factor common parsing out of parse_xen_cpuid()

dom0-cpuid= is going to want to reuse the common parsing loop, so factor it
out into parse_cpuid().

Irritatingly, despite being static const, the features[] array gets duplicated
each time parse_cpuid() is inlined.  As it is a large (and ever growing with
new CPU features) datastructure, move it to being file scope so all inlines
use the same single object.

No functional change.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
(cherry picked from commit 94c3df9188)
This commit is contained in:
Andrew Cooper committed 2023-08-03 19:13:39 +01:00
1 parent 11dd3480a8
commit 054a7ee1e6
1 file changed
+32 -13
+32 -13
View File
@@ -26,17 +26,26 @@ static const uint32_t __initconst hvm_hap_def_featuremask[] =
INIT_HVM_HAP_DEF_FEATURES;
static const uint32_t deep_features[] = INIT_DEEP_FEATURES;
static int __init parse_xen_cpuid(const char *s)
static const struct feature_name {
const char *name;
unsigned int bit;
} feature_names[] __initconstrel = INIT_FEATURE_NAMES;
/*
* Parse a list of cpuid feature names -> bool, calling the callback for any
* matches found.
*
* always_inline, because this is init code only and we really don't want a
* function pointer call in the middle of the loop.
*/
static int __init always_inline parse_cpuid(
const char *s, void (*callback)(unsigned int feat, bool val))
{
const char *ss;
int val, rc = 0;
do {
static const struct feature {
const char *name;
unsigned int bit;
} features[] __initconstrel = INIT_FEATURE_NAMES;
const struct feature *lhs, *rhs, *mid = NULL /* GCC... */;
const struct feature_name *lhs, *rhs, *mid = NULL /* GCC... */;
const char *feat;
ss = strchr(s, ',');
@@ -49,8 +58,8 @@ static int __init parse_xen_cpuid(const char *s)
feat += 3;
/* (Re)initalise lhs and rhs for binary search. */
lhs = features;
rhs = features + ARRAY_SIZE(features);
lhs = feature_names;
rhs = feature_names + ARRAY_SIZE(feature_names);
while ( lhs < rhs )
{
@@ -72,11 +81,7 @@ static int __init parse_xen_cpuid(const char *s)
if ( (val = parse_boolean(mid->name, s, ss)) >= 0 )
{
if ( !val )
setup_clear_cpu_cap(mid->bit);
else if ( mid->bit == X86_FEATURE_RDRAND &&
(cpuid_ecx(1) & cpufeat_mask(X86_FEATURE_RDRAND)) )
setup_force_cpu_cap(X86_FEATURE_RDRAND);
callback(mid->bit, val);
mid = NULL;
}
@@ -95,6 +100,20 @@ static int __init parse_xen_cpuid(const char *s)
return rc;
}
static void __init _parse_xen_cpuid(unsigned int feat, bool val)
{
if ( !val )
setup_clear_cpu_cap(feat);
else if ( feat == X86_FEATURE_RDRAND &&
(cpuid_ecx(1) & cpufeat_mask(X86_FEATURE_RDRAND)) )
setup_force_cpu_cap(X86_FEATURE_RDRAND);
}
static int __init parse_xen_cpuid(const char *s)
{
return parse_cpuid(s, _parse_xen_cpuid);
}
custom_param("cpuid", parse_xen_cpuid);
#define EMPTY_LEAF ((struct cpuid_leaf){})
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.