aboutsummaryrefslogtreecommitdiffstats
path: root/tools/lguest/lguest.c
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2015-02-10 23:45:11 -0500
committerRusty Russell <rusty@rustcorp.com.au>2015-02-11 01:17:35 -0500
commit0a6bcc183f5377eca07cbf0cf6f4b6cb00e4c1ec (patch)
tree3b6ba800b0672d2d9b855133d1320ae2b67bc72d /tools/lguest/lguest.c
parente1b83e27881cf3153ce420aea853797fed29a9ea (diff)
lguest: add MMIO region allocator in example launcher.
This is where we point our PCI BARs, so that we can intercept MMIO accesses. We tell the kernel about it so any faults in this area are directed to us. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'tools/lguest/lguest.c')
-rw-r--r--tools/lguest/lguest.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/tools/lguest/lguest.c b/tools/lguest/lguest.c
index 02f353989e6c..35d7aa90aa24 100644
--- a/tools/lguest/lguest.c
+++ b/tools/lguest/lguest.c
@@ -92,7 +92,7 @@ static bool verbose;
92/* The pointer to the start of guest memory. */ 92/* The pointer to the start of guest memory. */
93static void *guest_base; 93static void *guest_base;
94/* The maximum guest physical address allowed, and maximum possible. */ 94/* The maximum guest physical address allowed, and maximum possible. */
95static unsigned long guest_limit, guest_max; 95static unsigned long guest_limit, guest_max, guest_mmio;
96/* The /dev/lguest file descriptor. */ 96/* The /dev/lguest file descriptor. */
97static int lguest_fd; 97static int lguest_fd;
98 98
@@ -321,6 +321,23 @@ static void *get_pages(unsigned int num)
321 return addr; 321 return addr;
322} 322}
323 323
324/* Get some bytes which won't be mapped into the guest. */
325static unsigned long get_mmio_region(size_t size)
326{
327 unsigned long addr = guest_mmio;
328 size_t i;
329
330 if (!size)
331 return addr;
332
333 /* Size has to be a power of 2 (and multiple of 16) */
334 for (i = 1; i < size; i <<= 1);
335
336 guest_mmio += i;
337
338 return addr;
339}
340
324/* 341/*
325 * This routine is used to load the kernel or initrd. It tries mmap, but if 342 * This routine is used to load the kernel or initrd. It tries mmap, but if
326 * that fails (Plan 9's kernel file isn't nicely aligned on page boundaries), 343 * that fails (Plan 9's kernel file isn't nicely aligned on page boundaries),
@@ -549,9 +566,10 @@ static void tell_kernel(unsigned long start)
549 unsigned long args[] = { LHREQ_INITIALIZE, 566 unsigned long args[] = { LHREQ_INITIALIZE,
550 (unsigned long)guest_base, 567 (unsigned long)guest_base,
551 guest_limit / getpagesize(), start, 568 guest_limit / getpagesize(), start,
552 guest_limit / getpagesize() }; 569 (guest_mmio+getpagesize()-1) / getpagesize() };
553 verbose("Guest: %p - %p (%#lx)\n", 570 verbose("Guest: %p - %p (%#lx, MMIO %#lx)\n",
554 guest_base, guest_base + guest_limit, guest_limit); 571 guest_base, guest_base + guest_limit,
572 guest_limit, guest_mmio);
555 lguest_fd = open_or_die("/dev/lguest", O_RDWR); 573 lguest_fd = open_or_die("/dev/lguest", O_RDWR);
556 if (write(lguest_fd, args, sizeof(args)) < 0) 574 if (write(lguest_fd, args, sizeof(args)) < 0)
557 err(1, "Writing to /dev/lguest"); 575 err(1, "Writing to /dev/lguest");
@@ -2079,7 +2097,7 @@ int main(int argc, char *argv[])
2079 guest_base = map_zeroed_pages(mem / getpagesize() 2097 guest_base = map_zeroed_pages(mem / getpagesize()
2080 + DEVICE_PAGES); 2098 + DEVICE_PAGES);
2081 guest_limit = mem; 2099 guest_limit = mem;
2082 guest_max = mem + DEVICE_PAGES*getpagesize(); 2100 guest_max = guest_mmio = mem + DEVICE_PAGES*getpagesize();
2083 devices.descpage = get_pages(1); 2101 devices.descpage = get_pages(1);
2084 break; 2102 break;
2085 } 2103 }