diff options
-rw-r--r-- | arch/x86/kvm/emulate.c | 52 |
1 files changed, 26 insertions, 26 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 7fe5ed126f6f..906c5eb34aa7 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -2666,6 +2666,30 @@ static int em_dr_write(struct x86_emulate_ctxt *ctxt) | |||
2666 | return X86EMUL_CONTINUE; | 2666 | return X86EMUL_CONTINUE; |
2667 | } | 2667 | } |
2668 | 2668 | ||
2669 | static int em_wrmsr(struct x86_emulate_ctxt *ctxt) | ||
2670 | { | ||
2671 | u64 msr_data; | ||
2672 | |||
2673 | msr_data = (u32)ctxt->regs[VCPU_REGS_RAX] | ||
2674 | | ((u64)ctxt->regs[VCPU_REGS_RDX] << 32); | ||
2675 | if (ctxt->ops->set_msr(ctxt, ctxt->regs[VCPU_REGS_RCX], msr_data)) | ||
2676 | return emulate_gp(ctxt, 0); | ||
2677 | |||
2678 | return X86EMUL_CONTINUE; | ||
2679 | } | ||
2680 | |||
2681 | static int em_rdmsr(struct x86_emulate_ctxt *ctxt) | ||
2682 | { | ||
2683 | u64 msr_data; | ||
2684 | |||
2685 | if (ctxt->ops->get_msr(ctxt, ctxt->regs[VCPU_REGS_RCX], &msr_data)) | ||
2686 | return emulate_gp(ctxt, 0); | ||
2687 | |||
2688 | ctxt->regs[VCPU_REGS_RAX] = (u32)msr_data; | ||
2689 | ctxt->regs[VCPU_REGS_RDX] = msr_data >> 32; | ||
2690 | return X86EMUL_CONTINUE; | ||
2691 | } | ||
2692 | |||
2669 | static int em_mov_rm_sreg(struct x86_emulate_ctxt *ctxt) | 2693 | static int em_mov_rm_sreg(struct x86_emulate_ctxt *ctxt) |
2670 | { | 2694 | { |
2671 | if (ctxt->modrm_reg > VCPU_SREG_GS) | 2695 | if (ctxt->modrm_reg > VCPU_SREG_GS) |
@@ -3337,9 +3361,9 @@ static struct opcode twobyte_table[256] = { | |||
3337 | N, N, N, N, | 3361 | N, N, N, N, |
3338 | N, N, N, N, N, N, N, N, | 3362 | N, N, N, N, N, N, N, N, |
3339 | /* 0x30 - 0x3F */ | 3363 | /* 0x30 - 0x3F */ |
3340 | DI(ImplicitOps | Priv, wrmsr), | 3364 | II(ImplicitOps | Priv, em_wrmsr, wrmsr), |
3341 | IIP(ImplicitOps, em_rdtsc, rdtsc, check_rdtsc), | 3365 | IIP(ImplicitOps, em_rdtsc, rdtsc, check_rdtsc), |
3342 | DI(ImplicitOps | Priv, rdmsr), | 3366 | II(ImplicitOps | Priv, em_rdmsr, rdmsr), |
3343 | DIP(ImplicitOps | Priv, rdpmc, check_rdpmc), | 3367 | DIP(ImplicitOps | Priv, rdpmc, check_rdpmc), |
3344 | I(ImplicitOps | VendorSpecific, em_sysenter), | 3368 | I(ImplicitOps | VendorSpecific, em_sysenter), |
3345 | I(ImplicitOps | Priv | VendorSpecific, em_sysexit), | 3369 | I(ImplicitOps | Priv | VendorSpecific, em_sysexit), |
@@ -3818,7 +3842,6 @@ static bool string_insn_completed(struct x86_emulate_ctxt *ctxt) | |||
3818 | int x86_emulate_insn(struct x86_emulate_ctxt *ctxt) | 3842 | int x86_emulate_insn(struct x86_emulate_ctxt *ctxt) |
3819 | { | 3843 | { |
3820 | struct x86_emulate_ops *ops = ctxt->ops; | 3844 | struct x86_emulate_ops *ops = ctxt->ops; |
3821 | u64 msr_data; | ||
3822 | int rc = X86EMUL_CONTINUE; | 3845 | int rc = X86EMUL_CONTINUE; |
3823 | int saved_dst_type = ctxt->dst.type; | 3846 | int saved_dst_type = ctxt->dst.type; |
3824 | 3847 | ||
@@ -4108,29 +4131,6 @@ twobyte_insn: | |||
4108 | case 0x21: /* mov from dr to reg */ | 4131 | case 0x21: /* mov from dr to reg */ |
4109 | ops->get_dr(ctxt, ctxt->modrm_reg, &ctxt->dst.val); | 4132 | ops->get_dr(ctxt, ctxt->modrm_reg, &ctxt->dst.val); |
4110 | break; | 4133 | break; |
4111 | case 0x30: | ||
4112 | /* wrmsr */ | ||
4113 | msr_data = (u32)ctxt->regs[VCPU_REGS_RAX] | ||
4114 | | ((u64)ctxt->regs[VCPU_REGS_RDX] << 32); | ||
4115 | if (ops->set_msr(ctxt, ctxt->regs[VCPU_REGS_RCX], msr_data)) { | ||
4116 | emulate_gp(ctxt, 0); | ||
4117 | rc = X86EMUL_PROPAGATE_FAULT; | ||
4118 | goto done; | ||
4119 | } | ||
4120 | rc = X86EMUL_CONTINUE; | ||
4121 | break; | ||
4122 | case 0x32: | ||
4123 | /* rdmsr */ | ||
4124 | if (ops->get_msr(ctxt, ctxt->regs[VCPU_REGS_RCX], &msr_data)) { | ||
4125 | emulate_gp(ctxt, 0); | ||
4126 | rc = X86EMUL_PROPAGATE_FAULT; | ||
4127 | goto done; | ||
4128 | } else { | ||
4129 | ctxt->regs[VCPU_REGS_RAX] = (u32)msr_data; | ||
4130 | ctxt->regs[VCPU_REGS_RDX] = msr_data >> 32; | ||
4131 | } | ||
4132 | rc = X86EMUL_CONTINUE; | ||
4133 | break; | ||
4134 | case 0x40 ... 0x4f: /* cmov */ | 4134 | case 0x40 ... 0x4f: /* cmov */ |
4135 | ctxt->dst.val = ctxt->dst.orig_val = ctxt->src.val; | 4135 | ctxt->dst.val = ctxt->dst.orig_val = ctxt->src.val; |
4136 | if (!test_cc(ctxt->b, ctxt->eflags)) | 4136 | if (!test_cc(ctxt->b, ctxt->eflags)) |