pv event to notify host when the guest is panicked
v12 cover pv event to notify host when the guest is panicked
This series implements a new interface, kvm pv event, to notify host when some events happen in guest. Right now there is one supported event: guest panic.
Also, the cpu runstate is preserved during save/load vm and migration. Thus, if vm is panicked during migration, we can still know it by quring the status of vm in destination host.
This version is a rebase and no code change.
v12: http://lists.gnu.org/archive/html/qemu-devel/2012-12/msg01459.html
v11: http://lists.gnu.org/archive/html/qemu-devel/2012-10/msg04361.html
Hu Tao (7):
save/load cpu runstate
update kernel headers
add a new runstate: RUN_STATE_GUEST_PANICKED add a new qevent: QEVENT_GUEST_PANICKED introduce a new qom device to deal with panicked event allower the user to disable pv event support pv event: add document to describe the usage
Wen Congyang (1):
start vm after resetting it
docs/pv-event.txt | 17 ++++ hw/kvm/Makefile.objs | 2 +- hw/kvm/pv_event.c | 197 +++++++++++++++++++++++++++++++++++++++ hw/pc_piix.c | 12 +++ include/block/block.h | 2 + include/monitor/monitor.h | 1 + include/sysemu/kvm.h | 2 + include/sysemu/sysemu.h | 2 + kvm-stub.c | 4 + linux-headers/asm-x86/kvm_para.h | 1 + linux-headers/linux/kvm_para.h | 6 ++ migration.c | 7 +- monitor.c | 6 +- qapi-schema.json | 6 +- qemu-options.hx | 3 +- qmp.c | 5 +- savevm.c | 1 + vl.c | 56 ++++++++++- 18 files changed, 313 insertions(+), 17 deletions(-) create mode 100644 docs/pv-event.txt create mode 100644 hw/kvm/pv_event.c
Signature · 1 line
1.8.0.1.240.ge8a1f5a
PATCH v12 1/1 kvm: notify host when the guest is panicked
We can know the guest is panicked 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 panicked. If management app does not do auto dump, the guest's user can do dump by hand if he sees the guest is panicked.
We have three solutions to implement this feature:
1. use vmcall
2. use I/O port
3. use virtio-serial.
We have decided to avoid touching hypervisor. The reason why I choose choose the I/O port is:
1. it is easier to implememt
2. it does not depend any virtual device
3. it can work when starting the kernel
--- arch/ia64/kvm/irq.h | 19 +++++++++++++ arch/powerpc/include/asm/kvm_para.h | 18 ++++++++++++ arch/s390/include/asm/kvm_para.h | 19 +++++++++++++ arch/x86/include/asm/kvm_para.h | 20 ++++++++++++++ arch/x86/include/uapi/asm/kvm_para.h | 2 ++ arch/x86/kernel/kvm.c | 53 ++++++++++++++++++++++++++++++++++++ include/linux/kvm_para.h | 18 ++++++++++++ include/uapi/linux/kvm_para.h | 6 ++++ kernel/panic.c | 4 +++ 9 files changed, 159 insertions(+)
arch/ia64/kvm/irq.h +19 -0
@@ -30,4 +30,23 @@ static inline int irqchip_in_kernel(struct kvm *kvm) return 1; } +static inline int kvm_arch_pv_event_init (void ) +{ +return 0 ; +} + +static inline unsigned int kvm_arch_pv_features (void ) +{ +return 0 ; +} + +static inline void kvm_arch_pv_eject_event (unsigned int event) +{ +} + +static inline bool kvm_arch_pv_event_enabled (void ) +{ +return false; +} +#endif
arch/powerpc/include/asm/kvm_para.h +18 -0
@@ -144,4 +144,22 @@ static inline bool kvm_check_and_clear_guest_paused(void) return false; } +static inline int kvm_arch_pv_event_init (void ) +{ +return 0 ; +} + +static inline unsigned int kvm_arch_pv_features (void ) +{ +return 0 ; +} + +static inline void kvm_arch_pv_eject_event (unsigned int event) +{ +} + +static inline bool kvm_arch_pv_event_enabled (void ) +{ +return false; +}#endif /* __POWERPC_KVM_PARA_H__ */
arch/s390/include/asm/kvm_para.h +19 -0
@@ -154,4 +154,23 @@ static inline bool kvm_check_and_clear_guest_paused(void) return false; } +static inline int kvm_arch_pv_event_init (void ) +{ +return 0 ; +} + +static inline unsigned int kvm_arch_pv_features (void ) +{ +return 0 ; +} + +static inline void kvm_arch_pv_eject_event (unsigned int event) +{ +} + +static inline bool kvm_arch_pv_event_enabled (void ) +{ +return false; +} +#endif /* __S390_KVM_PARA_H */
arch/x86/include/asm/kvm_para.h +20 -0
@@ -133,4 +133,24 @@ static inline void kvm_disable_steal_time(void) }#endif +static inline int kvm_arch_pv_event_init (void ) +{ +if (!request_region (KVM_PV_EVENT_PORT ,4 ,"KVM_PV_EVENT" )) +return -1 ; + +return 0 ; +} + +static inline unsigned int kvm_arch_pv_features (void ) +{ +return inl (KVM_PV_EVENT_PORT ); +} + +static inline void kvm_arch_pv_eject_event (unsigned int event) +{ +outl (event,KVM_PV_EVENT_PORT ); +} + +bool kvm_arch_pv_event_enabled (void ); +#endif /* _ASM_X86_KVM_PARA_H */
arch/x86/include/uapi/asm/kvm_para.h +2 -0
@@ -96,5 +96,7 @@ struct kvm_vcpu_pv_apf_data {#define KVM_PV_EOI_ENABLED KVM_PV_EOI_MASK#define KVM_PV_EOI_DISABLED 0x0 +#define KVM_PV_EVENT_PORT (0x505UL) +#endif /* _UAPI_ASM_X86_KVM_PARA_H */
arch/x86/kernel/kvm.c +53 -0
71 lines not on this page · raw message
include/linux/kvm_para.h +18 -0
@@ -10,4 +10,22 @@ 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 ; +} + +static inline void kvm_pv_eject_event (unsigned int event) +{ +kvm_arch_pv_eject_event (event); +} + +static inline bool kvm_pv_event_enabled (void ) +{ +return kvm_arch_pv_event_enabled (); +} +#endif /* __LINUX_KVM_PARA_H */
include/uapi/linux/kvm_para.h +6 -0
@@ -20,6 +20,12 @@#define KVM_HC_FEATURES 3#define KVM_HC_PPC_MAP_MAGIC_PAGE 4 +/* The bit of supported pv event */ +#define KVM_PV_FEATURE_PANICKED 0 + +/* The pv event value */ +#define KVM_PV_EVENT_PANICKED 1 +/* * hypercalls use architecture specific */
kernel/panic.c +4 -0
@@ -23,6 +23,7 @@#include <linux/init.h> #include <linux/nmi.h> #include <linux/dmi.h> +#include <linux/kvm_para.h> #define PANIC_TIMER_STEP 100#define PANIC_BLINK_SPD 18
@@ -132,6 +133,9 @@ void panic(const char *fmt, ...)if (!panic_blink) panic_blink = no_blink; +if (kvm_pv_event_enabled ()) + panic_timeout =0 ; +if (panic_timeout >0 ) {/* * Delay timeout seconds before rebooting the machine.
Signature · 1 line
1.8.0.1.240.ge8a1f5a
Re: [PATCH v12 rebased] kvm: notify host when the guest is panicked
Hi,
Quoted 50 lines · Hu Tao
We can know the guest is panicked 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 panicked. If management app does not do auto dump, the guest's user can do dump by hand if he sees the guest is panicked.We have three solutions to implement this feature:
1. use vmcall
2. use I/O port
3. use virtio-serial.We have decided to avoid touching hypervisor. The reason why I choose choose the I/O port is:
1. it is easier to implememt
2. it does not depend any virtual device
3. it can work when starting the kernelSigned-off-by Wen Congyang <[email protected]>Signed-off-by Hu Tao <[email protected]>--- arch/ia64/kvm/irq.h | 19 +++++++++++++ arch/powerpc/include/asm/kvm_para.h | 18 ++++++++++++ arch/s390/include/asm/kvm_para.h | 19 +++++++++++++ arch/x86/include/asm/kvm_para.h | 20 ++++++++++++++ arch/x86/include/uapi/asm/kvm_para.h | 2 ++ arch/x86/kernel/kvm.c | 53 ++++++++++++++++++++++++++++++++++++ include/linux/kvm_para.h | 18 ++++++++++++ include/uapi/linux/kvm_para.h | 6 ++++ kernel/panic.c | 4 +++ 9 files changed, 159 insertions(+)arch/ia64/kvm/irq.h +9
-0@@ -30,4 +30,23 @@ static inline int irqchip_in_kernel(struct kvm *kvm)return 1 ; } +static inline int kvm_arch_pv_event_init (void ) +{ +return 0 ; +} + +static inline unsigned int kvm_arch_pv_features (void ) +{ +return 0 ; +}
arch/ia64/kvm/irq.h static inline int irqchip_in_kernel(struct kvm *kvm) · line 51
Quoted 10 lines
arch/ia64/kvm/irq.h +10
-0+ +static inline void kvm_arch_pv_eject_event (unsigned int event) +{ +} + +static inline bool kvm_arch_pv_event_enabled (void ) +{ +return false; +} +
The interface is x86 only, no need to touch other architectures.
Quoted 59 lines
arch/ia64/kvm/irq.h +0
-0#endif arch/powerpc/include/asm/kvm_para.h +18
-0@@ -144,4 +144,22 @@ static inline bool kvm_check_and_clear_guest_paused(void) return false; } +static inline int kvm_arch_pv_event_init (void ) +{ +return 0 ; +} + +static inline unsigned int kvm_arch_pv_features (void ) +{ +return 0 ; +} + +static inline void kvm_arch_pv_eject_event (unsigned int event) +{ +} + +static inline bool kvm_arch_pv_event_enabled (void ) +{ +return false; +}#endif /* __POWERPC_KVM_PARA_H__ */ arch/s390/include/asm/kvm_para.h +19
-0@@ -154,4 +154,23 @@ static inline bool kvm_check_and_clear_guest_paused(void) return false; } +static inline int kvm_arch_pv_event_init (void ) +{ +return 0 ; +} + +static inline unsigned int kvm_arch_pv_features (void ) +{ +return 0 ; +} + +static inline void kvm_arch_pv_eject_event (unsigned int event) +{ +} + +static inline bool kvm_arch_pv_event_enabled (void ) +{ +return false; +} +#endif /* __S390_KVM_PARA_H */
arch/x86/include/asm/kvm_para.h static inline void kvm_disable_steal_time(void) · line 142
Quoted 10 lines
arch/x86/include/asm/kvm_para.h +7
-0@@ -133,4 +133,24 @@ static inline void kvm_disable_steal_time(void) }#endif +static inline int kvm_arch_pv_event_init (void ) +{ +if (!request_region (KVM_PV_EVENT_PORT ,4 ,"KVM_PV_EVENT" )) +return -1 ; + +return 0 ; +}
This should be in a driver in arch/x86/kernel/kvm-panic.c, or so.
Quoted 20 lines
arch/x86/include/asm/kvm_para.h +13
-0+ +static inline unsigned int kvm_arch_pv_features (void ) +{ +return inl (KVM_PV_EVENT_PORT ); +} + +static inline void kvm_arch_pv_eject_event (unsigned int event) +{ +outl (event,KVM_PV_EVENT_PORT ); +} + +bool kvm_arch_pv_event_enabled (void ); +#endif /*
_ASM_X86_KVM_PARA_H*/arch/x86/include/uapi/asm/kvm_para.h +0
-0
arch/x86/include/uapi/asm/kvm_para.h struct kvm_vcpu_pv_apf_data { · line 100
Quoted 5 lines
arch/x86/include/uapi/asm/kvm_para.h +2
-0@@ -96,5 +96,7 @@ struct kvm_vcpu_pv_apf_data {#define KVM_PV_EOI_ENABLED KVM_PV_EOI_MASK#define KVM_PV_EOI_DISABLED 0x0 +#define KVM_PV_EVENT_PORT (0x505UL) +
No need for the ioport to be hard coded. What are the options to communicate an address to the guest? An MSR, via ACPI?
Quoted 14 lines
arch/x86/include/uapi/asm/kvm_para.h +0
-0#endif /* _UAPI_ASM_X86_KVM_PARA_H */ arch/x86/kernel/kvm.c +4
-0@@ -73,6 +73,20 @@ static int parse_no_kvmclock_vsyscall(char *arg)early_param ("no-kvmclock-vsyscall" , parse_no_kvmclock_vsyscall); +static int pv_event =1 ; +static int parse_no_pv_event (char *arg) +{ + pv_event =0 ;
arch/x86/kernel/kvm.c static int parse_no_kvmclock_vsyscall(char *arg) · line 89
Quoted 10 lines
arch/x86/kernel/kvm.c +10
-0+return 0 ; +} + +bool kvm_arch_pv_event_enabled (void ) +{ +return !!pv_event; +} + +early_param ("no-pv-event" , parse_no_pv_event); +
"pv-event" is a bad name for an interface which is specific to notify panic events. Please use pv-panic everywhere.
arch/x86/kernel/kvm.c static struct notifier_block kvm_pv_reboot_nb = { · line 407
Quoted 13 lines
arch/x86/kernel/kvm.c +6
-0static DEFINE_PER_CPU(struct kvm_vcpu_pv_apf_data, apf_reason) __aligned(64); static DEFINE_PER_CPU(struct kvm_steal_time, steal_time) __aligned(64);static int has_steal_clock =0 ;@@ -385,6 +399,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_pv_eject_event (KVM_PV_EVENT_PANICKED ); +return NOTIFY_DONE ; +}
Why 'eject' ?
Quoted 29 lines
arch/x86/kernel/kvm.c +22
-0+ +static struct notifier_block kvm_pv_panic_nb = { + .notifier_call = kvm_pv_panic_notify, +}; +static u64 kvm_steal_clock (int cpu) {u64 steal;@@ -462,6 +487,34 @@ static void __init kvm_apf_trap_init(void)set_intr_gate (14 , &async_page_fault); } +static void __init kvm_pv_panicked_event_init (void ) +{ +if (!kvm_para_available ()) +return ; + +if (kvm_pv_has_feature (KVM_PV_FEATURE_PANICKED )) +atomic_notifier_chain_register (&panic_notifier_list, + &kvm_pv_panic_nb); +} + +static inline int kvm_pv_event_init (void ) +{ +return kvm_arch_pv_event_init (); +} + +static int __init enable_pv_event (void ) +{
arch/x86/kernel/kvm.c static void __init kvm_apf_trap_init(void) · line 516
Quoted 10 lines
arch/x86/kernel/kvm.c +10
-0+if (pv_event) { +if (kvm_pv_event_init ()) +return 0 ; + +kvm_pv_panicked_event_init (); + } + +return 0 ; +} +arch_initcall (enable_pv_event);
Call the initialization code from kvm_guest_init, only one function is necessary.
Quoted 19 lines
arch/x86/kernel/kvm.c +1
-0+void __init kvm_guest_init (void ) {int i;include/linux/kvm_para.h +7
-0@@ -10,4 +10,22 @@ 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 ; +}
include/linux/kvm_para.h static inline int kvm_para_has_feature(unsigned int feature) · line 29
Quoted 10 lines
include/linux/kvm_para.h +10
-0+ +static inline void kvm_pv_eject_event (unsigned int event) +{ +kvm_arch_pv_eject_event (event); +} + +static inline bool kvm_pv_event_enabled (void ) +{ +return kvm_arch_pv_event_enabled (); +}
No need for this helpers, as noted.
Quoted 6 lines
include/linux/kvm_para.h +0
-0#endif /* __LINUX_KVM_PARA_H */ include/uapi/linux/kvm_para.h +0
-0
include/uapi/linux/kvm_para.h line 28
Quoted 9 lines
include/uapi/linux/kvm_para.h +6
-0@@ -20,6 +20,12 @@#define KVM_HC_FEATURES 3#define KVM_HC_PPC_MAP_MAGIC_PAGE 4 +/* The bit of supported pv event */ +#define KVM_PV_FEATURE_PANICKED 0 + +/* The pv event value */ +#define KVM_PV_EVENT_PANICKED 1 +
This is a hypercall header. You want
arch/x86/include/asm/kvm_para.h
Quoted 16 lines
include/uapi/linux/kvm_para.h +0
-0/* * hypercalls use architecture specific */ kernel/panic.c +1
-0@@ -23,6 +23,7 @@#include <linux/init.h> #include <linux/nmi.h> #include <linux/dmi.h> +#include <linux/kvm_para.h> #define PANIC_TIMER_STEP 100#define PANIC_BLINK_SPD 18
kernel/panic.c void panic(const char *fmt, ...) · line 138
Quoted 6 lines
kernel/panic.c +3
-0@@ -132,6 +133,9 @@ void panic(const char *fmt, ...)if (!panic_blink) panic_blink = no_blink; +if (kvm_pv_event_enabled ()) + panic_timeout =0 ; +
What is the rationale behind this?
Re: [PATCH v12 rebased] kvm: notify host when the guest is panicked
Quoted 57 lines · Marcelo Tosatti
Hi,
Quoted 54 lines · Hu Tao
We can know the guest is panicked 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 panicked. If management app does not do auto dump, the guest's user can do dump by hand if he sees the guest is panicked.We have three solutions to implement this feature:
1. use vmcall
2. use I/O port
3. use virtio-serial.We have decided to avoid touching hypervisor. The reason why I choose choose the I/O port is:
1. it is easier to implememt
2. it does not depend any virtual device
3. it can work when starting the kernelSigned-off-by Wen Congyang <[email protected]>Signed-off-by Hu Tao <[email protected]>--- arch/ia64/kvm/irq.h | 19 +++++++++++++ arch/powerpc/include/asm/kvm_para.h | 18 ++++++++++++ arch/s390/include/asm/kvm_para.h | 19 +++++++++++++ arch/x86/include/asm/kvm_para.h | 20 ++++++++++++++ arch/x86/include/uapi/asm/kvm_para.h | 2 ++ arch/x86/kernel/kvm.c | 53 ++++++++++++++++++++++++++++++++++++ include/linux/kvm_para.h | 18 ++++++++++++ include/uapi/linux/kvm_para.h | 6 ++++ kernel/panic.c | 4 +++ 9 files changed, 159 insertions(+)arch/ia64/kvm/irq.h +13
-0@@ -30,4 +30,23 @@ static inline int irqchip_in_kernel(struct kvm *kvm)return 1 ; } +static inline int kvm_arch_pv_event_init (void ) +{ +return 0 ; +} + +static inline unsigned int kvm_arch_pv_features (void ) +{ +return 0 ; +} + +static inline void kvm_arch_pv_eject_event (unsigned int event) +{ +}
Quoted 8 lines
arch/ia64/kvm/irq.h static inline int irqchip_in_kernel(struct kvm *kvm) · line 51
Quoted 6 lines
arch/ia64/kvm/irq.h +6
-0+ +static inline bool kvm_arch_pv_event_enabled (void ) +{ +return false; +} +The interface is x86 only, no need to touch other architectures.
OK.
Quoted 96 lines
Quoted 60 lines
arch/ia64/kvm/irq.h +0
-0#endif arch/powerpc/include/asm/kvm_para.h +18
-0@@ -144,4 +144,22 @@ static inline bool kvm_check_and_clear_guest_paused(void) return false; } +static inline int kvm_arch_pv_event_init (void ) +{ +return 0 ; +} + +static inline unsigned int kvm_arch_pv_features (void ) +{ +return 0 ; +} + +static inline void kvm_arch_pv_eject_event (unsigned int event) +{ +} + +static inline bool kvm_arch_pv_event_enabled (void ) +{ +return false; +}#endif /* __POWERPC_KVM_PARA_H__ */ arch/s390/include/asm/kvm_para.h +19
-0@@ -154,4 +154,23 @@ static inline bool kvm_check_and_clear_guest_paused(void) return false; } +static inline int kvm_arch_pv_event_init (void ) +{ +return 0 ; +} + +static inline unsigned int kvm_arch_pv_features (void ) +{ +return 0 ; +} + +static inline void kvm_arch_pv_eject_event (unsigned int event) +{ +} + +static inline bool kvm_arch_pv_event_enabled (void ) +{ +return false; +} +#endif /* __S390_KVM_PARA_H */ arch/x86/include/asm/kvm_para.h static inline void kvm_disable_steal_time(void) · line 142
Quoted 10 lines
arch/x86/include/asm/kvm_para.h +7
-0@@ -133,4 +133,24 @@ static inline void kvm_disable_steal_time(void) }#endif +static inline int kvm_arch_pv_event_init (void ) +{ +if (!request_region (KVM_PV_EVENT_PORT ,4 ,"KVM_PV_EVENT" )) +return -1 ; + +return 0 ; +}This should be in a driver in
arch/x86/kernel/kvm-panic.c, or so.Quoted 23 lines
arch/x86/include/asm/kvm_para.h +13
-0+ +static inline unsigned int kvm_arch_pv_features (void ) +{ +return inl (KVM_PV_EVENT_PORT ); +} + +static inline void kvm_arch_pv_eject_event (unsigned int event) +{ +outl (event,KVM_PV_EVENT_PORT ); +} + +bool kvm_arch_pv_event_enabled (void ); +#endif /*
_ASM_X86_KVM_PARA_H*/arch/x86/include/uapi/asm/kvm_para.h +0
-0@@ -96,5 +96,7 @@ struct kvm_vcpu_pv_apf_data {#define KVM_PV_EOI_ENABLED KVM_PV_EOI_MASK#define KVM_PV_EOI_DISABLED 0x0
Quoted 5 lines
arch/x86/include/uapi/asm/kvm_para.h struct kvm_vcpu_pv_apf_data { · line 100
Quoted 2 lines
arch/x86/include/uapi/asm/kvm_para.h +2
-0+#define KVM_PV_EVENT_PORT (0x505UL) +No need for the ioport to be hard coded. What are the options to communicate an address to the guest? An MSR, via ACPI?
I'm not quite understanding here. By 'address', you mean an ioport? how to communicate an address? (I have little knowledge about ACPI)
Quoted 20 lines
Quoted 20 lines
arch/x86/include/uapi/asm/kvm_para.h +0
-0#endif /* _UAPI_ASM_X86_KVM_PARA_H */ arch/x86/kernel/kvm.c +9
-0@@ -73,6 +73,20 @@ static int parse_no_kvmclock_vsyscall(char *arg)early_param ("no-kvmclock-vsyscall" , parse_no_kvmclock_vsyscall); +static int pv_event =1 ; +static int parse_no_pv_event (char *arg) +{ + pv_event =0 ; +return 0 ; +} + +bool kvm_arch_pv_event_enabled (void ) +{
Quoted 8 lines
arch/x86/kernel/kvm.c static int parse_no_kvmclock_vsyscall(char *arg) · line 89
Quoted 5 lines
arch/x86/kernel/kvm.c +5
-0+return !!pv_event; +} + +early_param ("no-pv-event" , parse_no_pv_event); +"pv-event" is a bad name for an interface which is specific to notify panic events. Please use pv-panic everywhere.
panic event is one of the events supported. Can we keep the name?
Quoted 8 lines
Quoted 8 lines
arch/x86/kernel/kvm.c +0
-0static DEFINE_PER_CPU(struct kvm_vcpu_pv_apf_data, apf_reason) __aligned(64); static DEFINE_PER_CPU(struct kvm_steal_time, steal_time) __aligned(64);static int has_steal_clock =0 ;@@ -385,6 +399,17 @@ static struct notifier_block kvm_pv_reboot_nb = { .notifier_call = kvm_pv_reboot_notify, };
Quoted 8 lines
arch/x86/kernel/kvm.c static struct notifier_block kvm_pv_reboot_nb = { · line 407
Quoted 6 lines
arch/x86/kernel/kvm.c +6
-0+static int +kvm_pv_panic_notify (struct notifier_block *nb,unsigned long code,void *unused) +{ +kvm_pv_eject_event (KVM_PV_EVENT_PANICKED ); +return NOTIFY_DONE ; +}Why 'eject' ?
changed to 'send'
Quoted 35 lines
Quoted 35 lines
arch/x86/kernel/kvm.c +27
-0+ +static struct notifier_block kvm_pv_panic_nb = { + .notifier_call = kvm_pv_panic_notify, +}; +static u64 kvm_steal_clock (int cpu) {u64 steal;@@ -462,6 +487,34 @@ static void __init kvm_apf_trap_init(void)set_intr_gate (14 , &async_page_fault); } +static void __init kvm_pv_panicked_event_init (void ) +{ +if (!kvm_para_available ()) +return ; + +if (kvm_pv_has_feature (KVM_PV_FEATURE_PANICKED )) +atomic_notifier_chain_register (&panic_notifier_list, + &kvm_pv_panic_nb); +} + +static inline int kvm_pv_event_init (void ) +{ +return kvm_arch_pv_event_init (); +} + +static int __init enable_pv_event (void ) +{ +if (pv_event) { +if (kvm_pv_event_init ()) +return 0 ; + +kvm_pv_panicked_event_init ();
Quoted 8 lines
arch/x86/kernel/kvm.c static void __init kvm_apf_trap_init(void) · line 516
Quoted 5 lines
arch/x86/kernel/kvm.c +5
-0+ } + +return 0 ; +} +arch_initcall (enable_pv_event);Call the initialization code from
kvm_guest_init, only one function is necessary.
At the point of kvm_guest_init, rqeust_region (called by kvm_pv_event_init) will block, so the guest kernel won't up.
Quoted 24 lines
Quoted 24 lines
arch/x86/kernel/kvm.c +1
-0+void __init kvm_guest_init (void ) {int i;include/linux/kvm_para.h +11
-0@@ -10,4 +10,22 @@ 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 ; +} + +static inline void kvm_pv_eject_event (unsigned int event) +{ +kvm_arch_pv_eject_event (event);
Quoted 8 lines
include/linux/kvm_para.h static inline int kvm_para_has_feature(unsigned int feature) · line 29
Quoted 6 lines
include/linux/kvm_para.h +6
-0+} + +static inline bool kvm_pv_event_enabled (void ) +{ +return kvm_arch_pv_event_enabled (); +}No need for this helpers, as noted.
OK.
Quoted 19 lines
Quoted 7 lines
include/linux/kvm_para.h +0
-0#endif /* __LINUX_KVM_PARA_H */ include/uapi/linux/kvm_para.h +0
-0include/uapi/linux/kvm_para.h line 28
Quoted 9 lines
include/uapi/linux/kvm_para.h +6
-0@@ -20,6 +20,12 @@#define KVM_HC_FEATURES 3#define KVM_HC_PPC_MAP_MAGIC_PAGE 4 +/* The bit of supported pv event */ +#define KVM_PV_FEATURE_PANICKED 0 + +/* The pv event value */ +#define KVM_PV_EVENT_PANICKED 1 +This is a hypercall header. You want
Quoted 1 line
arch/x86/include/asm/kvm_para.h
OK.
Quoted 20 lines
Quoted 20 lines
include/uapi/linux/kvm_para.h +0
-0/* * hypercalls use architecture specific */ kernel/panic.c +1
-0@@ -23,6 +23,7 @@#include <linux/init.h> #include <linux/nmi.h> #include <linux/dmi.h> +#include <linux/kvm_para.h> #define PANIC_TIMER_STEP 100#define PANIC_BLINK_SPD 18@@ -132,6 +133,9 @@ void panic(const char *fmt, ...)if (!panic_blink) panic_blink = no_blink;
Quoted 5 lines
kernel/panic.c void panic(const char *fmt, ...) · line 138
Quoted 3 lines
kernel/panic.c +3
-0+if (kvm_pv_event_enabled ()) + panic_timeout =0 ; +What is the rationale behind this?
This is a hack to disable reset_on_panic if user enables pv-event.
Re: [PATCH v12 rebased] kvm: notify host when the guest is panicked
Quoted 8 lines · Hu Tao
Quoted 8 lines
Quoted 8 lines
arch/x86/include/uapi/asm/kvm_para.h +0
-0@@ -96,5 +96,7 @@ struct kvm_vcpu_pv_apf_data {#define KVM_PV_EOI_ENABLED KVM_PV_EOI_MASK#define KVM_PV_EOI_DISABLED 0x0
Quoted 8 lines
Quoted 5 lines
arch/x86/include/uapi/asm/kvm_para.h struct kvm_vcpu_pv_apf_data { · line 100
Quoted 2 lines
arch/x86/include/uapi/asm/kvm_para.h +2
-0+#define KVM_PV_EVENT_PORT (0x505UL) +No need for the ioport to be hard coded. What are the options to communicate an address to the guest? An MSR, via ACPI?
I'm not quite understanding here. By 'address', you mean an ioport? how to communicate an address? (I have little knowledge about ACPI)
Yes, the ioport. The address of the ioport should not be fixed (for example future emulated board could use that fixed ioport address, 0x505UL).
One option is to pass the address via an MSR. Yes, that is probably the best option because there is no dependency on ACPI.
Quoted 10 lines
Quoted 2 lines
"pv-event" is a bad name for an interface which is specific to notify panic events. Please use pv-panic everywhere.
panic event is one of the events supported. Can we keep the name?
Quoted 2 lines
Call the initialization code from
kvm_guest_init, only one function is necessary.At the point of
kvm_guest_init,rqeust_region(called bykvm_pv_event_init) will block, so the guest kernel won't up.
Why does it block?
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
arch/x86/include/uapi/asm/kvm_para.h +0
-0#define PANIC_TIMER_STEP 100#define PANIC_BLINK_SPD 18@@ -132,6 +133,9 @@ void panic(const char *fmt, ...)if (!panic_blink) panic_blink = no_blink;
Quoted 8 lines
Quoted 5 lines
arch/x86/include/uapi/asm/kvm_para.h void panic(const char *fmt, ...) · line 138
Quoted 3 lines
arch/x86/include/uapi/asm/kvm_para.h +3
-0+if (kvm_pv_event_enabled ()) + panic_timeout =0 ; +What is the rationale behind this?
This is a hack to disable
reset_on_panicif user enables pv-event.
Condition it to kvm_pv_event_enabled() directly?
Re: [PATCH v12 rebased] kvm: notify host when the guest is panicked
Quoted 18 lines · Marcelo Tosatti
Quoted 8 lines · Hu Tao
Quoted 8 lines
Quoted 8 lines
arch/x86/include/uapi/asm/kvm_para.h +0
-0@@ -96,5 +96,7 @@ struct kvm_vcpu_pv_apf_data {#define KVM_PV_EOI_ENABLED KVM_PV_EOI_MASK#define KVM_PV_EOI_DISABLED 0x0Quoted 8 lines
Quoted 5 lines
arch/x86/include/uapi/asm/kvm_para.h struct kvm_vcpu_pv_apf_data { · line 100
Quoted 2 lines
arch/x86/include/uapi/asm/kvm_para.h +2
-0+#define KVM_PV_EVENT_PORT (0x505UL) +No need for the ioport to be hard coded. What are the options to communicate an address to the guest? An MSR, via ACPI?
I'm not quite understanding here. By 'address', you mean an ioport? how to communicate an address? (I have little knowledge about ACPI)
Quoted 7 lines
Yes, the ioport. The address of the ioport should not be fixed (for example future emulated board could use that fixed ioport address,
0x505UL).One option is to pass the address via an MSR. Yes, that is probably the best option because there is no dependency on ACPI.
Why dependency on ACPI is problematic? ACPI is the standard way on x86 to enumerate platform devices. Passing it through MSR makes this panic device CPU interface which it is not. And since relying on #GP to detect valid MSRs is not good interface we will have to guard it by cpuid bit.
--
Gleb.
Re: [PATCH v12 rebased] kvm: notify host when the guest is panicked
Quoted 26 lines · Gleb Natapov
Quoted 18 lines · Marcelo Tosatti
Quoted 8 lines · Hu Tao
Quoted 8 lines
Quoted 8 lines
arch/x86/include/uapi/asm/kvm_para.h +0
-0@@ -96,5 +96,7 @@ struct kvm_vcpu_pv_apf_data {#define KVM_PV_EOI_ENABLED KVM_PV_EOI_MASK#define KVM_PV_EOI_DISABLED 0x0Quoted 8 lines
Quoted 5 lines
arch/x86/include/uapi/asm/kvm_para.h struct kvm_vcpu_pv_apf_data { · line 100
Quoted 2 lines
arch/x86/include/uapi/asm/kvm_para.h +2
-0+#define KVM_PV_EVENT_PORT (0x505UL) +No need for the ioport to be hard coded. What are the options to communicate an address to the guest? An MSR, via ACPI?
I'm not quite understanding here. By 'address', you mean an ioport? how to communicate an address? (I have little knowledge about ACPI)
Quoted 7 lines
Yes, the ioport. The address of the ioport should not be fixed (for example future emulated board could use that fixed ioport address,
0x505UL).One option is to pass the address via an MSR. Yes, that is probably the best option because there is no dependency on ACPI.
Quoted 7 lines
Why dependency on ACPI is problematic? ACPI is the standard way on x86 to enumerate platform devices. Passing it through MSR makes this panic device CPU interface which it is not. And since relying on #GP to detect valid MSRs is not good interface we will have to guard it by cpuid bit.
--
Gleb.
KVM guest <-> KVM host interface is not dependent on ACPI, so far. Say, its possible to use a Linux guest without ACPI and have KVM paravirt fully functional.
Re: [PATCH v12 rebased] kvm: notify host when the guest is panicked
Quoted 32 lines · Marcelo Tosatti
Quoted 31 lines · Gleb Natapov
Quoted 18 lines · Marcelo Tosatti
Quoted 8 lines · Hu Tao
Quoted 8 lines
Quoted 8 lines
arch/x86/include/uapi/asm/kvm_para.h +0
-0@@ -96,5 +96,7 @@ struct kvm_vcpu_pv_apf_data {#define KVM_PV_EOI_ENABLED KVM_PV_EOI_MASK#define KVM_PV_EOI_DISABLED 0x0Quoted 8 lines
Quoted 5 lines
arch/x86/include/uapi/asm/kvm_para.h struct kvm_vcpu_pv_apf_data { · line 100
Quoted 2 lines
arch/x86/include/uapi/asm/kvm_para.h +2
-0+#define KVM_PV_EVENT_PORT (0x505UL) +No need for the ioport to be hard coded. What are the options to communicate an address to the guest? An MSR, via ACPI?
I'm not quite understanding here. By 'address', you mean an ioport? how to communicate an address? (I have little knowledge about ACPI)
Quoted 7 lines
Yes, the ioport. The address of the ioport should not be fixed (for example future emulated board could use that fixed ioport address,
0x505UL).One option is to pass the address via an MSR. Yes, that is probably the best option because there is no dependency on ACPI.
Why dependency on ACPI is problematic? ACPI is the standard way on x86 to enumerate platform devices. Passing it through MSR makes this panic device CPU interface which it is not. And since relying on #GP to detect valid MSRs is not good interface we will have to guard it by cpuid bit.
Quoted 6 lines
Quoted 2 lines
--
Gleb.KVM guest <-> KVM host interface is not dependent on ACPI, so far. Say, its possible to use a Linux guest without ACPI and have KVM paravirt fully functional.
This is not KVM guest <-> KVM host interface though. This is yet another device. We could implement real impi device that have crash reporting capability, but decided to go with something simpler. Without ACPI guest will not be able to power down itself too, but this is not the reason for us to introduce non-ACPI interface for power down.
--
Gleb.
A message that is not in the archive (sent off-list or not yet received): [email protected]
Re: [PATCH v12 rebased] kvm: notify host when the guest is panicked
Quoted 46 lines · Marcelo Tosatti
Quoted 36 lines · Gleb Natapov
Quoted 35 lines · Marcelo Tosatti
Quoted 33 lines · Gleb Natapov
Quoted 18 lines · Marcelo Tosatti
Quoted 8 lines · Hu Tao
Quoted 8 lines
Quoted 8 lines
arch/x86/include/uapi/asm/kvm_para.h +0
-0@@ -96,5 +96,7 @@ struct kvm_vcpu_pv_apf_data {#define KVM_PV_EOI_ENABLED KVM_PV_EOI_MASK#define KVM_PV_EOI_DISABLED 0x0Quoted 8 lines
Quoted 5 lines
arch/x86/include/uapi/asm/kvm_para.h struct kvm_vcpu_pv_apf_data { · line 100
Quoted 2 lines
arch/x86/include/uapi/asm/kvm_para.h +2
-0+#define KVM_PV_EVENT_PORT (0x505UL) +No need for the ioport to be hard coded. What are the options to communicate an address to the guest? An MSR, via ACPI?
I'm not quite understanding here. By 'address', you mean an ioport? how to communicate an address? (I have little knowledge about ACPI)
Quoted 7 lines
Yes, the ioport. The address of the ioport should not be fixed (for example future emulated board could use that fixed ioport address,
0x505UL).One option is to pass the address via an MSR. Yes, that is probably the best option because there is no dependency on ACPI.
Why dependency on ACPI is problematic? ACPI is the standard way on x86 to enumerate platform devices. Passing it through MSR makes this panic device CPU interface which it is not. And since relying on #GP to detect valid MSRs is not good interface we will have to guard it by cpuid bit.
--
Gleb.Quoted 8 lines
Quoted 3 lines
KVM guest <-> KVM host interface is not dependent on ACPI, so far. Say, its possible to use a Linux guest without ACPI and have KVM paravirt fully functional.
This is not KVM guest <-> KVM host interface though. This is yet another device. We could implement real impi device that have crash reporting capability, but decided to go with something simpler. Without ACPI guest will not be able to power down itself too, but this is not the reason for us to introduce non-ACPI interface for power down.
Quoted 4 lines
Sure (its more of an aesthetic/organizational point, i guess).
Anyway, one problem with ACPI is whether its initialized early enough (which is the whole point of PIO the x86 specific interface).
ACPI is needed pretty early in the boot process.
--
Gleb.
PATCH v12 1/8 preserve cpu runstate
In reply to Hu TaoThis patch enables preservation of cpu runstate during save/load vm. So when a vm is restored from snapshot, the cpu runstate is restored, too.
See following example:
# save two vms: one is running, the other is paused (qemu) info status VM status: running (qemu) savevm running (qemu) stop (qemu) info status VM status: paused (qemu) savevm paused
# restore the one running (qemu) info status VM status: paused (qemu) loadvm running (qemu) info status VM status: running
# restore the one paused (qemu) loadvm paused (qemu) info status VM status: paused (qemu) cont (qemu)info status VM status: running
--- include/sysemu/sysemu.h | 2 ++ migration.c | 6 +----- monitor.c | 5 ++--- savevm.c | 1 + vl.c | 34 ++++++++++++++++++++++++++++++++++ 5 files changed, 40 insertions(+), 8 deletions(-)
include/sysemu/sysemu.h +2 -0
@@ -19,6 +19,8 @@ extern uint8_t qemu_uuid[];int qemu_uuid_parse (const char *str,uint8_t *uuid);#define UUID_FMT "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx" +void save_run_state (void ); +void load_run_state (void );bool runstate_check (RunState state);void runstate_set (RunState new_state);int runstate_is_running (void );
migration.c +1 -5
@@ -108,11 +108,7 @@ static void process_incoming_migration_co(void *opaque)/* Make sure all file formats flush their mutable metadata */ bdrv_invalidate_cache_all (); -if (autostart) { -vm_start (); - }else { -runstate_set (RUN_STATE_PAUSED ); - } +load_run_state (); }static void enter_migration_coroutine (void *opaque)
monitor.c +2 -3
@@ -2059,13 +2059,12 @@ void qmp_closefd(const char *fdname, Error **errp)static void do_loadvm (Monitor *mon,const QDict *qdict) { -int saved_vm_running =runstate_is_running ();const char *name =qdict_get_str (qdict,"name" );vm_stop (RUN_STATE_RESTORE_VM ); -if (load_vmstate (name) ==0 && saved_vm_running) { -vm_start (); +if (load_vmstate (name) ==0 ) { +load_run_state (); } }
savevm.c +1 -0
@@ -2112,6 +2112,7 @@ void do_savevm(Monitor *mon, const QDict *qdict) } saved_vm_running =runstate_is_running (); +save_run_state ();vm_stop (RUN_STATE_SAVE_VM );memset (sn,0 ,sizeof (*sn));
vl.c +34 -0
@@ -520,6 +520,7 @@ static int default_driver_check(QemuOpts *opts, void *opaque)/* QEMU state */ static RunState current_run_state =RUN_STATE_PRELAUNCH ; +static RunState saved_run_state =RUN_STATE_PRELAUNCH ; typedef struct { RunState from;
@@ -543,6 +544,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_PAUSED, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_POSTMIGRATE, RUN_STATE_RUNNING }, + { RUN_STATE_POSTMIGRATE, RUN_STATE_PAUSED }, { RUN_STATE_POSTMIGRATE, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_PRELAUNCH, RUN_STATE_RUNNING },
@@ -553,6 +555,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_FINISH_MIGRATE, RUN_STATE_POSTMIGRATE }, { RUN_STATE_RESTORE_VM, RUN_STATE_RUNNING }, + { RUN_STATE_RESTORE_VM, RUN_STATE_PAUSED }, { RUN_STATE_RUNNING, RUN_STATE_DEBUG }, { RUN_STATE_RUNNING, RUN_STATE_INTERNAL_ERROR },
@@ -582,11 +585,39 @@ static const RunStateTransition runstate_transitions_def[] = {static bool runstate_valid_transitions[RUN_STATE_MAX ][RUN_STATE_MAX ]; +void save_run_state (void ) +{ + saved_run_state = current_run_state; +} + +void load_run_state (void ) +{ +if (saved_run_state ==RUN_STATE_RUNNING ) { +vm_start (); + }else if (!runstate_check (saved_run_state)) { +runstate_set (saved_run_state); + }else { + ;/* leave unchanged */ + } +} +bool runstate_check (RunState state) {return current_run_state == state; } +static void runstate_save (QEMUFile *f,void *opaque) +{ +qemu_put_byte (f, saved_run_state); +} + +static int runstate_load (QEMUFile *f,void *opaque,int version_id) +{ + saved_run_state =qemu_get_byte (f); + +return 0 ; +} +static void runstate_init (void ) {const RunStateTransition *p;
@@ -596,6 +627,9 @@ static void runstate_init(void)for (p = &runstate_transitions_def[0 ]; p->from !=RUN_STATE_MAX ; p++) { runstate_valid_transitions[p->from][p->to] = true; } + +register_savevm (NULL ,"runstate" ,0 ,1 , + runstate_save, runstate_load,NULL ); }/* This function will abort() on invalid state transitions */
Signature · 1 line
1.8.0.1.240.ge8a1f5a
Re: [PATCH v12 rebased 1/8] preserve cpu runstate
Quoted 31 lines · Hu Tao
This patch enables preservation of cpu runstate during save/load vm. So when a vm is restored from snapshot, the cpu runstate is restored, too.
See following example:
# save two vms: one is running, the other is paused (qemu) info status VM status: running (qemu) savevm running (qemu) stop (qemu) info status VM status: paused (qemu) savevm paused# restore the one running (qemu) info status VM status: paused (qemu) loadvm running (qemu) info status VM status: running# restore the one paused (qemu) loadvm paused (qemu) info status VM status: paused (qemu) cont (qemu)info status VM status: running
Quoted 1 line
Signed-off-by Hu Tao <[email protected]>
Lack of pause state on guest images is annoying.
Fail to see why the panic feature depends on preservation of cpu runstate.
Quoted 123 lines
include/sysemu/sysemu.h | 2 ++ migration.c | 6 +----- monitor.c | 5 ++--- savevm.c | 1 + vl.c | 34 ++++++++++++++++++++++++++++++++++ 5 files changed, 40 insertions(+), 8 deletions(-)include/sysemu/sysemu.h +2
-0@@ -19,6 +19,8 @@ extern uint8_t qemu_uuid[];int qemu_uuid_parse (const char *str,uint8_t *uuid);#define UUID_FMT "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx" +void save_run_state (void ); +void load_run_state (void );bool runstate_check (RunState state);void runstate_set (RunState new_state);int runstate_is_running (void );migration.c +1
-5@@ -108,11 +108,7 @@ static void process_incoming_migration_co(void *opaque)/* Make sure all file formats flush their mutable metadata */ bdrv_invalidate_cache_all (); -if (autostart) { -vm_start (); - }else { -runstate_set (RUN_STATE_PAUSED ); - } +load_run_state (); }static void enter_migration_coroutine (void *opaque)monitor.c +2
-3@@ -2059,13 +2059,12 @@ void qmp_closefd(const char *fdname, Error **errp)static void do_loadvm (Monitor *mon,const QDict *qdict) { -int saved_vm_running =runstate_is_running ();const char *name =qdict_get_str (qdict,"name" );vm_stop (RUN_STATE_RESTORE_VM ); -if (load_vmstate (name) ==0 && saved_vm_running) { -vm_start (); +if (load_vmstate (name) ==0 ) { +load_run_state (); } }savevm.c +1
-0@@ -2112,6 +2112,7 @@ void do_savevm(Monitor *mon, const QDict *qdict) } saved_vm_running =runstate_is_running (); +save_run_state ();vm_stop (RUN_STATE_SAVE_VM );memset (sn,0 ,sizeof (*sn));vl.c +20
-0@@ -520,6 +520,7 @@ static int default_driver_check(QemuOpts *opts, void *opaque)/* QEMU state */ static RunState current_run_state =RUN_STATE_PRELAUNCH ; +static RunState saved_run_state =RUN_STATE_PRELAUNCH ; typedef struct { RunState from;@@ -543,6 +544,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_PAUSED, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_POSTMIGRATE, RUN_STATE_RUNNING }, + { RUN_STATE_POSTMIGRATE, RUN_STATE_PAUSED }, { RUN_STATE_POSTMIGRATE, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_PRELAUNCH, RUN_STATE_RUNNING },@@ -553,6 +555,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_FINISH_MIGRATE, RUN_STATE_POSTMIGRATE }, { RUN_STATE_RESTORE_VM, RUN_STATE_RUNNING }, + { RUN_STATE_RESTORE_VM, RUN_STATE_PAUSED }, { RUN_STATE_RUNNING, RUN_STATE_DEBUG }, { RUN_STATE_RUNNING, RUN_STATE_INTERNAL_ERROR },@@ -582,11 +585,39 @@ static const RunStateTransition runstate_transitions_def[] = {static bool runstate_valid_transitions[RUN_STATE_MAX ][RUN_STATE_MAX ]; +void save_run_state (void ) +{ + saved_run_state = current_run_state; +} + +void load_run_state (void ) +{ +if (saved_run_state ==RUN_STATE_RUNNING ) { +vm_start (); + }else if (!runstate_check (saved_run_state)) { +runstate_set (saved_run_state); + }else { + ;/* leave unchanged */ + } +} +bool runstate_check (RunState state) {return current_run_state == state; } +static void runstate_save (QEMUFile *f,void *opaque)
vl.c static const RunStateTransition runstate_transitions_def[] = { · line 619
Quoted 10 lines
vl.c +10
-0+{ +qemu_put_byte (f, saved_run_state); +} + +static int runstate_load (QEMUFile *f,void *opaque,int version_id) +{ + saved_run_state =qemu_get_byte (f); + +return 0 ; +}
This breaks loading images without support for runstate information. Is it possible to overcome this limitation?
Would be happier if this patch could be debated on QEMU list.
Re: [PATCH v12 rebased 1/8] preserve cpu runstate
Quoted 32 lines · Marcelo Tosatti
Quoted 31 lines · Hu Tao
This patch enables preservation of cpu runstate during save/load vm. So when a vm is restored from snapshot, the cpu runstate is restored, too.
See following example:
# save two vms: one is running, the other is paused (qemu) info status VM status: running (qemu) savevm running (qemu) stop (qemu) info status VM status: paused (qemu) savevm paused# restore the one running (qemu) info status VM status: paused (qemu) loadvm running (qemu) info status VM status: running# restore the one paused (qemu) loadvm paused (qemu) info status VM status: paused (qemu) cont (qemu)info status VM status: running
Quoted 6 lines
Quoted 1 line
Signed-off-by Hu Tao <[email protected]>Lack of pause state on guest images is annoying.
Fail to see why the panic feature depends on preservation of cpu runstate.
To preserve the panic state if guest panic happens in the midway of migration.
Quoted 123 lines
Quoted 123 lines
include/sysemu/sysemu.h | 2 ++ migration.c | 6 +----- monitor.c | 5 ++--- savevm.c | 1 + vl.c | 34 ++++++++++++++++++++++++++++++++++ 5 files changed, 40 insertions(+), 8 deletions(-)include/sysemu/sysemu.h +2
-0@@ -19,6 +19,8 @@ extern uint8_t qemu_uuid[];int qemu_uuid_parse (const char *str,uint8_t *uuid);#define UUID_FMT "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx" +void save_run_state (void ); +void load_run_state (void );bool runstate_check (RunState state);void runstate_set (RunState new_state);int runstate_is_running (void );migration.c +1
-5@@ -108,11 +108,7 @@ static void process_incoming_migration_co(void *opaque)/* Make sure all file formats flush their mutable metadata */ bdrv_invalidate_cache_all (); -if (autostart) { -vm_start (); - }else { -runstate_set (RUN_STATE_PAUSED ); - } +load_run_state (); }static void enter_migration_coroutine (void *opaque)monitor.c +2
-3@@ -2059,13 +2059,12 @@ void qmp_closefd(const char *fdname, Error **errp)static void do_loadvm (Monitor *mon,const QDict *qdict) { -int saved_vm_running =runstate_is_running ();const char *name =qdict_get_str (qdict,"name" );vm_stop (RUN_STATE_RESTORE_VM ); -if (load_vmstate (name) ==0 && saved_vm_running) { -vm_start (); +if (load_vmstate (name) ==0 ) { +load_run_state (); } }savevm.c +1
-0@@ -2112,6 +2112,7 @@ void do_savevm(Monitor *mon, const QDict *qdict) } saved_vm_running =runstate_is_running (); +save_run_state ();vm_stop (RUN_STATE_SAVE_VM );memset (sn,0 ,sizeof (*sn));vl.c +19
-0@@ -520,6 +520,7 @@ static int default_driver_check(QemuOpts *opts, void *opaque)/* QEMU state */ static RunState current_run_state =RUN_STATE_PRELAUNCH ; +static RunState saved_run_state =RUN_STATE_PRELAUNCH ; typedef struct { RunState from;@@ -543,6 +544,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_PAUSED, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_POSTMIGRATE, RUN_STATE_RUNNING }, + { RUN_STATE_POSTMIGRATE, RUN_STATE_PAUSED }, { RUN_STATE_POSTMIGRATE, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_PRELAUNCH, RUN_STATE_RUNNING },@@ -553,6 +555,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_FINISH_MIGRATE, RUN_STATE_POSTMIGRATE }, { RUN_STATE_RESTORE_VM, RUN_STATE_RUNNING }, + { RUN_STATE_RESTORE_VM, RUN_STATE_PAUSED }, { RUN_STATE_RUNNING, RUN_STATE_DEBUG }, { RUN_STATE_RUNNING, RUN_STATE_INTERNAL_ERROR },@@ -582,11 +585,39 @@ static const RunStateTransition runstate_transitions_def[] = {static bool runstate_valid_transitions[RUN_STATE_MAX ][RUN_STATE_MAX ]; +void save_run_state (void ) +{ + saved_run_state = current_run_state; +} + +void load_run_state (void ) +{ +if (saved_run_state ==RUN_STATE_RUNNING ) { +vm_start (); + }else if (!runstate_check (saved_run_state)) { +runstate_set (saved_run_state); + }else { + ;/* leave unchanged */ + } +} +bool runstate_check (RunState state) {return current_run_state == state; }
Quoted 14 lines
vl.c static const RunStateTransition runstate_transitions_def[] = { · line 619
Quoted 11 lines
vl.c +11
-0+static void runstate_save (QEMUFile *f,void *opaque) +{ +qemu_put_byte (f, saved_run_state); +} + +static int runstate_load (QEMUFile *f,void *opaque,int version_id) +{ + saved_run_state =qemu_get_byte (f); + +return 0 ; +}This breaks loading images without support for runstate information. Is it possible to overcome this limitation?
It's successful to load images without support for runstate information, but trying to set run state to RUN_STATE_PRELAUNCH(the default value of saved_run_state), which is invalid. The problem can be solved by setting the default value of saved_run_state to RUN_STATE_RUNNING.
Quoted 2 lines
Would be happier if this patch could be debated on QEMU list.
Signature · 2 lines
Regards, Hu Tao
PATCH v12 2/8 start vm after resetting it
In reply to Hu TaoFrom: Wen Congyang <[email protected]>
The guest should run after resetting it, but it does not run if its old state is RUN_STATE_INTERNAL_ERROR or RUN_STATE_PAUSED.
We don't set runstate to RUN_STATE_PAUSED when resetting the guest, so the runstate will be changed from RUN_STATE_INTERNAL_ERROR or RUN_STATE_PAUSED to RUN_STATE_RUNNING(not RUN_STATE_PAUSED).
--- include/block/block.h | 2 ++ qmp.c | 2 +- vl.c | 7 ++++--- 3 files changed, 7 insertions(+), 4 deletions(-)
include/block/block.h +2 -0
@@ -366,6 +366,8 @@ void bdrv_disable_copy_on_read(BlockDriverState *bs);void bdrv_set_in_use (BlockDriverState *bs,int in_use);int bdrv_in_use (BlockDriverState *bs); +void iostatus_bdrv_it (void *opaque,BlockDriverState *bs); +#ifdef CONFIG_LINUX_AIO int raw_get_aio_fd (BlockDriverState *bs);#else
qmp.c +1 -1
@@ -130,7 +130,7 @@ SpiceInfo *qmp_query_spice(Error **errp) };#endif -static void iostatus_bdrv_it (void *opaque,BlockDriverState *bs) +void iostatus_bdrv_it (void *opaque,BlockDriverState *bs) {bdrv_iostatus_reset (bs); }
vl.c +4 -3
@@ -534,7 +534,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_INMIGRATE, RUN_STATE_RUNNING }, { RUN_STATE_INMIGRATE, RUN_STATE_PAUSED }, - { RUN_STATE_INTERNAL_ERROR, RUN_STATE_PAUSED }, + { RUN_STATE_INTERNAL_ERROR, RUN_STATE_RUNNING }, { RUN_STATE_INTERNAL_ERROR, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_IO_ERROR, RUN_STATE_RUNNING },
@@ -569,7 +569,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_SAVE_VM, RUN_STATE_RUNNING }, - { RUN_STATE_SHUTDOWN, RUN_STATE_PAUSED }, + { RUN_STATE_SHUTDOWN, RUN_STATE_RUNNING }, { RUN_STATE_SHUTDOWN, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_DEBUG, RUN_STATE_SUSPENDED },
@@ -1951,7 +1951,8 @@ static bool main_loop_should_exit(void)resume_all_vcpus ();if (runstate_check (RUN_STATE_INTERNAL_ERROR ) ||runstate_check (RUN_STATE_SHUTDOWN )) { -runstate_set (RUN_STATE_PAUSED ); +bdrv_iterate (iostatus_bdrv_it,NULL ); +vm_start (); } }if (qemu_wakeup_requested ()) {
Signature · 1 line
1.8.0.1.240.ge8a1f5a
Re: [PATCH v12 rebased 2/8] start vm after resetting it
Quoted 8 lines · Hu Tao
From: Wen Congyang <[email protected]>
The guest should run after resetting it, but it does not run if its old state is
RUN_STATE_INTERNAL_ERRORorRUN_STATE_PAUSED.We don't set runstate to
RUN_STATE_PAUSEDwhen resetting the guest, so the runstate will be changed fromRUN_STATE_INTERNAL_ERRORorRUN_STATE_PAUSEDtoRUN_STATE_RUNNING(not RUN_STATE_PAUSED).
It appears the last hunk will automatically reset state from RUN_STATE_INTERNAL_ERROR to RUN_STATE_RUNNING ?
I suppose the transition table allows, from RUN_STATE_INTERNAL_ERROR:
<monitor> system_reset
<monitor> cont
To resume the machine?
Quoted 73 lines
Signed-off-by Wen Congyang <[email protected]>--- include/block/block.h | 2 ++ qmp.c | 2 +- vl.c | 7 ++++--- 3 files changed, 7 insertions(+), 4 deletions(-)include/block/block.h +2
-0@@ -366,6 +366,8 @@ void bdrv_disable_copy_on_read(BlockDriverState *bs);void bdrv_set_in_use (BlockDriverState *bs,int in_use);int bdrv_in_use (BlockDriverState *bs); +void iostatus_bdrv_it (void *opaque,BlockDriverState *bs); +#ifdef CONFIG_LINUX_AIO int raw_get_aio_fd (BlockDriverState *bs);#else qmp.c +1
-1@@ -130,7 +130,7 @@ SpiceInfo *qmp_query_spice(Error **errp) };#endif -static void iostatus_bdrv_it (void *opaque,BlockDriverState *bs) +void iostatus_bdrv_it (void *opaque,BlockDriverState *bs) {bdrv_iostatus_reset (bs); }vl.c +4
-3@@ -534,7 +534,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_INMIGRATE, RUN_STATE_RUNNING }, { RUN_STATE_INMIGRATE, RUN_STATE_PAUSED }, - { RUN_STATE_INTERNAL_ERROR, RUN_STATE_PAUSED }, + { RUN_STATE_INTERNAL_ERROR, RUN_STATE_RUNNING }, { RUN_STATE_INTERNAL_ERROR, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_IO_ERROR, RUN_STATE_RUNNING },@@ -569,7 +569,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_SAVE_VM, RUN_STATE_RUNNING }, - { RUN_STATE_SHUTDOWN, RUN_STATE_PAUSED }, + { RUN_STATE_SHUTDOWN, RUN_STATE_RUNNING }, { RUN_STATE_SHUTDOWN, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_DEBUG, RUN_STATE_SUSPENDED },@@ -1951,7 +1951,8 @@ static bool main_loop_should_exit(void)resume_all_vcpus ();if (runstate_check (RUN_STATE_INTERNAL_ERROR ) ||runstate_check (RUN_STATE_SHUTDOWN )) { -runstate_set (RUN_STATE_PAUSED ); +bdrv_iterate (iostatus_bdrv_it,NULL ); +vm_start (); } }if (qemu_wakeup_requested ()) {Signature · 6 lines
1.8.0.1.240.ge8a1f5a -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v12 rebased 2/8] start vm after resetting it
Quoted 6 lines · Marcelo Tosatti
Quoted 5 lines · Hu Tao
From: Wen Congyang <[email protected]>
The guest should run after resetting it, but it does not run if its old state is
RUN_STATE_INTERNAL_ERRORorRUN_STATE_PAUSED.
Quoted 6 lines
Quoted 3 lines
We don't set runstate to
RUN_STATE_PAUSEDwhen resetting the guest, so the runstate will be changed fromRUN_STATE_INTERNAL_ERRORorRUN_STATE_PAUSEDtoRUN_STATE_RUNNING(not RUN_STATE_PAUSED).It appears the last hunk will automatically reset state from
RUN_STATE_INTERNAL_ERRORtoRUN_STATE_RUNNING?
Yes.
Quoted 7 lines
I suppose the transition table allows, from
RUN_STATE_INTERNAL_ERROR:<monitor>
system_reset
<monitor> contTo resume the machine?
True.
I think the purpose of this patch is to always reset and _run_ the guest by system_reset', avoiding an additional cont' following `system_reset'.
Quoted 74 lines
Quoted 74 lines
Signed-off-by Wen Congyang <[email protected]>--- include/block/block.h | 2 ++ qmp.c | 2 +- vl.c | 7 ++++--- 3 files changed, 7 insertions(+), 4 deletions(-)include/block/block.h +2
-0@@ -366,6 +366,8 @@ void bdrv_disable_copy_on_read(BlockDriverState *bs);void bdrv_set_in_use (BlockDriverState *bs,int in_use);int bdrv_in_use (BlockDriverState *bs); +void iostatus_bdrv_it (void *opaque,BlockDriverState *bs); +#ifdef CONFIG_LINUX_AIO int raw_get_aio_fd (BlockDriverState *bs);#else qmp.c +1
-1@@ -130,7 +130,7 @@ SpiceInfo *qmp_query_spice(Error **errp) };#endif -static void iostatus_bdrv_it (void *opaque,BlockDriverState *bs) +void iostatus_bdrv_it (void *opaque,BlockDriverState *bs) {bdrv_iostatus_reset (bs); }vl.c +4
-3@@ -534,7 +534,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_INMIGRATE, RUN_STATE_RUNNING }, { RUN_STATE_INMIGRATE, RUN_STATE_PAUSED }, - { RUN_STATE_INTERNAL_ERROR, RUN_STATE_PAUSED }, + { RUN_STATE_INTERNAL_ERROR, RUN_STATE_RUNNING }, { RUN_STATE_INTERNAL_ERROR, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_IO_ERROR, RUN_STATE_RUNNING },@@ -569,7 +569,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_SAVE_VM, RUN_STATE_RUNNING }, - { RUN_STATE_SHUTDOWN, RUN_STATE_PAUSED }, + { RUN_STATE_SHUTDOWN, RUN_STATE_RUNNING }, { RUN_STATE_SHUTDOWN, RUN_STATE_FINISH_MIGRATE }, { RUN_STATE_DEBUG, RUN_STATE_SUSPENDED },@@ -1951,7 +1951,8 @@ static bool main_loop_should_exit(void)resume_all_vcpus ();if (runstate_check (RUN_STATE_INTERNAL_ERROR ) ||runstate_check (RUN_STATE_SHUTDOWN )) { -runstate_set (RUN_STATE_PAUSED ); +bdrv_iterate (iostatus_bdrv_it,NULL ); +vm_start (); } }if (qemu_wakeup_requested ()) {Signature · 6 lines
1.8.0.1.240.ge8a1f5a -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Signature · 2 lines
Regards, Hu Tao
Re: [PATCH v12 rebased 2/8] start vm after resetting it
Quoted 22 lines · Hu Tao
Quoted 6 lines · Marcelo Tosatti
Quoted 5 lines · Hu Tao
From: Wen Congyang <[email protected]>
The guest should run after resetting it, but it does not run if its old state is
RUN_STATE_INTERNAL_ERRORorRUN_STATE_PAUSED.Quoted 6 lines
Quoted 3 lines
We don't set runstate to
RUN_STATE_PAUSEDwhen resetting the guest, so the runstate will be changed fromRUN_STATE_INTERNAL_ERRORorRUN_STATE_PAUSEDtoRUN_STATE_RUNNING(not RUN_STATE_PAUSED).It appears the last hunk will automatically reset state from
RUN_STATE_INTERNAL_ERRORtoRUN_STATE_RUNNING?Yes.
Quoted 6 lines
I suppose the transition table allows, from
RUN_STATE_INTERNAL_ERROR:<monitor>
system_reset
<monitor> cont
Quoted 6 lines
Quoted 1 line
To resume the machine?
True.
I think the purpose of this patch is to always reset and _run_ the guest by
system_reset', avoiding an additionalcont' following `system_reset'.
Unclear why its essential to the feature being proposed?
PATCH v12 3/8 update kernel headers
In reply to Hu Taoupdate kernel headers to add pv event macros.
--- linux-headers/asm-x86/kvm_para.h | 1 + linux-headers/linux/kvm_para.h | 6 ++++++ 2 files changed, 7 insertions(+)
linux-headers/asm-x86/kvm_para.h +1 -0
@@ -96,5 +96,6 @@ struct kvm_vcpu_pv_apf_data {#define KVM_PV_EOI_ENABLED KVM_PV_EOI_MASK#define KVM_PV_EOI_DISABLED 0x0 +#define KVM_PV_EVENT_PORT (0x505UL)#endif /* _ASM_X86_KVM_PARA_H */
linux-headers/linux/kvm_para.h +6 -0
@@ -20,6 +20,12 @@#define KVM_HC_FEATURES 3#define KVM_HC_PPC_MAP_MAGIC_PAGE 4 +/* The bit of supported pv event */ +#define KVM_PV_FEATURE_PANICKED 0 + +/* The pv event value */ +#define KVM_PV_EVENT_PANICKED 1 +/* * hypercalls use architecture specific */
Signature · 1 line
1.8.0.1.240.ge8a1f5a
PATCH v12 4/8 add a new runstate: RUN_STATE_GUEST_PANICKED
In reply to Hu TaoThe guest will be in this state when it is panicked.
If guest is panicked during live migration, the runstate RUN_STATE_GUEST_PANICKED will be transferred to dest machine.
--- migration.c | 1 + qapi-schema.json | 6 +++++- qmp.c | 3 ++- vl.c | 11 ++++++++++- 4 files changed, 18 insertions(+), 3 deletions(-)
migration.c +1 -0
@@ -705,6 +705,7 @@ static void *buffered_file_thread(void *opaque)int64_t start_time, end_time;DPRINTF ("done iterating\n" ); +save_run_state (); start_time =qemu_get_clock_ms (rt_clock);qemu_system_wakeup_request (QEMU_WAKEUP_REASON_OTHER );if (old_vm_running) {
qapi-schema.json +5 -1
@@ -174,11 +174,15 @@ # @suspended: guest is suspended (ACPI S3) # # @watchdog: the watchdog action is configured to pause and has been triggered +# +# @guest-panicked: the panicked action is configured to pause and has been +# triggered. ## { 'enum': 'RunState', 'data': [ 'debug', 'inmigrate', 'internal-error', 'io-error', 'paused', 'postmigrate', 'prelaunch', 'finish-migrate', 'restore-vm', - 'running', 'save-vm', 'shutdown', 'suspended', 'watchdog' ] } + 'running', 'save-vm', 'shutdown', 'suspended', 'watchdog', + 'guest-panicked' ] } ## # @SnapshotInfo
qmp.c +2 -1
@@ -150,7 +150,8 @@ void qmp_cont(Error **errp)Error *local_err =NULL ;if (runstate_check (RUN_STATE_INTERNAL_ERROR ) || -runstate_check (RUN_STATE_SHUTDOWN )) { +runstate_check (RUN_STATE_SHUTDOWN ) || +runstate_check (RUN_STATE_GUEST_PANICKED )) {error_set (errp,QERR_RESET_REQUIRED );return ; }else if (runstate_check (RUN_STATE_SUSPENDED )) {
vl.c +10 -1
@@ -533,6 +533,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_INMIGRATE, RUN_STATE_RUNNING }, { RUN_STATE_INMIGRATE, RUN_STATE_PAUSED }, + { RUN_STATE_INMIGRATE, RUN_STATE_GUEST_PANICKED }, { RUN_STATE_INTERNAL_ERROR, RUN_STATE_RUNNING }, { RUN_STATE_INTERNAL_ERROR, RUN_STATE_FINISH_MIGRATE },
@@ -546,6 +547,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_POSTMIGRATE, RUN_STATE_RUNNING }, { RUN_STATE_POSTMIGRATE, RUN_STATE_PAUSED }, { RUN_STATE_POSTMIGRATE, RUN_STATE_FINISH_MIGRATE }, + { RUN_STATE_POSTMIGRATE, RUN_STATE_GUEST_PANICKED }, { RUN_STATE_PRELAUNCH, RUN_STATE_RUNNING }, { RUN_STATE_PRELAUNCH, RUN_STATE_FINISH_MIGRATE },
@@ -556,6 +558,7 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_RESTORE_VM, RUN_STATE_RUNNING }, { RUN_STATE_RESTORE_VM, RUN_STATE_PAUSED }, + { RUN_STATE_RESTORE_VM, RUN_STATE_GUEST_PANICKED }, { RUN_STATE_RUNNING, RUN_STATE_DEBUG }, { RUN_STATE_RUNNING, RUN_STATE_INTERNAL_ERROR },
@@ -566,6 +569,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_GUEST_PANICKED }, { RUN_STATE_SAVE_VM, RUN_STATE_RUNNING },
@@ -580,6 +584,10 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_WATCHDOG, RUN_STATE_RUNNING }, { RUN_STATE_WATCHDOG, RUN_STATE_FINISH_MIGRATE }, + { RUN_STATE_GUEST_PANICKED, RUN_STATE_RUNNING }, + { RUN_STATE_GUEST_PANICKED, RUN_STATE_PAUSED }, + { RUN_STATE_GUEST_PANICKED, RUN_STATE_FINISH_MIGRATE }, + { RUN_STATE_MAX, RUN_STATE_MAX }, };
@@ -1950,7 +1958,8 @@ static bool main_loop_should_exit(void)qemu_system_reset (VMRESET_REPORT );resume_all_vcpus ();if (runstate_check (RUN_STATE_INTERNAL_ERROR ) || -runstate_check (RUN_STATE_SHUTDOWN )) { +runstate_check (RUN_STATE_SHUTDOWN ) || +runstate_check (RUN_STATE_GUEST_PANICKED )) {bdrv_iterate (iostatus_bdrv_it,NULL );vm_start (); }
Signature · 1 line
1.8.0.1.240.ge8a1f5a
PATCH v12 5/8 add a new qevent: QEVENT_GUEST_PANICKED
In reply to Hu TaoThis event will be emited when the guest is panicked.
--- include/monitor/monitor.h | 1 + monitor.c | 1 + 2 files changed, 2 insertions(+)
include/monitor/monitor.h +1 -0
@@ -45,6 +45,7 @@ typedef enum MonitorEvent {QEVENT_WAKEUP ,QEVENT_BALLOON_CHANGE ,QEVENT_SPICE_MIGRATE_COMPLETED , + QEVENT_GUEST_PANICKED,/* Add to 'monitor_event_names' array in monitor.c when * defining new events here */
monitor.c +1 -0
@@ -463,6 +463,7 @@ static const char *monitor_event_names[] = { [QEVENT_WAKEUP] = "WAKEUP", [QEVENT_BALLOON_CHANGE] = "BALLOON_CHANGE", [QEVENT_SPICE_MIGRATE_COMPLETED] = "SPICE_MIGRATE_COMPLETED", + [QEVENT_GUEST_PANICKED ] ="GUEST_PANICKED" , };QEMU_BUILD_BUG_ON (ARRAY_SIZE (monitor_event_names) !=QEVENT_MAX )
Signature · 1 line
1.8.0.1.240.ge8a1f5a
PATCH v12 6/8 introduce a new qom device to deal with panicked event
In reply to Hu TaoIf the target is x86/x86_64, the guest's kernel will write 0x01 to the port KVM_PV_EVENT_PORT when it is panciked. This patch introduces a new qom device kvm_pv_ioport to listen this I/O port, and deal with panicked event according to panicked_action's value. The possible actions are:
1. emit QEVENT_GUEST_PANICKED only
2. emit QEVENT_GUEST_PANICKED and pause the guest
3. emit QEVENT_GUEST_PANICKED and poweroff the guest
4. emit QEVENT_GUEST_PANICKED and reset the guest
I/O ports does not work for some targets(for example: s390). And you can implement another qom device, and include it's code into pv_event.c for such target.
Note: if we emit QEVENT_GUEST_PANICKED only, and the management application does not receive this event(the management may not run when the event is emitted), the management won't know the guest is panicked.
--- hw/kvm/Makefile.objs | 2 +- hw/kvm/pv_event.c | 197 +++++++++++++++++++++++++++++++++++++++++++++++++++ hw/pc_piix.c | 5 ++ include/sysemu/kvm.h | 2 + kvm-stub.c | 4 ++ 5 files changed, 209 insertions(+), 1 deletion(-) create mode 100644 hw/kvm/pv_event.c
hw/kvm/Makefile.objs +1 -1
@@ -1 +1 @@ -obj-$(CONFIG_KVM) += clock.o apic.o i8259.o ioapic.o i8254.o pci-assign.o +obj-$(CONFIG_KVM) += clock.o apic.o i8259.o ioapic.o i8254.o pci-assign.o pv_event.o
hw/kvm/pv_event.c new file +197 -0
197 lines not on this page · raw message
hw/pc_piix.c +5 -0
@@ -47,6 +47,7 @@#ifdef CONFIG_XEN # include <xen/hvm/hvm_info_table.h> #endif +#include <linux/kvm_para.h> #define MAX_IDE_BUS 2
@@ -216,6 +217,10 @@ static void pc_init1(MemoryRegion *system_memory,if (pci_enabled) {pc_pci_device_init (pci_bus); } + +if (kvm_enabled ()) { +kvm_pv_event_init (isa_bus); + } }static void pc_init_pci (QEMUMachineInitArgs *args)
include/sysemu/kvm.h +2 -0
@@ -292,4 +292,6 @@ int kvm_irqchip_add_irqfd_notifier(KVMState *s, EventNotifier *n, int virq);int kvm_irqchip_remove_irqfd_notifier (KVMState *s,EventNotifier *n,int virq);void kvm_pc_gsi_handler (void *opaque,int n,int level);void kvm_pc_setup_irq_routing (bool pci_enabled); + +void kvm_pv_event_init (void *opaque);#endif
kvm-stub.c +4 -0
@@ -145,3 +145,7 @@ int kvm_irqchip_remove_irqfd_notifier(KVMState *s, EventNotifier *n, int virq) {return -ENOSYS ; } + +void kvm_pv_event_init (void *opaque) +{ +}
Signature · 1 line
1.8.0.1.240.ge8a1f5a
PATCH v12 7/8 allower the user to disable pv event support
In reply to Hu Tao--- hw/pc_piix.c | 9 ++++++++- qemu-options.hx | 3 ++- vl.c | 4 ++++ 3 files changed, 14 insertions(+), 2 deletions(-)
hw/pc_piix.c +8 -1
@@ -44,6 +44,7 @@#include "exec/memory.h" #include "exec/address-spaces.h" #include "cpu.h" +#include "qemu/config-file.h" #ifdef CONFIG_XEN # include <xen/hvm/hvm_info_table.h> #endif
@@ -86,6 +87,8 @@ static void pc_init1(MemoryRegion *system_memory,MemoryRegion *pci_memory;MemoryRegion *rom_memory;void *fw_cfg =NULL ; +QemuOptsList *list =qemu_find_opts ("machine" ); +bool enable_pv_event = false;pc_cpus_init (cpu_model);pc_acpi_init ("acpi-dsdt.aml" );
@@ -218,7 +221,11 @@ static void pc_init1(MemoryRegion *system_memory,pc_pci_device_init (pci_bus); } -if (kvm_enabled ()) { +if (list && !QTAILQ_EMPTY (&list->head)) { + enable_pv_event =qemu_opt_get_bool (QTAILQ_FIRST (&list->head), +"enable_pv_event" , false); + } +if (kvm_enabled () && enable_pv_event) {kvm_pv_event_init (isa_bus); } }
qemu-options.hx +2 -1
@@ -35,7 +35,8 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \ " kernel_irqchip=on|off controls accelerated irqchip support\n" " kvm_shadow_mem=size of KVM shadow MMU\n" " dump-guest-core=on|off include guest memory in a core dump (default=on)\n" - " mem-merge=on|off controls memory merge support (default: on)\n", + " mem-merge=on|off controls memory merge support (default: on)\n" + " enable_pv_event=on|off controls pv event support (default: off)\n", QEMU_ARCH_ALL) STEXI @item -machine [type=]@var{name}[,prop=@var{value}[,...]]
vl.c +4 -0
@@ -424,6 +424,10 @@ static QemuOptsList qemu_machine_opts = { .name = "usb", .type = QEMU_OPT_BOOL, .help = "Set on/off to enable/disable usb", + }, { + .name = "enable_pv_event", + .type = QEMU_OPT_BOOL, + .help = "handle pv event" }, {/* End of list */ } },
Signature · 1 line
1.8.0.1.240.ge8a1f5a
PATCH v12 8/8 pv event: add document to describe the usage
In reply to Hu Tao--- docs/pv-event.txt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 docs/pv-event.txt
docs/pv-event.txt new file +17 -0
@@ -0,0 +1,17 @@ +KVM PV EVENT +============ + +kvm pv event allows guest OS to notify host OS of some events, for +example, guest panic. Currently, there is one event supported, that +is, guest panic. More events can be added later. + +By default, kvm pv event is disabled. In order to enable it, you have +to specify enable_pv_event=on for -machine command line option, along +with -global kvm_pv_event.panicked_action to specify the action taken +when panic event has occurred. Aviable panic actions are: "none", +"pause", "poweroff" and "reset". Following is example: + + qemu-system-x86_64 -enable-kvm -machine pc-0.12,enable_pv_event=on \ + -global kvm_pv_event.panicked_action=pause <other options> + +kvm pv event needs kvm support.
Signature · 1 line
1.8.0.1.240.ge8a1f5a