diff mbox series

[v5] x86/ucode/AMD: late load the patch on every logical thread

Message ID 20230223173924.11815-1-sergey.dyasli@citrix.com (mailing list archive)
State New, archived
Headers show
Series [v5] x86/ucode/AMD: late load the patch on every logical thread | expand

Commit Message

Sergey Dyasli Feb. 23, 2023, 5:39 p.m. UTC
Currently late ucode loading is performed only on the first core of CPU
siblings.  But according to the latest recommendation from AMD, late
ucode loading should happen on every logical thread/core on AMD CPUs.

To achieve that, introduce is_cpu_primary() helper which will consider
every logical cpu as "primary" when running on AMD CPUs.  Also include
Hygon in the check for future-proofing.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
---
v5:
- refactored the code by adding is_cpu_primary() helper
- include Hygon cpus into the check

v4:
- new patch
---
 xen/arch/x86/cpu/microcode/core.c | 24 +++++++++++++++++++-----
 1 file changed, 19 insertions(+), 5 deletions(-)

Comments

Jan Beulich Feb. 27, 2023, 4:05 p.m. UTC | #1
On 23.02.2023 18:39, Sergey Dyasli wrote:
> Currently late ucode loading is performed only on the first core of CPU
> siblings.  But according to the latest recommendation from AMD, late
> ucode loading should happen on every logical thread/core on AMD CPUs.
> 
> To achieve that, introduce is_cpu_primary() helper which will consider
> every logical cpu as "primary" when running on AMD CPUs.  Also include
> Hygon in the check for future-proofing.
> 
> Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>

Reviewed-by: Jan Beulich <jbeulich@suse.com>
diff mbox series

Patch

diff --git a/xen/arch/x86/cpu/microcode/core.c b/xen/arch/x86/cpu/microcode/core.c
index ba6e7b42c6..cfa2d5053a 100644
--- a/xen/arch/x86/cpu/microcode/core.c
+++ b/xen/arch/x86/cpu/microcode/core.c
@@ -276,6 +276,20 @@  static bool microcode_update_cache(struct microcode_patch *patch)
     return true;
 }
 
+/* Returns true if ucode should be loaded on a given cpu */
+static bool is_cpu_primary(unsigned int cpu)
+{
+    if ( boot_cpu_data.x86_vendor & (X86_VENDOR_AMD | X86_VENDOR_HYGON) )
+        /* Load ucode on every logical thread/core */
+        return true;
+
+    /* Intel CPUs should load ucode only on the first core of SMT siblings */
+    if ( cpu == cpumask_first(per_cpu(cpu_sibling_mask, cpu)) )
+        return true;
+
+    return false;
+}
+
 /* Wait for a condition to be met with a timeout (us). */
 static int wait_for_condition(bool (*func)(unsigned int data),
                               unsigned int data, unsigned int timeout)
@@ -382,7 +396,7 @@  static int primary_thread_work(const struct microcode_patch *patch)
 static int cf_check microcode_nmi_callback(
     const struct cpu_user_regs *regs, int cpu)
 {
-    unsigned int primary = cpumask_first(this_cpu(cpu_sibling_mask));
+    bool primary_cpu = is_cpu_primary(cpu);
     int ret;
 
     /* System-generated NMI, leave to main handler */
@@ -395,10 +409,10 @@  static int cf_check microcode_nmi_callback(
      * ucode_in_nmi.
      */
     if ( cpu == cpumask_first(&cpu_online_map) ||
-         (!ucode_in_nmi && cpu == primary) )
+         (!ucode_in_nmi && primary_cpu) )
         return 0;
 
-    if ( cpu == primary )
+    if ( primary_cpu )
         ret = primary_thread_work(nmi_patch);
     else
         ret = secondary_nmi_work();
@@ -549,7 +563,7 @@  static int cf_check do_microcode_update(void *patch)
      */
     if ( cpu == cpumask_first(&cpu_online_map) )
         ret = control_thread_fn(patch);
-    else if ( cpu == cpumask_first(this_cpu(cpu_sibling_mask)) )
+    else if ( is_cpu_primary(cpu) )
         ret = primary_thread_fn(patch);
     else
         ret = secondary_thread_fn();
@@ -642,7 +656,7 @@  static long cf_check microcode_update_helper(void *data)
     /* Calculate the number of online CPU core */
     nr_cores = 0;
     for_each_online_cpu(cpu)
-        if ( cpu == cpumask_first(per_cpu(cpu_sibling_mask, cpu)) )
+        if ( is_cpu_primary(cpu) )
             nr_cores++;
 
     printk(XENLOG_INFO "%u cores are to update their microcode\n", nr_cores);