diff options
Diffstat (limited to 'Documentation/lguest/lguest.c')
-rw-r--r-- | Documentation/lguest/lguest.c | 66 |
1 files changed, 9 insertions, 57 deletions
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c index 804520633fcf..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", |
@@ -1030,7 +985,7 @@ static void update_device_status(struct device *dev) | |||
1030 | /* Zero out the virtqueues. */ | 985 | /* Zero out the virtqueues. */ |
1031 | for (vq = dev->vq; vq; vq = vq->next) { | 986 | for (vq = dev->vq; vq; vq = vq->next) { |
1032 | memset(vq->vring.desc, 0, | 987 | memset(vq->vring.desc, 0, |
1033 | vring_size(vq->config.num, getpagesize())); | 988 | vring_size(vq->config.num, LGUEST_VRING_ALIGN)); |
1034 | lg_last_avail(vq) = 0; | 989 | lg_last_avail(vq) = 0; |
1035 | } | 990 | } |
1036 | } else if (dev->desc->status & VIRTIO_CONFIG_S_FAILED) { | 991 | } else if (dev->desc->status & VIRTIO_CONFIG_S_FAILED) { |
@@ -1211,7 +1166,7 @@ static void add_virtqueue(struct device *dev, unsigned int num_descs, | |||
1211 | void *p; | 1166 | void *p; |
1212 | 1167 | ||
1213 | /* First we need some memory for this virtqueue. */ | 1168 | /* First we need some memory for this virtqueue. */ |
1214 | pages = (vring_size(num_descs, getpagesize()) + getpagesize() - 1) | 1169 | pages = (vring_size(num_descs, LGUEST_VRING_ALIGN) + getpagesize() - 1) |
1215 | / getpagesize(); | 1170 | / getpagesize(); |
1216 | p = get_pages(pages); | 1171 | p = get_pages(pages); |
1217 | 1172 | ||
@@ -1228,7 +1183,7 @@ static void add_virtqueue(struct device *dev, unsigned int num_descs, | |||
1228 | vq->config.pfn = to_guest_phys(p) / getpagesize(); | 1183 | vq->config.pfn = to_guest_phys(p) / getpagesize(); |
1229 | 1184 | ||
1230 | /* Initialize the vring. */ | 1185 | /* Initialize the vring. */ |
1231 | vring_init(&vq->vring, num_descs, p, getpagesize()); | 1186 | vring_init(&vq->vring, num_descs, p, LGUEST_VRING_ALIGN); |
1232 | 1187 | ||
1233 | /* Append virtqueue to this device's descriptor. We use | 1188 | /* Append virtqueue to this device's descriptor. We use |
1234 | * device_config() to get the end of the device's current virtqueues; | 1189 | * device_config() to get the end of the device's current virtqueues; |
@@ -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 |