• Vitaly Kuznetsov's avatar
    KVM: selftests: Use "a" and "d" to set EAX/EDX for wrmsr_safe() · 14fd95bf
    Vitaly Kuznetsov authored
    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: 3b23054c ("KVM: selftests: Add x86-64 support for exception fixup")
    Signed-off-by: default avatarVitaly Kuznetsov <vkuznets@redhat.com>
    Link: https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html#Machine-Constraints
    [sean: use "& -1u", provide GCC blurb and link to documentation]
    Signed-off-by: default avatarSean Christopherson <seanjc@google.com>
    Link: https://lore.kernel.org/r/20220714011115.3135828-1-seanjc@google.com
    14fd95bf
processor.h 16.4 KB