aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation/lguest/lguest.c
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation/lguest/lguest.c')
-rw-r--r--Documentation/lguest/lguest.c66
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). */
491static 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. */
553static int tell_kernel(unsigned long pgdir, unsigned long start) 508static 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