]> err.no Git - linux-2.6/blobdiff - drivers/kvm/x86_emulate.c
m68k/mac: Make mac_hid_mouse_emulate_buttons() declaration visible
[linux-2.6] / drivers / kvm / x86_emulate.c
index f60012d626104c45c449cd2c0055468cd835f189..4b8a0cc9665eda6662c5248782ec846e1e6367e7 100644 (file)
@@ -163,7 +163,7 @@ static u16 twobyte_table[256] = {
        ModRM | ImplicitOps, ModRM, ModRM | ImplicitOps, ModRM, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0,
        /* 0x30 - 0x3F */
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+       ImplicitOps, 0, ImplicitOps, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        /* 0x40 - 0x47 */
        DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
        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)
        unsigned long modrm_ea;
        int use_modrm_ea, index_reg = 0, base_reg = 0, scale, rip_relative = 0;
        int no_wb = 0;
+       u64 msr_data;
 
        /* Shadow copy of register state. Committed on successful emulation. */
        unsigned long _regs[NR_VCPU_REGS];
@@ -1177,6 +1178,8 @@ pop_instruction:
 twobyte_insn:
        switch (b) {
        case 0x01: /* lgdt, lidt, lmsw */
+               /* Disable writeback. */
+               no_wb = 1;
                switch (modrm_reg) {
                        u16 size;
                        unsigned long address;
@@ -1214,11 +1217,13 @@ twobyte_insn:
                }
                break;
        case 0x21: /* mov from dr to reg */
+               no_wb = 1;
                if (modrm_mod != 3)
                        goto cannot_emulate;
                rc = emulator_get_dr(ctxt, modrm_reg, &_regs[modrm_rm]);
                break;
        case 0x23: /* mov from reg to dr */
+               no_wb = 1;
                if (modrm_mod != 3)
                        goto cannot_emulate;
                rc = emulator_set_dr(ctxt, modrm_reg, _regs[modrm_rm]);
@@ -1344,6 +1349,29 @@ twobyte_special_insn:
                        goto cannot_emulate;
                realmode_set_cr(ctxt->vcpu, modrm_reg, modrm_val, &_eflags);
                break;
+       case 0x30:
+               /* wrmsr */
+               msr_data = (u32)_regs[VCPU_REGS_RAX]
+                       | ((u64)_regs[VCPU_REGS_RDX] << 32);
+               rc = kvm_set_msr(ctxt->vcpu, _regs[VCPU_REGS_RCX], msr_data);
+               if (rc) {
+                       kvm_arch_ops->inject_gp(ctxt->vcpu, 0);
+                       _eip = ctxt->vcpu->rip;
+               }
+               rc = X86EMUL_CONTINUE;
+               break;
+       case 0x32:
+               /* rdmsr */
+               rc = kvm_get_msr(ctxt->vcpu, _regs[VCPU_REGS_RCX], &msr_data);
+               if (rc) {
+                       kvm_arch_ops->inject_gp(ctxt->vcpu, 0);
+                       _eip = ctxt->vcpu->rip;
+               } else {
+                       _regs[VCPU_REGS_RAX] = (u32)msr_data;
+                       _regs[VCPU_REGS_RDX] = msr_data >> 32;
+               }
+               rc = X86EMUL_CONTINUE;
+               break;
        case 0xc7:              /* Grp9 (cmpxchg8b) */
                {
                        u64 old, new;