x86/microcode/amd: Extract current patch level read to a function
Pave the way for checking the current patch level of the microcode in a core. We want to be able to do stuff depending on the patch level - in this case decide whether to update or not. But that will be added in a later patch. Drop unused local var uci assignment, while at it. Integrate a fix for 32-bit and CONFIG_PARAVIRT from Takashi Iwai: Use native_rdmsr() in check_current_patch_level() because with CONFIG_PARAVIRT enabled and on 32-bit, where we run before paging has been enabled, we cannot deref pv_info yet. Or we could, but we'd need to access its physical address. This way of fixing it is simpler. See: https://bugzilla.suse.com/show_bug.cgi?id=943179 for the background. Signed-off-by: Borislav Petkov <bp@suse.de> Cc: Borislav Petkov <bp@alien8.de> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Takashi Iwai <tiwai@suse.com>: Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Tony Luck <tony.luck@intel.com> Link: http://lkml.kernel.org/r/1444641762-9437-6-git-send-email-bp@alien8.de Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
parent
fa20a2ed6f
commit
2eff73c0a1
@ -76,4 +76,5 @@ static inline int __init save_microcode_in_initrd_amd(void) { return -EINVAL; }
|
||||
void reload_ucode_amd(void) {}
|
||||
#endif
|
||||
|
||||
extern bool check_current_patch_level(u32 *rev);
|
||||
#endif /* _ASM_X86_MICROCODE_AMD_H */
|
||||
|
@ -177,6 +177,25 @@ static unsigned int verify_patch_size(u8 family, u32 patch_size,
|
||||
return patch_size;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the current patch level on this CPU.
|
||||
*
|
||||
* @rev: Use it to return the patch level. It is set to 0 in the case of
|
||||
* error.
|
||||
*
|
||||
* Returns:
|
||||
* - true: if update should stop
|
||||
* - false: otherwise
|
||||
*/
|
||||
bool check_current_patch_level(u32 *rev)
|
||||
{
|
||||
u32 dummy;
|
||||
|
||||
native_rdmsr(MSR_AMD64_PATCH_LEVEL, *rev, dummy);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int __apply_microcode_amd(struct microcode_amd *mc_amd)
|
||||
{
|
||||
u32 rev, dummy;
|
||||
@ -197,7 +216,7 @@ int apply_microcode_amd(int cpu)
|
||||
struct microcode_amd *mc_amd;
|
||||
struct ucode_cpu_info *uci;
|
||||
struct ucode_patch *p;
|
||||
u32 rev, dummy;
|
||||
u32 rev;
|
||||
|
||||
BUG_ON(raw_smp_processor_id() != cpu);
|
||||
|
||||
@ -210,7 +229,8 @@ int apply_microcode_amd(int cpu)
|
||||
mc_amd = p->data;
|
||||
uci->mc = p->data;
|
||||
|
||||
rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
|
||||
if (check_current_patch_level(&rev))
|
||||
return -1;
|
||||
|
||||
/* need to apply patch? */
|
||||
if (rev >= mc_amd->hdr.patch_id) {
|
||||
|
@ -196,9 +196,8 @@ static void apply_ucode_in_initrd(void *ucode, size_t size, bool save_patch)
|
||||
return;
|
||||
}
|
||||
|
||||
/* find ucode and update if needed */
|
||||
|
||||
native_rdmsr(MSR_AMD64_PATCH_LEVEL, rev, eax);
|
||||
if (check_current_patch_level(&rev))
|
||||
return;
|
||||
|
||||
while (left > 0) {
|
||||
struct microcode_amd *mc;
|
||||
@ -319,7 +318,6 @@ static void __init get_bsp_sig(void)
|
||||
void load_ucode_amd_ap(void)
|
||||
{
|
||||
unsigned int cpu = smp_processor_id();
|
||||
struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
|
||||
struct equiv_cpu_entry *eq;
|
||||
struct microcode_amd *mc;
|
||||
u32 rev, eax;
|
||||
@ -332,10 +330,8 @@ void load_ucode_amd_ap(void)
|
||||
if (!container)
|
||||
return;
|
||||
|
||||
rdmsr(MSR_AMD64_PATCH_LEVEL, rev, eax);
|
||||
|
||||
uci->cpu_sig.rev = rev;
|
||||
uci->cpu_sig.sig = eax;
|
||||
if (check_current_patch_level(&rev))
|
||||
return;
|
||||
|
||||
eax = cpuid_eax(0x00000001);
|
||||
eq = (struct equiv_cpu_entry *)(container + CONTAINER_HDR_SZ);
|
||||
@ -424,9 +420,10 @@ int __init save_microcode_in_initrd_amd(void)
|
||||
void reload_ucode_amd(void)
|
||||
{
|
||||
struct microcode_amd *mc;
|
||||
u32 rev, eax;
|
||||
u32 rev;
|
||||
|
||||
rdmsr(MSR_AMD64_PATCH_LEVEL, rev, eax);
|
||||
if (check_current_patch_level(&rev))
|
||||
return;
|
||||
|
||||
mc = (struct microcode_amd *)amd_ucode_patch;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user