|
2 | 2 | #ifndef _ASM_X86_CPUFEATURE_H
|
3 | 3 | #define _ASM_X86_CPUFEATURE_H
|
4 | 4 |
|
5 |
| -#include <asm/processor.h> |
6 |
| - |
7 |
| -#if defined(__KERNEL__) && !defined(__ASSEMBLY__) |
| 5 | +#ifdef __KERNEL__ |
| 6 | +#ifndef __ASSEMBLY__ |
8 | 7 |
|
| 8 | +#include <asm/processor.h> |
9 | 9 | #include <asm/asm.h>
|
10 | 10 | #include <linux/bitops.h>
|
11 | 11 |
|
@@ -161,37 +161,10 @@ extern void clear_cpu_cap(struct cpuinfo_x86 *c, unsigned int bit);
|
161 | 161 | */
|
162 | 162 | static __always_inline __pure bool _static_cpu_has(u16 bit)
|
163 | 163 | {
|
164 |
| - asm_volatile_goto("1: jmp 6f\n" |
165 |
| - "2:\n" |
166 |
| - ".skip -(((5f-4f) - (2b-1b)) > 0) * " |
167 |
| - "((5f-4f) - (2b-1b)),0x90\n" |
168 |
| - "3:\n" |
169 |
| - ".section .altinstructions,\"a\"\n" |
170 |
| - " .long 1b - .\n" /* src offset */ |
171 |
| - " .long 4f - .\n" /* repl offset */ |
172 |
| - " .word %P[always]\n" /* always replace */ |
173 |
| - " .byte 3b - 1b\n" /* src len */ |
174 |
| - " .byte 5f - 4f\n" /* repl len */ |
175 |
| - " .byte 3b - 2b\n" /* pad len */ |
176 |
| - ".previous\n" |
177 |
| - ".section .altinstr_replacement,\"ax\"\n" |
178 |
| - "4: jmp %l[t_no]\n" |
179 |
| - "5:\n" |
180 |
| - ".previous\n" |
181 |
| - ".section .altinstructions,\"a\"\n" |
182 |
| - " .long 1b - .\n" /* src offset */ |
183 |
| - " .long 0\n" /* no replacement */ |
184 |
| - " .word %P[feature]\n" /* feature bit */ |
185 |
| - " .byte 3b - 1b\n" /* src len */ |
186 |
| - " .byte 0\n" /* repl len */ |
187 |
| - " .byte 0\n" /* pad len */ |
188 |
| - ".previous\n" |
189 |
| - ".section .altinstr_aux,\"ax\"\n" |
190 |
| - "6:\n" |
191 |
| - " testb %[bitnum],%[cap_byte]\n" |
192 |
| - " jnz %l[t_yes]\n" |
193 |
| - " jmp %l[t_no]\n" |
194 |
| - ".previous\n" |
| 164 | + asm_volatile_goto("STATIC_CPU_HAS bitnum=%[bitnum] " |
| 165 | + "cap_byte=\"%[cap_byte]\" " |
| 166 | + "feature=%P[feature] t_yes=%l[t_yes] " |
| 167 | + "t_no=%l[t_no] always=%P[always]" |
195 | 168 | : : [feature] "i" (bit),
|
196 | 169 | [always] "i" (X86_FEATURE_ALWAYS),
|
197 | 170 | [bitnum] "i" (1 << (bit & 7)),
|
@@ -226,5 +199,44 @@ static __always_inline __pure bool _static_cpu_has(u16 bit)
|
226 | 199 | #define CPU_FEATURE_TYPEVAL boot_cpu_data.x86_vendor, boot_cpu_data.x86, \
|
227 | 200 | boot_cpu_data.x86_model
|
228 | 201 |
|
229 |
| -#endif /* defined(__KERNEL__) && !defined(__ASSEMBLY__) */ |
| 202 | +#else /* __ASSEMBLY__ */ |
| 203 | + |
| 204 | +.macro STATIC_CPU_HAS bitnum:req cap_byte:req feature:req t_yes:req t_no:req always:req |
| 205 | +1: |
| 206 | + jmp 6f |
| 207 | +2: |
| 208 | + .skip -(((5f-4f) - (2b-1b)) > 0) * ((5f-4f) - (2b-1b)),0x90 |
| 209 | +3: |
| 210 | + .section .altinstructions,"a" |
| 211 | + .long 1b - . /* src offset */ |
| 212 | + .long 4f - . /* repl offset */ |
| 213 | + .word \always /* always replace */ |
| 214 | + .byte 3b - 1b /* src len */ |
| 215 | + .byte 5f - 4f /* repl len */ |
| 216 | + .byte 3b - 2b /* pad len */ |
| 217 | + .previous |
| 218 | + .section .altinstr_replacement,"ax" |
| 219 | +4: |
| 220 | + jmp \t_no |
| 221 | +5: |
| 222 | + .previous |
| 223 | + .section .altinstructions,"a" |
| 224 | + .long 1b - . /* src offset */ |
| 225 | + .long 0 /* no replacement */ |
| 226 | + .word \feature /* feature bit */ |
| 227 | + .byte 3b - 1b /* src len */ |
| 228 | + .byte 0 /* repl len */ |
| 229 | + .byte 0 /* pad len */ |
| 230 | + .previous |
| 231 | + .section .altinstr_aux,"ax" |
| 232 | +6: |
| 233 | + testb \bitnum,\cap_byte |
| 234 | + jnz \t_yes |
| 235 | + jmp \t_no |
| 236 | + .previous |
| 237 | +.endm |
| 238 | + |
| 239 | +#endif /* __ASSEMBLY__ */ |
| 240 | + |
| 241 | +#endif /* __KERNEL__ */ |
230 | 242 | #endif /* _ASM_X86_CPUFEATURE_H */
|
0 commit comments