diff options
-rw-r--r-- | arch/x86/include/asm/kvm_host.h | 1 | ||||
-rw-r--r-- | arch/x86/kvm/mmu.c | 5 | ||||
-rw-r--r-- | arch/x86/kvm/svm.c | 10 | ||||
-rw-r--r-- | arch/x86/kvm/vmx.c | 28 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 43 |
5 files changed, 26 insertions, 61 deletions
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 2ca1867ed97a..0c06148fa3b1 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h | |||
@@ -576,7 +576,6 @@ enum emulation_result { | |||
576 | #define EMULTYPE_SKIP (1 << 2) | 576 | #define EMULTYPE_SKIP (1 << 2) |
577 | int emulate_instruction(struct kvm_vcpu *vcpu, | 577 | int emulate_instruction(struct kvm_vcpu *vcpu, |
578 | unsigned long cr2, u16 error_code, int emulation_type); | 578 | unsigned long cr2, u16 error_code, int emulation_type); |
579 | void kvm_report_emulation_failure(struct kvm_vcpu *cvpu, const char *context); | ||
580 | void realmode_lgdt(struct kvm_vcpu *vcpu, u16 size, unsigned long address); | 579 | void realmode_lgdt(struct kvm_vcpu *vcpu, u16 size, unsigned long address); |
581 | void realmode_lidt(struct kvm_vcpu *vcpu, u16 size, unsigned long address); | 580 | void realmode_lidt(struct kvm_vcpu *vcpu, u16 size, unsigned long address); |
582 | 581 | ||
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index be981b1f1881..4a02dee1f2b5 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c | |||
@@ -2814,11 +2814,8 @@ int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t cr2, u32 error_code) | |||
2814 | return 1; | 2814 | return 1; |
2815 | case EMULATE_DO_MMIO: | 2815 | case EMULATE_DO_MMIO: |
2816 | ++vcpu->stat.mmio_exits; | 2816 | ++vcpu->stat.mmio_exits; |
2817 | return 0; | 2817 | /* fall through */ |
2818 | case EMULATE_FAIL: | 2818 | case EMULATE_FAIL: |
2819 | vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; | ||
2820 | vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION; | ||
2821 | vcpu->run->internal.ndata = 0; | ||
2822 | return 0; | 2819 | return 0; |
2823 | default: | 2820 | default: |
2824 | BUG(); | 2821 | BUG(); |
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 41fe0381a1ae..134260c36ce2 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
@@ -1535,7 +1535,7 @@ static int io_interception(struct vcpu_svm *svm) | |||
1535 | string = (io_info & SVM_IOIO_STR_MASK) != 0; | 1535 | string = (io_info & SVM_IOIO_STR_MASK) != 0; |
1536 | in = (io_info & SVM_IOIO_TYPE_MASK) != 0; | 1536 | in = (io_info & SVM_IOIO_TYPE_MASK) != 0; |
1537 | if (string || in) | 1537 | if (string || in) |
1538 | return !(emulate_instruction(vcpu, 0, 0, 0) == EMULATE_DO_MMIO); | 1538 | return emulate_instruction(vcpu, 0, 0, 0) == EMULATE_DONE; |
1539 | 1539 | ||
1540 | port = io_info >> 16; | 1540 | port = io_info >> 16; |
1541 | size = (io_info & SVM_IOIO_SIZE_MASK) >> SVM_IOIO_SIZE_SHIFT; | 1541 | size = (io_info & SVM_IOIO_SIZE_MASK) >> SVM_IOIO_SIZE_SHIFT; |
@@ -2386,16 +2386,12 @@ static int iret_interception(struct vcpu_svm *svm) | |||
2386 | 2386 | ||
2387 | static int invlpg_interception(struct vcpu_svm *svm) | 2387 | static int invlpg_interception(struct vcpu_svm *svm) |
2388 | { | 2388 | { |
2389 | if (emulate_instruction(&svm->vcpu, 0, 0, 0) != EMULATE_DONE) | 2389 | return emulate_instruction(&svm->vcpu, 0, 0, 0) == EMULATE_DONE; |
2390 | pr_unimpl(&svm->vcpu, "%s: failed\n", __func__); | ||
2391 | return 1; | ||
2392 | } | 2390 | } |
2393 | 2391 | ||
2394 | static int emulate_on_interception(struct vcpu_svm *svm) | 2392 | static int emulate_on_interception(struct vcpu_svm *svm) |
2395 | { | 2393 | { |
2396 | if (emulate_instruction(&svm->vcpu, 0, 0, 0) != EMULATE_DONE) | 2394 | return emulate_instruction(&svm->vcpu, 0, 0, 0) == EMULATE_DONE; |
2397 | pr_unimpl(&svm->vcpu, "%s: failed\n", __func__); | ||
2398 | return 1; | ||
2399 | } | 2395 | } |
2400 | 2396 | ||
2401 | static int cr8_write_interception(struct vcpu_svm *svm) | 2397 | static int cr8_write_interception(struct vcpu_svm *svm) |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 598931734251..a82cfa1e2a40 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -3070,7 +3070,7 @@ static int handle_io(struct kvm_vcpu *vcpu) | |||
3070 | ++vcpu->stat.io_exits; | 3070 | ++vcpu->stat.io_exits; |
3071 | 3071 | ||
3072 | if (string || in) | 3072 | if (string || in) |
3073 | return !(emulate_instruction(vcpu, 0, 0, 0) == EMULATE_DO_MMIO); | 3073 | return emulate_instruction(vcpu, 0, 0, 0) == EMULATE_DONE; |
3074 | 3074 | ||
3075 | port = exit_qualification >> 16; | 3075 | port = exit_qualification >> 16; |
3076 | size = (exit_qualification & 7) + 1; | 3076 | size = (exit_qualification & 7) + 1; |
@@ -3327,22 +3327,7 @@ static int handle_wbinvd(struct kvm_vcpu *vcpu) | |||
3327 | 3327 | ||
3328 | static int handle_apic_access(struct kvm_vcpu *vcpu) | 3328 | static int handle_apic_access(struct kvm_vcpu *vcpu) |
3329 | { | 3329 | { |
3330 | unsigned long exit_qualification; | 3330 | return emulate_instruction(vcpu, 0, 0, 0) == EMULATE_DONE; |
3331 | enum emulation_result er; | ||
3332 | unsigned long offset; | ||
3333 | |||
3334 | exit_qualification = vmcs_readl(EXIT_QUALIFICATION); | ||
3335 | offset = exit_qualification & 0xffful; | ||
3336 | |||
3337 | er = emulate_instruction(vcpu, 0, 0, 0); | ||
3338 | |||
3339 | if (er != EMULATE_DONE) { | ||
3340 | printk(KERN_ERR | ||
3341 | "Fail to handle apic access vmexit! Offset is 0x%lx\n", | ||
3342 | offset); | ||
3343 | return -ENOEXEC; | ||
3344 | } | ||
3345 | return 1; | ||
3346 | } | 3331 | } |
3347 | 3332 | ||
3348 | static int handle_task_switch(struct kvm_vcpu *vcpu) | 3333 | static int handle_task_switch(struct kvm_vcpu *vcpu) |
@@ -3554,13 +3539,8 @@ static int handle_invalid_guest_state(struct kvm_vcpu *vcpu) | |||
3554 | goto out; | 3539 | goto out; |
3555 | } | 3540 | } |
3556 | 3541 | ||
3557 | if (err != EMULATE_DONE) { | 3542 | if (err != EMULATE_DONE) |
3558 | vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; | 3543 | return 0; |
3559 | vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION; | ||
3560 | vcpu->run->internal.ndata = 0; | ||
3561 | ret = 0; | ||
3562 | goto out; | ||
3563 | } | ||
3564 | 3544 | ||
3565 | if (signal_pending(current)) | 3545 | if (signal_pending(current)) |
3566 | goto out; | 3546 | goto out; |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index fc5611b4007f..ae9d6f3e5d0d 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -3639,24 +3639,6 @@ int emulator_set_dr(int dr, unsigned long value, struct kvm_vcpu *vcpu) | |||
3639 | return __kvm_set_dr(vcpu, dr, value); | 3639 | return __kvm_set_dr(vcpu, dr, value); |
3640 | } | 3640 | } |
3641 | 3641 | ||
3642 | void kvm_report_emulation_failure(struct kvm_vcpu *vcpu, const char *context) | ||
3643 | { | ||
3644 | u8 opcodes[4]; | ||
3645 | unsigned long rip = kvm_rip_read(vcpu); | ||
3646 | unsigned long rip_linear; | ||
3647 | |||
3648 | if (!printk_ratelimit()) | ||
3649 | return; | ||
3650 | |||
3651 | rip_linear = rip + get_segment_base(vcpu, VCPU_SREG_CS); | ||
3652 | |||
3653 | kvm_read_guest_virt(rip_linear, (void *)opcodes, 4, vcpu, NULL); | ||
3654 | |||
3655 | printk(KERN_ERR "emulation failed (%s) rip %lx %02x %02x %02x %02x\n", | ||
3656 | context, rip, opcodes[0], opcodes[1], opcodes[2], opcodes[3]); | ||
3657 | } | ||
3658 | EXPORT_SYMBOL_GPL(kvm_report_emulation_failure); | ||
3659 | |||
3660 | static u64 mk_cr_64(u64 curr_cr, u32 new_val) | 3642 | static u64 mk_cr_64(u64 curr_cr, u32 new_val) |
3661 | { | 3643 | { |
3662 | return (curr_cr & ~((1ULL << 32) - 1)) | new_val; | 3644 | return (curr_cr & ~((1ULL << 32) - 1)) | new_val; |
@@ -3863,6 +3845,19 @@ static void inject_emulated_exception(struct kvm_vcpu *vcpu) | |||
3863 | kvm_queue_exception(vcpu, ctxt->exception); | 3845 | kvm_queue_exception(vcpu, ctxt->exception); |
3864 | } | 3846 | } |
3865 | 3847 | ||
3848 | static int handle_emulation_failure(struct kvm_vcpu *vcpu) | ||
3849 | { | ||
3850 | struct x86_emulate_ctxt *ctxt = &vcpu->arch.emulate_ctxt; | ||
3851 | |||
3852 | ++vcpu->stat.insn_emulation_fail; | ||
3853 | trace_kvm_emulate_insn_failed(vcpu); | ||
3854 | vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; | ||
3855 | vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION; | ||
3856 | vcpu->run->internal.ndata = 0; | ||
3857 | kvm_queue_exception(vcpu, UD_VECTOR); | ||
3858 | return EMULATE_FAIL; | ||
3859 | } | ||
3860 | |||
3866 | int emulate_instruction(struct kvm_vcpu *vcpu, | 3861 | int emulate_instruction(struct kvm_vcpu *vcpu, |
3867 | unsigned long cr2, | 3862 | unsigned long cr2, |
3868 | u16 error_code, | 3863 | u16 error_code, |
@@ -3931,11 +3926,11 @@ int emulate_instruction(struct kvm_vcpu *vcpu, | |||
3931 | 3926 | ||
3932 | ++vcpu->stat.insn_emulation; | 3927 | ++vcpu->stat.insn_emulation; |
3933 | if (r) { | 3928 | if (r) { |
3934 | ++vcpu->stat.insn_emulation_fail; | ||
3935 | trace_kvm_emulate_insn_failed(vcpu); | ||
3936 | if (kvm_mmu_unprotect_page_virt(vcpu, cr2)) | 3929 | if (kvm_mmu_unprotect_page_virt(vcpu, cr2)) |
3937 | return EMULATE_DONE; | 3930 | return EMULATE_DONE; |
3938 | return EMULATE_FAIL; | 3931 | if (emulation_type & EMULTYPE_SKIP) |
3932 | return EMULATE_FAIL; | ||
3933 | return handle_emulation_failure(vcpu); | ||
3939 | } | 3934 | } |
3940 | } | 3935 | } |
3941 | 3936 | ||
@@ -3960,9 +3955,7 @@ restart: | |||
3960 | if (kvm_mmu_unprotect_page_virt(vcpu, cr2)) | 3955 | if (kvm_mmu_unprotect_page_virt(vcpu, cr2)) |
3961 | return EMULATE_DONE; | 3956 | return EMULATE_DONE; |
3962 | 3957 | ||
3963 | trace_kvm_emulate_insn_failed(vcpu); | 3958 | return handle_emulation_failure(vcpu); |
3964 | kvm_report_emulation_failure(vcpu, "mmio"); | ||
3965 | return EMULATE_FAIL; | ||
3966 | } | 3959 | } |
3967 | 3960 | ||
3968 | toggle_interruptibility(vcpu, vcpu->arch.emulate_ctxt.interruptibility); | 3961 | toggle_interruptibility(vcpu, vcpu->arch.emulate_ctxt.interruptibility); |
@@ -4798,7 +4791,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
4798 | vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); | 4791 | vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); |
4799 | r = emulate_instruction(vcpu, 0, 0, EMULTYPE_NO_DECODE); | 4792 | r = emulate_instruction(vcpu, 0, 0, EMULTYPE_NO_DECODE); |
4800 | srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx); | 4793 | srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx); |
4801 | if (r == EMULATE_DO_MMIO) { | 4794 | if (r != EMULATE_DONE) { |
4802 | r = 0; | 4795 | r = 0; |
4803 | goto out; | 4796 | goto out; |
4804 | } | 4797 | } |