A later patch compiles out most of the microcode loading code by removing core.c from the Makefile based on Kconfig. These functions are important to set up the ucode_op to read the microcode revision and report it on every CPU.
Not a functional change. Signed-off-by: Alejandro Vallejo <[email protected]> --- xen/arch/x86/cpu/microcode/Makefile | 1 + xen/arch/x86/cpu/microcode/base.c | 72 ++++++++++++++++++++++++++++ xen/arch/x86/cpu/microcode/core.c | 57 +--------------------- xen/arch/x86/cpu/microcode/private.h | 14 ++++++ 4 files changed, 89 insertions(+), 55 deletions(-) create mode 100644 xen/arch/x86/cpu/microcode/base.c diff --git a/xen/arch/x86/cpu/microcode/Makefile b/xen/arch/x86/cpu/microcode/Makefile index 74289981e3..765195ada3 100644 --- a/xen/arch/x86/cpu/microcode/Makefile +++ b/xen/arch/x86/cpu/microcode/Makefile @@ -1,5 +1,6 @@ obj-$(CONFIG_AMD) += amd.o obj-$(CONFIG_AMD) += amd-base.o +obj-y += base.o obj-y += core.o obj-$(CONFIG_INTEL) += intel.o obj-$(CONFIG_INTEL) += intel-base.o diff --git a/xen/arch/x86/cpu/microcode/base.c b/xen/arch/x86/cpu/microcode/base.c new file mode 100644 index 0000000000..895ee78d2e --- /dev/null +++ b/xen/arch/x86/cpu/microcode/base.c @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#include <xen/alternative-call.h> + +#include <xen/errno.h> +#include <xen/init.h> +#include <xen/lib.h> + +#include <asm/asm_defns.h> +#include <asm/cpufeature.h> +#include <asm/x86-vendors.h> +#include <asm/microcode.h> + +#include "private.h" + +struct microcode_ops __ro_after_init ucode_ops; + +int microcode_update_one(void) +{ + /* + * This path is used for APs and S3 resume. Read the microcode revision + * if possible, even if we can't load microcode. + */ + if ( ucode_ops.collect_cpu_info ) + alternative_vcall(ucode_ops.collect_cpu_info); + + return _microcode_update_one(); +} + +int __init early_microcode_init(struct boot_info *bi) +{ + const struct cpuinfo_x86 *c = &boot_cpu_data; + + switch ( c->vendor ) + { + case X86_VENDOR_AMD: + ucode_probe_amd(&ucode_ops); + break; + + case X86_VENDOR_INTEL: + ucode_probe_intel(&ucode_ops); + break; + } + + if ( !ucode_ops.collect_cpu_info ) + { + printk(XENLOG_INFO "Microcode loading not available\n"); + return -ENODEV; + } + + ucode_ops.collect_cpu_info(); + + printk(XENLOG_INFO "BSP microcode revision: 0x%08x\n", this_cpu(cpu_sig).rev); + + /* + * Some hypervisors deliberately report a microcode revision of -1 to + * mean that they will not accept microcode updates. + * + * It's also possible the hardware might have built-in support to disable + * updates and someone (e.g: a baremetal cloud provider) disabled them. + * + * Take the hint in either case and ignore the microcode interface. + */ + if ( !ucode_ops.apply_microcode || this_cpu(cpu_sig).rev == ~0 ) + { + printk(XENLOG_INFO "Microcode loading disabled due to: %s\n", + ucode_ops.apply_microcode ? "rev = ~0" : "HW toggle"); + ucode_ops.apply_microcode = NULL; + return -ENODEV; + } + + return early_microcode_load(bi); +} diff --git a/xen/arch/x86/cpu/microcode/core.c b/xen/arch/x86/cpu/microcode/core.c index 1d1a5aa4b0..553a0ced15 100644 --- a/xen/arch/x86/cpu/microcode/core.c +++ b/xen/arch/x86/cpu/microcode/core.c @@ -162,8 +162,6 @@ static int __init cf_check parse_ucode(const char *s) } custom_param("ucode", parse_ucode); -static struct microcode_ops __ro_after_init ucode_ops; - static DEFINE_SPINLOCK(microcode_mutex); DEFINE_PER_CPU(struct cpu_signature, cpu_sig); @@ -648,7 +646,7 @@ int ucode_update_hcall(XEN_GUEST_HANDLE(const_void) buf, } /* Load a cached update to current cpu */ -int microcode_update_one(void) +int _microcode_update_one(void) { int rc; @@ -736,13 +734,7 @@ static int __init cf_check microcode_init_cache(void) } presmp_initcall(microcode_init_cache); -/* - * There are several tasks: - * - Locate the ucode blob in the boot modules. - * - Parse and attempt in-place load. - * - Inform microcode_init_cache() of how to find the blob again. - */ -static int __init early_microcode_load(struct boot_info *bi) +int __init early_microcode_load(struct boot_info *bi) { void *data = NULL; size_t size; @@ -873,48 +865,3 @@ static int __init early_microcode_load(struct boot_info *bi) return rc; } - -int __init early_microcode_init(struct boot_info *bi) -{ - const struct cpuinfo_x86 *c = &boot_cpu_data; - - switch ( c->vendor ) - { - case X86_VENDOR_AMD: - ucode_probe_amd(&ucode_ops); - break; - - case X86_VENDOR_INTEL: - ucode_probe_intel(&ucode_ops); - break; - } - - if ( !ucode_ops.collect_cpu_info ) - { - printk(XENLOG_INFO "Microcode loading not available\n"); - return -ENODEV; - } - - ucode_ops.collect_cpu_info(); - - printk(XENLOG_INFO "BSP microcode revision: 0x%08x\n", this_cpu(cpu_sig).rev); - - /* - * Some hypervisors deliberately report a microcode revision of -1 to - * mean that they will not accept microcode updates. - * - * It's also possible the hardware might have built-in support to disable - * updates and someone (e.g: a baremetal cloud provider) disabled them. - * - * Take the hint in either case and ignore the microcode interface. - */ - if ( !ucode_ops.apply_microcode || this_cpu(cpu_sig).rev == ~0 ) - { - printk(XENLOG_INFO "Microcode loading disabled due to: %s\n", - ucode_ops.apply_microcode ? "rev = ~0" : "HW toggle"); - ucode_ops.apply_microcode = NULL; - return -ENODEV; - } - - return early_microcode_load(bi); -} diff --git a/xen/arch/x86/cpu/microcode/private.h b/xen/arch/x86/cpu/microcode/private.h index e6c965dc99..881ea7d8d9 100644 --- a/xen/arch/x86/cpu/microcode/private.h +++ b/xen/arch/x86/cpu/microcode/private.h @@ -5,6 +5,8 @@ #include <asm/microcode.h> +struct boot_info; + /* Opaque. Internals are vendor-specific. */ struct microcode_patch; @@ -68,6 +70,7 @@ struct microcode_ops { }; extern bool opt_digest_check; +extern struct microcode_ops ucode_ops; /* * Microcode loading falls into one of 3 states. @@ -93,4 +96,15 @@ void ucode_probe_intel(struct microcode_ops *ops); static inline void ucode_probe_intel(struct microcode_ops *ops) {} #endif +/* + * There are several tasks: + * - Locate the ucode blob in the boot modules. + * - Parse and attempt in-place load. + * - Inform microcode_init_cache() of how to find the blob again. + */ +int early_microcode_load(struct boot_info *bi); + +/* Attempt performaing a microcode load */ +int _microcode_update_one(void); + #endif /* ASM_X86_MICROCODE_PRIVATE_H */ -- 2.43.0
