Hello, I'm working on a new target port and the linux-user emulation is fairly functional and passing quite extensive test-suites.
I've got a problem though, my target has 8K page sizes, so for example when running on a x86 host TARGET_PAGE_SIZE > host page size. I'm not very familiar with linux-user/mmap.c, but I though I'd let you know that with this patch things seem to be working fine for me. I am not sure if the patch is correct so if anyone with more experience sees an obvious flaw I'd appreciate to know. Thanks! Edgar E. Iglesias Axis Communications AB Index: linux-user/mmap.c =================================================================== RCS file: /sources/qemu/qemu/linux-user/mmap.c,v retrieving revision 1.14 diff -u -p -b -u -p -r1.14 mmap.c --- linux-user/mmap.c 17 Sep 2007 08:09:49 -0000 1.14 +++ linux-user/mmap.c 21 Sep 2007 13:24:42 -0000 @@ -209,26 +209,34 @@ long target_mmap(target_ulong start, tar last_start += HOST_PAGE_ALIGN(len); } #endif - if (0 && qemu_host_page_size != qemu_real_host_page_size) { + if (qemu_host_page_size != qemu_real_host_page_size) { /* NOTE: this code is only for debugging with '-p' option */ /* ??? Can also occur when TARGET_PAGE_SIZE > host page size. */ /* reserve a memory area */ /* ??? This needs fixing for remapping. */ -abort(); - host_len = HOST_PAGE_ALIGN(len) + qemu_host_page_size - TARGET_PAGE_SIZE; + + /* Make sure we have enough room for fixing up the buffer. */ + host_len = HOST_PAGE_ALIGN(len + TARGET_PAGE_SIZE); real_start = (long)mmap(g2h(real_start), host_len, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (real_start == -1) return real_start; real_end = real_start + host_len; - start = HOST_PAGE_ALIGN(real_start); - end = start + HOST_PAGE_ALIGN(len); + + /* Find start and end, aligned to the targets pagesize with-in the + mmaped area. */ + start = TARGET_PAGE_ALIGN(real_start); + end = start + TARGET_PAGE_ALIGN(len); + /* Chop off the leftovers, if any. */ if (start > real_start) munmap((void *)real_start, start - real_start); if (end < real_end) munmap((void *)end, real_end - end); /* use it as a fixed mapping */ flags |= MAP_FIXED; + /* These are now real. */ + real_start = start; + real_end = end; } else { /* if not fixed, no need to do anything */ host_offset = offset & qemu_host_page_mask;