diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2015-02-10 23:45:11 -0500 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2015-02-11 01:17:35 -0500 |
commit | 0a6bcc183f5377eca07cbf0cf6f4b6cb00e4c1ec (patch) | |
tree | 3b6ba800b0672d2d9b855133d1320ae2b67bc72d /tools/lguest/lguest.c | |
parent | e1b83e27881cf3153ce420aea853797fed29a9ea (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.c | 28 |
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. */ |
93 | static void *guest_base; | 93 | static void *guest_base; |
94 | /* The maximum guest physical address allowed, and maximum possible. */ | 94 | /* The maximum guest physical address allowed, and maximum possible. */ |
95 | static unsigned long guest_limit, guest_max; | 95 | static unsigned long guest_limit, guest_max, guest_mmio; |
96 | /* The /dev/lguest file descriptor. */ | 96 | /* The /dev/lguest file descriptor. */ |
97 | static int lguest_fd; | 97 | static 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. */ | ||
325 | static 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 | } |