---
 Documentation/lguest/lguest.c |   34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c
--- a/Documentation/lguest/lguest.c
+++ b/Documentation/lguest/lguest.c
@@ -838,6 +838,9 @@ static int do_thread(void *_vq)
 	fprintf(stderr, "Child for %s vq %s = %i\n",
 		vq->dev->name, vq->dev->vq == vq ? "1" : "2", getpid());
 
+	/* Ignore SIGUSR1, that's just for main thread. */
+	signal(SIGUSR1, SIG_IGN);
+
 	for (;;)
 		vq->service(vq);
 	return 0;
@@ -879,6 +882,35 @@ static void reset_device(struct device *
 	signal(SIGCHLD, (void *)kill_launcher);
 }
 
+static void dump_info(int signal)
+{
+	char buf[2048], *p = buf;
+	struct device *dev;
+	struct virtqueue *vq;
+	unsigned long args[] = { LHREQ_GETIP };
+	p += sprintf(p, "SIGUSR1: EIP = %#lx\n",
+		     (unsigned long)write(lguest_fd, &args, sizeof(args)));
+
+	for (dev = devices.dev; dev; dev = dev->next) {
+		for (vq = dev->vq; vq; vq = vq->next) {
+			p += sprintf(p, "%s virtqueue %s (irq %u):\n"
+				     "\tpending = %u\n"
+				     "\tavail = %u/%u\n"
+				     "\tused = %u/%u\n"
+				     "\tused flags (notify suppress) = %u\n"
+				     "\tavail dflags (irq suppress) = %u\n",
+				     dev->name, vq->name, vq->config.irq,
+				     vq->pending_used,
+				     lg_last_avail(vq), vq->vring.avail->idx,
+				     vring_last_used(&vq->vring),
+				     vq->vring.used->idx,
+				     vq->vring.used->flags,
+				     vq->vring.avail->flags);
+		}
+	}
+	write(STDOUT_FILENO, buf, strlen(buf));
+}
+
 static void start_device(struct device *dev)
 {
 	unsigned int i;
@@ -1793,6 +1825,8 @@ int main(int argc, char *argv[])
 	/* If we exit via err(), this kills all the threads, restores tty. */
 	atexit(cleanup_devices);
 
+	signal(SIGUSR1, dump_info);
+
 	/* Finally, run the Guest.  This doesn't return. */
 	run_guest();
 }
