diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c index cbf4becd2667..004c5c6aba6a 100644 --- a/Documentation/lguest/lguest.c +++ b/Documentation/lguest/lguest.c @@ -251,23 +251,6 @@ static void *get_pages(unsigned int num) return addr; } -/* To find out where to start we look for the magic Guest string, which marks - * the code we see in lguest_asm.S. This is a hack which we are currently - * plotting to replace with the normal Linux entry point. */ -static unsigned long entry_point(const void *start, const void *end) -{ - const void *p; - - /* The scan gives us the physical starting address. We boot with - * pagetables set up with virtual and physical the same, so that's - * OK. */ - for (p = start; p < end; p++) - if (memcmp(p, "GenuineLguest", strlen("GenuineLguest")) == 0) - return to_guest_phys(p + strlen("GenuineLguest")); - - errx(1, "Is this image a genuine lguest?"); -} - /* This routine is used to load the kernel or initrd. It tries mmap, but if * that fails (Plan 9's kernel file isn't nicely aligned on page boundaries), * 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) * We return the starting address. */ static unsigned long map_elf(int elf_fd, const Elf32_Ehdr *ehdr) { - void *start = (void *)-1, *end = NULL; Elf32_Phdr phdr[ehdr->e_phnum]; unsigned int i; @@ -335,19 +317,13 @@ static unsigned long map_elf(int elf_fd, const Elf32_Ehdr *ehdr) verbose("Section %i: size %i addr %p\n", i, phdr[i].p_memsz, (void *)phdr[i].p_paddr); - /* We track the first and last address we mapped, so we can - * tell entry_point() where to scan. */ - if (from_guest_phys(phdr[i].p_paddr) < start) - start = from_guest_phys(phdr[i].p_paddr); - if (from_guest_phys(phdr[i].p_paddr) + phdr[i].p_filesz > end) - end=from_guest_phys(phdr[i].p_paddr)+phdr[i].p_filesz; - /* We map this section of the file at its physical address. */ map_at(elf_fd, from_guest_phys(phdr[i].p_paddr), phdr[i].p_offset, phdr[i].p_filesz); } - return entry_point(start, end); + /* The entry point is given in the ELF header. */ + return ehdr->e_entry; } /*L:160 Unfortunately the entire ELF image isn't compressed: the segments @@ -374,7 +350,8 @@ static unsigned long unpack_bzimage(int fd) verbose("Unpacked size %i addr %p\n", len, img); - return entry_point(img, img + len); + /* The entry point for a bzImage is always the first byte */ + return (unsigned long)img; } /*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[]) *(u32 *)(boot + 0x228) = 4096; concat(boot + 4096, argv+optind+2); - /* The guest type value of "1" tells the Guest it's under lguest. */ - *(int *)(boot + 0x23c) = 1; + /* Boot protocol version: 2.07 supports the fields for lguest. */ + *(u16 *)(boot + 0x206) = 0x207; + + /* The hardware_subarch value of "1" tells the Guest it's an lguest. */ + *(u32 *)(boot + 0x23c) = 1; + + /* Set bit 6 of the loadflags (aka. KEEP_SEGMENTS) so the entry path + * does not try to reload segment registers. */ + *(u8 *)(boot + 0x211) |= (1 << 6); /* We tell the kernel to initialize the Guest: this returns the open * /dev/lguest file descriptor. */ diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index 495e46a1f111..d2235db4085f 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, /*G:030 Once we get to lguest_init(), we know we're a Guest. The pv_ops * structures in the kernel provide points for (almost) every routine we have * to override to avoid privileged instructions. */ -__init void lguest_init(void *boot) +__init void lguest_init(void) { - /* Copy boot parameters first: the Launcher put the physical location - * in %esi, and head.S converted that to a virtual address and handed - * it to us. We use "__memcpy" because "memcpy" sometimes tries to do - * tricky things to go faster, and we're not ready for that. */ - __memcpy(&boot_params, boot, PARAM_SIZE); - /* The boot parameters also tell us where the command-line is: save - * that, too. */ - __memcpy(boot_command_line, __va(boot_params.hdr.cmd_line_ptr), - COMMAND_LINE_SIZE); - /* We're under lguest, paravirt is enabled, and we're running at * privilege level 1, not 0 as normal. */ pv_info.name = "lguest"; @@ -1024,11 +1014,6 @@ __init void lguest_init(void *boot) * the normal data segment to get through booting. */ asm volatile ("mov %0, %%fs" : : "r" (__KERNEL_DS) : "memory"); - /* Clear the part of the kernel data which is expected to be zero. - * Normally it will be anyway, but if we're loading from a bzImage with - * CONFIG_RELOCATALE=y, the relocations will be sitting here. */ - memset(__bss_start, 0, __bss_stop - __bss_start); - /* The Host uses the top of the Guest's virtual address space for the * Host<->Guest Switcher, and it tells us how much it needs in * 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 ba4282eba5bf..ebc6ac733899 100644 --- a/arch/x86/lguest/i386_head.S +++ b/arch/x86/lguest/i386_head.S @@ -5,11 +5,8 @@ #include #include -/*G:020 This is where we begin: we have a magic signature which the launcher - * looks for. The plan is that the Linux boot protocol will be extended with a - * "platform type" field which will guide us here from the normal entry point, - * but for the moment this suffices. The normal boot code uses %esi for the - * boot header, so we do too. +/*G:020 This is where we begin: head.S notes that the boot header's platform + * type field is "1" (lguest), so calls us here. The boot header is in %esi. * * WARNING: be very careful here! We're running at addresses equal to physical * addesses (around 0), not above PAGE_OFFSET as most code expectes @@ -19,19 +16,14 @@ * The .section line puts this code in .init.text so it will be discarded after * boot. */ .section .init.text, "ax", @progbits -.ascii "GenuineLguest" +ENTRY(lguest_entry) /* Make initial hypercall now, so we can set up the pagetables. */ movl $LHCALL_LGUEST_INIT, %eax movl $lguest_data - __PAGE_OFFSET, %edx int $LGUEST_TRAP_ENTRY - /* Set up boot information pointer to hand to lguest_init(): it wants - * a virtual address. */ - movl %esi, %eax - addl $__PAGE_OFFSET, %eax - /* The Host put the toplevel pagetable in lguest_data.pgdir. The movsl - * instruction uses %esi, so we needed to save it above. */ + * instruction uses %esi implicitly. */ movl lguest_data - __PAGE_OFFSET + LGUEST_DATA_pgdir, %esi /* Copy first 32 entries of page directory to __PAGE_OFFSET entries. @@ -47,7 +39,6 @@ /* Set up the initial stack so we can run C code. */ movl $(init_thread_union+THREAD_SIZE),%esp - /* Jumps are relative, and we're running __PAGE_OFFSET too low at the * moment. */ jmp lguest_init+__PAGE_OFFSET