]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
KVM: x86: Exit to userspace on emulation skip failure
authorSean Christopherson <sean.j.christopherson@intel.com>
Tue, 27 Aug 2019 21:40:34 +0000 (14:40 -0700)
committerPaolo Bonzini <pbonzini@redhat.com>
Tue, 24 Sep 2019 12:31:07 +0000 (14:31 +0200)
Kill a few birds with one stone by forcing an exit to userspace on skip
emulation failure.  This removes a reference to EMULATE_FAIL, fixes a
bug in handle_ept_misconfig() where it would exit to userspace without
setting run->exit_reason, and fixes a theoretical bug in SVM's
task_switch_interception() where it would overwrite run->exit_reason on
a return of EMULATE_USER_EXIT.

Note, this technically doesn't fully fix task_switch_interception()
as it now incorrectly handles EMULATE_FAIL, but in practice there is no
bug as EMULATE_FAIL will never be returned for EMULTYPE_SKIP.

Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/svm.c
arch/x86/kvm/x86.c

index c7aa55e192c09080699c34d801bed40793bb78eb..fc40052fa3347b925fde792c9d2b1f796b3c895c 100644 (file)
@@ -3885,8 +3885,8 @@ static int task_switch_interception(struct vcpu_svm *svm)
            int_type == SVM_EXITINTINFO_TYPE_SOFT ||
            (int_type == SVM_EXITINTINFO_TYPE_EXEPT &&
             (int_vec == OF_VECTOR || int_vec == BP_VECTOR))) {
-               if (skip_emulated_instruction(&svm->vcpu) != EMULATE_DONE)
-                       goto fail;
+               if (skip_emulated_instruction(&svm->vcpu) == EMULATE_USER_EXIT)
+                       return 0;
        }
 
        if (int_type != SVM_EXITINTINFO_TYPE_SOFT)
index 64d584d48c60a2d07641f76d267bacce70d1e61f..802dfb926ca70f601a137c249469cf42c7e0bbde 100644 (file)
@@ -6306,6 +6306,13 @@ static int handle_emulation_failure(struct kvm_vcpu *vcpu, int emulation_type)
                return EMULATE_DONE;
        }
 
+       if (emulation_type & EMULTYPE_SKIP) {
+               vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
+               vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION;
+               vcpu->run->internal.ndata = 0;
+               return EMULATE_USER_EXIT;
+       }
+
        kvm_queue_exception(vcpu, UD_VECTOR);
 
        if (!is_guest_mode(vcpu) && kvm_x86_ops->get_cpl(vcpu) == 0) {
@@ -6641,8 +6648,6 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu,
                                inject_emulated_exception(vcpu);
                                return EMULATE_DONE;
                        }
-                       if (emulation_type & EMULTYPE_SKIP)
-                               return EMULATE_FAIL;
                        return handle_emulation_failure(vcpu, emulation_type);
                }
        }