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 [email protected]
>>>> 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 [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
>From 2c819655982a0b3043892e994fb87fd44fdca686 Mon Sep 17 00:00:00 2001
From: Wen Congyang <[email protected]>
Date: Tue, 17 Apr 2012 10:44:40 +0800
Subject: [PATCH] kvm: notify host when guest panicked
Signed-off-by: Wen Congyang <[email protected]>
---
arch/ia64/include/asm/kvm_para.h | 5 +++++
arch/powerpc/include/asm/kvm_para.h | 5 +++++
arch/s390/include/asm/kvm_para.h | 5 +++++
arch/x86/include/asm/kvm_para.h | 7 +++++++
arch/x86/kernel/kvm.c | 14 ++++++++++++++
include/linux/kvm_para.h | 13 +++++++++++++
6 files changed, 49 insertions(+), 0 deletions(-)
diff --git a/arch/ia64/include/asm/kvm_para.h b/arch/ia64/include/asm/kvm_para.h
index 1588aee..a890096 100644
--- a/arch/ia64/include/asm/kvm_para.h
+++ b/arch/ia64/include/asm/kvm_para.h
@@ -26,6 +26,11 @@ static inline unsigned int kvm_arch_para_features(void)
return 0;
}
+static inline unsigned int kvm_arch_pv_features(void)
+{
+ return 0;
+}
+
#endif
#endif
diff --git a/arch/powerpc/include/asm/kvm_para.h b/arch/powerpc/include/asm/kvm_para.h
index 7b754e7..b5f7c35 100644
--- a/arch/powerpc/include/asm/kvm_para.h
+++ b/arch/powerpc/include/asm/kvm_para.h
@@ -206,6 +206,11 @@ static inline unsigned int kvm_arch_para_features(void)
return r;
}
+static inline unsigned int kvm_arch_pv_features(void)
+{
+ return 0;
+}
+
#endif /* __KERNEL__ */
#endif /* __POWERPC_KVM_PARA_H__ */
diff --git a/arch/s390/include/asm/kvm_para.h b/arch/s390/include/asm/kvm_para.h
index 6964db2..21a8d18 100644
--- a/arch/s390/include/asm/kvm_para.h
+++ b/arch/s390/include/asm/kvm_para.h
@@ -149,6 +149,11 @@ static inline unsigned int kvm_arch_para_features(void)
return 0;
}
+static inline unsigned int kvm_arch_pv_features(void)
+{
+ return 0;
+}
+
#endif
#endif /* __S390_KVM_PARA_H */
diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h
index 734c376..02e214a 100644
--- a/arch/x86/include/asm/kvm_para.h
+++ b/arch/x86/include/asm/kvm_para.h
@@ -208,6 +208,13 @@ static inline void kvm_disable_steal_time(void)
}
#endif
+#define KVM_PV_PORT (0x505UL)
+
+static inline unsigned int kvm_arch_pv_features(void)
+{
+ return inl(KVM_PV_PORT);
+}
+
#endif /* __KERNEL__ */
#endif /* _ASM_X86_KVM_PARA_H */
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index b8ba6e4..adfde45 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -335,6 +335,17 @@ static struct notifier_block kvm_pv_reboot_nb = {
.notifier_call = kvm_pv_reboot_notify,
};
+static int
+kvm_pv_panic_notify(struct notifier_block *nb, unsigned long code, void *unused)
+{
+ outl(KVM_PV_PANICKED, KVM_PV_PORT);
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block kvm_pv_panic_nb = {
+ .notifier_call = kvm_pv_panic_notify,
+};
+
static u64 kvm_steal_clock(int cpu)
{
u64 steal;
@@ -421,6 +432,9 @@ void __init kvm_guest_init(void)
paravirt_ops_setup();
register_reboot_notifier(&kvm_pv_reboot_nb);
+ if (kvm_pv_has_feature(KVM_PV_FEATURE_PANICKED))
+ atomic_notifier_chain_register(&panic_notifier_list,
+ &kvm_pv_panic_nb);
for (i = 0; i < KVM_TASK_SLEEP_HASHSIZE; i++)
spin_lock_init(&async_pf_sleepers[i].lock);
if (kvm_para_has_feature(KVM_FEATURE_ASYNC_PF))
diff --git a/include/linux/kvm_para.h b/include/linux/kvm_para.h
index ff476dd..e73efcf 100644
--- a/include/linux/kvm_para.h
+++ b/include/linux/kvm_para.h
@@ -20,6 +20,12 @@
#define KVM_HC_FEATURES 3
#define KVM_HC_PPC_MAP_MAGIC_PAGE 4
+/* The bit of the value read from KVM_PV_PORT */
+#define KVM_PV_FEATURE_PANICKED 0
+
+/* The value writen to KVM_PV_PORT */
+#define KVM_PV_PANICKED 1
+
/*
* hypercalls use architecture specific
*/
@@ -33,5 +39,12 @@ static inline int kvm_para_has_feature(unsigned int feature)
return 1;
return 0;
}
+
+static inline int kvm_pv_has_feature(unsigned int feature)
+{
+ if (kvm_arch_pv_features() & (1UL << feature))
+ return 1;
+ return 0;
+}
#endif /* __KERNEL__ */
#endif /* __LINUX_KVM_PARA_H */
--
1.7.1
>From cb39cb1f36d4c37b3dc7942413550bb4b7c79a84 Mon Sep 17 00:00:00 2001
From: Wen Congyang <[email protected]>
Date: Tue, 17 Apr 2012 11:01:01 +0800
Subject: [PATCH] kvm: nofity thost when guest is panicked
Signed-off-by: Wen Congyang <[email protected]>
---
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