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)
committerGleb Natapov <gleb@redhat.com>
Sun, 14 Apr 2013 06:44:17 +0000 (09:44 +0300)
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>
arch/x86/include/asm/kvm_host.h
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c

index b2c7263c93b61ec1a84d34c92922cff614058081..82f1dc67782f0ebdd64eae25ca338336e7bbad43 100644 (file)
@@ -795,6 +795,7 @@ enum emulation_result {
 #define EMULTYPE_TRAP_UD           (1 << 1)
 #define EMULTYPE_SKIP              (1 << 2)
 #define EMULTYPE_RETRY             (1 << 3)
+#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 669b80378731f8e0ba3bff957562f46361a69fc5..d2686771481f3c45eb3399e74603dd6fbd59ac51 100644 (file)
@@ -5189,7 +5189,7 @@ static int handle_invalid_guest_state(struct kvm_vcpu *vcpu)
                if (test_bit(KVM_REQ_EVENT, &vcpu->requests))
                        return 1;
 
-               err = emulate_instruction(vcpu, 0);
+               err = emulate_instruction(vcpu, EMULTYPE_NO_REEXECUTE);
 
                if (err == EMULATE_DO_MMIO) {
                        ret = 0;
index eb9927e0af11b0a21c2a7eb3ae9f9a3573b423c7..999d1243a6ce163a37c3dc91b9adb173d8a07739 100644 (file)
@@ -4765,11 +4765,15 @@ static int handle_emulation_failure(struct kvm_vcpu *vcpu)
 }
 
 static bool reexecute_instruction(struct kvm_vcpu *vcpu, gva_t cr2,
-                                 bool write_fault_to_shadow_pgtable)
+                                 bool write_fault_to_shadow_pgtable,
+                                 int emulation_type)
 {
        gpa_t gpa = cr2;
        pfn_t pfn;
 
+       if (emulation_type & EMULTYPE_NO_REEXECUTE)
+               return false;
+
        if (!vcpu->arch.mmu.direct_map) {
                /*
                 * Write permission should be allowed since only
@@ -4912,8 +4916,8 @@ 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,
-                                                 write_fault_to_spt))
+                       if (reexecute_instruction(vcpu, cr2, write_fault_to_spt,
+                                               emulation_type))
                                return EMULATE_DONE;
                        if (emulation_type & EMULTYPE_SKIP)
                                return EMULATE_FAIL;
@@ -4943,7 +4947,8 @@ restart:
                return EMULATE_DONE;
 
        if (r == EMULATION_FAILED) {
-               if (reexecute_instruction(vcpu, cr2, write_fault_to_spt))
+               if (reexecute_instruction(vcpu, cr2, write_fault_to_spt,
+                                       emulation_type))
                        return EMULATE_DONE;
 
                return handle_emulation_failure(vcpu);