x86/ucode: Add Kconfig option to remove microcode loading

Amend docs to reflect ucode= command/stanza depend on MICROCODE_LOADING
being set.

The new MICROCODE_OP() is a conditional setter for the microcode_ops
struct. By using IS_ENABLED() there rather than ifdef we allow DCE to
remove all statics no longer used when microcode loading is disabled
without tagging them with __maybe_unused.

Signed-off-by: Alejandro Vallejo <alejandro.garciavallejo@amd.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
This commit is contained in:
Alejandro Vallejo authored and Andrew Cooper committed 2026-01-21 10:47:46 +00:00
1 parent 54deff5e13
commit c4fecc5267
10 files changed
+63 -18

No files matched your search

+2
View File
@@ -23,6 +23,8 @@ TSX errata which necessitated disabling the feature entirely), or the addition
of brand new features (e.g. the Spectre v2 controls to work around speculative
execution vulnerabilities).
Microcode loading support in Xen is controlled by the
``CONFIG_MICROCODE_LOADING`` Kconfig option.
Boot time microcode loading
---------------------------
+2
View File
@@ -104,6 +104,8 @@ Specifies an XSM module to load.
Specifies a CPU microcode blob to load. (x86 only)
Only available when Xen is compiled with CONFIG_MICROCODE_LOADING enabled.
###`dtb=<filename>`
Specifies a device tree file to load. The platform firmware may provide a
+4 -3
View File
@@ -2751,9 +2751,10 @@ performance.
Applicability: x86
Default: `scan` is selectable via Kconfig, `nmi,digest-check`
Controls for CPU microcode loading. For early loading, this parameter can
specify how and where to find the microcode update blob. For late loading,
this parameter specifies if the update happens within a NMI handler.
Controls for CPU microcode loading, available when `CONFIG_MICROCODE_LOADING`
is enabled. For early loading, this parameter can specify how and where to
find the microcode update blob. For late loading, this parameter specifies if
the update happens within a NMI handler.
'integer' specifies the CPU microcode update blob module index. When positive,
this specifies the n-th module (in the GrUB entry, zero based) to be used
+14
View File
@@ -331,8 +331,22 @@ config REQUIRE_NX
was unavailable. However, if enabled, Xen will no longer boot on
any CPU which is lacking NX support.
config MICROCODE_LOADING
bool "Microcode loading"
default y
help
Microcode updates for CPUs fix errata and provide new functionality for
software to work around bugs, such as the speculative execution
vulnerabilities. It is common for OSes to carry updated microcode as
software tends to get updated more frequently than firmware.
For embedded environments where a full firmware/software stack is being
provided, it might not be necessary for Xen to need to load microcode
itself.
config MICROCODE_SCAN_DEFAULT
bool "Scan for microcode by default"
depends on MICROCODE_LOADING
help
During boot, Xen can scan the multiboot images for a CPIO archive
containing CPU microcode to be loaded, which is Linux's mechanism for
+9 -7
View File
@@ -561,11 +561,11 @@ static const char __initconst amd_cpio_path[] =
"kernel/x86/microcode/AuthenticAMD.bin";
static const struct microcode_ops __initconst_cf_clobber amd_ucode_ops = {
.cpu_request_microcode = cpu_request_microcode,
.collect_cpu_info = collect_cpu_info,
.apply_microcode = apply_microcode,
.compare = amd_compare,
.cpio_path = amd_cpio_path,
.cpu_request_microcode = MICROCODE_OP(cpu_request_microcode),
.apply_microcode = MICROCODE_OP(apply_microcode),
.compare = MICROCODE_OP(amd_compare),
.cpio_path = MICROCODE_OP(amd_cpio_path),
};
void __init ucode_probe_amd(struct microcode_ops *ops)
@@ -574,7 +574,8 @@ void __init ucode_probe_amd(struct microcode_ops *ops)
* The Entrysign vulnerability (SB-7033, CVE-2024-36347) affects Zen1-5
* CPUs. Taint Xen if digest checking is turned off.
*/
if ( boot_cpu_data.family >= 0x17 && boot_cpu_data.family <= 0x1a &&
if ( IS_ENABLED(CONFIG_MICROCODE_LOADING) &&
boot_cpu_data.family >= 0x17 && boot_cpu_data.family <= 0x1a &&
!opt_digest_check )
{
printk(XENLOG_WARNING
@@ -614,8 +615,9 @@ void __init amd_check_entrysign(void)
unsigned int curr_rev;
uint8_t fixed_rev;
if ( boot_cpu_data.vendor != X86_VENDOR_AMD ||
boot_cpu_data.family < 0x17 ||
if ( !IS_ENABLED(CONFIG_MICROCODE_LOADING) ||
boot_cpu_data.vendor != X86_VENDOR_AMD ||
boot_cpu_data.family < 0x17 ||
boot_cpu_data.family > 0x1a )
return;
+12 -3
View File
@@ -58,7 +58,7 @@
*/
#define MICROCODE_UPDATE_TIMEOUT_US 1000000
static bool __initdata ucode_mod_forced;
static bool __initdata __maybe_unused ucode_mod_forced;
static unsigned int nr_cores;
/*
@@ -104,6 +104,7 @@ static int __initdata opt_mod_idx;
static bool __initdata opt_scan = IS_ENABLED(CONFIG_MICROCODE_SCAN_DEFAULT);
bool __ro_after_init opt_digest_check = true;
#ifdef CONFIG_MICROCODE_LOADING
/*
* Used by the EFI path only, when xen.cfg identifies an explicit microcode
* file. Overrides ucode=<int>|scan on the regular command line.
@@ -162,6 +163,7 @@ static int __init cf_check parse_ucode(const char *s)
return rc;
}
custom_param("ucode", parse_ucode);
#endif /* CONFIG_MICROCODE_LOADING */
static struct microcode_ops __ro_after_init ucode_ops;
@@ -469,7 +471,7 @@ struct ucode_buf {
char buffer[];
};
static long cf_check ucode_update_hcall_cont(void *data)
static long cf_check __maybe_unused ucode_update_hcall_cont(void *data)
{
struct microcode_patch *patch = NULL;
int ret, result;
@@ -613,6 +615,7 @@ static long cf_check ucode_update_hcall_cont(void *data)
return ret;
}
#ifdef CONFIG_MICROCODE_LOADING
int ucode_update_hcall(XEN_GUEST_HANDLE(const_void) buf,
unsigned long len, unsigned int flags)
{
@@ -645,6 +648,7 @@ int ucode_update_hcall(XEN_GUEST_HANDLE(const_void) buf,
*/
return continue_hypercall_on_cpu(0, ucode_update_hcall_cont, buffer);
}
#endif /* CONFIG_MICROCODE_LOADING */
/* Load a cached update to current cpu */
int microcode_update_one(void)
@@ -658,7 +662,7 @@ int microcode_update_one(void)
if ( ucode_ops.collect_cpu_info )
alternative_vcall(ucode_ops.collect_cpu_info);
if ( !ucode_ops.apply_microcode )
if ( !IS_ENABLED(CONFIG_MICROCODE_LOADING) || !ucode_ops.apply_microcode )
return -EOPNOTSUPP;
spin_lock(&microcode_mutex);
@@ -678,6 +682,7 @@ int microcode_update_one(void)
*/
static int __initdata early_mod_idx = -1;
#ifdef CONFIG_MICROCODE_LOADING
static int __init cf_check microcode_init_cache(void)
{
struct boot_info *bi = &xen_boot_info;
@@ -734,6 +739,7 @@ static int __init cf_check microcode_init_cache(void)
return rc;
}
presmp_initcall(microcode_init_cache);
#endif /* CONFIG_MICROCODE_LOADING */
/*
* There are several tasks:
@@ -898,6 +904,9 @@ int __init early_microcode_init(struct boot_info *bi)
printk(XENLOG_INFO "BSP microcode revision: 0x%08x\n", this_cpu(cpu_sig).rev);
if ( !IS_ENABLED(CONFIG_MICROCODE_LOADING) )
return -ENODEV;
/*
* Some hypervisors deliberately report a microcode revision of -1 to
* mean that they will not accept microcode updates.
+7 -4
View File
@@ -408,17 +408,20 @@ static const char __initconst intel_cpio_path[] =
"kernel/x86/microcode/GenuineIntel.bin";
static const struct microcode_ops __initconst_cf_clobber intel_ucode_ops = {
.cpu_request_microcode = cpu_request_microcode,
.collect_cpu_info = collect_cpu_info,
.apply_microcode = apply_microcode,
.compare = intel_compare,
.cpio_path = intel_cpio_path,
.cpu_request_microcode = MICROCODE_OP(cpu_request_microcode),
.apply_microcode = MICROCODE_OP(apply_microcode),
.compare = MICROCODE_OP(intel_compare),
.cpio_path = MICROCODE_OP(intel_cpio_path),
};
void __init ucode_probe_intel(struct microcode_ops *ops)
{
*ops = intel_ucode_ops;
if ( !IS_ENABLED(CONFIG_MICROCODE_LOADING) )
return;
if ( !can_load_microcode() )
ops->apply_microcode = NULL;
}
+3
View File
@@ -8,6 +8,9 @@
/* Opaque. Internals are vendor-specific. */
struct microcode_patch;
/* Aids dead-code elimination of the static hooks */
#define MICROCODE_OP(x) (IS_ENABLED(CONFIG_MICROCODE_LOADING) ? (x) : NULL)
struct microcode_ops {
/*
* Parse a microcode container. Format is vendor-specific.
+2 -1
View File
@@ -295,7 +295,8 @@ static void __init efi_arch_cfg_file_late(const EFI_LOADED_IMAGE *image,
{
union string name;
if ( read_section(image, L"ucode", &ucode, NULL) )
if ( !IS_ENABLED(CONFIG_MICROCODE_LOADING) ||
read_section(image, L"ucode", &ucode, NULL) )
return;
name.s = get_value(&cfg, section, "ucode");
+8
View File
@@ -317,6 +317,10 @@ ret_t do_platform_op(
{
XEN_GUEST_HANDLE(const_void) data;
ret = -EOPNOTSUPP;
if ( !IS_ENABLED(CONFIG_MICROCODE_LOADING) )
break;
guest_from_compat_handle(data, op->u.microcode.data);
ret = ucode_update_hcall(data, op->u.microcode.length, 0);
@@ -327,6 +331,10 @@ ret_t do_platform_op(
{
XEN_GUEST_HANDLE(const_void) data;
ret = -EOPNOTSUPP;
if ( !IS_ENABLED(CONFIG_MICROCODE_LOADING) )
break;
guest_from_compat_handle(data, op->u.microcode2.data);
ret = ucode_update_hcall(data, op->u.microcode2.length,
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.