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] [XEN] Allow stack-address-size to be spec

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [XEN] Allow stack-address-size to be specified differently from
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 15 Jan 2007 19:35:08 -0800
Delivery-date: Mon, 15 Jan 2007 19:35:10 -0800
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 kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1168875800 0
# Node ID 0ba81aa56455be37c2d5c19920f3633ad267604c
# Parent  ba5e80864f9c9cc91879e2fc175370634d3bdd9a
[XEN] Allow stack-address-size to be specified differently from
regular address-size in the emulator.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 tools/tests/test_x86_emulator.c   |    3 +-
 xen/arch/x86/mm.c                 |    3 +-
 xen/arch/x86/mm/shadow/common.c   |   25 +++++++++++++----
 xen/arch/x86/x86_emulate.c        |   53 ++++++++++++++++++++------------------
 xen/include/asm-x86/x86_emulate.h |    7 +++--
 5 files changed, 56 insertions(+), 35 deletions(-)

diff -r ba5e80864f9c -r 0ba81aa56455 tools/tests/test_x86_emulator.c
--- a/tools/tests/test_x86_emulator.c   Mon Jan 15 14:32:25 2007 +0000
+++ b/tools/tests/test_x86_emulator.c   Mon Jan 15 15:43:20 2007 +0000
@@ -118,7 +118,8 @@ int main(int argc, char **argv)
 #endif
 
     ctxt.regs = &regs;
-    ctxt.address_bytes = 4;
+    ctxt.addr_size = 32;
+    ctxt.sp_size   = 32;
 
     res = mmap((void *)0x100000, MMAP_SZ, PROT_READ|PROT_WRITE,
                MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
diff -r ba5e80864f9c -r 0ba81aa56455 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Mon Jan 15 14:32:25 2007 +0000
+++ b/xen/arch/x86/mm.c Mon Jan 15 15:43:20 2007 +0000
@@ -3376,7 +3376,8 @@ int ptwr_do_page_fault(struct vcpu *v, u
         goto bail;
 
     ptwr_ctxt.ctxt.regs = guest_cpu_user_regs();
-    ptwr_ctxt.ctxt.address_bytes = IS_COMPAT(d) ? 4 : sizeof(long);
+    ptwr_ctxt.ctxt.addr_size = ptwr_ctxt.ctxt.sp_size =
+        IS_COMPAT(d) ? 32 : BITS_PER_LONG;
     ptwr_ctxt.cr2 = addr;
     ptwr_ctxt.pte = pte;
     if ( x86_emulate(&ptwr_ctxt.ctxt, &ptwr_emulate_ops) )
diff -r ba5e80864f9c -r 0ba81aa56455 xen/arch/x86/mm/shadow/common.c
--- a/xen/arch/x86/mm/shadow/common.c   Mon Jan 15 14:32:25 2007 +0000
+++ b/xen/arch/x86/mm/shadow/common.c   Mon Jan 15 15:43:20 2007 +0000
@@ -110,7 +110,7 @@ static int hvm_translate_linear_addr(
     unsigned long limit, addr = offset;
     uint32_t last_byte;
 
-    if ( sh_ctxt->ctxt.address_bytes != 8 )
+    if ( sh_ctxt->ctxt.addr_size != 64 )
     {
         /*
          * COMPATIBILITY MODE: Apply segment checks and add base.
@@ -399,7 +399,7 @@ struct x86_emulate_ops *shadow_init_emul
 struct x86_emulate_ops *shadow_init_emulation(
     struct sh_emulate_ctxt *sh_ctxt, struct cpu_user_regs *regs)
 {
-    struct segment_register *creg;
+    struct segment_register *creg, *sreg;
     struct vcpu *v = current;
     unsigned long addr;
 
@@ -407,7 +407,7 @@ struct x86_emulate_ops *shadow_init_emul
 
     if ( !is_hvm_vcpu(v) )
     {
-        sh_ctxt->ctxt.address_bytes = sizeof(long);
+        sh_ctxt->ctxt.addr_size = sh_ctxt->ctxt.sp_size = BITS_PER_LONG;
         return &pv_shadow_emulator_ops;
     }
 
@@ -417,11 +417,24 @@ struct x86_emulate_ops *shadow_init_emul
 
     /* Work out the emulation mode. */
     if ( hvm_long_mode_enabled(v) )
-        sh_ctxt->ctxt.address_bytes = creg->attr.fields.l ? 8 : 4;
+    {
+        sh_ctxt->ctxt.addr_size = creg->attr.fields.l ? 64 : 32;
+        if ( (sh_ctxt->ctxt.sp_size = sh_ctxt->ctxt.addr_size) != 64 )
+        {
+            sreg = hvm_get_seg_reg(x86_seg_ss, sh_ctxt);
+            sh_ctxt->ctxt.sp_size = sreg->attr.fields.db ? 32 : 16;
+        }
+    }
     else if ( regs->eflags & X86_EFLAGS_VM )
-        sh_ctxt->ctxt.address_bytes = 2;
+    {
+        sh_ctxt->ctxt.addr_size = sh_ctxt->ctxt.sp_size = 16;
+    }
     else
-        sh_ctxt->ctxt.address_bytes = creg->attr.fields.db ? 4 : 2;
+    {
+        sreg = hvm_get_seg_reg(x86_seg_ss, sh_ctxt);
+        sh_ctxt->ctxt.addr_size = creg->attr.fields.db ? 32 : 16;
+        sh_ctxt->ctxt.sp_size   = sreg->attr.fields.db ? 32 : 16;
+    }
 
     /* Attempt to prefetch whole instruction. */
     sh_ctxt->insn_buf_bytes =
diff -r ba5e80864f9c -r 0ba81aa56455 xen/arch/x86/x86_emulate.c
--- a/xen/arch/x86/x86_emulate.c        Mon Jan 15 14:32:25 2007 +0000
+++ b/xen/arch/x86/x86_emulate.c        Mon Jan 15 15:43:20 2007 +0000
@@ -443,10 +443,11 @@ do{ __asm__ __volatile__ (              
 })
 #define insn_fetch_type(_type) ((_type)insn_fetch_bytes(sizeof(_type)))
 
-#define _truncate_ea(ea, byte_width)                    \
-({  unsigned long __ea = (ea);                          \
-    (((byte_width) == sizeof(unsigned long)) ? __ea :   \
-     (__ea & ((1UL << ((byte_width) << 3)) - 1)));      \
+#define _truncate_ea(ea, byte_width)            \
+({  unsigned long __ea = (ea);                  \
+    unsigned int _width = (byte_width);         \
+    ((_width == sizeof(unsigned long)) ? __ea : \
+     (__ea & ((1UL << (_width << 3)) - 1)));    \
 })
 #define truncate_ea(ea) _truncate_ea((ea), ad_bytes)
 
@@ -473,16 +474,27 @@ static int even_parity(uint8_t v)
 #define _register_address_increment(reg, inc, byte_width)               \
 do {                                                                    \
     int _inc = (inc); /* signed type ensures sign extension to long */  \
-    if ( (byte_width) == sizeof(unsigned long) )                        \
+    unsigned int _width = (byte_width);                                 \
+    if ( _width == sizeof(unsigned long) )                              \
         (reg) += _inc;                                                  \
     else if ( mode_64bit() )                                            \
-        (reg) = ((reg) + _inc) & ((1UL << ((byte_width) << 3)) - 1);    \
+        (reg) = ((reg) + _inc) & ((1UL << (_width << 3)) - 1);          \
     else                                                                \
-        (reg) = ((reg) & ~((1UL << ((byte_width) << 3)) - 1)) |         \
-                (((reg) + _inc) & ((1UL << ((byte_width) << 3)) - 1));  \
+        (reg) = ((reg) & ~((1UL << (_width << 3)) - 1)) |               \
+                (((reg) + _inc) & ((1UL << (_width << 3)) - 1));        \
 } while (0)
 #define register_address_increment(reg, inc) \
     _register_address_increment((reg), (inc), ad_bytes)
+
+#define sp_pre_dec(dec) ({                                              \
+    _register_address_increment(_regs.esp, -(dec), ctxt->sp_size/8);    \
+    _truncate_ea(_regs.esp, ctxt->sp_size/8);                           \
+})
+#define sp_post_inc(inc) ({                                             \
+    unsigned long __esp = _truncate_ea(_regs.esp, ctxt->sp_size/8);     \
+    _register_address_increment(_regs.esp, (inc), ctxt->sp_size/8);     \
+    __esp;                                                              \
+})
 
 #define jmp_rel(rel)                                                    \
 do {                                                                    \
@@ -679,7 +691,7 @@ x86_emulate(
     ea.mem.seg = x86_seg_ds;
     ea.mem.off = 0;
 
-    op_bytes = def_op_bytes = ad_bytes = def_ad_bytes = ctxt->address_bytes;
+    op_bytes = def_op_bytes = ad_bytes = def_ad_bytes = ctxt->addr_size/8;
     if ( op_bytes == 8 )
     {
         op_bytes = def_op_bytes = 4;
@@ -1194,10 +1206,9 @@ x86_emulate(
         /* 64-bit mode: POP defaults to a 64-bit operand. */
         if ( mode_64bit() && (dst.bytes == 4) )
             dst.bytes = 8;
-        if ( (rc = ops->read(x86_seg_ss, truncate_ea(_regs.esp),
+        if ( (rc = ops->read(x86_seg_ss, sp_post_inc(dst.bytes),
                              &dst.val, dst.bytes, ctxt)) != 0 )
             goto done;
-        register_address_increment(_regs.esp, dst.bytes);
         break;
 
     case 0xb0 ... 0xb7: /* mov imm8,r8 */
@@ -1488,8 +1499,7 @@ x86_emulate(
                                      &dst.val, 8, ctxt)) != 0 )
                     goto done;
             }
-            register_address_increment(_regs.esp, -dst.bytes);
-            if ( (rc = ops->write(x86_seg_ss, truncate_ea(_regs.esp),
+            if ( (rc = ops->write(x86_seg_ss, sp_pre_dec(dst.bytes),
                                   dst.val, dst.bytes, ctxt)) != 0 )
                 goto done;
             dst.type = OP_NONE;
@@ -1644,10 +1654,9 @@ x86_emulate(
         dst.bytes = op_bytes;
         if ( mode_64bit() && (dst.bytes == 4) )
             dst.bytes = 8;
-        if ( (rc = ops->read(x86_seg_ss, truncate_ea(_regs.esp),
+        if ( (rc = ops->read(x86_seg_ss, sp_post_inc(dst.bytes),
                              &dst.val, dst.bytes, ctxt)) != 0 )
             goto done;
-        register_address_increment(_regs.esp, dst.bytes);
         break;
 
     case 0x60: /* pusha */ {
@@ -1657,11 +1666,9 @@ x86_emulate(
             _regs.esp, _regs.ebp, _regs.esi, _regs.edi };
         generate_exception_if(mode_64bit(), EXC_UD);
         for ( i = 0; i < 8; i++ )
-            if ( (rc = ops->write(x86_seg_ss,
-                                  truncate_ea(_regs.esp-(i+1)*op_bytes),
+            if ( (rc = ops->write(x86_seg_ss, sp_pre_dec(op_bytes),
                                   regs[i], op_bytes, ctxt)) != 0 )
             goto done;
-        register_address_increment(_regs.esp, -8*op_bytes);
         break;
     }
 
@@ -1674,11 +1681,9 @@ x86_emulate(
             (unsigned long *)&_regs.ecx, (unsigned long *)&_regs.eax };
         generate_exception_if(mode_64bit(), EXC_UD);
         for ( i = 0; i < 8; i++ )
-            if ( (rc = ops->read(x86_seg_ss,
-                                 truncate_ea(_regs.esp+i*op_bytes),
+            if ( (rc = ops->read(x86_seg_ss, sp_post_inc(op_bytes),
                                  regs[i], op_bytes, ctxt)) != 0 )
             goto done;
-        register_address_increment(_regs.esp, 8*op_bytes);
         break;
     }
 
@@ -1697,9 +1702,8 @@ x86_emulate(
         if ( mode_64bit() && (dst.bytes == 4) )
             dst.bytes = 8;
         dst.val = src.val;
-        register_address_increment(_regs.esp, -dst.bytes);
         dst.mem.seg = x86_seg_ss;
-        dst.mem.off = truncate_ea(_regs.esp);
+        dst.mem.off = sp_pre_dec(dst.bytes);
         break;
 
     case 0x70 ... 0x7f: /* jcc (short) */ {
@@ -1813,11 +1817,10 @@ x86_emulate(
     case 0xc3: /* ret (near) */ {
         int offset = (b == 0xc2) ? insn_fetch_type(uint16_t) : 0;
         op_bytes = mode_64bit() ? 8 : op_bytes;
-        if ( (rc = ops->read(x86_seg_ss, truncate_ea(_regs.esp),
+        if ( (rc = ops->read(x86_seg_ss, sp_post_inc(op_bytes + offset),
                              &dst.val, op_bytes, ctxt)) != 0 )
             goto done;
         _regs.eip = dst.val;
-        register_address_increment(_regs.esp, op_bytes + offset);
         break;
     }
 
diff -r ba5e80864f9c -r 0ba81aa56455 xen/include/asm-x86/x86_emulate.h
--- a/xen/include/asm-x86/x86_emulate.h Mon Jan 15 14:32:25 2007 +0000
+++ b/xen/include/asm-x86/x86_emulate.h Mon Jan 15 15:43:20 2007 +0000
@@ -150,8 +150,11 @@ struct x86_emulate_ctxt
     /* Register state before/after emulation. */
     struct cpu_user_regs *regs;
 
-    /* Default address size in current execution mode (2, 4, or 8). */
-    int                   address_bytes;
+    /* Default address size in current execution mode (16, 32, or 64). */
+    unsigned int addr_size;
+
+    /* Stack pointer width in bits (16, 32 or 64). */
+    unsigned int sp_size;
 };
 
 /*

_______________________________________________
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] [XEN] Allow stack-address-size to be specified differently from, Xen patchbot-unstable <=