* [Qemu-devel] [6510] Partialy fix mmap at EOF for large pagesize targets in user-mode.
@ 2009-02-03 23:06 Edgar E. Iglesias
2009-02-04 20:17 ` Lionel Landwerlin
0 siblings, 1 reply; 2+ messages in thread
From: Edgar E. Iglesias @ 2009-02-03 23:06 UTC (permalink / raw)
To: qemu-devel
Revision: 6510
http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=6510
Author: edgar_igl
Date: 2009-02-03 23:06:34 +0000 (Tue, 03 Feb 2009)
Log Message:
-----------
Partialy fix mmap at EOF for large pagesize targets in user-mode.
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
Modified Paths:
--------------
trunk/linux-user/mmap.c
Modified: trunk/linux-user/mmap.c
===================================================================
--- trunk/linux-user/mmap.c 2009-02-03 22:45:00 UTC (rev 6509)
+++ trunk/linux-user/mmap.c 2009-02-03 23:06:34 UTC (rev 6510)
@@ -24,6 +24,8 @@
#include <string.h>
#include <unistd.h>
#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
#include <sys/mman.h>
#include <linux/mman.h>
#include <linux/unistd.h>
@@ -366,6 +368,36 @@
goto the_end;
real_start = start & qemu_host_page_mask;
+ /* When mapping files into a memory area larger than the file, accesses
+ to pages beyond the file size will cause a SIGBUS.
+
+ For example, if mmaping a file of 100 bytes on a host with 4K pages
+ emulating a target with 8K pages, the target expects to be able to
+ access the first 8K. But the host will trap us on any access beyond
+ 4K.
+
+ When emulating a target with a larger page-size than the hosts, we
+ may need to truncate file maps at EOF and add extra anonymous pages
+ up to the targets page boundary. */
+
+ if ((qemu_real_host_page_size < TARGET_PAGE_SIZE)
+ && !(flags & MAP_ANONYMOUS)) {
+ struct stat sb;
+
+ if (fstat (fd, &sb) == -1)
+ goto fail;
+
+ /* Are we trying to create a map beyond EOF?. */
+ if (offset + len > sb.st_size) {
+ /* If so, truncate the file map at eof aligned with
+ the hosts real pagesize. Additional anonymous maps
+ will be created beyond EOF. */
+ len = (sb.st_size - offset);
+ len += qemu_real_host_page_size - 1;
+ len &= ~(qemu_real_host_page_size - 1);
+ }
+ }
+
if (!(flags & MAP_FIXED)) {
abi_ulong mmap_start;
void *p;
@@ -381,13 +413,16 @@
especially important if qemu_host_page_size >
qemu_real_host_page_size */
p = mmap(g2h(mmap_start),
- host_len, prot, flags | MAP_FIXED, fd, host_offset);
+ host_len, prot, flags | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
if (p == MAP_FAILED)
goto fail;
/* update start so that it points to the file position at 'offset' */
host_start = (unsigned long)p;
- if (!(flags & MAP_ANONYMOUS))
+ if (!(flags & MAP_ANONYMOUS)) {
+ p = mmap(g2h(mmap_start), len, prot,
+ flags | MAP_FIXED, fd, host_offset);
host_start += offset - host_offset;
+ }
start = h2g(host_start);
} else {
int flg;
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [Qemu-devel] [6510] Partialy fix mmap at EOF for large pagesize targets in user-mode.
2009-02-03 23:06 [Qemu-devel] [6510] Partialy fix mmap at EOF for large pagesize targets in user-mode Edgar E. Iglesias
@ 2009-02-04 20:17 ` Lionel Landwerlin
0 siblings, 0 replies; 2+ messages in thread
From: Lionel Landwerlin @ 2009-02-04 20:17 UTC (permalink / raw)
To: qemu-devel
Le mardi 03 février 2009 à 23:06 +0000, Edgar E. Iglesias a écrit :
> Revision: 6510
> http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=6510
> Author: edgar_igl
> Date: 2009-02-03 23:06:34 +0000 (Tue, 03 Feb 2009)
>
> Log Message:
> -----------
> Partialy fix mmap at EOF for large pagesize targets in user-mode.
>
> Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
>
> Modified Paths:
> --------------
> trunk/linux-user/mmap.c
>
> Modified: trunk/linux-user/mmap.c
> ===================================================================
> --- trunk/linux-user/mmap.c 2009-02-03 22:45:00 UTC (rev 6509)
> +++ trunk/linux-user/mmap.c 2009-02-03 23:06:34 UTC (rev 6510)
> @@ -24,6 +24,8 @@
> #include <string.h>
> #include <unistd.h>
> #include <errno.h>
> +#include <sys/types.h>
> +#include <sys/stat.h>
> #include <sys/mman.h>
> #include <linux/mman.h>
> #include <linux/unistd.h>
> @@ -366,6 +368,36 @@
> goto the_end;
> real_start = start & qemu_host_page_mask;
>
> + /* When mapping files into a memory area larger than the file, accesses
> + to pages beyond the file size will cause a SIGBUS.
> +
> + For example, if mmaping a file of 100 bytes on a host with 4K pages
> + emulating a target with 8K pages, the target expects to be able to
> + access the first 8K. But the host will trap us on any access beyond
> + 4K.
> +
> + When emulating a target with a larger page-size than the hosts, we
> + may need to truncate file maps at EOF and add extra anonymous pages
> + up to the targets page boundary. */
> +
> + if ((qemu_real_host_page_size < TARGET_PAGE_SIZE)
> + && !(flags & MAP_ANONYMOUS)) {
> + struct stat sb;
> +
> + if (fstat (fd, &sb) == -1)
> + goto fail;
> +
> + /* Are we trying to create a map beyond EOF?. */
> + if (offset + len > sb.st_size) {
> + /* If so, truncate the file map at eof aligned with
> + the hosts real pagesize. Additional anonymous maps
> + will be created beyond EOF. */
> + len = (sb.st_size - offset);
> + len += qemu_real_host_page_size - 1;
> + len &= ~(qemu_real_host_page_size - 1);
> + }
> + }
> +
> if (!(flags & MAP_FIXED)) {
> abi_ulong mmap_start;
> void *p;
> @@ -381,13 +413,16 @@
> especially important if qemu_host_page_size >
> qemu_real_host_page_size */
> p = mmap(g2h(mmap_start),
> - host_len, prot, flags | MAP_FIXED, fd, host_offset);
> + host_len, prot, flags | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
> if (p == MAP_FAILED)
> goto fail;
> /* update start so that it points to the file position at 'offset' */
> host_start = (unsigned long)p;
> - if (!(flags & MAP_ANONYMOUS))
> + if (!(flags & MAP_ANONYMOUS)) {
> + p = mmap(g2h(mmap_start), len, prot,
> + flags | MAP_FIXED, fd, host_offset);
> host_start += offset - host_offset;
> + }
> start = h2g(host_start);
> } else {
> int flg;
>
We also need to check when mmap_start pointer is inside the code
generation buffer.
--
Lione Landwerlin
O p e n W i d e 14, rue Gaillon 75002 Paris
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2009-02-04 20:17 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-02-03 23:06 [Qemu-devel] [6510] Partialy fix mmap at EOF for large pagesize targets in user-mode Edgar E. Iglesias
2009-02-04 20:17 ` Lionel Landwerlin
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).