From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Kk1g5-0006c1-Bl for qemu-devel@nongnu.org; Sun, 28 Sep 2008 15:11:33 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1Kk1g2-0006b8-HG for qemu-devel@nongnu.org; Sun, 28 Sep 2008 15:11:32 -0400 Received: from [199.232.76.173] (port=49483 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Kk1g2-0006ay-DX for qemu-devel@nongnu.org; Sun, 28 Sep 2008 15:11:30 -0400 Received: from csl.cornell.edu ([128.84.224.10]:2577 helo=vlsi.csl.cornell.edu) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1Kk1g0-0005tp-0l for qemu-devel@nongnu.org; Sun, 28 Sep 2008 15:11:30 -0400 Received: from stanley.csl.cornell.edu (stanley.csl.cornell.edu [128.84.224.15]) by vlsi.csl.cornell.edu (8.13.4/8.13.4) with ESMTP id m8SJBK0s051852 for ; Sun, 28 Sep 2008 15:11:25 -0400 (EDT) Date: Sun, 28 Sep 2008 15:11:20 -0400 (EDT) From: Vince Weaver Subject: Re: [Qemu-devel] another 64/32 mmap() bug In-Reply-To: <20080927182454.A29159@stanley.csl.cornell.edu> Message-ID: <20080928150753.Q34188@stanley.csl.cornell.edu> References: <20080927182454.A29159@stanley.csl.cornell.edu> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org 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 {