diff options
| -rw-r--r-- | drivers/kvm/svm.c | 18 | ||||
| -rw-r--r-- | drivers/kvm/x86_emulate.c | 26 |
2 files changed, 28 insertions, 16 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 | ||
diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c index a6ace302e0cd..33b181451557 100644 --- a/drivers/kvm/x86_emulate.c +++ b/drivers/kvm/x86_emulate.c | |||
| @@ -167,7 +167,7 @@ static u8 opcode_table[256] = { | |||
| 167 | static u16 twobyte_table[256] = { | 167 | static u16 twobyte_table[256] = { |
| 168 | /* 0x00 - 0x0F */ | 168 | /* 0x00 - 0x0F */ |
| 169 | 0, SrcMem | ModRM | DstReg, 0, 0, 0, 0, ImplicitOps, 0, | 169 | 0, SrcMem | ModRM | DstReg, 0, 0, 0, 0, ImplicitOps, 0, |
| 170 | 0, ImplicitOps, 0, 0, 0, ImplicitOps | ModRM, 0, 0, | 170 | ImplicitOps, ImplicitOps, 0, 0, 0, ImplicitOps | ModRM, 0, 0, |
| 171 | /* 0x10 - 0x1F */ | 171 | /* 0x10 - 0x1F */ |
| 172 | 0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps | ModRM, 0, 0, 0, 0, 0, 0, 0, | 172 | 0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps | ModRM, 0, 0, 0, 0, 0, 0, 0, |
| 173 | /* 0x20 - 0x2F */ | 173 | /* 0x20 - 0x2F */ |
| @@ -980,17 +980,6 @@ done_prefixes: | |||
| 980 | goto cannot_emulate; | 980 | goto cannot_emulate; |
| 981 | dst.val = (s32) src.val; | 981 | dst.val = (s32) src.val; |
| 982 | break; | 982 | break; |
| 983 | case 0x6a: /* push imm8 */ | ||
| 984 | src.val = 0L; | ||
| 985 | src.val = insn_fetch(s8, 1, _eip); | ||
| 986 | push: | ||
| 987 | dst.type = OP_MEM; | ||
| 988 | dst.bytes = op_bytes; | ||
| 989 | dst.val = src.val; | ||
| 990 | register_address_increment(_regs[VCPU_REGS_RSP], -op_bytes); | ||
| 991 | dst.ptr = (void *) register_address(ctxt->ss_base, | ||
| 992 | _regs[VCPU_REGS_RSP]); | ||
| 993 | break; | ||
| 994 | case 0x80 ... 0x83: /* Grp1 */ | 983 | case 0x80 ... 0x83: /* Grp1 */ |
| 995 | switch (modrm_reg) { | 984 | switch (modrm_reg) { |
| 996 | case 0: | 985 | case 0: |
| @@ -1243,6 +1232,17 @@ special_insn: | |||
| 1243 | register_address_increment(_regs[VCPU_REGS_RSP], op_bytes); | 1232 | register_address_increment(_regs[VCPU_REGS_RSP], op_bytes); |
| 1244 | no_wb = 1; /* Disable writeback. */ | 1233 | no_wb = 1; /* Disable writeback. */ |
| 1245 | break; | 1234 | break; |
| 1235 | case 0x6a: /* push imm8 */ | ||
| 1236 | src.val = 0L; | ||
| 1237 | src.val = insn_fetch(s8, 1, _eip); | ||
| 1238 | push: | ||
| 1239 | dst.type = OP_MEM; | ||
| 1240 | dst.bytes = op_bytes; | ||
| 1241 | dst.val = src.val; | ||
| 1242 | register_address_increment(_regs[VCPU_REGS_RSP], -op_bytes); | ||
| 1243 | dst.ptr = (void *) register_address(ctxt->ss_base, | ||
| 1244 | _regs[VCPU_REGS_RSP]); | ||
| 1245 | break; | ||
| 1246 | case 0x6c: /* insb */ | 1246 | case 0x6c: /* insb */ |
| 1247 | case 0x6d: /* insw/insd */ | 1247 | case 0x6d: /* insw/insd */ |
| 1248 | if (kvm_emulate_pio_string(ctxt->vcpu, NULL, | 1248 | if (kvm_emulate_pio_string(ctxt->vcpu, NULL, |
| @@ -1532,6 +1532,8 @@ twobyte_special_insn: | |||
| 1532 | case 0x06: | 1532 | case 0x06: |
| 1533 | emulate_clts(ctxt->vcpu); | 1533 | emulate_clts(ctxt->vcpu); |
| 1534 | break; | 1534 | break; |
| 1535 | case 0x08: /* invd */ | ||
| 1536 | break; | ||
| 1535 | case 0x09: /* wbinvd */ | 1537 | case 0x09: /* wbinvd */ |
| 1536 | break; | 1538 | break; |
| 1537 | case 0x0d: /* GrpP (prefetch) */ | 1539 | case 0x0d: /* GrpP (prefetch) */ |
