diff options
| -rw-r--r-- | Documentation/lguest/Makefile | 3 | ||||
| -rw-r--r-- | Documentation/lguest/lguest.c | 84 |
2 files changed, 35 insertions, 52 deletions
diff --git a/Documentation/lguest/Makefile b/Documentation/lguest/Makefile index b9b9427376e9..31e794ef5f98 100644 --- a/Documentation/lguest/Makefile +++ b/Documentation/lguest/Makefile | |||
| @@ -11,8 +11,7 @@ endif | |||
| 11 | include $(KBUILD_OUTPUT)/.config | 11 | include $(KBUILD_OUTPUT)/.config |
| 12 | LGUEST_GUEST_TOP := ($(CONFIG_PAGE_OFFSET) - 0x08000000) | 12 | LGUEST_GUEST_TOP := ($(CONFIG_PAGE_OFFSET) - 0x08000000) |
| 13 | 13 | ||
| 14 | CFLAGS:=-Wall -Wmissing-declarations -Wmissing-prototypes -O3 \ | 14 | CFLAGS:=-Wall -Wmissing-declarations -Wmissing-prototypes -O3 -Wl,-T,lguest.lds |
| 15 | -static -DLGUEST_GUEST_TOP="$(LGUEST_GUEST_TOP)" -Wl,-T,lguest.lds | ||
| 16 | LDLIBS:=-lz | 15 | LDLIBS:=-lz |
| 17 | 16 | ||
| 18 | all: lguest.lds lguest | 17 | all: lguest.lds lguest |
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c index 1432b502a2d9..62a8133393e1 100644 --- a/Documentation/lguest/lguest.c +++ b/Documentation/lguest/lguest.c | |||
| @@ -47,12 +47,14 @@ static bool verbose; | |||
| 47 | #define verbose(args...) \ | 47 | #define verbose(args...) \ |
| 48 | do { if (verbose) printf(args); } while(0) | 48 | do { if (verbose) printf(args); } while(0) |
| 49 | static int waker_fd; | 49 | static int waker_fd; |
| 50 | static u32 top; | ||
| 50 | 51 | ||
| 51 | struct device_list | 52 | struct device_list |
| 52 | { | 53 | { |
| 53 | fd_set infds; | 54 | fd_set infds; |
| 54 | int max_infd; | 55 | int max_infd; |
| 55 | 56 | ||
| 57 | struct lguest_device_desc *descs; | ||
| 56 | struct device *dev; | 58 | struct device *dev; |
| 57 | struct device **lastdev; | 59 | struct device **lastdev; |
| 58 | }; | 60 | }; |
| @@ -324,8 +326,7 @@ static void concat(char *dst, char *args[]) | |||
| 324 | static int tell_kernel(u32 pgdir, u32 start, u32 page_offset) | 326 | static int tell_kernel(u32 pgdir, u32 start, u32 page_offset) |
| 325 | { | 327 | { |
| 326 | u32 args[] = { LHREQ_INITIALIZE, | 328 | u32 args[] = { LHREQ_INITIALIZE, |
| 327 | LGUEST_GUEST_TOP/getpagesize(), /* Just below us */ | 329 | top/getpagesize(), pgdir, start, page_offset }; |
| 328 | pgdir, start, page_offset }; | ||
| 329 | int fd; | 330 | int fd; |
| 330 | 331 | ||
| 331 | fd = open_or_die("/dev/lguest", O_RDWR); | 332 | fd = open_or_die("/dev/lguest", O_RDWR); |
| @@ -382,7 +383,7 @@ static int setup_waker(int lguest_fd, struct device_list *device_list) | |||
| 382 | static void *_check_pointer(unsigned long addr, unsigned int size, | 383 | static void *_check_pointer(unsigned long addr, unsigned int size, |
| 383 | unsigned int line) | 384 | unsigned int line) |
| 384 | { | 385 | { |
| 385 | if (addr >= LGUEST_GUEST_TOP || addr + size >= LGUEST_GUEST_TOP) | 386 | if (addr >= top || addr + size >= top) |
| 386 | errx(1, "%s:%i: Invalid address %li", __FILE__, line, addr); | 387 | errx(1, "%s:%i: Invalid address %li", __FILE__, line, addr); |
| 387 | return (void *)addr; | 388 | return (void *)addr; |
| 388 | } | 389 | } |
| @@ -629,24 +630,26 @@ static void handle_input(int fd, struct device_list *devices) | |||
| 629 | } | 630 | } |
| 630 | } | 631 | } |
| 631 | 632 | ||
| 632 | static struct lguest_device_desc *new_dev_desc(u16 type, u16 features, | 633 | static struct lguest_device_desc * |
| 633 | u16 num_pages) | 634 | new_dev_desc(struct lguest_device_desc *descs, |
| 635 | u16 type, u16 features, u16 num_pages) | ||
| 634 | { | 636 | { |
| 635 | static unsigned long top = LGUEST_GUEST_TOP; | 637 | unsigned int i; |
| 636 | struct lguest_device_desc *desc; | ||
| 637 | 638 | ||
| 638 | desc = malloc(sizeof(*desc)); | 639 | for (i = 0; i < LGUEST_MAX_DEVICES; i++) { |
| 639 | desc->type = type; | 640 | if (!descs[i].type) { |
| 640 | desc->num_pages = num_pages; | 641 | descs[i].type = type; |
| 641 | desc->features = features; | 642 | descs[i].features = features; |
| 642 | desc->status = 0; | 643 | descs[i].num_pages = num_pages; |
| 643 | if (num_pages) { | 644 | if (num_pages) { |
| 644 | top -= num_pages*getpagesize(); | 645 | map_zeroed_pages(top, num_pages); |
| 645 | map_zeroed_pages(top, num_pages); | 646 | descs[i].pfn = top/getpagesize(); |
| 646 | desc->pfn = top / getpagesize(); | 647 | top += num_pages*getpagesize(); |
| 647 | } else | 648 | } |
| 648 | desc->pfn = 0; | 649 | return &descs[i]; |
| 649 | return desc; | 650 | } |
| 651 | } | ||
| 652 | errx(1, "too many devices"); | ||
| 650 | } | 653 | } |
| 651 | 654 | ||
| 652 | static struct device *new_device(struct device_list *devices, | 655 | static struct device *new_device(struct device_list *devices, |
| @@ -669,7 +672,7 @@ static struct device *new_device(struct device_list *devices, | |||
| 669 | dev->fd = fd; | 672 | dev->fd = fd; |
| 670 | if (handle_input) | 673 | if (handle_input) |
| 671 | set_fd(dev->fd, devices); | 674 | set_fd(dev->fd, devices); |
| 672 | dev->desc = new_dev_desc(type, features, num_pages); | 675 | dev->desc = new_dev_desc(devices->descs, type, features, num_pages); |
| 673 | dev->mem = (void *)(dev->desc->pfn * getpagesize()); | 676 | dev->mem = (void *)(dev->desc->pfn * getpagesize()); |
| 674 | dev->handle_input = handle_input; | 677 | dev->handle_input = handle_input; |
| 675 | dev->watch_key = (unsigned long)dev->mem + watch_off; | 678 | dev->watch_key = (unsigned long)dev->mem + watch_off; |
| @@ -866,30 +869,6 @@ static void setup_tun_net(const char *arg, struct device_list *devices) | |||
| 866 | verbose("attached to bridge: %s\n", br_name); | 869 | verbose("attached to bridge: %s\n", br_name); |
| 867 | } | 870 | } |
| 868 | 871 | ||
| 869 | /* Now we know how much memory we have, we copy in device descriptors */ | ||
| 870 | static void map_device_descriptors(struct device_list *devs, unsigned long mem) | ||
| 871 | { | ||
| 872 | struct device *i; | ||
| 873 | unsigned int num; | ||
| 874 | struct lguest_device_desc *descs; | ||
| 875 | |||
| 876 | /* Device descriptor array sits just above top of normal memory */ | ||
| 877 | descs = map_zeroed_pages(mem, 1); | ||
| 878 | |||
| 879 | for (i = devs->dev, num = 0; i; i = i->next, num++) { | ||
| 880 | if (num == LGUEST_MAX_DEVICES) | ||
| 881 | errx(1, "too many devices"); | ||
| 882 | verbose("Device %i: %s\n", num, | ||
| 883 | i->desc->type == LGUEST_DEVICE_T_NET ? "net" | ||
| 884 | : i->desc->type == LGUEST_DEVICE_T_CONSOLE ? "console" | ||
| 885 | : i->desc->type == LGUEST_DEVICE_T_BLOCK ? "block" | ||
| 886 | : "unknown"); | ||
| 887 | descs[num] = *i->desc; | ||
| 888 | free(i->desc); | ||
| 889 | i->desc = &descs[num]; | ||
| 890 | } | ||
| 891 | } | ||
| 892 | |||
| 893 | static void __attribute__((noreturn)) | 872 | static void __attribute__((noreturn)) |
| 894 | run_guest(int lguest_fd, struct device_list *device_list) | 873 | run_guest(int lguest_fd, struct device_list *device_list) |
| 895 | { | 874 | { |
| @@ -934,8 +913,8 @@ static void usage(void) | |||
| 934 | 913 | ||
| 935 | int main(int argc, char *argv[]) | 914 | int main(int argc, char *argv[]) |
| 936 | { | 915 | { |
| 937 | unsigned long mem, pgdir, start, page_offset, initrd_size = 0; | 916 | unsigned long mem = 0, pgdir, start, page_offset, initrd_size = 0; |
| 938 | int c, lguest_fd; | 917 | int i, c, lguest_fd; |
| 939 | struct device_list device_list; | 918 | struct device_list device_list; |
| 940 | void *boot = (void *)0; | 919 | void *boot = (void *)0; |
| 941 | const char *initrd_name = NULL; | 920 | const char *initrd_name = NULL; |
| @@ -945,6 +924,15 @@ int main(int argc, char *argv[]) | |||
| 945 | device_list.lastdev = &device_list.dev; | 924 | device_list.lastdev = &device_list.dev; |
| 946 | FD_ZERO(&device_list.infds); | 925 | FD_ZERO(&device_list.infds); |
| 947 | 926 | ||
| 927 | /* We need to know how much memory so we can allocate devices. */ | ||
| 928 | for (i = 1; i < argc; i++) { | ||
| 929 | if (argv[i][0] != '-') { | ||
| 930 | mem = top = atoi(argv[i]) * 1024 * 1024; | ||
| 931 | device_list.descs = map_zeroed_pages(top, 1); | ||
| 932 | top += getpagesize(); | ||
| 933 | break; | ||
| 934 | } | ||
| 935 | } | ||
| 948 | while ((c = getopt_long(argc, argv, "v", opts, NULL)) != EOF) { | 936 | while ((c = getopt_long(argc, argv, "v", opts, NULL)) != EOF) { |
| 949 | switch (c) { | 937 | switch (c) { |
| 950 | case 'v': | 938 | case 'v': |
| @@ -974,16 +962,12 @@ int main(int argc, char *argv[]) | |||
| 974 | setup_console(&device_list); | 962 | setup_console(&device_list); |
| 975 | 963 | ||
| 976 | /* First we map /dev/zero over all of guest-physical memory. */ | 964 | /* First we map /dev/zero over all of guest-physical memory. */ |
| 977 | mem = atoi(argv[optind]) * 1024 * 1024; | ||
| 978 | map_zeroed_pages(0, mem / getpagesize()); | 965 | map_zeroed_pages(0, mem / getpagesize()); |
| 979 | 966 | ||
| 980 | /* Now we load the kernel */ | 967 | /* Now we load the kernel */ |
| 981 | start = load_kernel(open_or_die(argv[optind+1], O_RDONLY), | 968 | start = load_kernel(open_or_die(argv[optind+1], O_RDONLY), |
| 982 | &page_offset); | 969 | &page_offset); |
| 983 | 970 | ||
| 984 | /* Write the device descriptors into memory. */ | ||
| 985 | map_device_descriptors(&device_list, mem); | ||
| 986 | |||
| 987 | /* Map the initrd image if requested */ | 971 | /* Map the initrd image if requested */ |
| 988 | if (initrd_name) { | 972 | if (initrd_name) { |
| 989 | initrd_size = load_initrd(initrd_name, mem); | 973 | initrd_size = load_initrd(initrd_name, mem); |
