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>

+31 -5
+2
drivers/kvm/kvm.h
··· 569 569 unsigned long realmode_get_cr(struct kvm_vcpu *vcpu, int cr); 570 570 void realmode_set_cr(struct kvm_vcpu *vcpu, int cr, unsigned long value, 571 571 unsigned long *rflags); 572 + int kvm_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *data); 573 + int kvm_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data); 572 574 573 575 struct x86_emulate_ctxt; 574 576
+4 -4
drivers/kvm/kvm_main.c
··· 1517 1517 * Returns 0 on success, non-0 otherwise. 1518 1518 * Assumes vcpu_load() was already called. 1519 1519 */ 1520 - static int get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata) 1520 + int kvm_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata) 1521 1521 { 1522 1522 return kvm_arch_ops->get_msr(vcpu, msr_index, pdata); 1523 1523 } ··· 1595 1595 * Returns 0 on success, non-0 otherwise. 1596 1596 * Assumes vcpu_load() was already called. 1597 1597 */ 1598 - static int set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data) 1598 + int kvm_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data) 1599 1599 { 1600 1600 return kvm_arch_ops->set_msr(vcpu, msr_index, data); 1601 1601 } ··· 2133 2133 */ 2134 2134 static int do_set_msr(struct kvm_vcpu *vcpu, unsigned index, u64 *data) 2135 2135 { 2136 - return set_msr(vcpu, index, *data); 2136 + return kvm_set_msr(vcpu, index, *data); 2137 2137 } 2138 2138 2139 2139 /* ··· 2617 2617 break; 2618 2618 } 2619 2619 case KVM_GET_MSRS: 2620 - r = msr_io(vcpu, argp, get_msr, 1); 2620 + r = msr_io(vcpu, argp, kvm_get_msr, 1); 2621 2621 break; 2622 2622 case KVM_SET_MSRS: 2623 2623 r = msr_io(vcpu, argp, do_set_msr, 0);
+25 -1
drivers/kvm/x86_emulate.c
··· 163 163 ModRM | ImplicitOps, ModRM, ModRM | ImplicitOps, ModRM, 0, 0, 0, 0, 164 164 0, 0, 0, 0, 0, 0, 0, 0, 165 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 167 /* 0x40 - 0x47 */ 168 168 DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov, 169 169 DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov, ··· 486 486 unsigned long modrm_ea; 487 487 int use_modrm_ea, index_reg = 0, base_reg = 0, scale, rip_relative = 0; 488 488 int no_wb = 0; 489 + u64 msr_data; 489 490 490 491 /* Shadow copy of register state. Committed on successful emulation. */ 491 492 unsigned long _regs[NR_VCPU_REGS]; ··· 1344 1343 if (modrm_mod != 3) 1345 1344 goto cannot_emulate; 1346 1345 realmode_set_cr(ctxt->vcpu, modrm_reg, modrm_val, &_eflags); 1346 + break; 1347 + case 0x30: 1348 + /* wrmsr */ 1349 + msr_data = (u32)_regs[VCPU_REGS_RAX] 1350 + | ((u64)_regs[VCPU_REGS_RDX] << 32); 1351 + rc = kvm_set_msr(ctxt->vcpu, _regs[VCPU_REGS_RCX], msr_data); 1352 + if (rc) { 1353 + kvm_arch_ops->inject_gp(ctxt->vcpu, 0); 1354 + _eip = ctxt->vcpu->rip; 1355 + } 1356 + rc = X86EMUL_CONTINUE; 1357 + break; 1358 + case 0x32: 1359 + /* rdmsr */ 1360 + rc = kvm_get_msr(ctxt->vcpu, _regs[VCPU_REGS_RCX], &msr_data); 1361 + if (rc) { 1362 + kvm_arch_ops->inject_gp(ctxt->vcpu, 0); 1363 + _eip = ctxt->vcpu->rip; 1364 + } else { 1365 + _regs[VCPU_REGS_RAX] = (u32)msr_data; 1366 + _regs[VCPU_REGS_RDX] = msr_data >> 32; 1367 + } 1368 + rc = X86EMUL_CONTINUE; 1347 1369 break; 1348 1370 case 0xc7: /* Grp9 (cmpxchg8b) */ 1349 1371 {