mirror of
https://github.com/torvalds/linux.git
synced 2024-11-11 22:51:42 +00:00
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
This commit is contained in:
commit
e6a5c27f3b
@ -494,6 +494,7 @@ static void init_vmcb(struct vmcb *vmcb)
|
|||||||
*/
|
*/
|
||||||
/* (1ULL << INTERCEPT_SELECTIVE_CR0) | */
|
/* (1ULL << INTERCEPT_SELECTIVE_CR0) | */
|
||||||
(1ULL << INTERCEPT_CPUID) |
|
(1ULL << INTERCEPT_CPUID) |
|
||||||
|
(1ULL << INTERCEPT_INVD) |
|
||||||
(1ULL << INTERCEPT_HLT) |
|
(1ULL << INTERCEPT_HLT) |
|
||||||
(1ULL << INTERCEPT_INVLPGA) |
|
(1ULL << INTERCEPT_INVLPGA) |
|
||||||
(1ULL << INTERCEPT_IOIO_PROT) |
|
(1ULL << INTERCEPT_IOIO_PROT) |
|
||||||
@ -507,6 +508,7 @@ static void init_vmcb(struct vmcb *vmcb)
|
|||||||
(1ULL << INTERCEPT_STGI) |
|
(1ULL << INTERCEPT_STGI) |
|
||||||
(1ULL << INTERCEPT_CLGI) |
|
(1ULL << INTERCEPT_CLGI) |
|
||||||
(1ULL << INTERCEPT_SKINIT) |
|
(1ULL << INTERCEPT_SKINIT) |
|
||||||
|
(1ULL << INTERCEPT_WBINVD) |
|
||||||
(1ULL << INTERCEPT_MONITOR) |
|
(1ULL << INTERCEPT_MONITOR) |
|
||||||
(1ULL << INTERCEPT_MWAIT);
|
(1ULL << INTERCEPT_MWAIT);
|
||||||
|
|
||||||
@ -561,6 +563,12 @@ static void svm_vcpu_reset(struct kvm_vcpu *vcpu)
|
|||||||
struct vcpu_svm *svm = to_svm(vcpu);
|
struct vcpu_svm *svm = to_svm(vcpu);
|
||||||
|
|
||||||
init_vmcb(svm->vmcb);
|
init_vmcb(svm->vmcb);
|
||||||
|
|
||||||
|
if (vcpu->vcpu_id != 0) {
|
||||||
|
svm->vmcb->save.rip = 0;
|
||||||
|
svm->vmcb->save.cs.base = svm->vcpu.sipi_vector << 12;
|
||||||
|
svm->vmcb->save.cs.selector = svm->vcpu.sipi_vector << 8;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id)
|
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,
|
|||||||
[SVM_EXIT_VINTR] = interrupt_window_interception,
|
[SVM_EXIT_VINTR] = interrupt_window_interception,
|
||||||
/* [SVM_EXIT_CR0_SEL_WRITE] = emulate_on_interception, */
|
/* [SVM_EXIT_CR0_SEL_WRITE] = emulate_on_interception, */
|
||||||
[SVM_EXIT_CPUID] = cpuid_interception,
|
[SVM_EXIT_CPUID] = cpuid_interception,
|
||||||
|
[SVM_EXIT_INVD] = emulate_on_interception,
|
||||||
[SVM_EXIT_HLT] = halt_interception,
|
[SVM_EXIT_HLT] = halt_interception,
|
||||||
[SVM_EXIT_INVLPG] = emulate_on_interception,
|
[SVM_EXIT_INVLPG] = emulate_on_interception,
|
||||||
[SVM_EXIT_INVLPGA] = invalid_op_interception,
|
[SVM_EXIT_INVLPGA] = invalid_op_interception,
|
||||||
@ -1255,6 +1264,7 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm,
|
|||||||
[SVM_EXIT_STGI] = invalid_op_interception,
|
[SVM_EXIT_STGI] = invalid_op_interception,
|
||||||
[SVM_EXIT_CLGI] = invalid_op_interception,
|
[SVM_EXIT_CLGI] = invalid_op_interception,
|
||||||
[SVM_EXIT_SKINIT] = invalid_op_interception,
|
[SVM_EXIT_SKINIT] = invalid_op_interception,
|
||||||
|
[SVM_EXIT_WBINVD] = emulate_on_interception,
|
||||||
[SVM_EXIT_MONITOR] = invalid_op_interception,
|
[SVM_EXIT_MONITOR] = invalid_op_interception,
|
||||||
[SVM_EXIT_MWAIT] = invalid_op_interception,
|
[SVM_EXIT_MWAIT] = invalid_op_interception,
|
||||||
};
|
};
|
||||||
@ -1579,10 +1589,6 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
|
|||||||
#endif
|
#endif
|
||||||
: "cc", "memory" );
|
: "cc", "memory" );
|
||||||
|
|
||||||
local_irq_disable();
|
|
||||||
|
|
||||||
stgi();
|
|
||||||
|
|
||||||
if ((svm->vmcb->save.dr7 & 0xff))
|
if ((svm->vmcb->save.dr7 & 0xff))
|
||||||
load_db_regs(svm->host_db_regs);
|
load_db_regs(svm->host_db_regs);
|
||||||
|
|
||||||
@ -1599,6 +1605,10 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
|
|||||||
|
|
||||||
reload_tss(vcpu);
|
reload_tss(vcpu);
|
||||||
|
|
||||||
|
local_irq_disable();
|
||||||
|
|
||||||
|
stgi();
|
||||||
|
|
||||||
svm->next_rip = 0;
|
svm->next_rip = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,7 +167,7 @@ static u8 opcode_table[256] = {
|
|||||||
static u16 twobyte_table[256] = {
|
static u16 twobyte_table[256] = {
|
||||||
/* 0x00 - 0x0F */
|
/* 0x00 - 0x0F */
|
||||||
0, SrcMem | ModRM | DstReg, 0, 0, 0, 0, ImplicitOps, 0,
|
0, SrcMem | ModRM | DstReg, 0, 0, 0, 0, ImplicitOps, 0,
|
||||||
0, ImplicitOps, 0, 0, 0, ImplicitOps | ModRM, 0, 0,
|
ImplicitOps, ImplicitOps, 0, 0, 0, ImplicitOps | ModRM, 0, 0,
|
||||||
/* 0x10 - 0x1F */
|
/* 0x10 - 0x1F */
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps | ModRM, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps | ModRM, 0, 0, 0, 0, 0, 0, 0,
|
||||||
/* 0x20 - 0x2F */
|
/* 0x20 - 0x2F */
|
||||||
@ -980,17 +980,6 @@ done_prefixes:
|
|||||||
goto cannot_emulate;
|
goto cannot_emulate;
|
||||||
dst.val = (s32) src.val;
|
dst.val = (s32) src.val;
|
||||||
break;
|
break;
|
||||||
case 0x6a: /* push imm8 */
|
|
||||||
src.val = 0L;
|
|
||||||
src.val = insn_fetch(s8, 1, _eip);
|
|
||||||
push:
|
|
||||||
dst.type = OP_MEM;
|
|
||||||
dst.bytes = op_bytes;
|
|
||||||
dst.val = src.val;
|
|
||||||
register_address_increment(_regs[VCPU_REGS_RSP], -op_bytes);
|
|
||||||
dst.ptr = (void *) register_address(ctxt->ss_base,
|
|
||||||
_regs[VCPU_REGS_RSP]);
|
|
||||||
break;
|
|
||||||
case 0x80 ... 0x83: /* Grp1 */
|
case 0x80 ... 0x83: /* Grp1 */
|
||||||
switch (modrm_reg) {
|
switch (modrm_reg) {
|
||||||
case 0:
|
case 0:
|
||||||
@ -1243,6 +1232,17 @@ special_insn:
|
|||||||
register_address_increment(_regs[VCPU_REGS_RSP], op_bytes);
|
register_address_increment(_regs[VCPU_REGS_RSP], op_bytes);
|
||||||
no_wb = 1; /* Disable writeback. */
|
no_wb = 1; /* Disable writeback. */
|
||||||
break;
|
break;
|
||||||
|
case 0x6a: /* push imm8 */
|
||||||
|
src.val = 0L;
|
||||||
|
src.val = insn_fetch(s8, 1, _eip);
|
||||||
|
push:
|
||||||
|
dst.type = OP_MEM;
|
||||||
|
dst.bytes = op_bytes;
|
||||||
|
dst.val = src.val;
|
||||||
|
register_address_increment(_regs[VCPU_REGS_RSP], -op_bytes);
|
||||||
|
dst.ptr = (void *) register_address(ctxt->ss_base,
|
||||||
|
_regs[VCPU_REGS_RSP]);
|
||||||
|
break;
|
||||||
case 0x6c: /* insb */
|
case 0x6c: /* insb */
|
||||||
case 0x6d: /* insw/insd */
|
case 0x6d: /* insw/insd */
|
||||||
if (kvm_emulate_pio_string(ctxt->vcpu, NULL,
|
if (kvm_emulate_pio_string(ctxt->vcpu, NULL,
|
||||||
@ -1532,6 +1532,8 @@ twobyte_special_insn:
|
|||||||
case 0x06:
|
case 0x06:
|
||||||
emulate_clts(ctxt->vcpu);
|
emulate_clts(ctxt->vcpu);
|
||||||
break;
|
break;
|
||||||
|
case 0x08: /* invd */
|
||||||
|
break;
|
||||||
case 0x09: /* wbinvd */
|
case 0x09: /* wbinvd */
|
||||||
break;
|
break;
|
||||||
case 0x0d: /* GrpP (prefetch) */
|
case 0x0d: /* GrpP (prefetch) */
|
||||||
|
Loading…
Reference in New Issue
Block a user