Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

x86/cpu: Add the 'setcpuid=' boot parameter

In preparation for adding support to inject fake CPU bugs at boot-time,
add a general facility to force enablement of CPU flags.

The flag taints the kernel and the documentation attempts to be clear
that this is highly unsuitable for uses outside of kernel development
and platform experimentation.

The new arg is parsed just like clearcpuid, but instead of leading to
setup_clear_cpu_cap() it leads to setup_force_cpu_cap().

I've tested this by booting a nested QEMU guest on an Intel host, which
with setcpuid=svm will claim that it supports AMD virtualization.

Signed-off-by: Brendan Jackman <jackmanb@google.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Link: https://lore.kernel.org/r/20241220-force-cpu-bug-v2-2-7dc71bce742a@google.com

authored by

Brendan Jackman and committed by
Ingo Molnar
814165e9 f034937f

+26 -9
+26 -9
arch/x86/kernel/cpu/common.c
··· 1479 1479 #endif 1480 1480 } 1481 1481 1482 - static inline void parse_clearcpuid(char *arg) 1482 + static inline void parse_set_clear_cpuid(char *arg, bool set) 1483 1483 { 1484 1484 char *opt; 1485 1485 int taint = 0; 1486 1486 1487 - pr_info("Clearing CPUID bits:"); 1487 + pr_info("%s CPUID bits:", set ? "Force-enabling" : "Clearing"); 1488 1488 1489 1489 while (arg) { 1490 1490 bool found __maybe_unused = false; ··· 1505 1505 else 1506 1506 pr_cont(" " X86_CAP_FMT, x86_cap_flag(bit)); 1507 1507 1508 - setup_clear_cpu_cap(bit); 1508 + if (set) 1509 + setup_force_cpu_cap(bit); 1510 + else 1511 + setup_clear_cpu_cap(bit); 1509 1512 taint++; 1510 1513 } 1511 1514 /* ··· 1526 1523 continue; 1527 1524 1528 1525 pr_cont(" %s", opt); 1529 - setup_clear_cpu_cap(bit); 1526 + if (set) 1527 + setup_force_cpu_cap(bit); 1528 + else 1529 + setup_clear_cpu_cap(bit); 1530 1530 taint++; 1531 1531 found = true; 1532 1532 break; ··· 1585 1579 setup_clear_cpu_cap(X86_FEATURE_FRED); 1586 1580 1587 1581 arglen = cmdline_find_option(boot_command_line, "clearcpuid", arg, sizeof(arg)); 1588 - if (arglen <= 0) 1589 - return; 1590 - parse_clearcpuid(arg); 1582 + if (arglen > 0) 1583 + parse_set_clear_cpuid(arg, false); 1584 + 1585 + arglen = cmdline_find_option(boot_command_line, "setcpuid", arg, sizeof(arg)); 1586 + if (arglen > 0) 1587 + parse_set_clear_cpuid(arg, true); 1591 1588 } 1592 1589 1593 1590 /* ··· 2022 2013 } 2023 2014 2024 2015 /* 2025 - * clearcpuid= was already parsed in cpu_parse_early_param(). This dummy 2026 - * function prevents it from becoming an environment variable for init. 2016 + * clearcpuid= and setcpuid= were already parsed in cpu_parse_early_param(). 2017 + * These dummy functions prevent them from becoming an environment variable for 2018 + * init. 2027 2019 */ 2020 + 2028 2021 static __init int setup_clearcpuid(char *arg) 2029 2022 { 2030 2023 return 1; 2031 2024 } 2032 2025 __setup("clearcpuid=", setup_clearcpuid); 2026 + 2027 + static __init int setup_setcpuid(char *arg) 2028 + { 2029 + return 1; 2030 + } 2031 + __setup("setcpuid=", setup_setcpuid); 2033 2032 2034 2033 DEFINE_PER_CPU_ALIGNED(struct pcpu_hot, pcpu_hot) = { 2035 2034 .current_task = &init_task,