Skip to contentSkip to conversation

kvm: notify host when guest paniced

PATCH Superseded Wen Congyang 3 participants 8 messages Mar 7, 2012

Subsystems (4)

v2 of 10 Superseded Latest is v10 →

lore
Share & tools
lore
#0 lore raw

v2 cover kvm: notify host when guest paniced

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 v1 to v2:
1. split up host and guest-side changes
2. introduce new request flag to avoid changing return values.

Wen Congyang (2):
kvm: notify host when guest paniced
kvm: set exit_reason to KVM_EXIT_GUEST_PANICED when guest paniced

 arch/x86/kernel/kvm.c    |   12 ++++++++++++
 arch/x86/kvm/x86.c       |   11 +++++++++++
 include/linux/kvm.h      |    1 +
 include/linux/kvm_host.h |    1 +
 include/linux/kvm_para.h |    1 +
 5 files changed, 26 insertions(+), 0 deletions(-)
#1 lore raw

PATCH v2 1/2 kvm: notify host when guest paniced

The implementation is the same as xen:
register panic notifier, and call hypercall when the guest is paniced.

---
 arch/x86/kernel/kvm.c    |   12 ++++++++++++
 include/linux/kvm_para.h |    1 +
 2 files changed, 13 insertions(+), 0 deletions(-)
arch/x86/kernel/kvm.c +12 -0
index f0c6fd6..7f9afc5 100644
@@ -331,6 +331,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)
+{
+	kvm_hypercall0(KVM_HC_GUEST_PANICED);
+	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;
@@ -417,6 +428,7 @@ void __init kvm_guest_init(void)
 
 	paravirt_ops_setup();
 	register_reboot_notifier(&kvm_pv_reboot_nb);
+	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))
include/linux/kvm_para.h +1 -0
index ff476dd..d030a22 100644
@@ -19,6 +19,7 @@
 #define KVM_HC_MMU_OP			2
 #define KVM_HC_FEATURES			3
 #define KVM_HC_PPC_MAP_MAGIC_PAGE	4
+#define KVM_HC_GUEST_PANICED		5
 
 /*
  * hypercalls use architecture specific
Signature · 1 line
1.7.1
#2 lore raw

PATCH v2 2/2 kvm: set exit_reason to KVM_EXIT_GUEST_PANICED when guest paniced

In reply to Wen Congyang

This patch introduces new request bit KVM_REQ_GUEST_PANICED. If this bit is set, set vcpu's exit_reason to KVM_EXIT_GUEST_PANICED. And then the user space can know the guest paniced.

---
 arch/x86/kvm/x86.c       |   11 +++++++++++
 include/linux/kvm.h      |    1 +
 include/linux/kvm_host.h |    1 +
 3 files changed, 13 insertions(+), 0 deletions(-)
arch/x86/kvm/x86.c +11 -0
index c9d99e5..978e398 100644
@@ -5013,6 +5013,10 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
 	case KVM_HC_VAPIC_POLL_IRQ:
 		ret = 0;
 		break;
+	case KVM_HC_GUEST_PANICED:
+		ret = 0;
+		kvm_make_request(KVM_REQ_GUEST_PANICED, vcpu);
+		break;
 	default:
 		ret = -KVM_ENOSYS;
 		break;
@@ -5228,6 +5232,13 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
 			r = 0;
 			goto out;
 		}
+
+		if (kvm_check_request(KVM_REQ_GUEST_PANICED, vcpu)) {
+			vcpu->run->exit_reason = KVM_EXIT_GUEST_PANICED;
+			r = 0;
+			goto out;
+		}
+
 		if (kvm_check_request(KVM_REQ_DEACTIVATE_FPU, vcpu)) {
 			vcpu->fpu_active = 0;
 			kvm_x86_ops->fpu_deactivate(vcpu);
include/linux/kvm.h +1 -0
index acbe429..a46052e 100644
@@ -163,6 +163,7 @@ struct kvm_pit_config {
 #define KVM_EXIT_OSI              18
 #define KVM_EXIT_PAPR_HCALL	  19
 #define KVM_EXIT_S390_UCONTROL	  20
+#define KVM_EXIT_GUEST_PANICED	  21
 
 /* For KVM_EXIT_INTERNAL_ERROR */
 #define KVM_INTERNAL_ERROR_EMULATION 1
include/linux/kvm_host.h +1 -0
index 355e445..026bbe5 100644
@@ -54,6 +54,7 @@
 #define KVM_REQ_IMMEDIATE_EXIT    15
 #define KVM_REQ_PMU               16
 #define KVM_REQ_PMI               17
+#define KVM_REQ_GUEST_PANICED     18
 
 #define KVM_USERSPACE_IRQ_SOURCE_ID	0
 
Signature · 1 line
1.7.1
#3 lore raw

PATCH v2 1/1 deal with guest paniced event

In reply to Wen Congyang

When the host knows the guest is paniced, it will set exit_reason to KVM_EXIT_GUEST_PANICED. So if qemu receive this exit_reason, we can send a event to tell management application that the guest is paniced and set the guest status to RUN_STATE_PANICED.

---
 kvm-all.c                 |    4 ++++
 linux-headers/linux/kvm.h |    1 +
 monitor.c                 |    3 +++
 monitor.h                 |    1 +
 qapi-schema.json          |    2 +-
 qmp.c                     |    3 ++-
 vl.c                      |    1 +
 7 files changed, 13 insertions(+), 2 deletions(-)
kvm-all.c +4 -0
index c4babda..d356948 100644
@@ -1190,6 +1190,10 @@ int kvm_cpu_exec(CPUState *env)
                     (uint64_t)run->hw.hardware_exit_reason);
             ret = -1;
             break;
+        case KVM_EXIT_GUEST_PANICED:
+            monitor_protocol_event(QEVENT_GUEST_PANICED, NULL);
+            vm_stop(RUN_STATE_PANICED);
+            break;
         case KVM_EXIT_INTERNAL_ERROR:
             ret = kvm_handle_internal_error(env, run);
             break;
linux-headers/linux/kvm.h +1 -0
index f6b5343..ddc9716 100644
@@ -163,6 +163,7 @@ struct kvm_pit_config {
 #define KVM_EXIT_OSI              18
 #define KVM_EXIT_PAPR_HCALL	  19
 #define KVM_EXIT_S390_UCONTROL	  20
+#define KVM_EXIT_GUEST_PANICED	  21
 
 /* For KVM_EXIT_INTERNAL_ERROR */
 #define KVM_INTERNAL_ERROR_EMULATION 1
monitor.c +3 -0
index 953e748..9802792 100644
@@ -494,6 +494,9 @@ void monitor_protocol_event(MonitorEvent event, QObject *data)
         case QEVENT_WAKEUP:
             event_name = "WAKEUP";
             break;
+        case QEVENT_GUEST_PANICED:
+            event_name = "GUEST_PANICED";
+            break;
         default:
             abort();
             break;
monitor.h +1 -0
index 0d49800..a62da93 100644
@@ -41,6 +41,7 @@ typedef enum MonitorEvent {
     QEVENT_DEVICE_TRAY_MOVED,
     QEVENT_SUSPEND,
     QEVENT_WAKEUP,
+    QEVENT_GUEST_PANICED,
     QEVENT_MAX,
 } MonitorEvent;
 
qapi-schema.json +1 -1
index d0b6792..dd4b7a0 100644
@@ -121,7 +121,7 @@
 { 'enum': 'RunState',
   'data': [ 'debug', 'inmigrate', 'internal-error', 'io-error', 'paused',
             'postmigrate', 'prelaunch', 'finish-migrate', 'restore-vm',
-            'running', 'save-vm', 'shutdown', 'watchdog' ] }
+            'running', 'save-vm', 'shutdown', 'watchdog', 'paniced' ] }
 
 ##
 # @StatusInfo:
qmp.c +2 -1
index a182b51..eeb6d3b 100644
@@ -148,7 +148,8 @@ void qmp_cont(Error **errp)
         error_set(errp, QERR_MIGRATION_EXPECTED);
         return;
     } else if (runstate_check(RUN_STATE_INTERNAL_ERROR) ||
-               runstate_check(RUN_STATE_SHUTDOWN)) {
+               runstate_check(RUN_STATE_SHUTDOWN) ||
+               runstate_check(RUN_STATE_PANICED)) {
         error_set(errp, QERR_RESET_REQUIRED);
         return;
     }
vl.c +1 -0
index 1d4c350..d9c13cf 100644
@@ -359,6 +359,7 @@ static const RunStateTransition runstate_transitions_def[] = {
     { RUN_STATE_RUNNING, RUN_STATE_SAVE_VM },
     { RUN_STATE_RUNNING, RUN_STATE_SHUTDOWN },
     { RUN_STATE_RUNNING, RUN_STATE_WATCHDOG },
+    { RUN_STATE_RUNNING, RUN_STATE_PANICED },
 
     { RUN_STATE_SAVE_VM, RUN_STATE_RUNNING },
 
Signature · 1 line
1.7.1
#4 lore raw

Re: [Qemu-devel] [PATCH v2] deal with guest paniced event

Quoted 5 lines · Wen Congyang

When the host knows the guest is paniced, it will set exit_reason to KVM_EXIT_GUEST_PANICED. So if qemu receive this exit_reason, we can send a event to tell management application that the guest is paniced and set the guest status to RUN_STATE_PANICED.

s/PANICED/PANICKED/ throughout your series, for the correct spelling of the past tense of panic.

Signature · 2 lines
Eric Blake   [email protected]    +1-919-301-3266
Libvirt virtualization library http://libvirt.org
#5 lore raw

Re: [Qemu-devel] [PATCH v2] deal with guest paniced event

At 03/07/2012 10:40 AM, Eric Blake Wrote:

Quoted 9 lines · Wen Congyang
Quoted 5 lines

When the host knows the guest is paniced, it will set exit_reason to KVM_EXIT_GUEST_PANICED. So if qemu receive this exit_reason, we can send a event to tell management application that the guest is paniced and set the guest status to RUN_STATE_PANICED.

s/PANICED/PANICKED/ throughout your series, for the correct spelling of the past tense of panic.

Sorry for my bad english. I will update it.

Thanks
Wen Congyang

Quoted 1 line
#6 lore raw

Re: [PATCH v2] deal with guest paniced event

In reply to Wen Congyang
Quoted 22 lines · Wen Congyang

When the host knows the guest is paniced, it will set exit_reason to KVM_EXIT_GUEST_PANICED. So if qemu receive this exit_reason, we can send a event to tell management application that the guest is paniced and set the guest status to RUN_STATE_PANICED.

---
 kvm-all.c                 |    4 ++++
 linux-headers/linux/kvm.h |    1 +
 monitor.c                 |    3 +++
 monitor.h                 |    1 +
 qapi-schema.json          |    2 +-
 qmp.c                     |    3 ++-
 vl.c                      |    1 +
 7 files changed, 13 insertions(+), 2 deletions(-)
kvm-all.c +0 -0
index c4babda..d356948 100644

kvm-all.c int kvm_cpu_exec(CPUState *env) · line 1196

Quoted 7 lines
kvm-all.c +4 -0
@@ -1190,6 +1190,10 @@ int kvm_cpu_exec(CPUState *env)
                     (uint64_t)run->hw.hardware_exit_reason);
             ret = -1;
             break;
+        case KVM_EXIT_GUEST_PANICED:
+            monitor_protocol_event(QEVENT_GUEST_PANICED, NULL);
+            vm_stop(RUN_STATE_PANICED);
+            break;

This cannot work. You missed to set ret to -1 to break out of loop.

linux-headers/linux/kvm.h struct kvm_pit_config { · line 166

Quoted 12 lines
kvm-all.c +0 -0
         case KVM_EXIT_INTERNAL_ERROR:
             ret = kvm_handle_internal_error(env, run);
             break;
linux-headers/linux/kvm.h +1 -0
index f6b5343..ddc9716 100644
@@ -163,6 +163,7 @@ struct kvm_pit_config {
 #define KVM_EXIT_OSI              18
 #define KVM_EXIT_PAPR_HCALL	  19
 #define KVM_EXIT_S390_UCONTROL	  20
+#define KVM_EXIT_GUEST_PANICED	  21

Linux header must be sync'ed in a separate patch, referencing the upstream (typically kvm.git) commit hash that was used as base. Make sure to use the update-linux-headers.sh script for this.

So the ordering is: Get the kernel changes accepted, then push the (final) user space patches. That said, a patch like this can still be posted in advance for informational purposes, but not for application.

Jan

Signature · 2 lines
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux
#7 lore raw

Re: [PATCH v2] deal with guest paniced event

At 03/07/2012 05:53 PM, Jan Kiszka Wrote:

Quoted 18 lines · Wen Congyang
Quoted 17 lines

When the host knows the guest is paniced, it will set exit_reason to KVM_EXIT_GUEST_PANICED. So if qemu receive this exit_reason, we can send a event to tell management application that the guest is paniced and set the guest status to RUN_STATE_PANICED.

---
 kvm-all.c                 |    4 ++++
 linux-headers/linux/kvm.h |    1 +
 monitor.c                 |    3 +++
 monitor.h                 |    1 +
 qapi-schema.json          |    2 +-
 qmp.c                     |    3 ++-
 vl.c                      |    1 +
 7 files changed, 13 insertions(+), 2 deletions(-)
Quoted 14 lines

kvm-all.c int kvm_cpu_exec(CPUState *env) · line 1196

Quoted 12 lines
kvm-all.c +4 -0
index c4babda..d356948 100644
@@ -1190,6 +1190,10 @@ int kvm_cpu_exec(CPUState *env)
                     (uint64_t)run->hw.hardware_exit_reason);
             ret = -1;
             break;
+        case KVM_EXIT_GUEST_PANICED:
+            monitor_protocol_event(QEVENT_GUEST_PANICED, NULL);
+            vm_stop(RUN_STATE_PANICED);
+            break;

This cannot work. You missed to set ret to -1 to break out of loop.

I fotgot to do it. But it works fine while I test this patch. I think ret has set to 0 before I guest is panicked.

Quoted 18 lines

linux-headers/linux/kvm.h struct kvm_pit_config { · line 166

Quoted 13 lines
kvm-all.c +0 -0
         case KVM_EXIT_INTERNAL_ERROR:
             ret = kvm_handle_internal_error(env, run);
             break;
linux-headers/linux/kvm.h +1 -0
index f6b5343..ddc9716 100644
@@ -163,6 +163,7 @@ struct kvm_pit_config {
 #define KVM_EXIT_OSI              18
 #define KVM_EXIT_PAPR_HCALL	  19
 #define KVM_EXIT_S390_UCONTROL	  20
+#define KVM_EXIT_GUEST_PANICED	  21

Linux header must be sync'ed in a separate patch, referencing the upstream (typically kvm.git) commit hash that was used as base. Make sure to use the update-linux-headers.sh script for this.

Quoted 3 lines

So the ordering is: Get the kernel changes accepted, then push the (final) user space patches. That said, a patch like this can still be posted in advance for informational purposes, but not for application.

OK.

Thanks
Wen Congyang

Quoted 3 lines

Jan