WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] x86_emulate: Emulate MMX movq instruction

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] x86_emulate: Emulate MMX movq instructions.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 22 Apr 2008 07:10:25 -0700
Delivery-date: Tue, 22 Apr 2008 07:12:31 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1208425614 -3600
# Node ID d178c5ee6822a269e365d206da74e9704f059fa1
# Parent  a38a41de0800cefca755ffb600d6d5e96f084697
x86_emulate: Emulate MMX movq instructions.
Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 xen/arch/x86/hvm/emulate.c             |   19 +++++++-
 xen/arch/x86/x86_emulate/x86_emulate.c |   77 ++++++++++++++++++++++++++-------
 xen/arch/x86/x86_emulate/x86_emulate.h |    9 +++
 3 files changed, 87 insertions(+), 18 deletions(-)

diff -r a38a41de0800 -r d178c5ee6822 xen/arch/x86/hvm/emulate.c
--- a/xen/arch/x86/hvm/emulate.c        Wed Apr 16 16:42:47 2008 +0100
+++ b/xen/arch/x86/hvm/emulate.c        Thu Apr 17 10:46:54 2008 +0100
@@ -674,16 +674,33 @@ static int hvmemul_inject_sw_interrupt(
     return X86EMUL_OKAY;
 }
 
-static void hvmemul_get_fpu(
+static int hvmemul_get_fpu(
     void (*exception_callback)(void *, struct cpu_user_regs *),
     void *exception_callback_arg,
+    enum x86_emulate_fpu_type type,
     struct x86_emulate_ctxt *ctxt)
 {
     struct vcpu *curr = current;
+
+    switch ( type )
+    {
+    case X86EMUL_FPU_fpu:
+        break;
+    case X86EMUL_FPU_mmx:
+        if ( !cpu_has_mmx )
+            return X86EMUL_UNHANDLEABLE;
+        break;
+    default:
+        return X86EMUL_UNHANDLEABLE;
+    }
+
     if ( !curr->fpu_dirtied )
         hvm_funcs.fpu_dirty_intercept();
+
     curr->arch.hvm_vcpu.fpu_exception_callback = exception_callback;
     curr->arch.hvm_vcpu.fpu_exception_callback_arg = exception_callback_arg;
+
+    return X86EMUL_OKAY;
 }
 
 static void hvmemul_put_fpu(
diff -r a38a41de0800 -r d178c5ee6822 xen/arch/x86/x86_emulate/x86_emulate.c
--- a/xen/arch/x86/x86_emulate/x86_emulate.c    Wed Apr 16 16:42:47 2008 +0100
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c    Thu Apr 17 10:46:54 2008 +0100
@@ -195,9 +195,9 @@ static uint8_t twobyte_table[256] = {
     /* 0x50 - 0x5F */
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     /* 0x60 - 0x6F */
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps|ModRM,
     /* 0x70 - 0x7F */
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps|ModRM,
     /* 0x80 - 0x87 */
     ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
     ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
@@ -558,41 +558,48 @@ static void fpu_handle_exception(void *_
     regs->eip += fic->insn_bytes;
 }
 
+#define get_fpu(_type, _fic)                                    \
+do{ (_fic)->exn_raised = 0;                                     \
+    fail_if(ops->get_fpu == NULL);                              \
+    rc = ops->get_fpu(fpu_handle_exception, _fic, _type, ctxt); \
+    if ( rc ) goto done;                                        \
+} while (0)
+#define put_fpu(_fic)                                           \
+do{                                                             \
+    if ( ops->put_fpu != NULL )                                 \
+        ops->put_fpu(ctxt);                                     \
+    generate_exception_if((_fic)->exn_raised, EXC_MF, -1);      \
+} while (0)
+
 #define emulate_fpu_insn(_op)                           \
-do{ struct fpu_insn_ctxt fic = { 0 };                   \
-    fail_if(ops->get_fpu == NULL);                      \
-    ops->get_fpu(fpu_handle_exception, &fic, ctxt);     \
+do{ struct fpu_insn_ctxt fic;                           \
+    get_fpu(X86EMUL_FPU_fpu, &fic);                     \
     asm volatile (                                      \
         "movb $2f-1f,%0 \n"                             \
         "1: " _op "     \n"                             \
         "2:             \n"                             \
         : "=m" (fic.insn_bytes) : : "memory" );         \
-    ops->put_fpu(ctxt);                                 \
-    generate_exception_if(fic.exn_raised, EXC_MF, -1);  \
+    put_fpu(&fic);                                      \
 } while (0)
 
 #define emulate_fpu_insn_memdst(_op, _arg)              \
-do{ struct fpu_insn_ctxt fic = { 0 };                   \
-    fail_if(ops->get_fpu == NULL);                      \
-    ops->get_fpu(fpu_handle_exception, &fic, ctxt);     \
+do{ struct fpu_insn_ctxt fic;                           \
+    get_fpu(X86EMUL_FPU_fpu, &fic);                     \
     asm volatile (                                      \
         "movb $2f-1f,%0 \n"                             \
         "1: " _op " %1  \n"                             \
         "2:             \n"                             \
         : "=m" (fic.insn_bytes), "=m" (_arg)            \
         : : "memory" );                                 \
-    ops->put_fpu(ctxt);                                 \
-    generate_exception_if(fic.exn_raised, EXC_MF, -1);  \
+    put_fpu(&fic);                                      \
 } while (0)
 
 #define emulate_fpu_insn_stub(_bytes...)                                \
 do{ uint8_t stub[] = { _bytes, 0xc3 };                                  \
     struct fpu_insn_ctxt fic = { .insn_bytes = sizeof(stub)-1 };        \
-    fail_if(ops->get_fpu == NULL);                                      \
-    ops->get_fpu(fpu_handle_exception, &fic, ctxt);                     \
+    get_fpu(X86EMUL_FPU_fpu, &fic);                                     \
     (*(void(*)(void))stub)();                                           \
-    ops->put_fpu(ctxt);                                                 \
-    generate_exception_if(fic.exn_raised, EXC_MF, -1);                  \
+    put_fpu(&fic);                                                      \
 } while (0)
 
 static unsigned long __get_rep_prefix(
@@ -3369,6 +3376,44 @@ x86_emulate(
         break;
     }
 
+    case 0x6f: /* movq mm/m64,mm */ {
+        uint8_t stub[] = { 0x0f, 0x6f, modrm, 0xc3 };
+        struct fpu_insn_ctxt fic = { .insn_bytes = sizeof(stub)-1 };
+        uint64_t val;
+        if ( ea.type == OP_MEM )
+        {
+            unsigned long lval, hval;
+            if ( (rc = ops->read(ea.mem.seg, ea.mem.off+0, &lval, 4, ctxt)) ||
+                 (rc = ops->read(ea.mem.seg, ea.mem.off+4, &hval, 4, ctxt)) )
+                goto done;
+            val = ((uint64_t)hval << 32) | (uint32_t)lval;
+            stub[2] = modrm & 0x38; /* movq (%eax),%mmN */
+        }
+        get_fpu(X86EMUL_FPU_mmx, &fic);
+        asm volatile ( "call *%0" : : "r" (stub), "a" (&val) : "memory" );
+        put_fpu(&fic);
+        break;
+    }
+
+    case 0x7f: /* movq mm,mm/m64 */ {
+        uint8_t stub[] = { 0x0f, 0x7f, modrm, 0xc3 };
+        struct fpu_insn_ctxt fic = { .insn_bytes = sizeof(stub)-1 };
+        uint64_t val;
+        if ( ea.type == OP_MEM )
+            stub[2] = modrm & 0x38; /* movq %mmN,(%eax) */
+        get_fpu(X86EMUL_FPU_mmx, &fic);
+        asm volatile ( "call *%0" : : "r" (stub), "a" (&val) : "memory" );
+        put_fpu(&fic);
+        if ( ea.type == OP_MEM )
+        {
+            unsigned long lval = (uint32_t)val, hval = (uint32_t)(val >> 32);
+            if ( (rc = ops->write(ea.mem.seg, ea.mem.off+0, lval, 4, ctxt)) ||
+                 (rc = ops->write(ea.mem.seg, ea.mem.off+4, hval, 4, ctxt)) )
+                goto done;
+        }
+        break;
+    }
+
     case 0x80 ... 0x8f: /* jcc (near) */ {
         int rel = (((op_bytes == 2) && !mode_64bit())
                    ? (int32_t)insn_fetch_type(int16_t)
diff -r a38a41de0800 -r d178c5ee6822 xen/arch/x86/x86_emulate/x86_emulate.h
--- a/xen/arch/x86/x86_emulate/x86_emulate.h    Wed Apr 16 16:42:47 2008 +0100
+++ b/xen/arch/x86/x86_emulate/x86_emulate.h    Thu Apr 17 10:46:54 2008 +0100
@@ -95,6 +95,12 @@ struct segment_register {
  /* (cmpxchg accessor): CMPXCHG failed. Maps to X86EMUL_RETRY in caller. */
 #define X86EMUL_CMPXCHG_FAILED 3
 
+/* FPU sub-types which may be requested via ->get_fpu(). */
+enum x86_emulate_fpu_type {
+    X86EMUL_FPU_fpu, /* Standard FPU coprocessor instruction set */
+    X86EMUL_FPU_mmx  /* MMX instruction set (%mm0-%mm7) */
+};
+
 /*
  * These operations represent the instruction emulator's interface to memory.
  * 
@@ -347,9 +353,10 @@ struct x86_emulate_ops
      *  @exn_callback: On any FPU or SIMD exception, pass control to
      *                 (*exception_callback)(exception_callback_arg, regs).
      */
-    void (*get_fpu)(
+    int (*get_fpu)(
         void (*exception_callback)(void *, struct cpu_user_regs *),
         void *exception_callback_arg,
+        enum x86_emulate_fpu_type type,
         struct x86_emulate_ctxt *ctxt);
 
     /* put_fpu: Relinquish the FPU. Unhook from FPU/SIMD exception handlers. */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] x86_emulate: Emulate MMX movq instructions., Xen patchbot-unstable <=