diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-01-30 17:35:32 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-01-30 17:35:32 -0500 |
| commit | d145c7253c8cb2ed8a75a8839621b0bb8f778820 (patch) | |
| tree | fac21920d149a2cddfdfbde65066ff98935a9c57 | |
| parent | 44c3b59102e3ecc7a01e9811862633e670595e51 (diff) | |
| parent | 84f12e39c856a8b1ab407f8216ecebaf4204b94d (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus
* git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus: (27 commits)
lguest: use __PAGE_KERNEL instead of _PAGE_KERNEL
lguest: Use explicit includes rateher than indirect
lguest: get rid of lg variable assignments
lguest: change gpte_addr header
lguest: move changed bitmap to lg_cpu
lguest: move last_pages to lg_cpu
lguest: change last_guest to last_cpu
lguest: change spte_addr header
lguest: per-vcpu lguest pgdir management
lguest: make pending notifications per-vcpu
lguest: makes special fields be per-vcpu
lguest: per-vcpu lguest task management
lguest: replace lguest_arch with lg_cpu_arch.
lguest: make registers per-vcpu
lguest: make emulate_insn receive a vcpu struct.
lguest: map_switcher_in_guest() per-vcpu
lguest: per-vcpu interrupt processing.
lguest: per-vcpu lguest timers
lguest: make hypercalls use the vcpu struct
lguest: make write() operation smp aware
...
Manual conflict resolved (maybe even correctly, who knows) in
drivers/lguest/x86/core.c
| -rw-r--r-- | Documentation/lguest/lguest.c | 49 | ||||
| -rw-r--r-- | arch/x86/lguest/boot.c | 11 | ||||
| -rw-r--r-- | drivers/Makefile | 2 | ||||
| -rw-r--r-- | drivers/lguest/core.c | 46 | ||||
| -rw-r--r-- | drivers/lguest/hypercalls.c | 106 | ||||
| -rw-r--r-- | drivers/lguest/interrupts_and_traps.c | 149 | ||||
| -rw-r--r-- | drivers/lguest/lg.h | 154 | ||||
| -rw-r--r-- | drivers/lguest/lguest_user.c | 147 | ||||
| -rw-r--r-- | drivers/lguest/page_tables.c | 179 | ||||
| -rw-r--r-- | drivers/lguest/segments.c | 48 | ||||
| -rw-r--r-- | drivers/lguest/x86/core.c | 127 | ||||
| -rw-r--r-- | include/asm-x86/lguest.h | 2 | ||||
| -rw-r--r-- | include/asm-x86/lguest_hcall.h | 6 |
13 files changed, 571 insertions, 455 deletions
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c index 9b0e322118b5..6c8a2386cd50 100644 --- a/Documentation/lguest/lguest.c +++ b/Documentation/lguest/lguest.c | |||
| @@ -79,6 +79,9 @@ static void *guest_base; | |||
| 79 | /* The maximum guest physical address allowed, and maximum possible. */ | 79 | /* The maximum guest physical address allowed, and maximum possible. */ |
| 80 | static unsigned long guest_limit, guest_max; | 80 | static unsigned long guest_limit, guest_max; |
| 81 | 81 | ||
| 82 | /* a per-cpu variable indicating whose vcpu is currently running */ | ||
| 83 | static unsigned int __thread cpu_id; | ||
| 84 | |||
| 82 | /* This is our list of devices. */ | 85 | /* This is our list of devices. */ |
| 83 | struct device_list | 86 | struct device_list |
| 84 | { | 87 | { |
| @@ -153,6 +156,9 @@ struct virtqueue | |||
| 153 | void (*handle_output)(int fd, struct virtqueue *me); | 156 | void (*handle_output)(int fd, struct virtqueue *me); |
| 154 | }; | 157 | }; |
| 155 | 158 | ||
| 159 | /* Remember the arguments to the program so we can "reboot" */ | ||
| 160 | static char **main_args; | ||
| 161 | |||
| 156 | /* Since guest is UP and we don't run at the same time, we don't need barriers. | 162 | /* Since guest is UP and we don't run at the same time, we don't need barriers. |
| 157 | * But I include them in the code in case others copy it. */ | 163 | * But I include them in the code in case others copy it. */ |
| 158 | #define wmb() | 164 | #define wmb() |
| @@ -554,7 +560,7 @@ static void wake_parent(int pipefd, int lguest_fd) | |||
| 554 | else | 560 | else |
| 555 | FD_CLR(-fd - 1, &devices.infds); | 561 | FD_CLR(-fd - 1, &devices.infds); |
| 556 | } else /* Send LHREQ_BREAK command. */ | 562 | } else /* Send LHREQ_BREAK command. */ |
| 557 | write(lguest_fd, args, sizeof(args)); | 563 | pwrite(lguest_fd, args, sizeof(args), cpu_id); |
| 558 | } | 564 | } |
| 559 | } | 565 | } |
| 560 | 566 | ||
| @@ -1489,7 +1495,9 @@ static void setup_block_file(const char *filename) | |||
| 1489 | 1495 | ||
| 1490 | /* Create stack for thread and run it */ | 1496 | /* Create stack for thread and run it */ |
| 1491 | stack = malloc(32768); | 1497 | stack = malloc(32768); |
| 1492 | if (clone(io_thread, stack + 32768, CLONE_VM, dev) == -1) | 1498 | /* SIGCHLD - We dont "wait" for our cloned thread, so prevent it from |
| 1499 | * becoming a zombie. */ | ||
| 1500 | if (clone(io_thread, stack + 32768, CLONE_VM | SIGCHLD, dev) == -1) | ||
| 1493 | err(1, "Creating clone"); | 1501 | err(1, "Creating clone"); |
| 1494 | 1502 | ||
| 1495 | /* We don't need to keep the I/O thread's end of the pipes open. */ | 1503 | /* We don't need to keep the I/O thread's end of the pipes open. */ |
| @@ -1499,7 +1507,21 @@ static void setup_block_file(const char *filename) | |||
| 1499 | verbose("device %u: virtblock %llu sectors\n", | 1507 | verbose("device %u: virtblock %llu sectors\n", |
| 1500 | devices.device_num, cap); | 1508 | devices.device_num, cap); |
| 1501 | } | 1509 | } |
| 1502 | /* That's the end of device setup. */ | 1510 | /* That's the end of device setup. :*/ |
| 1511 | |||
| 1512 | /* Reboot */ | ||
| 1513 | static void __attribute__((noreturn)) restart_guest(void) | ||
| 1514 | { | ||
| 1515 | unsigned int i; | ||
| 1516 | |||
| 1517 | /* Closing pipes causes the waker thread and io_threads to die, and | ||
| 1518 | * closing /dev/lguest cleans up the Guest. Since we don't track all | ||
| 1519 | * open fds, we simply close everything beyond stderr. */ | ||
| 1520 | for (i = 3; i < FD_SETSIZE; i++) | ||
| 1521 | close(i); | ||
| 1522 | execv(main_args[0], main_args); | ||
| 1523 | err(1, "Could not exec %s", main_args[0]); | ||
| 1524 | } | ||
| 1503 | 1525 | ||
| 1504 | /*L:220 Finally we reach the core of the Launcher, which runs the Guest, serves | 1526 | /*L:220 Finally we reach the core of the Launcher, which runs the Guest, serves |
| 1505 | * its input and output, and finally, lays it to rest. */ | 1527 | * its input and output, and finally, lays it to rest. */ |
| @@ -1511,7 +1533,8 @@ static void __attribute__((noreturn)) run_guest(int lguest_fd) | |||
| 1511 | int readval; | 1533 | int readval; |
| 1512 | 1534 | ||
| 1513 | /* We read from the /dev/lguest device to run the Guest. */ | 1535 | /* We read from the /dev/lguest device to run the Guest. */ |
| 1514 | readval = read(lguest_fd, ¬ify_addr, sizeof(notify_addr)); | 1536 | readval = pread(lguest_fd, ¬ify_addr, |
| 1537 | sizeof(notify_addr), cpu_id); | ||
| 1515 | 1538 | ||
| 1516 | /* One unsigned long means the Guest did HCALL_NOTIFY */ | 1539 | /* One unsigned long means the Guest did HCALL_NOTIFY */ |
| 1517 | if (readval == sizeof(notify_addr)) { | 1540 | if (readval == sizeof(notify_addr)) { |
| @@ -1521,16 +1544,23 @@ static void __attribute__((noreturn)) run_guest(int lguest_fd) | |||
| 1521 | /* ENOENT means the Guest died. Reading tells us why. */ | 1544 | /* ENOENT means the Guest died. Reading tells us why. */ |
| 1522 | } else if (errno == ENOENT) { | 1545 | } else if (errno == ENOENT) { |
| 1523 | char reason[1024] = { 0 }; | 1546 | char reason[1024] = { 0 }; |
| 1524 | read(lguest_fd, reason, sizeof(reason)-1); | 1547 | pread(lguest_fd, reason, sizeof(reason)-1, cpu_id); |
| 1525 | errx(1, "%s", reason); | 1548 | errx(1, "%s", reason); |
| 1549 | /* ERESTART means that we need to reboot the guest */ | ||
| 1550 | } else if (errno == ERESTART) { | ||
| 1551 | restart_guest(); | ||
| 1526 | /* EAGAIN means the Waker wanted us to look at some input. | 1552 | /* EAGAIN means the Waker wanted us to look at some input. |
| 1527 | * Anything else means a bug or incompatible change. */ | 1553 | * Anything else means a bug or incompatible change. */ |
| 1528 | } else if (errno != EAGAIN) | 1554 | } else if (errno != EAGAIN) |
| 1529 | err(1, "Running guest failed"); | 1555 | err(1, "Running guest failed"); |
| 1530 | 1556 | ||
| 1557 | /* Only service input on thread for CPU 0. */ | ||
| 1558 | if (cpu_id != 0) | ||
| 1559 | continue; | ||
| 1560 | |||
| 1531 | /* Service input, then unset the BREAK to release the Waker. */ | 1561 | /* Service input, then unset the BREAK to release the Waker. */ |
| 1532 | handle_input(lguest_fd); | 1562 | handle_input(lguest_fd); |
| 1533 | if (write(lguest_fd, args, sizeof(args)) < 0) | 1563 | if (pwrite(lguest_fd, args, sizeof(args), cpu_id) < 0) |
| 1534 | err(1, "Resetting break"); | 1564 | err(1, "Resetting break"); |
| 1535 | } | 1565 | } |
| 1536 | } | 1566 | } |
| @@ -1571,6 +1601,12 @@ int main(int argc, char *argv[]) | |||
| 1571 | /* If they specify an initrd file to load. */ | 1601 | /* If they specify an initrd file to load. */ |
| 1572 | const char *initrd_name = NULL; | 1602 | const char *initrd_name = NULL; |
| 1573 | 1603 | ||
| 1604 | /* Save the args: we "reboot" by execing ourselves again. */ | ||
| 1605 | main_args = argv; | ||
| 1606 | /* We don't "wait" for the children, so prevent them from becoming | ||
| 1607 | * zombies. */ | ||
| 1608 | signal(SIGCHLD, SIG_IGN); | ||
| 1609 | |||
| 1574 | /* First we initialize the device list. Since console and network | 1610 | /* First we initialize the device list. Since console and network |
| 1575 | * device receive input from a file descriptor, we keep an fdset | 1611 | * device receive input from a file descriptor, we keep an fdset |
| 1576 | * (infds) and the maximum fd number (max_infd) with the head of the | 1612 | * (infds) and the maximum fd number (max_infd) with the head of the |
| @@ -1582,6 +1618,7 @@ int main(int argc, char *argv[]) | |||
| 1582 | devices.lastdev = &devices.dev; | 1618 | devices.lastdev = &devices.dev; |
| 1583 | devices.next_irq = 1; | 1619 | devices.next_irq = 1; |
| 1584 | 1620 | ||
| 1621 | cpu_id = 0; | ||
| 1585 | /* We need to know how much memory so we can set up the device | 1622 | /* We need to know how much memory so we can set up the device |
| 1586 | * descriptor and memory pages for the devices as we parse the command | 1623 | * descriptor and memory pages for the devices as we parse the command |
| 1587 | * line. So we quickly look through the arguments to find the amount | 1624 | * line. So we quickly look through the arguments to find the amount |
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index a63373759f08..5afdde4895dc 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c | |||
| @@ -67,6 +67,7 @@ | |||
| 67 | #include <asm/mce.h> | 67 | #include <asm/mce.h> |
| 68 | #include <asm/io.h> | 68 | #include <asm/io.h> |
| 69 | #include <asm/i387.h> | 69 | #include <asm/i387.h> |
| 70 | #include <asm/reboot.h> /* for struct machine_ops */ | ||
| 70 | 71 | ||
| 71 | /*G:010 Welcome to the Guest! | 72 | /*G:010 Welcome to the Guest! |
| 72 | * | 73 | * |
| @@ -813,7 +814,7 @@ static void lguest_safe_halt(void) | |||
| 813 | * rather than virtual addresses, so we use __pa() here. */ | 814 | * rather than virtual addresses, so we use __pa() here. */ |
| 814 | static void lguest_power_off(void) | 815 | static void lguest_power_off(void) |
| 815 | { | ||
