mbox series

[v3,00/33] KVM: VMX: Move vCPU-run to proper asm sub-routine

Message ID 20190125154120.19385-1-sean.j.christopherson@intel.com (mailing list archive)
Headers show
Series KVM: VMX: Move vCPU-run to proper asm sub-routine | expand

Message

Sean Christopherson Jan. 25, 2019, 3:40 p.m. UTC
KVM's assembly for transitioning to/from a VMX guest is currently
implemented via inline asm.  At best it can be called "inscrutable", at
worst, well, that can't be printed here.

This series' ultimate goal is to move the transition code to a proper
assembly sub-routine that can be directly invoked from C code.
Unsurprisingly, making that happen requires a large number of patches
to carefully disarm all of the booby traps hiding in the shadows.

This series does NOT apply directly on the official KVM branches, but
rather on the official branches plus the patch that splits out a small
amount of vmx_vcpu_run() code to a helper, __vmx_vcpu_run()[1].  Adding
the helper function fixes a bug for kernel v5.0, i.e. absolutely should
be applied before this series, and not accounting for that change would
result in non-trivial conflicts.

A few patches in this series are carried over from the back half of the
series that moved VM-Enter and VM-Exit to proper assembly[2], but is
versioned as a different series given the much more ambitious end goal.

v1: https://patchwork.kernel.org/cover/10771525/

v2: https://patchwork.kernel.org/cover/10779721/
  - Fully tested 32-bit, amazingly there was no breakage.
  - Use 'b' and '=b' for asm constraints instead of trying to get fancy
    with 'bl' and '=ebx'. [Paolo]
  - Rename explicit VCPU reg indicides to __VCPU_REGS_R*. [Paolo]
  - Add Jim and Konrad's Reviewed-by tags.

v3:
  - Add patch to zero out registers that are reloaded from the stack. [Paolo]
  - Let compiler choose reg for @vm_fail in nested early checks. [Jim]
  - Add more "Reviewed-by Jim" tags.
  - Split "Make the vCPU-run asm routine callable from C" into separate
    patches to make each incremental change bisect-friendly.

[1] https://patchwork.kernel.org/patch/10765309/
[2] https://patchwork.kernel.org/cover/10739549/

Sean Christopherson (33):
  KVM: VMX: Compare only a single byte for VMCS' "launched" in vCPU-run
  KVM: nVMX: Check a single byte for VMCS "launched" in nested early
    checks
  KVM: VMX: Zero out *all* general purpose registers after VM-Exit
  KVM: VMX: Modify only RSP when creating a placeholder for guest's RCX
  KVM: VMX: Save RSI to an unused output in the vCPU-run asm blob
  KVM: VMX: Manually load RDX in vCPU-run asm blob
  KVM: VMX: Let the compiler save/load RDX during vCPU-run
  KVM: nVMX: Remove a rogue "rax" clobber from
    nested_vmx_check_vmentry_hw()
  KVM: nVMX: Drop STACK_FRAME_NON_STANDARD from
    nested_vmx_check_vmentry_hw()
  KVM: nVMX: Explicitly reference the scratch reg in nested early checks
  KVM: nVMX: Capture VM-Fail to a local var in
    nested_vmx_check_vmentry_hw()
  KVM: nVMX: Capture VM-Fail via CC_{SET,OUT} in nested early checks
  KVM: nVMX: Reference vmx->loaded_vmcs->launched directly
  KVM: nVMX: Let the compiler select the reg for holding HOST_RSP
  KVM: nVMX: Cache host_rsp on a per-VMCS basis
  KVM: VMX: Load/save guest CR2 via C code in __vmx_vcpu_run()
  KVM: VMX: Update VMCS.HOST_RSP via helper C function
  KVM: VMX: Pass "launched" directly to the vCPU-run asm blob
  KVM: VMX: Invert the ordering of saving guest/host scratch reg at
    VM-Enter
  KVM: VMX: Don't save guest registers after VM-Fail
  KVM: VMX: Use vcpu->arch.regs directly when saving/loading guest state
  KVM: x86: Explicitly #define the VCPU_REGS_* indices
  KVM: VMX: Use #defines in place of immediates in VM-Enter inline asm
  KVM: VMX: Create a stack frame in vCPU-run
  KVM: VMX: Move vCPU-run code to a proper assembly routine
  KVM: VMX: Fold __vmx_vcpu_run() back into vmx_vcpu_run()
  KVM: VMX: Rename ____vmx_vcpu_run() to __vmx_vcpu_run()
  KVM: VMX: Use RAX as the scratch register during vCPU-run
  KVM: VMX: Pass @launched to the vCPU-run asm via standard ABI regs
  KVM: VMX: Return VM-Fail from vCPU-run assembly via standard ABI reg
  KVM: VMX: Preserve callee-save registers in vCPU-run asm sub-routine
  KVM: VMX: Call vCPU-run asm sub-routine from C and remove clobbering
  KVM: VMX: Reorder clearing of registers in the vCPU-run assembly flow

 arch/x86/include/asm/kvm_host.h      |  33 +++---
 arch/x86/include/asm/kvm_vcpu_regs.h |  25 ++++
 arch/x86/kvm/vmx/nested.c            |  53 ++++-----
 arch/x86/kvm/vmx/vmcs.h              |   1 +
 arch/x86/kvm/vmx/vmenter.S           | 170 +++++++++++++++++++++++++++
 arch/x86/kvm/vmx/vmx.c               | 160 +++----------------------
 arch/x86/kvm/vmx/vmx.h               |   3 +-
 7 files changed, 252 insertions(+), 193 deletions(-)
 create mode 100644 arch/x86/include/asm/kvm_vcpu_regs.h

Comments

Paolo Bonzini Jan. 30, 2019, 4:05 p.m. UTC | #1
On 25/01/19 16:40, Sean Christopherson wrote:
> KVM's assembly for transitioning to/from a VMX guest is currently
> implemented via inline asm.  At best it can be called "inscrutable", at
> worst, well, that can't be printed here.
> 
> This series' ultimate goal is to move the transition code to a proper
> assembly sub-routine that can be directly invoked from C code.
> Unsurprisingly, making that happen requires a large number of patches
> to carefully disarm all of the booby traps hiding in the shadows.
> 
> This series does NOT apply directly on the official KVM branches, but
> rather on the official branches plus the patch that splits out a small
> amount of vmx_vcpu_run() code to a helper, __vmx_vcpu_run()[1].  Adding
> the helper function fixes a bug for kernel v5.0, i.e. absolutely should
> be applied before this series, and not accounting for that change would
> result in non-trivial conflicts.
> 
> A few patches in this series are carried over from the back half of the
> series that moved VM-Enter and VM-Exit to proper assembly[2], but is
> versioned as a different series given the much more ambitious end goal.
> 
> v1: https://patchwork.kernel.org/cover/10771525/
> 
> v2: https://patchwork.kernel.org/cover/10779721/
>   - Fully tested 32-bit, amazingly there was no breakage.
>   - Use 'b' and '=b' for asm constraints instead of trying to get fancy
>     with 'bl' and '=ebx'. [Paolo]
>   - Rename explicit VCPU reg indicides to __VCPU_REGS_R*. [Paolo]
>   - Add Jim and Konrad's Reviewed-by tags.
> 
> v3:
>   - Add patch to zero out registers that are reloaded from the stack. [Paolo]
>   - Let compiler choose reg for @vm_fail in nested early checks. [Jim]
>   - Add more "Reviewed-by Jim" tags.
>   - Split "Make the vCPU-run asm routine callable from C" into separate
>     patches to make each incremental change bisect-friendly.
> 
> [1] https://patchwork.kernel.org/patch/10765309/
> [2] https://patchwork.kernel.org/cover/10739549/
> 
> Sean Christopherson (33):
>   KVM: VMX: Compare only a single byte for VMCS' "launched" in vCPU-run
>   KVM: nVMX: Check a single byte for VMCS "launched" in nested early
>     checks
>   KVM: VMX: Zero out *all* general purpose registers after VM-Exit
>   KVM: VMX: Modify only RSP when creating a placeholder for guest's RCX
>   KVM: VMX: Save RSI to an unused output in the vCPU-run asm blob
>   KVM: VMX: Manually load RDX in vCPU-run asm blob
>   KVM: VMX: Let the compiler save/load RDX during vCPU-run
>   KVM: nVMX: Remove a rogue "rax" clobber from
>     nested_vmx_check_vmentry_hw()
>   KVM: nVMX: Drop STACK_FRAME_NON_STANDARD from
>     nested_vmx_check_vmentry_hw()
>   KVM: nVMX: Explicitly reference the scratch reg in nested early checks
>   KVM: nVMX: Capture VM-Fail to a local var in
>     nested_vmx_check_vmentry_hw()
>   KVM: nVMX: Capture VM-Fail via CC_{SET,OUT} in nested early checks
>   KVM: nVMX: Reference vmx->loaded_vmcs->launched directly
>   KVM: nVMX: Let the compiler select the reg for holding HOST_RSP
>   KVM: nVMX: Cache host_rsp on a per-VMCS basis
>   KVM: VMX: Load/save guest CR2 via C code in __vmx_vcpu_run()
>   KVM: VMX: Update VMCS.HOST_RSP via helper C function
>   KVM: VMX: Pass "launched" directly to the vCPU-run asm blob
>   KVM: VMX: Invert the ordering of saving guest/host scratch reg at
>     VM-Enter
>   KVM: VMX: Don't save guest registers after VM-Fail
>   KVM: VMX: Use vcpu->arch.regs directly when saving/loading guest state
>   KVM: x86: Explicitly #define the VCPU_REGS_* indices
>   KVM: VMX: Use #defines in place of immediates in VM-Enter inline asm
>   KVM: VMX: Create a stack frame in vCPU-run
>   KVM: VMX: Move vCPU-run code to a proper assembly routine
>   KVM: VMX: Fold __vmx_vcpu_run() back into vmx_vcpu_run()
>   KVM: VMX: Rename ____vmx_vcpu_run() to __vmx_vcpu_run()
>   KVM: VMX: Use RAX as the scratch register during vCPU-run
>   KVM: VMX: Pass @launched to the vCPU-run asm via standard ABI regs
>   KVM: VMX: Return VM-Fail from vCPU-run assembly via standard ABI reg
>   KVM: VMX: Preserve callee-save registers in vCPU-run asm sub-routine
>   KVM: VMX: Call vCPU-run asm sub-routine from C and remove clobbering
>   KVM: VMX: Reorder clearing of registers in the vCPU-run assembly flow
> 
>  arch/x86/include/asm/kvm_host.h      |  33 +++---
>  arch/x86/include/asm/kvm_vcpu_regs.h |  25 ++++
>  arch/x86/kvm/vmx/nested.c            |  53 ++++-----
>  arch/x86/kvm/vmx/vmcs.h              |   1 +
>  arch/x86/kvm/vmx/vmenter.S           | 170 +++++++++++++++++++++++++++
>  arch/x86/kvm/vmx/vmx.c               | 160 +++----------------------
>  arch/x86/kvm/vmx/vmx.h               |   3 +-
>  7 files changed, 252 insertions(+), 193 deletions(-)
>  create mode 100644 arch/x86/include/asm/kvm_vcpu_regs.h
> 

Queued, thanks.

Paolo