0001
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
0052
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
0061
0062
0063
0064
0065
0066 #define CHECK_BIT_IN_MASK_WORD(maskname, word, bit) \
0067 (((bit)>>5)==(word) && (1UL<<((bit)&31) & maskname##word ))
0068
0069
0070
0071
0072
0073
0074
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
0135
0136
0137
0138
0139
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
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
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
0214 #endif