x86/microcode/intel: Expose collect_cpu_info_early() for IFS
authorJithu Joseph <jithu.joseph@intel.com>
Fri, 6 May 2022 22:53:59 +0000 (15:53 -0700)
committerHans de Goede <hdegoede@redhat.com>
Thu, 12 May 2022 13:35:29 +0000 (15:35 +0200)
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>
arch/x86/include/asm/cpu.h
arch/x86/kernel/cpu/intel.c
arch/x86/kernel/cpu/microcode/intel.c

index 86e5e4e..9901673 100644 (file)
@@ -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 */
index 8321c43..29d1522 100644 (file)
@@ -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;
index d28a9f8..025c8f0 100644 (file)
@@ -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)