Commit 991eebf9 authored by Gleb Natapov's avatar Gleb Natapov

KVM: VMX: do not try to reexecute failed instruction while emulating invalid guest state

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: default avatarGleb Natapov <gleb@redhat.com>
parent 0b789eee
...@@ -795,6 +795,7 @@ enum emulation_result { ...@@ -795,6 +795,7 @@ enum emulation_result {
#define EMULTYPE_TRAP_UD (1 << 1) #define EMULTYPE_TRAP_UD (1 << 1)
#define EMULTYPE_SKIP (1 << 2) #define EMULTYPE_SKIP (1 << 2)
#define EMULTYPE_RETRY (1 << 3) #define EMULTYPE_RETRY (1 << 3)
#define EMULTYPE_NO_REEXECUTE (1 << 4)
int x86_emulate_instruction(struct kvm_vcpu *vcpu, unsigned long cr2, int x86_emulate_instruction(struct kvm_vcpu *vcpu, unsigned long cr2,
int emulation_type, void *insn, int insn_len); int emulation_type, void *insn, int insn_len);
......
...@@ -5189,7 +5189,7 @@ static int handle_invalid_guest_state(struct kvm_vcpu *vcpu) ...@@ -5189,7 +5189,7 @@ static int handle_invalid_guest_state(struct kvm_vcpu *vcpu)
if (test_bit(KVM_REQ_EVENT, &vcpu->requests)) if (test_bit(KVM_REQ_EVENT, &vcpu->requests))
return 1; return 1;
err = emulate_instruction(vcpu, 0); err = emulate_instruction(vcpu, EMULTYPE_NO_REEXECUTE);
if (err == EMULATE_DO_MMIO) { if (err == EMULATE_DO_MMIO) {
ret = 0; ret = 0;
......
...@@ -4765,11 +4765,15 @@ static int handle_emulation_failure(struct kvm_vcpu *vcpu) ...@@ -4765,11 +4765,15 @@ static int handle_emulation_failure(struct kvm_vcpu *vcpu)
} }
static bool reexecute_instruction(struct kvm_vcpu *vcpu, gva_t cr2, 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; gpa_t gpa = cr2;
pfn_t pfn; pfn_t pfn;
if (emulation_type & EMULTYPE_NO_REEXECUTE)
return false;
if (!vcpu->arch.mmu.direct_map) { if (!vcpu->arch.mmu.direct_map) {
/* /*
* Write permission should be allowed since only * Write permission should be allowed since only
...@@ -4912,8 +4916,8 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu, ...@@ -4912,8 +4916,8 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu,
if (r != EMULATION_OK) { if (r != EMULATION_OK) {
if (emulation_type & EMULTYPE_TRAP_UD) if (emulation_type & EMULTYPE_TRAP_UD)
return EMULATE_FAIL; return EMULATE_FAIL;
if (reexecute_instruction(vcpu, cr2, if (reexecute_instruction(vcpu, cr2, write_fault_to_spt,
write_fault_to_spt)) emulation_type))
return EMULATE_DONE; return EMULATE_DONE;
if (emulation_type & EMULTYPE_SKIP) if (emulation_type & EMULTYPE_SKIP)
return EMULATE_FAIL; return EMULATE_FAIL;
...@@ -4943,7 +4947,8 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu, ...@@ -4943,7 +4947,8 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu,
return EMULATE_DONE; return EMULATE_DONE;
if (r == EMULATION_FAILED) { 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 EMULATE_DONE;
return handle_emulation_failure(vcpu); return handle_emulation_failure(vcpu);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment