aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm/svm.c
diff options
context:
space:
mode:
authorAnthony Liguori <aliguori@us.ibm.com>2007-09-17 15:57:50 -0400
committerAvi Kivity <avi@qumranet.com>2008-01-30 10:52:46 -0500
commit7aa81cc04781b5b99a0647ec04533599d78cd219 (patch)
tree6ac8854faf3db2bc499e2c105fdfdab95df52170 /drivers/kvm/svm.c
parentaca7f96600b170e470b3056aba0ed8d7df8d330d (diff)
KVM: Refactor hypercall infrastructure (v3)
This patch refactors the current hypercall infrastructure to better support live migration and SMP. It eliminates the hypercall page by trapping the UD exception that would occur if you used the wrong hypercall instruction for the underlying architecture and replacing it with the right one lazily. A fall-out of this patch is that the unhandled hypercalls no longer trap to userspace. There is very little reason though to use a hypercall to communicate with userspace as PIO or MMIO can be used. There is no code in tree that uses userspace hypercalls. [avi: fix #ud injection on vmx] Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'drivers/kvm/svm.c')
-rw-r--r--drivers/kvm/svm.c19
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
983static 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
982static int nm_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) 994static 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
1051static int invalid_op_interception(struct vcpu_svm *svm, 1064static 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
1681static void svm_check_processor_compat(void *rtn) 1694static void svm_check_processor_compat(void *rtn)