Skip to content

Commit 7453b94

Browse files
committed
x86: improve array_index_mask_nospec() code generation
Don't force the inputs to be 'unsigned long', when the comparison can easily be done in 32-bit if that's more appropriate. Note that while we can look at the inputs to choose an appropriate size for the compare instruction, the output is fixed at 'unsigned long'. That's not technically optimal either, since a 32-bit 'sbbl' would often be sufficient. But for the outgoing mask we don't know how the mask ends up being used (ie we have uses that have an incoming 32-bit array index, but end up using the mask for other things). That said, it only costs the extra REX prefix to always generate the 64-bit mask. [ A 'sbbl' also always technically generates a 64-bit mask, but with the upper 32 bits clear: that's fine for when the incoming index that will be masked is already 32-bit, but not if you use the mask to mask a pointer afterwards, like the file table lookup does ] Cc: Peter Zijlstra <[email protected]> Cc: H. Peter Anvin <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Thomas Gleixner <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent dbaaabd commit 7453b94

File tree

1 file changed

+10
-14
lines changed

1 file changed

+10
-14
lines changed

arch/x86/include/asm/barrier.h

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,20 +33,16 @@
3333
* Returns:
3434
* 0 - (index < size)
3535
*/
36-
static __always_inline unsigned long array_index_mask_nospec(unsigned long index,
37-
unsigned long size)
38-
{
39-
unsigned long mask;
40-
41-
asm volatile ("cmp %1,%2; sbb %0,%0;"
42-
:"=r" (mask)
43-
:"g"(size),"r" (index)
44-
:"cc");
45-
return mask;
46-
}
47-
48-
/* Override the default implementation from linux/nospec.h. */
49-
#define array_index_mask_nospec array_index_mask_nospec
36+
#define array_index_mask_nospec(idx,sz) ({ \
37+
typeof((idx)+(sz)) __idx = (idx); \
38+
typeof(__idx) __sz = (sz); \
39+
unsigned long __mask; \
40+
asm volatile ("cmp %1,%2; sbb %0,%0" \
41+
:"=r" (__mask) \
42+
:ASM_INPUT_G (__sz), \
43+
"r" (__idx) \
44+
:"cc"); \
45+
__mask; })
5046

5147
/* Prevent speculative execution past this barrier. */
5248
#define barrier_nospec() alternative("", "lfence", X86_FEATURE_LFENCE_RDTSC)

0 commit comments

Comments
 (0)