mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
x86/mwait-idle: Add C-states validation
Add validation for C-states specified via the "table=" module parameter. Treat this module parameter as untrusted input and validate it thoroughly. Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com> Link: https://patch.msgid.link/20251216080402.156988-4-dedekind1@gmail.com Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Origin: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git be6a150829b3 Add __init to validate_cmdline_cstate(). Other adjustments to fit our env. Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Roger Pau Monné <roger.pau@citrix.com> Release-Acked-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
This commit is contained in:
1 parent
78c159bdf6
commit
77ce01fb93
1 file changed
+55
@@ -72,6 +72,11 @@ boolean_param("mwait-idle", opt_mwait_idle);
|
||||
|
||||
/* The maximum allowed length for the 'table' module parameter */
|
||||
#define MAX_CMDLINE_TABLE_LEN 256
|
||||
/* Maximum allowed C-state latency */
|
||||
#define MAX_CMDLINE_LATENCY_US (5 * 1000 /* USEC_PER_MSEC */)
|
||||
/* Maximum allowed C-state target residency */
|
||||
#define MAX_CMDLINE_RESIDENCY_US (100 * 1000 /* USEC_PER_MSEC */)
|
||||
|
||||
static char cmdline_table_str[MAX_CMDLINE_TABLE_LEN] __initdata;
|
||||
string_param("mwait-idle.table", cmdline_table_str);
|
||||
|
||||
@@ -1589,6 +1594,41 @@ static char *__init get_cmdline_field(char *args, char **field, char sep)
|
||||
return args + i + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* validate_cmdline_cstate - Validate a C-state from cmdline.
|
||||
* @state: The C-state to validate.
|
||||
* @prev_state: The previous C-state in the table or NULL.
|
||||
*
|
||||
* Return: 0 if the C-state is valid or -EINVAL otherwise.
|
||||
*/
|
||||
static int __init validate_cmdline_cstate(const struct cpuidle_state *state,
|
||||
const struct cpuidle_state *prev_state)
|
||||
{
|
||||
if (state->exit_latency == 0)
|
||||
/* Exit latency 0 can only be used for the POLL state */
|
||||
return -EINVAL;
|
||||
|
||||
if (state->exit_latency > MAX_CMDLINE_LATENCY_US)
|
||||
return -EINVAL;
|
||||
|
||||
if (state->target_residency > MAX_CMDLINE_RESIDENCY_US)
|
||||
return -EINVAL;
|
||||
|
||||
if (state->target_residency < state->exit_latency)
|
||||
return -EINVAL;
|
||||
|
||||
if (!prev_state)
|
||||
return 0;
|
||||
|
||||
if (state->exit_latency <= prev_state->exit_latency)
|
||||
return -EINVAL;
|
||||
|
||||
if (state->target_residency <= prev_state->target_residency)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* cmdline_table_adjust - Adjust the C-states table with data from cmdline.
|
||||
*
|
||||
@@ -1697,6 +1737,21 @@ static void __init cmdline_table_adjust(void)
|
||||
state->name, state->exit_latency, state->target_residency);
|
||||
}
|
||||
|
||||
/* Validate the adjusted C-states */
|
||||
for (i = 0; i < state_count; i++) {
|
||||
const struct cpuidle_state *prev_state;
|
||||
|
||||
state = &cmdline_states[i];
|
||||
prev_state = i ? &cmdline_states[i - 1] : NULL;
|
||||
|
||||
if (validate_cmdline_cstate(state, prev_state)) {
|
||||
printk(XENLOG_ERR PREFIX
|
||||
"C-state '%s' validation failed\n",
|
||||
state->name);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy the adjusted C-states table back */
|
||||
for (i = 0; i < state_count; i++)
|
||||
icpu.state_table[i] = cmdline_states[i];
|
||||
|
||||