Patchwork [0/2,v3] kvm: notify host when guest panicked

login
register
mail settings
Submitter Wen Congyang
Date April 17, 2012, 3:14 a.m.
Message ID <4F8CE026.1050205@cn.fujitsu.com>
Download mbox | patch
Permalink /patch/153030/
State New
Headers show

Comments

Wen Congyang - April 17, 2012, 3:14 a.m.
At 03/20/2012 11:45 PM, Gleb Natapov Wrote:
> On Tue, Mar 20, 2012 at 05:59:16PM +0800, Wen Congyang wrote:
>> At 03/19/2012 03:33 PM, Wen Congyang Wrote:
>>> At 03/08/2012 03:57 PM, Wen Congyang Wrote:
>>>> We can know the guest is paniced when the guest runs on xen.
>>>> But we do not have such feature on kvm.
>>>>
>>>> Another purpose of this feature is: management app(for example:
>>>> libvirt) can do auto dump when the guest is crashed. If management
>>>> app does not do auto dump, the guest's user can do dump by hand if
>>>> he sees the guest is paniced.
>>>>
>>>> I touch the hypervisor instead of using virtio-serial, because
>>>> 1. it is simple
>>>> 2. the virtio-serial is an optional device, and the guest may
>>>>    not have such device.
>>>>
>>>> Changes from v2 to v3:
>>>> 1. correct spelling
>>>>
>>>> Changes from v1 to v2:
>>>> 1. split up host and guest-side changes
>>>> 2. introduce new request flag to avoid changing return values.
>>>> --
>>>> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
>>>> the body of a message to majordomo@vger.kernel.org
>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>> Please read the FAQ at  http://www.tux.org/lkml/
>>>>
>>>
>>>
>>> Hi all:
>>>
>>> we neet this feature, but we don't decide how to implement it.
>>> We have two solution:
>>> 1. use vmcall
>>> 2. use virtio-serial.
>>>
>>> I will not change this patch set before we decide how to do it.
>>> Can we make a decision recent days?
>>
>> Anybody can decide which solution to use?
>>
> To make an informed decision we need to have at least raw idea how
> virtio-serial variant will look.

We have three solutions now:
1. use vmcall
2. use I/O port
3. use virtio-serial

I write a sample patch of solution 2 and 3:
    patch 1: solution 2
    patch 2: solution 3

Note, ther are only sample patches, and it can work. I send them, so we
can decide which solution will be used.

Thanks
Wen Congyang



> 
> --
> 			Gleb.
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
>

Patch

From cb39cb1f36d4c37b3dc7942413550bb4b7c79a84 Mon Sep 17 00:00:00 2001
From: Wen Congyang <wency@cn.fujitsu.com>
Date: Tue, 17 Apr 2012 11:01:01 +0800
Subject: [PATCH] kvm: nofity thost when guest is panicked

Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
---
 drivers/char/virtio_console.c |   49 +++++++++++++++++++++++++++++++++++++++++
 1 files changed, 49 insertions(+), 0 deletions(-)

diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index ddf86b6..ecccd30 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -225,8 +225,14 @@  struct port {
 
 	/* We should allow only one process to open a port */
 	bool guest_connected;
+
+	/* We use this port to tell the host that the guest is panicked */
+	bool panicked_port;
+	char *panicked_buf;
 };
 
+static struct port *panicked_port;
+
 /* This is the very early arch-specified put chars function. */
 static int (*early_put_chars)(u32, const char *, int);
 
@@ -806,6 +812,15 @@  static int port_fops_open(struct inode *inode, struct file *filp)
 		goto out;
 	}
 
+	/*
+	 * Don't allow opening of panicked port devices -- that's reserved
+	 * for kernel space
+	 */
+	if (port->panicked_port) {
+		ret = -ENXIO;
+		goto out;
+	}
+
 	/* Allow only one process to open a particular port at a time */
 	spin_lock_irq(&port->inbuf_lock);
 	if (port->guest_connected) {
@@ -1126,6 +1141,20 @@  static void send_sigio_to_port(struct port *port)
 		kill_fasync(&port->async_queue, SIGIO, POLL_OUT);
 }
 
+static int
+kvm_pv_panic_notify(struct notifier_block *nb, unsigned long code, void *unused)
+{
+	send_control_msg(panicked_port, VIRTIO_CONSOLE_PORT_OPEN, 1);
+	memcpy(panicked_port->panicked_buf, "Kernel panicked\n", 16);
+	send_buf(panicked_port, panicked_port->panicked_buf, 16, true);
+	send_control_msg(panicked_port, VIRTIO_CONSOLE_CONSOLE_PORT, 0);
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block kvm_pv_panic_nb = {
+	.notifier_call = kvm_pv_panic_notify,
+};
+
 static int add_port(struct ports_device *portdev, u32 id)
 {
 	char debugfs_name[16];
@@ -1262,6 +1291,10 @@  static void remove_port(struct kref *kref)
 
 	debugfs_remove(port->debugfs_file);
 
+	if (port->panicked_port)
+		atomic_notifier_chain_unregister(&panic_notifier_list,
+						 &kvm_pv_panic_nb);
+
 	kfree(port);
 }
 
@@ -1433,6 +1466,22 @@  static void handle_control_message(struct ports_device *portdev,
 			name_size - 1);
 		port->name[name_size - 1] = 0;
 
+		if (!panicked_port && !strcmp(port->name, "status")) {
+			port->panicked_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+			if (!port->panicked_buf) {
+				dev_warn(port->dev,
+					 "Not enough space to store panicked"
+					 " message");
+				goto skip;
+			}
+			send_sigio_to_port(port);
+			port->panicked_port = true;
+			panicked_port = port;
+			atomic_notifier_chain_register(&panic_notifier_list,
+						       &kvm_pv_panic_nb);
+		}
+
+skip:
 		/*
 		 * Since we only have one sysfs attribute, 'name',
 		 * create it only if we have a name for the port.
-- 
1.7.1