Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef _ASM_X86_CPUFEATURE_H
0003 #define _ASM_X86_CPUFEATURE_H
0004 
0005 #include <asm/processor.h>
0006 
0007 #if defined(__KERNEL__) && !defined(__ASSEMBLY__)
0008 
0009 #include <asm/asm.h>
0010 #include <linux/bitops.h>
0011 #include <asm/alternative.h>
0012 
0013 enum cpuid_leafs
0014 {
0015     CPUID_1_EDX     = 0,
0016     CPUID_8000_0001_EDX,
0017     CPUID_8086_0001_EDX,
0018     CPUID_LNX_1,
0019     CPUID_1_ECX,
0020     CPUID_C000_0001_EDX,
0021     CPUID_8000_0001_ECX,
0022     CPUID_LNX_2,
0023     CPUID_LNX_3,
0024     CPUID_7_0_EBX,
0025     CPUID_D_1_EAX,
0026     CPUID_LNX_4,
0027     CPUID_7_1_EAX,
0028     CPUID_8000_0008_EBX,
0029     CPUID_6_EAX,
0030     CPUID_8000_000A_EDX,
0031     CPUID_7_ECX,
0032     CPUID_8000_0007_EBX,
0033     CPUID_7_EDX,
0034     CPUID_8000_001F_EAX,
0035 };
0036 
0037 #define X86_CAP_FMT_NUM "%d:%d"
0038 #define x86_cap_flag_num(flag) ((flag) >> 5), ((flag) & 31)
0039 
0040 #ifdef CONFIG_X86_FEATURE_NAMES
0041 extern const char * const x86_cap_flags[NCAPINTS*32];
0042 extern const char * const x86_power_flags[32];
0043 #define X86_CAP_FMT "%s"
0044 #define x86_cap_flag(flag) x86_cap_flags[flag]
0045 #else
0046 #define X86_CAP_FMT X86_CAP_FMT_NUM
0047 #define x86_cap_flag x86_cap_flag_num
0048 #endif
0049 
0050 /*
0051  * In order to save room, we index into this array by doing
0052  * X86_BUG_<name> - NCAPINTS*32.
0053  */
0054 extern const char * const x86_bug_flags[NBUGINTS*32];
0055 
0056 #define test_cpu_cap(c, bit)                        \
0057      arch_test_bit(bit, (unsigned long *)((c)->x86_capability))
0058 
0059 /*
0060  * There are 32 bits/features in each mask word.  The high bits
0061  * (selected with (bit>>5) give us the word number and the low 5
0062  * bits give us the bit/feature number inside the word.
0063  * (1UL<<((bit)&31) gives us a mask for the feature_bit so we can
0064  * see if it is set in the mask word.
0065  */
0066 #define CHECK_BIT_IN_MASK_WORD(maskname, word, bit) \
0067     (((bit)>>5)==(word) && (1UL<<((bit)&31) & maskname##word ))
0068 
0069 /*
0070  * {REQUIRED,DISABLED}_MASK_CHECK below may seem duplicated with the
0071  * following BUILD_BUG_ON_ZERO() check but when NCAPINTS gets changed, all
0072  * header macros which use NCAPINTS need to be changed. The duplicated macro
0073  * use causes the compiler to issue errors for all headers so that all usage
0074  * sites can be corrected.
0075  */
0076 #define REQUIRED_MASK_BIT_SET(feature_bit)      \
0077      ( CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK,  0, feature_bit) ||    \
0078        CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK,  1, feature_bit) ||    \
0079        CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK,  2, feature_bit) ||    \
0080        CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK,  3, feature_bit) ||    \
0081        CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK,  4, feature_bit) ||    \
0082        CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK,  5, feature_bit) ||    \
0083        CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK,  6, feature_bit) ||    \
0084        CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK,  7, feature_bit) ||    \
0085        CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK,  8, feature_bit) ||    \
0086        CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK,  9, feature_bit) ||    \
0087        CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 10, feature_bit) ||    \
0088        CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 11, feature_bit) ||    \
0089        CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 12, feature_bit) ||    \
0090        CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 13, feature_bit) ||    \
0091        CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 14, feature_bit) ||    \
0092        CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 15, feature_bit) ||    \
0093        CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 16, feature_bit) ||    \
0094        CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 17, feature_bit) ||    \
0095        CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 18, feature_bit) ||    \
0096        CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 19, feature_bit) ||    \
0097        REQUIRED_MASK_CHECK                    ||    \
0098        BUILD_BUG_ON_ZERO(NCAPINTS != 20))
0099 
0100 #define DISABLED_MASK_BIT_SET(feature_bit)              \
0101      ( CHECK_BIT_IN_MASK_WORD(DISABLED_MASK,  0, feature_bit) ||    \
0102        CHECK_BIT_IN_MASK_WORD(DISABLED_MASK,  1, feature_bit) ||    \
0103        CHECK_BIT_IN_MASK_WORD(DISABLED_MASK,  2, feature_bit) ||    \
0104        CHECK_BIT_IN_MASK_WORD(DISABLED_MASK,  3, feature_bit) ||    \
0105        CHECK_BIT_IN_MASK_WORD(DISABLED_MASK,  4, feature_bit) ||    \
0106        CHECK_BIT_IN_MASK_WORD(DISABLED_MASK,  5, feature_bit) ||    \
0107        CHECK_BIT_IN_MASK_WORD(DISABLED_MASK,  6, feature_bit) ||    \
0108        CHECK_BIT_IN_MASK_WORD(DISABLED_MASK,  7, feature_bit) ||    \
0109        CHECK_BIT_IN_MASK_WORD(DISABLED_MASK,  8, feature_bit) ||    \
0110        CHECK_BIT_IN_MASK_WORD(DISABLED_MASK,  9, feature_bit) ||    \
0111        CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 10, feature_bit) ||    \
0112        CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 11, feature_bit) ||    \
0113        CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 12, feature_bit) ||    \
0114        CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 13, feature_bit) ||    \
0115        CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 14, feature_bit) ||    \
0116        CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 15, feature_bit) ||    \
0117        CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 16, feature_bit) ||    \
0118        CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 17, feature_bit) ||    \
0119        CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 18, feature_bit) ||    \
0120        CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 19, feature_bit) ||    \
0121        DISABLED_MASK_CHECK                    ||    \
0122        BUILD_BUG_ON_ZERO(NCAPINTS != 20))
0123 
0124 #define cpu_has(c, bit)                         \
0125     (__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 :  \
0126      test_cpu_cap(c, bit))
0127 
0128 #define this_cpu_has(bit)                       \
0129     (__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 :  \
0130      x86_this_cpu_test_bit(bit,                 \
0131         (unsigned long __percpu *)&cpu_info.x86_capability))
0132 
0133 /*
0134  * This macro is for detection of features which need kernel
0135  * infrastructure to be used.  It may *not* directly test the CPU
0136  * itself.  Use the cpu_has() family if you want true runtime
0137  * testing of CPU features, like in hypervisor code where you are
0138  * supporting a possible guest feature where host support for it
0139  * is not relevant.
0140  */
0141 #define cpu_feature_enabled(bit)    \
0142     (__builtin_constant_p(bit) && DISABLED_MASK_BIT_SET(bit) ? 0 : static_cpu_has(bit))
0143 
0144 #define boot_cpu_has(bit)   cpu_has(&boot_cpu_data, bit)
0145 
0146 #define set_cpu_cap(c, bit) set_bit(bit, (unsigned long *)((c)->x86_capability))
0147 
0148 extern void setup_clear_cpu_cap(unsigned int bit);
0149 extern void clear_cpu_cap(struct cpuinfo_x86 *c, unsigned int bit);
0150 
0151 #define setup_force_cpu_cap(bit) do { \
0152     set_cpu_cap(&boot_cpu_data, bit);   \
0153     set_bit(bit, (unsigned long *)cpu_caps_set);    \
0154 } while (0)
0155 
0156 #define setup_force_cpu_bug(bit) setup_force_cpu_cap(bit)
0157 
0158 /*
0159  * Static testing of CPU features. Used the same as boot_cpu_has(). It
0160  * statically patches the target code for additional performance. Use
0161  * static_cpu_has() only in fast paths, where every cycle counts. Which
0162  * means that the boot_cpu_has() variant is already fast enough for the
0163  * majority of cases and you should stick to using it as it is generally
0164  * only two instructions: a RIP-relative MOV and a TEST.
0165  *
0166  * Do not use an "m" constraint for [cap_byte] here: gcc doesn't know
0167  * that this is only used on a fallback path and will sometimes cause
0168  * it to manifest the address of boot_cpu_data in a register, fouling
0169  * the mainline (post-initialization) code.
0170  */
0171 static __always_inline bool _static_cpu_has(u16 bit)
0172 {
0173     asm_volatile_goto(
0174         ALTERNATIVE_TERNARY("jmp 6f", %P[feature], "", "jmp %l[t_no]")
0175         ".pushsection .altinstr_aux,\"ax\"\n"
0176         "6:\n"
0177         " testb %[bitnum]," _ASM_RIP(%P[cap_byte]) "\n"
0178         " jnz %l[t_yes]\n"
0179         " jmp %l[t_no]\n"
0180         ".popsection\n"
0181          : : [feature]  "i" (bit),
0182              [bitnum]   "i" (1 << (bit & 7)),
0183              [cap_byte] "i" (&((const char *)boot_cpu_data.x86_capability)[bit >> 3])
0184          : : t_yes, t_no);
0185 t_yes:
0186     return true;
0187 t_no:
0188     return false;
0189 }
0190 
0191 #define static_cpu_has(bit)                 \
0192 (                               \
0193     __builtin_constant_p(boot_cpu_has(bit)) ?       \
0194         boot_cpu_has(bit) :             \
0195         _static_cpu_has(bit)                \
0196 )
0197 
0198 #define cpu_has_bug(c, bit)     cpu_has(c, (bit))
0199 #define set_cpu_bug(c, bit)     set_cpu_cap(c, (bit))
0200 #define clear_cpu_bug(c, bit)       clear_cpu_cap(c, (bit))
0201 
0202 #define static_cpu_has_bug(bit)     static_cpu_has((bit))
0203 #define boot_cpu_has_bug(bit)       cpu_has_bug(&boot_cpu_data, (bit))
0204 #define boot_cpu_set_bug(bit)       set_cpu_cap(&boot_cpu_data, (bit))
0205 
0206 #define MAX_CPU_FEATURES        (NCAPINTS * 32)
0207 #define cpu_have_feature        boot_cpu_has
0208 
0209 #define CPU_FEATURE_TYPEFMT     "x86,ven%04Xfam%04Xmod%04X"
0210 #define CPU_FEATURE_TYPEVAL     boot_cpu_data.x86_vendor, boot_cpu_data.x86, \
0211                     boot_cpu_data.x86_model
0212 
0213 #endif /* defined(__KERNEL__) && !defined(__ASSEMBLY__) */
0214 #endif /* _ASM_X86_CPUFEATURE_H */