On [Tue, 19.06.2007 16:03], Alexander Graf wrote:
> Paul Brook wrote:
> > On Thursday 24 May 2007, Alexander Graf wrote:
> >   
> >> Hi,
> >>
> >> while playing around with TLS on i386 i came across this problem which
> >> occurs even when no TLS is used at all. If two threads just malloc()
> >> memory all the time I get a segmentation fault after a short time. Might
> >> this be a serious bug?
> >>     
> >
> > qemu is not even vaguely threadsafe.
> >
> > Paul
> >
> >
> >   
> Hi,
> 
> I somehow narrowed the problem down to x86_64. As soon as I use
> qemu-i386 on i386 or ppc the memory mapping tables are OK. When using
> x86_64 as host they are broken. Could this be a generic 64-bit host
> problem? I doubt that this actually has to do too much with the
> threading itself, because it works fine on other platforms.

On x86_64 mmap() sometimes return address above 4G. It is problem if target 
system is 32-bit. I use attached patch to solve it.

-- 
Regards,  Kirill A. Shutemov
 + Belarus, Minsk
 + Velesys LLC, http://www.velesys.com/
 + ALT Linux Team, http://www.altlinux.com/
diff -uNr qemu-0.8.2.orig/linux-user/mmap.c qemu-0.8.2/linux-user/mmap.c
--- qemu-0.8.2.orig/linux-user/mmap.c   2007-01-16 16:05:33 +0200
+++ qemu-0.8.2/linux-user/mmap.c        2007-01-16 16:27:28 +0200
@@ -27,6 +27,10 @@
 
 #include "qemu.h"
 
+#if !defined(MAP_32BIT)
+#define MAP_32BIT 0
+#endif
+
 //#define DEBUG_MMAP
 
 /* NOTE: all the constants are the HOST ones, but addresses are target. */
@@ -116,7 +120,7 @@
     if (prot1 == 0) {
         /* no page was there, so we allocate one */
         ret = (long)mmap(host_start, qemu_host_page_size, prot, 
-                         flags | MAP_ANONYMOUS, -1, 0);
+                         flags | MAP_ANONYMOUS | MAP_32BIT, -1, 0);
         if (ret == -1)
             return ret;
         prot1 = prot;
@@ -217,7 +221,8 @@
 abort();
             host_len = HOST_PAGE_ALIGN(len) + qemu_host_page_size - 
TARGET_PAGE_SIZE;
             real_start = (long)mmap(g2h(real_start), host_len, PROT_NONE, 
-                                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+                                    MAP_PRIVATE | MAP_ANONYMOUS | MAP_32BIT
+                                                                       , -1, 
0);
             if (real_start == -1)
                 return real_start;
             real_end = real_start + host_len;
@@ -234,7 +239,7 @@
             host_offset = offset & qemu_host_page_mask;
             host_len = len + offset - host_offset;
             host_start = (long)mmap(real_start ? g2h(real_start) : NULL,
-                                    host_len, prot, flags, fd, host_offset);
+                                    host_len, prot, flags | MAP_32BIT, fd, 
host_offset);
             if (host_start == -1)
                 return host_start;
             /* update start so that it points to the file position at 'offset' 
*/
@@ -312,7 +317,7 @@
        else
          offset1 = offset + real_start - start;
         ret = (long)mmap(g2h(real_start), real_end - real_start, 
-                         prot, flags, fd, offset1);
+                         prot, flags | MAP_32BIT, fd, offset1);
         if (ret == -1)
             return ret;
     }
@@ -388,7 +393,7 @@
     int prot;
 
     /* XXX: use 5 args syscall */
-    new_addr = (long)mremap(g2h(old_addr), old_size, new_size, flags);
+    new_addr = (long)mremap(g2h(old_addr), old_size, new_size, flags | 
MAP_32BIT);
     if (new_addr == -1)
         return new_addr;
     new_addr = h2g(new_addr);

Attachment: signature.asc
Description: Digital signature

Reply via email to