[xen-unstable] x86_emulate: Emulate IRET.

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[xen-unstable] x86_emulate: Emulate IRET.

Xen patchbot-unstable
# HG changeset patch
# User Keir Fraser <[hidden email]>
# Date 1196013990 0
# Node ID 7c6944d861b21772faa1898a00322a382166ca6e
# Parent  502f5b9469c35ed1f93ebf7ac6b5f6efb2698fc7
x86_emulate: Emulate IRET.
Signed-off-by: Keir Fraser <[hidden email]>
---
 xen/arch/x86/x86_emulate.c |   29 ++++++++++++++++++++++++++++-
 1 files changed, 28 insertions(+), 1 deletion(-)

diff -r 502f5b9469c3 -r 7c6944d861b2 xen/arch/x86/x86_emulate.c
--- a/xen/arch/x86/x86_emulate.c Sun Nov 25 18:05:56 2007 +0000
+++ b/xen/arch/x86/x86_emulate.c Sun Nov 25 18:06:30 2007 +0000
@@ -149,7 +149,7 @@ static uint8_t opcode_table[256] = {
     ImplicitOps, ImplicitOps,
     0, 0, ByteOp|DstMem|SrcImm|ModRM|Mov, DstMem|SrcImm|ModRM|Mov,
     /* 0xC8 - 0xCF */
-    0, 0, 0, 0, ImplicitOps, ImplicitOps, ImplicitOps, 0,
+    0, 0, 0, 0, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
     /* 0xD0 - 0xD7 */
     ByteOp|DstMem|SrcImplicit|ModRM, DstMem|SrcImplicit|ModRM,
     ByteOp|DstMem|SrcImplicit|ModRM, DstMem|SrcImplicit|ModRM,
@@ -2214,6 +2214,33 @@ x86_emulate(
         src.val = EXC_OF;
         goto swint;
 
+    case 0xcf: /* iret */ {
+        unsigned long cs, eip, eflags;
+        uint32_t mask = EFLG_VIP | EFLG_VIF | EFLG_VM;
+        if ( !mode_iopl() )
+            mask |= EFLG_IOPL;
+        fail_if(!in_realmode(ctxt, ops));
+        fail_if(ops->write_rflags == NULL);
+        if ( (rc = ops->read(x86_seg_ss, sp_post_inc(op_bytes),
+                             &eip, op_bytes, ctxt)) ||
+             (rc = ops->read(x86_seg_ss, sp_post_inc(op_bytes),
+                             &cs, op_bytes, ctxt)) ||
+             (rc = ops->read(x86_seg_ss, sp_post_inc(op_bytes),
+                             &eflags, op_bytes, ctxt)) )
+            goto done;
+        if ( op_bytes == 2 )
+            eflags = (uint16_t)eflags | (_regs.eflags & 0xffff0000u);
+        eflags &= 0x257fd5;
+        _regs.eflags &= mask;
+        _regs.eflags |= (uint32_t)(eflags & ~mask) | 0x02;
+        if ( (rc = ops->write_rflags(_regs.eflags, ctxt)) != 0 )
+            goto done;
+        _regs.eip = eip;
+        if ( (rc = load_seg(x86_seg_cs, (uint16_t)cs, ctxt, ops)) != 0 )
+            goto done;
+        break;
+    }
+
     case 0xd4: /* aam */ {
         unsigned int base = insn_fetch_type(uint8_t);
         uint8_t al = _regs.eax;

_______________________________________________
Xen-changelog mailing list
[hidden email]
http://lists.xensource.com/xen-changelog