[Lguest] [TUTORIAL 2/2] M-lmapfile: Make the memory mapped for guest RAM and DMA file-backed

Paul TBBle Hampson Paul.Hampson at Pobox.com
Thu Jan 31 21:15:48 EST 2008


This creates a file in $HOME/.lguest/ to directly back the RAM and DMA memory
mappings created by map_zeroed_pages.
---
 Documentation/lguest/lguest.c |   48 +++++++++++++++++++++++++++++++++++-----
 1 files changed, 42 insertions(+), 6 deletions(-)

diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c
index 73c5f1f..8f1be7c 100644
--- a/Documentation/lguest/lguest.c
+++ b/Documentation/lguest/lguest.c
@@ -126,18 +126,54 @@ static int open_or_die(const char *name, int flags)
 /* map_zeroed_pages() takes a (page-aligned) address and a number of pages. */
 static void *map_zeroed_pages(unsigned long addr, unsigned int num)
 {
-	/* We cache the /dev/zero file-descriptor so we only open it once. */
+	static unsigned long highwater = 0;
+
 	static int fd = -1;
 
+	unsigned long newhighwater = addr + getpagesize() * num;
+
 	if (fd == -1)
-		fd = open_or_die("/dev/zero", O_RDONLY);
+	{
+		char ourpage[ PATH_MAX ];
+		/* Get the directory name we care about, with some space for the filename and a NULL */
+		snprintf( ourpage, PATH_MAX - 21, "%s/.lguest/", getenv( "HOME" ) );
+		if ( mkdir( ourpage, S_IRWXU ) && errno != EEXIST )
+		{
+			err( 1, "Creating directory %s", ourpage );
+		}
+		char ourpid[ 20 ]; /* "map." + 64-bit pid + '\0' + rounding up a fair bit */
+		snprintf( ourpid, 20, "map.%u", getpid() );
+		strncat( ourpage, ourpid, 20 );
+		fd = open( ourpage, O_RDWR | O_CREAT | O_TRUNC, S_IRWXU );
+		if (fd < 0)
+			err( 1, "Creating memory backing file %s", ourpage );
+		verbose( "Memory backing file is %s\n", ourpage );
+	}
 
-	/* We use a private mapping (ie. if we write to the page, it will be
-	 * copied), and obviously we insist that it be mapped where we ask. */
+	/* If we need more space in our backing file, grow it out. */
+	if ( newhighwater > highwater )
+	{
+		if ( ftruncate( fd, newhighwater ) )
+		{
+			err( 1, "Failed to grow our map file" );
+		}
+	}
+
+	/* We use a shared mapping (ie. if we write to the page, it will be
+	 * backed to the file), and obviously we insist that it be mapped where we
+	 * ask.
+	 * We map from our backing file such that it should match memory, in order.
+	 * This also means it'll merge our mmaps into one mapping, which is neat. */
 	if (mmap((void *)addr, getpagesize() * num,
-		 PROT_READ|PROT_WRITE|PROT_EXEC, MAP_FIXED|MAP_PRIVATE, fd, 0)
+		 PROT_READ|PROT_WRITE|PROT_EXEC, MAP_FIXED|MAP_SHARED, fd, addr)
 	    != (void *)addr)
-		err(1, "Mmaping %u pages of /dev/zero @%p", num, (void *)addr);
+		err(1, "Mmaping %u pages of memory backing file @%p", num, (void *)addr);
+
+	if ( newhighwater > highwater )
+		highwater = newhighwater;
+
+	verbose( "Mapped %u pages of memory backing file @%p, now %lu bytes\n", num,
+		 (void *)addr, highwater);
 
 	/* Returning the address is just a courtesy: can simplify callers. */
 	return (void *)addr;
-- 
1.5.3.8


-- 
-----------------------------------------------------------
Paul "TBBle" Hampson, B.Sc, LPI, MCSE
Very-later-year Asian Studies student, ANU
The Boss, Bubblesworth Pty Ltd (ABN: 51 095 284 361)
Paul.Hampson at Pobox.com

Of course Pacman didn't influence us as kids. If it did,
we'd be running around in darkened rooms, popping pills and
listening to repetitive music.
 -- Kristian Wilson, Nintendo, Inc, 1989

License: http://creativecommons.org/licenses/by/2.1/au/
-----------------------------------------------------------
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: <http://lists.ozlabs.org/pipermail/lguest/attachments/20080131/203a74d6/attachment.pgp>


More information about the Lguest mailing list