:p
atchew
Login
Hi, The series is mostly a refactor between everything needed to load microcode and the bare minimum to probe the current microcode revision. The Kconfig option keeps the reading of microcode rev data around, as it's very relevant for security and debuggability in order to deduce which erratas apply to the current platform. The idea is to move everything that must still be compiled with !CONFIG_UCODE onto {,amd-,intel-}base.c, then remove everything else conditionally at the Makefile level. Renaming files (e.g: s/base/core/ and s/core/common/) would better reflect post-series reality, but it'd be annoying for later backports in this general area. Cheers, Alejandro Alejandro Vallejo (4): x86: Split out AMD-specific code to be executed without ucode loading x86: Split out Intel-specific code to be executed without ucode loading x86: Split out early_microcode_load() and microcode_load_one() x86: Add Kconfig option to disable microcode loading xen/arch/x86/Kconfig | 12 ++++ xen/arch/x86/cpu/microcode/Makefile | 9 ++- xen/arch/x86/cpu/microcode/amd-base.c | 55 +++++++++++++++++++ xen/arch/x86/cpu/microcode/amd.c | 55 ++----------------- xen/arch/x86/cpu/microcode/amd.h | 15 +++++ xen/arch/x86/cpu/microcode/base.c | 73 +++++++++++++++++++++++++ xen/arch/x86/cpu/microcode/core.c | 58 +------------------- xen/arch/x86/cpu/microcode/intel-base.c | 50 +++++++++++++++++ xen/arch/x86/cpu/microcode/intel.c | 56 +++---------------- xen/arch/x86/cpu/microcode/intel.h | 16 ++++++ xen/arch/x86/cpu/microcode/private.h | 14 +++++ xen/arch/x86/efi/efi-boot.h | 2 +- xen/arch/x86/platform_hypercall.c | 2 + 13 files changed, 259 insertions(+), 158 deletions(-) create mode 100644 xen/arch/x86/cpu/microcode/amd-base.c create mode 100644 xen/arch/x86/cpu/microcode/amd.h create mode 100644 xen/arch/x86/cpu/microcode/base.c create mode 100644 xen/arch/x86/cpu/microcode/intel-base.c create mode 100644 xen/arch/x86/cpu/microcode/intel.h base-commit: e00c1673992e07ed31e9c60fefa8d053491abbe6 -- 2.43.0
Some code must be executed even with microcode loading disabled to find out the current microcode revision. This is important to determine active erratas and such. With the intent of stripping microcode loading via Kconfig, move such essential AMD-specific code to an amd-base.c file. Not a functional change. Signed-off-by: Alejandro Vallejo <alejandro.garciavallejo@amd.com> --- xen/arch/x86/cpu/microcode/Makefile | 1 + xen/arch/x86/cpu/microcode/amd-base.c | 50 ++++++++++++++++++++++++ xen/arch/x86/cpu/microcode/amd.c | 55 +++------------------------ xen/arch/x86/cpu/microcode/amd.h | 15 ++++++++ 4 files changed, 72 insertions(+), 49 deletions(-) create mode 100644 xen/arch/x86/cpu/microcode/amd-base.c create mode 100644 xen/arch/x86/cpu/microcode/amd.h diff --git a/xen/arch/x86/cpu/microcode/Makefile b/xen/arch/x86/cpu/microcode/Makefile index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/x86/cpu/microcode/Makefile +++ b/xen/arch/x86/cpu/microcode/Makefile @@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_AMD) += amd.o +obj-$(CONFIG_AMD) += amd-base.o obj-y += core.o obj-$(CONFIG_INTEL) += intel.o diff --git a/xen/arch/x86/cpu/microcode/amd-base.c b/xen/arch/x86/cpu/microcode/amd-base.c new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/xen/arch/x86/cpu/microcode/amd-base.c @@ -XXX,XX +XXX,XX @@ +#include <xen/init.h> + +#include <asm/msr.h> +#include <asm/processor.h> +#include <asm/x86-vendors.h> + +#include "amd.h" + +#define pr_debug(x...) ((void)0) + +static void cf_check collect_cpu_info(void) +{ + struct cpu_signature *csig = &this_cpu(cpu_sig); + + memset(csig, 0, sizeof(*csig)); + + csig->sig = cpuid_eax(1); + rdmsrl(MSR_AMD_PATCHLEVEL, csig->rev); + + pr_debug("microcode: CPU%d collect_cpu_info: patch_id=%#x\n", + smp_processor_id(), csig->rev); +} + +static const struct microcode_ops __initconst_cf_clobber amd_ucode_ops = { + .cpu_request_microcode = amd_cpu_request_microcode, + .collect_cpu_info = collect_cpu_info, + .apply_microcode = amd_apply_microcode, + .compare = amd_compare, + .cpio_path = amd_cpio_path, +}; + +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 && + !opt_digest_check ) + { + printk(XENLOG_WARNING + "Microcode patch additional digest checks disabled\n"); + add_taint(TAINT_CPU_OUT_OF_SPEC); + } + + if ( boot_cpu_data.family < 0x10 ) + return; + + *ops = amd_ucode_ops; +} diff --git a/xen/arch/x86/cpu/microcode/amd.c b/xen/arch/x86/cpu/microcode/amd.c index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/x86/cpu/microcode/amd.c +++ b/xen/arch/x86/cpu/microcode/amd.c @@ -XXX,XX +XXX,XX @@ #include <asm/msr.h> -#include "private.h" - -#define pr_debug(x...) ((void)0) +#include "amd.h" struct equiv_cpu_entry { uint32_t installed_cpu; @@ -XXX,XX +XXX,XX @@ static bool check_digest(const struct container_microcode *mc) return true; } -static void cf_check collect_cpu_info(void) -{ - struct cpu_signature *csig = &this_cpu(cpu_sig); - - memset(csig, 0, sizeof(*csig)); - - csig->sig = cpuid_eax(1); - rdmsrl(MSR_AMD_PATCHLEVEL, csig->rev); - - pr_debug("microcode: CPU%d collect_cpu_info: patch_id=%#x\n", - smp_processor_id(), csig->rev); -} - static bool verify_patch_size(uint32_t patch_size) { uint32_t max_size; @@ -XXX,XX +XXX,XX @@ static bool microcode_fits_cpu(const struct microcode_patch *patch) return equiv.id == patch->processor_rev_id; } -static int cf_check amd_compare( +int cf_check amd_compare( const struct microcode_patch *old, const struct microcode_patch *new) { /* Both patches to compare are supposed to be applicable to local CPU. */ @@ -XXX,XX +XXX,XX @@ static bool check_min_rev(const struct microcode_patch *patch) return this_cpu(cpu_sig).rev >= patch->min_rev; } -static int cf_check apply_microcode(const struct microcode_patch *patch, - unsigned int flags) +int cf_check amd_apply_microcode(const struct microcode_patch *patch, + unsigned int flags) { int hw_err, result; unsigned int cpu = smp_processor_id(); @@ -XXX,XX +XXX,XX @@ static int scan_equiv_cpu_table(const struct container_equiv_table *et) return -ESRCH; } -static struct microcode_patch *cf_check cpu_request_microcode( +struct microcode_patch *cf_check amd_cpu_request_microcode( const void *buf, size_t size, bool make_copy) { const struct microcode_patch *saved = NULL; @@ -XXX,XX +XXX,XX @@ static struct microcode_patch *cf_check cpu_request_microcode( return patch; } -static const char __initconst amd_cpio_path[] = +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, -}; - -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 && - !opt_digest_check ) - { - printk(XENLOG_WARNING - "Microcode patch additional digest checks disabled\n"); - add_taint(TAINT_CPU_OUT_OF_SPEC); - } - - if ( boot_cpu_data.family < 0x10 ) - return; - - *ops = amd_ucode_ops; -} - #if 0 /* Manual CONFIG_SELF_TESTS */ static void __init __constructor test_digests_sorted(void) { diff --git a/xen/arch/x86/cpu/microcode/amd.h b/xen/arch/x86/cpu/microcode/amd.h new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/xen/arch/x86/cpu/microcode/amd.h @@ -XXX,XX +XXX,XX @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef ASM_X86_MICROCODE_AMD_H +#define ASM_X86_MICROCODE_AMD_H + +#include "private.h" + +int cf_check amd_compare(const struct microcode_patch *old, + const struct microcode_patch *new); +int cf_check amd_apply_microcode(const struct microcode_patch *patch, + unsigned int flags); +struct microcode_patch *cf_check amd_cpu_request_microcode( + const void *buf, size_t size, bool make_copy); +extern const char amd_cpio_path[]; + +#endif /* ASM_X86_MICROCODE_AMD_H */ -- 2.43.0
Some code must be executed even with microcode loading disabled to find out the current microcode revision. This is important to determine active erratas and such. With the intent of stripping microcode loading via Kconfig, move such essential Intel-specific code to an intel-base.c file. Not a functional change. Signed-off-by: Alejandro Vallejo <alejandro.garciavallejo@amd.com> --- xen/arch/x86/cpu/microcode/Makefile | 1 + xen/arch/x86/cpu/microcode/intel-base.c | 48 +++++++++++++++++++++ xen/arch/x86/cpu/microcode/intel.c | 56 ++++--------------------- xen/arch/x86/cpu/microcode/intel.h | 16 +++++++ 4 files changed, 72 insertions(+), 49 deletions(-) create mode 100644 xen/arch/x86/cpu/microcode/intel-base.c create mode 100644 xen/arch/x86/cpu/microcode/intel.h diff --git a/xen/arch/x86/cpu/microcode/Makefile b/xen/arch/x86/cpu/microcode/Makefile index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/x86/cpu/microcode/Makefile +++ b/xen/arch/x86/cpu/microcode/Makefile @@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_AMD) += amd.o obj-$(CONFIG_AMD) += amd-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/intel-base.c b/xen/arch/x86/cpu/microcode/intel-base.c new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/xen/arch/x86/cpu/microcode/intel-base.c @@ -XXX,XX +XXX,XX @@ +#include <xen/init.h> + +#include <asm/msr.h> +#include <asm/processor.h> + +#include "intel.h" + +#define pr_debug(x...) ((void)0) + +static void cf_check collect_cpu_info(void) +{ + struct cpu_signature *csig = &this_cpu(cpu_sig); + uint64_t msr_content; + + memset(csig, 0, sizeof(*csig)); + + rdmsrl(MSR_IA32_PLATFORM_ID, msr_content); + csig->pf = 1 << ((msr_content >> 50) & 7); + + /* + * Obtaining the microcode version involves writing 0 to the "read only" + * UCODE_REV MSR, executing any CPUID instruction, after which a nonzero + * revision should appear. + */ + wrmsrl(MSR_IA32_UCODE_REV, 0); + csig->sig = cpuid_eax(1); + rdmsrl(MSR_IA32_UCODE_REV, msr_content); + csig->rev = msr_content >> 32; + + pr_debug("microcode: collect_cpu_info : sig=%#x, pf=%#x, rev=%#x\n", + csig->sig, csig->pf, csig->rev); +} + +static const struct microcode_ops __initconst_cf_clobber intel_ucode_ops = { + .cpu_request_microcode = intel_cpu_request_microcode, + .apply_microcode = intel_apply_microcode, + .collect_cpu_info = collect_cpu_info, + .compare = intel_compare, + .cpio_path = intel_cpio_path, +}; + +void __init ucode_probe_intel(struct microcode_ops *ops) +{ + *ops = intel_ucode_ops; + + if ( !intel_can_load_microcode() ) + ops->apply_microcode = NULL; +} diff --git a/xen/arch/x86/cpu/microcode/intel.c b/xen/arch/x86/cpu/microcode/intel.c index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/x86/cpu/microcode/intel.c +++ b/xen/arch/x86/cpu/microcode/intel.c @@ -XXX,XX +XXX,XX @@ #include <asm/processor.h> #include <asm/system.h> -#include "private.h" - -#define pr_debug(x...) ((void)0) +#include "intel.h" struct microcode_patch { uint32_t hdrver; @@ -XXX,XX +XXX,XX @@ static bool signature_matches(const struct cpu_signature *cpu_sig, return cpu_sig->pf & ucode_pf; } -static void cf_check collect_cpu_info(void) -{ - struct cpu_signature *csig = &this_cpu(cpu_sig); - uint64_t msr_content; - - memset(csig, 0, sizeof(*csig)); - - rdmsrl(MSR_IA32_PLATFORM_ID, msr_content); - csig->pf = 1 << ((msr_content >> 50) & 7); - - /* - * Obtaining the microcode version involves writing 0 to the "read only" - * UCODE_REV MSR, executing any CPUID instruction, after which a nonzero - * revision should appear. - */ - wrmsrl(MSR_IA32_UCODE_REV, 0); - csig->sig = cpuid_eax(1); - rdmsrl(MSR_IA32_UCODE_REV, msr_content); - csig->rev = msr_content >> 32; - - pr_debug("microcode: collect_cpu_info : sig=%#x, pf=%#x, rev=%#x\n", - csig->sig, csig->pf, csig->rev); -} - /* * Sanity check a blob which is expected to be a microcode patch. The 48 byte * header is of a known format, and together with totalsize are within the @@ -XXX,XX +XXX,XX @@ static bool microcode_fits_cpu(const struct microcode_patch *mc) return false; } -static int cf_check intel_compare( +int cf_check intel_compare( const struct microcode_patch *old, const struct microcode_patch *new) { /* @@ -XXX,XX +XXX,XX @@ static int cf_check intel_compare( return compare_revisions(old->rev, new->rev); } -static int cf_check apply_microcode(const struct microcode_patch *patch, - unsigned int flags) +int cf_check intel_apply_microcode(const struct microcode_patch *patch, + unsigned int flags) { uint64_t msr_content; unsigned int cpu = smp_processor_id(); @@ -XXX,XX +XXX,XX @@ static int cf_check apply_microcode(const struct microcode_patch *patch, return 0; } -static struct microcode_patch *cf_check cpu_request_microcode( +struct microcode_patch *cf_check intel_cpu_request_microcode( const void *buf, size_t size, bool make_copy) { int error = 0; @@ -XXX,XX +XXX,XX @@ static struct microcode_patch *cf_check cpu_request_microcode( return patch; } -static bool __init can_load_microcode(void) +bool __init intel_can_load_microcode(void) { uint64_t mcu_ctrl; @@ -XXX,XX +XXX,XX @@ static bool __init can_load_microcode(void) return !(mcu_ctrl & MCU_CONTROL_DIS_MCU_LOAD); } -static const char __initconst intel_cpio_path[] = +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, -}; - -void __init ucode_probe_intel(struct microcode_ops *ops) -{ - *ops = intel_ucode_ops; - - if ( !can_load_microcode() ) - ops->apply_microcode = NULL; -} diff --git a/xen/arch/x86/cpu/microcode/intel.h b/xen/arch/x86/cpu/microcode/intel.h new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/xen/arch/x86/cpu/microcode/intel.h @@ -XXX,XX +XXX,XX @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef ASM_X86_MICROCODE_INTEL_H +#define ASM_X86_MICROCODE_INTEL_H + +#include "private.h" + +bool intel_can_load_microcode(void); +int cf_check intel_compare(const struct microcode_patch *old, + const struct microcode_patch *new); +int cf_check intel_apply_microcode(const struct microcode_patch *patch, + unsigned int flags); +struct microcode_patch *cf_check intel_cpu_request_microcode( + const void *buf, size_t size, bool make_copy); +extern const char intel_cpio_path[]; + +#endif /* ASM_X86_MICROCODE_INTEL_H */ -- 2.43.0
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 <alejandro.garciavallejo@amd.com> --- 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 XXXXXXX..XXXXXXX 100644 --- a/xen/arch/x86/cpu/microcode/Makefile +++ b/xen/arch/x86/cpu/microcode/Makefile @@ -XXX,XX +XXX,XX @@ 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 XXXXXXX..XXXXXXX --- /dev/null +++ b/xen/arch/x86/cpu/microcode/base.c @@ -XXX,XX +XXX,XX @@ +/* 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 XXXXXXX..XXXXXXX 100644 --- a/xen/arch/x86/cpu/microcode/core.c +++ b/xen/arch/x86/cpu/microcode/core.c @@ -XXX,XX +XXX,XX @@ 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); @@ -XXX,XX +XXX,XX @@ 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; @@ -XXX,XX +XXX,XX @@ 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; @@ -XXX,XX +XXX,XX @@ 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 XXXXXXX..XXXXXXX 100644 --- a/xen/arch/x86/cpu/microcode/private.h +++ b/xen/arch/x86/cpu/microcode/private.h @@ -XXX,XX +XXX,XX @@ #include <asm/microcode.h> +struct boot_info; + /* Opaque. Internals are vendor-specific. */ struct microcode_patch; @@ -XXX,XX +XXX,XX @@ struct microcode_ops { }; extern bool opt_digest_check; +extern struct microcode_ops ucode_ops; /* * Microcode loading falls into one of 3 states. @@ -XXX,XX +XXX,XX @@ 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
Keeps around the microcode revision reading logic, as that's security sensitive to detect out-of-date patforms and report them. Move cpu_sig to base.c, because that's externally visible symbol outside the microcode subsystem and we need it always accesible. Signed-off-by: Alejandro Vallejo <alejandro.garciavallejo@amd.com> --- xen/arch/x86/Kconfig | 12 ++++++++++++ xen/arch/x86/cpu/microcode/Makefile | 6 +++--- xen/arch/x86/cpu/microcode/amd-base.c | 9 +++++++-- xen/arch/x86/cpu/microcode/base.c | 21 +++++++++++---------- xen/arch/x86/cpu/microcode/core.c | 1 - xen/arch/x86/cpu/microcode/intel-base.c | 6 ++++-- xen/arch/x86/efi/efi-boot.h | 2 +- xen/arch/x86/platform_hypercall.c | 2 ++ 8 files changed, 40 insertions(+), 19 deletions(-) diff --git a/xen/arch/x86/Kconfig b/xen/arch/x86/Kconfig index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/x86/Kconfig +++ b/xen/arch/x86/Kconfig @@ -XXX,XX +XXX,XX @@ config REQUIRE_NX was unavailable. However, if enabled, Xen will no longer boot on any CPU which is lacking NX support. +config UCODE + bool "Microcode loading" + default y + help + Support updating the microcode revision of available CPUs with a newer + vendor-provided microcode blob. Microcode updates address some classes of + silicon defects. It's a very common delivery mechanism for fixes or + workarounds for speculative execution vulnerabilities. + + If unsure, say Y + config UCODE_SCAN_DEFAULT bool "Scan for microcode by default" + depends on UCODE 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 diff --git a/xen/arch/x86/cpu/microcode/Makefile b/xen/arch/x86/cpu/microcode/Makefile index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/x86/cpu/microcode/Makefile +++ b/xen/arch/x86/cpu/microcode/Makefile @@ -XXX,XX +XXX,XX @@ -obj-$(CONFIG_AMD) += amd.o +obj-$(filter $(CONFIG_AMD),$(CONFIG_UCODE)) += amd.o obj-$(CONFIG_AMD) += amd-base.o obj-y += base.o -obj-y += core.o -obj-$(CONFIG_INTEL) += intel.o +obj-$(CONFIG_UCODE) += core.o +obj-$(filter $(CONFIG_INTEL),$(CONFIG_UCODE)) += intel.o obj-$(CONFIG_INTEL) += intel-base.o diff --git a/xen/arch/x86/cpu/microcode/amd-base.c b/xen/arch/x86/cpu/microcode/amd-base.c index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/x86/cpu/microcode/amd-base.c +++ b/xen/arch/x86/cpu/microcode/amd-base.c @@ -XXX,XX +XXX,XX @@ static void cf_check collect_cpu_info(void) } static const struct microcode_ops __initconst_cf_clobber amd_ucode_ops = { - .cpu_request_microcode = amd_cpu_request_microcode, .collect_cpu_info = collect_cpu_info, +#ifdef CONFIG_UCODE + .cpu_request_microcode = amd_cpu_request_microcode, .apply_microcode = amd_apply_microcode, .compare = amd_compare, .cpio_path = amd_cpio_path, +#endif /* CONFIG_UCODE */ }; 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. + * CPUs. Taint Xen if digest checking is turned off and microcode loading is + * compiled in. */ +#ifdef CONFIG_UCODE if ( boot_cpu_data.family >= 0x17 && boot_cpu_data.family <= 0x1a && !opt_digest_check ) { @@ -XXX,XX +XXX,XX @@ void __init ucode_probe_amd(struct microcode_ops *ops) "Microcode patch additional digest checks disabled\n"); add_taint(TAINT_CPU_OUT_OF_SPEC); } +#endif /* CONFIG_UCODE */ if ( boot_cpu_data.family < 0x10 ) return; diff --git a/xen/arch/x86/cpu/microcode/base.c b/xen/arch/x86/cpu/microcode/base.c index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/x86/cpu/microcode/base.c +++ b/xen/arch/x86/cpu/microcode/base.c @@ -XXX,XX +XXX,XX @@ #include "private.h" struct microcode_ops __ro_after_init ucode_ops; +DEFINE_PER_CPU(struct cpu_signature, cpu_sig); int microcode_update_one(void) { @@ -XXX,XX +XXX,XX @@ int microcode_update_one(void) if ( ucode_ops.collect_cpu_info ) alternative_vcall(ucode_ops.collect_cpu_info); + if ( !IS_ENABLED(CONFIG_UCODE) ) + return 0; + return _microcode_update_one(); } @@ -XXX,XX +XXX,XX @@ int __init early_microcode_init(struct boot_info *bi) { const struct cpuinfo_x86 *c = &boot_cpu_data; - switch ( c->vendor ) - { - case X86_VENDOR_AMD: + if ( IS_ENABLED(CONFIG_AMD) && c->vendor == X86_VENDOR_AMD ) ucode_probe_amd(&ucode_ops); - break; - - case X86_VENDOR_INTEL: + else if ( IS_ENABLED(CONFIG_INTEL) && c->vendor == X86_VENDOR_INTEL ) ucode_probe_intel(&ucode_ops); - break; - } if ( !ucode_ops.collect_cpu_info ) { @@ -XXX,XX +XXX,XX @@ int __init early_microcode_init(struct boot_info *bi) * * Take the hint in either case and ignore the microcode interface. */ - if ( !ucode_ops.apply_microcode || this_cpu(cpu_sig).rev == ~0 ) + if ( !IS_ENABLED(CONFIG_UCODE) || !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"); + !IS_ENABLED(CONFIG_UCODE) ? "not compiled-in" : + ucode_ops.apply_microcode ? "rev = ~0" : + "HW toggle"); ucode_ops.apply_microcode = NULL; return -ENODEV; } diff --git a/xen/arch/x86/cpu/microcode/core.c b/xen/arch/x86/cpu/microcode/core.c index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/x86/cpu/microcode/core.c +++ b/xen/arch/x86/cpu/microcode/core.c @@ -XXX,XX +XXX,XX @@ custom_param("ucode", parse_ucode); static DEFINE_SPINLOCK(microcode_mutex); -DEFINE_PER_CPU(struct cpu_signature, cpu_sig); /* Store error code of the work done in NMI handler */ static DEFINE_PER_CPU(int, loading_err); diff --git a/xen/arch/x86/cpu/microcode/intel-base.c b/xen/arch/x86/cpu/microcode/intel-base.c index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/x86/cpu/microcode/intel-base.c +++ b/xen/arch/x86/cpu/microcode/intel-base.c @@ -XXX,XX +XXX,XX @@ static void cf_check collect_cpu_info(void) } static const struct microcode_ops __initconst_cf_clobber intel_ucode_ops = { + .collect_cpu_info = collect_cpu_info, +#ifdef CONFIG_UCODE .cpu_request_microcode = intel_cpu_request_microcode, .apply_microcode = intel_apply_microcode, - .collect_cpu_info = collect_cpu_info, .compare = intel_compare, .cpio_path = intel_cpio_path, +#endif /* CONFIG_UCODE */ }; void __init ucode_probe_intel(struct microcode_ops *ops) { *ops = intel_ucode_ops; - if ( !intel_can_load_microcode() ) + if ( IS_ENABLED(CONFIG_UCODE) && !intel_can_load_microcode() ) ops->apply_microcode = NULL; } diff --git a/xen/arch/x86/efi/efi-boot.h b/xen/arch/x86/efi/efi-boot.h index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/x86/efi/efi-boot.h +++ b/xen/arch/x86/efi/efi-boot.h @@ -XXX,XX +XXX,XX @@ 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_UCODE) || read_section(image, L"ucode", &ucode, NULL) ) return; name.s = get_value(&cfg, section, "ucode"); diff --git a/xen/arch/x86/platform_hypercall.c b/xen/arch/x86/platform_hypercall.c index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/x86/platform_hypercall.c +++ b/xen/arch/x86/platform_hypercall.c @@ -XXX,XX +XXX,XX @@ ret_t do_platform_op( break; } +#ifdef CONFIG_UCODE case XENPF_microcode_update: { XEN_GUEST_HANDLE(const_void) data; @@ -XXX,XX +XXX,XX @@ ret_t do_platform_op( op->u.microcode2.flags); break; } +#endif /* CONFIG_UCODE */ case XENPF_platform_quirk: { -- 2.43.0
Hi, v1: https://lore.kernel.org/xen-devel/20251112162219.226075-1-alejandro.garciavallejo@amd.com/ v2: https://lore.kernel.org/xen-devel/20260112150259.74535-1-alejandro.garciavallejo@amd.com/ v3: https://lore.kernel.org/xen-devel/20260113122109.62399-1-alejandro.garciavallejo@amd.com/ pipeline (red, but see below): https://gitlab.com/xen-project/people/agvallejo/xen/-/pipelines/2272127547 Pipeline failures are on ARM builds, so clearly unrelated to this. Also has an eclair run on allcode that shows no new failures in earlycpio.c. The only dependency here is patch 2 going in before patch 3. Everything else can be freely rearranged. Cheers, Alejandro Alejandro Vallejo (5): x86/ucode: Add Kconfig option to remove microcode loading xen: Allow lib-y targets to also be .init.o earlycpio: lib-ify earlycpio.c docs/misra: Remove earlycpio.c from the Eclair exclusion list. automation: Disable ucode loading on AMD's analysis run automation/gitlab-ci/analyze.yaml | 1 + docs/admin-guide/microcode-loading.rst | 2 ++ docs/misc/efi.pandoc | 2 ++ docs/misc/xen-command-line.pandoc | 7 ++++--- docs/misra/exclude-list.json | 4 ---- xen/Rules.mk | 10 +++++----- xen/arch/x86/Kconfig | 14 ++++++++++++++ xen/arch/x86/cpu/microcode/amd.c | 16 +++++++++------- xen/arch/x86/cpu/microcode/core.c | 15 ++++++++++++--- xen/arch/x86/cpu/microcode/intel.c | 11 +++++++---- xen/arch/x86/cpu/microcode/private.h | 3 +++ xen/arch/x86/efi/efi-boot.h | 3 ++- xen/arch/x86/platform_hypercall.c | 10 ++++++++-- xen/common/Makefile | 2 +- xen/lib/Makefile | 1 + xen/{common => lib}/earlycpio.c | 0 16 files changed, 71 insertions(+), 30 deletions(-) rename xen/{common => lib}/earlycpio.c (100%) base-commit: 7b3e1b4e848d34c9a5b6634009959a7b9dd42104 -- 2.43.0
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> --- v4: * Minor spell fix in commit message ("rather") * efi.pandoc: terminate sentence with "enabled". * xen-command-line: State applicability as first line. * reorder cpu hooks. * MICROCODE_OP() comment * MICROCODE_OP() moved next to microcode_ops * Re-arranged platform_ops to turn them into smaller hunks. --- docs/admin-guide/microcode-loading.rst | 2 ++ docs/misc/efi.pandoc | 2 ++ docs/misc/xen-command-line.pandoc | 7 ++++--- xen/arch/x86/Kconfig | 14 ++++++++++++++ xen/arch/x86/cpu/microcode/amd.c | 16 +++++++++------- xen/arch/x86/cpu/microcode/core.c | 15 ++++++++++++--- xen/arch/x86/cpu/microcode/intel.c | 11 +++++++---- xen/arch/x86/cpu/microcode/private.h | 3 +++ xen/arch/x86/efi/efi-boot.h | 3 ++- xen/arch/x86/platform_hypercall.c | 10 ++++++++-- 10 files changed, 63 insertions(+), 20 deletions(-) diff --git a/docs/admin-guide/microcode-loading.rst b/docs/admin-guide/microcode-loading.rst index XXXXXXX..XXXXXXX 100644 --- a/docs/admin-guide/microcode-loading.rst +++ b/docs/admin-guide/microcode-loading.rst @@ -XXX,XX +XXX,XX @@ 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 --------------------------- diff --git a/docs/misc/efi.pandoc b/docs/misc/efi.pandoc index XXXXXXX..XXXXXXX 100644 --- a/docs/misc/efi.pandoc +++ b/docs/misc/efi.pandoc @@ -XXX,XX +XXX,XX @@ 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 diff --git a/docs/misc/xen-command-line.pandoc b/docs/misc/xen-command-line.pandoc index XXXXXXX..XXXXXXX 100644 --- a/docs/misc/xen-command-line.pandoc +++ b/docs/misc/xen-command-line.pandoc @@ -XXX,XX +XXX,XX @@ 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 diff --git a/xen/arch/x86/Kconfig b/xen/arch/x86/Kconfig index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/x86/Kconfig +++ b/xen/arch/x86/Kconfig @@ -XXX,XX +XXX,XX @@ 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 diff --git a/xen/arch/x86/cpu/microcode/amd.c b/xen/arch/x86/cpu/microcode/amd.c index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/x86/cpu/microcode/amd.c +++ b/xen/arch/x86/cpu/microcode/amd.c @@ -XXX,XX +XXX,XX @@ 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) @@ -XXX,XX +XXX,XX @@ 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 @@ -XXX,XX +XXX,XX @@ 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; diff --git a/xen/arch/x86/cpu/microcode/core.c b/xen/arch/x86/cpu/microcode/core.c index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/x86/cpu/microcode/core.c +++ b/xen/arch/x86/cpu/microcode/core.c @@ -XXX,XX +XXX,XX @@ */ #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; /* @@ -XXX,XX +XXX,XX @@ 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. @@ -XXX,XX +XXX,XX @@ 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; @@ -XXX,XX +XXX,XX @@ 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; @@ -XXX,XX +XXX,XX @@ 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) { @@ -XXX,XX +XXX,XX @@ 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) @@ -XXX,XX +XXX,XX @@ 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); @@ -XXX,XX +XXX,XX @@ 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; @@ -XXX,XX +XXX,XX @@ static int __init cf_check microcode_init_cache(void) return rc; } presmp_initcall(microcode_init_cache); +#endif /* CONFIG_MICROCODE_LOADING */ /* * There are several tasks: @@ -XXX,XX +XXX,XX @@ 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. diff --git a/xen/arch/x86/cpu/microcode/intel.c b/xen/arch/x86/cpu/microcode/intel.c index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/x86/cpu/microcode/intel.c +++ b/xen/arch/x86/cpu/microcode/intel.c @@ -XXX,XX +XXX,XX @@ 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; } diff --git a/xen/arch/x86/cpu/microcode/private.h b/xen/arch/x86/cpu/microcode/private.h index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/x86/cpu/microcode/private.h +++ b/xen/arch/x86/cpu/microcode/private.h @@ -XXX,XX +XXX,XX @@ /* 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. diff --git a/xen/arch/x86/efi/efi-boot.h b/xen/arch/x86/efi/efi-boot.h index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/x86/efi/efi-boot.h +++ b/xen/arch/x86/efi/efi-boot.h @@ -XXX,XX +XXX,XX @@ 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"); diff --git a/xen/arch/x86/platform_hypercall.c b/xen/arch/x86/platform_hypercall.c index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/x86/platform_hypercall.c +++ b/xen/arch/x86/platform_hypercall.c @@ -XXX,XX +XXX,XX @@ ret_t do_platform_op( { XEN_GUEST_HANDLE(const_void) data; - guest_from_compat_handle(data, op->u.microcode.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); break; } @@ -XXX,XX +XXX,XX @@ ret_t do_platform_op( { XEN_GUEST_HANDLE(const_void) data; - guest_from_compat_handle(data, op->u.microcode2.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, op->u.microcode2.flags); break; -- 2.43.0
There's some assumptions as to which targets may be init-only. But there's little reason to preclude libraries from being init-only. Signed-off-by: Alejandro Vallejo <alejandro.garciavallejo@amd.com> --- xen/Rules.mk | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/xen/Rules.mk b/xen/Rules.mk index XXXXXXX..XXXXXXX 100644 --- a/xen/Rules.mk +++ b/xen/Rules.mk @@ -XXX,XX +XXX,XX @@ endif targets += $(targets-for-builtin) -$(filter %.init.o,$(obj-y) $(obj-bin-y) $(extra-y)): CFLAGS-y += -DINIT_SECTIONS_ONLY +$(filter %.init.o,$(obj-y) $(obj-bin-y) $(extra-y) $(lib-y)): CFLAGS-y += -DINIT_SECTIONS_ONLY -non-init-objects = $(filter-out %.init.o, $(obj-y) $(obj-bin-y) $(extra-y)) +non-init-objects = $(filter-out %.init.o, $(obj-y) $(obj-bin-y) $(extra-y) $(lib-y)) ifeq ($(CONFIG_CC_IS_CLANG),y) cov-cflags-$(CONFIG_COVERAGE) := -fprofile-instr-generate -fcoverage-mapping @@ -XXX,XX +XXX,XX @@ endif $(call cc-option-add,cov-cflags-$(CONFIG_COVERAGE),CC,-fprofile-update=atomic) # Reset cov-cflags-y in cases where an objects has another one as prerequisite -$(nocov-y) $(filter %.init.o, $(obj-y) $(obj-bin-y) $(extra-y)): \ +$(nocov-y) $(filter %.init.o, $(obj-y) $(obj-bin-y) $(extra-y) $(lib-y)): \ cov-cflags-y := $(non-init-objects): _c_flags += $(cov-cflags-y) @@ -XXX,XX +XXX,XX @@ ifeq ($(CONFIG_UBSAN),y) UBSAN_FLAGS := $(filter-out -fno-%,$(CFLAGS_UBSAN)) $(filter -fno-%,$(CFLAGS_UBSAN)) # Reset UBSAN_FLAGS in cases where an objects has another one as prerequisite -$(noubsan-y) $(filter %.init.o, $(obj-y) $(obj-bin-y) $(extra-y)): \ +$(noubsan-y) $(filter %.init.o, $(obj-y) $(obj-bin-y) $(extra-y) $(lib-y)): \ UBSAN_FLAGS := $(non-init-objects): _c_flags += $(UBSAN_FLAGS) @@ -XXX,XX +XXX,XX @@ define cmd_obj_init_o $(OBJCOPY) $(foreach s,$(SPECIAL_DATA_SECTIONS),--rename-section .$(s)=.init.$(s)) $< $@ endef -$(filter %.init.o,$(obj-y) $(obj-bin-y) $(extra-y)): $(obj)/%.init.o: $(obj)/%.o FORCE +$(filter %.init.o,$(obj-y) $(obj-bin-y) $(extra-y) $(lib-y)): $(obj)/%.init.o: $(obj)/%.o FORCE $(call if_changed,obj_init_o) quiet_cmd_cpp_i_c = CPP $@ -- 2.43.0
It's only used for microcode loading on x86. By lib-ifying it we can make it go away automatically when microcode loading becomes an optional feature in follow-up patches. Signed-off-by: Alejandro Vallejo <alejandro.garciavallejo@amd.com> --- v4: * Makes the lib-y target init-only --- xen/common/Makefile | 2 +- xen/lib/Makefile | 1 + xen/{common => lib}/earlycpio.c | 0 3 files changed, 2 insertions(+), 1 deletion(-) rename xen/{common => lib}/earlycpio.c (100%) diff --git a/xen/common/Makefile b/xen/common/Makefile index XXXXXXX..XXXXXXX 100644 --- a/xen/common/Makefile +++ b/xen/common/Makefile @@ -XXX,XX +XXX,XX @@ obj-y += wait.o obj-bin-y += warning.init.o obj-y += xmalloc_tlsf.o -obj-bin-$(CONFIG_X86) += $(foreach n,decompress bunzip2 unxz unlzma lzo unlzo unlz4 unzstd earlycpio,$(n).init.o) +obj-bin-$(CONFIG_X86) += $(foreach n,decompress bunzip2 unxz unlzma lzo unlzo unlz4 unzstd,$(n).init.o) obj-$(CONFIG_COMPAT) += $(addprefix compat/,domain.o memory.o multicall.o xlat.o) diff --git a/xen/lib/Makefile b/xen/lib/Makefile index XXXXXXX..XXXXXXX 100644 --- a/xen/lib/Makefile +++ b/xen/lib/Makefile @@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_X86) += x86/ lib-y += bsearch.o lib-y += ctors.o lib-y += ctype.o +lib-y += earlycpio.init.o lib-y += find-next-bit.o lib-y += generic-ffsl.o lib-y += generic-flsl.o diff --git a/xen/common/earlycpio.c b/xen/lib/earlycpio.c similarity index 100% rename from xen/common/earlycpio.c rename to xen/lib/earlycpio.c -- 2.43.0
It's clean. Signed-off-by: Alejandro Vallejo <alejandro.garciavallejo@amd.com> --- docs/misra/exclude-list.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs/misra/exclude-list.json b/docs/misra/exclude-list.json index XXXXXXX..XXXXXXX 100644 --- a/docs/misra/exclude-list.json +++ b/docs/misra/exclude-list.json @@ -XXX,XX +XXX,XX @@ "rel_path": "common/bunzip2.c", "comment": "Imported from Linux, ignore for now" }, - { - "rel_path": "common/earlycpio.c", - "comment": "Imported from Linux, ignore for now" - }, { "rel_path": "common/gzip/*", "comment": "Imported from Linux, ignore for now" -- 2.43.0
Explicitly set CONFIG_MICROCODE_LOADING=n Signed-off-by: Alejandro Vallejo <alejandro.garciavallejo@amd.com> --- automation/gitlab-ci/analyze.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/automation/gitlab-ci/analyze.yaml b/automation/gitlab-ci/analyze.yaml index XXXXXXX..XXXXXXX 100644 --- a/automation/gitlab-ci/analyze.yaml +++ b/automation/gitlab-ci/analyze.yaml @@ -XXX,XX +XXX,XX @@ eclair-x86_64-amd: CONFIG_DEBUG_LOCKS=n CONFIG_SCRUB_DEBUG=n CONFIG_XMEM_POOL_POISON=n + CONFIG_MICROCODE_LOADING=n rules: - if: $ECLAIR_SAFETY when: always -- 2.43.0