x86: msr: fix bogus return values from rdmsr_safe/wrmsr_safe
Impact: bogus error codes (+other?) on x86-64 The rdmsr_safe/wrmsr_safe routines have macros for the handling of the edx:eax arguments. Those macros take a variable number of assembly arguments. This is rather inherently incompatible with using %digit-style escapes in the inline assembly; replace those with %[name]-style escapes. This fixes miscompilation on x86-64, which at the very least caused bogus return values. It is possible that this could also corrupt the return value; I am not sure. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
parent
9ea2b82ed6
commit
08970fc4e0
@ -52,14 +52,14 @@ static inline unsigned long long native_read_msr_safe(unsigned int msr,
|
|||||||
{
|
{
|
||||||
DECLARE_ARGS(val, low, high);
|
DECLARE_ARGS(val, low, high);
|
||||||
|
|
||||||
asm volatile("2: rdmsr ; xor %0,%0\n"
|
asm volatile("2: rdmsr ; xor %[err],%[err]\n"
|
||||||
"1:\n\t"
|
"1:\n\t"
|
||||||
".section .fixup,\"ax\"\n\t"
|
".section .fixup,\"ax\"\n\t"
|
||||||
"3: mov %3,%0 ; jmp 1b\n\t"
|
"3: mov %[fault],%[err] ; jmp 1b\n\t"
|
||||||
".previous\n\t"
|
".previous\n\t"
|
||||||
_ASM_EXTABLE(2b, 3b)
|
_ASM_EXTABLE(2b, 3b)
|
||||||
: "=r" (*err), EAX_EDX_RET(val, low, high)
|
: [err] "=r" (*err), EAX_EDX_RET(val, low, high)
|
||||||
: "c" (msr), "i" (-EFAULT));
|
: "c" (msr), [fault] "i" (-EFAULT));
|
||||||
return EAX_EDX_VAL(val, low, high);
|
return EAX_EDX_VAL(val, low, high);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,15 +73,15 @@ static inline int native_write_msr_safe(unsigned int msr,
|
|||||||
unsigned low, unsigned high)
|
unsigned low, unsigned high)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
asm volatile("2: wrmsr ; xor %0,%0\n"
|
asm volatile("2: wrmsr ; xor %[err],%[err]\n"
|
||||||
"1:\n\t"
|
"1:\n\t"
|
||||||
".section .fixup,\"ax\"\n\t"
|
".section .fixup,\"ax\"\n\t"
|
||||||
"3: mov %4,%0 ; jmp 1b\n\t"
|
"3: mov %[fault],%[err] ; jmp 1b\n\t"
|
||||||
".previous\n\t"
|
".previous\n\t"
|
||||||
_ASM_EXTABLE(2b, 3b)
|
_ASM_EXTABLE(2b, 3b)
|
||||||
: "=a" (err)
|
: [err] "=a" (err)
|
||||||
: "c" (msr), "0" (low), "d" (high),
|
: "c" (msr), "0" (low), "d" (high),
|
||||||
"i" (-EFAULT)
|
[fault] "i" (-EFAULT)
|
||||||
: "memory");
|
: "memory");
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user