Plan 9 from Bell Labs’s /usr/web/sources/contrib/rminnich/lguest/diff2.6.23

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


diff --git a/Documentation/lguest/Makefile b/Documentation/lguest/Makefile
index 31e794e..60136d8 100644
--- a/Documentation/lguest/Makefile
+++ b/Documentation/lguest/Makefile
@@ -13,7 +13,7 @@ LGUEST_GUEST_TOP := ($(CONFIG_PAGE_OFFSET) - 0x08000000)
 
 CFLAGS:=-Wall -Wmissing-declarations -Wmissing-prototypes -O3 -Wl,-T,lguest.lds
 LDLIBS:=-lz
-
+LDFLAGS+=-static
 all: lguest.lds lguest
 
 # The linker script on x86 is so complex the only way of creating one
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c
index f791840..bb33ae9 100644
--- a/Documentation/lguest/lguest.c
+++ b/Documentation/lguest/lguest.c
@@ -15,6 +15,7 @@
 #include <stdlib.h>
 #include <elf.h>
 #include <sys/mman.h>
+#include <sys/param.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/wait.h>
@@ -235,15 +236,36 @@ static unsigned long map_elf(int elf_fd, const Elf32_Ehdr *ehdr,
 		 *
 		 * MAP_PRIVATE means that the page won't be copied until a
 		 * write is done to it.  This allows us to share much of the
-		 * kernel memory between Guests. */
+		 * kernel memory between Guests.
+		 * Also, another gratuitous use of getpageize :-) as we round
+		 * up the section file size. 
+		 */
 		addr = mmap((void *)phdr[i].p_paddr,
-			    phdr[i].p_filesz,
+			    roundup(phdr[i].p_filesz, getpagesize()),
 			    PROT_READ|PROT_WRITE|PROT_EXEC,
 			    MAP_FIXED|MAP_PRIVATE,
 			    elf_fd, phdr[i].p_offset);
-		if (addr != (void *)phdr[i].p_paddr)
-			err(1, "Mmaping vmlinux seg %i gave %p not %p",
-			    i, addr, (void *)phdr[i].p_paddr);
+		/* There is no requirement or guarantee that an ELF file
+		 * be appropriately laid out for mmap. In fact, it's 
+		 * not possible to know for sure beforehand: what if the 
+		 * file is linked on a machine running with 4K pages and
+		 * we end up on a machine with much bigger pages? So we
+		 * let the kernel tell us that it can or can not map
+		 * the file. If it fails, we read the loader section in and
+		 * lose the benefit of the mmap
+		 */
+		if (addr != (void *)phdr[i].p_paddr){
+			ssize_t rsize;
+			warn("Mmaping vmlinux seg %i gave %p not %p",
+				i, addr, (void *)phdr[i].p_paddr);
+			addr = (void *) phdr[i].p_paddr;
+			/* read it in ... */
+			if ((rsize = pread(elf_fd, addr, phdr[i].p_filesz, 
+				phdr[i].p_offset)) < phdr[i].p_filesz)
+				err(1, 
+				"Reading in ELF file gave %i not %d\n", rsize, 
+					phdr[i].p_filesz);		
+		}
 	}
 
 	return entry_point((void *)start, (void *)end, *page_offset);
diff --git a/drivers/lguest/Kconfig b/drivers/lguest/Kconfig
index 888205c..736e1e3 100644
--- a/drivers/lguest/Kconfig
+++ b/drivers/lguest/Kconfig
@@ -3,6 +3,9 @@ config LGUEST
 	depends on X86 && PARAVIRT && EXPERIMENTAL && !X86_PAE
 	select LGUEST_GUEST
 	select HVC_DRIVER
+	select LGUEST_PLAN9_SYSCALL
+	select LGUEST_NET
+	select LGUEST_BLOCK
 	---help---
 	  This is a very simple module which allows you to run
 	  multiple instances of the same Linux kernel, using the
@@ -19,6 +22,11 @@ config LGUEST_GUEST
 	  support as a module.  The drivers are tiny, so we build them
 	  in too.
 
+config LGUEST_PLAN9_SYSCALL
+	bool
+	help
+	  Support for Plan 9 system calls.
+
 config LGUEST_NET
 	tristate
 	depends on LGUEST_GUEST && NET
diff --git a/drivers/lguest/interrupts_and_traps.c b/drivers/lguest/interrupts_and_traps.c
index 49787e9..4f83224 100644
--- a/drivers/lguest/interrupts_and_traps.c
+++ b/drivers/lguest/interrupts_and_traps.c
@@ -222,7 +222,11 @@ static int direct_trap(const struct lguest *lg,
 {
 	/* Hardware interrupts don't go to the Guest at all (except system
 	 * call). */
-	if (num >= FIRST_EXTERNAL_VECTOR && num != SYSCALL_VECTOR)
+	if (num >= FIRST_EXTERNAL_VECTOR && 
+#ifdef CONFIG_LGUEST_PLAN9_SYSCALL
+	    num != PLAN9_SYSCALL_VECTOR &&
+#endif
+	    num != SYSCALL_VECTOR)
 		return 0;
 
 	/* The Host needs to see page faults (for shadow paging and to save the
@@ -351,6 +355,10 @@ void load_guest_idt_entry(struct lguest *lg, unsigned int num, u32 lo, u32 hi)
 		set_trap(lg, &lg->idt[num], num, lo, hi);
 	else if (num == SYSCALL_VECTOR)
 		set_trap(lg, &lg->syscall_idt, num, lo, hi);
+#ifdef CONFIG_LGUEST_PLAN9_SYSCALL
+	else if (num == PLAN9_SYSCALL_VECTOR)
+		set_trap(lg, &lg->syscall_idt, num, lo, hi);
+#endif
 }
 
 /* The default entry for each interrupt points into the Switcher routines which
@@ -407,6 +415,13 @@ void copy_traps(const struct lguest *lg, struct desc_struct *idt,
 		idt[i] = lg->syscall_idt;
 	else
 		default_idt_entry(&idt[i], i, def[i]);
+#ifdef CONFIG_LGUEST_PLAN9_SYSCALL
+	i = PLAN9_SYSCALL_VECTOR;
+	if (direct_trap(lg, &lg->syscall_idt, i))
+		idt[i] = lg->syscall_idt;
+	else
+		default_idt_entry(&idt[i], i, def[i]);
+#endif
 }
 
 void guest_set_clockevent(struct lguest *lg, unsigned long delta)
diff --git a/include/linux/lguest.h b/include/linux/lguest.h
index 157ad64..08d5474 100644
--- a/include/linux/lguest.h
+++ b/include/linux/lguest.h
@@ -26,6 +26,7 @@
 #define LG_CLOCK_MIN_DELTA	100UL
 #define LG_CLOCK_MAX_DELTA	ULONG_MAX
 
+#define PLAN9_SYSCALL_VECTOR	0x40
 /*G:031 First, how does our Guest contact the Host to ask for privileged
  * operations?  There are two ways: the direct way is to make a "hypercall",
  * to make requests of the Host Itself.

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].