summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '0059-x86-ucode-AMD-late-load-the-patch-on-every-logical-t.patch')
-rw-r--r--0059-x86-ucode-AMD-late-load-the-patch-on-every-logical-t.patch90
1 files changed, 90 insertions, 0 deletions
diff --git a/0059-x86-ucode-AMD-late-load-the-patch-on-every-logical-t.patch b/0059-x86-ucode-AMD-late-load-the-patch-on-every-logical-t.patch
new file mode 100644
index 0000000..292a61a
--- /dev/null
+++ b/0059-x86-ucode-AMD-late-load-the-patch-on-every-logical-t.patch
@@ -0,0 +1,90 @@
+From ec5b058d2a6436a2e180315522fcf1645a8153b4 Mon Sep 17 00:00:00 2001
+From: Sergey Dyasli <sergey.dyasli@citrix.com>
+Date: Fri, 3 Mar 2023 08:03:43 +0100
+Subject: [PATCH 59/89] 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@citrix.com>
+Reviewed-by: Jan Beulich <jbeulich@suse.com>
+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 57ecc5358b..2497630bbe 100644
+--- a/xen/arch/x86/cpu/microcode/core.c
++++ b/xen/arch/x86/cpu/microcode/core.c
+@@ -274,6 +274,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)
+@@ -380,7 +394,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 */
+@@ -393,10 +407,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();
+@@ -547,7 +561,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();
+@@ -640,7 +654,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);
+--
+2.40.0
+