aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-01-30 17:35:32 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2008-01-30 17:35:32 -0500
commitd145c7253c8cb2ed8a75a8839621b0bb8f778820 (patch)
treefac21920d149a2cddfdfbde65066ff98935a9c57 /Documentation
parent44c3b59102e3ecc7a01e9811862633e670595e51 (diff)
parent84f12e39c856a8b1ab407f8216ecebaf4204b94d (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
Diffstat (limited to 'Documentation')
-rw-r--r--Documentation/lguest/lguest.c49
1 files changed, 43 insertions, 6 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. */
80static unsigned long guest_limit, guest_max; 80static unsigned long guest_limit, guest_max;
81 81
82/* a per-cpu variable indicating whose vcpu is currently running */
83static unsigned int __thread cpu_id;
84
82/* This is our list of devices. */ 85/* This is our list of devices. */
83struct device_list 86struct 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" */
160static 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 */
1513static 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, &notify_addr, sizeof(notify_addr)); 1536 readval = pread(lguest_fd, &notify_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