All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chao Gao <chao.gao@intel.com>
To: Jan Beulich <JBeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>,
	Wei Liu <wei.liu2@citrix.com>,
	xen-devel <xen-devel@lists.xenproject.org>,
	Roger Pau Monne <roger.pau@citrix.com>
Subject: Re: [PATCH v5 3/8] microcode: introduce the global microcode cache
Date: Mon, 11 Feb 2019 11:59:21 +0800	[thread overview]
Message-ID: <20190211035919.GA17802@gao-cwp> (raw)
In-Reply-To: <5C5D6ADF020000780021502D@prv1-mh.provo.novell.com>

On Fri, Feb 08, 2019 at 04:41:19AM -0700, Jan Beulich wrote:
>>>> On 28.01.19 at 08:06, <chao.gao@intel.com> wrote:
>> @@ -208,6 +210,58 @@ static void microcode_fini_cpu(unsigned int cpu)
>>      spin_unlock(&microcode_mutex);
>>  }
>>  
>> +/* Save a ucode patch to the global cache list */
>> +bool save_patch(struct microcode_patch *new_patch)
>> +{
>> +    struct microcode_patch *microcode_patch;
>> +
>> +    list_for_each_entry(microcode_patch, &microcode_cache, list)
>> +    {
>> +        enum microcode_match_result result =
>> +            microcode_ops->replace_patch(new_patch, microcode_patch);
>> +
>> +        switch ( result )
>> +        {
>> +        case OLD_UCODE:
>> +            microcode_ops->free_patch(new_patch);
>> +            return false;
>> +
>> +        case NEW_UCODE:
>> +            microcode_ops->free_patch(microcode_patch);
>> +            return true;
>> +
>> +        case MIS_UCODE:
>> +            continue;
>> +
>> +        default:
>> +            ASSERT_UNREACHABLE();
>> +            return 0;
>
>false (or true; either value is going to be fine/wrong here afaict)
>
>Anyway I'm having some difficulty seeing what the intended
>meaning of the return value is, and without that being clear I
>also can't make up my mind whether I agree with the cases
>here.

The return value means whether saving a ucode patch succeeded or failed.
In another word, it also means whether the ucode cache is updated or
not. According to the return value, the caller decides not to do the
expensive late ucode update for some cases (i.e. when admin provides a
old ucode).

>
>> +        }
>> +    }
>> +    list_add_tail(&new_patch->list, &microcode_cache);
>
>Hmm, you add _every_ patch producing MIS_UCODE to the list.
>This is going to be a long list then - there are over 100 blobs in
>the latest dropping, and this number is only going to grow.
>Saving blobs is useful only for cases where mixed steppings are
>actually supported. I guess that wouldn't go much beyond the
>stepping and/or "pf" differing, but family and model matching up.

We can introduce another type (i.e. MIX_UCODE) to denote the ucode
patch which mismatches any saved patches but only differs from current
cpu in stepping or "pf" (or model for AMD).

And save ucodes of MIX_UCODE type and discard ucodes of MIS_UCODE type.

Arch specific callback can determine the type (MIX_UCODE or MIS_UCODE)
according to the supported mixes.

>
>Additionally list management generally requires locking. This
>function doesn't even have a comment saying what lock(s) is
>(are) necessary to be held (same elsewhere).
>
>Finally please add blank lines ahead of the line above as well
>as (not just here) ahead of the main return statement of the
>function.

Will do

>
>> +/* Find a ucode patch who has newer revision than the one in use */
>> +struct microcode_patch *find_patch(unsigned int cpu)
>
>Is the caller allowed to alter the returned object? If not, you want
>to return a pointer to const.

No. Will constify the return value.

>
>> +{
>> +    struct microcode_patch *microcode_patch;
>> +    struct ucode_cpu_info *uci = &per_cpu(ucode_cpu_info, cpu);
>> +
>> +    if ( microcode_ops->collect_cpu_info(cpu, &uci->cpu_sig) )
>> +    {
>> +        __microcode_fini_cpu(cpu);
>
>This is kind of a library function - I can't see how it could legitimately
>invoke "fini", the more that you do here but not ...
>
>> +        return NULL;
>> +    }
>> +
>> +    list_for_each_entry(microcode_patch, &microcode_cache, list)
>> +    {
>> +        if ( microcode_ops->match_cpu(microcode_patch, cpu) )
>> +            return microcode_patch;
>> +    }
>> +    return NULL;
>
>... here.

My understanding is saving the cpu signature and ucode revision can
reduce MSR reads to get such information. So "fini" is invoked when
"collect" failed. The apply_microcode() following find_patch() can
access "uci" without invoking "collect" again.

>
>> +static enum microcode_match_result replace_patch(struct microcode_patch *new,
>> +                                                 struct microcode_patch *old)
>> +{
>> +    struct microcode_amd *new_mc = new->data;
>> +    struct microcode_header_amd *new_header = new_mc->mpb;
>> +    struct microcode_amd *old_mc = old->data;
>> +    struct microcode_header_amd *old_header = old_mc->mpb;
>
>const (all four of them afaict)
>
>> --- a/xen/arch/x86/microcode_intel.c
>> +++ b/xen/arch/x86/microcode_intel.c
>> @@ -147,6 +147,15 @@ static enum microcode_match_result microcode_update_match(
>>      return MIS_UCODE;
>>  }
>>  
>> +static bool match_cpu(const struct microcode_patch *patch, unsigned int cpu)
>> +{
>> +    struct ucode_cpu_info *uci = &per_cpu(ucode_cpu_info, cpu);
>
>const
>
>> +static enum microcode_match_result replace_patch(struct microcode_patch *new,
>> +                                                 struct microcode_patch *old)
>> +{
>> +    struct microcode_header_intel *old_header = old->data;
>
>const
>
>> +    enum microcode_match_result ret =
>> +                microcode_update_match(new->data, old_header->sig,
>> +                                       old_header->pf, old_header->rev);
>> +
>> +    if ( ret == NEW_UCODE )
>> +        list_replace(&old->list, &new->list);
>
>I think it would be better to leave actual list maintenance to generic
>code. That way the function parameters can also be pointer-to-const.

Will do.

>
>> @@ -248,6 +277,25 @@ static int get_matching_microcode(const void *mc, unsigned int cpu)
>>      const struct microcode_header_intel *mc_header = mc;
>>      unsigned long total_size = get_totalsize(mc_header);
>>      void *new_mc;
>> +    struct microcode_patch *microcode_patch = xmalloc(struct microcode_patch);
>> +    void *new_mc2 = xmalloc_bytes(total_size);
>
>Why don't you use the already existing new_mc here?

Will reuse the new_mc here.

>
>> @@ -276,18 +324,24 @@ static int apply_microcode(unsigned int cpu)
>>      unsigned int val[2];
>>      unsigned int cpu_num = raw_smp_processor_id();
>>      struct ucode_cpu_info *uci = &per_cpu(ucode_cpu_info, cpu_num);
>> +    struct microcode_intel *mc_intel;
>> +    struct microcode_patch *patch;
>>  
>>      /* We should bind the task to the CPU */
>>      BUG_ON(cpu_num != cpu);
>>  
>> -    if ( uci->mc.mc_intel == NULL )
>> +    patch = find_patch(cpu);
>> +    if ( !patch )
>>          return -EINVAL;
>>  
>> +    mc_intel = patch->data;
>> +    BUG_ON(!mc_intel);
>
>I'm not convinced this is a useful check - you never save_patch()
>anything that has a NULL pointer here. And general corruption might
>put bad values other than NULL into the field.

Then I will remove this check.

Thanks
Chao

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

  reply	other threads:[~2019-02-11  3:55 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 [this message]
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
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=20190211035919.GA17802@gao-cwp \
    --to=chao.gao@intel.com \
    --cc=JBeulich@suse.com \
    --cc=andrew.cooper3@citrix.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.