diff mbox series

[v8,02/16] x86/microcode: always collect_cpu_info() during boot

Message ID 1564654971-31328-3-git-send-email-chao.gao@intel.com (mailing list archive)
State Superseded
Headers show
Series improve late microcode loading | expand

Commit Message

Chao Gao Aug. 1, 2019, 10:22 a.m. UTC
From: Sergey Dyasli <sergey.dyasli@citrix.com>

Currently cpu_sig struct is not updated during boot if no microcode blob
is specified by "ucode=[<interger>| scan]".

It will result in cpu_sig.rev being 0 which affects APIC's
check_deadline_errata() and retpoline_safe() functions.

Fix this by getting ucode revision early during boot and SMP bring up.
While at it, protect early_microcode_update_cpu() for cases when
microcode_ops is NULL.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Signed-off-by: Chao Gao <chao.gao@intel.com>
---
Changes in v8:
 - refine description.
 - Jan asked if we could drop the call of collect_cpu_info() from
 microcode_update_cpu(). In theory, yes, but should be placed later
 in the series. Because there is an error path (__microcode_fini_cpu())
 in which cpu_sig.rev is cleared, it is hard to make things right
 in all cases without removing the error path (which is done by following
 patches). Considering it is a good fix, put it here so that it can
 be merged without following patches.
---
 xen/arch/x86/microcode.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

Comments

Andrew Cooper Aug. 1, 2019, 10:35 a.m. UTC | #1
On 01/08/2019 11:22, Chao Gao wrote:
> From: Sergey Dyasli <sergey.dyasli@citrix.com>
>
> Currently cpu_sig struct is not updated during boot if no microcode blob
> is specified by "ucode=[<interger>| scan]".
>
> It will result in cpu_sig.rev being 0 which affects APIC's
> check_deadline_errata() and retpoline_safe() functions.
>
> Fix this by getting ucode revision early during boot and SMP bring up.
> While at it, protect early_microcode_update_cpu() for cases when
> microcode_ops is NULL.
>
> Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
> Signed-off-by: Chao Gao <chao.gao@intel.com>
> ---
> Changes in v8:
>  - refine description.
>  - Jan asked if we could drop the call of collect_cpu_info() from
>  microcode_update_cpu(). In theory, yes, but should be placed later
>  in the series. Because there is an error path (__microcode_fini_cpu())
>  in which cpu_sig.rev is cleared, it is hard to make things right
>  in all cases without removing the error path (which is done by following
>  patches). Considering it is a good fix, put it here so that it can
>  be merged without following patches.

Ok.

Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>, and this does
really want backporting.
Jan Beulich Aug. 2, 2019, 1:23 p.m. UTC | #2
On 01.08.2019 12:22, Chao Gao wrote:
> --- a/xen/arch/x86/microcode.c
> +++ b/xen/arch/x86/microcode.c
> @@ -383,10 +383,15 @@ static struct notifier_block microcode_percpu_nfb = {
>   
>   int __init early_microcode_update_cpu(bool start_update)
>   {
> +    unsigned int cpu = smp_processor_id();
> +    struct ucode_cpu_info *uci = &per_cpu(ucode_cpu_info, cpu);
>       int rc = 0;
>       void *data = NULL;
>       size_t len;
>   
> +    if ( !microcode_ops )
> +        return -ENOSYS;

For posterity (realizing the patch has gone in already) - I'm not
convinced this should be an error condition, but the error
produced here is being ignored anyway afaics (i.e. the function
could as well return void). In no case is this an appropriate use
of ENOSYS: This isn't even on a hypercall path.

Jan
diff mbox series

Patch

diff --git a/xen/arch/x86/microcode.c b/xen/arch/x86/microcode.c
index 4163f50..421d57e 100644
--- a/xen/arch/x86/microcode.c
+++ b/xen/arch/x86/microcode.c
@@ -383,10 +383,15 @@  static struct notifier_block microcode_percpu_nfb = {
 
 int __init early_microcode_update_cpu(bool start_update)
 {
+    unsigned int cpu = smp_processor_id();
+    struct ucode_cpu_info *uci = &per_cpu(ucode_cpu_info, cpu);
     int rc = 0;
     void *data = NULL;
     size_t len;
 
+    if ( !microcode_ops )
+        return -ENOSYS;
+
     if ( ucode_blob.size )
     {
         len = ucode_blob.size;
@@ -397,6 +402,9 @@  int __init early_microcode_update_cpu(bool start_update)
         len = ucode_mod.mod_end;
         data = bootstrap_map(&ucode_mod);
     }
+
+    microcode_ops->collect_cpu_info(cpu, &uci->cpu_sig);
+
     if ( data )
     {
         if ( start_update && microcode_ops->start_update )
@@ -413,6 +421,8 @@  int __init early_microcode_update_cpu(bool start_update)
 
 int __init early_microcode_init(void)
 {
+    unsigned int cpu = smp_processor_id();
+    struct ucode_cpu_info *uci = &per_cpu(ucode_cpu_info, cpu);
     int rc;
 
     rc = microcode_init_intel();
@@ -425,6 +435,8 @@  int __init early_microcode_init(void)
 
     if ( microcode_ops )
     {
+        microcode_ops->collect_cpu_info(cpu, &uci->cpu_sig);
+
         if ( ucode_mod.mod_end || ucode_blob.size )
             rc = early_microcode_update_cpu(true);