All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chao Gao <chao.gao@intel.com>
To: "Roger Pau Monné" <roger.pau@citrix.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 20:47:07 +0800	[thread overview]
Message-ID: <20190129124705.GA8249@gao-cwp> (raw)
In-Reply-To: <20190129095811.j3q5fudvobsrhjca@mac>

On Tue, Jan 29, 2019 at 10:58:11AM +0100, Roger Pau Monné wrote:
>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.

I agree with you and will remove the 'cpu' parameter from the interfaces
you mentioned above.

>
>>      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?

Yes. Will remove the 'cpu' field.

>
>> +
>>      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 think APs are woken up one-by-one. See the call site of cpu_up in
__start_xen.

>
>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"

Do you think it is better:
remove the parsed flag and check whether current cpu is bsp in
early_microcode_init(); bsp calls the early_microcode_update_cpu(). APs
just call microcode_update_cpu().

>
>>      }
>>      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?

lines below "matched_cnt++" should be removed. They slipped in when I
did a rebasing.

Thanks
Chao

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

  reply	other threads:[~2019-01-29 12:43 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é
2019-01-29 12:47     ` Chao Gao [this message]
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=20190129124705.GA8249@gao-cwp \
    --to=chao.gao@intel.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=jbeulich@suse.com \
    --cc=roger.pau@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 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.