diff options
author | Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp> | 2011-05-29 08:56:26 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2011-07-12 06:15:59 -0400 |
commit | db5b0762f3cab58398f16379ab37ef66ef9ba497 (patch) | |
tree | d4b7c00fcb088ad41f9fbddcacf250c2b5cb4a9f /arch/x86/kvm/emulate.c | |
parent | e01991e71a179ddab494c8e02100ad73bc0010c4 (diff) |
KVM: x86 emulator: Use opcode::execute for some instructions
Move the following functions to the opcode tables:
RET (Far return) : CB
IRET : CF
JMP (Jump far) : EA
SYSCALL : 0F 05
CLTS : 0F 06
SYSENTER : 0F 34
SYSEXIT : 0F 35
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 | 37 |
1 files changed, 8 insertions, 29 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 4af94424fe87..136bc6cbd5fa 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -3169,9 +3169,9 @@ static struct opcode opcode_table[256] = { | |||
3169 | D(DstReg | SrcMemFAddr | ModRM | No64), D(DstReg | SrcMemFAddr | ModRM | No64), | 3169 | D(DstReg | SrcMemFAddr | ModRM | No64), D(DstReg | SrcMemFAddr | ModRM | No64), |
3170 | G(ByteOp, group11), G(0, group11), | 3170 | G(ByteOp, group11), G(0, group11), |
3171 | /* 0xC8 - 0xCF */ | 3171 | /* 0xC8 - 0xCF */ |
3172 | N, N, N, D(ImplicitOps | Stack), | 3172 | N, N, N, I(ImplicitOps | Stack, em_ret_far), |
3173 | D(ImplicitOps), DI(SrcImmByte, intn), | 3173 | D(ImplicitOps), DI(SrcImmByte, intn), |
3174 | D(ImplicitOps | No64), DI(ImplicitOps, iret), | 3174 | D(ImplicitOps | No64), II(ImplicitOps, em_iret, iret), |
3175 | /* 0xD0 - 0xD7 */ | 3175 | /* 0xD0 - 0xD7 */ |
3176 | D2bv(DstMem | SrcOne | ModRM), D2bv(DstMem | ModRM), | 3176 | D2bv(DstMem | SrcOne | ModRM), D2bv(DstMem | ModRM), |
3177 | N, N, N, N, | 3177 | N, N, N, N, |
@@ -3183,7 +3183,7 @@ static struct opcode opcode_table[256] = { | |||
3183 | D2bvIP(SrcAcc | DstImmUByte, out, check_perm_out), | 3183 | D2bvIP(SrcAcc | DstImmUByte, out, check_perm_out), |
3184 | /* 0xE8 - 0xEF */ | 3184 | /* 0xE8 - 0xEF */ |
3185 | D(SrcImm | Stack), D(SrcImm | ImplicitOps), | 3185 | D(SrcImm | Stack), D(SrcImm | ImplicitOps), |
3186 | D(SrcImmFAddr | No64), D(SrcImmByte | ImplicitOps), | 3186 | I(SrcImmFAddr | No64, em_jmp_far), D(SrcImmByte | ImplicitOps), |
3187 | D2bvIP(SrcDX | DstAcc, in, check_perm_in), | 3187 | D2bvIP(SrcDX | DstAcc, in, check_perm_in), |
3188 | D2bvIP(SrcAcc | DstDX, out, check_perm_out), | 3188 | D2bvIP(SrcAcc | DstDX, out, check_perm_out), |
3189 | /* 0xF0 - 0xF7 */ | 3189 | /* 0xF0 - 0xF7 */ |
@@ -3198,7 +3198,8 @@ static struct opcode opcode_table[256] = { | |||
3198 | static struct opcode twobyte_table[256] = { | 3198 | static struct opcode twobyte_table[256] = { |
3199 | /* 0x00 - 0x0F */ | 3199 | /* 0x00 - 0x0F */ |
3200 | G(0, group6), GD(0, &group7), N, N, | 3200 | G(0, group6), GD(0, &group7), N, N, |
3201 | N, D(ImplicitOps | VendorSpecific), DI(ImplicitOps | Priv, clts), N, | 3201 | N, I(ImplicitOps | VendorSpecific, em_syscall), |
3202 | II(ImplicitOps | Priv, em_clts, clts), N, | ||
3202 | DI(ImplicitOps | Priv, invd), DI(ImplicitOps | Priv, wbinvd), N, N, | 3203 | DI(ImplicitOps | Priv, invd), DI(ImplicitOps | Priv, wbinvd), N, N, |
3203 | N, D(ImplicitOps | ModRM), N, N, | 3204 | N, D(ImplicitOps | ModRM), N, N, |
3204 | /* 0x10 - 0x1F */ | 3205 | /* 0x10 - 0x1F */ |
@@ -3215,7 +3216,8 @@ static struct opcode twobyte_table[256] = { | |||
3215 | IIP(ImplicitOps, em_rdtsc, rdtsc, check_rdtsc), | 3216 | IIP(ImplicitOps, em_rdtsc, rdtsc, check_rdtsc), |
3216 | DI(ImplicitOps | Priv, rdmsr), | 3217 | DI(ImplicitOps | Priv, rdmsr), |
3217 | DIP(ImplicitOps | Priv, rdpmc, check_rdpmc), | 3218 | DIP(ImplicitOps | Priv, rdpmc, check_rdpmc), |
3218 | D(ImplicitOps | VendorSpecific), D(ImplicitOps | Priv | VendorSpecific), | 3219 | I(ImplicitOps | VendorSpecific, em_sysenter), |
3220 | I(ImplicitOps | Priv | VendorSpecific, em_sysexit), | ||
3219 | N, N, | 3221 | N, N, |
3220 | N, N, N, N, N, N, N, N, | 3222 | N, N, N, N, N, N, N, N, |
3221 | /* 0x40 - 0x4F */ | 3223 | /* 0x40 - 0x4F */ |
@@ -3947,9 +3949,6 @@ special_insn: | |||
3947 | case 0xc5: /* lds */ | 3949 | case 0xc5: /* lds */ |
3948 | rc = emulate_load_segment(ctxt, VCPU_SREG_DS); | 3950 | rc = emulate_load_segment(ctxt, VCPU_SREG_DS); |
3949 | break; | 3951 | break; |
3950 | case 0xcb: /* ret far */ | ||
3951 | rc = em_ret_far(ctxt); | ||
3952 | break; | ||
3953 | case 0xcc: /* int3 */ | 3952 | case 0xcc: /* int3 */ |
3954 | irq = 3; | 3953 | irq = 3; |
3955 | goto do_interrupt; | 3954 | goto do_interrupt; |
@@ -3964,9 +3963,6 @@ special_insn: | |||
3964 | goto do_interrupt; | 3963 | goto do_interrupt; |
3965 | } | 3964 | } |
3966 | break; | 3965 | break; |
3967 | case 0xcf: /* iret */ | ||
3968 | rc = em_iret(ctxt); | ||
3969 | break; | ||
3970 | case 0xd0 ... 0xd1: /* Grp2 */ | 3966 | case 0xd0 ... 0xd1: /* Grp2 */ |
3971 | rc = em_grp2(ctxt); | 3967 | rc = em_grp2(ctxt); |
3972 | break; | 3968 | break; |
@@ -3998,12 +3994,7 @@ special_insn: | |||
3998 | break; | 3994 | break; |
3999 | } | 3995 | } |
4000 | case 0xe9: /* jmp rel */ | 3996 | case 0xe9: /* jmp rel */ |
4001 | goto jmp; | 3997 | case 0xeb: /* jmp rel short */ |
4002 | case 0xea: /* jmp far */ | ||
4003 | rc = em_jmp_far(ctxt); | ||
4004 | break; | ||
4005 | case 0xeb: | ||
4006 | jmp: /* jmp rel short */ | ||
4007 | jmp_rel(c, c->src.val); | 3998 | jmp_rel(c, c->src.val); |
4008 | c->dst.type = OP_NONE; /* Disable writeback. */ | 3999 | c->dst.type = OP_NONE; /* Disable writeback. */ |
4009 | break; | 4000 | break; |
@@ -4126,12 +4117,6 @@ done: | |||
4126 | 4117 | ||
4127 | twobyte_insn: | 4118 | twobyte_insn: |
4128 | switch (c->b) { | 4119 | switch (c->b) { |
4129 | case 0x05: /* syscall */ | ||
4130 | rc = em_syscall(ctxt); | ||
4131 | break; | ||
4132 | case 0x06: | ||
4133 | rc = em_clts(ctxt); | ||
4134 | break; | ||
4135 | case 0x09: /* wbinvd */ | 4120 | case 0x09: /* wbinvd */ |
4136 | (ctxt->ops->wbinvd)(ctxt); | 4121 | (ctxt->ops->wbinvd)(ctxt); |
4137 | break; | 4122 | break; |
@@ -4188,12 +4173,6 @@ twobyte_insn: | |||
4188 | } | 4173 | } |
4189 | rc = X86EMUL_CONTINUE; | 4174 | rc = X86EMUL_CONTINUE; |
4190 | break; | 4175 | break; |
4191 | case 0x34: /* sysenter */ | ||
4192 | rc = em_sysenter(ctxt); | ||
4193 | break; | ||
4194 | case 0x35: /* sysexit */ | ||
4195 | rc = em_sysexit(ctxt); | ||
4196 | break; | ||
4197 | case 0x40 ... 0x4f: /* cmov */ | 4176 | case 0x40 ... 0x4f: /* cmov */ |
4198 | c->dst.val = c->dst.orig_val = c->src.val; | 4177 | c->dst.val = c->dst.orig_val = c->src.val; |
4199 | if (!test_cc(c->b, ctxt->eflags)) | 4178 | if (!test_cc(c->b, ctxt->eflags)) |