2022-12-27 19:52:01

by Ashok Raj

[permalink] [raw]
Subject: [PATCH v2 0/6] Some fixes and cleanups for microcode

Hi Boris

This is a followup after earlier post [1]
First 2 patches have been merged, sending the rest of the patches after
addressing comments and adding Thomas's reviewed by.

Please review and consider applying.

Changes since last post.

v2:
- Updated commit logs as suggested by Thomas and Boris
- Added Reviewed-by Thomas, and Tony

[1]https://lore.kernel.org/lkml/[email protected]/

Cheers,
Ashok

Ashok Raj (6):
x86/microcode/core: Move microcode_check() to cpu/microcode/core.c
x86/microcode/core: Take a snapshot before and after applying
microcode
x86/microcode: Display revisions only when update is successful
x86/microcode/intel: Use a plain revision argument for
print_ucode_rev()
x86/microcode/intel: Print old and new rev during early boot
x86/microcode/intel: Print when early microcode loading fails

arch/x86/include/asm/processor.h | 3 +-
arch/x86/kernel/cpu/cpu.h | 1 -
arch/x86/kernel/cpu/common.c | 32 --------------
arch/x86/kernel/cpu/microcode/core.c | 62 +++++++++++++++++++++++++--
arch/x86/kernel/cpu/microcode/intel.c | 52 +++++++++++-----------
5 files changed, 83 insertions(+), 67 deletions(-)


base-commit: 1b929c02afd37871d5afb9d498426f83432e71c2
--
2.34.1


2022-12-27 19:55:17

by Ashok Raj

[permalink] [raw]
Subject: [PATCH v2 1/6] x86/microcode/core: Move microcode_check() to cpu/microcode/core.c

microcode_check() is only called from microcode/core.c. Move it and make
it static to prepare for upcoming fix for false negative when checking CPU
features after a microcode update. Also move get_cpu_cap() to processor.h
for general use outside of arch/x86/kernel/cpu/cpu.h

No functional change.

Suggested-by: Alison Schofield <[email protected]>
Signed-off-by: Ashok Raj <[email protected]>
Reviewed-by: Thomas Gleixner <[email protected]>
Cc: LKML <[email protected]>
Cc: x86 <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: Dave Hansen <[email protected]>
Cc: Alison Schofield <[email protected]>
Cc: Reinette Chatre <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Tom Lendacky <[email protected]>
---
arch/x86/include/asm/processor.h | 3 +--
arch/x86/kernel/cpu/cpu.h | 1 -
arch/x86/kernel/cpu/common.c | 32 ----------------------------
arch/x86/kernel/cpu/microcode/core.c | 31 +++++++++++++++++++++++++++
4 files changed, 32 insertions(+), 35 deletions(-)

diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 4e35c66edeb7..70d01ecc39a4 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -182,8 +182,8 @@ extern const struct seq_operations cpuinfo_op;

#define cache_line_size() (boot_cpu_data.x86_cache_alignment)

+extern void get_cpu_cap(struct cpuinfo_x86 *c);
extern void cpu_detect(struct cpuinfo_x86 *c);
-
static inline unsigned long long l1tf_pfn_limit(void)
{
return BIT_ULL(boot_cpu_data.x86_cache_bits - 1 - PAGE_SHIFT);
@@ -697,7 +697,6 @@ bool xen_set_default_idle(void);
#endif

void __noreturn stop_this_cpu(void *dummy);
-void microcode_check(void);

enum l1tf_mitigations {
L1TF_MITIGATION_OFF,
diff --git a/arch/x86/kernel/cpu/cpu.h b/arch/x86/kernel/cpu/cpu.h
index 7c9b5893c30a..a142b8d543a3 100644
--- a/arch/x86/kernel/cpu/cpu.h
+++ b/arch/x86/kernel/cpu/cpu.h
@@ -63,7 +63,6 @@ static inline void tsx_ap_init(void) { }

extern void init_spectral_chicken(struct cpuinfo_x86 *c);

-extern void get_cpu_cap(struct cpuinfo_x86 *c);
extern void get_cpu_address_sizes(struct cpuinfo_x86 *c);
extern void cpu_detect_cache_sizes(struct cpuinfo_x86 *c);
extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c);
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 9cfca3d7d0e2..7b06034eeddc 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -2296,38 +2296,6 @@ void cpu_init_secondary(void)
}
#endif

-#ifdef CONFIG_MICROCODE_LATE_LOADING
-/*
- * The microcode loader calls this upon late microcode load to recheck features,
- * only when microcode has been updated. Caller holds microcode_mutex and CPU
- * hotplug lock.
- */
-void microcode_check(void)
-{
- struct cpuinfo_x86 info;
-
- perf_check_microcode();
-
- /* Reload CPUID max function as it might've changed. */
- info.cpuid_level = cpuid_eax(0);
-
- /*
- * Copy all capability leafs to pick up the synthetic ones so that
- * memcmp() below doesn't fail on that. The ones coming from CPUID will
- * get overwritten in get_cpu_cap().
- */
- memcpy(&info.x86_capability, &boot_cpu_data.x86_capability, sizeof(info.x86_capability));
-
- get_cpu_cap(&info);
-
- if (!memcmp(&info.x86_capability, &boot_cpu_data.x86_capability, sizeof(info.x86_capability)))
- return;
-
- pr_warn("x86/CPU: CPU features have changed after loading microcode, but might not take effect.\n");
- pr_warn("x86/CPU: Please consider either early loading through initrd/built-in or a potential BIOS update.\n");
-}
-#endif
-
/*
* Invoked from core CPU hotplug code after hotplug operations
*/
diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
index c4cd7328177b..0051ebf7c53e 100644
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -432,6 +432,37 @@ static int __reload_late(void *info)
return ret;
}

+/*
+ * The microcode loader calls this upon late microcode load to recheck features,
+ * only when microcode has been updated. Caller holds microcode_mutex and CPU
+ * hotplug lock.
+ */
+static void microcode_check(void)
+{
+ struct cpuinfo_x86 info;
+
+ perf_check_microcode();
+
+ /* Reload CPUID max function as it might've changed. */
+ info.cpuid_level = cpuid_eax(0);
+
+ /*
+ * Copy all capability leafs to pick up the synthetic ones so that
+ * memcmp() below doesn't fail on that. The ones coming from CPUID will
+ * get overwritten in get_cpu_cap().
+ */
+ memcpy(&info.x86_capability, &boot_cpu_data.x86_capability, sizeof(info.x86_capability));
+
+ get_cpu_cap(&info);
+
+ if (!memcmp(&info.x86_capability, &boot_cpu_data.x86_capability,
+ sizeof(info.x86_capability)))
+ return;
+
+ pr_warn("x86/CPU: CPU features have changed after loading microcode, but might not take effect.\n");
+ pr_warn("x86/CPU: Please consider either early loading through initrd/built-in or a potential BIOS update.\n");
+}
+
/*
* Reload microcode late on all CPUs. Wait for a sec until they
* all gather together.
--
2.34.1

2022-12-27 19:55:21

by Ashok Raj

[permalink] [raw]
Subject: [PATCH v2 3/6] x86/microcode: Display revisions only when update is successful

Right now, microcode loading failures and successes print the same
message "Reloading completed". This is misleading to users.

Display the updated revision number only if an update was successful.

Suggested-by: Thomas Gleixner <[email protected]>
Signed-off-by: Ashok Raj <[email protected]>
Reviewed-by: Tony Luck <[email protected]>
Link: https://lore.kernel.org/lkml/874judpqqd.ffs@tglx/
Cc: LKML <[email protected]>
Cc: x86 <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: Dave Hansen <[email protected]>
Cc: Alison Schofield <[email protected]>
Cc: Reinette Chatre <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Tom Lendacky <[email protected]>
---
arch/x86/kernel/cpu/microcode/core.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
index e2cdf3e989e7..e60cf0f66bf5 100644
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -500,11 +500,12 @@ static int microcode_reload_late(void)
store_cpu_caps(&info);

ret = stop_machine_cpuslocked(__reload_late, NULL, cpu_online_mask);
- if (ret == 0)
- microcode_check(&info);

- pr_info("Reload completed, microcode revision: 0x%x -> 0x%x\n",
- old, boot_cpu_data.microcode);
+ if (ret == 0) {
+ pr_info("Reload completed, microcode revision: 0x%x -> 0x%x\n",
+ old, boot_cpu_data.microcode);
+ microcode_check(&info);
+ }

return ret;
}
--
2.34.1

2022-12-27 19:56:02

by Ashok Raj

[permalink] [raw]
Subject: [PATCH v2 2/6] x86/microcode/core: Take a snapshot before and after applying microcode

The kernel caches features about each CPU's features at boot in an
x86_capability[] structure. The microcode update takes one snapshot and
compares it with the saved copy at boot.

However, the capabilities in the boot copy can be turned off as a result of
certain command line parameters or configuration restrictions. This can
cause a mismatch when comparing the values before and after the microcode
update.

microcode_check() is called after an update to report any previously
cached CPUID bits might have changed due to the update.

store_cpu_caps() basically stores the original CPU reported values and not
the OS modified values. This will avoid giving a false warning even if no
capabilities have changed.

Ignore the capabilities recorded at boot. Take a new snapshot before the
update and compare with a snapshot after the update to eliminate the false
warning.

Fixes: 1008c52c09dc ("x86/CPU: Add a microcode loader callback")
Signed-off-by: Ashok Raj <[email protected]>
Cc: LKML <[email protected]>
Cc: x86 <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: Dave Hansen <[email protected]>
Cc: Alison Schofield <[email protected]>
Cc: Reinette Chatre <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Tom Lendacky <[email protected]>
---
Changes since last post

- Boris : Change function from copy_cpu_caps() -> store_cpu_caps()
- Thomas : Commit log changes.
---
arch/x86/kernel/cpu/microcode/core.c | 42 +++++++++++++++++++++-------
1 file changed, 32 insertions(+), 10 deletions(-)

diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
index 0051ebf7c53e..e2cdf3e989e7 100644
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -432,12 +432,28 @@ static int __reload_late(void *info)
return ret;
}

+static void store_cpu_caps(struct cpuinfo_x86 *info)
+{
+ /* Reload CPUID max function as it might've changed. */
+ info->cpuid_level = cpuid_eax(0);
+
+ /*
+ * Copy all capability leafs to pick up the synthetic ones so that
+ * memcmp() below doesn't fail on that. The ones coming from CPUID will
+ * get overwritten in get_cpu_cap().
+ */
+ memcpy(info->x86_capability, &boot_cpu_data.x86_capability,
+ sizeof(info->x86_capability));
+
+ get_cpu_cap(info);
+}
+
/*
* The microcode loader calls this upon late microcode load to recheck features,
* only when microcode has been updated. Caller holds microcode_mutex and CPU
* hotplug lock.
*/
-static void microcode_check(void)
+static void microcode_check(struct cpuinfo_x86 *orig)
{
struct cpuinfo_x86 info;

@@ -447,15 +463,13 @@ static void microcode_check(void)
info.cpuid_level = cpuid_eax(0);

/*
- * Copy all capability leafs to pick up the synthetic ones so that
- * memcmp() below doesn't fail on that. The ones coming from CPUID will
- * get overwritten in get_cpu_cap().
- */
- memcpy(&info.x86_capability, &boot_cpu_data.x86_capability, sizeof(info.x86_capability));
+ * Copy all capability leafs to pick up the synthetic ones so that
+ * memcmp() below doesn't fail on that. The ones coming from CPUID will
+ * get overwritten in get_cpu_cap().
+ */
+ store_cpu_caps(&info);

- get_cpu_cap(&info);
-
- if (!memcmp(&info.x86_capability, &boot_cpu_data.x86_capability,
+ if (!memcmp(&info.x86_capability, &orig->x86_capability,
sizeof(info.x86_capability)))
return;

@@ -470,6 +484,7 @@ static void microcode_check(void)
static int microcode_reload_late(void)
{
int old = boot_cpu_data.microcode, ret;
+ struct cpuinfo_x86 info;

pr_err("Attempting late microcode loading - it is dangerous and taints the kernel.\n");
pr_err("You should switch to early loading, if possible.\n");
@@ -477,9 +492,16 @@ static int microcode_reload_late(void)
atomic_set(&late_cpus_in, 0);
atomic_set(&late_cpus_out, 0);

+ /*
+ * Take a snapshot before the microcode update, so we can compare
+ * them after the update is successful to check for any bits
+ * changed.
+ */
+ store_cpu_caps(&info);
+
ret = stop_machine_cpuslocked(__reload_late, NULL, cpu_online_mask);
if (ret == 0)
- microcode_check();
+ microcode_check(&info);

pr_info("Reload completed, microcode revision: 0x%x -> 0x%x\n",
old, boot_cpu_data.microcode);
--
2.34.1

2022-12-27 20:33:14

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH v2 1/6] x86/microcode/core: Move microcode_check() to cpu/microcode/core.c

On Tue, Dec 27, 2022 at 11:23:35AM -0800, Ashok Raj wrote:
> microcode_check() is only called from microcode/core.c. Move it and make
> it static to prepare for upcoming fix for false negative when checking CPU
> features after a microcode update. Also move get_cpu_cap() to processor.h
> for general use outside of arch/x86/kernel/cpu/cpu.h

I thought we agreed not to do this:

https://lore.kernel.org/r/Y44bbZMMf8I6Lzl/@zn.tnic

Or was this a misunderstanding?

--
Regards/Gruss,
Boris.

https://people.kernel.org/tglx/notes-about-netiquette

2022-12-27 20:34:50

by Ashok Raj

[permalink] [raw]
Subject: Re: [PATCH v2 1/6] x86/microcode/core: Move microcode_check() to cpu/microcode/core.c

On Tue, Dec 27, 2022 at 08:50:25PM +0100, Borislav Petkov wrote:
> On Tue, Dec 27, 2022 at 11:23:35AM -0800, Ashok Raj wrote:
> > microcode_check() is only called from microcode/core.c. Move it and make
> > it static to prepare for upcoming fix for false negative when checking CPU
> > features after a microcode update. Also move get_cpu_cap() to processor.h
> > for general use outside of arch/x86/kernel/cpu/cpu.h
>
> I thought we agreed not to do this:
>
> https://lore.kernel.org/r/Y44bbZMMf8I6Lzl/@zn.tnic
>
> Or was this a misunderstanding?

Bah... you are correct, I should drop this one.

I'll fix it up

Cheers,
Ashok

2022-12-27 21:12:06

by Ashok Raj

[permalink] [raw]
Subject: [PATCH v3 1/2] x86/microcode: Add a parameter to microcode_check() to store CPU capabilities

This is a preparation before the next patch uses this to compare CPU
capabilities after performing an update.

Add a parameter to store CPU capabilities before performing a microcode
update.

Signed-off-by: Ashok Raj <[email protected]>
Cc: LKML <[email protected]>
Cc: x86 <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: Dave Hansen <[email protected]>
Cc: Alison Schofield <[email protected]>
Cc: Reinette Chatre <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Tom Lendacky <[email protected]>
---
arch/x86/include/asm/processor.h | 2 +-
arch/x86/kernel/cpu/common.c | 12 +++++-------
arch/x86/kernel/cpu/microcode/core.c | 3 ++-
3 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 4e35c66edeb7..387578049de0 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -697,7 +697,7 @@ bool xen_set_default_idle(void);
#endif

void __noreturn stop_this_cpu(void *dummy);
-void microcode_check(void);
+void microcode_check(struct cpuinfo_x86 *info);

enum l1tf_mitigations {
L1TF_MITIGATION_OFF,
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 9cfca3d7d0e2..b9c7529c920e 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -2302,25 +2302,23 @@ void cpu_init_secondary(void)
* only when microcode has been updated. Caller holds microcode_mutex and CPU
* hotplug lock.
*/
-void microcode_check(void)
+void microcode_check(struct cpuinfo_x86 *info)
{
- struct cpuinfo_x86 info;
-
perf_check_microcode();

/* Reload CPUID max function as it might've changed. */
- info.cpuid_level = cpuid_eax(0);
+ info->cpuid_level = cpuid_eax(0);

/*
* Copy all capability leafs to pick up the synthetic ones so that
* memcmp() below doesn't fail on that. The ones coming from CPUID will
* get overwritten in get_cpu_cap().
*/
- memcpy(&info.x86_capability, &boot_cpu_data.x86_capability, sizeof(info.x86_capability));
+ memcpy(&info->x86_capability, &boot_cpu_data.x86_capability, sizeof(info->x86_capability));

- get_cpu_cap(&info);
+ get_cpu_cap(info);

- if (!memcmp(&info.x86_capability, &boot_cpu_data.x86_capability, sizeof(info.x86_capability)))
+ if (!memcmp(&info->x86_capability, &boot_cpu_data.x86_capability, sizeof(info->x86_capability)))
return;

pr_warn("x86/CPU: CPU features have changed after loading microcode, but might not take effect.\n");
diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
index c4cd7328177b..d86a4f910a6b 100644
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -439,6 +439,7 @@ static int __reload_late(void *info)
static int microcode_reload_late(void)
{
int old = boot_cpu_data.microcode, ret;
+ struct cpuinfo_x86 info;

pr_err("Attempting late microcode loading - it is dangerous and taints the kernel.\n");
pr_err("You should switch to early loading, if possible.\n");
@@ -448,7 +449,7 @@ static int microcode_reload_late(void)

ret = stop_machine_cpuslocked(__reload_late, NULL, cpu_online_mask);
if (ret == 0)
- microcode_check();
+ microcode_check(&info);

pr_info("Reload completed, microcode revision: 0x%x -> 0x%x\n",
old, boot_cpu_data.microcode);
--
2.34.1

2022-12-27 22:24:16

by Ashok Raj

[permalink] [raw]
Subject: [PATCH v3 2/2] x86/microcode/core: Take a snapshot before and after applying microcode

The kernel caches features about each CPU's features at boot in an
x86_capability[] structure. The microcode update takes one snapshot and
compares it with the saved copy at boot.

However, the capabilities in the boot copy can be turned off as a result of
certain command line parameters or configuration restrictions. This can
cause a mismatch when comparing the values before and after the microcode
update.

microcode_check() is called after an update to report any previously
cached CPUID bits might have changed due to the update.

microcode_store_cpu_caps() basically stores the original CPU reported
values and not the OS modified values. This will avoid giving a false
warning even if no capabilities have changed.

Ignore the capabilities recorded at boot. Take a new snapshot before the
update and compare with a snapshot after the update to eliminate the false
warning.

Fixes: 1008c52c09dc ("x86/CPU: Add a microcode loader callback")
Signed-off-by: Ashok Raj <[email protected]>
Cc: LKML <[email protected]>
Cc: x86 <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: Dave Hansen <[email protected]>
Cc: Alison Schofield <[email protected]>
Cc: Reinette Chatre <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Tom Lendacky <[email protected]>
---
Changes since last post

- Boris
- Change function from copy_cpu_caps() -> store_cpu_caps()
- Keep microcode_check() inside cpu/common.c and not bleed
get_cpu_caps() outside of core code.

- Thomas : Commit log changes.
---
arch/x86/include/asm/processor.h | 1 +
arch/x86/kernel/cpu/common.c | 17 +++++++++++++++++
arch/x86/kernel/cpu/microcode/core.c | 7 +++++++
3 files changed, 25 insertions(+)

diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 387578049de0..ac2e67156b9b 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -697,6 +697,7 @@ bool xen_set_default_idle(void);
#endif

void __noreturn stop_this_cpu(void *dummy);
+void microcode_store_cpu_caps(struct cpuinfo_x86 *info);
void microcode_check(struct cpuinfo_x86 *info);

enum l1tf_mitigations {
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index b9c7529c920e..1f0b57a5d89d 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -2297,6 +2297,23 @@ void cpu_init_secondary(void)
#endif

#ifdef CONFIG_MICROCODE_LATE_LOADING
+
+void microcode_store_cpu_caps(struct cpuinfo_x86 *info)
+{
+ /* Reload CPUID max function as it might've changed. */
+ info->cpuid_level = cpuid_eax(0);
+
+ /*
+ * Copy all capability leafs to pick up the synthetic ones so that
+ * memcmp() below doesn't fail on that. The ones coming from CPUID will
+ * get overwritten in get_cpu_cap().
+ */
+ memcpy(info->x86_capability, &boot_cpu_data.x86_capability,
+ sizeof(info->x86_capability));
+
+ get_cpu_cap(info);
+}
+
/*
* The microcode loader calls this upon late microcode load to recheck features,
* only when microcode has been updated. Caller holds microcode_mutex and CPU
diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
index d86a4f910a6b..14d9031ed68a 100644
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -447,6 +447,13 @@ static int microcode_reload_late(void)
atomic_set(&late_cpus_in, 0);
atomic_set(&late_cpus_out, 0);

+ /*
+ * Take a snapshot before the microcode update, so we can compare
+ * them after the update is successful to check for any bits
+ * changed.
+ */
+ microcode_store_cpu_caps(&info);
+
ret = stop_machine_cpuslocked(__reload_late, NULL, cpu_online_mask);
if (ret == 0)
microcode_check(&info);
--
2.34.1

2022-12-28 18:44:09

by Ashok Raj

[permalink] [raw]
Subject: Re: [PATCH v3 2/2] x86/microcode/core: Take a snapshot before and after applying microcode

On Tue, Dec 27, 2022 at 01:01:44PM -0800, Ashok Raj wrote:
> The kernel caches features about each CPU's features at boot in an
> x86_capability[] structure. The microcode update takes one snapshot and
> compares it with the saved copy at boot.
>
> However, the capabilities in the boot copy can be turned off as a result of
> certain command line parameters or configuration restrictions. This can
> cause a mismatch when comparing the values before and after the microcode
> update.
>
> microcode_check() is called after an update to report any previously
> cached CPUID bits might have changed due to the update.
>

I'll send you a clean version. Somehow this picked up an interim change and
the change to microcode_check() is not there. I remember testing but it
happened to be a different system I updated.

I'll send something after the new years.. working during holidays isn't
efficient :-(.


Cheers,
Ashok