From: Chao Gao <chao.gao@intel.com>
To: "Roger Pau Monné" <roger.pau@citrix.com>
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>,
xen-devel@lists.xenproject.org
Subject: Re: [PATCH v6 04/12] microcode: introduce a global cache of ucode patch
Date: Wed, 13 Mar 2019 13:28:01 +0800 [thread overview]
Message-ID: <20190313052800.GC24657@gao-cwp> (raw)
In-Reply-To: <20190312165353.j6fj53ho2y6rcxzr@Air-de-Roger>
Thanks for your great suggestion.
On Tue, Mar 12, 2019 at 05:53:53PM +0100, Roger Pau Monné wrote:
>On Mon, Mar 11, 2019 at 03:57:28PM +0800, Chao Gao wrote:
>> to replace the current per-cpu cache 'uci->mc'.
>>
>> Compared to the current per-cpu cache, the benefits of the global
>> microcode cache are:
>> 1. It reduces the work that need to be done on each CPU. Parsing ucode
>> file is done once on one CPU. Other CPUs needn't parse ucode file.
>> Instead, they can find out and load the newest patch from the global
>> cache.
>> 2. It reduces the memory consumption on a system with many CPU cores.
>>
>> Two functions, microcode_save_patch() and microcode_find_patch() are
>> introduced. The former adds one given patch to the global cache. The
>> latter gets a newer and matched ucode patch from the global cache.
>> All operations on the cache is expected to be done with the
>> 'microcode_mutex' hold.
>>
>> Note that I deliberately avoid touching 'uci->mc' as I am going to
>> remove it completely in the next patch.
>>
>> Signed-off-by: Chao Gao <chao.gao@intel.com>
>> ---
>> Changes in v6:
>> - constify local variables and function parameters if possible
>> - comment that the global cache is protected by 'microcode_mutex'.
>> and add assertions to catch violations in microcode_{save/find}_patch()
>>
>> Changes in v5:
>> - reword the commit description
>> - find_patch() and save_patch() are abstracted into common functions
>> with some hooks for AMD and Intel
>> ---
>> xen/arch/x86/microcode.c | 60 +++++++++++++++++++++++++++
>> xen/arch/x86/microcode_amd.c | 91 +++++++++++++++++++++++++++++++++++++----
>> xen/arch/x86/microcode_intel.c | 66 ++++++++++++++++++++++++++----
>> xen/include/asm-x86/microcode.h | 13 ++++++
>> 4 files changed, 215 insertions(+), 15 deletions(-)
>>
>> diff --git a/xen/arch/x86/microcode.c b/xen/arch/x86/microcode.c
>> index 4163f50..e629e6c 100644
>> --- a/xen/arch/x86/microcode.c
>> +++ b/xen/arch/x86/microcode.c
>> @@ -61,6 +61,8 @@ static struct ucode_mod_blob __initdata ucode_blob;
>> */
>> static bool_t __initdata ucode_scan;
>>
>> +static LIST_HEAD(microcode_cache);
>> +
>> void __init microcode_set_module(unsigned int idx)
>> {
>> ucode_mod_idx = idx;
>> @@ -208,6 +210,64 @@ static void microcode_fini_cpu(unsigned int cpu)
>> spin_unlock(µcode_mutex);
>> }
>>
>> +/*
>> + * Save an ucode patch to the global cache list.
>> + *
>> + * Return true if a patch is added to the global cache or it replaces
>> + * one old patch in the cache. Otherwise, return false. According to
>> + * the return value, the caller decides not to do an expensive ucode
>> + * update for some cases (i.e. when admin provides an old ucode).
>> + */
>> +bool microcode_save_patch(struct microcode_patch *new)
>> +{
>> + struct microcode_patch *old;
>> +
>> + ASSERT(spin_is_locked(µcode_mutex));
>> +
>> + list_for_each_entry(old, µcode_cache, list)
>> + {
>> + enum microcode_match_result result =
>> + microcode_ops->compare_patch(new, old);
>> +
>> + if ( result == OLD_UCODE )
>> + {
>> + microcode_ops->free_patch(new);
>> + return false;
>> + }
>> + else if ( result == NEW_UCODE )
>> + {
>> + list_replace(&old->list, &new->list);
>> + microcode_ops->free_patch(old);
>> + return true;
>> + }
>> + else /* result == MIS_UCODE */
>> + continue;
>
>I think this is rather too simplistic, and I'm not sure you really
>need a list in order to store the microcodes.
>
>IIRC we agreed that systems with mixed CPU versions are not supported,
In previous version, I also mentioned that one instance might be enough.
(two instances considering the concern you elaborated below)
But I was told that it would be better to support mixed CPUs if they are
allowed by Intel or AMD. And the old per-cpu cache, IMO, also supports
mixed CPUs.
If now we don't want to support it any longer, I agree to your proposal.
I will defer to Jan's opinion.
Thanks
Chao
>hence the same microcode blob should be used to update all the
>possible CPUs on the system, so a list should not be needed here.
>
>Also I'm afraid that freeing the old microcode when a new version is
>uploaded is not fully correct. For example given the following
>scenario:
>
>1. Upload a microcode blob to the hypervisor and apply it to online
>CPUs.
>
>2. Upload a microcode blob with a higher version than the previous one,
>but which fails to apply. This microcode would replace the
>previous one.
>
>3. Online a CPU. This CPU will try to use the last uploaded microcode
>and fail, because last uploaded version is broken. Newly onlined CPUs
>would then end up with a microcode version different from the
>currently running CPUs, likely breaking the system.
>
>I think the best way to solve this is to ditch the list usage and
>instead only keep at most two microcode versions cached in the
>hypervisor:
>
> - The microcode version that's currently successfully applied (if any).
> - A microcode version higher than the current version, that has yet
> to be applied.
>
>Once this new microcode version has been applied it will replace the
>previously applied version. If the new microcode version fails to
>apply it will be discarded, thus keeping a copy of the currently
>applied microcode version.
>
>With this approach AFAICT you only need two variables, one to store
>the currently applied microcode_patch and another one to save the new
>microcode version in order to attempt to apply it.
>
>I think this will also simplify some of the code. Let me know if this
>sounds sensible, or if I'm missing something.
>
>Thanks, Roger.
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
next prev parent reply other threads:[~2019-03-13 5:23 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 [this message]
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 ` [PATCH v6 08/12] microcode: split out apply_microcode() from cpu_request_microcode() Chao Gao
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=20190313052800.GC24657@gao-cwp \
--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).