kvm: notify host when guest paniced
Subsystems (4)
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(-)
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
@@ -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
@@ -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
PATCH v2 2/2 kvm: set exit_reason to KVM_EXIT_GUEST_PANICED when guest paniced
In reply to Wen CongyangThis 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
@@ -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
@@ -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
@@ -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
PATCH v2 1/1 deal with guest paniced event
In reply to Wen CongyangWhen 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
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_reasontoKVM_EXIT_GUEST_PANICED. So if qemu receive thisexit_reason, we can send a event to tell management application that the guest is paniced and set the guest status toRUN_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
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_reasontoKVM_EXIT_GUEST_PANICED. So if qemu receive thisexit_reason, we can send a event to tell management application that the guest is paniced and set the guest status toRUN_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
Re: [PATCH v2] deal with guest paniced event
In reply to Wen CongyangQuoted 22 lines · Wen Congyang
When the host knows the guest is paniced, it will set
exit_reasontoKVM_EXIT_GUEST_PANICED. So if qemu receive thisexit_reason, we can send a event to tell management application that the guest is paniced and set the guest status toRUN_STATE_PANICED.Signed-off-by Wen Congyang <[email protected]>--- 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
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
-0case KVM_EXIT_INTERNAL_ERROR : ret =kvm_handle_internal_error (env, run);break ;linux-headers/linux/kvm.h +1
-0@@ -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
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_reasontoKVM_EXIT_GUEST_PANICED. So if qemu receive thisexit_reason, we can send a event to tell management application that the guest is paniced and set the guest status toRUN_STATE_PANICED.Signed-off-by Wen Congyang <[email protected]>--- 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@@ -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
-0case KVM_EXIT_INTERNAL_ERROR : ret =kvm_handle_internal_error (env, run);break ;linux-headers/linux/kvm.h +1
-0@@ -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 21Linux 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.shscript 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