diff options
Diffstat (limited to 'Documentation/lguest/lguest.c')
| -rw-r--r-- | Documentation/lguest/lguest.c | 60 |
1 files changed, 6 insertions, 54 deletions
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c index aa2574ca94c7..f2dbbf3bdeab 100644 --- a/Documentation/lguest/lguest.c +++ b/Documentation/lguest/lguest.c | |||
| @@ -481,51 +481,6 @@ static unsigned long load_initrd(const char *name, unsigned long mem) | |||
| 481 | /* We return the initrd size. */ | 481 | /* We return the initrd size. */ |
| 482 | return len; | 482 | return len; |
| 483 | } | 483 | } |
| 484 | |||
| 485 | /* Once we know how much memory we have we can construct simple linear page | ||
| 486 | * tables which set virtual == physical which will get the Guest far enough | ||
| 487 | * into the boot to create its own. | ||
| 488 | * | ||
| 489 | * We lay them out of the way, just below the initrd (which is why we need to | ||
| 490 | * know its size here). */ | ||
| 491 | static unsigned long setup_pagetables(unsigned long mem, | ||
| 492 | unsigned long initrd_size) | ||
| 493 | { | ||
| 494 | unsigned long *pgdir, *linear; | ||
| 495 | unsigned int mapped_pages, i, linear_pages; | ||
| 496 | unsigned int ptes_per_page = getpagesize()/sizeof(void *); | ||
| 497 | |||
| 498 | mapped_pages = mem/getpagesize(); | ||
| 499 | |||
| 500 | /* Each PTE page can map ptes_per_page pages: how many do we need? */ | ||
| 501 | linear_pages = (mapped_pages + ptes_per_page-1)/ptes_per_page; | ||
| 502 | |||
| 503 | /* We put the toplevel page directory page at the top of memory. */ | ||
| 504 | pgdir = from_guest_phys(mem) - initrd_size - getpagesize(); | ||
| 505 | |||
| 506 | /* Now we use the next linear_pages pages as pte pages */ | ||
| 507 | linear = (void *)pgdir - linear_pages*getpagesize(); | ||
| 508 | |||
| 509 | /* Linear mapping is easy: put every page's address into the mapping in | ||
| 510 | * order. PAGE_PRESENT contains the flags Present, Writable and | ||
| 511 | * Executable. */ | ||
| 512 | for (i = 0; i < mapped_pages; i++) | ||
| 513 | linear[i] = ((i * getpagesize()) | PAGE_PRESENT); | ||
| 514 | |||
| 515 | /* The top level points to the linear page table pages above. */ | ||
| 516 | for (i = 0; i < mapped_pages; i += ptes_per_page) { | ||
| 517 | pgdir[i/ptes_per_page] | ||
| 518 | = ((to_guest_phys(linear) + i*sizeof(void *)) | ||
| 519 | | PAGE_PRESENT); | ||
| 520 | } | ||
| 521 | |||
| 522 | verbose("Linear mapping of %u pages in %u pte pages at %#lx\n", | ||
| 523 | mapped_pages, linear_pages, to_guest_phys(linear)); | ||
| 524 | |||
| 525 | /* We return the top level (guest-physical) address: the kernel needs | ||
| 526 | * to know where it is. */ | ||
| 527 | return to_guest_phys(pgdir); | ||
| 528 | } | ||
| 529 | /*:*/ | 484 | /*:*/ |
| 530 | 485 | ||
| 531 | /* Simple routine to roll all the commandline arguments together with spaces | 486 | /* Simple routine to roll all the commandline arguments together with spaces |
| @@ -548,13 +503,13 @@ static void concat(char *dst, char *args[]) | |||
| 548 | 503 | ||
| 549 | /*L:185 This is where we actually tell the kernel to initialize the Guest. We | 504 | /*L:185 This is where we actually tell the kernel to initialize the Guest. We |
| 550 | * saw the arguments it expects when we looked at initialize() in lguest_user.c: | 505 | * saw the arguments it expects when we looked at initialize() in lguest_user.c: |
| 551 | * the base of Guest "physical" memory, the top physical page to allow, the | 506 | * the base of Guest "physical" memory, the top physical page to allow and the |
| 552 | * top level pagetable and the entry point for the Guest. */ | 507 | * entry point for the Guest. */ |
| 553 | static int tell_kernel(unsigned long pgdir, unsigned long start) | 508 | static int tell_kernel(unsigned long start) |
| 554 | { | 509 | { |
| 555 | unsigned long args[] = { LHREQ_INITIALIZE, | 510 | unsigned long args[] = { LHREQ_INITIALIZE, |
| 556 | (unsigned long)guest_base, | 511 | (unsigned long)guest_base, |
| 557 | guest_limit / getpagesize(), pgdir, start }; | 512 | guest_limit / getpagesize(), start }; |
| 558 | int fd; | 513 | int fd; |
| 559 | 514 | ||
| 560 | verbose("Guest: %p - %p (%#lx)\n", | 515 | verbose("Guest: %p - %p (%#lx)\n", |
| @@ -1941,7 +1896,7 @@ int main(int argc, char *argv[]) | |||
| 1941 | { | 1896 | { |
| 1942 | /* Memory, top-level pagetable, code startpoint and size of the | 1897 | /* Memory, top-level pagetable, code startpoint and size of the |
| 1943 | * (optional) initrd. */ | 1898 | * (optional) initrd. */ |
| 1944 | unsigned long mem = 0, pgdir, start, initrd_size = 0; | 1899 | unsigned long mem = 0, start, initrd_size = 0; |
| 1945 | /* Two temporaries and the /dev/lguest file descriptor. */ | 1900 | /* Two temporaries and the /dev/lguest file descriptor. */ |
| 1946 | int i, c, lguest_fd; | 1901 | int i, c, lguest_fd; |
| 1947 | /* The boot information for the Guest. */ | 1902 | /* The boot information for the Guest. */ |
| @@ -2040,9 +1995,6 @@ int main(int argc, char *argv[]) | |||
| 2040 | boot->hdr.type_of_loader = 0xFF; | 1995 | boot->hdr.type_of_loader = 0xFF; |
| 2041 | } | 1996 | } |
| 2042 | 1997 | ||
| 2043 | /* Set up the initial linear pagetables, starting below the initrd. */ | ||
| 2044 | pgdir = setup_pagetables(mem, initrd_size); | ||
| 2045 | |||
| 2046 | /* The Linux boot header contains an "E820" memory map: ours is a | 1998 | /* The Linux boot header contains an "E820" memory map: ours is a |
| 2047 | * simple, single region. */ | 1999 | * simple, single region. */ |
| 2048 | boot->e820_entries = 1; | 2000 | boot->e820_entries = 1; |
| @@ -2064,7 +2016,7 @@ int main(int argc, char *argv[]) | |||
| 2064 | 2016 | ||
| 2065 | /* We tell the kernel to initialize the Guest: this returns the open | 2017 | /* We tell the kernel to initialize the Guest: this returns the open |
| 2066 | * /dev/lguest file descriptor. */ | 2018 | * /dev/lguest file descriptor. */ |
| 2067 | lguest_fd = tell_kernel(pgdir, start); | 2019 | lguest_fd = tell_kernel(start); |
| 2068 | 2020 | ||
| 2069 | /* We clone off a thread, which wakes the Launcher whenever one of the | 2021 | /* We clone off a thread, which wakes the Launcher whenever one of the |
| 2070 | * input file descriptors needs attention. We call this the Waker, and | 2022 | * input file descriptors needs attention. We call this the Waker, and |
