Ths patch adds IRET instruction (opcode 0xcf).
Currently, only IRET in real mode is emulated. Protected mode support is to be 
added later if needed.

Signed-off-by: Mohammed Gamal <[email protected]>
---
 arch/x86/kvm/emulate.c |   63 +++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 62 insertions(+), 1 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index b38bd8b..ddc1da3 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -1,5 +1,5 @@
 /******************************************************************************
- * emulate.c
+ i emulate.c
  *
  * Generic x86 (32-bit and 64-bit) instruction decoder and emulator.
  *
@@ -1778,6 +1778,61 @@ static int emulate_popa(struct x86_emulate_ctxt *ctxt,
        return rc;
 }
 
+static int emulate_iret_real(struct x86_emulate_ctxt *ctxt,
+                            struct x86_emulate_ops *ops)
+{
+       struct decode_cache *c = &ctxt->decode;
+       int rc = X86EMUL_CONTINUE;
+       unsigned long temp_eip = 0;
+       unsigned long temp_eflags = 0;
+       /* TODO: Add stack limit check */
+
+       rc = emulate_pop(ctxt, ops, &temp_eip, c->op_bytes);
+
+       if (rc != X86EMUL_CONTINUE)
+               return rc;
+
+       if (temp_eip & ~0xffff) {
+               emulate_gp(ctxt, 0);
+               return X86EMUL_PROPAGATE_FAULT;
+       }
+
+       c->eip = temp_eip;
+
+       rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_CS);
+
+       if (rc != X86EMUL_CONTINUE)
+               return rc;
+
+       rc = emulate_pop(ctxt, ops, &temp_eflags, c->op_bytes);
+
+       if (rc != X86EMUL_CONTINUE)
+               return rc;
+
+       if (c->op_bytes == 4)
+               temp_eflags = ((temp_eflags & 0x257fd5) | (ctxt->eflags & 
0x1a0000));
+       
+       ctxt->eflags = temp_eflags;
+
+       return rc;
+}
+
+static inline int emulate_iret(struct x86_emulate_ctxt *ctxt,
+                                   struct x86_emulate_ops* ops)
+{
+       switch(ctxt->mode) {
+       case X86EMUL_MODE_REAL:
+               return emulate_iret_real(ctxt, ops);
+       case X86EMUL_MODE_VM86:
+       case X86EMUL_MODE_PROT16:
+       case X86EMUL_MODE_PROT32:
+       case X86EMUL_MODE_PROT64:
+       default:
+               /* iret from protected mode unimplemented yet */
+               return X86EMUL_UNHANDLEABLE;            
+       }
+}
+
 static inline int emulate_grp1a(struct x86_emulate_ctxt *ctxt,
                                struct x86_emulate_ops *ops)
 {
@@ -2910,6 +2965,12 @@ special_insn:
                if (rc != X86EMUL_CONTINUE)
                        goto done;
                break;
+       case 0xcf:              /* iret */
+               rc = emulate_iret(ctxt, ops);
+
+               if (rc != X86EMUL_CONTINUE)
+                       goto done;
+               break;
        case 0xd0 ... 0xd1:     /* Grp2 */
                c->src.val = 1;
                emulate_grp2(ctxt);
-- 
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to