diff options
Diffstat (limited to 'drivers/kvm/svm.c')
-rw-r--r-- | drivers/kvm/svm.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c index ced4ac1955db..794d95416f7b 100644 --- a/drivers/kvm/svm.c +++ b/drivers/kvm/svm.c | |||
@@ -476,7 +476,8 @@ static void init_vmcb(struct vmcb *vmcb) | |||
476 | INTERCEPT_DR5_MASK | | 476 | INTERCEPT_DR5_MASK | |
477 | INTERCEPT_DR7_MASK; | 477 | INTERCEPT_DR7_MASK; |
478 | 478 | ||
479 | control->intercept_exceptions = 1 << PF_VECTOR; | 479 | control->intercept_exceptions = (1 << PF_VECTOR) | |
480 | (1 << UD_VECTOR); | ||
480 | 481 | ||
481 | 482 | ||
482 | control->intercept = (1ULL << INTERCEPT_INTR) | | 483 | control->intercept = (1ULL << INTERCEPT_INTR) | |
@@ -979,6 +980,17 @@ static int pf_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) | |||
979 | return 0; | 980 | return 0; |
980 | } | 981 | } |
981 | 982 | ||
983 | static int ud_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) | ||
984 | { | ||
985 | int er; | ||
986 | |||
987 | er = emulate_instruction(&svm->vcpu, kvm_run, 0, 0); | ||
988 | if (er != EMULATE_DONE) | ||
989 | inject_ud(&svm->vcpu); | ||
990 | |||
991 | return 1; | ||
992 | } | ||
993 | |||
982 | static int nm_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) | 994 | static int nm_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) |
983 | { | 995 | { |
984 | svm->vmcb->control.intercept_exceptions &= ~(1 << NM_VECTOR); | 996 | svm->vmcb->control.intercept_exceptions &= ~(1 << NM_VECTOR); |
@@ -1045,7 +1057,8 @@ static int vmmcall_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) | |||
1045 | { | 1057 | { |
1046 | svm->next_rip = svm->vmcb->save.rip + 3; | 1058 | svm->next_rip = svm->vmcb->save.rip + 3; |
1047 | skip_emulated_instruction(&svm->vcpu); | 1059 | skip_emulated_instruction(&svm->vcpu); |
1048 | return kvm_hypercall(&svm->vcpu, kvm_run); | 1060 | kvm_emulate_hypercall(&svm->vcpu); |
1061 | return 1; | ||
1049 | } | 1062 | } |
1050 | 1063 | ||
1051 | static int invalid_op_interception(struct vcpu_svm *svm, | 1064 | static int invalid_op_interception(struct vcpu_svm *svm, |
@@ -1241,6 +1254,7 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm, | |||
1241 | [SVM_EXIT_WRITE_DR3] = emulate_on_interception, | 1254 | [SVM_EXIT_WRITE_DR3] = emulate_on_interception, |
1242 | [SVM_EXIT_WRITE_DR5] = emulate_on_interception, | 1255 | [SVM_EXIT_WRITE_DR5] = emulate_on_interception, |
1243 | [SVM_EXIT_WRITE_DR7] = emulate_on_interception, | 1256 | [SVM_EXIT_WRITE_DR7] = emulate_on_interception, |
1257 | [SVM_EXIT_EXCP_BASE + UD_VECTOR] = ud_interception, | ||
1244 | [SVM_EXIT_EXCP_BASE + PF_VECTOR] = pf_interception, | 1258 | [SVM_EXIT_EXCP_BASE + PF_VECTOR] = pf_interception, |
1245 | [SVM_EXIT_EXCP_BASE + NM_VECTOR] = nm_interception, | 1259 | [SVM_EXIT_EXCP_BASE + NM_VECTOR] = nm_interception, |
1246 | [SVM_EXIT_INTR] = nop_on_interception, | 1260 | [SVM_EXIT_INTR] = nop_on_interception, |
@@ -1675,7 +1689,6 @@ svm_patch_hypercall(struct kvm_vcpu *vcpu, unsigned char *hypercall) | |||
1675 | hypercall[0] = 0x0f; | 1689 | hypercall[0] = 0x0f; |
1676 | hypercall[1] = 0x01; | 1690 | hypercall[1] = 0x01; |
1677 | hypercall[2] = 0xd9; | 1691 | hypercall[2] = 0xd9; |
1678 | hypercall[3] = 0xc3; | ||
1679 | } | 1692 | } |
1680 | 1693 | ||
1681 | static void svm_check_processor_compat(void *rtn) | 1694 | static void svm_check_processor_compat(void *rtn) |