x86/nospec: Simplify alternative_msr_write()
The macro is not type safe and I did look for why that "g" constraint for
the asm doesn't work: it's because the asm is more fundamentally wrong.
It does
movl %[val], %%eax
but "val" isn't a 32-bit value, so then gcc will pass it in a register,
and generate code like
movl %rsi, %eax
and gas will complain about a nonsensical 'mov' instruction (it's moving a
64-bit register to a 32-bit one).
Passing it through memory will just hide the real bug - gcc still thinks
the memory location is 64-bit, but the "movl" will only load the first 32
bits and it all happens to work because x86 is little-endian.
Convert it to a type safe inline function with a little trick which hands
the feature into the ALTERNATIVE macro.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
committed by
Thomas Gleixner
parent
c65732e4f7
commit
1aa7a5735a
@@ -241,15 +241,16 @@ static inline void vmexit_fill_RSB(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#define alternative_msr_write(_msr, _val, _feature) \
|
static __always_inline
|
||||||
asm volatile(ALTERNATIVE("", \
|
void alternative_msr_write(unsigned int msr, u64 val, unsigned int feature)
|
||||||
"movl %[msr], %%ecx\n\t" \
|
{
|
||||||
"movl %[val], %%eax\n\t" \
|
asm volatile(ALTERNATIVE("", "wrmsr", %c[feature])
|
||||||
"movl $0, %%edx\n\t" \
|
: : "c" (msr),
|
||||||
"wrmsr", \
|
"a" (val),
|
||||||
_feature) \
|
"d" (val >> 32),
|
||||||
: : [msr] "i" (_msr), [val] "i" (_val) \
|
[feature] "i" (feature)
|
||||||
: "eax", "ecx", "edx", "memory")
|
: "memory");
|
||||||
|
}
|
||||||
|
|
||||||
static inline void indirect_branch_prediction_barrier(void)
|
static inline void indirect_branch_prediction_barrier(void)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user