KVM: VMX: Add a trampoline to fix VMREAD error handling
authorSean Christopherson <sean.j.christopherson@intel.com>
Thu, 26 Mar 2020 16:07:12 +0000 (09:07 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 17 Apr 2020 08:50:14 +0000 (10:50 +0200)
commit93a2b736886248a8cf3a5c8129fabc266b8dc6dc
treeac1246d7c3588cfed56f9147c5570c22860c4744
parent771b9374a529744c02c503b2a846c458a4aa5aa3
KVM: VMX: Add a trampoline to fix VMREAD error handling

commit 842f4be95899df22b5843ba1a7c8cf37e831a6e8 upstream.

Add a hand coded assembly trampoline to preserve volatile registers
across vmread_error(), and to handle the calling convention differences
between 64-bit and 32-bit due to asmlinkage on vmread_error().  Pass
@field and @fault on the stack when invoking the trampoline to avoid
clobbering volatile registers in the context of the inline assembly.

Calling vmread_error() directly from inline assembly is partially broken
on 64-bit, and completely broken on 32-bit.  On 64-bit, it will clobber
%rdi and %rsi (used to pass @field and @fault) and any volatile regs
written by vmread_error().  On 32-bit, asmlinkage means vmread_error()
expects the parameters to be passed on the stack, not via regs.

Opportunistically zero out the result in the trampoline to save a few
bytes of code for every VMREAD.  A happy side effect of the trampoline
is that the inline code footprint is reduced by three bytes on 64-bit
due to PUSH/POP being more efficent (in terms of opcode bytes) than MOV.

Fixes: 6e2020977e3e6 ("KVM: VMX: Add error handling to VMREAD helper")
Cc: stable@vger.kernel.org
Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
Message-Id: <20200326160712.28803-1-sean.j.christopherson@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/x86/kvm/vmx/ops.h
arch/x86/kvm/vmx/vmenter.S