mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
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:
1 parent
54deff5e13
commit
c4fecc5267
10 files changed
+63
-18
No files matched your search
@@ -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
|
||||
---------------------------
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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(µcode_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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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.
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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,
|
||||
|
||||