[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[xen stable-4.16] x86/ucode/AMD: late load the patch on every logical thread



commit 84dfe7a56f04a7412fa4869b3e756c49e1cfbe75
Author:     Sergey Dyasli <sergey.dyasli@xxxxxxxxxx>
AuthorDate: Fri Mar 3 08:17:40 2023 +0100
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Fri Mar 3 08:17:40 2023 +0100

    x86/ucode/AMD: late load the patch on every logical thread
    
    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@xxxxxxxxxx>
    Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
    master commit: f1315e48a03a42f78f9b03c0a384165baf02acae
    master date: 2023-02-28 14:51:28 +0100
---
 xen/arch/x86/cpu/microcode/core.c | 24 +++++++++++++++++++-----
 1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/xen/arch/x86/cpu/microcode/core.c 
b/xen/arch/x86/cpu/microcode/core.c
index ceec1f1edc..ee7df9a591 100644
--- a/xen/arch/x86/cpu/microcode/core.c
+++ b/xen/arch/x86/cpu/microcode/core.c
@@ -273,6 +273,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)
@@ -378,7 +392,7 @@ static int primary_thread_work(const struct microcode_patch 
*patch)
 
 static int 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 */
@@ -391,10 +405,10 @@ static int microcode_nmi_callback(const struct 
cpu_user_regs *regs, int cpu)
      * 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();
@@ -545,7 +559,7 @@ static int 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();
@@ -637,7 +651,7 @@ static long 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);
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.16



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.