diff options
author | Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp> | 2011-11-22 01:19:19 -0500 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2011-12-27 04:17:28 -0500 |
commit | bc00f8d2c2df33c6e7fc8a12c94c0c74d491e566 (patch) | |
tree | bb7ddb5ad8b137ba33caa072b6b72e742150dc66 /arch/x86/kvm/emulate.c | |
parent | d4ddafcdf2201326ec9717172767cfad0ede1472 (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.c | 52 |
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 | ||
2641 | static 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 | |||
2651 | static 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 | |||
2641 | static int em_mov_rm_sreg(struct x86_emulate_ctxt *ctxt) | 2669 | static 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] |