[01/43] KVM: nVMX: Set LDTR to its architecturally defined value on nested VM-Exit
diff mbox series

Message ID 20210424004645.3950558-2-seanjc@google.com
State New, archived
Headers show
Series
  • KVM: x86: vCPU RESET/INIT fixes and consolidation
Related show

Commit Message

Sean Christopherson April 24, 2021, 12:46 a.m. UTC
Set L1's LDTR on VM-Exit per the Intel SDM:

  The host-state area does not contain a selector field for LDTR. LDTR is
  established as follows on all VM exits: the selector is cleared to
  0000H, the segment is marked unusable and is otherwise undefined
  (although the base address is always canonical).

This is likely a benign bug since the LDTR is unusable, as it means the
L1 VMM is conditioned to reload its LDTR in order to function properly on
bare metal.

Fixes: 4704d0befb07 ("KVM: nVMX: Exiting from L2 to L1")
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 arch/x86/kvm/vmx/nested.c | 4 ++++
 1 file changed, 4 insertions(+)

Comments

Reiji Watanabe May 19, 2021, 5:30 a.m. UTC | #1
On Fri, Apr 23, 2021 at 5:47 PM Sean Christopherson <seanjc@google.com> wrote:
>
> Set L1's LDTR on VM-Exit per the Intel SDM:
>
>   The host-state area does not contain a selector field for LDTR. LDTR is
>   established as follows on all VM exits: the selector is cleared to
>   0000H, the segment is marked unusable and is otherwise undefined
>   (although the base address is always canonical).
>
> This is likely a benign bug since the LDTR is unusable, as it means the
> L1 VMM is conditioned to reload its LDTR in order to function properly on
> bare metal.
>
> Fixes: 4704d0befb07 ("KVM: nVMX: Exiting from L2 to L1")
> Signed-off-by: Sean Christopherson <seanjc@google.com>

Reviewed-by: Reiji Watanabe <reijiw@google.com>

Patch
diff mbox series

diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
index 00339d624c92..32126fa0c4d8 100644
--- a/arch/x86/kvm/vmx/nested.c
+++ b/arch/x86/kvm/vmx/nested.c
@@ -4276,6 +4276,10 @@  static void load_vmcs12_host_state(struct kvm_vcpu *vcpu,
 	};
 	vmx_set_segment(vcpu, &seg, VCPU_SREG_TR);
 
+	memset(&seg, 0, sizeof(seg));
+	seg.unusable = 1;
+	vmx_set_segment(vcpu, &seg, VCPU_SREG_LDTR);
+
 	kvm_set_dr(vcpu, 7, 0x400);
 	vmcs_write64(GUEST_IA32_DEBUGCTL, 0);