aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2014-09-04 13:46:15 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2014-09-05 06:01:06 -0400
commitef54bcfeea6c8b04e2a4f9396e16d88558aa2eee (patch)
treeb55206cb61665de87690edff04c6f8d21889913d
parent5e352519519623a0b62587c606280e534d0cf1d9 (diff)
KVM: x86: skip writeback on injection of nested exception
If a nested page fault happens during emulation, we will inject a vmexit, not a page fault. However because writeback happens after the injection, we will write ctxt->eip from L2 into the L1 EIP. We do not write back if an instruction caused an interception vmexit---do the same for page faults. Suggested-by: Gleb Natapov <gleb@kernel.org> Reviewed-by: Gleb Natapov <gleb@kernel.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--arch/x86/include/asm/kvm_host.h1
-rw-r--r--arch/x86/kvm/x86.c15
2 files changed, 10 insertions, 6 deletions
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 08cc299ec6f4..c9896518e54d 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -893,7 +893,6 @@ void kvm_inject_page_fault(struct kvm_vcpu *vcpu, struct x86_exception *fault);
893int kvm_read_guest_page_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, 893int kvm_read_guest_page_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
894 gfn_t gfn, void *data, int offset, int len, 894 gfn_t gfn, void *data, int offset, int len,
895 u32 access); 895 u32 access);
896void kvm_propagate_fault(struct kvm_vcpu *vcpu, struct x86_exception *fault);
897bool kvm_require_cpl(struct kvm_vcpu *vcpu, int required_cpl); 896bool kvm_require_cpl(struct kvm_vcpu *vcpu, int required_cpl);
898 897
899static inline int __kvm_irq_line_state(unsigned long *irq_state, 898static inline int __kvm_irq_line_state(unsigned long *irq_state,
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index e4ed85e07a01..354194671902 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -408,12 +408,14 @@ void kvm_inject_page_fault(struct kvm_vcpu *vcpu, struct x86_exception *fault)
408} 408}
409EXPORT_SYMBOL_GPL(kvm_inject_page_fault); 409EXPORT_SYMBOL_GPL(kvm_inject_page_fault);
410 410
411void kvm_propagate_fault(struct kvm_vcpu *vcpu, struct x86_exception *fault) 411static bool kvm_propagate_fault(struct kvm_vcpu *vcpu, struct x86_exception *fault)
412{ 412{
413 if (mmu_is_nested(vcpu) && !fault->nested_page_fault) 413 if (mmu_is_nested(vcpu) && !fault->nested_page_fault)
414 vcpu->arch.nested_mmu.inject_page_fault(vcpu, fault); 414 vcpu->arch.nested_mmu.inject_page_fault(vcpu, fault);
415 else 415 else
416 vcpu->arch.mmu.inject_page_fault(vcpu, fault); 416 vcpu->arch.mmu.inject_page_fault(vcpu, fault);
417
418 return fault->nested_page_fault;
417} 419}
418 420
419void kvm_inject_nmi(struct kvm_vcpu *vcpu) 421void kvm_inject_nmi(struct kvm_vcpu *vcpu)
@@ -4929,16 +4931,18 @@ static void toggle_interruptibility(struct kvm_vcpu *vcpu, u32 mask)
4929 } 4931 }
4930} 4932}
4931 4933
4932static void inject_emulated_exception(struct kvm_vcpu *vcpu) 4934static bool inject_emulated_exception(struct kvm_vcpu *vcpu)
4933{ 4935{
4934 struct x86_emulate_ctxt *ctxt = &vcpu->arch.emulate_ctxt; 4936 struct x86_emulate_ctxt *ctxt = &vcpu->arch.emulate_ctxt;
4935 if (ctxt->exception.vector == PF_VECTOR) 4937 if (ctxt->exception.vector == PF_VECTOR)
4936 kvm_propagate_fault(vcpu, &ctxt->exception); 4938 return kvm_propagate_fault(vcpu, &ctxt->exception);
4937 else if (ctxt->exception.error_code_valid) 4939
4940 if (ctxt->exception.error_code_valid)
4938 kvm_queue_exception_e(vcpu, ctxt->exception.vector, 4941 kvm_queue_exception_e(vcpu, ctxt->exception.vector,
4939 ctxt->exception.error_code); 4942 ctxt->exception.error_code);
4940 else 4943 else
4941 kvm_queue_exception(vcpu, ctxt->exception.vector); 4944 kvm_queue_exception(vcpu, ctxt->exception.vector);
4945 return false;
4942} 4946}
4943 4947
4944static void init_emulate_ctxt(struct kvm_vcpu *vcpu) 4948static void init_emulate_ctxt(struct kvm_vcpu *vcpu)
@@ -5300,8 +5304,9 @@ restart:
5300 } 5304 }
5301 5305
5302 if (ctxt->have_exception) { 5306 if (ctxt->have_exception) {
5303 inject_emulated_exception(vcpu);
5304 r = EMULATE_DONE; 5307 r = EMULATE_DONE;
5308 if (inject_emulated_exception(vcpu))
5309 return r;
5305 } else if (vcpu->arch.pio.count) { 5310 } else if (vcpu->arch.pio.count) {
5306 if (!vcpu->arch.pio.in) { 5311 if (!vcpu->arch.pio.in) {
5307 /* FIXME: return into emulator if single-stepping. */ 5312 /* FIXME: return into emulator if single-stepping. */