qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] another 64/32 mmap() bug
@ 2008-09-27 22:28 Vince Weaver
  2008-09-28 19:11 ` Vince Weaver
  0 siblings, 1 reply; 2+ messages in thread
From: Vince Weaver @ 2008-09-27 22:28 UTC (permalink / raw)
  To: qemu-devel


In trying to get the remaining spec2k/spec2k6 benchmarks to run, I've 
found another 64-bit/32-bit mmap() linux-user problem.

This could be a kernel problem.

The mmap() call in conjunction with MAP_32BIT will make sure the address 
of an allocation is < 32-bit.  The problem is it doesn't check that the
_entire address range_ is < 32-bit.

So it will return an address of say 0xffff0000 for an allocation of
128kB, and the end of that allocation will not be addressable, causing 
a segfault.

Vince

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [Qemu-devel] another 64/32 mmap() bug
  2008-09-27 22:28 [Qemu-devel] another 64/32 mmap() bug Vince Weaver
@ 2008-09-28 19:11 ` Vince Weaver
  0 siblings, 0 replies; 2+ messages in thread
From: Vince Weaver @ 2008-09-28 19:11 UTC (permalink / raw)
  To: qemu-devel

Hello

So I've tracked down this problem.  The linux-user mmap() code does not 
check to see if an allocation crosses the 2^32 barrier, which is a problem 
for emulating 32-bit code on a 64-bit machine.

The attached patch is a hack that fixes this problem, and also the related 
mremap() problem.  These definitely aren't meant to be committed. 
Hoepfully someone who understands the linux-user mmap() code better than I 
do can take a look at things.

With the patch though, I can finally run correctly all 48 of Spec2k on 
sparc32-linux-user on x86_64, and I can run all but 5 of Spec2k6.

Patch below, hoepfully pine doesn't mess it up this time.

Vince

Index: linux-user/mmap.c
===================================================================
--- linux-user/mmap.c	(revision 5321)
+++ linux-user/mmap.c	(working copy)
@@ -353,16 +353,27 @@
          host_offset = offset & qemu_host_page_mask;
          host_len = len + offset - host_offset;
          host_len = HOST_PAGE_ALIGN(host_len);
+try_again:
          mmap_start = mmap_find_vma(real_start, host_len);
          if (mmap_start == (abi_ulong)-1) {
              errno = ENOMEM;
              goto fail;
          }
+
+#if TARGET_ABI_BITS == 32 
+               /* vmw */
+        if ( (long)g2h(mmap_start)+host_len > 0xffff0000) {
+	   printf("WARNING! Host len too high: 0x%x + 0x%x\n",mmap_start,host_len);
+	   goto try_again;
+        }
+#endif 
+
          /* Note: we prefer to control the mapping address. It is
             especially important if qemu_host_page_size >
-           qemu_real_host_page_size */
+           qemu_real_host_page_size */
          p = mmap(g2h(mmap_start),
                   host_len, prot, flags | MAP_FIXED, fd, host_offset);
+
          if (p == MAP_FAILED)
              goto fail;
          /* update start so that it points to the file position at 'offset' */
@@ -538,6 +549,25 @@
      mmap_lock();
      /* XXX: use 5 args syscall */
      host_addr = (long)mremap(g2h(old_addr), old_size, new_size, flags);
+#if TARGET_ABI_BITS == 32
+    if (host_addr > 0xffffffff) {
+       void *temp_addr;
+ 
+       temp_addr = mmap(NULL,new_size,
+			PROT_READ|PROT_WRITE,MAP_ANONYMOUS|MAP_PRIVATE|MAP_32BIT, 0, 0);
+       memcpy(temp_addr,(void *)host_addr,old_size);
+       munmap((void *)host_addr,new_size); 
+       host_addr=(long)temp_addr;
+
+ 
+       if (host_addr > 0xffffffff) {
+ 
+          printf("ERROR!  mremap() returned 64-bit value on 32-bit target!\n\n");
+          exit(-1); 
+       }
+    }
+#endif 
+
      if (host_addr == -1) {
          new_addr = -1;
      } else {

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2008-09-28 19:11 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-09-27 22:28 [Qemu-devel] another 64/32 mmap() bug Vince Weaver
2008-09-28 19:11 ` Vince Weaver

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).