qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH for-2.4] tcg/i386: ignore high bits for user mode 32


From: Aurelien Jarno
Subject: [Qemu-devel] [PATCH for-2.4] tcg/i386: ignore high bits for user mode 32-bit qemu_ld/st
Date: Wed, 15 Jul 2015 15:55:36 +0200

For a 64-bit host not implementing the trunc_shr_i32 op, the high bits
of a register should be ignored for 32-bit ops. This is currently not
the case of qemu_ld/st ops in user mode.

Fix that by either using the ADDR32 prefix (in case GUEST_BASE == 0 or
a segment register is in use), or by doing an explicit zero-extension.
The zero-extension can be done in place as we know the registers holds
a 32-bit value.

Reported-by: Leon Alrae <address@hidden>
Cc: Leon Alrae <address@hidden>
Cc: Paolo Bonzini <address@hidden>
Cc: Richard Henderson <address@hidden>
Signed-off-by: Aurelien Jarno <address@hidden>
---
 tcg/i386/tcg-target.c | 44 ++++++++++++++++++++++++++++++++------------
 1 file changed, 32 insertions(+), 12 deletions(-)

diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index f952645..f77e6c1 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -1570,12 +1570,21 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg 
*args, bool is64)
         int32_t offset = GUEST_BASE;
         TCGReg base = addrlo;
         int seg = 0;
+        int addr32 = 0;
+
+        /* The x86 TCG backend doesn't implement the trunc_shr_i32 op.  This
+           means the high bits of a register should be ignored for 32-bit ops.
+           For that we either use the ADDR32 prefix (in case GUEST_BASE == 0
+           or a segment register is in use), or by doing an explicit
+           zero-extension.  */
+        if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
+            if (GUEST_BASE == 0 || guest_base_flags) {
+                addr32 = P_ADDR32;
+            } else {
+                tcg_out_ext32u(s, base, base);
+            }
+        }
 
-        /* ??? We assume all operations have left us with register contents
-           that are zero extended.  So far this appears to be true.  If we
-           want to enforce this, we can either do an explicit zero-extension
-           here, or (if GUEST_BASE == 0, or a segment register is in use)
-           use the ADDR32 prefix.  For now, do nothing.  */
         if (GUEST_BASE && guest_base_flags) {
             seg = guest_base_flags;
             offset = 0;
@@ -1586,7 +1595,8 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg 
*args, bool is64)
             offset = 0;
         }
 
-        tcg_out_qemu_ld_direct(s, datalo, datahi, base, offset, seg, opc);
+        tcg_out_qemu_ld_direct(s, datalo, datahi, base, offset,
+                               addr32 | seg, opc);
     }
 #endif
 }
@@ -1701,12 +1711,21 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg 
*args, bool is64)
         int32_t offset = GUEST_BASE;
         TCGReg base = addrlo;
         int seg = 0;
+        int addr32 = 0;
+
+        /* The x86 TCG backend doesn't implement the trunc_shr_i32 op.  This
+           means the high bits of a register should be ignored for 32-bit ops.
+           For that we either use the ADDR32 prefix (in case GUEST_BASE == 0
+           or a segment register is in use), or by doing an explicit
+           zero-extension.  */
+        if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
+            if (GUEST_BASE == 0 || guest_base_flags) {
+                addr32 = P_ADDR32;
+            } else {
+                tcg_out_ext32u(s, base, base);
+            }
+        }
 
-        /* ??? We assume all operations have left us with register contents
-           that are zero extended.  So far this appears to be true.  If we
-           want to enforce this, we can either do an explicit zero-extension
-           here, or (if GUEST_BASE == 0, or a segment register is in use)
-           use the ADDR32 prefix.  For now, do nothing.  */
         if (GUEST_BASE && guest_base_flags) {
             seg = guest_base_flags;
             offset = 0;
@@ -1717,7 +1736,8 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg 
*args, bool is64)
             offset = 0;
         }
 
-        tcg_out_qemu_st_direct(s, datalo, datahi, base, offset, seg, opc);
+        tcg_out_qemu_st_direct(s, datalo, datahi, base, offset,
+                               addr32 | seg, opc);
     }
 #endif
 }
-- 
2.1.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]