diff options
-rw-r--r-- | Documentation/virtual/lguest/lguest.c | 12 | ||||
-rw-r--r-- | arch/x86/include/asm/lguest_hcall.h | 1 | ||||
-rw-r--r-- | arch/x86/lguest/boot.c | 21 | ||||
-rw-r--r-- | arch/x86/lguest/i386_head.S | 18 | ||||
-rw-r--r-- | drivers/lguest/core.c | 2 | ||||
-rw-r--r-- | drivers/lguest/interrupts_and_traps.c | 4 | ||||
-rw-r--r-- | drivers/lguest/lguest_user.c | 17 | ||||
-rw-r--r-- | drivers/lguest/page_tables.c | 4 | ||||
-rw-r--r-- | drivers/lguest/x86/core.c | 10 |
9 files changed, 50 insertions, 39 deletions
diff --git a/Documentation/virtual/lguest/lguest.c b/Documentation/virtual/lguest/lguest.c index 80261d34da3d..043bd7df3139 100644 --- a/Documentation/virtual/lguest/lguest.c +++ b/Documentation/virtual/lguest/lguest.c | |||
@@ -51,7 +51,7 @@ | |||
51 | #include <asm/bootparam.h> | 51 | #include <asm/bootparam.h> |
52 | #include "../../../include/linux/lguest_launcher.h" | 52 | #include "../../../include/linux/lguest_launcher.h" |
53 | /*L:110 | 53 | /*L:110 |
54 | * We can ignore the 42 include files we need for this program, but I do want | 54 | * We can ignore the 43 include files we need for this program, but I do want |
55 | * to draw attention to the use of kernel-style types. | 55 | * to draw attention to the use of kernel-style types. |
56 | * | 56 | * |
57 | * As Linus said, "C is a Spartan language, and so should your naming be." I | 57 | * As Linus said, "C is a Spartan language, and so should your naming be." I |
@@ -65,7 +65,6 @@ typedef uint16_t u16; | |||
65 | typedef uint8_t u8; | 65 | typedef uint8_t u8; |
66 | /*:*/ | 66 | /*:*/ |
67 | 67 | ||
68 | #define PAGE_PRESENT 0x7 /* Present, RW, Execute */ | ||
69 | #define BRIDGE_PFX "bridge:" | 68 | #define BRIDGE_PFX "bridge:" |
70 | #ifndef SIOCBRADDIF | 69 | #ifndef SIOCBRADDIF |
71 | #define SIOCBRADDIF 0x89a2 /* add interface to bridge */ | 70 | #define SIOCBRADDIF 0x89a2 /* add interface to bridge */ |
@@ -1359,7 +1358,7 @@ static void setup_console(void) | |||
1359 | * --sharenet=<name> option which opens or creates a named pipe. This can be | 1358 | * --sharenet=<name> option which opens or creates a named pipe. This can be |
1360 | * used to send packets to another guest in a 1:1 manner. | 1359 | * used to send packets to another guest in a 1:1 manner. |
1361 | * | 1360 | * |
1362 | * More sopisticated is to use one of the tools developed for project like UML | 1361 | * More sophisticated is to use one of the tools developed for project like UML |
1363 | * to do networking. | 1362 | * to do networking. |
1364 | * | 1363 | * |
1365 | * Faster is to do virtio bonding in kernel. Doing this 1:1 would be | 1364 | * Faster is to do virtio bonding in kernel. Doing this 1:1 would be |
@@ -1369,7 +1368,7 @@ static void setup_console(void) | |||
1369 | * multiple inter-guest channels behind one interface, although it would | 1368 | * multiple inter-guest channels behind one interface, although it would |
1370 | * require some manner of hotplugging new virtio channels. | 1369 | * require some manner of hotplugging new virtio channels. |
1371 | * | 1370 | * |
1372 | * Finally, we could implement a virtio network switch in the kernel. | 1371 | * Finally, we could use a virtio network switch in the kernel, ie. vhost. |
1373 | :*/ | 1372 | :*/ |
1374 | 1373 | ||
1375 | static u32 str2ip(const char *ipaddr) | 1374 | static u32 str2ip(const char *ipaddr) |
@@ -2006,10 +2005,7 @@ int main(int argc, char *argv[]) | |||
2006 | /* Tell the entry path not to try to reload segment registers. */ | 2005 | /* Tell the entry path not to try to reload segment registers. */ |
2007 | boot->hdr.loadflags |= KEEP_SEGMENTS; | 2006 | boot->hdr.loadflags |= KEEP_SEGMENTS; |
2008 | 2007 | ||
2009 | /* | 2008 | /* We tell the kernel to initialize the Guest. */ |
2010 | * We tell the kernel to initialize the Guest: this returns the open | ||
2011 | * /dev/lguest file descriptor. | ||
2012 | */ | ||
2013 | tell_kernel(start); | 2009 | tell_kernel(start); |
2014 | 2010 | ||
2015 | /* Ensure that we terminate if a device-servicing child dies. */ | 2011 | /* Ensure that we terminate if a device-servicing child dies. */ |
diff --git a/arch/x86/include/asm/lguest_hcall.h b/arch/x86/include/asm/lguest_hcall.h index b60f2924c413..879fd7d33877 100644 --- a/arch/x86/include/asm/lguest_hcall.h +++ b/arch/x86/include/asm/lguest_hcall.h | |||
@@ -61,6 +61,7 @@ hcall(unsigned long call, | |||
61 | : "memory"); | 61 | : "memory"); |
62 | return call; | 62 | return call; |
63 | } | 63 | } |
64 | /*:*/ | ||
64 | 65 | ||
65 | /* Can't use our min() macro here: needs to be a constant */ | 66 | /* Can't use our min() macro here: needs to be a constant */ |
66 | #define LGUEST_IRQS (NR_IRQS < 32 ? NR_IRQS: 32) | 67 | #define LGUEST_IRQS (NR_IRQS < 32 ? NR_IRQS: 32) |
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index 719a32c60516..74279907bc1a 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c | |||
@@ -71,7 +71,8 @@ | |||
71 | #include <asm/stackprotector.h> | 71 | #include <asm/stackprotector.h> |
72 | #include <asm/reboot.h> /* for struct machine_ops */ | 72 | #include <asm/reboot.h> /* for struct machine_ops */ |
73 | 73 | ||
74 | /*G:010 Welcome to the Guest! | 74 | /*G:010 |
75 | * Welcome to the Guest! | ||
75 | * | 76 | * |
76 | * The Guest in our tale is a simple creature: identical to the Host but | 77 | * The Guest in our tale is a simple creature: identical to the Host but |
77 | * behaving in simplified but equivalent ways. In particular, the Guest is the | 78 | * behaving in simplified but equivalent ways. In particular, the Guest is the |
@@ -190,15 +191,23 @@ static void lazy_hcall4(unsigned long call, | |||
190 | #endif | 191 | #endif |
191 | 192 | ||
192 | /*G:036 | 193 | /*G:036 |
193 | * When lazy mode is turned off reset the per-cpu lazy mode variable and then | 194 | * When lazy mode is turned off, we issue the do-nothing hypercall to |
194 | * issue the do-nothing hypercall to flush any stored calls. | 195 | * flush any stored calls, and call the generic helper to reset the |
195 | :*/ | 196 | * per-cpu lazy mode variable. |
197 | */ | ||
196 | static void lguest_leave_lazy_mmu_mode(void) | 198 | static void lguest_leave_lazy_mmu_mode(void) |
197 | { | 199 | { |
198 | hcall(LHCALL_FLUSH_ASYNC, 0, 0, 0, 0); | 200 | hcall(LHCALL_FLUSH_ASYNC, 0, 0, 0, 0); |
199 | paravirt_leave_lazy_mmu(); | 201 | paravirt_leave_lazy_mmu(); |
200 | } | 202 | } |
201 | 203 | ||
204 | /* | ||
205 | * We also catch the end of context switch; we enter lazy mode for much of | ||
206 | * that too, so again we need to flush here. | ||
207 | * | ||
208 | * (Technically, this is lazy CPU mode, and normally we're in lazy MMU | ||
209 | * mode, but unlike Xen, lguest doesn't care about the difference). | ||
210 | */ | ||
202 | static void lguest_end_context_switch(struct task_struct *next) | 211 | static void lguest_end_context_switch(struct task_struct *next) |
203 | { | 212 | { |
204 | hcall(LHCALL_FLUSH_ASYNC, 0, 0, 0, 0); | 213 | hcall(LHCALL_FLUSH_ASYNC, 0, 0, 0, 0); |
@@ -640,7 +649,7 @@ static void lguest_write_cr4(unsigned long val) | |||
640 | 649 | ||
641 | /* | 650 | /* |
642 | * The Guest calls this after it has set a second-level entry (pte), ie. to map | 651 | * The Guest calls this after it has set a second-level entry (pte), ie. to map |
643 | * a page into a process' address space. Wetell the Host the toplevel and | 652 | * a page into a process' address space. We tell the Host the toplevel and |
644 | * address this corresponds to. The Guest uses one pagetable per process, so | 653 | * address this corresponds to. The Guest uses one pagetable per process, so |
645 | * we need to tell the Host which one we're changing (mm->pgd). | 654 | * we need to tell the Host which one we're changing (mm->pgd). |
646 | */ | 655 | */ |
@@ -1139,7 +1148,7 @@ static struct notifier_block paniced = { | |||
1139 | static __init char *lguest_memory_setup(void) | 1148 | static __init char *lguest_memory_setup(void) |
1140 | { | 1149 | { |
1141 | /* | 1150 | /* |
1142 | *The Linux bootloader header contains an "e820" memory map: the | 1151 | * The Linux bootloader header contains an "e820" memory map: the |
1143 | * Launcher populated the first entry with our memory limit. | 1152 | * Launcher populated the first entry with our memory limit. |
1144 | */ | 1153 | */ |
1145 | e820_add_region(boot_params.e820_map[0].addr, | 1154 | e820_add_region(boot_params.e820_map[0].addr, |
diff --git a/arch/x86/lguest/i386_head.S b/arch/x86/lguest/i386_head.S index c8c95e575c1e..cfa23e37ec5c 100644 --- a/arch/x86/lguest/i386_head.S +++ b/arch/x86/lguest/i386_head.S | |||
@@ -6,18 +6,22 @@ | |||
6 | #include <asm/processor-flags.h> | 6 | #include <asm/processor-flags.h> |
7 | 7 | ||
8 | /*G:020 | 8 | /*G:020 |
9 | * Our story starts with the kernel booting into startup_32 in | 9 | |
10 | * arch/x86/kernel/head_32.S. It expects a boot header, which is created by | 10 | * Our story starts with the bzImage: booting starts at startup_32 in |
11 | * the bootloader (the Launcher in our case). | 11 | * arch/x86/boot/compressed/head_32.S. This merely uncompresses the real |
12 | * kernel in place and then jumps into it: startup_32 in | ||
13 | * arch/x86/kernel/head_32.S. Both routines expects a boot header in the %esi | ||
14 | * register, which is created by the bootloader (the Launcher in our case). | ||
12 | * | 15 | * |
13 | * The startup_32 function does very little: it clears the uninitialized global | 16 | * The startup_32 function does very little: it clears the uninitialized global |
14 | * C variables which we expect to be zero (ie. BSS) and then copies the boot | 17 | * C variables which we expect to be zero (ie. BSS) and then copies the boot |
15 | * header and kernel command line somewhere safe. Finally it checks the | 18 | * header and kernel command line somewhere safe, and populates some initial |
16 | * 'hardware_subarch' field. This was introduced in 2.6.24 for lguest and Xen: | 19 | * page tables. Finally it checks the 'hardware_subarch' field. This was |
17 | * if it's set to '1' (lguest's assigned number), then it calls us here. | 20 | * introduced in 2.6.24 for lguest and Xen: if it's set to '1' (lguest's |
21 | * assigned number), then it calls us here. | ||
18 | * | 22 | * |
19 | * WARNING: be very careful here! We're running at addresses equal to physical | 23 | * WARNING: be very careful here! We're running at addresses equal to physical |
20 | * addesses (around 0), not above PAGE_OFFSET as most code expectes | 24 | * addesses (around 0), not above PAGE_OFFSET as most code expects |
21 | * (eg. 0xC0000000). Jumps are relative, so they're OK, but we can't touch any | 25 | * (eg. 0xC0000000). Jumps are relative, so they're OK, but we can't touch any |
22 | * data without remembering to subtract __PAGE_OFFSET! | 26 | * data without remembering to subtract __PAGE_OFFSET! |
23 | * | 27 | * |
diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c index efa202499e37..2535933c49f8 100644 --- a/drivers/lguest/core.c +++ b/drivers/lguest/core.c | |||
@@ -117,7 +117,7 @@ static __init int map_switcher(void) | |||
117 | 117 | ||
118 | /* | 118 | /* |
119 | * Now the Switcher is mapped at the right address, we can't fail! | 119 | * Now the Switcher is mapped at the right address, we can't fail! |
120 | * Copy in the compiled-in Switcher code (from <arch>_switcher.S). | 120 | * Copy in the compiled-in Switcher code (from x86/switcher_32.S). |
121 | */ | 121 | */ |
122 | memcpy(switcher_vma->addr, start_switcher_text, | 122 | memcpy(switcher_vma->addr, start_switcher_text, |
123 | end_switcher_text - start_switcher_text); | 123 | end_switcher_text - start_switcher_text); |
diff --git a/drivers/lguest/interrupts_and_traps.c b/drivers/lguest/interrupts_and_traps.c index f0c171506371..28433a155d67 100644 --- a/drivers/lguest/interrupts_and_traps.c +++ b/drivers/lguest/interrupts_and_traps.c | |||
@@ -427,8 +427,8 @@ void pin_stack_pages(struct lg_cpu *cpu) | |||
427 | 427 | ||
428 | /* | 428 | /* |
429 | * Direct traps also mean that we need to know whenever the Guest wants to use | 429 | * Direct traps also mean that we need to know whenever the Guest wants to use |
430 | * a different kernel stack, so we can change the IDT entries to use that | 430 | * a different kernel stack, so we can change the guest TSS to use that |
431 | * stack. The IDT entries expect a virtual address, so unlike most addresses | 431 | * stack. The TSS entries expect a virtual address, so unlike most addresses |
432 | * the Guest gives us, the "esp" (stack pointer) value here is virtual, not | 432 | * the Guest gives us, the "esp" (stack pointer) value here is virtual, not |
433 | * physical. | 433 | * physical. |
434 | * | 434 | * |
diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c index 948c547b8e9e..f97e625241ad 100644 --- a/drivers/lguest/lguest_user.c +++ b/drivers/lguest/lguest_user.c | |||
@@ -1,8 +1,10 @@ | |||
1 | /*P:200 This contains all the /dev/lguest code, whereby the userspace launcher | 1 | /*P:200 This contains all the /dev/lguest code, whereby the userspace |
2 | * controls and communicates with the Guest. For example, the first write will | 2 | * launcher controls and communicates with the Guest. For example, |
3 | * tell us the Guest's memory layout and entry point. A read will run the | 3 | * the first write will tell us the Guest's memory layout and entry |
4 | * Guest until something happens, such as a signal or the Guest doing a NOTIFY | 4 | * point. A read will run the Guest until something happens, such as |
5 | * out to the Launcher. | 5 | * a signal or the Guest doing a NOTIFY out to the Launcher. There is |
6 | * also a way for the Launcher to attach eventfds to particular NOTIFY | ||
7 | * values instead of returning from the read() call. | ||
6 | :*/ | 8 | :*/ |
7 | #include <linux/uaccess.h> | 9 | #include <linux/uaccess.h> |
8 | #include <linux/miscdevice.h> | 10 | #include <linux/miscdevice.h> |
@@ -357,8 +359,8 @@ static int initialize(struct file *file, const unsigned long __user *input) | |||
357 | goto free_eventfds; | 359 | goto free_eventfds; |
358 | 360 | ||
359 | /* | 361 | /* |
360 | * Initialize the Guest's shadow page tables, using the toplevel | 362 | * Initialize the Guest's shadow page tables. This allocates |
361 | * address the Launcher gave us. This allocates memory, so can fail. | 363 | * memory, so can fail. |
362 | */ | 364 | */ |
363 | err = init_guest_pagetable(lg); | 365 | err = init_guest_pagetable(lg); |
364 | if (err) | 366 | if (err) |
@@ -516,6 +518,7 @@ static const struct file_operations lguest_fops = { | |||
516 | .read = read, | 518 | .read = read, |
517 | .llseek = default_llseek, | 519 | .llseek = default_llseek, |
518 | }; | 520 | }; |
521 | /*:*/ | ||
519 | 522 | ||
520 | /* | 523 | /* |
521 | * This is a textbook example of a "misc" character device. Populate a "struct | 524 | * This is a textbook example of a "misc" character device. Populate a "struct |
diff --git a/drivers/lguest/page_tables.c b/drivers/lguest/page_tables.c index 00026222bde8..3b62be160a6e 100644 --- a/drivers/lguest/page_tables.c +++ b/drivers/lguest/page_tables.c | |||
@@ -155,7 +155,7 @@ static pte_t *spte_addr(struct lg_cpu *cpu, pgd_t spgd, unsigned long vaddr) | |||
155 | } | 155 | } |
156 | 156 | ||
157 | /* | 157 | /* |
158 | * These functions are just like the above two, except they access the Guest | 158 | * These functions are just like the above, except they access the Guest |
159 | * page tables. Hence they return a Guest address. | 159 | * page tables. Hence they return a Guest address. |
160 | */ | 160 | */ |
161 | static unsigned long gpgd_addr(struct lg_cpu *cpu, unsigned long vaddr) | 161 | static unsigned long gpgd_addr(struct lg_cpu *cpu, unsigned long vaddr) |
@@ -195,7 +195,7 @@ static unsigned long gpte_addr(struct lg_cpu *cpu, | |||
195 | #endif | 195 | #endif |
196 | /*:*/ | 196 | /*:*/ |
197 | 197 | ||
198 | /*M:014 | 198 | /*M:007 |
199 | * get_pfn is slow: we could probably try to grab batches of pages here as | 199 | * get_pfn is slow: we could probably try to grab batches of pages here as |
200 | * an optimization (ie. pre-faulting). | 200 | * an optimization (ie. pre-faulting). |
201 | :*/ | 201 | :*/ |
diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c index ec0cdfc04e78..3b9b810cbf28 100644 --- a/drivers/lguest/x86/core.c +++ b/drivers/lguest/x86/core.c | |||
@@ -272,7 +272,7 @@ static int emulate_insn(struct lg_cpu *cpu) | |||
272 | unsigned int insnlen = 0, in = 0, shift = 0; | 272 | unsigned int insnlen = 0, in = 0, shift = 0; |
273 | /* | 273 | /* |
274 | * The eip contains the *virtual* address of the Guest's instruction: | 274 | * The eip contains the *virtual* address of the Guest's instruction: |
275 | * guest_pa just subtracts the Guest's page_offset. | 275 | * walk the Guest's page tables to find the "physical" address. |
276 | */ | 276 | */ |
277 | unsigned long physaddr = guest_pa(cpu, cpu->regs->eip); | 277 | unsigned long physaddr = guest_pa(cpu, cpu->regs->eip); |
278 | 278 | ||
@@ -409,7 +409,7 @@ void lguest_arch_handle_trap(struct lg_cpu *cpu) | |||
409 | * These values mean a real interrupt occurred, in which case | 409 | * These values mean a real interrupt occurred, in which case |
410 | * the Host handler has already been run. We just do a | 410 | * the Host handler has already been run. We just do a |
411 | * friendly check if another process should now be run, then | 411 | * friendly check if another process should now be run, then |
412 | * return to run the Guest again | 412 | * return to run the Guest again. |
413 | */ | 413 | */ |
414 | cond_resched(); | 414 | cond_resched(); |
415 | return; | 415 | return; |
@@ -459,7 +459,7 @@ void __init lguest_arch_host_init(void) | |||
459 | int i; | 459 | int i; |
460 | 460 | ||
461 | /* | 461 | /* |
462 | * Most of the i386/switcher.S doesn't care that it's been moved; on | 462 | * Most of the x86/switcher_32.S doesn't care that it's been moved; on |
463 | * Intel, jumps are relative, and it doesn't access any references to | 463 | * Intel, jumps are relative, and it doesn't access any references to |
464 | * external code or data. | 464 | * external code or data. |
465 | * | 465 | * |
@@ -587,7 +587,7 @@ void __init lguest_arch_host_init(void) | |||
587 | clear_cpu_cap(&boot_cpu_data, X86_FEATURE_PGE); | 587 | clear_cpu_cap(&boot_cpu_data, X86_FEATURE_PGE); |
588 | } | 588 | } |
589 | put_online_cpus(); | 589 | put_online_cpus(); |
590 | }; | 590 | } |
591 | /*:*/ | 591 | /*:*/ |
592 | 592 | ||
593 | void __exit lguest_arch_host_fini(void) | 593 | void __exit lguest_arch_host_fini(void) |
@@ -670,8 +670,6 @@ int lguest_arch_init_hypercalls(struct lg_cpu *cpu) | |||
670 | /*:*/ | 670 | /*:*/ |
671 | 671 | ||
672 | /*L:030 | 672 | /*L:030 |
673 | * lguest_arch_setup_regs() | ||
674 | * | ||
675 | * Most of the Guest's registers are left alone: we used get_zeroed_page() to | 673 | * Most of the Guest's registers are left alone: we used get_zeroed_page() to |
676 | * allocate the structure, so they will be 0. | 674 | * allocate the structure, so they will be 0. |
677 | */ | 675 | */ |