All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Roger Pau Monné" <roger.pau@citrix.com>
To: Chao Gao <chao.gao@intel.com>
Cc: xen-devel@lists.xenproject.org, Wei Liu <wei.liu2@citrix.com>,
	Jan Beulich <jbeulich@suse.com>,
	Andrew Cooper <andrew.cooper3@citrix.com>
Subject: Re: [PATCH v5 5/8] microcode: split out apply_microcode() from cpu_request_microcode()
Date: Tue, 29 Jan 2019 10:58:11 +0100	[thread overview]
Message-ID: <20190129095811.j3q5fudvobsrhjca@mac> (raw)
In-Reply-To: <1548659210-16870-6-git-send-email-chao.gao@intel.com>

On Mon, Jan 28, 2019 at 03:06:47PM +0800, Chao Gao wrote:
> 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 also moved to the
> end of apply_microcode().
> 
> Signed-off-by: Chao Gao <chao.gao@intel.com>
> ---
>  xen/arch/x86/microcode.c       | 80 +++++++++++++++++++++++++-----------------
>  xen/arch/x86/microcode_amd.c   | 23 +++++++-----
>  xen/arch/x86/microcode_intel.c | 20 ++---------
>  3 files changed, 64 insertions(+), 59 deletions(-)
> 
> diff --git a/xen/arch/x86/microcode.c b/xen/arch/x86/microcode.c
> index 0c77e90..936f0b8 100644
> --- a/xen/arch/x86/microcode.c
> +++ b/xen/arch/x86/microcode.c
> @@ -254,47 +254,42 @@ struct microcode_patch *find_patch(unsigned int cpu)
>      return NULL;
>  }
>  
> -int microcode_resume_cpu(unsigned int cpu)
> +/*
> + * Return the number of ucode patch inserted to the global cache.
> + * Return negtive value on error.
> + */
> +static int parse_microcode_blob(const void *buffer, size_t len)
>  {
> -    int err;
> +    unsigned int cpu = smp_processor_id();
>      struct ucode_cpu_info *uci = &per_cpu(ucode_cpu_info, cpu);
> -
> -    if ( !microcode_ops )
> -        return 0;
> +    int ret;
>  
>      spin_lock(&microcode_mutex);
> -
> -    err = microcode_ops->collect_cpu_info(cpu, &uci->cpu_sig);
> -    if ( err )
> -    {
> +    ret = microcode_ops->collect_cpu_info(cpu, &uci->cpu_sig);
> +    if ( likely(!ret) )
> +        ret = microcode_ops->cpu_request_microcode(cpu, buffer, len);
> +    else
>          microcode_fini_cpu(cpu);
> -        spin_unlock(&microcode_mutex);
> -        return err;
> -    }
> -
> -    err = microcode_ops->apply_microcode(cpu);
>      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 ucode_cpu_info *uci = &per_cpu(ucode_cpu_info, cpu);
> +    int ret;
>  
>      spin_lock(&microcode_mutex);
> -
> -    err = microcode_ops->collect_cpu_info(cpu, &uci->cpu_sig);
> -    if ( likely(!err) )
> -        err = microcode_ops->cpu_request_microcode(cpu, buf, size);
> -    else
> -        microcode_fini_cpu(cpu);
> -
> +    ret = microcode_ops->apply_microcode(smp_processor_id());

I've realized that most of this helpers take a cpu id parameter
(apply_microcode, collect_cpu_info and cpu_request_microcode), but
that at least on Intel they are required to be called on the current
CPU, at which point I wonder about their purpose. IMO they just make
the interface more messy, without adding any functionality.

>      spin_unlock(&microcode_mutex);
>  
> -    return err;
> +    return ret;
> +}
> +
> +int microcode_resume_cpu(unsigned int cpu)
> +{
> +    BUG_ON(cpu != smp_processor_id());

Same here, what's the point of passing a cpu id as parameter when
there's only one valid value?

> +    return microcode_ops ? microcode_update_cpu() : 0;
>  }
>  
>  static long do_microcode_update(void *_info)
> @@ -304,7 +299,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;
>  
> @@ -339,10 +334,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();
> @@ -353,6 +344,18 @@ int microcode_update(XEN_GUEST_HANDLE_PARAM(const_void) buf, unsigned long len)
>          }
>      }
>  
> +    ret = parse_microcode_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);

It looks like you can also get rid of the cpu field in microcode_info,
since it's always smp_processor_id?

> +
>      return continue_hypercall_on_cpu(info->cpu, do_microcode_update, info);
>  }
>  
> @@ -396,13 +399,24 @@ int __init early_microcode_update_cpu(bool start_update)
>      }
>      if ( data )
>      {
> +        static bool parsed = false;
> +
>          if ( start_update && microcode_ops->start_update )
>              rc = microcode_ops->start_update();
>  
>          if ( rc )
>              return rc;
>  
> -        return microcode_update_cpu(data, len);
> +        if ( !parsed )
> +        {
> +            rc = parse_microcode_blob(data, len);
> +            parsed = true;
> +
> +            if ( rc <= 0 )
> +                return -EINVAL;
> +        }
> +
> +        return microcode_update_cpu();

Hm, the usage of parsed here is kind of dangerous. I assume this works
fine because early_microcode_update_cpu is called from the BSP in
early_microcode_init, and then concurrent calls done by the APs always
see parsed as true.

I would however recommend that you move the parsing to
early_microcode_init, and that early_microcode_update_cpu always
assume the blob has been parsed.

If that doesn't work for some reason, I would then recommend that you
gate the parsing based on cpu_id, so "smp_processor_id() == 0"

>      }
>      else
>          return -ENOMEM;
> diff --git a/xen/arch/x86/microcode_amd.c b/xen/arch/x86/microcode_amd.c
> index d86a596..80e274e 100644
> --- a/xen/arch/x86/microcode_amd.c
> +++ b/xen/arch/x86/microcode_amd.c
> @@ -297,6 +297,10 @@ static int apply_microcode(unsigned int cpu)
>  
>      uci->cpu_sig.rev = rev;
>  
> +#if CONFIG_HVM
> +    svm_host_osvw_init();
> +#endif
> +
>      return 0;
>  }
>  
> @@ -463,6 +467,7 @@ static int cpu_request_microcode(unsigned int cpu, const void *buf,
>      struct ucode_cpu_info *uci = &per_cpu(ucode_cpu_info, cpu);
>      unsigned int current_cpu_id;
>      unsigned int equiv_cpu_id;
> +    unsigned int matched_cnt = 0;
>  
>      /* We should bind the task to the CPU */
>      BUG_ON(cpu != raw_smp_processor_id());
> @@ -564,11 +569,15 @@ static int cpu_request_microcode(unsigned int cpu, const void *buf,
>           * this ucode patch before checking whether it matches with
>           * current CPU.
>           */
> -        if ( save_patch(microcode_patch) && microcode_fits(mc_amd, cpu) )
> +        if ( save_patch(microcode_patch) )
>          {
> -            error = apply_microcode(cpu);
> -            if ( error )
> -                break;
> +            matched_cnt++;
> +            if ( microcode_fits(mc_amd, cpu) )
> +            {
> +                error = apply_microcode(cpu);
> +                if ( error )
> +                    break;
> +            }

In the commit message you mention that apply_microcode won't be called
by cpu_request_microcode, yet it seems it's called?

Thanks, Roger.

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

  reply	other threads:[~2019-01-29  9:58 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-28  7:06 [PATCH v5 0/8] improve late microcode loading Chao Gao
2019-01-28  7:06 ` [PATCH v5 1/8] microcode/intel: remove redundent check against ucode size Chao Gao
2019-01-28 16:40   ` Roger Pau Monné
2019-01-29 10:26   ` Jan Beulich
2019-01-29 13:34     ` Chao Gao
2019-01-28  7:06 ` [PATCH v5 2/8] microcode/intel: extend microcode_update_match() Chao Gao
2019-01-28 16:55   ` Roger Pau Monné
2019-01-28 17:00     ` Jan Beulich
2019-01-29 10:41   ` Jan Beulich
2019-01-29 13:52     ` Chao Gao
2019-01-28  7:06 ` [PATCH v5 3/8] microcode: introduce the global microcode cache Chao Gao
2019-01-28 17:39   ` Roger Pau Monné
2019-01-29  4:41     ` Chao Gao
2019-01-29  8:56       ` Roger Pau Monné
2019-02-08 11:41   ` Jan Beulich
2019-02-11  3:59     ` Chao Gao
2019-02-11 13:16       ` Jan Beulich
2019-01-28  7:06 ` [PATCH v5 4/8] microcode: delete 'mc' field from struct ucode_cpu_info Chao Gao
2019-01-29  9:25   ` Roger Pau Monné
2019-01-29 13:27     ` Chao Gao
2019-01-28  7:06 ` [PATCH v5 5/8] microcode: split out apply_microcode() from cpu_request_microcode() Chao Gao
2019-01-29  9:58   ` Roger Pau Monné [this message]
2019-01-29 12:47     ` Chao Gao
2019-02-08 15:58   ` Jan Beulich
2019-01-28  7:06 ` [PATCH v5 6/8] microcode: delete microcode pointer and size from microcode_info Chao Gao
2019-01-29 10:10   ` Roger Pau Monné
2019-01-29 14:11     ` Chao Gao
2019-01-28  7:06 ` [PATCH v5 7/8] x86/microcode: Synchronize late microcode loading Chao Gao
2019-01-29 10:37   ` Roger Pau Monné
2019-01-29 10:45     ` Jan Beulich
2019-01-30 13:44     ` Chao Gao
2019-02-08 16:29   ` Jan Beulich
2019-02-11  5:40     ` Chao Gao
2019-02-11 13:23       ` Jan Beulich
2019-02-11 13:35         ` Juergen Gross
2019-02-11 15:28           ` Raj, Ashok
2019-02-11 16:49           ` Jan Beulich
2019-01-28  7:06 ` [PATCH v5 8/8] microcode: update microcode on cores in parallel Chao Gao
2019-01-29 11:27   ` Roger Pau Monné
2019-01-30 13:36     ` Chao Gao
2019-02-12 12:51   ` Jan Beulich
2019-02-12 13:25     ` Roger Pau Monné
2019-02-12 13:55       ` Jan Beulich
2019-02-13  2:30         ` Chao Gao
2019-02-13  7:20           ` Jan Beulich
2019-02-13  8:50             ` Chao Gao
2019-02-13 10:05               ` Jan Beulich
2019-01-29 11:31 ` [PATCH v5 0/8] improve late microcode loading Roger Pau Monné
2019-01-29 12:11   ` Chao Gao
2019-01-29 14:17     ` Roger Pau Monné

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=20190129095811.j3q5fudvobsrhjca@mac \
    --to=roger.pau@citrix.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=chao.gao@intel.com \
    --cc=jbeulich@suse.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.