* [Qemu-devel] qemu-arm fails on test-mmap - take #2 @ 2009-08-09 23:45 Jan-Simon Möller 2009-08-10 2:09 ` Jan-Simon Möller [not found] ` <cc557aab0908092333n1e2b3aa3l2d703352297e83a6@mail.gmail.com> 0 siblings, 2 replies; 4+ messages in thread From: Jan-Simon Möller @ 2009-08-09 23:45 UTC (permalink / raw) To: qemu-devel; +Cc: Laurent Desnogues Hi ! This is a follow-up to my tests about test-mmap failing inside an arm chroot when using qemu-arm in user-mode. Here are 2 snippets running "qemu-arm ./test-mmap" outside and inside the ARM chroot env. I turned DEBUG_MMAP on in linux-user/mmap.c . legolas:/var/tmp/build-root # ./usr/bin/qemu-arm test-mmap ------snip------- mmap: start=0x00000000 len=0x00001000 prot=r-- flags=MAP_ANON MAP_PRIVATE fd=-1 offset=00000000 ret=0x40b77000 start end size prot 00008000-00081000 00079000 r-x 00088000-0008a000 00002000 rw- 0008a000-0008c000 00002000 rwx 0008c000-000af000 00023000 rw- 40000000-40080000 00080000 rw- 40080000-40081000 00001000 --- 40081000-40082000 00001000 rw- 40339000-40347000 0000e000 --- 407d6000-407d7000 00001000 --- 4096b000-40974000 00009000 --- 40b76000-40b78000 00002000 r-- 40e8a000-40e8c000 00002000 --- 41dc7000-455ca000 03803000 --- 60000000-60166000 00166000 --- 60266000-6231d000 020b7000 --- ------snip------- Note the last 2 lines !! Now same procedure inside the chroot ... legolas:/> chroot /var/tmp/build-root legolas:/> ./test-mmap ------snip------- mmap: start=0x00000000 len=0x00001000 prot=r-- flags=MAP_ANON MAP_PRIVATE fd=-1 offset=00000000 ret=0x40b74000 start end size prot 00008000-00081000 00079000 r-x 00088000-0008a000 00002000 rw- 0008a000-0008c000 00002000 rwx 0008c000-000af000 00023000 rw- 40000000-40080000 00080000 rw- 40080000-40081000 00001000 --- 40081000-40082000 00001000 rw- 40191000-40192000 00001000 --- 40b73000-40b75000 00002000 r-- 40c6c000-40c75000 00009000 --- 41105000-41106000 00001000 --- 41283000-44a95000 03812000 --- ------snip------- The lines with 60000000-60166000 are gone ... Thus as soon as those pages will get allocated it will segfault. This is reproducible on different machines: 1) openSUSE 11.1 64bit on Core 2 Duo with 2GB Ram, qemu git head The ARM chroot uses gcc4.4 and glibc 2.10.1 . 2) openSUSE 11.0 32bit Athlon XP 2GB RAM, same qemu, same chroot Now my question is: how is the data of the already blocked pages processed/aquired ? It seems to me that the pages get "lost" somewhere. Best, Jan-Simon ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] qemu-arm fails on test-mmap - take #2 2009-08-09 23:45 [Qemu-devel] qemu-arm fails on test-mmap - take #2 Jan-Simon Möller @ 2009-08-10 2:09 ` Jan-Simon Möller 2009-08-10 8:33 ` [Qemu-devel] qemu-arm fails on test-mmap Martin Mohring [not found] ` <cc557aab0908092333n1e2b3aa3l2d703352297e83a6@mail.gmail.com> 1 sibling, 1 reply; 4+ messages in thread From: Jan-Simon Möller @ 2009-08-10 2:09 UTC (permalink / raw) To: qemu-devel A quick hack around is this: diff --git a/linux-user/mmap.c b/linux-user/mmap.c index e05caa0..a04d6b1 100644 --- a/linux-user/mmap.c +++ b/linux-user/mmap.c @@ -316,8 +316,14 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size) if (addr == addr_start) return (abi_ulong)-1; } - if (start == 0) - mmap_next_start = addr + size; + if (start == 0) { + abi_ulong mynext = addr + size ; + if ( (mynext > 0x5f000000) && (mynext < 0x65000000) ) { + mmap_next_start = 0x65000000 ; + } else { + mmap_next_start = addr + size; + } + } return addr; } But this is for sure not the real solution. Best, Jan-Simon ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] qemu-arm fails on test-mmap 2009-08-10 2:09 ` Jan-Simon Möller @ 2009-08-10 8:33 ` Martin Mohring 0 siblings, 0 replies; 4+ messages in thread From: Martin Mohring @ 2009-08-10 8:33 UTC (permalink / raw) To: qemu-devel; +Cc: Riku Voipio, Aurelien Jarno, Jan-Simon Möller Hi, yesterday, we tracked down the problem to a kernel bug in this area: http://bugzilla.kernel.org/attachment.cgi?id=17219 What do I want to say with this: the user mode memory allocator does not work because it runs into a kernel bug. Kudos to Jan-Simon. Has anyone an idea how to handle such a case.... Patching the kernel is not the best idea. We will check which kernels are affected. Cheers, Martin Jan-Simon Möller wrote: > A quick hack around is this: > > diff --git a/linux-user/mmap.c b/linux-user/mmap.c > index e05caa0..a04d6b1 100644 > --- a/linux-user/mmap.c > +++ b/linux-user/mmap.c > @@ -316,8 +316,14 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size) > if (addr == addr_start) > return (abi_ulong)-1; > } > - if (start == 0) > - mmap_next_start = addr + size; > + if (start == 0) { > + abi_ulong mynext = addr + size ; > + if ( (mynext > 0x5f000000) && (mynext < 0x65000000) ) { > + mmap_next_start = 0x65000000 ; > + } else { > + mmap_next_start = addr + size; > + } > + } > return addr; > } > > > But this is for sure not the real solution. > > Best, > Jan-Simon > > > ^ permalink raw reply [flat|nested] 4+ messages in thread
[parent not found: <cc557aab0908092333n1e2b3aa3l2d703352297e83a6@mail.gmail.com>]
* Re: [Qemu-devel] qemu-arm fails on test-mmap - take #2 [not found] ` <cc557aab0908092333n1e2b3aa3l2d703352297e83a6@mail.gmail.com> @ 2009-08-10 13:52 ` Jan-Simon Möller 0 siblings, 0 replies; 4+ messages in thread From: Jan-Simon Möller @ 2009-08-10 13:52 UTC (permalink / raw) To: Kirill A. Shutemov; +Cc: riku.voipio, qemu-devel [-- Attachment #1: Type: text/plain, Size: 988 bytes --] Am Montag 10 August 2009 08:33:38 schrieb Kirill A. Shutemov: > > Now my question is: how is the data of the already blocked pages > > processed/aquired ? It seems to me that the pages get "lost" somewhere. > > Current mmap() implementation requires /proc to obtain all mappings. > > I have alternative implementation of mmap_find_vma() which doesn't > require /proc: > > http://www.archivum.info/qemu-devel@nongnu.org/2008-10/01118/%5BQemu-devel% >5D_%5BPATCH,_v2%5D_Rewrite_mmap_find_vma%28%29_to_work_fine_on_64-bit_hosts_ >with_32-bit_targets > > It is probably out of date. This does the trick ! I've attached a version against trunk. @Riku: can we apply this to git ? Acked-by: Jan-Simon Möller <dl9pf@gmx.de> Original post: http://www.archivum.info/qemu-devel%40nongnu.org/2008-10/01118/[Qemu-devel]_[PATCH,_v2]_Rewrite_mmap_find_vma()_to_work_fine_on_64-bit_hosts_with_32-bit_targets Attachement: Patch rebased to trunk. Best, Jan-Simon [-- Attachment #2: qemu-0.11-git-user-linux-mmap_find_vma.patch --] [-- Type: text/x-diff, Size: 3284 bytes --] diff --git a/linux-user/mmap.c b/linux-user/mmap.c index 6f300a0..8cec230 100644 --- a/linux-user/mmap.c +++ b/linux-user/mmap.c @@ -275,52 +275,59 @@ abi_ulong mmap_next_start = 0x40000000; unsigned long last_brk; -/* find a free memory area of size 'size'. The search starts at - 'start'. If 'start' == 0, then a default start address is used. - Return -1 if error. -*/ -/* page_init() marks pages used by the host as reserved to be sure not - to use them. */ -abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size) +/* + * Find and reserve a free memory area of size 'size'. The search + * starts at 'start'. + * It must be called with mmap_lock() held. + * Return -1 if error. + */ +abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size) { - abi_ulong addr, addr1, addr_start; - int prot; - unsigned long new_brk; - - new_brk = (unsigned long)sbrk(0); - if (last_brk && last_brk < new_brk && last_brk == (target_ulong)last_brk) { - /* This is a hack to catch the host allocating memory with brk(). - If it uses mmap then we loose. - FIXME: We really want to avoid the host allocating memory in - the first place, and maybe leave some slack to avoid switching - to mmap. */ - page_set_flags(last_brk & TARGET_PAGE_MASK, - TARGET_PAGE_ALIGN(new_brk), - PAGE_RESERVED); - } - last_brk = new_brk; + void *ptr; + abi_ulong addr; size = HOST_PAGE_ALIGN(size); - start = start & qemu_host_page_mask; + start &= qemu_host_page_mask; + + /* If 'start' == 0, then a default start address is used. */ + if (start == 0) + start = mmap_next_start; + addr = start; - if (addr == 0) - addr = mmap_next_start; - addr_start = addr; + for(;;) { - prot = 0; - for(addr1 = addr; addr1 < (addr + size); addr1 += TARGET_PAGE_SIZE) { - prot |= page_get_flags(addr1); - } - if (prot == 0) + /* + * Reserve needed memory area to avoid a race. + * It should be discarded using: + * - mmap() with MAP_FIXED flag + * - mremap() with MREMAP_FIXED flag + * - shmat() with SHM_REMAP flag + */ + ptr = mmap((void *)(unsigned long)addr, size, PROT_NONE, + MAP_ANONYMOUS|MAP_PRIVATE|MAP_NORESERVE, -1, 0); + + /* ENOMEM, if host address space has no memory */ + if (ptr == MAP_FAILED) + return (abi_ulong)-1; + + /* If address fits target address space we've found what we need */ + if ((unsigned long)ptr + size - 1 <= (abi_ulong)-1) break; + + /* Unmap and try again with new page */ + munmap(ptr, size); addr += qemu_host_page_size; - /* we found nothing */ - if (addr == addr_start) + + /* ENOMEM if we check whole of target address space */ + if (addr == start) return (abi_ulong)-1; } - if (start == 0) - mmap_next_start = addr + size; - return addr; + + /* Update default start address */ + if (start == mmap_next_start) + mmap_next_start = (unsigned long)ptr + size; + + return h2g(ptr); } /* NOTE: all the constants are the HOST ones */ ^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2009-08-10 13:53 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2009-08-09 23:45 [Qemu-devel] qemu-arm fails on test-mmap - take #2 Jan-Simon Möller 2009-08-10 2:09 ` Jan-Simon Möller 2009-08-10 8:33 ` [Qemu-devel] qemu-arm fails on test-mmap Martin Mohring [not found] ` <cc557aab0908092333n1e2b3aa3l2d703352297e83a6@mail.gmail.com> 2009-08-10 13:52 ` [Qemu-devel] qemu-arm fails on test-mmap - take #2 Jan-Simon Möller
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).