| From b5f253c75628fa491fb805793e68ba7aac9bc6ca Mon Sep 17 00:00:00 2001 |
| From: Oliver Upton <oupton@google.com> |
| Date: Sat, 29 Feb 2020 11:30:14 -0800 |
| Subject: [PATCH] KVM: VMX: check descriptor table exits on instruction |
| emulation |
| |
| commit 86f7e90ce840aa1db407d3ea6e9b3a52b2ce923c upstream. |
| |
| KVM emulates UMIP on hardware that doesn't support it by setting the |
| 'descriptor table exiting' VM-execution control and performing |
| instruction emulation. When running nested, this emulation is broken as |
| KVM refuses to emulate L2 instructions by default. |
| |
| Correct this regression by allowing the emulation of descriptor table |
| instructions if L1 hasn't requested 'descriptor table exiting'. |
| |
| Fixes: 07721feee46b ("KVM: nVMX: Don't emulate instructions in guest mode") |
| Reported-by: Jan Kiszka <jan.kiszka@web.de> |
| Cc: stable@vger.kernel.org |
| Cc: Paolo Bonzini <pbonzini@redhat.com> |
| Cc: Jim Mattson <jmattson@google.com> |
| Signed-off-by: Oliver Upton <oupton@google.com> |
| Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c |
| index 053235096c51..e814351ec049 100644 |
| --- a/arch/x86/kvm/vmx/vmx.c |
| +++ b/arch/x86/kvm/vmx/vmx.c |
| @@ -7042,6 +7042,7 @@ static int vmx_check_intercept_io(struct kvm_vcpu *vcpu, |
| else |
| intercept = nested_vmx_check_io_bitmaps(vcpu, port, size); |
| |
| + /* FIXME: produce nested vmexit and return X86EMUL_INTERCEPTED. */ |
| return intercept ? X86EMUL_UNHANDLEABLE : X86EMUL_CONTINUE; |
| } |
| |
| @@ -7071,6 +7072,20 @@ static int vmx_check_intercept(struct kvm_vcpu *vcpu, |
| case x86_intercept_outs: |
| return vmx_check_intercept_io(vcpu, info); |
| |
| + case x86_intercept_lgdt: |
| + case x86_intercept_lidt: |
| + case x86_intercept_lldt: |
| + case x86_intercept_ltr: |
| + case x86_intercept_sgdt: |
| + case x86_intercept_sidt: |
| + case x86_intercept_sldt: |
| + case x86_intercept_str: |
| + if (!nested_cpu_has2(vmcs12, SECONDARY_EXEC_DESC)) |
| + return X86EMUL_CONTINUE; |
| + |
| + /* FIXME: produce nested vmexit and return X86EMUL_INTERCEPTED. */ |
| + break; |
| + |
| /* TODO: check more intercepts... */ |
| default: |
| break; |
| -- |
| 2.7.4 |
| |