KVM: x86 emulator: Use opcode::execute for RET(C3)
[firefly-linux-kernel-4.4.55.git] / arch / x86 / kvm / emulate.c
index adc98675cda03505cff59be011df491cd271072a..2ebec692d44b6f55d3575835735f1aed6b6b8857 100644 (file)
@@ -407,23 +407,6 @@ struct gprefix {
                }                                                       \
        } while (0)
 
-/* Fetch next part of the instruction being emulated. */
-#define insn_fetch(_type, _size, _eip)                                  \
-({     unsigned long _x;                                               \
-       rc = do_insn_fetch(ctxt, ops, (_eip), &_x, (_size));            \
-       if (rc != X86EMUL_CONTINUE)                                     \
-               goto done;                                              \
-       (_eip) += (_size);                                              \
-       (_type)_x;                                                      \
-})
-
-#define insn_fetch_arr(_arr, _size, _eip)                              \
-({     rc = do_insn_fetch(ctxt, ops, (_eip), _arr, (_size));           \
-       if (rc != X86EMUL_CONTINUE)                                     \
-               goto done;                                              \
-       (_eip) += (_size);                                              \
-})
-
 static int emulator_check_intercept(struct x86_emulate_ctxt *ctxt,
                                    enum x86_intercept intercept,
                                    enum x86_intercept_stage stage)
@@ -492,13 +475,12 @@ static void set_seg_override(struct decode_cache *c, int seg)
        c->seg_override = seg;
 }
 
-static unsigned long seg_base(struct x86_emulate_ctxt *ctxt,
-                             struct x86_emulate_ops *ops, int seg)
+static unsigned long seg_base(struct x86_emulate_ctxt *ctxt, int seg)
 {
        if (ctxt->mode == X86EMUL_MODE_PROT64 && seg < VCPU_SREG_FS)
                return 0;
 
-       return ops->get_cached_segment_base(ctxt, seg);
+       return ctxt->ops->get_cached_segment_base(ctxt, seg);
 }
 
 static unsigned seg_override(struct x86_emulate_ctxt *ctxt,
@@ -587,7 +569,7 @@ static int __linearize(struct x86_emulate_ctxt *ctxt,
        u16 sel;
        unsigned cpl, rpl;
 
-       la = seg_base(ctxt, ctxt->ops, addr.seg) + addr.ea;
+       la = seg_base(ctxt, addr.seg) + addr.ea;
        switch (ctxt->mode) {
        case X86EMUL_MODE_REAL:
                break;
@@ -671,8 +653,7 @@ static int segmented_read_std(struct x86_emulate_ctxt *ctxt,
        return ctxt->ops->read_std(ctxt, linear, data, size, &ctxt->exception);
 }
 
-static int do_fetch_insn_byte(struct x86_emulate_ctxt *ctxt,
-                             struct x86_emulate_ops *ops,
+static int do_insn_fetch_byte(struct x86_emulate_ctxt *ctxt,
                              unsigned long eip, u8 *dest)
 {
        struct fetch_cache *fc = &ctxt->decode.fetch;
@@ -687,8 +668,8 @@ static int do_fetch_insn_byte(struct x86_emulate_ctxt *ctxt,
                rc = __linearize(ctxt, addr, size, false, true, &linear);
                if (rc != X86EMUL_CONTINUE)
                        return rc;
-               rc = ops->fetch(ctxt, linear, fc->data + cur_size,
-                               size, &ctxt->exception);
+               rc = ctxt->ops->fetch(ctxt, linear, fc->data + cur_size,
+                                     size, &ctxt->exception);
                if (rc != X86EMUL_CONTINUE)
                        return rc;
                fc->end += size;
@@ -698,7 +679,6 @@ static int do_fetch_insn_byte(struct x86_emulate_ctxt *ctxt,
 }
 
 static int do_insn_fetch(struct x86_emulate_ctxt *ctxt,
-                        struct x86_emulate_ops *ops,
                         unsigned long eip, void *dest, unsigned size)
 {
        int rc;
@@ -707,13 +687,30 @@ static int do_insn_fetch(struct x86_emulate_ctxt *ctxt,
        if (eip + size - ctxt->eip > 15)
                return X86EMUL_UNHANDLEABLE;
        while (size--) {
-               rc = do_fetch_insn_byte(ctxt, ops, eip++, dest++);
+               rc = do_insn_fetch_byte(ctxt, eip++, dest++);
                if (rc != X86EMUL_CONTINUE)
                        return rc;
        }
        return X86EMUL_CONTINUE;
 }
 
+/* Fetch next part of the instruction being emulated. */
+#define insn_fetch(_type, _size, _eip)                                 \
+({     unsigned long _x;                                               \
+       rc = do_insn_fetch(ctxt, (_eip), &_x, (_size));                 \
+       if (rc != X86EMUL_CONTINUE)                                     \
+               goto done;                                              \
+       (_eip) += (_size);                                              \
+       (_type)_x;                                                      \
+})
+
+#define insn_fetch_arr(_arr, _size, _eip)                              \
+({     rc = do_insn_fetch(ctxt, (_eip), _arr, (_size));                \
+       if (rc != X86EMUL_CONTINUE)                                     \
+               goto done;                                              \
+       (_eip) += (_size);                                              \
+})
+
 /*
  * Given the 'reg' portion of a ModRM byte, and a register block, return a
  * pointer into the block that addresses the relevant register.
@@ -887,7 +884,6 @@ static void decode_register_operand(struct x86_emulate_ctxt *ctxt,
 }
 
 static int decode_modrm(struct x86_emulate_ctxt *ctxt,
-                       struct x86_emulate_ops *ops,
                        struct operand *op)
 {
        struct decode_cache *c = &ctxt->decode;
@@ -1014,7 +1010,6 @@ done:
 }
 
 static int decode_abs(struct x86_emulate_ctxt *ctxt,
-                     struct x86_emulate_ops *ops,
                      struct operand *op)
 {
        struct decode_cache *c = &ctxt->decode;
@@ -1056,7 +1051,6 @@ static void fetch_bit_operand(struct decode_cache *c)
 }
 
 static int read_emulated(struct x86_emulate_ctxt *ctxt,
-                        struct x86_emulate_ops *ops,
                         unsigned long addr, void *dest, unsigned size)
 {
        int rc;
@@ -1068,8 +1062,8 @@ static int read_emulated(struct x86_emulate_ctxt *ctxt,
                if (mc->pos < mc->end)
                        goto read_cached;
 
-               rc = ops->read_emulated(ctxt, addr, mc->data + mc->end, n,
-                                       &ctxt->exception);
+               rc = ctxt->ops->read_emulated(ctxt, addr, mc->data + mc->end, n,
+                                             &ctxt->exception);
                if (rc != X86EMUL_CONTINUE)
                        return rc;
                mc->end += n;
@@ -1094,7 +1088,7 @@ static int segmented_read(struct x86_emulate_ctxt *ctxt,
        rc = linearize(ctxt, addr, size, false, &linear);
        if (rc != X86EMUL_CONTINUE)
                return rc;
-       return read_emulated(ctxt, ctxt->ops, linear, data, size);
+       return read_emulated(ctxt, linear, data, size);
 }
 
 static int segmented_write(struct x86_emulate_ctxt *ctxt,
@@ -1128,7 +1122,6 @@ static int segmented_cmpxchg(struct x86_emulate_ctxt *ctxt,
 }
 
 static int pio_in_emulated(struct x86_emulate_ctxt *ctxt,
-                          struct x86_emulate_ops *ops,
                           unsigned int size, unsigned short port,
                           void *dest)
 {
@@ -1147,7 +1140,7 @@ static int pio_in_emulated(struct x86_emulate_ctxt *ctxt,
                if (n == 0)
                        n = 1;
                rc->pos = rc->end = 0;
-               if (!ops->pio_in_emulated(ctxt, size, port, rc->data, n))
+               if (!ctxt->ops->pio_in_emulated(ctxt, size, port, rc->data, n))
                        return 0;
                rc->end = n * size;
        }
@@ -1158,9 +1151,10 @@ static int pio_in_emulated(struct x86_emulate_ctxt *ctxt,
 }
 
 static void get_descriptor_table_ptr(struct x86_emulate_ctxt *ctxt,
-                                    struct x86_emulate_ops *ops,
                                     u16 selector, struct desc_ptr *dt)
 {
+       struct x86_emulate_ops *ops = ctxt->ops;
+
        if (selector & 1 << 2) {
                struct desc_struct desc;
                u16 sel;
@@ -1177,48 +1171,42 @@ static void get_descriptor_table_ptr(struct x86_emulate_ctxt *ctxt,
 
 /* allowed just for 8 bytes segments */
 static int read_segment_descriptor(struct x86_emulate_ctxt *ctxt,
-                                  struct x86_emulate_ops *ops,
                                   u16 selector, struct desc_struct *desc)
 {
        struct desc_ptr dt;
        u16 index = selector >> 3;
-       int ret;
        ulong addr;
 
-       get_descriptor_table_ptr(ctxt, ops, selector, &dt);
+       get_descriptor_table_ptr(ctxt, selector, &dt);
 
        if (dt.size < index * 8 + 7)
                return emulate_gp(ctxt, selector & 0xfffc);
-       addr = dt.address + index * 8;
-       ret = ops->read_std(ctxt, addr, desc, sizeof *desc, &ctxt->exception);
 
-       return ret;
+       addr = dt.address + index * 8;
+       return ctxt->ops->read_std(ctxt, addr, desc, sizeof *desc,
+                                  &ctxt->exception);
 }
 
 /* allowed just for 8 bytes segments */
 static int write_segment_descriptor(struct x86_emulate_ctxt *ctxt,
-                                   struct x86_emulate_ops *ops,
                                    u16 selector, struct desc_struct *desc)
 {
        struct desc_ptr dt;
        u16 index = selector >> 3;
        ulong addr;
-       int ret;
 
-       get_descriptor_table_ptr(ctxt, ops, selector, &dt);
+       get_descriptor_table_ptr(ctxt, selector, &dt);
 
        if (dt.size < index * 8 + 7)
                return emulate_gp(ctxt, selector & 0xfffc);
 
        addr = dt.address + index * 8;
-       ret = ops->write_std(ctxt, addr, desc, sizeof *desc, &ctxt->exception);
-
-       return ret;
+       return ctxt->ops->write_std(ctxt, addr, desc, sizeof *desc,
+                                   &ctxt->exception);
 }
 
 /* Does not support long mode */
 static int load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
-                                  struct x86_emulate_ops *ops,
                                   u16 selector, int seg)
 {
        struct desc_struct seg_desc;
@@ -1253,7 +1241,7 @@ static int load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
        if (null_selector) /* for NULL selector skip all following checks */
                goto load;
 
-       ret = read_segment_descriptor(ctxt, ops, selector, &seg_desc);
+       ret = read_segment_descriptor(ctxt, selector, &seg_desc);
        if (ret != X86EMUL_CONTINUE)
                return ret;
 
@@ -1271,7 +1259,7 @@ static int load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
 
        rpl = selector & 3;
        dpl = seg_desc.dpl;
-       cpl = ops->cpl(ctxt);
+       cpl = ctxt->ops->cpl(ctxt);
 
        switch (seg) {
        case VCPU_SREG_SS:
@@ -1322,12 +1310,12 @@ static int load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
        if (seg_desc.s) {
                /* mark segment as accessed */
                seg_desc.type |= 1;
-               ret = write_segment_descriptor(ctxt, ops, selector, &seg_desc);
+               ret = write_segment_descriptor(ctxt, selector, &seg_desc);
                if (ret != X86EMUL_CONTINUE)
                        return ret;
        }
 load:
-       ops->set_segment(ctxt, selector, &seg_desc, 0, seg);
+       ctxt->ops->set_segment(ctxt, selector, &seg_desc, 0, seg);
        return X86EMUL_CONTINUE;
 exception:
        emulate_exception(ctxt, err_vec, err_code, true);
@@ -1428,13 +1416,12 @@ static int em_pop(struct x86_emulate_ctxt *ctxt)
 }
 
 static int emulate_popf(struct x86_emulate_ctxt *ctxt,
-                      struct x86_emulate_ops *ops,
-                      void *dest, int len)
+                       void *dest, int len)
 {
        int rc;
        unsigned long val, change_mask;
        int iopl = (ctxt->eflags & X86_EFLAGS_IOPL) >> IOPL_SHIFT;
-       int cpl = ops->cpl(ctxt);
+       int cpl = ctxt->ops->cpl(ctxt);
 
        rc = emulate_pop(ctxt, &val, len);
        if (rc != X86EMUL_CONTINUE)
@@ -1475,11 +1462,10 @@ static int em_popf(struct x86_emulate_ctxt *ctxt)
        c->dst.type = OP_REG;
        c->dst.addr.reg = &ctxt->eflags;
        c->dst.bytes = c->op_bytes;
-       return emulate_popf(ctxt, ctxt->ops, &c->dst.val, c->op_bytes);
+       return emulate_popf(ctxt, &c->dst.val, c->op_bytes);
 }
 
-static int emulate_push_sreg(struct x86_emulate_ctxt *ctxt,
-                            struct x86_emulate_ops *ops, int seg)
+static int emulate_push_sreg(struct x86_emulate_ctxt *ctxt, int seg)
 {
        struct decode_cache *c = &ctxt->decode;
 
@@ -1488,8 +1474,7 @@ static int emulate_push_sreg(struct x86_emulate_ctxt *ctxt,
        return em_push(ctxt);
 }
 
-static int emulate_pop_sreg(struct x86_emulate_ctxt *ctxt,
-                            struct x86_emulate_ops *ops, int seg)
+static int emulate_pop_sreg(struct x86_emulate_ctxt *ctxt, int seg)
 {
        struct decode_cache *c = &ctxt->decode;
        unsigned long selector;
@@ -1499,7 +1484,7 @@ static int emulate_pop_sreg(struct x86_emulate_ctxt *ctxt,
        if (rc != X86EMUL_CONTINUE)
                return rc;
 
-       rc = load_segment_descriptor(ctxt, ops, (u16)selector, seg);
+       rc = load_segment_descriptor(ctxt, (u16)selector, seg);
        return rc;
 }
 
@@ -1553,10 +1538,10 @@ static int em_popa(struct x86_emulate_ctxt *ctxt)
        return rc;
 }
 
-int emulate_int_real(struct x86_emulate_ctxt *ctxt,
-                              struct x86_emulate_ops *ops, int irq)
+int emulate_int_real(struct x86_emulate_ctxt *ctxt, int irq)
 {
        struct decode_cache *c = &ctxt->decode;
+       struct x86_emulate_ops *ops = ctxt->ops;
        int rc;
        struct desc_ptr dt;
        gva_t cs_addr;
@@ -1594,7 +1579,7 @@ int emulate_int_real(struct x86_emulate_ctxt *ctxt,
        if (rc != X86EMUL_CONTINUE)
                return rc;
 
-       rc = load_segment_descriptor(ctxt, ops, cs, VCPU_SREG_CS);
+       rc = load_segment_descriptor(ctxt, cs, VCPU_SREG_CS);
        if (rc != X86EMUL_CONTINUE)
                return rc;
 
@@ -1603,12 +1588,11 @@ int emulate_int_real(struct x86_emulate_ctxt *ctxt,
        return rc;
 }
 
-static int emulate_int(struct x86_emulate_ctxt *ctxt,
-                      struct x86_emulate_ops *ops, int irq)
+static int emulate_int(struct x86_emulate_ctxt *ctxt, int irq)
 {
        switch(ctxt->mode) {
        case X86EMUL_MODE_REAL:
-               return emulate_int_real(ctxt, ops, irq);
+               return emulate_int_real(ctxt, irq);
        case X86EMUL_MODE_VM86:
        case X86EMUL_MODE_PROT16:
        case X86EMUL_MODE_PROT32:
@@ -1619,8 +1603,7 @@ static int emulate_int(struct x86_emulate_ctxt *ctxt,
        }
 }
 
-static int emulate_iret_real(struct x86_emulate_ctxt *ctxt,
-                            struct x86_emulate_ops *ops)
+static int emulate_iret_real(struct x86_emulate_ctxt *ctxt)
 {
        struct decode_cache *c = &ctxt->decode;
        int rc = X86EMUL_CONTINUE;
@@ -1652,7 +1635,7 @@ static int emulate_iret_real(struct x86_emulate_ctxt *ctxt,
        if (rc != X86EMUL_CONTINUE)
                return rc;
 
-       rc = load_segment_descriptor(ctxt, ops, (u16)cs, VCPU_SREG_CS);
+       rc = load_segment_descriptor(ctxt, (u16)cs, VCPU_SREG_CS);
 
        if (rc != X86EMUL_CONTINUE)
                return rc;
@@ -1673,12 +1656,11 @@ static int emulate_iret_real(struct x86_emulate_ctxt *ctxt,
        return rc;
 }
 
-static inline int emulate_iret(struct x86_emulate_ctxt *ctxt,
-                                   struct x86_emulate_ops* ops)
+static int em_iret(struct x86_emulate_ctxt *ctxt)
 {
        switch(ctxt->mode) {
        case X86EMUL_MODE_REAL:
-               return emulate_iret_real(ctxt, ops);
+               return emulate_iret_real(ctxt);
        case X86EMUL_MODE_VM86:
        case X86EMUL_MODE_PROT16:
        case X86EMUL_MODE_PROT32:
@@ -1697,7 +1679,7 @@ static int em_jmp_far(struct x86_emulate_ctxt *ctxt)
 
        memcpy(&sel, c->src.valptr + c->op_bytes, 2);
 
-       rc = load_segment_descriptor(ctxt, ctxt->ops, sel, VCPU_SREG_CS);
+       rc = load_segment_descriptor(ctxt, sel, VCPU_SREG_CS);
        if (rc != X86EMUL_CONTINUE)
                return rc;
 
@@ -1834,8 +1816,17 @@ static int em_grp9(struct x86_emulate_ctxt *ctxt)
        return X86EMUL_CONTINUE;
 }
 
-static int emulate_ret_far(struct x86_emulate_ctxt *ctxt,
-                          struct x86_emulate_ops *ops)
+static int em_ret(struct x86_emulate_ctxt *ctxt)
+{
+       struct decode_cache *c = &ctxt->decode;
+
+       c->dst.type = OP_REG;
+       c->dst.addr.reg = &c->eip;
+       c->dst.bytes = c->op_bytes;
+       return em_pop(ctxt);
+}
+
+static int em_ret_far(struct x86_emulate_ctxt *ctxt)
 {
        struct decode_cache *c = &ctxt->decode;
        int rc;
@@ -1849,12 +1840,11 @@ static int emulate_ret_far(struct x86_emulate_ctxt *ctxt,
        rc = emulate_pop(ctxt, &cs, c->op_bytes);
        if (rc != X86EMUL_CONTINUE)
                return rc;
-       rc = load_segment_descriptor(ctxt, ops, (u16)cs, VCPU_SREG_CS);
+       rc = load_segment_descriptor(ctxt, (u16)cs, VCPU_SREG_CS);
        return rc;
 }
 
-static int emulate_load_segment(struct x86_emulate_ctxt *ctxt,
-                          struct x86_emulate_ops *ops, int seg)
+static int emulate_load_segment(struct x86_emulate_ctxt *ctxt, int seg)
 {
        struct decode_cache *c = &ctxt->decode;
        unsigned short sel;
@@ -1862,7 +1852,7 @@ static int emulate_load_segment(struct x86_emulate_ctxt *ctxt,
 
        memcpy(&sel, c->src.valptr + c->op_bytes, 2);
 
-       rc = load_segment_descriptor(ctxt, ops, sel, seg);
+       rc = load_segment_descriptor(ctxt, sel, seg);
        if (rc != X86EMUL_CONTINUE)
                return rc;
 
@@ -1870,15 +1860,14 @@ static int emulate_load_segment(struct x86_emulate_ctxt *ctxt,
        return rc;
 }
 
-static inline void
+static void
 setup_syscalls_segments(struct x86_emulate_ctxt *ctxt,
-                       struct x86_emulate_ops *ops, struct desc_struct *cs,
-                       struct desc_struct *ss)
+                       struct desc_struct *cs, struct desc_struct *ss)
 {
        u16 selector;
 
        memset(cs, 0, sizeof(struct desc_struct));
-       ops->get_segment(ctxt, &selector, cs, NULL, VCPU_SREG_CS);
+       ctxt->ops->get_segment(ctxt, &selector, cs, NULL, VCPU_SREG_CS);
        memset(ss, 0, sizeof(struct desc_struct));
 
        cs->l = 0;              /* will be adjusted later */
@@ -1901,10 +1890,10 @@ setup_syscalls_segments(struct x86_emulate_ctxt *ctxt,
        ss->p = 1;
 }
 
-static int
-emulate_syscall(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
+static int em_syscall(struct x86_emulate_ctxt *ctxt)
 {
        struct decode_cache *c = &ctxt->decode;
+       struct x86_emulate_ops *ops = ctxt->ops;
        struct desc_struct cs, ss;
        u64 msr_data;
        u16 cs_sel, ss_sel;
@@ -1916,7 +1905,7 @@ emulate_syscall(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
                return emulate_ud(ctxt);
 
        ops->get_msr(ctxt, MSR_EFER, &efer);
-       setup_syscalls_segments(ctxt, ops, &cs, &ss);
+       setup_syscalls_segments(ctxt, &cs, &ss);
 
        ops->get_msr(ctxt, MSR_STAR, &msr_data);
        msr_data >>= 32;
@@ -1954,16 +1943,16 @@ emulate_syscall(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
        return X86EMUL_CONTINUE;
 }
 
-static int
-emulate_sysenter(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
+static int em_sysenter(struct x86_emulate_ctxt *ctxt)
 {
        struct decode_cache *c = &ctxt->decode;
+       struct x86_emulate_ops *ops = ctxt->ops;
        struct desc_struct cs, ss;
        u64 msr_data;
        u16 cs_sel, ss_sel;
        u64 efer = 0;
 
-       ctxt->ops->get_msr(ctxt, MSR_EFER, &efer);
+       ops->get_msr(ctxt, MSR_EFER, &efer);
        /* inject #GP if in real mode */
        if (ctxt->mode == X86EMUL_MODE_REAL)
                return emulate_gp(ctxt, 0);
@@ -1974,7 +1963,7 @@ emulate_sysenter(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
        if (ctxt->mode == X86EMUL_MODE_PROT64)
                return emulate_ud(ctxt);
 
-       setup_syscalls_segments(ctxt, ops, &cs, &ss);
+       setup_syscalls_segments(ctxt, &cs, &ss);
 
        ops->get_msr(ctxt, MSR_IA32_SYSENTER_CS, &msr_data);
        switch (ctxt->mode) {
@@ -2010,21 +1999,21 @@ emulate_sysenter(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
        return X86EMUL_CONTINUE;
 }
 
-static int
-emulate_sysexit(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
+static int em_sysexit(struct x86_emulate_ctxt *ctxt)
 {
        struct decode_cache *c = &ctxt->decode;
+       struct x86_emulate_ops *ops = ctxt->ops;
        struct desc_struct cs, ss;
        u64 msr_data;
        int usermode;
-       u16 cs_sel, ss_sel;
+       u16 cs_sel = 0, ss_sel = 0;
 
        /* inject #GP if in real mode or Virtual 8086 mode */
        if (ctxt->mode == X86EMUL_MODE_REAL ||
            ctxt->mode == X86EMUL_MODE_VM86)
                return emulate_gp(ctxt, 0);
 
-       setup_syscalls_segments(ctxt, ops, &cs, &ss);
+       setup_syscalls_segments(ctxt, &cs, &ss);
 
        if ((c->rex_prefix & 0x8) != 0x0)
                usermode = X86EMUL_MODE_PROT64;
@@ -2062,8 +2051,7 @@ emulate_sysexit(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
        return X86EMUL_CONTINUE;
 }
 
-static bool emulator_bad_iopl(struct x86_emulate_ctxt *ctxt,
-                             struct x86_emulate_ops *ops)
+static bool emulator_bad_iopl(struct x86_emulate_ctxt *ctxt)
 {
        int iopl;
        if (ctxt->mode == X86EMUL_MODE_REAL)
@@ -2071,13 +2059,13 @@ static bool emulator_bad_iopl(struct x86_emulate_ctxt *ctxt,
        if (ctxt->mode == X86EMUL_MODE_VM86)
                return true;
        iopl = (ctxt->eflags & X86_EFLAGS_IOPL) >> IOPL_SHIFT;
-       return ops->cpl(ctxt) > iopl;
+       return ctxt->ops->cpl(ctxt) > iopl;
 }
 
 static bool emulator_io_port_access_allowed(struct x86_emulate_ctxt *ctxt,
-                                           struct x86_emulate_ops *ops,
                                            u16 port, u16 len)
 {
+       struct x86_emulate_ops *ops = ctxt->ops;
        struct desc_struct tr_seg;
        u32 base3;
        int r;
@@ -2108,14 +2096,13 @@ static bool emulator_io_port_access_allowed(struct x86_emulate_ctxt *ctxt,
 }
 
 static bool emulator_io_permited(struct x86_emulate_ctxt *ctxt,
-                                struct x86_emulate_ops *ops,
                                 u16 port, u16 len)
 {
        if (ctxt->perm_ok)
                return true;
 
-       if (emulator_bad_iopl(ctxt, ops))
-               if (!emulator_io_port_access_allowed(ctxt, ops, port, len))
+       if (emulator_bad_iopl(ctxt))
+               if (!emulator_io_port_access_allowed(ctxt, port, len))
                        return false;
 
        ctxt->perm_ok = true;
@@ -2124,7 +2111,6 @@ static bool emulator_io_permited(struct x86_emulate_ctxt *ctxt,
 }
 
 static void save_state_to_tss16(struct x86_emulate_ctxt *ctxt,
-                               struct x86_emulate_ops *ops,
                                struct tss_segment_16 *tss)
 {
        struct decode_cache *c = &ctxt->decode;
@@ -2148,7 +2134,6 @@ static void save_state_to_tss16(struct x86_emulate_ctxt *ctxt,
 }
 
 static int load_state_from_tss16(struct x86_emulate_ctxt *ctxt,
-                                struct x86_emulate_ops *ops,
                                 struct tss_segment_16 *tss)
 {
        struct decode_cache *c = &ctxt->decode;
@@ -2179,19 +2164,19 @@ static int load_state_from_tss16(struct x86_emulate_ctxt *ctxt,
         * Now load segment descriptors. If fault happenes at this stage
         * it is handled in a context of new task
         */
-       ret = load_segment_descriptor(ctxt, ops, tss->ldt, VCPU_SREG_LDTR);
+       ret = load_segment_descriptor(ctxt, tss->ldt, VCPU_SREG_LDTR);
        if (ret != X86EMUL_CONTINUE)
                return ret;
-       ret = load_segment_descriptor(ctxt, ops, tss->es, VCPU_SREG_ES);
+       ret = load_segment_descriptor(ctxt, tss->es, VCPU_SREG_ES);
        if (ret != X86EMUL_CONTINUE)
                return ret;
-       ret = load_segment_descriptor(ctxt, ops, tss->cs, VCPU_SREG_CS);
+       ret = load_segment_descriptor(ctxt, tss->cs, VCPU_SREG_CS);
        if (ret != X86EMUL_CONTINUE)
                return ret;
-       ret = load_segment_descriptor(ctxt, ops, tss->ss, VCPU_SREG_SS);
+       ret = load_segment_descriptor(ctxt, tss->ss, VCPU_SREG_SS);
        if (ret != X86EMUL_CONTINUE)
                return ret;
-       ret = load_segment_descriptor(ctxt, ops, tss->ds, VCPU_SREG_DS);
+       ret = load_segment_descriptor(ctxt, tss->ds, VCPU_SREG_DS);
        if (ret != X86EMUL_CONTINUE)
                return ret;
 
@@ -2199,10 +2184,10 @@ static int load_state_from_tss16(struct x86_emulate_ctxt *ctxt,
 }
 
 static int task_switch_16(struct x86_emulate_ctxt *ctxt,
-                         struct x86_emulate_ops *ops,
                          u16 tss_selector, u16 old_tss_sel,
                          ulong old_tss_base, struct desc_struct *new_desc)
 {
+       struct x86_emulate_ops *ops = ctxt->ops;
        struct tss_segment_16 tss_seg;
        int ret;
        u32 new_tss_base = get_desc_base(new_desc);
@@ -2213,7 +2198,7 @@ static int task_switch_16(struct x86_emulate_ctxt *ctxt,
                /* FIXME: need to provide precise fault address */
                return ret;
 
-       save_state_to_tss16(ctxt, ops, &tss_seg);
+       save_state_to_tss16(ctxt, &tss_seg);
 
        ret = ops->write_std(ctxt, old_tss_base, &tss_seg, sizeof tss_seg,
                             &ctxt->exception);
@@ -2239,16 +2224,15 @@ static int task_switch_16(struct x86_emulate_ctxt *ctxt,
                        return ret;
        }
 
-       return load_state_from_tss16(ctxt, ops, &tss_seg);
+       return load_state_from_tss16(ctxt, &tss_seg);
 }
 
 static void save_state_to_tss32(struct x86_emulate_ctxt *ctxt,
-                               struct x86_emulate_ops *ops,
                                struct tss_segment_32 *tss)
 {
        struct decode_cache *c = &ctxt->decode;
 
-       tss->cr3 = ops->get_cr(ctxt, 3);
+       tss->cr3 = ctxt->ops->get_cr(ctxt, 3);
        tss->eip = c->eip;
        tss->eflags = ctxt->eflags;
        tss->eax = c->regs[VCPU_REGS_RAX];
@@ -2270,13 +2254,12 @@ static void save_state_to_tss32(struct x86_emulate_ctxt *ctxt,
 }
 
 static int load_state_from_tss32(struct x86_emulate_ctxt *ctxt,
-                                struct x86_emulate_ops *ops,
                                 struct tss_segment_32 *tss)
 {
        struct decode_cache *c = &ctxt->decode;
        int ret;
 
-       if (ops->set_cr(ctxt, 3, tss->cr3))
+       if (ctxt->ops->set_cr(ctxt, 3, tss->cr3))
                return emulate_gp(ctxt, 0);
        c->eip = tss->eip;
        ctxt->eflags = tss->eflags | 2;
@@ -2305,25 +2288,25 @@ static int load_state_from_tss32(struct x86_emulate_ctxt *ctxt,
         * Now load segment descriptors. If fault happenes at this stage
         * it is handled in a context of new task
         */
-       ret = load_segment_descriptor(ctxt, ops, tss->ldt_selector, VCPU_SREG_LDTR);
+       ret = load_segment_descriptor(ctxt, tss->ldt_selector, VCPU_SREG_LDTR);
        if (ret != X86EMUL_CONTINUE)
                return ret;
-       ret = load_segment_descriptor(ctxt, ops, tss->es, VCPU_SREG_ES);
+       ret = load_segment_descriptor(ctxt, tss->es, VCPU_SREG_ES);
        if (ret != X86EMUL_CONTINUE)
                return ret;
-       ret = load_segment_descriptor(ctxt, ops, tss->cs, VCPU_SREG_CS);
+       ret = load_segment_descriptor(ctxt, tss->cs, VCPU_SREG_CS);
        if (ret != X86EMUL_CONTINUE)
                return ret;
-       ret = load_segment_descriptor(ctxt, ops, tss->ss, VCPU_SREG_SS);
+       ret = load_segment_descriptor(ctxt, tss->ss, VCPU_SREG_SS);
        if (ret != X86EMUL_CONTINUE)
                return ret;
-       ret = load_segment_descriptor(ctxt, ops, tss->ds, VCPU_SREG_DS);
+       ret = load_segment_descriptor(ctxt, tss->ds, VCPU_SREG_DS);
        if (ret != X86EMUL_CONTINUE)
                return ret;
-       ret = load_segment_descriptor(ctxt, ops, tss->fs, VCPU_SREG_FS);
+       ret = load_segment_descriptor(ctxt, tss->fs, VCPU_SREG_FS);
        if (ret != X86EMUL_CONTINUE)
                return ret;
-       ret = load_segment_descriptor(ctxt, ops, tss->gs, VCPU_SREG_GS);
+       ret = load_segment_descriptor(ctxt, tss->gs, VCPU_SREG_GS);
        if (ret != X86EMUL_CONTINUE)
                return ret;
 
@@ -2331,10 +2314,10 @@ static int load_state_from_tss32(struct x86_emulate_ctxt *ctxt,
 }
 
 static int task_switch_32(struct x86_emulate_ctxt *ctxt,
-                         struct x86_emulate_ops *ops,
                          u16 tss_selector, u16 old_tss_sel,
                          ulong old_tss_base, struct desc_struct *new_desc)
 {
+       struct x86_emulate_ops *ops = ctxt->ops;
        struct tss_segment_32 tss_seg;
        int ret;
        u32 new_tss_base = get_desc_base(new_desc);
@@ -2345,7 +2328,7 @@ static int task_switch_32(struct x86_emulate_ctxt *ctxt,
                /* FIXME: need to provide precise fault address */
                return ret;
 
-       save_state_to_tss32(ctxt, ops, &tss_seg);
+       save_state_to_tss32(ctxt, &tss_seg);
 
        ret = ops->write_std(ctxt, old_tss_base, &tss_seg, sizeof tss_seg,
                             &ctxt->exception);
@@ -2371,14 +2354,14 @@ static int task_switch_32(struct x86_emulate_ctxt *ctxt,
                        return ret;
        }
 
-       return load_state_from_tss32(ctxt, ops, &tss_seg);
+       return load_state_from_tss32(ctxt, &tss_seg);
 }
 
 static int emulator_do_task_switch(struct x86_emulate_ctxt *ctxt,
-                                  struct x86_emulate_ops *ops,
                                   u16 tss_selector, int reason,
                                   bool has_error_code, u32 error_code)
 {
+       struct x86_emulate_ops *ops = ctxt->ops;
        struct desc_struct curr_tss_desc, next_tss_desc;
        int ret;
        u16 old_tss_sel = get_segment_selector(ctxt, VCPU_SREG_TR);
@@ -2388,10 +2371,10 @@ static int emulator_do_task_switch(struct x86_emulate_ctxt *ctxt,
 
        /* FIXME: old_tss_base == ~0 ? */
 
-       ret = read_segment_descriptor(ctxt, ops, tss_selector, &next_tss_desc);
+       ret = read_segment_descriptor(ctxt, tss_selector, &next_tss_desc);
        if (ret != X86EMUL_CONTINUE)
                return ret;
-       ret = read_segment_descriptor(ctxt, ops, old_tss_sel, &curr_tss_desc);
+       ret = read_segment_descriptor(ctxt, old_tss_sel, &curr_tss_desc);
        if (ret != X86EMUL_CONTINUE)
                return ret;
 
@@ -2413,8 +2396,7 @@ static int emulator_do_task_switch(struct x86_emulate_ctxt *ctxt,
 
        if (reason == TASK_SWITCH_IRET || reason == TASK_SWITCH_JMP) {
                curr_tss_desc.type &= ~(1 << 1); /* clear busy flag */
-               write_segment_descriptor(ctxt, ops, old_tss_sel,
-                                        &curr_tss_desc);
+               write_segment_descriptor(ctxt, old_tss_sel, &curr_tss_desc);
        }
 
        if (reason == TASK_SWITCH_IRET)
@@ -2426,10 +2408,10 @@ static int emulator_do_task_switch(struct x86_emulate_ctxt *ctxt,
                old_tss_sel = 0xffff;
 
        if (next_tss_desc.type & 8)
-               ret = task_switch_32(ctxt, ops, tss_selector, old_tss_sel,
+               ret = task_switch_32(ctxt, tss_selector, old_tss_sel,
                                     old_tss_base, &next_tss_desc);
        else
-               ret = task_switch_16(ctxt, ops, tss_selector, old_tss_sel,
+               ret = task_switch_16(ctxt, tss_selector, old_tss_sel,
                                     old_tss_base, &next_tss_desc);
        if (ret != X86EMUL_CONTINUE)
                return ret;
@@ -2439,8 +2421,7 @@ static int emulator_do_task_switch(struct x86_emulate_ctxt *ctxt,
 
        if (reason != TASK_SWITCH_IRET) {
                next_tss_desc.type |= (1 << 1); /* set busy flag */
-               write_segment_descriptor(ctxt, ops, tss_selector,
-                                        &next_tss_desc);
+               write_segment_descriptor(ctxt, tss_selector, &next_tss_desc);
        }
 
        ops->set_cr(ctxt, 0,  ops->get_cr(ctxt, 0) | X86_CR0_TS);
@@ -2462,14 +2443,13 @@ int emulator_task_switch(struct x86_emulate_ctxt *ctxt,
                         u16 tss_selector, int reason,
                         bool has_error_code, u32 error_code)
 {
-       struct x86_emulate_ops *ops = ctxt->ops;
        struct decode_cache *c = &ctxt->decode;
        int rc;
 
        c->eip = ctxt->eip;
        c->dst.type = OP_NONE;
 
-       rc = emulator_do_task_switch(ctxt, ops, tss_selector, reason,
+       rc = emulator_do_task_switch(ctxt, tss_selector, reason,
                                     has_error_code, error_code);
 
        if (rc == X86EMUL_CONTINUE)
@@ -2539,7 +2519,7 @@ static int em_call_far(struct x86_emulate_ctxt *ctxt)
        old_eip = c->eip;
 
        memcpy(&sel, c->src.valptr + c->op_bytes, 2);
-       if (load_segment_descriptor(ctxt, ctxt->ops, sel, VCPU_SREG_CS))
+       if (load_segment_descriptor(ctxt, sel, VCPU_SREG_CS))
                return X86EMUL_CONTINUE;
 
        c->eip = 0;
@@ -2635,6 +2615,28 @@ static int em_cmp(struct x86_emulate_ctxt *ctxt)
        return X86EMUL_CONTINUE;
 }
 
+static int em_test(struct x86_emulate_ctxt *ctxt)
+{
+       struct decode_cache *c = &ctxt->decode;
+
+       emulate_2op_SrcV("test", c->src, c->dst, ctxt->eflags);
+       return X86EMUL_CONTINUE;
+}
+
+static int em_xchg(struct x86_emulate_ctxt *ctxt)
+{
+       struct decode_cache *c = &ctxt->decode;
+
+       /* Write back the register source. */
+       c->src.val = c->dst.val;
+       write_register_operand(&c->src);
+
+       /* Write back the memory destination with implicit LOCK prefix. */
+       c->dst.val = c->src.orig_val;
+       c->lock_prefix = 1;
+       return X86EMUL_CONTINUE;
+}
+
 static int em_imul(struct x86_emulate_ctxt *ctxt)
 {
        struct decode_cache *c = &ctxt->decode;
@@ -2977,7 +2979,7 @@ static int check_perm_in(struct x86_emulate_ctxt *ctxt)
        struct decode_cache *c = &ctxt->decode;
 
        c->dst.bytes = min(c->dst.bytes, 4u);
-       if (!emulator_io_permited(ctxt, ctxt->ops, c->src.val, c->dst.bytes))
+       if (!emulator_io_permited(ctxt, c->src.val, c->dst.bytes))
                return emulate_gp(ctxt, 0);
 
        return X86EMUL_CONTINUE;
@@ -2988,7 +2990,7 @@ static int check_perm_out(struct x86_emulate_ctxt *ctxt)
        struct decode_cache *c = &ctxt->decode;
 
        c->src.bytes = min(c->src.bytes, 4u);
-       if (!emulator_io_permited(ctxt, ctxt->ops, c->dst.val, c->src.bytes))
+       if (!emulator_io_permited(ctxt, c->dst.val, c->src.bytes))
                return emulate_gp(ctxt, 0);
 
        return X86EMUL_CONTINUE;
@@ -3165,7 +3167,8 @@ static struct opcode opcode_table[256] = {
        G(DstMem | SrcImm | ModRM | Group, group1),
        G(ByteOp | DstMem | SrcImm | ModRM | No64 | Group, group1),
        G(DstMem | SrcImmByte | ModRM | Group, group1),
-       D2bv(DstMem | SrcReg | ModRM), D2bv(DstMem | SrcReg | ModRM | Lock),
+       I2bv(DstMem | SrcReg | ModRM, em_test),
+       I2bv(DstMem | SrcReg | ModRM | Lock, em_xchg),
        /* 0x88 - 0x8F */
        I2bv(DstMem | SrcReg | ModRM | Mov, em_mov),
        I2bv(DstReg | SrcMem | ModRM | Mov, em_mov),
@@ -3184,7 +3187,7 @@ static struct opcode opcode_table[256] = {
        I2bv(SrcSI | DstDI | Mov | String, em_mov),
        I2bv(SrcSI | DstDI | String, em_cmp),
        /* 0xA8 - 0xAF */
-       D2bv(DstAcc | SrcImm),
+       I2bv(DstAcc | SrcImm, em_test),
        I2bv(SrcAcc | DstDI | Mov | String, em_mov),
        I2bv(SrcSI | DstAcc | Mov | String, em_mov),
        I2bv(SrcAcc | DstDI | String, em_cmp),
@@ -3195,13 +3198,13 @@ static struct opcode opcode_table[256] = {
        /* 0xC0 - 0xC7 */
        D2bv(DstMem | SrcImmByte | ModRM),
        I(ImplicitOps | Stack | SrcImmU16, em_ret_near_imm),
-       D(ImplicitOps | Stack),
+       I(ImplicitOps | Stack, em_ret),
        D(DstReg | SrcMemFAddr | ModRM | No64), D(DstReg | SrcMemFAddr | ModRM | No64),
        G(ByteOp, group11), G(0, group11),
        /* 0xC8 - 0xCF */
-       N, N, N, D(ImplicitOps | Stack),
+       N, N, N, I(ImplicitOps | Stack, em_ret_far),
        D(ImplicitOps), DI(SrcImmByte, intn),
-       D(ImplicitOps | No64), DI(ImplicitOps, iret),
+       D(ImplicitOps | No64), II(ImplicitOps, em_iret, iret),
        /* 0xD0 - 0xD7 */
        D2bv(DstMem | SrcOne | ModRM), D2bv(DstMem | ModRM),
        N, N, N, N,
@@ -3213,7 +3216,7 @@ static struct opcode opcode_table[256] = {
        D2bvIP(SrcAcc | DstImmUByte, out, check_perm_out),
        /* 0xE8 - 0xEF */
        D(SrcImm | Stack), D(SrcImm | ImplicitOps),
-       D(SrcImmFAddr | No64), D(SrcImmByte | ImplicitOps),
+       I(SrcImmFAddr | No64, em_jmp_far), D(SrcImmByte | ImplicitOps),
        D2bvIP(SrcDX | DstAcc, in,  check_perm_in),
        D2bvIP(SrcAcc | DstDX, out, check_perm_out),
        /* 0xF0 - 0xF7 */
@@ -3228,7 +3231,8 @@ static struct opcode opcode_table[256] = {
 static struct opcode twobyte_table[256] = {
        /* 0x00 - 0x0F */
        G(0, group6), GD(0, &group7), N, N,
-       N, D(ImplicitOps | VendorSpecific), DI(ImplicitOps | Priv, clts), N,
+       N, I(ImplicitOps | VendorSpecific, em_syscall),
+       II(ImplicitOps | Priv, em_clts, clts), N,
        DI(ImplicitOps | Priv, invd), DI(ImplicitOps | Priv, wbinvd), N, N,
        N, D(ImplicitOps | ModRM), N, N,
        /* 0x10 - 0x1F */
@@ -3245,7 +3249,8 @@ static struct opcode twobyte_table[256] = {
        IIP(ImplicitOps, em_rdtsc, rdtsc, check_rdtsc),
        DI(ImplicitOps | Priv, rdmsr),
        DIP(ImplicitOps | Priv, rdpmc, check_rdpmc),
-       D(ImplicitOps | VendorSpecific), D(ImplicitOps | Priv | VendorSpecific),
+       I(ImplicitOps | VendorSpecific, em_sysenter),
+       I(ImplicitOps | Priv | VendorSpecific, em_sysexit),
        N, N,
        N, N, N, N, N, N, N, N,
        /* 0x40 - 0x4F */
@@ -3327,7 +3332,6 @@ static int decode_imm(struct x86_emulate_ctxt *ctxt, struct operand *op,
                      unsigned size, bool sign_extension)
 {
        struct decode_cache *c = &ctxt->decode;
-       struct x86_emulate_ops *ops = ctxt->ops;
        int rc = X86EMUL_CONTINUE;
 
        op->type = OP_IMM;
@@ -3362,10 +3366,8 @@ done:
        return rc;
 }
 
-int
-x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len)
+int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len)
 {
-       struct x86_emulate_ops *ops = ctxt->ops;
        struct decode_cache *c = &ctxt->decode;
        int rc = X86EMUL_CONTINUE;
        int mode = ctxt->mode;
@@ -3531,11 +3533,11 @@ done_prefixes:
 
        /* ModRM and SIB bytes. */
        if (c->d & ModRM) {
-               rc = decode_modrm(ctxt, ops, &memop);
+               rc = decode_modrm(ctxt, &memop);
                if (!c->has_seg_override)
                        set_seg_override(c, c->modrm_seg);
        } else if (c->d & MemAbs)
-               rc = decode_abs(ctxt, ops, &memop);
+               rc = decode_abs(ctxt, &memop);
        if (rc != X86EMUL_CONTINUE)
                goto done;
 
@@ -3731,8 +3733,7 @@ static bool string_insn_completed(struct x86_emulate_ctxt *ctxt)
        return false;
 }
 
-int
-x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
+int x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
 {
        struct x86_emulate_ops *ops = ctxt->ops;
        u64 msr_data;
@@ -3741,7 +3742,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
        int saved_dst_type = c->dst.type;
        int irq; /* Used for int 3, int, and into */
 
-       ctxt->decode.mem_read.pos = 0;
+       c->mem_read.pos = 0;
 
        if (ctxt->mode == X86EMUL_MODE_PROT64 && (c->d & No64)) {
                rc = emulate_ud(ctxt);
@@ -3861,25 +3862,25 @@ special_insn:
 
        switch (c->b) {
        case 0x06:              /* push es */
-               rc = emulate_push_sreg(ctxt, ops, VCPU_SREG_ES);
+               rc = emulate_push_sreg(ctxt, VCPU_SREG_ES);
                break;
        case 0x07:              /* pop es */
-               rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_ES);
+               rc = emulate_pop_sreg(ctxt, VCPU_SREG_ES);
                break;
        case 0x0e:              /* push cs */
-               rc = emulate_push_sreg(ctxt, ops, VCPU_SREG_CS);
+               rc = emulate_push_sreg(ctxt, VCPU_SREG_CS);
                break;
        case 0x16:              /* push ss */
-               rc = emulate_push_sreg(ctxt, ops, VCPU_SREG_SS);
+               rc = emulate_push_sreg(ctxt, VCPU_SREG_SS);
                break;
        case 0x17:              /* pop ss */
-               rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_SS);
+               rc = emulate_pop_sreg(ctxt, VCPU_SREG_SS);
                break;
        case 0x1e:              /* push ds */
-               rc = emulate_push_sreg(ctxt, ops, VCPU_SREG_DS);
+               rc = emulate_push_sreg(ctxt, VCPU_SREG_DS);
                break;
        case 0x1f:              /* pop ds */
-               rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_DS);
+               rc = emulate_pop_sreg(ctxt, VCPU_SREG_DS);
                break;
        case 0x40 ... 0x47: /* inc r16/r32 */
                emulate_1op("inc", c->dst, ctxt->eflags);
@@ -3905,22 +3906,6 @@ special_insn:
                if (test_cc(c->b, ctxt->eflags))
                        jmp_rel(c, c->src.val);
                break;
-       case 0x84 ... 0x85:
-       test:
-               emulate_2op_SrcV("test", c->src, c->dst, ctxt->eflags);
-               break;
-       case 0x86 ... 0x87:     /* xchg */
-       xchg:
-               /* Write back the register source. */
-               c->src.val = c->dst.val;
-               write_register_operand(&c->src);
-               /*
-                * Write back the memory destination with implicit LOCK
-                * prefix.
-                */
-               c->dst.val = c->src.orig_val;
-               c->lock_prefix = 1;
-               break;
        case 0x8c:  /* mov r/m, sreg */
                if (c->modrm_reg > VCPU_SREG_GS) {
                        rc = emulate_ud(ctxt);
@@ -3945,7 +3930,7 @@ special_insn:
                if (c->modrm_reg == VCPU_SREG_SS)
                        ctxt->interruptibility = KVM_X86_SHADOW_INT_MOV_SS;
 
-               rc = load_segment_descriptor(ctxt, ops, sel, c->modrm_reg);
+               rc = load_segment_descriptor(ctxt, sel, c->modrm_reg);
 
                c->dst.type = OP_NONE;  /* Disable writeback. */
                break;
@@ -3956,7 +3941,8 @@ special_insn:
        case 0x90 ... 0x97: /* nop / xchg reg, rax */
                if (c->dst.addr.reg == &c->regs[VCPU_REGS_RAX])
                        break;
-               goto xchg;
+               rc = em_xchg(ctxt);
+               break;
        case 0x98: /* cbw/cwde/cdqe */
                switch (c->op_bytes) {
                case 2: c->dst.val = (s8)c->dst.val; break;
@@ -3964,25 +3950,14 @@ special_insn:
                case 8: c->dst.val = (s32)c->dst.val; break;
                }
                break;
-       case 0xa8 ... 0xa9:     /* test ax, imm */
-               goto test;
        case 0xc0 ... 0xc1:
                rc = em_grp2(ctxt);
                break;
-       case 0xc3: /* ret */
-               c->dst.type = OP_REG;
-               c->dst.addr.reg = &c->eip;
-               c->dst.bytes = c->op_bytes;
-               rc = em_pop(ctxt);
-               break;
        case 0xc4:              /* les */
-               rc = emulate_load_segment(ctxt, ops, VCPU_SREG_ES);
+               rc = emulate_load_segment(ctxt, VCPU_SREG_ES);
                break;
        case 0xc5:              /* lds */
-               rc = emulate_load_segment(ctxt, ops, VCPU_SREG_DS);
-               break;
-       case 0xcb:              /* ret far */
-               rc = emulate_ret_far(ctxt, ops);
+               rc = emulate_load_segment(ctxt, VCPU_SREG_DS);
                break;
        case 0xcc:              /* int3 */
                irq = 3;
@@ -3990,7 +3965,7 @@ special_insn:
        case 0xcd:              /* int n */
                irq = c->src.val;
        do_interrupt:
-               rc = emulate_int(ctxt, ops, irq);
+               rc = emulate_int(ctxt, irq);
                break;
        case 0xce:              /* into */
                if (ctxt->eflags & EFLG_OF) {
@@ -3998,9 +3973,6 @@ special_insn:
                        goto do_interrupt;
                }
                break;
-       case 0xcf:              /* iret */
-               rc = emulate_iret(ctxt, ops);
-               break;
        case 0xd0 ... 0xd1:     /* Grp2 */
                rc = em_grp2(ctxt);
                break;
@@ -4032,19 +4004,14 @@ special_insn:
                break;
        }
        case 0xe9: /* jmp rel */
-               goto jmp;
-       case 0xea: /* jmp far */
-               rc = em_jmp_far(ctxt);
-               break;
-       case 0xeb:
-             jmp:              /* jmp rel short */
+       case 0xeb: /* jmp rel short */
                jmp_rel(c, c->src.val);
                c->dst.type = OP_NONE; /* Disable writeback. */
                break;
        case 0xec: /* in al,dx */
        case 0xed: /* in (e/r)ax,dx */
        do_io_in:
-               if (!pio_in_emulated(ctxt, ops, c->dst.bytes, c->src.val,
+               if (!pio_in_emulated(ctxt, c->dst.bytes, c->src.val,
                                     &c->dst.val))
                        goto done; /* IO is needed */
                break;
@@ -4072,14 +4039,14 @@ special_insn:
                ctxt->eflags |= EFLG_CF;
                break;
        case 0xfa: /* cli */
-               if (emulator_bad_iopl(ctxt, ops)) {
+               if (emulator_bad_iopl(ctxt)) {
                        rc = emulate_gp(ctxt, 0);
                        goto done;
                } else
                        ctxt->eflags &= ~X86_EFLAGS_IF;
                break;
        case 0xfb: /* sti */
-               if (emulator_bad_iopl(ctxt, ops)) {
+               if (emulator_bad_iopl(ctxt)) {
                        rc = emulate_gp(ctxt, 0);
                        goto done;
                } else {
@@ -4126,7 +4093,7 @@ writeback:
                                &c->dst);
 
        if (c->rep_prefix && (c->d & String)) {
-               struct read_cache *r = &ctxt->decode.io_read;
+               struct read_cache *r = &c->io_read;
                register_address_increment(c, &c->regs[VCPU_REGS_RCX], -1);
 
                if (!string_insn_completed(ctxt)) {
@@ -4141,7 +4108,7 @@ writeback:
                                 * decode, but since instruction is restarted
                                 * we have to do it here.
                                 */
-                               ctxt->decode.mem_read.end = 0;
+                               c->mem_read.end = 0;
                                return EMULATION_RESTART;
                        }
                        goto done; /* skip rip writeback */
@@ -4160,12 +4127,6 @@ done:
 
 twobyte_insn:
        switch (c->b) {
-       case 0x05:              /* syscall */
-               rc = emulate_syscall(ctxt, ops);
-               break;
-       case 0x06:
-               rc = em_clts(ctxt);
-               break;
        case 0x09:              /* wbinvd */
                (ctxt->ops->wbinvd)(ctxt);
                break;
@@ -4222,12 +4183,6 @@ twobyte_insn:
                }
                rc = X86EMUL_CONTINUE;
                break;
-       case 0x34:              /* sysenter */
-               rc = emulate_sysenter(ctxt, ops);
-               break;
-       case 0x35:              /* sysexit */
-               rc = emulate_sysexit(ctxt, ops);
-               break;
        case 0x40 ... 0x4f:     /* cmov */
                c->dst.val = c->dst.orig_val = c->src.val;
                if (!test_cc(c->b, ctxt->eflags))
@@ -4241,10 +4196,10 @@ twobyte_insn:
                c->dst.val = test_cc(c->b, ctxt->eflags);
                break;
        case 0xa0:        /* push fs */
-               rc = emulate_push_sreg(ctxt, ops, VCPU_SREG_FS);
+               rc = emulate_push_sreg(ctxt, VCPU_SREG_FS);
                break;
        case 0xa1:       /* pop fs */
-               rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_FS);
+               rc = emulate_pop_sreg(ctxt, VCPU_SREG_FS);
                break;
        case 0xa3:
              bt:               /* bt */
@@ -4258,10 +4213,10 @@ twobyte_insn:
                emulate_2op_cl("shld", c->src2, c->src, c->dst, ctxt->eflags);
                break;
        case 0xa8:      /* push gs */
-               rc = emulate_push_sreg(ctxt, ops, VCPU_SREG_GS);
+               rc = emulate_push_sreg(ctxt, VCPU_SREG_GS);
                break;
        case 0xa9:      /* pop gs */
-               rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_GS);
+               rc = emulate_pop_sreg(ctxt, VCPU_SREG_GS);
                break;
        case 0xab:
              bts:              /* bts */
@@ -4291,17 +4246,17 @@ twobyte_insn:
                }
                break;
        case 0xb2:              /* lss */
-               rc = emulate_load_segment(ctxt, ops, VCPU_SREG_SS);
+               rc = emulate_load_segment(ctxt, VCPU_SREG_SS);
                break;
        case 0xb3:
              btr:              /* btr */
                emulate_2op_SrcV_nobyte("btr", c->src, c->dst, ctxt->eflags);
                break;
        case 0xb4:              /* lfs */
-               rc = emulate_load_segment(ctxt, ops, VCPU_SREG_FS);
+               rc = emulate_load_segment(ctxt, VCPU_SREG_FS);
                break;
        case 0xb5:              /* lgs */
-               rc = emulate_load_segment(ctxt, ops, VCPU_SREG_GS);
+               rc = emulate_load_segment(ctxt, VCPU_SREG_GS);
                break;
        case 0xb6 ... 0xb7:     /* movzx */
                c->dst.bytes = c->op_bytes;