Mailing List Archive

[xen staging] x86/ucode: Move vendor specifics back out of early_microcode_init()
commit 2eea952b70d297b0c86b70bff55d75b3ff9aa782
Author: Andrew Cooper <andrew.cooper3@citrix.com>
AuthorDate: Tue Oct 24 19:32:31 2023 +0100
Commit: Andrew Cooper <andrew.cooper3@citrix.com>
CommitDate: Wed Apr 10 18:34:46 2024 +0100

x86/ucode: Move vendor specifics back out of early_microcode_init()

I know it was me who dropped microcode_init_{intel,amd}() in c/s
dd5f07997f29 ("x86/ucode: Rationalise startup and family/model checks"), but
times have moved on. We've gained new conditional support, and a wish to
compile-time specialise Xen to single platform.

(Re)introduce ucode_probe_{amd,intel}() and move the recent vendor specific
additions back out. Encode the conditional support state in the NULL-ness of
hooks as it's already done on other paths.

No functional change.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
xen/arch/x86/cpu/microcode/amd.c | 10 +++++++++-
xen/arch/x86/cpu/microcode/core.c | 16 +++++-----------
xen/arch/x86/cpu/microcode/intel.c | 12 ++++++++++--
xen/arch/x86/cpu/microcode/private.h | 16 ++++++++++------
4 files changed, 34 insertions(+), 20 deletions(-)

diff --git a/xen/arch/x86/cpu/microcode/amd.c b/xen/arch/x86/cpu/microcode/amd.c
index 75fc84e445..17e68697d5 100644
--- a/xen/arch/x86/cpu/microcode/amd.c
+++ b/xen/arch/x86/cpu/microcode/amd.c
@@ -434,9 +434,17 @@ static struct microcode_patch *cf_check cpu_request_microcode(
return patch;
}

-const struct microcode_ops __initconst_cf_clobber amd_ucode_ops = {
+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_patch = compare_patch,
};
+
+void __init ucode_probe_amd(struct microcode_ops *ops)
+{
+ if ( boot_cpu_data.x86 < 0x10 )
+ return;
+
+ *ops = amd_ucode_ops;
+}
diff --git a/xen/arch/x86/cpu/microcode/core.c b/xen/arch/x86/cpu/microcode/core.c
index 1c9f66ea8a..e738a88f5c 100644
--- a/xen/arch/x86/cpu/microcode/core.c
+++ b/xen/arch/x86/cpu/microcode/core.c
@@ -861,25 +861,19 @@ int __init early_microcode_init(unsigned long *module_map,
{
const struct cpuinfo_x86 *c = &boot_cpu_data;
int rc = 0;
- bool can_load = false;

switch ( c->x86_vendor )
{
case X86_VENDOR_AMD:
- if ( c->x86 >= 0x10 )
- {
- ucode_ops = amd_ucode_ops;
- can_load = true;
- }
+ ucode_probe_amd(&ucode_ops);
break;

case X86_VENDOR_INTEL:
- ucode_ops = intel_ucode_ops;
- can_load = intel_can_load_microcode();
+ ucode_probe_intel(&ucode_ops);
break;
}

- if ( !ucode_ops.apply_microcode )
+ if ( !ucode_ops.collect_cpu_info )
{
printk(XENLOG_INFO "Microcode loading not available\n");
return -ENODEV;
@@ -896,10 +890,10 @@ int __init early_microcode_init(unsigned long *module_map,
*
* Take the hint in either case and ignore the microcode interface.
*/
- if ( this_cpu(cpu_sig).rev == ~0 || !can_load )
+ if ( !ucode_ops.apply_microcode || this_cpu(cpu_sig).rev == ~0 )
{
printk(XENLOG_INFO "Microcode loading disabled due to: %s\n",
- can_load ? "rev = ~0" : "HW toggle");
+ ucode_ops.apply_microcode ? "rev = ~0" : "HW toggle");
ucode_ops.apply_microcode = NULL;
return -ENODEV;
}
diff --git a/xen/arch/x86/cpu/microcode/intel.c b/xen/arch/x86/cpu/microcode/intel.c
index 060c529a6e..96f34b336b 100644
--- a/xen/arch/x86/cpu/microcode/intel.c
+++ b/xen/arch/x86/cpu/microcode/intel.c
@@ -385,7 +385,7 @@ static struct microcode_patch *cf_check cpu_request_microcode(
return patch;
}

-bool __init intel_can_load_microcode(void)
+static bool __init can_load_microcode(void)
{
uint64_t mcu_ctrl;

@@ -398,9 +398,17 @@ bool __init intel_can_load_microcode(void)
return !(mcu_ctrl & MCU_CONTROL_DIS_MCU_LOAD);
}

-const struct microcode_ops __initconst_cf_clobber intel_ucode_ops = {
+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_patch = compare_patch,
};
+
+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/private.h b/xen/arch/x86/cpu/microcode/private.h
index d80787205a..b58611e908 100644
--- a/xen/arch/x86/cpu/microcode/private.h
+++ b/xen/arch/x86/cpu/microcode/private.h
@@ -60,13 +60,17 @@ struct microcode_ops {
const struct microcode_patch *new, const struct microcode_patch *old);
};

-/**
- * Checks whether we can perform microcode updates on this Intel system
+/*
+ * Microcode loading falls into one of 3 states.
+ * - No support at all
+ * - Read-only (locked by firmware, or we're virtualised)
+ * - Loading available
*
- * @return True iff the microcode update facilities are enabled
+ * These are encoded by (not) filling in ops->collect_cpu_info (i.e. no
+ * support available) and (not) ops->apply_microcode (i.e. read only).
+ * Otherwise, all hooks must be filled in.
*/
-bool intel_can_load_microcode(void);
-
-extern const struct microcode_ops amd_ucode_ops, intel_ucode_ops;
+void ucode_probe_amd(struct microcode_ops *ops);
+void ucode_probe_intel(struct microcode_ops *ops);

#endif /* ASM_X86_MICROCODE_PRIVATE_H */
--
generated by git-patchbot for /home/xen/git/xen.git#staging