aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/lguest/lguest.c73
-rw-r--r--Documentation/lguest/lguest.txt5
-rw-r--r--arch/x86/lguest/Kconfig1
-rw-r--r--arch/x86/lguest/boot.c2
-rw-r--r--drivers/lguest/page_tables.c2
-rw-r--r--drivers/lguest/x86/core.c4
-rw-r--r--drivers/virtio/virtio_pci.c20
7 files changed, 77 insertions, 30 deletions
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c
index dc73bc54cc4e..d9da7e148538 100644
--- a/Documentation/lguest/lguest.c
+++ b/Documentation/lguest/lguest.c
@@ -39,6 +39,9 @@
39#include <limits.h> 39#include <limits.h>
40#include <stddef.h> 40#include <stddef.h>
41#include <signal.h> 41#include <signal.h>
42#include <pwd.h>
43#include <grp.h>
44
42#include <linux/virtio_config.h> 45#include <linux/virtio_config.h>
43#include <linux/virtio_net.h> 46#include <linux/virtio_net.h>
44#include <linux/virtio_blk.h> 47#include <linux/virtio_blk.h>
@@ -298,20 +301,27 @@ static void *map_zeroed_pages(unsigned int num)
298 301
299 /* 302 /*
300 * We use a private mapping (ie. if we write to the page, it will be 303 * We use a private mapping (ie. if we write to the page, it will be
301 * copied). 304 * copied). We allocate an extra two pages PROT_NONE to act as guard
305 * pages against read/write attempts that exceed allocated space.
302 */ 306 */
303 addr = mmap(NULL, getpagesize() * num, 307 addr = mmap(NULL, getpagesize() * (num+2),
304 PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, fd, 0); 308 PROT_NONE, MAP_PRIVATE, fd, 0);
309
305 if (addr == MAP_FAILED) 310 if (addr == MAP_FAILED)
306 err(1, "Mmapping %u pages of /dev/zero", num); 311 err(1, "Mmapping %u pages of /dev/zero", num);
307 312
313 if (mprotect(addr + getpagesize(), getpagesize() * num,
314 PROT_READ|PROT_WRITE) == -1)
315 err(1, "mprotect rw %u pages failed", num);
316
308 /* 317 /*
309 * One neat mmap feature is that you can close the fd, and it 318 * One neat mmap feature is that you can close the fd, and it
310 * stays mapped. 319 * stays mapped.
311 */ 320 */
312 close(fd); 321 close(fd);
313 322
314 return addr; 323 /* Return address after PROT_NONE page */
324 return addr + getpagesize();
315} 325}
316 326
317/* Get some more pages for a device. */ 327/* Get some more pages for a device. */
@@ -343,7 +353,7 @@ static void map_at(int fd, void *addr, unsigned long offset, unsigned long len)
343 * done to it. This allows us to share untouched memory between 353 * done to it. This allows us to share untouched memory between
344 * Guests. 354 * Guests.
345 */ 355 */
346 if (mmap(addr, len, PROT_READ|PROT_WRITE|PROT_EXEC, 356 if (mmap(addr, len, PROT_READ|PROT_WRITE,
347 MAP_FIXED|MAP_PRIVATE, fd, offset) != MAP_FAILED) 357 MAP_FIXED|MAP_PRIVATE, fd, offset) != MAP_FAILED)
348 return; 358 return;
349 359
@@ -573,10 +583,10 @@ static void *_check_pointer(unsigned long addr, unsigned int size,
573 unsigned int line) 583 unsigned int line)
574{ 584{
575 /* 585 /*
576 * We have to separately check addr and addr+size, because size could 586 * Check if the requested address and size exceeds the allocated memory,
577 * be huge and addr + size might wrap around. 587 * or addr + size wraps around.
578 */ 588 */
579 if (addr >= guest_limit || addr + size >= guest_limit) 589 if ((addr + size) > guest_limit || (addr + size) < addr)
580 errx(1, "%s:%i: Invalid address %#lx", __FILE__, line, addr); 590 errx(1, "%s:%i: Invalid address %#lx", __FILE__, line, addr);
581 /* 591 /*
582 * We return a pointer for the caller's convenience, now we know it's 592 * We return a pointer for the caller's convenience, now we know it's
@@ -1872,6 +1882,8 @@ static struct option opts[] = {
1872 { "block", 1, NULL, 'b' }, 1882 { "block", 1, NULL, 'b' },
1873 { "rng", 0, NULL, 'r' }, 1883 { "rng", 0, NULL, 'r' },
1874 { "initrd", 1, NULL, 'i' }, 1884 { "initrd", 1, NULL, 'i' },
1885 { "username", 1, NULL, 'u' },
1886 { "chroot", 1, NULL, 'c' },
1875 { NULL }, 1887 { NULL },
1876}; 1888};
1877static void usage(void) 1889static void usage(void)
@@ -1894,6 +1906,12 @@ int main(int argc, char *argv[])
1894 /* If they specify an initrd file to load. */ 1906 /* If they specify an initrd file to load. */
1895 const char *initrd_name = NULL; 1907 const char *initrd_name = NULL;
1896 1908
1909 /* Password structure for initgroups/setres[gu]id */
1910 struct passwd *user_details = NULL;
1911
1912 /* Directory to chroot to */
1913 char *chroot_path = NULL;
1914
1897 /* Save the args: we "reboot" by execing ourselves again. */ 1915 /* Save the args: we "reboot" by execing ourselves again. */
1898 main_args = argv; 1916 main_args = argv;
1899 1917
@@ -1950,6 +1968,14 @@ int main(int argc, char *argv[])
1950 case 'i': 1968 case 'i':
1951 initrd_name = optarg; 1969 initrd_name = optarg;
1952 break; 1970 break;
1971 case 'u':
1972 user_details = getpwnam(optarg);
1973 if (!user_details)
1974 err(1, "getpwnam failed, incorrect username?");
1975 break;
1976 case 'c':
1977 chroot_path = optarg;
1978 break;
1953 default: 1979 default:
1954 warnx("Unknown argument %s", argv[optind]); 1980 warnx("Unknown argument %s", argv[optind]);
1955 usage(); 1981 usage();
@@ -2021,6 +2047,37 @@ int main(int argc, char *argv[])
2021 /* If we exit via err(), this kills all the threads, restores tty. */ 2047 /* If we exit via err(), this kills all the threads, restores tty. */
2022 atexit(cleanup_devices); 2048 atexit(cleanup_devices);
2023 2049
2050 /* If requested, chroot to a directory */
2051 if (chroot_path) {
2052 if (chroot(chroot_path) != 0)
2053 err(1, "chroot(\"%s\") failed", chroot_path);
2054
2055 if (chdir("/") != 0)
2056 err(1, "chdir(\"/\") failed");
2057
2058 verbose("chroot done\n");
2059 }
2060
2061 /* If requested, drop privileges */
2062 if (user_details) {
2063 uid_t u;
2064 gid_t g;
2065
2066 u = user_details->pw_uid;
2067 g = user_details->pw_gid;
2068
2069 if (initgroups(user_details->pw_name, g) != 0)
2070 err(1, "initgroups failed");
2071
2072 if (setresgid(g, g, g) != 0)
2073 err(1, "setresgid failed");
2074
2075 if (setresuid(u, u, u) != 0)
2076 err(1, "setresuid failed");
2077
2078 verbose("Dropping privileges completed\n");
2079 }
2080
2024 /* Finally, run the Guest. This doesn't return. */ 2081 /* Finally, run the Guest. This doesn't return. */
2025 run_guest(); 2082 run_guest();
2026} 2083}
diff --git a/Documentation/lguest/lguest.txt b/Documentation/lguest/lguest.txt
index 6ccaf8e1a00e..dad99978a6a8 100644
--- a/Documentation/lguest/lguest.txt
+++ b/Documentation/lguest/lguest.txt
@@ -117,6 +117,11 @@ Running Lguest:
117 117
118 for general information on how to get bridging to work. 118 for general information on how to get bridging to work.
119 119
120- Random number generation. Using the --rng option will provide a
121 /dev/hwrng in the guest that will read from the host's /dev/random.
122 Use this option in conjunction with rng-tools (see ../hw_random.txt)
123 to provide entropy to the guest kernel's /dev/random.
124
120There is a helpful mailing list at http://ozlabs.org/mailman/listinfo/lguest 125There is a helpful mailing list at http://ozlabs.org/mailman/listinfo/lguest
121 126
122Good luck! 127Good luck!
diff --git a/arch/x86/lguest/Kconfig b/arch/x86/lguest/Kconfig
index 38718041efc3..6e121a2a49e1 100644
--- a/arch/x86/lguest/Kconfig
+++ b/arch/x86/lguest/Kconfig
@@ -2,6 +2,7 @@ config LGUEST_GUEST
2 bool "Lguest guest support" 2 bool "Lguest guest support"
3 select PARAVIRT 3 select PARAVIRT
4 depends on X86_32 4 depends on X86_32
5 select VIRTUALIZATION
5 select VIRTIO 6 select VIRTIO
6 select VIRTIO_RING 7 select VIRTIO_RING
7 select VIRTIO_CONSOLE 8 select VIRTIO_CONSOLE
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
index 4996cf5f73a0..eba687f0cc0c 100644
--- a/arch/x86/lguest/boot.c
+++ b/arch/x86/lguest/boot.c
@@ -824,7 +824,7 @@ static void __init lguest_init_IRQ(void)
824 824
825 for (i = FIRST_EXTERNAL_VECTOR; i < NR_VECTORS; i++) { 825 for (i = FIRST_EXTERNAL_VECTOR; i < NR_VECTORS; i++) {
826 /* Some systems map "vectors" to interrupts weirdly. Not us! */ 826 /* Some systems map "vectors" to interrupts weirdly. Not us! */
827 __get_cpu_var(vector_irq)[i] = i - FIRST_EXTERNAL_VECTOR; 827 __this_cpu_write(vector_irq[i], i - FIRST_EXTERNAL_VECTOR);
828 if (i != SYSCALL_VECTOR) 828 if (i != SYSCALL_VECTOR)
829 set_intr_gate(i, interrupt[i - FIRST_EXTERNAL_VECTOR]); 829 set_intr_gate(i, interrupt[i - FIRST_EXTERNAL_VECTOR]);
830 } 830 }
diff --git a/drivers/lguest/page_tables.c b/drivers/lguest/page_tables.c
index 04b22128a474..d21578ee95de 100644
--- a/drivers/lguest/page_tables.c
+++ b/drivers/lguest/page_tables.c
@@ -1137,7 +1137,7 @@ void free_guest_pagetable(struct lguest *lg)
1137 */ 1137 */
1138void map_switcher_in_guest(struct lg_cpu *cpu, struct lguest_pages *pages) 1138void map_switcher_in_guest(struct lg_cpu *cpu, struct lguest_pages *pages)
1139{ 1139{
1140 pte_t *switcher_pte_page = __get_cpu_var(switcher_pte_pages); 1140 pte_t *switcher_pte_page = __this_cpu_read(switcher_pte_pages);
1141 pte_t regs_pte; 1141 pte_t regs_pte;
1142 1142
1143#ifdef CONFIG_X86_PAE 1143#ifdef CONFIG_X86_PAE
diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
index b4eb675a807e..9f1659c3d1f3 100644
--- a/drivers/lguest/x86/core.c
+++ b/drivers/lguest/x86/core.c
@@ -90,8 +90,8 @@ static void copy_in_guest_info(struct lg_cpu *cpu, struct lguest_pages *pages)
90 * meanwhile). If that's not the case, we pretend everything in the 90 * meanwhile). If that's not the case, we pretend everything in the
91 * Guest has changed. 91 * Guest has changed.
92 */ 92 */
93 if (__get_cpu_var(lg_last_cpu) != cpu || cpu->last_pages != pages) { 93 if (__this_cpu_read(lg_last_cpu) != cpu || cpu->last_pages != pages) {
94 __get_cpu_var(lg_last_cpu) = cpu; 94 __this_cpu_write(lg_last_cpu, cpu);
95 cpu->last_pages = pages; 95 cpu->last_pages = pages;
96 cpu->changed = CHANGED_ALL; 96 cpu->changed = CHANGED_ALL;
97 } 97 }
diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c
index ef8d9d558fc7..4fb5b2bf2348 100644
--- a/drivers/virtio/virtio_pci.c
+++ b/drivers/virtio/virtio_pci.c
@@ -96,11 +96,6 @@ static struct pci_device_id virtio_pci_id_table[] = {
96 96
97MODULE_DEVICE_TABLE(pci, virtio_pci_id_table); 97MODULE_DEVICE_TABLE(pci, virtio_pci_id_table);
98 98
99/* A PCI device has it's own struct device and so does a virtio device so
100 * we create a place for the virtio devices to show up in sysfs. I think it
101 * would make more sense for virtio to not insist on having it's own device. */
102static struct device *virtio_pci_root;
103
104/* Convert a generic virtio device to our structure */ 99/* Convert a generic virtio device to our structure */
105static struct virtio_pci_device *to_vp_device(struct virtio_device *vdev) 100static struct virtio_pci_device *to_vp_device(struct virtio_device *vdev)
106{ 101{
@@ -629,7 +624,7 @@ static int __devinit virtio_pci_probe(struct pci_dev *pci_dev,
629 if (vp_dev == NULL) 624 if (vp_dev == NULL)
630 return -ENOMEM; 625 return -ENOMEM;
631 626
632 vp_dev->vdev.dev.parent = virtio_pci_root; 627 vp_dev->vdev.dev.parent = &pci_dev->dev;
633 vp_dev->vdev.dev.release = virtio_pci_release_dev; 628 vp_dev->vdev.dev.release = virtio_pci_release_dev;
634 vp_dev->vdev.config = &virtio_pci_config_ops; 629 vp_dev->vdev.config = &virtio_pci_config_ops;
635 vp_dev->pci_dev = pci_dev; 630 vp_dev->pci_dev = pci_dev;
@@ -717,17 +712,7 @@ static struct pci_driver virtio_pci_driver = {
717 712
718static int __init virtio_pci_init(void) 713static int __init virtio_pci_init(void)
719{ 714{
720 int err; 715 return pci_register_driver(&virtio_pci_driver);
721
722 virtio_pci_root = root_device_register("virtio-pci");
723 if (IS_ERR(virtio_pci_root))
724 return PTR_ERR(virtio_pci_root);
725
726 err = pci_register_driver(&virtio_pci_driver);
727 if (err)
728 root_device_unregister(virtio_pci_root);
729
730 return err;
731} 716}
732 717
733module_init(virtio_pci_init); 718module_init(virtio_pci_init);
@@ -735,7 +720,6 @@ module_init(virtio_pci_init);
735static void __exit virtio_pci_exit(void) 720static void __exit virtio_pci_exit(void)
736{ 721{
737 pci_unregister_driver(&virtio_pci_driver); 722 pci_unregister_driver(&virtio_pci_driver);
738 root_device_unregister(virtio_pci_root);
739} 723}
740 724
741module_exit(virtio_pci_exit); 725module_exit(virtio_pci_exit);