aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm/x86_emulate.c
diff options
context:
space:
mode:
authorAvi Kivity <avi@qumranet.com>2007-07-17 07:20:30 -0400
committerAvi Kivity <avi@qumranet.com>2007-07-20 13:16:29 -0400
commit35f3f28613bc7263949db23a4c7078e425810c8c (patch)
tree134729d56cf503029e1e667df9bfe30b7410ad3b /drivers/kvm/x86_emulate.c
parent90cb0529dd230548a7f0d6b315997be854caea1b (diff)
KVM: x86 emulator: implement rdmsr and wrmsr
Allow real-mode emulation of rdmsr and wrmsr. This allows smp Windows to boot, presumably for its sipi trampoline. Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'drivers/kvm/x86_emulate.c')
-rw-r--r--drivers/kvm/x86_emulate.c26
1 files changed, 25 insertions, 1 deletions
diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index f60012d62610..1b800fc00342 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -163,7 +163,7 @@ static u16 twobyte_table[256] = {
163 ModRM | ImplicitOps, ModRM, ModRM | ImplicitOps, ModRM, 0, 0, 0, 0, 163 ModRM | ImplicitOps, ModRM, ModRM | ImplicitOps, ModRM, 0, 0, 0, 0,
164 0, 0, 0, 0, 0, 0, 0, 0, 164 0, 0, 0, 0, 0, 0, 0, 0,
165 /* 0x30 - 0x3F */ 165 /* 0x30 - 0x3F */
166 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166 ImplicitOps, 0, ImplicitOps, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
167 /* 0x40 - 0x47 */ 167 /* 0x40 - 0x47 */
168 DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov, 168 DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
169 DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov, 169 DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
@@ -486,6 +486,7 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
486 unsigned long modrm_ea; 486 unsigned long modrm_ea;
487 int use_modrm_ea, index_reg = 0, base_reg = 0, scale, rip_relative = 0; 487 int use_modrm_ea, index_reg = 0, base_reg = 0, scale, rip_relative = 0;
488 int no_wb = 0; 488 int no_wb = 0;
489 u64 msr_data;
489 490
490 /* Shadow copy of register state. Committed on successful emulation. */ 491 /* Shadow copy of register state. Committed on successful emulation. */
491 unsigned long _regs[NR_VCPU_REGS]; 492 unsigned long _regs[NR_VCPU_REGS];
@@ -1344,6 +1345,29 @@ twobyte_special_insn:
1344 goto cannot_emulate; 1345 goto cannot_emulate;
1345 realmode_set_cr(ctxt->vcpu, modrm_reg, modrm_val, &_eflags); 1346 realmode_set_cr(ctxt->vcpu, modrm_reg, modrm_val, &_eflags);
1346 break; 1347 break;
1348 case 0x30:
1349 /* wrmsr */
1350 msr_data = (u32)_regs[VCPU_REGS_RAX]
1351 | ((u64)_regs[VCPU_REGS_RDX] << 32);
1352 rc = kvm_set_msr(ctxt->vcpu, _regs[VCPU_REGS_RCX], msr_data);
1353 if (rc) {
1354 kvm_arch_ops->inject_gp(ctxt->vcpu, 0);
1355 _eip = ctxt->vcpu->rip;
1356 }
1357 rc = X86EMUL_CONTINUE;
1358 break;
1359 case 0x32:
1360 /* rdmsr */
1361 rc = kvm_get_msr(ctxt->vcpu, _regs[VCPU_REGS_RCX], &msr_data);
1362 if (rc) {
1363 kvm_arch_ops->inject_gp(ctxt->vcpu, 0);
1364 _eip = ctxt->vcpu->rip;
1365 } else {
1366 _regs[VCPU_REGS_RAX] = (u32)msr_data;
1367 _regs[VCPU_REGS_RDX] = msr_data >> 32;
1368 }
1369 rc = X86EMUL_CONTINUE;
1370 break;
1347 case 0xc7: /* Grp9 (cmpxchg8b) */ 1371 case 0xc7: /* Grp9 (cmpxchg8b) */
1348 { 1372 {
1349 u64 old, new; 1373 u64 old, new;