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>
{
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"
".section .fixup,\"ax\"\n\t"
"1:\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"
_ASM_EXTABLE(2b, 3b)
".previous\n\t"
_ASM_EXTABLE(2b, 3b)
- : "=r" (*err), EAX_EDX_RET(val, low, high)
- : "c" (msr), "i" (-EFAULT));
+ : [err] "=r" (*err), EAX_EDX_RET(val, low, high)
+ : "c" (msr), [fault] "i" (-EFAULT));
return EAX_EDX_VAL(val, low, high);
}
return EAX_EDX_VAL(val, low, high);
}
unsigned low, unsigned high)
{
int err;
unsigned low, unsigned high)
{
int err;
- asm volatile("2: wrmsr ; xor %0,%0\n"
+ asm volatile("2: wrmsr ; xor %[err],%[err]\n"
"1:\n\t"
".section .fixup,\"ax\"\n\t"
"1:\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"
_ASM_EXTABLE(2b, 3b)
".previous\n\t"
_ASM_EXTABLE(2b, 3b)
: "c" (msr), "0" (low), "d" (high),
: "c" (msr), "0" (low), "d" (high),
: "memory");
return err;
}
: "memory");
return err;
}