]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
KVM: VMX: do not try to reexecute failed instruction while emulating invalid guest...
authorGleb Natapov <gleb@redhat.com>
Thu, 11 Apr 2013 09:10:51 +0000 (12:10 +0300)
committerBen Hutchings <ben@decadent.org.uk>
Sat, 3 Mar 2018 15:50:37 +0000 (15:50 +0000)
commit 991eebf9f8e523e7ff1e4d31ac80641582b2e57a upstream.

During invalid guest state emulation vcpu cannot enter guest mode to try
to reexecute instruction that emulator failed to emulate, so emulation
will happen again and again.  Prevent that by telling the emulator that
instruction reexecution should not be attempted.

Signed-off-by: Gleb Natapov <gleb@redhat.com>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
arch/x86/include/asm/kvm_host.h
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c

index 51f85fc08cf144bdbe8bb828e285d7fd6f9de8f1..6782e51c1fdbce77dedc52f85c06eb0b6abc60c5 100644 (file)
@@ -694,6 +694,7 @@ enum emulation_result {
 #define EMULTYPE_NO_DECODE         (1 << 0)
 #define EMULTYPE_TRAP_UD           (1 << 1)
 #define EMULTYPE_SKIP              (1 << 2)
+#define EMULTYPE_NO_REEXECUTE      (1 << 4)
 int x86_emulate_instruction(struct kvm_vcpu *vcpu, unsigned long cr2,
                            int emulation_type, void *insn, int insn_len);
 
index 346fac6eab9f049a468a7b89ba0a02d0c47d818c..cfd6ed40c9cae03020042d7d3fbeb2be574653da 100644 (file)
@@ -4891,7 +4891,7 @@ static int handle_invalid_guest_state(struct kvm_vcpu *vcpu)
                    && (kvm_get_rflags(&vmx->vcpu) & X86_EFLAGS_IF))
                        return handle_interrupt_window(&vmx->vcpu);
 
-               err = emulate_instruction(vcpu, 0);
+               err = emulate_instruction(vcpu, EMULTYPE_NO_REEXECUTE);
 
                if (err == EMULATE_DO_MMIO) {
                        ret = 0;
index 29d04a41ee0a9e0a1c29ef1779d3cd541f98f846..9f2bb5b69d3d0568c2d677dbbb428bbd424acebe 100644 (file)
@@ -4888,10 +4888,14 @@ static int handle_emulation_failure(struct kvm_vcpu *vcpu)
        return r;
 }
 
-static bool reexecute_instruction(struct kvm_vcpu *vcpu, gva_t gva)
+static bool reexecute_instruction(struct kvm_vcpu *vcpu, gva_t gva,
+                                 int emulation_type)
 {
        gpa_t gpa;
 
+       if (emulation_type & EMULTYPE_NO_REEXECUTE)
+               return false;
+
        if (tdp_enabled)
                return false;
 
@@ -4942,7 +4946,7 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu,
                if (r != EMULATION_OK)  {
                        if (emulation_type & EMULTYPE_TRAP_UD)
                                return EMULATE_FAIL;
-                       if (reexecute_instruction(vcpu, cr2))
+                       if (reexecute_instruction(vcpu, cr2, emulation_type))
                                return EMULATE_DONE;
                        if (emulation_type & EMULTYPE_SKIP)
                                return EMULATE_FAIL;
@@ -4969,7 +4973,7 @@ restart:
                return EMULATE_DONE;
 
        if (r == EMULATION_FAILED) {
-               if (reexecute_instruction(vcpu, cr2))
+               if (reexecute_instruction(vcpu, cr2, emulation_type))
                        return EMULATE_DONE;
 
                return handle_emulation_failure(vcpu);