In case you've been wondered about kvm emulation, devs did
steb-by-step decoding/emulation. Really outstanding and impressive:
arch/x86/kvm/emulate.c
x86_emulate_insn
[..]
3036 switch (c->b) {
[..]
3078 case 0x28 ... 0x2d:
3079 sub: /* sub */
3080 emulate_2op_SrcV("sub", c->src, c->dst, ctxt->eflags);
3081 break;
3082 case 0x30 ... 0x35:
3083 xor: /* xor */
3084 emulate_2op_SrcV("xor", c->src, c->dst, ctxt->eflags);
3085 break;
3086 case 0x38 ... 0x3d:
3087 cmp: /* cmp */
3088 emulate_2op_SrcV("cmp", c->src, c->dst, ctxt->eflags);
3089 break;
3090 case 0x40 ... 0x47: /* inc r16/r32 */
3091 emulate_1op("inc", c->dst, ctxt->eflags);
3092 break;
3093 case 0x48 ... 0x4f: /* dec r16/r32 */
3094 emulate_1op("dec", c->dst, ctxt->eflags);
3095 break;
3096 case 0x58 ... 0x5f: /* pop reg */
3097 pop_instruction:
3098 rc = emulate_pop(ctxt, ops, &c->dst.val, c->op_bytes);
3099 break;
3100 case 0x60: /* pusha */
3101 rc = emulate_pusha(ctxt, ops);
3102 break;
3103 case 0x61: /* popa */
3104 rc = emulate_popa(ctxt, ops);
3105 break;
3106 case 0x63: /* movsxd */
3107 if (ctxt->mode != X86EMUL_MODE_PROT64)
3108 goto cannot_emulate;
3109 c->dst.val = (s32) c->src.val;
3110 break;
3111 case 0x6c: /* insb */
3112 case 0x6d: /* insw/insd */
3113 c->src.val = c->regs[VCPU_REGS_RDX];
3114 goto do_io_in;
3115 case 0x6e: /* outsb */
3116 case 0x6f: /* outsw/outsd */
3117 c->dst.val = c->regs[VCPU_REGS_RDX];
3118 goto do_io_out;
3119 break;
3120 case 0x70 ... 0x7f: /* jcc (short) */
3121 if (test_cc(c->b, ctxt->eflags))
3122 jmp_rel(c, c->src.val);
3123 break;
3124 case 0x80 ... 0x83: /* Grp1 */
3125 switch (c->modrm_reg) {
3126 case 0:
3127 goto add;
3128 case 1:
3129 goto or;
3130 case 2:
3131 goto adc;
3132 case 3:
3133 goto sbb;
3134 case 4:
3135 goto and;
3136 case 5:
3137 goto sub;
3138 case 6:
3139 goto xor;
3140 case 7:
3141 goto cmp;
3142 }
3143 break;
3144 case 0x84 ... 0x85:
[..]
the whole platform... with sysenter/sysexit/syscal/etc.
emulate_sysenter
[..]
1650 /* inject #GP if in real mode */
1651 if (ctxt->mode == X86EMUL_MODE_REAL)
1652 return emulate_gp(ctxt, 0);
1653
1654 /* XXX sysenter/sysexit have not been tested in 64bit mode.
1655 * Therefore, we inject an #UD.
1656 */
1657 if (ctxt->mode == X86EMUL_MODE_PROT64)
1658 return emulate_ud(ctxt);
1659
1660 setup_syscalls_segments(ctxt, ops, &cs, &ss);
1661
1662 ops->get_msr(ctxt->vcpu, MSR_IA32_SYSENTER_CS, &msr_data);
1663 switch (ctxt->mode) {
1664 case X86EMUL_MODE_PROT32:
1665 if ((msr_data & 0xfffc) == 0x0)
1666 return emulate_gp(ctxt, 0);
1667 break;
1668 case X86EMUL_MODE_PROT64:
1669 if (msr_data == 0x0)
1670 return emulate_gp(ctxt, 0);
1671 break;
1672 }
[..]
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment