Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fbae4ba8 authored by Borislav Petkov's avatar Borislav Petkov
Browse files

x86, microcode: Reload microcode on resume



Normally, we do reapply microcode on resume. However, in the cases where
that microcode comes from the early loader and the late loader hasn't
been utilized yet, there's no easy way for us to go and apply the patch
applied during boot by the early loader.

Thus, reuse the patch stashed by the early loader for the BSP.

Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
parent a18a0f68
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -78,6 +78,7 @@ static inline void __exit exit_amd_microcode(void) {}
extern void __init load_ucode_bsp(void);
extern void __init load_ucode_bsp(void);
extern void load_ucode_ap(void);
extern void load_ucode_ap(void);
extern int __init save_microcode_in_initrd(void);
extern int __init save_microcode_in_initrd(void);
void reload_early_microcode(void);
#else
#else
static inline void __init load_ucode_bsp(void) {}
static inline void __init load_ucode_bsp(void) {}
static inline void load_ucode_ap(void) {}
static inline void load_ucode_ap(void) {}
@@ -85,6 +86,7 @@ static inline int __init save_microcode_in_initrd(void)
{
{
	return 0;
	return 0;
}
}
static inline void reload_early_microcode(void) {}
#endif
#endif


#endif /* _ASM_X86_MICROCODE_H */
#endif /* _ASM_X86_MICROCODE_H */
+2 −0
Original line number Original line Diff line number Diff line
@@ -68,10 +68,12 @@ extern u8 amd_ucode_patch[PATCH_MAX_SIZE];
extern void __init load_ucode_amd_bsp(void);
extern void __init load_ucode_amd_bsp(void);
extern void load_ucode_amd_ap(void);
extern void load_ucode_amd_ap(void);
extern int __init save_microcode_in_initrd_amd(void);
extern int __init save_microcode_in_initrd_amd(void);
void reload_ucode_amd(void);
#else
#else
static inline void __init load_ucode_amd_bsp(void) {}
static inline void __init load_ucode_amd_bsp(void) {}
static inline void load_ucode_amd_ap(void) {}
static inline void load_ucode_amd_ap(void) {}
static inline int __init save_microcode_in_initrd_amd(void) { return -EINVAL; }
static inline int __init save_microcode_in_initrd_amd(void) { return -EINVAL; }
void reload_ucode_amd(void) {}
#endif
#endif


#endif /* _ASM_X86_MICROCODE_AMD_H */
#endif /* _ASM_X86_MICROCODE_AMD_H */
+2 −0
Original line number Original line Diff line number Diff line
@@ -68,11 +68,13 @@ extern void __init load_ucode_intel_bsp(void);
extern void load_ucode_intel_ap(void);
extern void load_ucode_intel_ap(void);
extern void show_ucode_info_early(void);
extern void show_ucode_info_early(void);
extern int __init save_microcode_in_initrd_intel(void);
extern int __init save_microcode_in_initrd_intel(void);
void reload_ucode_intel(void);
#else
#else
static inline __init void load_ucode_intel_bsp(void) {}
static inline __init void load_ucode_intel_bsp(void) {}
static inline void load_ucode_intel_ap(void) {}
static inline void load_ucode_intel_ap(void) {}
static inline void show_ucode_info_early(void) {}
static inline void show_ucode_info_early(void) {}
static inline int __init save_microcode_in_initrd_intel(void) { return -EINVAL; }
static inline int __init save_microcode_in_initrd_intel(void) { return -EINVAL; }
static inline void reload_ucode_intel(void) {}
#endif
#endif


#if defined(CONFIG_MICROCODE_INTEL_EARLY) && defined(CONFIG_HOTPLUG_CPU)
#if defined(CONFIG_MICROCODE_INTEL_EARLY) && defined(CONFIG_HOTPLUG_CPU)
+18 −0
Original line number Original line Diff line number Diff line
@@ -402,3 +402,21 @@ int __init save_microcode_in_initrd_amd(void)


	return retval;
	return retval;
}
}

void reload_ucode_amd(void)
{
	struct microcode_amd *mc;
	u32 rev, eax;

	rdmsr(MSR_AMD64_PATCH_LEVEL, rev, eax);

	mc = (struct microcode_amd *)amd_ucode_patch;

	if (mc && rev < mc->hdr.patch_id) {
		if (!__apply_microcode_amd(mc)) {
			ucode_new_rev = mc->hdr.patch_id;
			pr_info("microcode: reload patch_level=0x%08x\n",
				ucode_new_rev);
		}
	}
}
+1 −7
Original line number Original line Diff line number Diff line
@@ -466,13 +466,7 @@ static void mc_bp_resume(void)
	if (uci->valid && uci->mc)
	if (uci->valid && uci->mc)
		microcode_ops->apply_microcode(cpu);
		microcode_ops->apply_microcode(cpu);
	else if (!uci->mc)
	else if (!uci->mc)
		/*
		reload_early_microcode();
		 * We might resume and not have applied late microcode but still
		 * have a newer patch stashed from the early loader. We don't
		 * have it in uci->mc so we have to load it the same way we're
		 * applying patches early on the APs.
		 */
		load_ucode_ap();
}
}


static struct syscore_ops mc_syscore_ops = {
static struct syscore_ops mc_syscore_ops = {
Loading