aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/lguest/lguest.c42
-rw-r--r--arch/x86/lguest/boot.c17
-rw-r--r--arch/x86/lguest/i386_head.S17
3 files changed, 18 insertions, 58 deletions
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c
index cbf4becd266..004c5c6aba6 100644
--- a/Documentation/lguest/lguest.c
+++ b/Documentation/lguest/lguest.c
@@ -251,23 +251,6 @@ static void *get_pages(unsigned int num)
251 return addr; 251 return addr;
252} 252}
253 253
254/* To find out where to start we look for the magic Guest string, which marks
255 * the code we see in lguest_asm.S. This is a hack which we are currently
256 * plotting to replace with the normal Linux entry point. */
257static unsigned long entry_point(const void *start, const void *end)
258{
259 const void *p;
260
261 /* The scan gives us the physical starting address. We boot with
262 * pagetables set up with virtual and physical the same, so that's
263 * OK. */
264 for (p = start; p < end; p++)
265 if (memcmp(p, "GenuineLguest", strlen("GenuineLguest")) == 0)
266 return to_guest_phys(p + strlen("GenuineLguest"));
267
268 errx(1, "Is this image a genuine lguest?");
269}
270
271/* This routine is used to load the kernel or initrd. It tries mmap, but if 254/* This routine is used to load the kernel or initrd. It tries mmap, but if
272 * that fails (Plan 9's kernel file isn't nicely aligned on page boundaries), 255 * that fails (Plan 9's kernel file isn't nicely aligned on page boundaries),
273 * it falls back to reading the memory in. */ 256 * it falls back to reading the memory in. */
@@ -303,7 +286,6 @@ static void map_at(int fd, void *addr, unsigned long offset, unsigned long len)
303 * We return the starting address. */ 286 * We return the starting address. */
304static unsigned long map_elf(int elf_fd, const Elf32_Ehdr *ehdr) 287static unsigned long map_elf(int elf_fd, const Elf32_Ehdr *ehdr)
305{ 288{
306 void *start = (void *)-1, *end = NULL;
307 Elf32_Phdr phdr[ehdr->e_phnum]; 289 Elf32_Phdr phdr[ehdr->e_phnum];
308 unsigned int i; 290 unsigned int i;
309 291
@@ -335,19 +317,13 @@ static unsigned long map_elf(int elf_fd, const Elf32_Ehdr *ehdr)
335 verbose("Section %i: size %i addr %p\n", 317 verbose("Section %i: size %i addr %p\n",
336 i, phdr[i].p_memsz, (void *)phdr[i].p_paddr); 318 i, phdr[i].p_memsz, (void *)phdr[i].p_paddr);
337 319
338 /* We track the first and last address we mapped, so we can
339 * tell entry_point() where to scan. */
340 if (from_guest_phys(phdr[i].p_paddr) < start)
341 start = from_guest_phys(phdr[i].p_paddr);
342 if (from_guest_phys(phdr[i].p_paddr) + phdr[i].p_filesz > end)
343 end=from_guest_phys(phdr[i].p_paddr)+phdr[i].p_filesz;
344
345 /* We map this section of the file at its physical address. */ 320 /* We map this section of the file at its physical address. */
346 map_at(elf_fd, from_guest_phys(phdr[i].p_paddr), 321 map_at(elf_fd, from_guest_phys(phdr[i].p_paddr),
347 phdr[i].p_offset, phdr[i].p_filesz); 322 phdr[i].p_offset, phdr[i].p_filesz);
348 } 323 }
349 324
350 return entry_point(start, end); 325 /* The entry point is given in the ELF header. */
326 return ehdr->e_entry;
351} 327}
352 328
353/*L:160 Unfortunately the entire ELF image isn't compressed: the segments 329/*L:160 Unfortunately the entire ELF image isn't compressed: the segments
@@ -374,7 +350,8 @@ static unsigned long unpack_bzimage(int fd)
374 350
375 verbose("Unpacked size %i addr %p\n", len, img); 351 verbose("Unpacked size %i addr %p\n", len, img);
376 352
377 return entry_point(img, img + len); 353 /* The entry point for a bzImage is always the first byte */
354 return (unsigned long)img;
378} 355}
379 356
380/*L:150 A bzImage, unlike an ELF file, is not meant to be loaded. You're 357/*L:150 A bzImage, unlike an ELF file, is not meant to be loaded. You're
@@ -1684,8 +1661,15 @@ int main(int argc, char *argv[])
1684 *(u32 *)(boot + 0x228) = 4096; 1661 *(u32 *)(boot + 0x228) = 4096;
1685 concat(boot + 4096, argv+optind+2); 1662 concat(boot + 4096, argv+optind+2);
1686 1663
1687 /* The guest type value of "1" tells the Guest it's under lguest. */ 1664 /* Boot protocol version: 2.07 supports the fields for lguest. */
1688 *(int *)(boot + 0x23c) = 1; 1665 *(u16 *)(boot + 0x206) = 0x207;
1666
1667 /* The hardware_subarch value of "1" tells the Guest it's an lguest. */
1668 *(u32 *)(boot + 0x23c) = 1;
1669
1670 /* Set bit 6 of the loadflags (aka. KEEP_SEGMENTS) so the entry path
1671 * does not try to reload segment registers. */
1672 *(u8 *)(boot + 0x211) |= (1 << 6);
1689 1673
1690 /* We tell the kernel to initialize the Guest: this returns the open 1674 /* We tell the kernel to initialize the Guest: this returns the open
1691 * /dev/lguest file descriptor. */ 1675 * /dev/lguest file descriptor. */
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
index 495e46a1f11..d2235db4085 100644
--- a/arch/x86/lguest/boot.c
+++ b/arch/x86/lguest/boot.c
@@ -928,18 +928,8 @@ static unsigned lguest_patch(u8 type, u16 clobber, void *ibuf,
928/*G:030 Once we get to lguest_init(), we know we're a Guest. The pv_ops 928/*G:030 Once we get to lguest_init(), we know we're a Guest. The pv_ops
929 * structures in the kernel provide points for (almost) every routine we have 929 * structures in the kernel provide points for (almost) every routine we have
930 * to override to avoid privileged instructions. */ 930 * to override to avoid privileged instructions. */
931__init void lguest_init(void *boot) 931__init void lguest_init(void)
932{ 932{
933 /* Copy boot parameters first: the Launcher put the physical location
934 * in %esi, and head.S converted that to a virtual address and handed
935 * it to us. We use "__memcpy" because "memcpy" sometimes tries to do
936 * tricky things to go faster, and we're not ready for that. */
937 __memcpy(&boot_params, boot, PARAM_SIZE);
938 /* The boot parameters also tell us where the command-line is: save
939 * that, too. */
940 __memcpy(boot_command_line, __va(boot_params.hdr.cmd_line_ptr),
941 COMMAND_LINE_SIZE);
942
943 /* We're under lguest, paravirt is enabled, and we're running at 933 /* We're under lguest, paravirt is enabled, and we're running at
944 * privilege level 1, not 0 as normal. */ 934 * privilege level 1, not 0 as normal. */
945 pv_info.name = "lguest"; 935 pv_info.name = "lguest";
@@ -1024,11 +1014,6 @@ __init void lguest_init(void *boot)
1024 * the normal data segment to get through booting. */ 1014 * the normal data segment to get through booting. */
1025 asm volatile ("mov %0, %%fs" : : "r" (__KERNEL_DS) : "memory"); 1015 asm volatile ("mov %0, %%fs" : : "r" (__KERNEL_DS) : "memory");
1026 1016
1027 /* Clear the part of the kernel data which is expected to be zero.
1028 * Normally it will be anyway, but if we're loading from a bzImage with
1029 * CONFIG_RELOCATALE=y, the relocations will be sitting here. */
1030 memset(__bss_start, 0, __bss_stop - __bss_start);
1031
1032 /* The Host uses the top of the Guest's virtual address space for the 1017 /* The Host uses the top of the Guest's virtual address space for the
1033 * Host<->Guest Switcher, and it tells us how much it needs in 1018 * Host<->Guest Switcher, and it tells us how much it needs in
1034 * lguest_data.reserve_mem, set up on the LGUEST_INIT hypercall. */ 1019 * lguest_data.reserve_mem, set up on the LGUEST_INIT hypercall. */
diff --git a/arch/x86/lguest/i386_head.S b/arch/x86/lguest/i386_head.S
index ba4282eba5b..ebc6ac73389 100644
--- a/arch/x86/lguest/i386_head.S
+++ b/arch/x86/lguest/i386_head.S
@@ -5,11 +5,8 @@
5#include <asm/thread_info.h> 5#include <asm/thread_info.h>
6#include <asm/processor-flags.h> 6#include <asm/processor-flags.h>
7 7
8/*G:020 This is where we begin: we have a magic signature which the launcher 8/*G:020 This is where we begin: head.S notes that the boot header's platform
9 * looks for. The plan is that the Linux boot protocol will be extended with a 9 * type field is "1" (lguest), so calls us here. The boot header is in %esi.
10 * "platform type" field which will guide us here from the normal entry point,
11 * but for the moment this suffices. The normal boot code uses %esi for the
12 * boot header, so we do too.
13 * 10 *
14 * WARNING: be very careful here! We're running at addresses equal to physical 11 * 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 12 * addesses (around 0), not above PAGE_OFFSET as most code expectes
@@ -19,19 +16,14 @@
19 * The .section line puts this code in .init.text so it will be discarded after 16 * The .section line puts this code in .init.text so it will be discarded after
20 * boot. */ 17 * boot. */
21.section .init.text, "ax", @progbits 18.section .init.text, "ax", @progbits
22.ascii "GenuineLguest" 19ENTRY(lguest_entry)
23 /* Make initial hypercall now, so we can set up the pagetables. */ 20 /* Make initial hypercall now, so we can set up the pagetables. */
24 movl $LHCALL_LGUEST_INIT, %eax 21 movl $LHCALL_LGUEST_INIT, %eax
25 movl $lguest_data - __PAGE_OFFSET, %edx 22 movl $lguest_data - __PAGE_OFFSET, %edx
26 int $LGUEST_TRAP_ENTRY 23 int $LGUEST_TRAP_ENTRY
27 24
28 /* Set up boot information pointer to hand to lguest_init(): it wants
29 * a virtual address. */
30 movl %esi, %eax
31 addl $__PAGE_OFFSET, %eax
32
33 /* The Host put the toplevel pagetable in lguest_data.pgdir. The movsl 25 /* The Host put the toplevel pagetable in lguest_data.pgdir. The movsl
34 * instruction uses %esi, so we needed to save it above. */ 26 * instruction uses %esi implicitly. */
35 movl lguest_data - __PAGE_OFFSET + LGUEST_DATA_pgdir, %esi 27 movl lguest_data - __PAGE_OFFSET + LGUEST_DATA_pgdir, %esi
36 28
37 /* Copy first 32 entries of page directory to __PAGE_OFFSET entries. 29 /* Copy first 32 entries of page directory to __PAGE_OFFSET entries.
@@ -47,7 +39,6 @@
47 /* Set up the initial stack so we can run C code. */ 39 /* Set up the initial stack so we can run C code. */
48 movl $(init_thread_union+THREAD_SIZE),%esp 40 movl $(init_thread_union+THREAD_SIZE),%esp
49 41
50
51 /* Jumps are relative, and we're running __PAGE_OFFSET too low at the 42 /* Jumps are relative, and we're running __PAGE_OFFSET too low at the
52 * moment. */ 43 * moment. */
53 jmp lguest_init+__PAGE_OFFSET 44 jmp lguest_init+__PAGE_OFFSET