diff options
author | Avi Kivity <avi@redhat.com> | 2011-09-13 03:45:51 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2011-09-25 12:52:58 -0400 |
commit | 1cd196ea42c526549ded4fd29809c3fdaa4a7f41 (patch) | |
tree | 8320953cf4310b70861c4d678df8049301d54279 /arch | |
parent | d4b4325fdb66739a74148f90da360ff82ce707d4 (diff) |
KVM: x86 emulator: convert push %sreg/pop %sreg to direct decode
Signed-off-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kvm/emulate.c | 44 |
1 files changed, 15 insertions, 29 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index bd3e488c734e..f1e3be18a08f 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -1458,15 +1458,18 @@ static int em_popf(struct x86_emulate_ctxt *ctxt) | |||
1458 | return emulate_popf(ctxt, &ctxt->dst.val, ctxt->op_bytes); | 1458 | return emulate_popf(ctxt, &ctxt->dst.val, ctxt->op_bytes); |
1459 | } | 1459 | } |
1460 | 1460 | ||
1461 | static int emulate_push_sreg(struct x86_emulate_ctxt *ctxt, int seg) | 1461 | static int em_push_sreg(struct x86_emulate_ctxt *ctxt) |
1462 | { | 1462 | { |
1463 | int seg = ctxt->src2.val; | ||
1464 | |||
1463 | ctxt->src.val = get_segment_selector(ctxt, seg); | 1465 | ctxt->src.val = get_segment_selector(ctxt, seg); |
1464 | 1466 | ||
1465 | return em_push(ctxt); | 1467 | return em_push(ctxt); |
1466 | } | 1468 | } |
1467 | 1469 | ||
1468 | static int emulate_pop_sreg(struct x86_emulate_ctxt *ctxt, int seg) | 1470 | static int em_pop_sreg(struct x86_emulate_ctxt *ctxt) |
1469 | { | 1471 | { |
1472 | int seg = ctxt->src2.val; | ||
1470 | unsigned long selector; | 1473 | unsigned long selector; |
1471 | int rc; | 1474 | int rc; |
1472 | 1475 | ||
@@ -3114,19 +3117,20 @@ static struct gprefix pfx_0f_6f_0f_7f = { | |||
3114 | static struct opcode opcode_table[256] = { | 3117 | static struct opcode opcode_table[256] = { |
3115 | /* 0x00 - 0x07 */ | 3118 | /* 0x00 - 0x07 */ |
3116 | I6ALU(Lock, em_add), | 3119 | I6ALU(Lock, em_add), |
3117 | D(ImplicitOps | Stack | No64 | Src2ES), | 3120 | I(ImplicitOps | Stack | No64 | Src2ES, em_push_sreg), |
3118 | D(ImplicitOps | Stack | No64 | Src2ES), | 3121 | I(ImplicitOps | Stack | No64 | Src2ES, em_pop_sreg), |
3119 | /* 0x08 - 0x0F */ | 3122 | /* 0x08 - 0x0F */ |
3120 | I6ALU(Lock, em_or), | 3123 | I6ALU(Lock, em_or), |
3121 | D(ImplicitOps | Stack | No64 | Src2CS), N, | 3124 | I(ImplicitOps | Stack | No64 | Src2CS, em_push_sreg), |
3125 | N, | ||
3122 | /* 0x10 - 0x17 */ | 3126 | /* 0x10 - 0x17 */ |
3123 | I6ALU(Lock, em_adc), | 3127 | I6ALU(Lock, em_adc), |
3124 | D(ImplicitOps | Stack | No64 | Src2SS), | 3128 | I(ImplicitOps | Stack | No64 | Src2SS, em_push_sreg), |
3125 | D(ImplicitOps | Stack | No64 | Src2SS), | 3129 | I(ImplicitOps | Stack | No64 | Src2SS, em_pop_sreg), |
3126 | /* 0x18 - 0x1F */ | 3130 | /* 0x18 - 0x1F */ |
3127 | I6ALU(Lock, em_sbb), | 3131 | I6ALU(Lock, em_sbb), |
3128 | D(ImplicitOps | Stack | No64 | Src2DS), | 3132 | I(ImplicitOps | Stack | No64 | Src2DS, em_push_sreg), |
3129 | D(ImplicitOps | Stack | No64 | Src2DS), | 3133 | I(ImplicitOps | Stack | No64 | Src2DS, em_pop_sreg), |
3130 | /* 0x20 - 0x27 */ | 3134 | /* 0x20 - 0x27 */ |
3131 | I6ALU(Lock, em_and), N, N, | 3135 | I6ALU(Lock, em_and), N, N, |
3132 | /* 0x28 - 0x2F */ | 3136 | /* 0x28 - 0x2F */ |
@@ -3270,12 +3274,12 @@ static struct opcode twobyte_table[256] = { | |||
3270 | /* 0x90 - 0x9F */ | 3274 | /* 0x90 - 0x9F */ |
3271 | X16(D(ByteOp | DstMem | SrcNone | ModRM| Mov)), | 3275 | X16(D(ByteOp | DstMem | SrcNone | ModRM| Mov)), |
3272 | /* 0xA0 - 0xA7 */ | 3276 | /* 0xA0 - 0xA7 */ |
3273 | D(Stack | Src2FS), D(Stack | Src2FS), | 3277 | I(Stack | Src2FS, em_push_sreg), I(Stack | Src2FS, em_pop_sreg), |
3274 | DI(ImplicitOps, cpuid), D(DstMem | SrcReg | ModRM | BitOp), | 3278 | DI(ImplicitOps, cpuid), D(DstMem | SrcReg | ModRM | BitOp), |
3275 | D(DstMem | SrcReg | Src2ImmByte | ModRM), | 3279 | D(DstMem | SrcReg | Src2ImmByte | ModRM), |
3276 | D(DstMem | SrcReg | Src2CL | ModRM), N, N, | 3280 | D(DstMem | SrcReg | Src2CL | ModRM), N, N, |
3277 | /* 0xA8 - 0xAF */ | 3281 | /* 0xA8 - 0xAF */ |
3278 | D(Stack | Src2GS), D(Stack | Src2GS), | 3282 | I(Stack | Src2GS, em_push_sreg), I(Stack | Src2GS, em_pop_sreg), |
3279 | DI(ImplicitOps, rsm), D(DstMem | SrcReg | ModRM | BitOp | Lock), | 3283 | DI(ImplicitOps, rsm), D(DstMem | SrcReg | ModRM | BitOp | Lock), |
3280 | D(DstMem | SrcReg | Src2ImmByte | ModRM), | 3284 | D(DstMem | SrcReg | Src2ImmByte | ModRM), |
3281 | D(DstMem | SrcReg | Src2CL | ModRM), | 3285 | D(DstMem | SrcReg | Src2CL | ModRM), |
@@ -3839,16 +3843,6 @@ special_insn: | |||
3839 | goto twobyte_insn; | 3843 | goto twobyte_insn; |
3840 | 3844 | ||
3841 | switch (ctxt->b) { | 3845 | switch (ctxt->b) { |
3842 | case 0x06: /* push es */ | ||
3843 | case 0x0e: /* push cs */ | ||
3844 | case 0x16: /* push ss */ | ||
3845 | case 0x1e: /* push ds */ | ||
3846 | rc = emulate_push_sreg(ctxt, ctxt->src2.val); | ||
3847 | break; | ||
3848 | case 0x07: /* pop es */ | ||
3849 | case 0x17: /* pop ss */ | ||
3850 | case 0x1f: /* pop ds */ | ||
3851 | rc = emulate_pop_sreg(ctxt, ctxt->src2.val); | ||
3852 | case 0x40 ... 0x47: /* inc r16/r32 */ | 3846 | case 0x40 ... 0x47: /* inc r16/r32 */ |
3853 | emulate_1op(ctxt, "inc"); | 3847 | emulate_1op(ctxt, "inc"); |
3854 | break; | 3848 | break; |
@@ -4097,14 +4091,6 @@ twobyte_insn: | |||
4097 | case 0x90 ... 0x9f: /* setcc r/m8 */ | 4091 | case 0x90 ... 0x9f: /* setcc r/m8 */ |
4098 | ctxt->dst.val = test_cc(ctxt->b, ctxt->eflags); | 4092 | ctxt->dst.val = test_cc(ctxt->b, ctxt->eflags); |
4099 | break; | 4093 | break; |
4100 | case 0xa0: /* push fs */ | ||
4101 | case 0xa8: /* push gs */ | ||
4102 | rc = emulate_push_sreg(ctxt, ctxt->src2.val); | ||
4103 | break; | ||
4104 | case 0xa1: /* pop fs */ | ||
4105 | case 0xa9: /* pop gs */ | ||
4106 | rc = emulate_pop_sreg(ctxt, ctxt->src2.val); | ||
4107 | break; | ||
4108 | case 0xa3: | 4094 | case 0xa3: |
4109 | bt: /* bt */ | 4095 | bt: /* bt */ |
4110 | ctxt->dst.type = OP_NONE; | 4096 | ctxt->dst.type = OP_NONE; |