14fd95bf14
Do not use GCC's "A" constraint to load EAX:EDX in wrmsr_safe(). Per
GCC's documenation on x86-specific constraints, "A" will not actually
load a 64-bit value into EAX:EDX on x86-64.
The a and d registers. This class is used for instructions that return
double word results in the ax:dx register pair. Single word values will
be allocated either in ax or dx. For example on i386 the following
implements rdtsc:
unsigned long long rdtsc (void)
{
unsigned long long tick;
__asm__ __volatile__("rdtsc":"=A"(tick));
return tick;
}
This is not correct on x86-64 as it would allocate tick in either ax or
dx. You have to use the following variant instead:
unsigned long long rdtsc (void)
{
unsigned int tickl, tickh;
__asm__ __volatile__("rdtsc":"=a"(tickl),"=d"(tickh));
return ((unsigned long long)tickh << 32)|tickl;
}
Because a u64 fits in a single 64-bit register, using "A" for selftests,
which are 64-bit only, results in GCC loading the value into either RAX
or RDX instead of splitting it across EAX:EDX.
E.g.:
kvm_exit: reason MSR_WRITE rip 0x402919 info 0 0
kvm_msr: msr_write 40000118 = 0x60000000001 (#GP)
...
With "A":
48 8b 43 08 mov 0x8(%rbx),%rax
49 b9 ba da ca ba 0a movabs $0xabacadaba,%r9
00 00 00
4c 8d 15 07 00 00 00 lea 0x7(%rip),%r10 # 402f44 <guest_msr+0x34>
4c 8d 1d 06 00 00 00 lea 0x6(%rip),%r11 # 402f4a <guest_msr+0x3a>
0f 30 wrmsr
With "a"/"d":
48 8b 53 08 mov 0x8(%rbx),%rdx
89 d0 mov %edx,%eax
48 c1 ea 20 shr $0x20,%rdx
49 b9 ba da ca ba 0a movabs $0xabacadaba,%r9
00 00 00
4c 8d 15 07 00 00 00 lea 0x7(%rip),%r10 # 402fc3 <guest_msr+0xb3>
4c 8d 1d 06 00 00 00 lea 0x6(%rip),%r11 # 402fc9 <guest_msr+0xb9>
0f 30 wrmsr
Fixes:
|
||
---|---|---|
.. | ||
accounting | ||
arch | ||
bootconfig | ||
bpf | ||
build | ||
certs | ||
cgroup | ||
counter | ||
debugging | ||
edid | ||
firewire | ||
firmware | ||
gpio | ||
hv | ||
iio | ||
include | ||
io_uring | ||
kvm/kvm_stat | ||
laptop | ||
leds | ||
lib | ||
memory-model | ||
objtool | ||
pci | ||
pcmcia | ||
perf | ||
power | ||
rcu | ||
scripts | ||
spi | ||
testing | ||
thermal | ||
time | ||
tracing | ||
usb | ||
virtio | ||
vm | ||
wmi | ||
Makefile |