| .. | .. | 
|---|
| 8 | 8 |   | 
|---|
| 9 | 9 |  #include <asm/asm.h> | 
|---|
| 10 | 10 |  #include <linux/bitops.h> | 
|---|
 | 11 | +#include <asm/alternative.h>  | 
|---|
| 11 | 12 |   | 
|---|
| 12 | 13 |  enum cpuid_leafs | 
|---|
| 13 | 14 |  { | 
|---|
| .. | .. | 
|---|
| 23 | 24 |  	CPUID_7_0_EBX, | 
|---|
| 24 | 25 |  	CPUID_D_1_EAX, | 
|---|
| 25 | 26 |  	CPUID_LNX_4, | 
|---|
| 26 |  | -	CPUID_DUMMY,  | 
|---|
 | 27 | +	CPUID_7_1_EAX,  | 
|---|
| 27 | 28 |  	CPUID_8000_0008_EBX, | 
|---|
| 28 | 29 |  	CPUID_6_EAX, | 
|---|
| 29 | 30 |  	CPUID_8000_000A_EDX, | 
|---|
| 30 | 31 |  	CPUID_7_ECX, | 
|---|
| 31 | 32 |  	CPUID_8000_0007_EBX, | 
|---|
| 32 | 33 |  	CPUID_7_EDX, | 
|---|
 | 34 | +	CPUID_8000_001F_EAX,  | 
|---|
 | 35 | +	CPUID_8000_0021_EAX,  | 
|---|
| 33 | 36 |  }; | 
|---|
| 34 | 37 |   | 
|---|
| 35 | 38 |  #ifdef CONFIG_X86_FEATURE_NAMES | 
|---|
| .. | .. | 
|---|
| 49 | 52 |  extern const char * const x86_bug_flags[NBUGINTS*32]; | 
|---|
| 50 | 53 |   | 
|---|
| 51 | 54 |  #define test_cpu_cap(c, bit)						\ | 
|---|
| 52 |  | -	 test_bit(bit, (unsigned long *)((c)->x86_capability))  | 
|---|
 | 55 | +	 arch_test_bit(bit, (unsigned long *)((c)->x86_capability))  | 
|---|
| 53 | 56 |   | 
|---|
| 54 | 57 |  /* | 
|---|
| 55 | 58 |   * There are 32 bits/features in each mask word.  The high bits | 
|---|
| .. | .. | 
|---|
| 61 | 64 |  #define CHECK_BIT_IN_MASK_WORD(maskname, word, bit)	\ | 
|---|
| 62 | 65 |  	(((bit)>>5)==(word) && (1UL<<((bit)&31) & maskname##word )) | 
|---|
| 63 | 66 |   | 
|---|
 | 67 | +/*  | 
|---|
 | 68 | + * {REQUIRED,DISABLED}_MASK_CHECK below may seem duplicated with the  | 
|---|
 | 69 | + * following BUILD_BUG_ON_ZERO() check but when NCAPINTS gets changed, all  | 
|---|
 | 70 | + * header macros which use NCAPINTS need to be changed. The duplicated macro  | 
|---|
 | 71 | + * use causes the compiler to issue errors for all headers so that all usage  | 
|---|
 | 72 | + * sites can be corrected.  | 
|---|
 | 73 | + */  | 
|---|
| 64 | 74 |  #define REQUIRED_MASK_BIT_SET(feature_bit)		\ | 
|---|
| 65 | 75 |  	 ( CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK,  0, feature_bit) ||	\ | 
|---|
| 66 | 76 |  	   CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK,  1, feature_bit) ||	\ | 
|---|
| .. | .. | 
|---|
| 81 | 91 |  	   CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 16, feature_bit) ||	\ | 
|---|
| 82 | 92 |  	   CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 17, feature_bit) ||	\ | 
|---|
| 83 | 93 |  	   CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 18, feature_bit) ||	\ | 
|---|
 | 94 | +	   CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 19, feature_bit) ||	\  | 
|---|
 | 95 | +	   CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 20, feature_bit) ||	\  | 
|---|
| 84 | 96 |  	   REQUIRED_MASK_CHECK					  ||	\ | 
|---|
| 85 |  | -	   BUILD_BUG_ON_ZERO(NCAPINTS != 19))  | 
|---|
 | 97 | +	   BUILD_BUG_ON_ZERO(NCAPINTS != 21))  | 
|---|
| 86 | 98 |   | 
|---|
| 87 | 99 |  #define DISABLED_MASK_BIT_SET(feature_bit)				\ | 
|---|
| 88 | 100 |  	 ( CHECK_BIT_IN_MASK_WORD(DISABLED_MASK,  0, feature_bit) ||	\ | 
|---|
| .. | .. | 
|---|
| 104 | 116 |  	   CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 16, feature_bit) ||	\ | 
|---|
| 105 | 117 |  	   CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 17, feature_bit) ||	\ | 
|---|
| 106 | 118 |  	   CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 18, feature_bit) ||	\ | 
|---|
 | 119 | +	   CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 19, feature_bit) ||	\  | 
|---|
 | 120 | +	   CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 20, feature_bit) ||	\  | 
|---|
| 107 | 121 |  	   DISABLED_MASK_CHECK					  ||	\ | 
|---|
| 108 |  | -	   BUILD_BUG_ON_ZERO(NCAPINTS != 19))  | 
|---|
 | 122 | +	   BUILD_BUG_ON_ZERO(NCAPINTS != 21))  | 
|---|
| 109 | 123 |   | 
|---|
| 110 | 124 |  #define cpu_has(c, bit)							\ | 
|---|
| 111 | 125 |  	(__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 :	\ | 
|---|
| 112 | 126 |  	 test_cpu_cap(c, bit)) | 
|---|
| 113 | 127 |   | 
|---|
| 114 | 128 |  #define this_cpu_has(bit)						\ | 
|---|
| 115 |  | -	(__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 : 	\  | 
|---|
| 116 |  | -	 x86_this_cpu_test_bit(bit, (unsigned long *)&cpu_info.x86_capability))  | 
|---|
 | 129 | +	(__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 :	\  | 
|---|
 | 130 | +	 x86_this_cpu_test_bit(bit,					\  | 
|---|
 | 131 | +		(unsigned long __percpu *)&cpu_info.x86_capability))  | 
|---|
| 117 | 132 |   | 
|---|
| 118 | 133 |  /* | 
|---|
| 119 | 134 |   * This macro is for detection of features which need kernel | 
|---|
| .. | .. | 
|---|
| 146 | 161 |   * Workaround for the sake of BPF compilation which utilizes kernel | 
|---|
| 147 | 162 |   * headers, but clang does not support ASM GOTO and fails the build. | 
|---|
| 148 | 163 |   */ | 
|---|
 | 164 | +#ifndef __BPF_TRACING__  | 
|---|
 | 165 | +#warning "Compiler lacks ASM_GOTO support. Add -D __BPF_TRACING__ to your compiler arguments"  | 
|---|
 | 166 | +#endif  | 
|---|
| 149 | 167 |   | 
|---|
| 150 | 168 |  #define static_cpu_has(bit)            boot_cpu_has(bit) | 
|---|
| 151 | 169 |   | 
|---|
| 152 | 170 |  #else | 
|---|
| 153 | 171 |   | 
|---|
| 154 | 172 |  /* | 
|---|
| 155 |  | - * Static testing of CPU features.  Used the same as boot_cpu_has().  | 
|---|
| 156 |  | - * These will statically patch the target code for additional  | 
|---|
| 157 |  | - * performance.  | 
|---|
 | 173 | + * Static testing of CPU features. Used the same as boot_cpu_has(). It  | 
|---|
 | 174 | + * statically patches the target code for additional performance. Use  | 
|---|
 | 175 | + * static_cpu_has() only in fast paths, where every cycle counts. Which  | 
|---|
 | 176 | + * means that the boot_cpu_has() variant is already fast enough for the  | 
|---|
 | 177 | + * majority of cases and you should stick to using it as it is generally  | 
|---|
 | 178 | + * only two instructions: a RIP-relative MOV and a TEST.  | 
|---|
| 158 | 179 |   */ | 
|---|
| 159 |  | -static __always_inline __pure bool _static_cpu_has(u16 bit)  | 
|---|
 | 180 | +static __always_inline bool _static_cpu_has(u16 bit)  | 
|---|
| 160 | 181 |  { | 
|---|
| 161 |  | -	asm_volatile_goto("1: jmp 6f\n"  | 
|---|
| 162 |  | -		 "2:\n"  | 
|---|
| 163 |  | -		 ".skip -(((5f-4f) - (2b-1b)) > 0) * "  | 
|---|
| 164 |  | -			 "((5f-4f) - (2b-1b)),0x90\n"  | 
|---|
| 165 |  | -		 "3:\n"  | 
|---|
| 166 |  | -		 ".section .altinstructions,\"a\"\n"  | 
|---|
| 167 |  | -		 " .long 1b - .\n"		/* src offset */  | 
|---|
| 168 |  | -		 " .long 4f - .\n"		/* repl offset */  | 
|---|
| 169 |  | -		 " .word %P[always]\n"		/* always replace */  | 
|---|
| 170 |  | -		 " .byte 3b - 1b\n"		/* src len */  | 
|---|
| 171 |  | -		 " .byte 5f - 4f\n"		/* repl len */  | 
|---|
| 172 |  | -		 " .byte 3b - 2b\n"		/* pad len */  | 
|---|
| 173 |  | -		 ".previous\n"  | 
|---|
| 174 |  | -		 ".section .altinstr_replacement,\"ax\"\n"  | 
|---|
| 175 |  | -		 "4: jmp %l[t_no]\n"  | 
|---|
| 176 |  | -		 "5:\n"  | 
|---|
| 177 |  | -		 ".previous\n"  | 
|---|
| 178 |  | -		 ".section .altinstructions,\"a\"\n"  | 
|---|
| 179 |  | -		 " .long 1b - .\n"		/* src offset */  | 
|---|
| 180 |  | -		 " .long 0\n"			/* no replacement */  | 
|---|
| 181 |  | -		 " .word %P[feature]\n"		/* feature bit */  | 
|---|
| 182 |  | -		 " .byte 3b - 1b\n"		/* src len */  | 
|---|
| 183 |  | -		 " .byte 0\n"			/* repl len */  | 
|---|
| 184 |  | -		 " .byte 0\n"			/* pad len */  | 
|---|
| 185 |  | -		 ".previous\n"  | 
|---|
| 186 |  | -		 ".section .altinstr_aux,\"ax\"\n"  | 
|---|
| 187 |  | -		 "6:\n"  | 
|---|
| 188 |  | -		 " testb %[bitnum],%[cap_byte]\n"  | 
|---|
| 189 |  | -		 " jnz %l[t_yes]\n"  | 
|---|
| 190 |  | -		 " jmp %l[t_no]\n"  | 
|---|
| 191 |  | -		 ".previous\n"  | 
|---|
 | 182 | +	asm_volatile_goto(  | 
|---|
 | 183 | +		ALTERNATIVE_TERNARY("jmp 6f", %P[feature], "", "jmp %l[t_no]")  | 
|---|
 | 184 | +		".section .altinstr_aux,\"ax\"\n"  | 
|---|
 | 185 | +		"6:\n"  | 
|---|
 | 186 | +		" testb %[bitnum],%[cap_byte]\n"  | 
|---|
 | 187 | +		" jnz %l[t_yes]\n"  | 
|---|
 | 188 | +		" jmp %l[t_no]\n"  | 
|---|
 | 189 | +		".previous\n"  | 
|---|
| 192 | 190 |  		 : : [feature]  "i" (bit), | 
|---|
| 193 |  | -		     [always]   "i" (X86_FEATURE_ALWAYS),  | 
|---|
| 194 | 191 |  		     [bitnum]   "i" (1 << (bit & 7)), | 
|---|
| 195 | 192 |  		     [cap_byte] "m" (((const char *)boot_cpu_data.x86_capability)[bit >> 3]) | 
|---|
| 196 | 193 |  		 : : t_yes, t_no); | 
|---|