aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/emulate.c
diff options
context:
space:
mode:
authorTakuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>2011-11-22 01:19:19 -0500
committerAvi Kivity <avi@redhat.com>2011-12-27 04:17:28 -0500
commitbc00f8d2c2df33c6e7fc8a12c94c0c74d491e566 (patch)
treebb7ddb5ad8b137ba33caa072b6b72e742150dc66 /arch/x86/kvm/emulate.c
parentd4ddafcdf2201326ec9717172767cfad0ede1472 (diff)
KVM: x86 emulator: Use opcode::execute for MOV to cr/dr
MOV: 0F 22 (move to control registers) MOV: 0F 23 (move to debug registers) Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch/x86/kvm/emulate.c')
-rw-r--r--arch/x86/kvm/emulate.c52
1 files changed, 30 insertions, 22 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 6b7a03b18f89..7fe5ed126f6f 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2638,6 +2638,34 @@ static int em_mov(struct x86_emulate_ctxt *ctxt)
2638 return X86EMUL_CONTINUE; 2638 return X86EMUL_CONTINUE;
2639} 2639}
2640 2640
2641static int em_cr_write(struct x86_emulate_ctxt *ctxt)
2642{
2643 if (ctxt->ops->set_cr(ctxt, ctxt->modrm_reg, ctxt->src.val))
2644 return emulate_gp(ctxt, 0);
2645
2646 /* Disable writeback. */
2647 ctxt->dst.type = OP_NONE;
2648 return X86EMUL_CONTINUE;
2649}
2650
2651static int em_dr_write(struct x86_emulate_ctxt *ctxt)
2652{
2653 unsigned long val;
2654
2655 if (ctxt->mode == X86EMUL_MODE_PROT64)
2656 val = ctxt->src.val & ~0ULL;
2657 else
2658 val = ctxt->src.val & ~0U;
2659
2660 /* #UD condition is already handled. */
2661 if (ctxt->ops->set_dr(ctxt, ctxt->modrm_reg, val) < 0)
2662 return emulate_gp(ctxt, 0);
2663
2664 /* Disable writeback. */
2665 ctxt->dst.type = OP_NONE;
2666 return X86EMUL_CONTINUE;
2667}
2668
2641static int em_mov_rm_sreg(struct x86_emulate_ctxt *ctxt) 2669static int em_mov_rm_sreg(struct x86_emulate_ctxt *ctxt)
2642{ 2670{
2643 if (ctxt->modrm_reg > VCPU_SREG_GS) 2671 if (ctxt->modrm_reg > VCPU_SREG_GS)
@@ -3304,8 +3332,8 @@ static struct opcode twobyte_table[256] = {
3304 /* 0x20 - 0x2F */ 3332 /* 0x20 - 0x2F */
3305 DIP(ModRM | DstMem | Priv | Op3264, cr_read, check_cr_read), 3333 DIP(ModRM | DstMem | Priv | Op3264, cr_read, check_cr_read),
3306 DIP(ModRM | DstMem | Priv | Op3264, dr_read, check_dr_read), 3334 DIP(ModRM | DstMem | Priv | Op3264, dr_read, check_dr_read),
3307 DIP(ModRM | SrcMem | Priv | Op3264, cr_write, check_cr_write), 3335 IIP(ModRM | SrcMem | Priv | Op3264, em_cr_write, cr_write, check_cr_write),
3308 DIP(ModRM | SrcMem | Priv | Op3264, dr_write, check_dr_write), 3336 IIP(ModRM | SrcMem | Priv | Op3264, em_dr_write, dr_write, check_dr_write),
3309 N, N, N, N, 3337 N, N, N, N,
3310 N, N, N, N, N, N, N, N, 3338 N, N, N, N, N, N, N, N,
3311 /* 0x30 - 0x3F */ 3339 /* 0x30 - 0x3F */
@@ -4080,26 +4108,6 @@ twobyte_insn:
4080 case 0x21: /* mov from dr to reg */ 4108 case 0x21: /* mov from dr to reg */
4081 ops->get_dr(ctxt, ctxt->modrm_reg, &ctxt->dst.val); 4109 ops->get_dr(ctxt, ctxt->modrm_reg, &ctxt->dst.val);
4082 break; 4110 break;
4083 case 0x22: /* mov reg, cr */
4084 if (ops->set_cr(ctxt, ctxt->modrm_reg, ctxt->src.val)) {
4085 emulate_gp(ctxt, 0);
4086 rc = X86EMUL_PROPAGATE_FAULT;
4087 goto done;
4088 }
4089 ctxt->dst.type = OP_NONE;
4090 break;
4091 case 0x23: /* mov from reg to dr */
4092 if (ops->set_dr(ctxt, ctxt->modrm_reg, ctxt->src.val &
4093 ((ctxt->mode == X86EMUL_MODE_PROT64) ?
4094 ~0ULL : ~0U)) < 0) {
4095 /* #UD condition is already handled by the code above */
4096 emulate_gp(ctxt, 0);
4097 rc = X86EMUL_PROPAGATE_FAULT;
4098 goto done;
4099 }
4100
4101 ctxt->dst.type = OP_NONE; /* no writeback */
4102 break;
4103 case 0x30: 4111 case 0x30:
4104 /* wrmsr */ 4112 /* wrmsr */
4105 msr_data = (u32)ctxt->regs[VCPU_REGS_RAX] 4113 msr_data = (u32)ctxt->regs[VCPU_REGS_RAX]