Re: [PATCH 10/11] qemu/kvm: kvm hyper-v based guest crash event handling

2015-06-22 Thread Paolo Bonzini


On 22/06/2015 18:05, Denis V. Lunev wrote:
 +void qemu_system_guest_panicked(void)
 +{
 +qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_PAUSE, error_abort);
 +vm_stop(RUN_STATE_GUEST_PANICKED);
 +}
 +

Please call this in pvpanic.c and target-s390x/kvm.c (replacing the
guest_panicked function in that file there) as well.

 @@ -2540,6 +2573,53 @@ static bool host_supports_vmx(void)
  return ecx  CPUID_EXT_VMX;
  }
  
 +int kvm_arch_handle_hv_crash(CPUState *cs)
 +{
 +X86CPU *cpu = X86_CPU(cs);
 +CPUX86State *env = cpu-env;
 +struct {
 +struct kvm_msrs info;
 +struct kvm_msr_entry entries[HV_X64_MSR_CRASH_PARAMS + 1];
 +} msr_data;
 +struct kvm_msr_entry *msrs = msr_data.entries;
 +int ret, n, i;
 +
 +if (!has_msr_hv_crash) {
 +return -EINVAL;
 +}
 +
 +for (n = 0; n  HV_X64_MSR_CRASH_PARAMS; n++) {
 +msrs[n].index = HV_X64_MSR_CRASH_P0 + n;
 +}
 +
 +msrs[n++].index = HV_X64_MSR_CRASH_CTL;
 +msr_data.info = (struct kvm_msrs) {
 +.nmsrs = n,
 +};
 +
 +ret = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_MSRS, msr_data);
 +if (ret  0) {
 +return ret;
 +}
 +
 +for (i = 0; i  ret; i++) {
 +uint32_t index = msrs[i].index;
 +
 +switch (index) {
 +case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4:
 +env-msr_hv_crash_prm[index - HV_X64_MSR_CRASH_P0] = 
 msrs[i].data;
 +break;
 +case HV_X64_MSR_CRASH_CTL:
 +env-msr_hv_crash_ctl = msrs[i].data;
 +break;
 +default:
 +break;
 +}
 +}
 +
 +return 0;
 +}
 +

Is this necessary?  The call to cpu_synchronize_all_states in
qemu_savevm_state_complete should be enough.  If necessary, you can call
it from qemu_system_guest_panicked instead of special casing the crash
MSRs here.

Paolo
--
To unsubscribe from this list: send the line unsubscribe kvm in


Re: [PATCH 10/11] qemu/kvm: kvm hyper-v based guest crash event handling

2015-06-22 Thread Paolo Bonzini
Another one...

On 22/06/2015 18:05, Denis V. Lunev wrote:
 +case KVM_SYSTEM_EVENT_CRASH:
 +if (run-system_event.flags  KVM_SYSTEM_EVENT_FL_HV_CRASH) {
 +kvm_arch_handle_hv_crash(cpu);
 +}
 +qemu_system_guest_panicked();

Please call

kvm_arch_handle_crash(cpu);
qemu_system_guest_panicked();

here, and check the HV_CRASH flag inside x86 specific code.

Paolo

 +ret = 0;
 +break;
--
To unsubscribe from this list: send the line unsubscribe kvm in


[PATCH 10/11] qemu/kvm: kvm hyper-v based guest crash event handling

2015-06-22 Thread Denis V. Lunev
From: Andrey Smetanin asmeta...@virtuozzo.com

KVM Hyper-V based guests can notify hypervisor about
occurred guest crash. This patch does handling of KVM crash event
by sending to libvirt guest panic event that allows to gather
guest crash dump by QEMU/LIBVIRT. Add support of HV_X64_MSR_CRASH_P0-P4,
HV_X64_MSR_CRASH_CTL msrs.

The idea is to provide functionality equal to pvpanic device without
QEMU guest agent for Windows.

The idea is borrowed from Linux HyperV bus driver and validated against
Windows 2k12.

Signed-off-by: Andrey Smetanin asmeta...@virtuozzo.com
Signed-off-by: Denis V. Lunev d...@openvz.org
CC: Paolo Bonzini pbonz...@redhat.com
CC: Andreas Färber afaer...@suse.de
---
 include/sysemu/kvm.h   |  2 ++
 include/sysemu/sysemu.h|  1 +
 kvm-all.c  |  7 
 linux-headers/asm-x86/hyperv.h | 16 +
 linux-headers/linux/kvm.h  |  2 ++
 target-arm/kvm.c   |  5 +++
 target-i386/cpu-qom.h  |  1 +
 target-i386/cpu.c  |  1 +
 target-i386/cpu.h  |  3 ++
 target-i386/kvm.c  | 80 ++
 target-i386/machine.c  | 23 
 target-mips/kvm.c  |  5 +++
 target-ppc/kvm.c   |  5 +++
 target-s390x/kvm.c |  5 +++
 vl.c   |  6 
 15 files changed, 162 insertions(+)

diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index f459fbd..3c0fa02 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -257,6 +257,8 @@ extern const KVMCapabilityInfo 
kvm_arch_required_capabilities[];
 void kvm_arch_pre_run(CPUState *cpu, struct kvm_run *run);
 MemTxAttrs kvm_arch_post_run(CPUState *cpu, struct kvm_run *run);
 
+int kvm_arch_handle_hv_crash(CPUState *cpu);
+
 int kvm_arch_handle_exit(CPUState *cpu, struct kvm_run *run);
 
 int kvm_arch_process_async_events(CPUState *cpu);
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index df80951..70164c9 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -68,6 +68,7 @@ int qemu_reset_requested_get(void);
 void qemu_system_killed(int signal, pid_t pid);
 void qemu_devices_reset(void);
 void qemu_system_reset(bool report);
+void qemu_system_guest_panicked(void);
 
 void qemu_add_exit_notifier(Notifier *notify);
 void qemu_remove_exit_notifier(Notifier *notify);
diff --git a/kvm-all.c b/kvm-all.c
index 53e01d4..1528fb5 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1844,6 +1844,13 @@ int kvm_cpu_exec(CPUState *cpu)
 qemu_system_reset_request();
 ret = EXCP_INTERRUPT;
 break;
+case KVM_SYSTEM_EVENT_CRASH:
+if (run-system_event.flags  KVM_SYSTEM_EVENT_FL_HV_CRASH) {
+kvm_arch_handle_hv_crash(cpu);
+}
+qemu_system_guest_panicked();
+ret = 0;
+break;
 default:
 DPRINTF(kvm_arch_handle_exit\n);
 ret = kvm_arch_handle_exit(cpu, run);
diff --git a/linux-headers/asm-x86/hyperv.h b/linux-headers/asm-x86/hyperv.h
index ce6068d..aec7d27 100644
--- a/linux-headers/asm-x86/hyperv.h
+++ b/linux-headers/asm-x86/hyperv.h
@@ -108,6 +108,8 @@
 #define HV_X64_HYPERCALL_PARAMS_XMM_AVAILABLE  (1  4)
 /* Support for a virtual guest idle state is available */
 #define HV_X64_GUEST_IDLE_STATE_AVAILABLE  (1  5)
+/* Guest crash data handler available */
+#define HV_X64_GUEST_CRASH_MSR_AVAILABLE   (1  10)
 
 /*
  * Implementation recommendations. Indicates which behaviors the hypervisor
@@ -199,6 +201,20 @@
 #define HV_X64_MSR_STIMER3_CONFIG  0x40B6
 #define HV_X64_MSR_STIMER3_COUNT   0x40B7
 
+/* Hypev-V guest crash notification MSR's */
+#define HV_X64_MSR_CRASH_P00x4100
+#define HV_X64_MSR_CRASH_P10x4101
+#define HV_X64_MSR_CRASH_P20x4102
+#define HV_X64_MSR_CRASH_P30x4103
+#define HV_X64_MSR_CRASH_P40x4104
+#define HV_X64_MSR_CRASH_CTL   0x4105
+#define HV_X64_MSR_CRASH_CTL_NOTIFY(1ULL  63)
+#define HV_X64_MSR_CRASH_CTL_CONTENTS  \
+   (HV_X64_MSR_CRASH_CTL_NOTIFY)
+
+#define HV_X64_MSR_CRASH_PARAMS\
+   (1 + (HV_X64_MSR_CRASH_P4 - HV_X64_MSR_CRASH_P0))
+
 #define HV_X64_MSR_HYPERCALL_ENABLE0x0001
 #define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT12
 #define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_MASK \
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index fad9e5c..46cb7e0 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -317,6 +317,8 @@ struct kvm_run {
struct {
 #define KVM_SYSTEM_EVENT_SHUTDOWN   1
 #define KVM_SYSTEM_EVENT_RESET  2
+#define KVM_SYSTEM_EVENT_CRASH  3
+#define KVM_SYSTEM_EVENT_FL_HV_CRASH(1ULL