Skip to content

Commit 0507503

Browse files
H. Peter Anvinsuryasaimadhu
authored andcommitted
x86/asm: Avoid adding register pressure for the init case in static_cpu_has()
gcc will sometimes manifest the address of boot_cpu_data in a register as part of constant propagation. When multiple static_cpu_has() are used this may foul the mainline code with a register load which will only be used on the fallback path, which is unused after initialization. Explicitly force gcc to use immediate (rip-relative) addressing for the fallback path, thus removing any possible register use from static_cpu_has(). While making changes, modernize the code to use .pushsection...popsection instead of .section...previous. Signed-off-by: H. Peter Anvin (Intel) <[email protected]> Signed-off-by: Borislav Petkov <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent f87bc8d commit 0507503

File tree

1 file changed

+9
-4
lines changed

1 file changed

+9
-4
lines changed

arch/x86/include/asm/cpufeature.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -173,20 +173,25 @@ extern void clear_cpu_cap(struct cpuinfo_x86 *c, unsigned int bit);
173173
* means that the boot_cpu_has() variant is already fast enough for the
174174
* majority of cases and you should stick to using it as it is generally
175175
* only two instructions: a RIP-relative MOV and a TEST.
176+
*
177+
* Do not use an "m" constraint for [cap_byte] here: gcc doesn't know
178+
* that this is only used on a fallback path and will sometimes cause
179+
* it to manifest the address of boot_cpu_data in a register, fouling
180+
* the mainline (post-initialization) code.
176181
*/
177182
static __always_inline bool _static_cpu_has(u16 bit)
178183
{
179184
asm_volatile_goto(
180185
ALTERNATIVE_TERNARY("jmp 6f", %P[feature], "", "jmp %l[t_no]")
181-
".section .altinstr_aux,\"ax\"\n"
186+
".pushsection .altinstr_aux,\"ax\"\n"
182187
"6:\n"
183-
" testb %[bitnum],%[cap_byte]\n"
188+
" testb %[bitnum]," _ASM_RIP(%P[cap_byte]) "\n"
184189
" jnz %l[t_yes]\n"
185190
" jmp %l[t_no]\n"
186-
".previous\n"
191+
".popsection\n"
187192
: : [feature] "i" (bit),
188193
[bitnum] "i" (1 << (bit & 7)),
189-
[cap_byte] "m" (((const char *)boot_cpu_data.x86_capability)[bit >> 3])
194+
[cap_byte] "i" (&((const char *)boot_cpu_data.x86_capability)[bit >> 3])
190195
: : t_yes, t_no);
191196
t_yes:
192197
return true;

0 commit comments

Comments
 (0)