int val, rc = 0;
do {
+ static const struct feature {
+ const char *name;
+ unsigned int bit;
+ } features[] __initconstrel = INIT_FEATURE_NAMES;
+ const struct feature *lhs, *mid, *rhs;
+ const char *feat;
+
ss = strchr(s, ',');
if ( !ss )
ss = strchr(s, '\0');
- if ( (val = parse_boolean("md-clear", s, ss)) >= 0 )
- {
- if ( !val )
- setup_clear_cpu_cap(X86_FEATURE_MD_CLEAR);
- }
- else if ( (val = parse_boolean("ibpb", s, ss)) >= 0 )
- {
- if ( !val )
- setup_clear_cpu_cap(X86_FEATURE_IBPB);
- }
- else if ( (val = parse_boolean("ibrsb", s, ss)) >= 0 )
- {
- if ( !val )
- setup_clear_cpu_cap(X86_FEATURE_IBRSB);
- }
- else if ( (val = parse_boolean("stibp", s, ss)) >= 0 )
- {
- if ( !val )
- setup_clear_cpu_cap(X86_FEATURE_STIBP);
- }
- else if ( (val = parse_boolean("l1d-flush", s, ss)) >= 0 )
- {
- if ( !val )
- setup_clear_cpu_cap(X86_FEATURE_L1D_FLUSH);
- }
- else if ( (val = parse_boolean("ssbd", s, ss)) >= 0 )
+ /* Skip the 'no-' prefix for name comparisons. */
+ feat = s;
+ if ( strncmp(s, "no-", 3) == 0 )
+ feat += 3;
+
+ /* (Re)initalise lhs and rhs for binary search. */
+ lhs = features;
+ rhs = features + ARRAY_SIZE(features);
+
+ while ( lhs < rhs )
{
- if ( !val )
- setup_clear_cpu_cap(X86_FEATURE_SSBD);
+ int res;
+
+ mid = lhs + (rhs - lhs) / 2;
+ res = cmdline_strcmp(feat, mid->name);
+
+ if ( res < 0 )
+ {
+ rhs = mid;
+ continue;
+ }
+ if ( res > 0 )
+ {
+ lhs = mid + 1;
+ continue;
+ }
+
+ if ( (val = parse_boolean(mid->name, s, ss)) >= 0 )
+ {
+ if ( !val )
+ setup_clear_cpu_cap(mid->bit);
+ mid = NULL;
+ }
+
+ break;
}
- else
+
+ /*
+ * Mid being NULL means that the name and boolean were successfully
+ * identified. Everything else is an error.
+ */
+ if ( mid )
rc = -EINVAL;
s = ss + 1;
if ( res || n == '\0' )
{
/*
- * NUL in 'name' matching a comma, colon or semicolon in 'frag'
- * implies success.
+ * NUL in 'name' matching a comma, colon, semicolon or equals in
+ * 'frag' implies success.
*/
- if ( n == '\0' && (f == ',' || f == ':' || f == ';') )
+ if ( n == '\0' && (f == ',' || f == ':' || f == ';' || f == '=') )
res = 0;
return res;
/**
* Very similar to strcmp(), but will declare a match if the NUL in 'name'
- * lines up with comma, colon or semicolon in 'frag'. Designed for picking
- * exact string matches out of a delimited command line list.
+ * lines up with comma, colon, semicolon or equals in 'frag'. Designed for
+ * picking exact string matches out of a delimited command line list.
*/
int cmdline_strcmp(const char *frag, const char *name);
self.output = open_file_or_fd(output, "w", 2)
# State parsed from input
- self.names = {} # Name => value mapping
+ self.names = {} # Value => Name mapping
+ self.values = {} # Name => Value mapping
self.raw_special = set()
self.raw_pv = set()
self.raw_hvm_shadow = set()
this_name = name
setattr(this, this_name, val)
- # Construct a reverse mapping of value to name
+ # Construct forward and reverse mappings between name and value
state.names[val] = name
+ state.values[name.lower().replace("_", "-")] = val
for a in attr:
state.output.write(
"""}
+#define INIT_FEATURE_NAMES { \\
+""")
+
+ try:
+ _tmp = state.values.iteritems()
+ except AttributeError:
+ _tmp = state.values.items()
+
+ for name, bit in sorted(_tmp):
+ state.output.write(
+ ' { "%s", %sU },\\\n' % (name, bit)
+ )
+
+ state.output.write(
+"""}
+
""")
for idx, text in enumerate(state.bitfields):