diff options
| author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-11-12 14:13:54 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-11-12 14:13:54 -0500 |
| commit | e6a5c27f3b0fef72e528fc35e343af4b2db790ff (patch) | |
| tree | c34374b96071fe4c5579643da2c10fb630d23b10 /drivers/kvm/svm.c | |
| parent | 05f3f415894d061f7d3e77e3d46caeb4c184b005 (diff) | |
| parent | cf5a94d1331b411b84414c13e43f578260942d6b (diff) | |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/avi/kvm
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/avi/kvm:
KVM: SVM: Intercept the 'invd' and 'wbinvd' instructions
KVM: x86 emulator: invd instruction
KVM: SVM: Defer nmi processing until switch to host state is complete
KVM: SVM: Fix SMP with kernel apic
KVM: x86 emulator: fix 'push imm8' emulation
Diffstat (limited to 'drivers/kvm/svm.c')
| -rw-r--r-- | drivers/kvm/svm.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c index 729f1cd93606..7a6eead63a6b 100644 --- a/drivers/kvm/svm.c +++ b/drivers/kvm/svm.c | |||
| @@ -494,6 +494,7 @@ static void init_vmcb(struct vmcb *vmcb) | |||
| 494 | */ | 494 | */ |
| 495 | /* (1ULL << INTERCEPT_SELECTIVE_CR0) | */ | 495 | /* (1ULL << INTERCEPT_SELECTIVE_CR0) | */ |
| 496 | (1ULL << INTERCEPT_CPUID) | | 496 | (1ULL << INTERCEPT_CPUID) | |
| 497 | (1ULL << INTERCEPT_INVD) | | ||
| 497 | (1ULL << INTERCEPT_HLT) | | 498 | (1ULL << INTERCEPT_HLT) | |
| 498 | (1ULL << INTERCEPT_INVLPGA) | | 499 | (1ULL << INTERCEPT_INVLPGA) | |
| 499 | (1ULL << INTERCEPT_IOIO_PROT) | | 500 | (1ULL << INTERCEPT_IOIO_PROT) | |
| @@ -507,6 +508,7 @@ static void init_vmcb(struct vmcb *vmcb) | |||
| 507 | (1ULL << INTERCEPT_STGI) | | 508 | (1ULL << INTERCEPT_STGI) | |
| 508 | (1ULL << INTERCEPT_CLGI) | | 509 | (1ULL << INTERCEPT_CLGI) | |
| 509 | (1ULL << INTERCEPT_SKINIT) | | 510 | (1ULL << INTERCEPT_SKINIT) | |
| 511 | (1ULL << INTERCEPT_WBINVD) | | ||
| 510 | (1ULL << INTERCEPT_MONITOR) | | 512 | (1ULL << INTERCEPT_MONITOR) | |
| 511 | (1ULL << INTERCEPT_MWAIT); | 513 | (1ULL << INTERCEPT_MWAIT); |
| 512 | 514 | ||
| @@ -561,6 +563,12 @@ static void svm_vcpu_reset(struct kvm_vcpu *vcpu) | |||
| 561 | struct vcpu_svm *svm = to_svm(vcpu); | 563 | struct vcpu_svm *svm = to_svm(vcpu); |
| 562 | 564 | ||
| 563 | init_vmcb(svm->vmcb); | 565 | init_vmcb(svm->vmcb); |
| 566 | |||
| 567 | if (vcpu->vcpu_id != 0) { | ||
| 568 | svm->vmcb->save.rip = 0; | ||
| 569 | svm->vmcb->save.cs.base = svm->vcpu.sipi_vector << 12; | ||
| 570 | svm->vmcb->save.cs.selector = svm->vcpu.sipi_vector << 8; | ||
| 571 | } | ||
| 564 | } | 572 | } |
| 565 | 573 | ||
| 566 | static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id) | 574 | static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id) |
| @@ -1241,6 +1249,7 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm, | |||
| 1241 | [SVM_EXIT_VINTR] = interrupt_window_interception, | 1249 | [SVM_EXIT_VINTR] = interrupt_window_interception, |
| 1242 | /* [SVM_EXIT_CR0_SEL_WRITE] = emulate_on_interception, */ | 1250 | /* [SVM_EXIT_CR0_SEL_WRITE] = emulate_on_interception, */ |
| 1243 | [SVM_EXIT_CPUID] = cpuid_interception, | 1251 | [SVM_EXIT_CPUID] = cpuid_interception, |
| 1252 | [SVM_EXIT_INVD] = emulate_on_interception, | ||
| 1244 | [SVM_EXIT_HLT] = halt_interception, | 1253 | [SVM_EXIT_HLT] = halt_interception, |
| 1245 | [SVM_EXIT_INVLPG] = emulate_on_interception, | 1254 | [SVM_EXIT_INVLPG] = emulate_on_interception, |
| 1246 | [SVM_EXIT_INVLPGA] = invalid_op_interception, | 1255 | [SVM_EXIT_INVLPGA] = invalid_op_interception, |
| @@ -1255,6 +1264,7 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm, | |||
| 1255 | [SVM_EXIT_STGI] = invalid_op_interception, | 1264 | [SVM_EXIT_STGI] = invalid_op_interception, |
| 1256 | [SVM_EXIT_CLGI] = invalid_op_interception, | 1265 | [SVM_EXIT_CLGI] = invalid_op_interception, |
| 1257 | [SVM_EXIT_SKINIT] = invalid_op_interception, | 1266 | [SVM_EXIT_SKINIT] = invalid_op_interception, |
| 1267 | [SVM_EXIT_WBINVD] = emulate_on_interception, | ||
| 1258 | [SVM_EXIT_MONITOR] = invalid_op_interception, | 1268 | [SVM_EXIT_MONITOR] = invalid_op_interception, |
| 1259 | [SVM_EXIT_MWAIT] = invalid_op_interception, | 1269 | [SVM_EXIT_MWAIT] = invalid_op_interception, |
| 1260 | }; | 1270 | }; |
| @@ -1579,10 +1589,6 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
| 1579 | #endif | 1589 | #endif |
| 1580 | : "cc", "memory" ); | 1590 | : "cc", "memory" ); |
| 1581 | 1591 | ||
| 1582 | local_irq_disable(); | ||
| 1583 | |||
| 1584 | stgi(); | ||
| 1585 | |||
| 1586 | if ((svm->vmcb->save.dr7 & 0xff)) | 1592 | if ((svm->vmcb->save.dr7 & 0xff)) |
| 1587 | load_db_regs(svm->host_db_regs); | 1593 | load_db_regs(svm->host_db_regs); |
| 1588 | 1594 | ||
| @@ -1599,6 +1605,10 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
| 1599 | 1605 | ||
| 1600 | reload_tss(vcpu); | 1606 | reload_tss(vcpu); |
| 1601 | 1607 | ||
| 1608 | local_irq_disable(); | ||
| 1609 | |||
| 1610 | stgi(); | ||
| 1611 | |||
| 1602 | svm->next_rip = 0; | 1612 | svm->next_rip = 0; |
| 1603 | } | 1613 | } |
| 1604 | 1614 | ||
