x86/cpuid: Carve out all CPUID functionality
authorBorislav Petkov <bp@suse.de>
Thu, 24 Nov 2022 15:31:27 +0000 (16:31 +0100)
committerBorislav Petkov <bp@suse.de>
Tue, 29 Nov 2022 19:41:24 +0000 (20:41 +0100)
Carve it out into a special header, where it belongs.

No functional changes.

Signed-off-by: Borislav Petkov <bp@suse.de>
Link: https://lore.kernel.org/r/20221124164150.3040-1-bp@alien8.de
arch/x86/include/asm/cpuid.h
arch/x86/include/asm/processor.h

index 70b2db18165eb87e2ddb2dd61283d5400ef90f7c..9bee3e7bf97363e1d9b76438e94b902c8e1baf92 100644 (file)
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
  * CPUID-related helpers/definitions
- *
- * Derived from arch/x86/kvm/cpuid.c
  */
 
 #ifndef _ASM_X86_CPUID_H
 #define _ASM_X86_CPUID_H
 
+#include <asm/string.h>
+
+struct cpuid_regs {
+       u32 eax, ebx, ecx, edx;
+};
+
+enum cpuid_regs_idx {
+       CPUID_EAX = 0,
+       CPUID_EBX,
+       CPUID_ECX,
+       CPUID_EDX,
+};
+
+#ifdef CONFIG_X86_32
+extern int have_cpuid_p(void);
+#else
+static inline int have_cpuid_p(void)
+{
+       return 1;
+}
+#endif
+static inline void native_cpuid(unsigned int *eax, unsigned int *ebx,
+                               unsigned int *ecx, unsigned int *edx)
+{
+       /* ecx is often an input as well as an output. */
+       asm volatile("cpuid"
+           : "=a" (*eax),
+             "=b" (*ebx),
+             "=c" (*ecx),
+             "=d" (*edx)
+           : "0" (*eax), "2" (*ecx)
+           : "memory");
+}
+
+#define native_cpuid_reg(reg)                                  \
+static inline unsigned int native_cpuid_##reg(unsigned int op) \
+{                                                              \
+       unsigned int eax = op, ebx, ecx = 0, edx;               \
+                                                               \
+       native_cpuid(&eax, &ebx, &ecx, &edx);                   \
+                                                               \
+       return reg;                                             \
+}
+
+/*
+ * Native CPUID functions returning a single datum.
+ */
+native_cpuid_reg(eax)
+native_cpuid_reg(ebx)
+native_cpuid_reg(ecx)
+native_cpuid_reg(edx)
+
+#ifdef CONFIG_PARAVIRT_XXL
+#include <asm/paravirt.h>
+#else
+#define __cpuid                        native_cpuid
+#endif
+
+/*
+ * Generic CPUID function
+ * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx
+ * resulting in stale register contents being returned.
+ */
+static inline void cpuid(unsigned int op,
+                        unsigned int *eax, unsigned int *ebx,
+                        unsigned int *ecx, unsigned int *edx)
+{
+       *eax = op;
+       *ecx = 0;
+       __cpuid(eax, ebx, ecx, edx);
+}
+
+/* Some CPUID calls want 'count' to be placed in ecx */
+static inline void cpuid_count(unsigned int op, int count,
+                              unsigned int *eax, unsigned int *ebx,
+                              unsigned int *ecx, unsigned int *edx)
+{
+       *eax = op;
+       *ecx = count;
+       __cpuid(eax, ebx, ecx, edx);
+}
+
+/*
+ * CPUID functions returning a single datum
+ */
+static inline unsigned int cpuid_eax(unsigned int op)
+{
+       unsigned int eax, ebx, ecx, edx;
+
+       cpuid(op, &eax, &ebx, &ecx, &edx);
+
+       return eax;
+}
+
+static inline unsigned int cpuid_ebx(unsigned int op)
+{
+       unsigned int eax, ebx, ecx, edx;
+
+       cpuid(op, &eax, &ebx, &ecx, &edx);
+
+       return ebx;
+}
+
+static inline unsigned int cpuid_ecx(unsigned int op)
+{
+       unsigned int eax, ebx, ecx, edx;
+
+       cpuid(op, &eax, &ebx, &ecx, &edx);
+
+       return ecx;
+}
+
+static inline unsigned int cpuid_edx(unsigned int op)
+{
+       unsigned int eax, ebx, ecx, edx;
+
+       cpuid(op, &eax, &ebx, &ecx, &edx);
+
+       return edx;
+}
+
 static __always_inline bool cpuid_function_is_indexed(u32 function)
 {
        switch (function) {
@@ -31,4 +150,22 @@ static __always_inline bool cpuid_function_is_indexed(u32 function)
        return false;
 }
 
+#define for_each_possible_hypervisor_cpuid_base(function) \
+       for (function = 0x40000000; function < 0x40010000; function += 0x100)
+
+static inline uint32_t hypervisor_cpuid_base(const char *sig, uint32_t leaves)
+{
+       uint32_t base, eax, signature[3];
+
+       for_each_possible_hypervisor_cpuid_base(base) {
+               cpuid(base, &eax, &signature[0], &signature[1], &signature[2]);
+
+               if (!memcmp(sig, signature, 12) &&
+                   (leaves == 0 || ((eax - base) >= leaves)))
+                       return base;
+       }
+
+       return 0;
+}
+
 #endif /* _ASM_X86_CPUID_H */
index 67c9d73b31faa1590c0aa4abd72da7d5b20ff0ed..6836c64b9819e589eedb08f5bd47d255ea95b05d 100644 (file)
@@ -16,6 +16,7 @@ struct vm86;
 #include <uapi/asm/sigcontext.h>
 #include <asm/current.h>
 #include <asm/cpufeatures.h>
+#include <asm/cpuid.h>
 #include <asm/page.h>
 #include <asm/pgtable_types.h>
 #include <asm/percpu.h>
@@ -146,17 +147,6 @@ struct cpuinfo_x86 {
        unsigned                initialized : 1;
 } __randomize_layout;
 
-struct cpuid_regs {
-       u32 eax, ebx, ecx, edx;
-};
-
-enum cpuid_regs_idx {
-       CPUID_EAX = 0,
-       CPUID_EBX,
-       CPUID_ECX,
-       CPUID_EDX,
-};
-
 #define X86_VENDOR_INTEL       0
 #define X86_VENDOR_CYRIX       1
 #define X86_VENDOR_AMD         2
@@ -205,45 +195,6 @@ extern void identify_secondary_cpu(struct cpuinfo_x86 *);
 extern void print_cpu_info(struct cpuinfo_x86 *);
 void print_cpu_msr(struct cpuinfo_x86 *);
 
-#ifdef CONFIG_X86_32
-extern int have_cpuid_p(void);
-#else
-static inline int have_cpuid_p(void)
-{
-       return 1;
-}
-#endif
-static inline void native_cpuid(unsigned int *eax, unsigned int *ebx,
-                               unsigned int *ecx, unsigned int *edx)
-{
-       /* ecx is often an input as well as an output. */
-       asm volatile("cpuid"
-           : "=a" (*eax),
-             "=b" (*ebx),
-             "=c" (*ecx),
-             "=d" (*edx)
-           : "0" (*eax), "2" (*ecx)
-           : "memory");
-}
-
-#define native_cpuid_reg(reg)                                  \
-static inline unsigned int native_cpuid_##reg(unsigned int op) \
-{                                                              \
-       unsigned int eax = op, ebx, ecx = 0, edx;               \
-                                                               \
-       native_cpuid(&eax, &ebx, &ecx, &edx);                   \
-                                                               \
-       return reg;                                             \
-}
-
-/*
- * Native CPUID functions returning a single datum.
- */
-native_cpuid_reg(eax)
-native_cpuid_reg(ebx)
-native_cpuid_reg(ecx)
-native_cpuid_reg(edx)
-
 /*
  * Friendlier CR3 helpers.
  */
@@ -578,7 +529,6 @@ static __always_inline bool on_thread_stack(void)
 #ifdef CONFIG_PARAVIRT_XXL
 #include <asm/paravirt.h>
 #else
-#define __cpuid                        native_cpuid
 
 static inline void load_sp0(unsigned long sp0)
 {
@@ -589,69 +539,6 @@ static inline void load_sp0(unsigned long sp0)
 
 unsigned long __get_wchan(struct task_struct *p);
 
-/*
- * Generic CPUID function
- * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx
- * resulting in stale register contents being returned.
- */
-static inline void cpuid(unsigned int op,
-                        unsigned int *eax, unsigned int *ebx,
-                        unsigned int *ecx, unsigned int *edx)
-{
-       *eax = op;
-       *ecx = 0;
-       __cpuid(eax, ebx, ecx, edx);
-}
-
-/* Some CPUID calls want 'count' to be placed in ecx */
-static inline void cpuid_count(unsigned int op, int count,
-                              unsigned int *eax, unsigned int *ebx,
-                              unsigned int *ecx, unsigned int *edx)
-{
-       *eax = op;
-       *ecx = count;
-       __cpuid(eax, ebx, ecx, edx);
-}
-
-/*
- * CPUID functions returning a single datum
- */
-static inline unsigned int cpuid_eax(unsigned int op)
-{
-       unsigned int eax, ebx, ecx, edx;
-
-       cpuid(op, &eax, &ebx, &ecx, &edx);
-
-       return eax;
-}
-
-static inline unsigned int cpuid_ebx(unsigned int op)
-{
-       unsigned int eax, ebx, ecx, edx;
-
-       cpuid(op, &eax, &ebx, &ecx, &edx);
-
-       return ebx;
-}
-
-static inline unsigned int cpuid_ecx(unsigned int op)
-{
-       unsigned int eax, ebx, ecx, edx;
-
-       cpuid(op, &eax, &ebx, &ecx, &edx);
-
-       return ecx;
-}
-
-static inline unsigned int cpuid_edx(unsigned int op)
-{
-       unsigned int eax, ebx, ecx, edx;
-
-       cpuid(op, &eax, &ebx, &ecx, &edx);
-
-       return edx;
-}
-
 extern void select_idle_routine(const struct cpuinfo_x86 *c);
 extern void amd_e400_c1e_apic_setup(void);
 
@@ -805,24 +692,6 @@ static inline u32 amd_get_nodes_per_socket(void)   { return 0; }
 static inline u32 amd_get_highest_perf(void)           { return 0; }
 #endif
 
-#define for_each_possible_hypervisor_cpuid_base(function) \
-       for (function = 0x40000000; function < 0x40010000; function += 0x100)
-
-static inline uint32_t hypervisor_cpuid_base(const char *sig, uint32_t leaves)
-{
-       uint32_t base, eax, signature[3];
-
-       for_each_possible_hypervisor_cpuid_base(base) {
-               cpuid(base, &eax, &signature[0], &signature[1], &signature[2]);
-
-               if (!memcmp(sig, signature, 12) &&
-                   (leaves == 0 || ((eax - base) >= leaves)))
-                       return base;
-       }
-
-       return 0;
-}
-
 extern unsigned long arch_align_stack(unsigned long sp);
 void free_init_pages(const char *what, unsigned long begin, unsigned long end);
 extern void free_kernel_image_pages(const char *what, void *begin, void *end);