[PATCH 3/4] x86: Split out early_microcode_load() and microcode_load_one()

Alejandro Vallejo posted 4 patches 6 days, 9 hours ago
[PATCH 3/4] x86: Split out early_microcode_load() and microcode_load_one()
Posted by Alejandro Vallejo 6 days, 9 hours ago
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 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