aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2007-10-21 21:03:36 -0400
committerRusty Russell <rusty@rustcorp.com.au>2007-10-23 01:49:54 -0400
commit47436aa4ad054c1c7c8231618e86ebd9305308dc (patch)
treea9ba6e0521f9116442144a86e781a3164ec86094 /arch/x86
parentc18acd73ffc209def08003a1927473096f66c5ad (diff)
Boot with virtual == physical to get closer to native Linux.
1) This allows us to get alot closer to booting bzImages. 2) It means we don't have to know page_offset. 3) The Guest needs to modify the boot pagetables to create the PAGE_OFFSET mapping before jumping to C code. 4) guest_pa() walks the page tables rather than using page_offset. 5) We don't use page_offset to figure out whether to emulate: it was always kinda quesationable, and won't work for instructions done before remapping (bzImage unpacking in particular). 6) We still want the kernel address for tlb flushing: have the initial hypercall give us that, too. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/kernel/asm-offsets_32.c1
-rw-r--r--arch/x86/lguest/boot.c7
-rw-r--r--arch/x86/lguest/i386_head.S41
3 files changed, 39 insertions, 10 deletions
diff --git a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c
index f8764716b0c0..0e45981b2dd7 100644
--- a/arch/x86/kernel/asm-offsets_32.c
+++ b/arch/x86/kernel/asm-offsets_32.c
@@ -136,6 +136,7 @@ void foo(void)
136#ifdef CONFIG_LGUEST_GUEST 136#ifdef CONFIG_LGUEST_GUEST
137 BLANK(); 137 BLANK();
138 OFFSET(LGUEST_DATA_irq_enabled, lguest_data, irq_enabled); 138 OFFSET(LGUEST_DATA_irq_enabled, lguest_data, irq_enabled);
139 OFFSET(LGUEST_DATA_pgdir, lguest_data, pgdir);
139 OFFSET(LGUEST_PAGES_host_gdt_desc, lguest_pages, state.host_gdt_desc); 140 OFFSET(LGUEST_PAGES_host_gdt_desc, lguest_pages, state.host_gdt_desc);
140 OFFSET(LGUEST_PAGES_host_idt_desc, lguest_pages, state.host_idt_desc); 141 OFFSET(LGUEST_PAGES_host_idt_desc, lguest_pages, state.host_idt_desc);
141 OFFSET(LGUEST_PAGES_host_cr3, lguest_pages, state.host_cr3); 142 OFFSET(LGUEST_PAGES_host_cr3, lguest_pages, state.host_cr3);
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
index 3a06b51c98ad..090f30cbf24c 100644
--- a/arch/x86/lguest/boot.c
+++ b/arch/x86/lguest/boot.c
@@ -86,6 +86,7 @@ struct lguest_data lguest_data = {
86 .hcall_status = { [0 ... LHCALL_RING_SIZE-1] = 0xFF }, 86 .hcall_status = { [0 ... LHCALL_RING_SIZE-1] = 0xFF },
87 .noirq_start = (u32)lguest_noirq_start, 87 .noirq_start = (u32)lguest_noirq_start,
88 .noirq_end = (u32)lguest_noirq_end, 88 .noirq_end = (u32)lguest_noirq_end,
89 .kernel_address = PAGE_OFFSET,
89 .blocked_interrupts = { 1 }, /* Block timer interrupts */ 90 .blocked_interrupts = { 1 }, /* Block timer interrupts */
90 .syscall_vec = SYSCALL_VECTOR, 91 .syscall_vec = SYSCALL_VECTOR,
91}; 92};
@@ -1033,11 +1034,7 @@ __init void lguest_init(void *boot)
1033 1034
1034 /*G:070 Now we've seen all the paravirt_ops, we return to 1035 /*G:070 Now we've seen all the paravirt_ops, we return to
1035 * lguest_init() where the rest of the fairly chaotic boot setup 1036 * lguest_init() where the rest of the fairly chaotic boot setup
1036 * occurs. 1037 * occurs. */
1037 *
1038 * The Host expects our first hypercall to tell it where our "struct
1039 * lguest_data" is, so we do that first. */
1040 hcall(LHCALL_LGUEST_INIT, __pa(&lguest_data), 0, 0);
1041 1038
1042 /* The native boot code sets up initial page tables immediately after 1039 /* The native boot code sets up initial page tables immediately after
1043 * the kernel itself, and sets init_pg_tables_end so they're not 1040 * the kernel itself, and sets init_pg_tables_end so they're not
diff --git a/arch/x86/lguest/i386_head.S b/arch/x86/lguest/i386_head.S
index 6d7a74f07c41..ba4282eba5bf 100644
--- a/arch/x86/lguest/i386_head.S
+++ b/arch/x86/lguest/i386_head.S
@@ -1,5 +1,6 @@
1#include <linux/linkage.h> 1#include <linux/linkage.h>
2#include <linux/lguest.h> 2#include <linux/lguest.h>
3#include <asm/lguest_hcall.h>
3#include <asm/asm-offsets.h> 4#include <asm/asm-offsets.h>
4#include <asm/thread_info.h> 5#include <asm/thread_info.h>
5#include <asm/processor-flags.h> 6#include <asm/processor-flags.h>
@@ -8,18 +9,48 @@
8 * looks for. The plan is that the Linux boot protocol will be extended with a 9 * looks for. The plan is that the Linux boot protocol will be extended with a
9 * "platform type" field which will guide us here from the normal entry point, 10 * "platform type" field which will guide us here from the normal entry point,
10 * but for the moment this suffices. The normal boot code uses %esi for the 11 * but for the moment this suffices. The normal boot code uses %esi for the
11 * boot header, so we do too. We convert it to a virtual address by adding 12 * boot header, so we do too.
12 * PAGE_OFFSET, and hand it to lguest_init() as its argument (ie. %eax). 13 *
14 * WARNING: be very careful here! We're running at addresses equal to physical
15 * addesses (around 0), not above PAGE_OFFSET as most code expectes
16 * (eg. 0xC0000000). Jumps are relative, so they're OK, but we can't touch any
17 * data.
13 * 18 *
14 * The .section line puts this code in .init.text so it will be discarded after 19 * The .section line puts this code in .init.text so it will be discarded after
15 * boot. */ 20 * boot. */
16.section .init.text, "ax", @progbits 21.section .init.text, "ax", @progbits
17.ascii "GenuineLguest" 22.ascii "GenuineLguest"
18 /* Set up initial stack. */ 23 /* Make initial hypercall now, so we can set up the pagetables. */
19 movl $(init_thread_union+THREAD_SIZE),%esp 24 movl $LHCALL_LGUEST_INIT, %eax
25 movl $lguest_data - __PAGE_OFFSET, %edx
26 int $LGUEST_TRAP_ENTRY
27
28 /* Set up boot information pointer to hand to lguest_init(): it wants
29 * a virtual address. */
20 movl %esi, %eax 30 movl %esi, %eax
21 addl $__PAGE_OFFSET, %eax 31 addl $__PAGE_OFFSET, %eax
22 jmp lguest_init 32
33 /* The Host put the toplevel pagetable in lguest_data.pgdir. The movsl
34 * instruction uses %esi, so we needed to save it above. */
35 movl lguest_data - __PAGE_OFFSET + LGUEST_DATA_pgdir, %esi
36
37 /* Copy first 32 entries of page directory to __PAGE_OFFSET entries.
38 * This means the first 128M of kernel memory will be mapped at
39 * PAGE_OFFSET where the kernel expects to run. This will get it far
40 * enough through boot to switch to its own pagetables. */
41 movl $32, %ecx
42 movl %esi, %edi
43 addl $((__PAGE_OFFSET >> 22) * 4), %edi
44 rep
45 movsl
46
47 /* Set up the initial stack so we can run C code. */
48 movl $(init_thread_union+THREAD_SIZE),%esp
49
50
51 /* Jumps are relative, and we're running __PAGE_OFFSET too low at the
52 * moment. */
53 jmp lguest_init+__PAGE_OFFSET
23 54
24/*G:055 We create a macro which puts the assembler code between lgstart_ and 55/*G:055 We create a macro which puts the assembler code between lgstart_ and
25 * lgend_ markers. These templates are put in the .text section: they can't be 56 * lgend_ markers. These templates are put in the .text section: they can't be