xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Chao Gao <chao.gao@intel.com>
To: xen-devel@lists.xenproject.org
Cc: "Sergey Dyasli" <sergey.dyasli@citrix.com>,
	"Wei Liu" <wei.liu2@citrix.com>,
	"Ashok Raj" <ashok.raj@intel.com>,
	"Andrew Cooper" <andrew.cooper3@citrix.com>,
	"Jan Beulich" <jbeulich@suse.com>,
	"Chao Gao" <chao.gao@intel.com>,
	"Roger Pau Monné" <roger.pau@citrix.com>
Subject: [PATCH v6 08/12] microcode: split out apply_microcode() from cpu_request_microcode()
Date: Mon, 11 Mar 2019 15:57:32 +0800	[thread overview]
Message-ID: <1552291056-20286-9-git-send-email-chao.gao@intel.com> (raw)
In-Reply-To: <1552291056-20286-1-git-send-email-chao.gao@intel.com>

During late microcode update, apply_microcode() is invoked in
cpu_request_microcode(). To make late microcode update more reliable,
we want to put the apply_microcode() into stop_machine context. So
we split out it from cpu_request_microcode(). As a consequence,
apply_microcode() should be invoked explicitly in the common code.

Also with the global ucode cache, microcode parsing only needs
to be done once; cpu_request_microcode() is also moved out of
microcode_update_cpu().

On AMD side, svm_host_osvw_init() is supposed to be called after
microcode update. As apply_micrcode() won't be called by
cpu_request_microcode() now, svm_host_osvw_init() is moved to the
end of apply_microcode().

Signed-off-by: Chao Gao <chao.gao@intel.com>
---
Changes in v6:
 - during early microcode update, BSP and APs call different functions.
   Thus AP can bypass parsing microcode blob.
---
 xen/arch/x86/acpi/power.c       |  2 +-
 xen/arch/x86/microcode.c        | 77 +++++++++++++++++++++++++----------------
 xen/arch/x86/microcode_amd.c    | 19 +++++-----
 xen/arch/x86/microcode_intel.c  | 19 ++--------
 xen/arch/x86/smpboot.c          |  5 +--
 xen/include/asm-x86/processor.h |  3 +-
 6 files changed, 62 insertions(+), 63 deletions(-)

diff --git a/xen/arch/x86/acpi/power.c b/xen/arch/x86/acpi/power.c
index b4c3669..aeacb57 100644
--- a/xen/arch/x86/acpi/power.c
+++ b/xen/arch/x86/acpi/power.c
@@ -253,7 +253,7 @@ static int enter_state(u32 state)
 
     console_end_sync();
 
-    microcode_resume_cpu();
+    early_microcode_update_cpu();
 
     if ( !recheck_cpu_features(0) )
         panic("Missing previously available feature(s)\n");
diff --git a/xen/arch/x86/microcode.c b/xen/arch/x86/microcode.c
index 8bfdf95..e4e2e74 100644
--- a/xen/arch/x86/microcode.c
+++ b/xen/arch/x86/microcode.c
@@ -261,38 +261,34 @@ const struct microcode_patch *microcode_find_patch(void)
     return NULL;
 }
 
-int microcode_resume_cpu(void)
+/*
+ * Return the number of ucode patch inserted to the global cache.
+ * Return a negtive value on error.
+ */
+static int microcode_parse_blob(char *buf, uint32_t len)
 {
-    int err;
-    struct cpu_signature *sig = &this_cpu(cpu_sig);
-
-    if ( !microcode_ops )
-        return 0;
+    int ret;
 
     spin_lock(&microcode_mutex);
-
-    err = microcode_ops->collect_cpu_info(sig);
-    if ( likely(!err) )
-        err = microcode_ops->apply_microcode();
+    ret = microcode_ops->collect_cpu_info(&this_cpu(cpu_sig));
+    if ( likely(!ret) )
+        ret = microcode_ops->cpu_request_microcode(buf, len);
     spin_unlock(&microcode_mutex);
 
-    return err;
+    return ret;
 }
 
-static int microcode_update_cpu(const void *buf, size_t size)
+static int microcode_update_cpu(void)
 {
-    int err;
-    unsigned int cpu = smp_processor_id();
-    struct cpu_signature *sig = &per_cpu(cpu_sig, cpu);
+    int ret;
 
     spin_lock(&microcode_mutex);
-
-    err = microcode_ops->collect_cpu_info(sig);
-    if ( likely(!err) )
-        err = microcode_ops->cpu_request_microcode(buf, size);
+    ret = microcode_ops->collect_cpu_info(&this_cpu(cpu_sig));
+    if ( likely(!ret) )
+        ret = microcode_ops->apply_microcode();
     spin_unlock(&microcode_mutex);
 
-    return err;
+    return ret;
 }
 
 static long do_microcode_update(void *_info)
@@ -302,7 +298,7 @@ static long do_microcode_update(void *_info)
 
     BUG_ON(info->cpu != smp_processor_id());
 
-    error = microcode_update_cpu(info->buffer, info->buffer_size);
+    error = microcode_update_cpu();
     if ( error )
         info->error = error;
 
@@ -337,10 +333,6 @@ int microcode_update(XEN_GUEST_HANDLE_PARAM(const_void) buf, unsigned long len)
         return ret;
     }
 
-    info->buffer_size = len;
-    info->error = 0;
-    info->cpu = cpumask_first(&cpu_online_map);
-
     if ( microcode_ops->start_update )
     {
         ret = microcode_ops->start_update();
@@ -351,6 +343,18 @@ int microcode_update(XEN_GUEST_HANDLE_PARAM(const_void) buf, unsigned long len)
         }
     }
 
+    ret = microcode_parse_blob(info->buffer, len);
+    if ( ret <= 0 )
+    {
+        printk(XENLOG_ERR "No valid or newer ucode found. Update abort!\n");
+        xfree(info);
+        return -EINVAL;
+    }
+
+    info->buffer_size = len;
+    info->error = 0;
+    info->cpu = cpumask_first(&cpu_online_map);
+
     return continue_hypercall_on_cpu(info->cpu, do_microcode_update, info);
 }
 
@@ -376,7 +380,16 @@ static int __init microcode_init(void)
 }
 __initcall(microcode_init);
 
-int __init early_microcode_update_cpu(bool start_update)
+int early_microcode_update_cpu(void)
+{
+    return microcode_ops ? microcode_update_cpu() : 0;
+}
+
+/*
+ * BSP needs to parse the ucode blob and then apply an update.
+ * APs just apply an update by calling early_microcode_update_cpu().
+ */
+static int __init early_microcode_parse_and_update_cpu(void)
 {
     int rc = 0;
     void *data = NULL;
@@ -394,13 +407,17 @@ int __init early_microcode_update_cpu(bool start_update)
     }
     if ( data )
     {
-        if ( start_update && microcode_ops->start_update )
+        if ( microcode_ops->start_update )
             rc = microcode_ops->start_update();
 
         if ( rc )
             return rc;
 
-        return microcode_update_cpu(data, len);
+        rc = microcode_parse_blob(data, len);
+        if ( rc <= 0 )
+            return -EINVAL;
+
+        return early_microcode_update_cpu();
     }
     else
         return -ENOMEM;
@@ -419,8 +436,10 @@ int __init early_microcode_init(void)
         return rc;
 
     if ( microcode_ops )
+    {
         if ( ucode_mod.mod_end || ucode_blob.size )
-            rc = early_microcode_update_cpu(true);
+            rc = early_microcode_parse_and_update_cpu();
+    }
 
     return rc;
 }
diff --git a/xen/arch/x86/microcode_amd.c b/xen/arch/x86/microcode_amd.c
index 25935dd..5c25ff2 100644
--- a/xen/arch/x86/microcode_amd.c
+++ b/xen/arch/x86/microcode_amd.c
@@ -293,6 +293,10 @@ static int apply_microcode(void)
 
     sig->rev = rev;
 
+#ifdef CONFIG_HVM
+    svm_host_osvw_init();
+#endif
+
     return 0;
 }
 
@@ -459,6 +463,7 @@ static int cpu_request_microcode(const void *buf, size_t bufsize)
     unsigned int equiv_cpu_id;
     unsigned int cpu = smp_processor_id();
     const struct cpu_signature *sig = &per_cpu(cpu_sig, cpu);
+    unsigned int matched_cnt = 0;
 
     current_cpu_id = cpuid_eax(0x00000001);
 
@@ -557,12 +562,8 @@ static int cpu_request_microcode(const void *buf, size_t bufsize)
          * this ucode patch before checking whether it matches with
          * current CPU.
          */
-        if ( microcode_save_patch(microcode_patch) && microcode_fits(mc_amd) )
-        {
-            error = apply_microcode();
-            if ( error )
-                break;
-        }
+        if ( microcode_save_patch(microcode_patch) )
+            matched_cnt++;
 
         if ( offset >= bufsize )
             break;
@@ -593,17 +594,13 @@ static int cpu_request_microcode(const void *buf, size_t bufsize)
     }
 
   out:
-#if CONFIG_HVM
-    svm_host_osvw_init();
-#endif
-
     /*
      * In some cases we may return an error even if processor's microcode has
      * been updated. For example, the first patch in a container file is loaded
      * successfully but subsequent container file processing encounters a
      * failure.
      */
-    return error;
+    return error ?: matched_cnt;
 }
 
 static int start_update(void)
diff --git a/xen/arch/x86/microcode_intel.c b/xen/arch/x86/microcode_intel.c
index 18c833f..c921ea9 100644
--- a/xen/arch/x86/microcode_intel.c
+++ b/xen/arch/x86/microcode_intel.c
@@ -310,7 +310,6 @@ static enum microcode_match_result compare_patch(
  */
 static int get_matching_microcode(const void *mc, unsigned int cpu)
 {
-    const struct cpu_signature *sig = &per_cpu(cpu_sig, cpu);
     const struct microcode_header_intel *mc_header = mc;
     unsigned long total_size = get_totalsize(mc_header);
     void *new_mc = xmalloc_bytes(total_size);
@@ -328,18 +327,9 @@ static int get_matching_microcode(const void *mc, unsigned int cpu)
 
     /*
      * In order to support a system with mixed stepping CPUs, save this ucode
-     * patch before checking whether it matches with current CPU.
+     * patch without checking whether it matches with current CPU.
      */
-    if ( !microcode_save_patch(microcode_patch) )
-        return 0;
-
-    if ( microcode_update_match(mc, sig->sig, sig->pf, sig->rev) != NEW_UCODE )
-        return 0;
-
-    pr_debug("microcode: CPU%d found a matching microcode update with"
-             " version %#x (current=%#x)\n",
-             cpu, mc_header->rev, sig->rev);
-    return 1;
+    return microcode_save_patch(microcode_patch);
 }
 
 static int apply_microcode(void)
@@ -451,10 +441,7 @@ static int cpu_request_microcode(const void *buf, size_t size)
     if ( offset < 0 )
         error = offset;
 
-    if ( !error && matching_count )
-        error = apply_microcode();
-
-    return error;
+    return error ?: matching_count;
 }
 
 static const struct microcode_ops microcode_intel_ops = {
diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c
index 763b0bd..2a7f30e 100644
--- a/xen/arch/x86/smpboot.c
+++ b/xen/arch/x86/smpboot.c
@@ -363,10 +363,7 @@ void start_secondary(void *unused)
 
     initialize_cpu_data(cpu);
 
-    if ( system_state <= SYS_STATE_smp_boot )
-        early_microcode_update_cpu(false);
-    else
-        microcode_resume_cpu();
+    early_microcode_update_cpu();
 
     /*
      * If MSR_SPEC_CTRL is available, apply Xen's default setting and discard
diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h
index 186eb8b..9925916 100644
--- a/xen/include/asm-x86/processor.h
+++ b/xen/include/asm-x86/processor.h
@@ -573,8 +573,7 @@ int guest_wrmsr_xen(struct vcpu *v, uint32_t idx, uint64_t val);
 
 void microcode_set_module(unsigned int);
 int microcode_update(XEN_GUEST_HANDLE_PARAM(const_void), unsigned long len);
-int microcode_resume_cpu(void);
-int early_microcode_update_cpu(bool start_update);
+int early_microcode_update_cpu(void);
 int early_microcode_init(void);
 int microcode_init_intel(void);
 int microcode_init_amd(void);
-- 
1.8.3.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

  parent reply	other threads:[~2019-03-11  7:53 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-03-11  7:57 [PATCH v6 00/12] improve late microcode loading Chao Gao
2019-03-11  7:57 ` [PATCH v6 01/12] misc/xenmicrocode: Upload a microcode blob to the hypervisor Chao Gao
2019-03-12 15:27   ` Roger Pau Monné
2019-03-13  5:05     ` Chao Gao
2019-03-13  9:24   ` Wei Liu
2019-03-25  9:38   ` Sergey Dyasli
2019-04-02  2:26     ` Chao Gao
2019-03-11  7:57 ` [PATCH v6 02/12] microcode/intel: use union to get fields without shifting and masking Chao Gao
2019-03-12 15:33   ` Roger Pau Monné
2019-03-12 16:43     ` Jan Beulich
2019-03-12 18:23       ` Wei Liu
2019-03-11  7:57 ` [PATCH v6 03/12] microcode/intel: extend microcode_update_match() Chao Gao
2019-03-11  7:57 ` [PATCH v6 04/12] microcode: introduce a global cache of ucode patch Chao Gao
2019-03-12 16:53   ` Roger Pau Monné
2019-03-12 23:31     ` Raj, Ashok
2019-03-13  5:28     ` Chao Gao
2019-03-13  7:39     ` Jan Beulich
2019-03-13 10:30       ` Andrew Cooper
2019-03-13 17:04         ` Andrew Cooper
2019-03-14  7:42           ` Jan Beulich
2019-03-13 16:36   ` Sergey Dyasli
2019-03-14  1:39     ` Chao Gao
2019-03-11  7:57 ` [PATCH v6 05/12] microcode: only save compatible ucode patches Chao Gao
2019-03-12 17:03   ` Roger Pau Monné
2019-03-13  7:45     ` Jan Beulich
2019-03-11  7:57 ` [PATCH v6 06/12] microcode: remove struct ucode_cpu_info Chao Gao
2019-03-11  7:57 ` [PATCH v6 07/12] microcode: remove pointless 'cpu' parameter Chao Gao
2019-03-11  7:57 ` Chao Gao [this message]
2019-03-11  7:57 ` [PATCH v6 09/12] microcode: remove struct microcode_info Chao Gao
2019-03-11  7:57 ` [PATCH v6 10/12] microcode/intel: Writeback and invalidate caches before updating microcode Chao Gao
2019-03-21 11:08   ` Sergey Dyasli
2019-03-11  7:57 ` [PATCH v6 11/12] x86/microcode: Synchronize late microcode loading Chao Gao
2019-03-13  0:07   ` Raj, Ashok
2019-03-13  5:02     ` Chao Gao
2019-03-13  7:54       ` Jan Beulich
2019-03-13  8:02         ` Jan Beulich
2019-03-14 12:39           ` Andrew Cooper
2019-03-14 18:57             ` Raj, Ashok
2019-03-14 20:25               ` Thomas Gleixner
2019-03-15  9:40                 ` Andrew Cooper
2019-03-15 10:44                   ` Thomas Gleixner
2019-03-14 13:01           ` Chao Gao
2019-03-14 13:08             ` Jan Beulich
2019-03-11  7:57 ` [PATCH v6 12/12] microcode: update microcode on cores in parallel Chao Gao
2019-03-21 12:24   ` [RFC PATCH v6 13/12] microcode: add sequential application policy Sergey Dyasli
2019-03-21 14:25     ` Chao Gao
2019-03-26 16:23     ` Jan Beulich
2019-03-19 20:22 ` [PATCH v6 00/12] improve late microcode loading Woods, Brian
2019-03-19 21:39   ` Woods, Brian
2019-03-20  8:58     ` Chao Gao

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1552291056-20286-9-git-send-email-chao.gao@intel.com \
    --to=chao.gao@intel.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=ashok.raj@intel.com \
    --cc=jbeulich@suse.com \
    --cc=roger.pau@citrix.com \
    --cc=sergey.dyasli@citrix.com \
    --cc=wei.liu2@citrix.com \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).