diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2014-09-04 13:46:15 -0400 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2014-09-05 06:01:06 -0400 |
commit | ef54bcfeea6c8b04e2a4f9396e16d88558aa2eee (patch) | |
tree | b55206cb61665de87690edff04c6f8d21889913d | |
parent | 5e352519519623a0b62587c606280e534d0cf1d9 (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.h | 1 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 15 |
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); | |||
893 | int kvm_read_guest_page_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, | 893 | int 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); |
896 | void kvm_propagate_fault(struct kvm_vcpu *vcpu, struct x86_exception *fault); | ||
897 | bool kvm_require_cpl(struct kvm_vcpu *vcpu, int required_cpl); | 896 | bool kvm_require_cpl(struct kvm_vcpu *vcpu, int required_cpl); |
898 | 897 | ||
899 | static inline int __kvm_irq_line_state(unsigned long *irq_state, | 898 | static 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 | } |
409 | EXPORT_SYMBOL_GPL(kvm_inject_page_fault); | 409 | EXPORT_SYMBOL_GPL(kvm_inject_page_fault); |
410 | 410 | ||
411 | void kvm_propagate_fault(struct kvm_vcpu *vcpu, struct x86_exception *fault) | 411 | static 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 | ||
419 | void kvm_inject_nmi(struct kvm_vcpu *vcpu) | 421 | void 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 | ||
4932 | static void inject_emulated_exception(struct kvm_vcpu *vcpu) | 4934 | static 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 | ||
4944 | static void init_emulate_ctxt(struct kvm_vcpu *vcpu) | 4948 | static 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. */ |