aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWei Yongjun <yjwei@cn.fujitsu.com>2010-08-23 02:56:54 -0400
committerAvi Kivity <avi@redhat.com>2010-10-24 04:51:20 -0400
commit09b5f4d3c4aa2d4928c0a3723a8de26a76b6339e (patch)
tree8d937d45806faf3af18073099eb3e3b017d339f0
parent45221ab6684a82a5b60208b76d6f8bfb1bbcb969 (diff)
KVM: x86 emulator: add LDS/LES/LFS/LGS/LSS instruction emulation
Add LDS/LES/LFS/LGS/LSS instruction emulation. (opcode 0xc4, 0xc5, 0x0f 0xb2, 0x0f 0xb4~0xb5) Signed-off-by: Wei Yongjun <yjwei@cn.fujitsu.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
-rw-r--r--arch/x86/kvm/emulate.c50
1 files changed, 46 insertions, 4 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index e257f2286866..aece501edce4 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -1514,6 +1514,23 @@ static int emulate_ret_far(struct x86_emulate_ctxt *ctxt,
1514 return rc; 1514 return rc;
1515} 1515}
1516 1516
1517static int emulate_load_segment(struct x86_emulate_ctxt *ctxt,
1518 struct x86_emulate_ops *ops, int seg)
1519{
1520 struct decode_cache *c = &ctxt->decode;
1521 unsigned short sel;
1522 int rc;
1523
1524 memcpy(&sel, c->src.valptr + c->op_bytes, 2);
1525
1526 rc = load_segment_descriptor(ctxt, ops, sel, seg);
1527 if (rc != X86EMUL_CONTINUE)
1528 return rc;
1529
1530 c->dst.val = c->src.val;
1531 return rc;
1532}
1533
1517static inline void 1534static inline void
1518setup_syscalls_segments(struct x86_emulate_ctxt *ctxt, 1535setup_syscalls_segments(struct x86_emulate_ctxt *ctxt,
1519 struct x86_emulate_ops *ops, struct desc_struct *cs, 1536 struct x86_emulate_ops *ops, struct desc_struct *cs,
@@ -2458,7 +2475,7 @@ static struct opcode opcode_table[256] = {
2458 D(ByteOp | DstMem | SrcImm | ModRM), D(DstMem | SrcImmByte | ModRM), 2475 D(ByteOp | DstMem | SrcImm | ModRM), D(DstMem | SrcImmByte | ModRM),
2459 I(ImplicitOps | Stack | SrcImmU16, em_ret_near_imm), 2476 I(ImplicitOps | Stack | SrcImmU16, em_ret_near_imm),
2460 D(ImplicitOps | Stack), 2477 D(ImplicitOps | Stack),
2461 N, N, 2478 D(DstReg | SrcMemFAddr | ModRM | No64), D(DstReg | SrcMemFAddr | ModRM | No64),
2462 D(ByteOp | DstMem | SrcImm | ModRM | Mov), D(DstMem | SrcImm | ModRM | Mov), 2479 D(ByteOp | DstMem | SrcImm | ModRM | Mov), D(DstMem | SrcImm | ModRM | Mov),
2463 /* 0xC8 - 0xCF */ 2480 /* 0xC8 - 0xCF */
2464 N, N, N, D(ImplicitOps | Stack), 2481 N, N, N, D(ImplicitOps | Stack),
@@ -2529,9 +2546,9 @@ static struct opcode twobyte_table[256] = {
2529 D(ModRM), I(DstReg | SrcMem | ModRM, em_imul), 2546 D(ModRM), I(DstReg | SrcMem | ModRM, em_imul),
2530 /* 0xB0 - 0xB7 */ 2547 /* 0xB0 - 0xB7 */
2531 D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock), 2548 D(ByteOp | DstMem | SrcReg | ModRM | Lock), D(DstMem | SrcReg | ModRM | Lock),
2532 N, D(DstMem | SrcReg | ModRM | BitOp | Lock), 2549 D(DstReg | SrcMemFAddr | ModRM), D(DstMem | SrcReg | ModRM | BitOp | Lock),
2533 N, N, D(ByteOp | DstReg | SrcMem | ModRM | Mov), 2550 D(DstReg | SrcMemFAddr | ModRM), D(DstReg | SrcMemFAddr | ModRM),
2534 D(DstReg | SrcMem16 | ModRM | Mov), 2551 D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov),
2535 /* 0xB8 - 0xBF */ 2552 /* 0xB8 - 0xBF */
2536 N, N, 2553 N, N,
2537 G(BitOp, group8), D(DstMem | SrcReg | ModRM | BitOp | Lock), 2554 G(BitOp, group8), D(DstMem | SrcReg | ModRM | BitOp | Lock),
@@ -3214,6 +3231,16 @@ special_insn:
3214 c->dst.addr.reg = &c->eip; 3231 c->dst.addr.reg = &c->eip;
3215 c->dst.bytes = c->op_bytes; 3232 c->dst.bytes = c->op_bytes;
3216 goto pop_instruction; 3233 goto pop_instruction;
3234 case 0xc4: /* les */
3235 rc = emulate_load_segment(ctxt, ops, VCPU_SREG_ES);
3236 if (rc != X86EMUL_CONTINUE)
3237 goto done;
3238 break;
3239 case 0xc5: /* lds */
3240 rc = emulate_load_segment(ctxt, ops, VCPU_SREG_DS);
3241 if (rc != X86EMUL_CONTINUE)
3242 goto done;
3243 break;
3217 case 0xc6 ... 0xc7: /* mov (sole member of Grp11) */ 3244 case 0xc6 ... 0xc7: /* mov (sole member of Grp11) */
3218 mov: 3245 mov:
3219 c->dst.val = c->src.val; 3246 c->dst.val = c->src.val;
@@ -3659,10 +3686,25 @@ twobyte_insn:
3659 c->dst.addr.reg = (unsigned long *)&c->regs[VCPU_REGS_RAX]; 3686 c->dst.addr.reg = (unsigned long *)&c->regs[VCPU_REGS_RAX];
3660 } 3687 }
3661 break; 3688 break;
3689 case 0xb2: /* lss */
3690 rc = emulate_load_segment(ctxt, ops, VCPU_SREG_SS);
3691 if (rc != X86EMUL_CONTINUE)
3692 goto done;
3693 break;
3662 case 0xb3: 3694 case 0xb3:
3663 btr: /* btr */ 3695 btr: /* btr */
3664 emulate_2op_SrcV_nobyte("btr", c->src, c->dst, ctxt->eflags); 3696 emulate_2op_SrcV_nobyte("btr", c->src, c->dst, ctxt->eflags);
3665 break; 3697 break;
3698 case 0xb4: /* lfs */
3699 rc = emulate_load_segment(ctxt, ops, VCPU_SREG_FS);
3700 if (rc != X86EMUL_CONTINUE)
3701 goto done;
3702 break;
3703 case 0xb5: /* lgs */
3704 rc = emulate_load_segment(ctxt, ops, VCPU_SREG_GS);
3705 if (rc != X86EMUL_CONTINUE)
3706 goto done;
3707 break;
3666 case 0xb6 ... 0xb7: /* movzx */ 3708 case 0xb6 ... 0xb7: /* movzx */
3667 c->dst.bytes = c->op_bytes; 3709 c->dst.bytes = c->op_bytes;
3668 c->dst.val = (c->d & ByteOp) ? (u8) c->src.val 3710 c->dst.val = (c->d & ByteOp) ? (u8) c->src.val