x86/microcode/intel: Expose collect_cpu_info_early() for IFS
IFS is a CPU feature that allows a binary blob, similar to microcode, to be loaded and consumed to perform low level validation of CPU circuitry. In fact, it carries the same Processor Signature (family/model/stepping) details that are contained in Intel microcode blobs. In support of an IFS driver to trigger loading, validation, and running of these tests blobs, make the functionality of cpu_signatures_match() and collect_cpu_info_early() available outside of the microcode driver. Add an "intel_" prefix and drop the "_early" suffix from collect_cpu_info_early() and EXPORT_SYMBOL_GPL() it. Add declaration to x86 <asm/cpu.h> Make cpu_signatures_match() an inline function in x86 <asm/cpu.h>, and also give it an "intel_" prefix. No functional change intended. Reviewed-by: Dan Williams <dan.j.williams@intel.com> Signed-off-by: Jithu Joseph <jithu.joseph@intel.com> Co-developed-by: Tony Luck <tony.luck@intel.com> Signed-off-by: Tony Luck <tony.luck@intel.com> Reviewed-by: Thomas Gleixner <tglx@linutronix.de> Acked-by: Borislav Petkov <bp@suse.de> Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Link: https://lore.kernel.org/r/20220506225410.1652287-2-tony.luck@intel.com Signed-off-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
parent
33e21e5624
commit
d3287fb0d3
@ -76,4 +76,22 @@ static inline void init_ia32_feat_ctl(struct cpuinfo_x86 *c) {}
|
||||
|
||||
extern __noendbr void cet_disable(void);
|
||||
|
||||
struct ucode_cpu_info;
|
||||
|
||||
int intel_cpu_collect_info(struct ucode_cpu_info *uci);
|
||||
|
||||
static inline bool intel_cpu_signatures_match(unsigned int s1, unsigned int p1,
|
||||
unsigned int s2, unsigned int p2)
|
||||
{
|
||||
if (s1 != s2)
|
||||
return false;
|
||||
|
||||
/* Processor flags are either both 0 ... */
|
||||
if (!p1 && !p2)
|
||||
return true;
|
||||
|
||||
/* ... or they intersect. */
|
||||
return p1 & p2;
|
||||
}
|
||||
|
||||
#endif /* _ASM_X86_CPU_H */
|
||||
|
@ -181,6 +181,38 @@ static bool bad_spectre_microcode(struct cpuinfo_x86 *c)
|
||||
return false;
|
||||
}
|
||||
|
||||
int intel_cpu_collect_info(struct ucode_cpu_info *uci)
|
||||
{
|
||||
unsigned int val[2];
|
||||
unsigned int family, model;
|
||||
struct cpu_signature csig = { 0 };
|
||||
unsigned int eax, ebx, ecx, edx;
|
||||
|
||||
memset(uci, 0, sizeof(*uci));
|
||||
|
||||
eax = 0x00000001;
|
||||
ecx = 0;
|
||||
native_cpuid(&eax, &ebx, &ecx, &edx);
|
||||
csig.sig = eax;
|
||||
|
||||
family = x86_family(eax);
|
||||
model = x86_model(eax);
|
||||
|
||||
if (model >= 5 || family > 6) {
|
||||
/* get processor flags from MSR 0x17 */
|
||||
native_rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]);
|
||||
csig.pf = 1 << ((val[1] >> 18) & 7);
|
||||
}
|
||||
|
||||
csig.rev = intel_get_microcode_revision();
|
||||
|
||||
uci->cpu_sig = csig;
|
||||
uci->valid = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(intel_cpu_collect_info);
|
||||
|
||||
static void early_init_intel(struct cpuinfo_x86 *c)
|
||||
{
|
||||
u64 misc_enable;
|
||||
|
@ -45,20 +45,6 @@ static struct microcode_intel *intel_ucode_patch;
|
||||
/* last level cache size per core */
|
||||
static int llc_size_per_core;
|
||||
|
||||
static inline bool cpu_signatures_match(unsigned int s1, unsigned int p1,
|
||||
unsigned int s2, unsigned int p2)
|
||||
{
|
||||
if (s1 != s2)
|
||||
return false;
|
||||
|
||||
/* Processor flags are either both 0 ... */
|
||||
if (!p1 && !p2)
|
||||
return true;
|
||||
|
||||
/* ... or they intersect. */
|
||||
return p1 & p2;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns 1 if update has been found, 0 otherwise.
|
||||
*/
|
||||
@ -69,7 +55,7 @@ static int find_matching_signature(void *mc, unsigned int csig, int cpf)
|
||||
struct extended_signature *ext_sig;
|
||||
int i;
|
||||
|
||||
if (cpu_signatures_match(csig, cpf, mc_hdr->sig, mc_hdr->pf))
|
||||
if (intel_cpu_signatures_match(csig, cpf, mc_hdr->sig, mc_hdr->pf))
|
||||
return 1;
|
||||
|
||||
/* Look for ext. headers: */
|
||||
@ -80,7 +66,7 @@ static int find_matching_signature(void *mc, unsigned int csig, int cpf)
|
||||
ext_sig = (void *)ext_hdr + EXT_HEADER_SIZE;
|
||||
|
||||
for (i = 0; i < ext_hdr->count; i++) {
|
||||
if (cpu_signatures_match(csig, cpf, ext_sig->sig, ext_sig->pf))
|
||||
if (intel_cpu_signatures_match(csig, cpf, ext_sig->sig, ext_sig->pf))
|
||||
return 1;
|
||||
ext_sig++;
|
||||
}
|
||||
@ -342,37 +328,6 @@ next:
|
||||
return patch;
|
||||
}
|
||||
|
||||
static int collect_cpu_info_early(struct ucode_cpu_info *uci)
|
||||
{
|
||||
unsigned int val[2];
|
||||
unsigned int family, model;
|
||||
struct cpu_signature csig = { 0 };
|
||||
unsigned int eax, ebx, ecx, edx;
|
||||
|
||||
memset(uci, 0, sizeof(*uci));
|
||||
|
||||
eax = 0x00000001;
|
||||
ecx = 0;
|
||||
native_cpuid(&eax, &ebx, &ecx, &edx);
|
||||
csig.sig = eax;
|
||||
|
||||
family = x86_family(eax);
|
||||
model = x86_model(eax);
|
||||
|
||||
if ((model >= 5) || (family > 6)) {
|
||||
/* get processor flags from MSR 0x17 */
|
||||
native_rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]);
|
||||
csig.pf = 1 << ((val[1] >> 18) & 7);
|
||||
}
|
||||
|
||||
csig.rev = intel_get_microcode_revision();
|
||||
|
||||
uci->cpu_sig = csig;
|
||||
uci->valid = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void show_saved_mc(void)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
@ -386,7 +341,7 @@ static void show_saved_mc(void)
|
||||
return;
|
||||
}
|
||||
|
||||
collect_cpu_info_early(&uci);
|
||||
intel_cpu_collect_info(&uci);
|
||||
|
||||
sig = uci.cpu_sig.sig;
|
||||
pf = uci.cpu_sig.pf;
|
||||
@ -502,7 +457,7 @@ void show_ucode_info_early(void)
|
||||
struct ucode_cpu_info uci;
|
||||
|
||||
if (delay_ucode_info) {
|
||||
collect_cpu_info_early(&uci);
|
||||
intel_cpu_collect_info(&uci);
|
||||
print_ucode_info(&uci, current_mc_date);
|
||||
delay_ucode_info = 0;
|
||||
}
|
||||
@ -604,7 +559,7 @@ int __init save_microcode_in_initrd_intel(void)
|
||||
if (!(cp.data && cp.size))
|
||||
return 0;
|
||||
|
||||
collect_cpu_info_early(&uci);
|
||||
intel_cpu_collect_info(&uci);
|
||||
|
||||
scan_microcode(cp.data, cp.size, &uci, true);
|
||||
|
||||
@ -637,7 +592,7 @@ static struct microcode_intel *__load_ucode_intel(struct ucode_cpu_info *uci)
|
||||
if (!(cp.data && cp.size))
|
||||
return NULL;
|
||||
|
||||
collect_cpu_info_early(uci);
|
||||
intel_cpu_collect_info(uci);
|
||||
|
||||
return scan_microcode(cp.data, cp.size, uci, false);
|
||||
}
|
||||
@ -712,7 +667,7 @@ void reload_ucode_intel(void)
|
||||
struct microcode_intel *p;
|
||||
struct ucode_cpu_info uci;
|
||||
|
||||
collect_cpu_info_early(&uci);
|
||||
intel_cpu_collect_info(&uci);
|
||||
|
||||
p = find_patch(&uci);
|
||||
if (!p)
|
||||
|
Loading…
x
Reference in New Issue
Block a user