* [Qemu-devel] [PATCH v3 0/9] HyperV equivalent of pvpanic driver
@ 2015-06-30 11:33 Denis V. Lunev
2015-06-30 11:33 ` [Qemu-devel] [PATCH 1/9] kvm/x86: move Hyper-V MSR's/hypercall code into hyperv.c file Denis V. Lunev
` (10 more replies)
0 siblings, 11 replies; 31+ messages in thread
From: Denis V. Lunev @ 2015-06-30 11:33 UTC (permalink / raw)
Cc: kvm, Gleb Natapov, qemu-devel, Paolo Bonzini, Andrey Smetanin,
Denis V. Lunev
Windows 2012 guests can notify hypervisor about occurred guest crash
(Windows bugcheck(BSOD)) by writing specific Hyper-V msrs. This patch does
handling of this MSR's by KVM and sending notification to user space that
allows to gather Windows guest crash dump by QEMU/LIBVIRT.
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.
Changes from v2:
* forbid modification crash ctl msr by guest
* qemu_system_guest_panicked usage in pvpanic and s390x
* hyper-v crash handler move from generic kvm to i386
* hyper-v crash handler: skip fetching crash msrs just mark crash occured
* sync with linux-next 20150629
* patch 11 squashed to patch 10
* patch 9 squashed to patch 7
Changes from v1:
* hyperv code move to hyperv.c
* added read handlers of crash data msrs
* added per vm and per cpu hyperv context structures
* added saving crash msrs inside qemu cpu state
* added qemu fetch and update of crash msrs
* added qemu crash msrs store in cpu state and it's migration
Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Gleb Natapov <gleb@kernel.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
^ permalink raw reply [flat|nested] 31+ messages in thread
* [Qemu-devel] [PATCH 1/9] kvm/x86: move Hyper-V MSR's/hypercall code into hyperv.c file
2015-06-30 11:33 [Qemu-devel] [PATCH v3 0/9] HyperV equivalent of pvpanic driver Denis V. Lunev
@ 2015-06-30 11:33 ` Denis V. Lunev
2015-07-01 0:11 ` Peter Hornyack
2015-06-30 11:33 ` [Qemu-devel] [PATCH 2/9] kvm: introduce vcpu_debug = kvm_debug + vcpu context Denis V. Lunev
` (9 subsequent siblings)
10 siblings, 1 reply; 31+ messages in thread
From: Denis V. Lunev @ 2015-06-30 11:33 UTC (permalink / raw)
Cc: kvm, Gleb Natapov, qemu-devel, Paolo Bonzini, Andrey Smetanin,
Denis V. Lunev
From: Andrey Smetanin <asmetanin@virtuozzo.com>
This patch introduce Hyper-V related source code file - hyperv.c and
per vm and per vcpu hyperv context structures.
All Hyper-V MSR's and hypercall code moved into hyperv.c.
All Hyper-V kvm/vcpu fields moved into appropriate hyperv context
structures. Copyrights and authors information copied from x86.c
to hyperv.c.
Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Gleb Natapov <gleb@kernel.org>
---
arch/x86/include/asm/kvm_host.h | 20 ++-
arch/x86/kvm/Makefile | 4 +-
arch/x86/kvm/hyperv.c | 307 ++++++++++++++++++++++++++++++++++++++++
arch/x86/kvm/hyperv.h | 32 +++++
arch/x86/kvm/lapic.h | 2 +-
arch/x86/kvm/x86.c | 265 +---------------------------------
arch/x86/kvm/x86.h | 5 +
7 files changed, 366 insertions(+), 269 deletions(-)
create mode 100644 arch/x86/kvm/hyperv.c
create mode 100644 arch/x86/kvm/hyperv.h
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index c7fa57b..78616aa 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -358,6 +358,11 @@ struct kvm_mtrr {
struct list_head head;
};
+/* Hyper-V per vcpu emulation context */
+struct kvm_vcpu_hv {
+ u64 hv_vapic;
+};
+
struct kvm_vcpu_arch {
/*
* rip and regs accesses must go through
@@ -514,8 +519,7 @@ struct kvm_vcpu_arch {
/* used for guest single stepping over the given code position */
unsigned long singlestep_rip;
- /* fields used by HYPER-V emulation */
- u64 hv_vapic;
+ struct kvm_vcpu_hv hyperv;
cpumask_var_t wbinvd_dirty_mask;
@@ -586,6 +590,13 @@ struct kvm_apic_map {
struct kvm_lapic *logical_map[16][16];
};
+/* Hyper-V emulation context */
+struct kvm_hv {
+ u64 hv_guest_os_id;
+ u64 hv_hypercall;
+ u64 hv_tsc_page;
+};
+
struct kvm_arch {
unsigned int n_used_mmu_pages;
unsigned int n_requested_mmu_pages;
@@ -643,10 +654,7 @@ struct kvm_arch {
/* reads protected by irq_srcu, writes by irq_lock */
struct hlist_head mask_notifier_list;
- /* fields used by HYPER-V emulation */
- u64 hv_guest_os_id;
- u64 hv_hypercall;
- u64 hv_tsc_page;
+ struct kvm_hv hyperv;
#ifdef CONFIG_KVM_MMU_AUDIT
int audit_point;
diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile
index 67d215c..a1ff508 100644
--- a/arch/x86/kvm/Makefile
+++ b/arch/x86/kvm/Makefile
@@ -12,7 +12,9 @@ kvm-y += $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o \
kvm-$(CONFIG_KVM_ASYNC_PF) += $(KVM)/async_pf.o
kvm-y += x86.o mmu.o emulate.o i8259.o irq.o lapic.o \
- i8254.o ioapic.o irq_comm.o cpuid.o pmu.o mtrr.o
+ i8254.o ioapic.o irq_comm.o cpuid.o pmu.o mtrr.o \
+ hyperv.o
+
kvm-$(CONFIG_KVM_DEVICE_ASSIGNMENT) += assigned-dev.o iommu.o
kvm-intel-y += vmx.o pmu_intel.o
kvm-amd-y += svm.o pmu_amd.o
diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
new file mode 100644
index 0000000..2b49f10
--- /dev/null
+++ b/arch/x86/kvm/hyperv.c
@@ -0,0 +1,307 @@
+/*
+ * KVM Microsoft Hyper-V emulation
+ *
+ * derived from arch/x86/kvm/x86.c
+ *
+ * Copyright (C) 2006 Qumranet, Inc.
+ * Copyright (C) 2008 Qumranet, Inc.
+ * Copyright IBM Corporation, 2008
+ * Copyright 2010 Red Hat, Inc. and/or its affiliates.
+ * Copyright (C) 2015 Andrey Smetanin <asmetanin@virtuozzo.com>
+ *
+ * Authors:
+ * Avi Kivity <avi@qumranet.com>
+ * Yaniv Kamay <yaniv@qumranet.com>
+ * Amit Shah <amit.shah@qumranet.com>
+ * Ben-Ami Yassour <benami@il.ibm.com>
+ * Andrey Smetanin <asmetanin@virtuozzo.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include "x86.h"
+#include "lapic.h"
+#include "hyperv.h"
+
+#include <linux/kvm_host.h>
+#include <trace/events/kvm.h>
+
+#include "trace.h"
+
+static bool kvm_hv_msr_partition_wide(u32 msr)
+{
+ bool r = false;
+
+ switch (msr) {
+ case HV_X64_MSR_GUEST_OS_ID:
+ case HV_X64_MSR_HYPERCALL:
+ case HV_X64_MSR_REFERENCE_TSC:
+ case HV_X64_MSR_TIME_REF_COUNT:
+ r = true;
+ break;
+ }
+
+ return r;
+}
+
+static int kvm_hv_set_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data)
+{
+ struct kvm *kvm = vcpu->kvm;
+ struct kvm_hv *hv = &kvm->arch.hyperv;
+
+ switch (msr) {
+ case HV_X64_MSR_GUEST_OS_ID:
+ hv->hv_guest_os_id = data;
+ /* setting guest os id to zero disables hypercall page */
+ if (!hv->hv_guest_os_id)
+ hv->hv_hypercall &= ~HV_X64_MSR_HYPERCALL_ENABLE;
+ break;
+ case HV_X64_MSR_HYPERCALL: {
+ u64 gfn;
+ unsigned long addr;
+ u8 instructions[4];
+
+ /* if guest os id is not set hypercall should remain disabled */
+ if (!hv->hv_guest_os_id)
+ break;
+ if (!(data & HV_X64_MSR_HYPERCALL_ENABLE)) {
+ hv->hv_hypercall = data;
+ break;
+ }
+ gfn = data >> HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT;
+ addr = gfn_to_hva(kvm, gfn);
+ if (kvm_is_error_hva(addr))
+ return 1;
+ kvm_x86_ops->patch_hypercall(vcpu, instructions);
+ ((unsigned char *)instructions)[3] = 0xc3; /* ret */
+ if (__copy_to_user((void __user *)addr, instructions, 4))
+ return 1;
+ hv->hv_hypercall = data;
+ mark_page_dirty(kvm, gfn);
+ break;
+ }
+ case HV_X64_MSR_REFERENCE_TSC: {
+ u64 gfn;
+ HV_REFERENCE_TSC_PAGE tsc_ref;
+
+ memset(&tsc_ref, 0, sizeof(tsc_ref));
+ hv->hv_tsc_page = data;
+ if (!(data & HV_X64_MSR_TSC_REFERENCE_ENABLE))
+ break;
+ gfn = data >> HV_X64_MSR_TSC_REFERENCE_ADDRESS_SHIFT;
+ if (kvm_write_guest(
+ kvm,
+ gfn << HV_X64_MSR_TSC_REFERENCE_ADDRESS_SHIFT,
+ &tsc_ref, sizeof(tsc_ref)))
+ return 1;
+ mark_page_dirty(kvm, gfn);
+ break;
+ }
+ default:
+ vcpu_unimpl(vcpu, "Hyper-V uhandled wrmsr: 0x%x data 0x%llx\n",
+ msr, data);
+ return 1;
+ }
+ return 0;
+}
+
+static int kvm_hv_set_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data)
+{
+ struct kvm_vcpu_hv *hv = &vcpu->arch.hyperv;
+
+ switch (msr) {
+ case HV_X64_MSR_APIC_ASSIST_PAGE: {
+ u64 gfn;
+ unsigned long addr;
+
+ if (!(data & HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE)) {
+ hv->hv_vapic = data;
+ if (kvm_lapic_enable_pv_eoi(vcpu, 0))
+ return 1;
+ break;
+ }
+ gfn = data >> HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT;
+ addr = kvm_vcpu_gfn_to_hva(vcpu, gfn);
+ if (kvm_is_error_hva(addr))
+ return 1;
+ if (__clear_user((void __user *)addr, PAGE_SIZE))
+ return 1;
+ hv->hv_vapic = data;
+ kvm_vcpu_mark_page_dirty(vcpu, gfn);
+ if (kvm_lapic_enable_pv_eoi(vcpu,
+ gfn_to_gpa(gfn) | KVM_MSR_ENABLED))
+ return 1;
+ break;
+ }
+ case HV_X64_MSR_EOI:
+ return kvm_hv_vapic_msr_write(vcpu, APIC_EOI, data);
+ case HV_X64_MSR_ICR:
+ return kvm_hv_vapic_msr_write(vcpu, APIC_ICR, data);
+ case HV_X64_MSR_TPR:
+ return kvm_hv_vapic_msr_write(vcpu, APIC_TASKPRI, data);
+ default:
+ vcpu_unimpl(vcpu, "Hyper-V uhandled wrmsr: 0x%x data 0x%llx\n",
+ msr, data);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int kvm_hv_get_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
+{
+ u64 data = 0;
+ struct kvm *kvm = vcpu->kvm;
+ struct kvm_hv *hv = &kvm->arch.hyperv;
+
+ switch (msr) {
+ case HV_X64_MSR_GUEST_OS_ID:
+ data = hv->hv_guest_os_id;
+ break;
+ case HV_X64_MSR_HYPERCALL:
+ data = hv->hv_hypercall;
+ break;
+ case HV_X64_MSR_TIME_REF_COUNT: {
+ data =
+ div_u64(get_kernel_ns() + kvm->arch.kvmclock_offset, 100);
+ break;
+ }
+ case HV_X64_MSR_REFERENCE_TSC:
+ data = hv->hv_tsc_page;
+ break;
+ default:
+ vcpu_unimpl(vcpu, "Hyper-V unhandled rdmsr: 0x%x\n", msr);
+ return 1;
+ }
+
+ *pdata = data;
+ return 0;
+}
+
+static int kvm_hv_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
+{
+ u64 data = 0;
+ struct kvm_vcpu_hv *hv = &vcpu->arch.hyperv;
+
+ switch (msr) {
+ case HV_X64_MSR_VP_INDEX: {
+ int r;
+ struct kvm_vcpu *v;
+
+ kvm_for_each_vcpu(r, v, vcpu->kvm) {
+ if (v == vcpu) {
+ data = r;
+ break;
+ }
+ }
+ break;
+ }
+ case HV_X64_MSR_EOI:
+ return kvm_hv_vapic_msr_read(vcpu, APIC_EOI, pdata);
+ case HV_X64_MSR_ICR:
+ return kvm_hv_vapic_msr_read(vcpu, APIC_ICR, pdata);
+ case HV_X64_MSR_TPR:
+ return kvm_hv_vapic_msr_read(vcpu, APIC_TASKPRI, pdata);
+ case HV_X64_MSR_APIC_ASSIST_PAGE:
+ data = hv->hv_vapic;
+ break;
+ default:
+ vcpu_unimpl(vcpu, "Hyper-V unhandled rdmsr: 0x%x\n", msr);
+ return 1;
+ }
+ *pdata = data;
+ return 0;
+}
+
+int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
+{
+ if (kvm_hv_msr_partition_wide(msr)) {
+ int r;
+
+ mutex_lock(&vcpu->kvm->lock);
+ r = kvm_hv_set_msr_pw(vcpu, msr, data);
+ mutex_unlock(&vcpu->kvm->lock);
+ return r;
+ } else
+ return kvm_hv_set_msr(vcpu, msr, data);
+}
+
+int kvm_hv_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
+{
+ if (kvm_hv_msr_partition_wide(msr)) {
+ int r;
+
+ mutex_lock(&vcpu->kvm->lock);
+ r = kvm_hv_get_msr_pw(vcpu, msr, pdata);
+ mutex_unlock(&vcpu->kvm->lock);
+ return r;
+ } else
+ return kvm_hv_get_msr(vcpu, msr, pdata);
+}
+
+bool kvm_hv_hypercall_enabled(struct kvm *kvm)
+{
+ return kvm->arch.hyperv.hv_hypercall & HV_X64_MSR_HYPERCALL_ENABLE;
+}
+
+int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
+{
+ u64 param, ingpa, outgpa, ret;
+ uint16_t code, rep_idx, rep_cnt, res = HV_STATUS_SUCCESS, rep_done = 0;
+ bool fast, longmode;
+
+ /*
+ * hypercall generates UD from non zero cpl and real mode
+ * per HYPER-V spec
+ */
+ if (kvm_x86_ops->get_cpl(vcpu) != 0 || !is_protmode(vcpu)) {
+ kvm_queue_exception(vcpu, UD_VECTOR);
+ return 0;
+ }
+
+ longmode = is_64_bit_mode(vcpu);
+
+ if (!longmode) {
+ param = ((u64)kvm_register_read(vcpu, VCPU_REGS_RDX) << 32) |
+ (kvm_register_read(vcpu, VCPU_REGS_RAX) & 0xffffffff);
+ ingpa = ((u64)kvm_register_read(vcpu, VCPU_REGS_RBX) << 32) |
+ (kvm_register_read(vcpu, VCPU_REGS_RCX) & 0xffffffff);
+ outgpa = ((u64)kvm_register_read(vcpu, VCPU_REGS_RDI) << 32) |
+ (kvm_register_read(vcpu, VCPU_REGS_RSI) & 0xffffffff);
+ }
+#ifdef CONFIG_X86_64
+ else {
+ param = kvm_register_read(vcpu, VCPU_REGS_RCX);
+ ingpa = kvm_register_read(vcpu, VCPU_REGS_RDX);
+ outgpa = kvm_register_read(vcpu, VCPU_REGS_R8);
+ }
+#endif
+
+ code = param & 0xffff;
+ fast = (param >> 16) & 0x1;
+ rep_cnt = (param >> 32) & 0xfff;
+ rep_idx = (param >> 48) & 0xfff;
+
+ trace_kvm_hv_hypercall(code, fast, rep_cnt, rep_idx, ingpa, outgpa);
+
+ switch (code) {
+ case HV_X64_HV_NOTIFY_LONG_SPIN_WAIT:
+ kvm_vcpu_on_spin(vcpu);
+ break;
+ default:
+ res = HV_STATUS_INVALID_HYPERCALL_CODE;
+ break;
+ }
+
+ ret = res | (((u64)rep_done & 0xfff) << 32);
+ if (longmode) {
+ kvm_register_write(vcpu, VCPU_REGS_RAX, ret);
+ } else {
+ kvm_register_write(vcpu, VCPU_REGS_RDX, ret >> 32);
+ kvm_register_write(vcpu, VCPU_REGS_RAX, ret & 0xffffffff);
+ }
+
+ return 1;
+}
diff --git a/arch/x86/kvm/hyperv.h b/arch/x86/kvm/hyperv.h
new file mode 100644
index 0000000..115c738
--- /dev/null
+++ b/arch/x86/kvm/hyperv.h
@@ -0,0 +1,32 @@
+/*
+ * KVM Microsoft Hyper-V emulation
+ *
+ * derived from arch/x86/kvm/x86.c
+ *
+ * Copyright (C) 2006 Qumranet, Inc.
+ * Copyright (C) 2008 Qumranet, Inc.
+ * Copyright IBM Corporation, 2008
+ * Copyright 2010 Red Hat, Inc. and/or its affiliates.
+ * Copyright (C) 2015 Andrey Smetanin <asmetanin@virtuozzo.com>
+ *
+ * Authors:
+ * Avi Kivity <avi@qumranet.com>
+ * Yaniv Kamay <yaniv@qumranet.com>
+ * Amit Shah <amit.shah@qumranet.com>
+ * Ben-Ami Yassour <benami@il.ibm.com>
+ * Andrey Smetanin <asmetanin@virtuozzo.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef __ARCH_X86_KVM_HYPERV_H__
+#define __ARCH_X86_KVM_HYPERV_H__
+
+int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data);
+int kvm_hv_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata);
+bool kvm_hv_hypercall_enabled(struct kvm *kvm);
+int kvm_hv_hypercall(struct kvm_vcpu *vcpu);
+
+#endif
diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h
index f2f4e10..26f7817 100644
--- a/arch/x86/kvm/lapic.h
+++ b/arch/x86/kvm/lapic.h
@@ -90,7 +90,7 @@ int kvm_hv_vapic_msr_read(struct kvm_vcpu *vcpu, u32 msr, u64 *data);
static inline bool kvm_hv_vapic_assist_page_enabled(struct kvm_vcpu *vcpu)
{
- return vcpu->arch.hv_vapic & HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE;
+ return vcpu->arch.hyperv.hv_vapic & HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE;
}
int kvm_lapic_enable_pv_eoi(struct kvm_vcpu *vcpu, u64 data);
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index ac165c2..301ee01 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -29,6 +29,7 @@
#include "cpuid.h"
#include "assigned-dev.h"
#include "pmu.h"
+#include "hyperv.h"
#include <linux/clocksource.h>
#include <linux/interrupt.h>
@@ -1217,11 +1218,6 @@ static void kvm_get_time_scale(uint32_t scaled_khz, uint32_t base_khz,
__func__, base_khz, scaled_khz, shift, *pmultiplier);
}
-static inline u64 get_kernel_ns(void)
-{
- return ktime_get_boot_ns();
-}
-
#ifdef CONFIG_X86_64
static atomic_t kvm_guest_has_master_clock = ATOMIC_INIT(0);
#endif
@@ -1869,123 +1865,6 @@ out:
return r;
}
-static bool kvm_hv_hypercall_enabled(struct kvm *kvm)
-{
- return kvm->arch.hv_hypercall & HV_X64_MSR_HYPERCALL_ENABLE;
-}
-
-static bool kvm_hv_msr_partition_wide(u32 msr)
-{
- bool r = false;
- switch (msr) {
- case HV_X64_MSR_GUEST_OS_ID:
- case HV_X64_MSR_HYPERCALL:
- case HV_X64_MSR_REFERENCE_TSC:
- case HV_X64_MSR_TIME_REF_COUNT:
- r = true;
- break;
- }
-
- return r;
-}
-
-static int set_msr_hyperv_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data)
-{
- struct kvm *kvm = vcpu->kvm;
-
- switch (msr) {
- case HV_X64_MSR_GUEST_OS_ID:
- kvm->arch.hv_guest_os_id = data;
- /* setting guest os id to zero disables hypercall page */
- if (!kvm->arch.hv_guest_os_id)
- kvm->arch.hv_hypercall &= ~HV_X64_MSR_HYPERCALL_ENABLE;
- break;
- case HV_X64_MSR_HYPERCALL: {
- u64 gfn;
- unsigned long addr;
- u8 instructions[4];
-
- /* if guest os id is not set hypercall should remain disabled */
- if (!kvm->arch.hv_guest_os_id)
- break;
- if (!(data & HV_X64_MSR_HYPERCALL_ENABLE)) {
- kvm->arch.hv_hypercall = data;
- break;
- }
- gfn = data >> HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT;
- addr = gfn_to_hva(kvm, gfn);
- if (kvm_is_error_hva(addr))
- return 1;
- kvm_x86_ops->patch_hypercall(vcpu, instructions);
- ((unsigned char *)instructions)[3] = 0xc3; /* ret */
- if (__copy_to_user((void __user *)addr, instructions, 4))
- return 1;
- kvm->arch.hv_hypercall = data;
- mark_page_dirty(kvm, gfn);
- break;
- }
- case HV_X64_MSR_REFERENCE_TSC: {
- u64 gfn;
- HV_REFERENCE_TSC_PAGE tsc_ref;
- memset(&tsc_ref, 0, sizeof(tsc_ref));
- kvm->arch.hv_tsc_page = data;
- if (!(data & HV_X64_MSR_TSC_REFERENCE_ENABLE))
- break;
- gfn = data >> HV_X64_MSR_TSC_REFERENCE_ADDRESS_SHIFT;
- if (kvm_write_guest(kvm, gfn << HV_X64_MSR_TSC_REFERENCE_ADDRESS_SHIFT,
- &tsc_ref, sizeof(tsc_ref)))
- return 1;
- mark_page_dirty(kvm, gfn);
- break;
- }
- default:
- vcpu_unimpl(vcpu, "HYPER-V unimplemented wrmsr: 0x%x "
- "data 0x%llx\n", msr, data);
- return 1;
- }
- return 0;
-}
-
-static int set_msr_hyperv(struct kvm_vcpu *vcpu, u32 msr, u64 data)
-{
- switch (msr) {
- case HV_X64_MSR_APIC_ASSIST_PAGE: {
- u64 gfn;
- unsigned long addr;
-
- if (!(data & HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE)) {
- vcpu->arch.hv_vapic = data;
- if (kvm_lapic_enable_pv_eoi(vcpu, 0))
- return 1;
- break;
- }
- gfn = data >> HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT;
- addr = kvm_vcpu_gfn_to_hva(vcpu, gfn);
- if (kvm_is_error_hva(addr))
- return 1;
- if (__clear_user((void __user *)addr, PAGE_SIZE))
- return 1;
- vcpu->arch.hv_vapic = data;
- kvm_vcpu_mark_page_dirty(vcpu, gfn);
- if (kvm_lapic_enable_pv_eoi(vcpu, gfn_to_gpa(gfn) | KVM_MSR_ENABLED))
- return 1;
- break;
- }
- case HV_X64_MSR_EOI:
- return kvm_hv_vapic_msr_write(vcpu, APIC_EOI, data);
- case HV_X64_MSR_ICR:
- return kvm_hv_vapic_msr_write(vcpu, APIC_ICR, data);
- case HV_X64_MSR_TPR:
- return kvm_hv_vapic_msr_write(vcpu, APIC_TASKPRI, data);
- default:
- vcpu_unimpl(vcpu, "HYPER-V unimplemented wrmsr: 0x%x "
- "data 0x%llx\n", msr, data);
- return 1;
- }
-
- return 0;
-}
-
static int kvm_pv_enable_async_pf(struct kvm_vcpu *vcpu, u64 data)
{
gpa_t gpa = data & ~0x3f;
@@ -2224,15 +2103,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
*/
break;
case HV_X64_MSR_GUEST_OS_ID ... HV_X64_MSR_SINT15:
- if (kvm_hv_msr_partition_wide(msr)) {
- int r;
- mutex_lock(&vcpu->kvm->lock);
- r = set_msr_hyperv_pw(vcpu, msr, data);
- mutex_unlock(&vcpu->kvm->lock);
- return r;
- } else
- return set_msr_hyperv(vcpu, msr, data);
- break;
+ return kvm_hv_set_msr_common(vcpu, msr, data);
case MSR_IA32_BBL_CR_CTL3:
/* Drop writes to this legacy MSR -- see rdmsr
* counterpart for further detail.
@@ -2315,68 +2186,6 @@ static int get_msr_mce(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
return 0;
}
-static int get_msr_hyperv_pw(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
-{
- u64 data = 0;
- struct kvm *kvm = vcpu->kvm;
-
- switch (msr) {
- case HV_X64_MSR_GUEST_OS_ID:
- data = kvm->arch.hv_guest_os_id;
- break;
- case HV_X64_MSR_HYPERCALL:
- data = kvm->arch.hv_hypercall;
- break;
- case HV_X64_MSR_TIME_REF_COUNT: {
- data =
- div_u64(get_kernel_ns() + kvm->arch.kvmclock_offset, 100);
- break;
- }
- case HV_X64_MSR_REFERENCE_TSC:
- data = kvm->arch.hv_tsc_page;
- break;
- default:
- vcpu_unimpl(vcpu, "Hyper-V unhandled rdmsr: 0x%x\n", msr);
- return 1;
- }
-
- *pdata = data;
- return 0;
-}
-
-static int get_msr_hyperv(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
-{
- u64 data = 0;
-
- switch (msr) {
- case HV_X64_MSR_VP_INDEX: {
- int r;
- struct kvm_vcpu *v;
- kvm_for_each_vcpu(r, v, vcpu->kvm) {
- if (v == vcpu) {
- data = r;
- break;
- }
- }
- break;
- }
- case HV_X64_MSR_EOI:
- return kvm_hv_vapic_msr_read(vcpu, APIC_EOI, pdata);
- case HV_X64_MSR_ICR:
- return kvm_hv_vapic_msr_read(vcpu, APIC_ICR, pdata);
- case HV_X64_MSR_TPR:
- return kvm_hv_vapic_msr_read(vcpu, APIC_TASKPRI, pdata);
- case HV_X64_MSR_APIC_ASSIST_PAGE:
- data = vcpu->arch.hv_vapic;
- break;
- default:
- vcpu_unimpl(vcpu, "Hyper-V unhandled rdmsr: 0x%x\n", msr);
- return 1;
- }
- *pdata = data;
- return 0;
-}
-
int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
{
u64 data;
@@ -2495,14 +2304,8 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
msr_info->data = 0x20000000;
break;
case HV_X64_MSR_GUEST_OS_ID ... HV_X64_MSR_SINT15:
- if (kvm_hv_msr_partition_wide(msr_info->index)) {
- int r;
- mutex_lock(&vcpu->kvm->lock);
- r = get_msr_hyperv_pw(vcpu, msr_info->index, &msr_info->data);
- mutex_unlock(&vcpu->kvm->lock);
- return r;
- } else
- return get_msr_hyperv(vcpu, msr_info->index, &msr_info->data);
+ return kvm_hv_get_msr_common(vcpu,
+ msr_info->index, &msr_info->data);
break;
case MSR_IA32_BBL_CR_CTL3:
/* This legacy MSR exists but isn't fully documented in current
@@ -5885,66 +5688,6 @@ int kvm_emulate_halt(struct kvm_vcpu *vcpu)
}
EXPORT_SYMBOL_GPL(kvm_emulate_halt);
-int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
-{
- u64 param, ingpa, outgpa, ret;
- uint16_t code, rep_idx, rep_cnt, res = HV_STATUS_SUCCESS, rep_done = 0;
- bool fast, longmode;
-
- /*
- * hypercall generates UD from non zero cpl and real mode
- * per HYPER-V spec
- */
- if (kvm_x86_ops->get_cpl(vcpu) != 0 || !is_protmode(vcpu)) {
- kvm_queue_exception(vcpu, UD_VECTOR);
- return 0;
- }
-
- longmode = is_64_bit_mode(vcpu);
-
- if (!longmode) {
- param = ((u64)kvm_register_read(vcpu, VCPU_REGS_RDX) << 32) |
- (kvm_register_read(vcpu, VCPU_REGS_RAX) & 0xffffffff);
- ingpa = ((u64)kvm_register_read(vcpu, VCPU_REGS_RBX) << 32) |
- (kvm_register_read(vcpu, VCPU_REGS_RCX) & 0xffffffff);
- outgpa = ((u64)kvm_register_read(vcpu, VCPU_REGS_RDI) << 32) |
- (kvm_register_read(vcpu, VCPU_REGS_RSI) & 0xffffffff);
- }
-#ifdef CONFIG_X86_64
- else {
- param = kvm_register_read(vcpu, VCPU_REGS_RCX);
- ingpa = kvm_register_read(vcpu, VCPU_REGS_RDX);
- outgpa = kvm_register_read(vcpu, VCPU_REGS_R8);
- }
-#endif
-
- code = param & 0xffff;
- fast = (param >> 16) & 0x1;
- rep_cnt = (param >> 32) & 0xfff;
- rep_idx = (param >> 48) & 0xfff;
-
- trace_kvm_hv_hypercall(code, fast, rep_cnt, rep_idx, ingpa, outgpa);
-
- switch (code) {
- case HV_X64_HV_NOTIFY_LONG_SPIN_WAIT:
- kvm_vcpu_on_spin(vcpu);
- break;
- default:
- res = HV_STATUS_INVALID_HYPERCALL_CODE;
- break;
- }
-
- ret = res | (((u64)rep_done & 0xfff) << 32);
- if (longmode) {
- kvm_register_write(vcpu, VCPU_REGS_RAX, ret);
- } else {
- kvm_register_write(vcpu, VCPU_REGS_RDX, ret >> 32);
- kvm_register_write(vcpu, VCPU_REGS_RAX, ret & 0xffffffff);
- }
-
- return 1;
-}
-
/*
* kvm_pv_kick_cpu_op: Kick a vcpu.
*
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index edc8cdc..c04b56b 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -147,6 +147,11 @@ static inline void kvm_register_writel(struct kvm_vcpu *vcpu,
return kvm_register_write(vcpu, reg, val);
}
+static inline u64 get_kernel_ns(void)
+{
+ return ktime_get_boot_ns();
+}
+
void kvm_before_handle_nmi(struct kvm_vcpu *vcpu);
void kvm_after_handle_nmi(struct kvm_vcpu *vcpu);
void kvm_set_pending_timer(struct kvm_vcpu *vcpu);
--
2.1.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PATCH 2/9] kvm: introduce vcpu_debug = kvm_debug + vcpu context
2015-06-30 11:33 [Qemu-devel] [PATCH v3 0/9] HyperV equivalent of pvpanic driver Denis V. Lunev
2015-06-30 11:33 ` [Qemu-devel] [PATCH 1/9] kvm/x86: move Hyper-V MSR's/hypercall code into hyperv.c file Denis V. Lunev
@ 2015-06-30 11:33 ` Denis V. Lunev
2015-07-01 0:12 ` Peter Hornyack
2015-06-30 11:33 ` [Qemu-devel] [PATCH 3/9] kvm: add hyper-v crash msrs values Denis V. Lunev
` (8 subsequent siblings)
10 siblings, 1 reply; 31+ messages in thread
From: Denis V. Lunev @ 2015-06-30 11:33 UTC (permalink / raw)
Cc: kvm, Gleb Natapov, qemu-devel, Paolo Bonzini, Andrey Smetanin,
Denis V. Lunev
From: Andrey Smetanin <asmetanin@virtuozzo.com>
vcpu_debug is useful macro like kvm_debug but additionally
includes vcpu context inside output.
Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Gleb Natapov <gleb@kernel.org>
---
include/linux/kvm_host.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 9564fd7..2b2edf1 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -424,6 +424,9 @@ struct kvm {
#define vcpu_unimpl(vcpu, fmt, ...) \
kvm_pr_unimpl("vcpu%i " fmt, (vcpu)->vcpu_id, ## __VA_ARGS__)
+#define vcpu_debug(vcpu, fmt, ...) \
+ kvm_debug("vcpu%i " fmt, (vcpu)->vcpu_id, ## __VA_ARGS__)
+
static inline struct kvm_vcpu *kvm_get_vcpu(struct kvm *kvm, int i)
{
smp_rmb();
--
2.1.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PATCH 3/9] kvm: add hyper-v crash msrs values
2015-06-30 11:33 [Qemu-devel] [PATCH v3 0/9] HyperV equivalent of pvpanic driver Denis V. Lunev
2015-06-30 11:33 ` [Qemu-devel] [PATCH 1/9] kvm/x86: move Hyper-V MSR's/hypercall code into hyperv.c file Denis V. Lunev
2015-06-30 11:33 ` [Qemu-devel] [PATCH 2/9] kvm: introduce vcpu_debug = kvm_debug + vcpu context Denis V. Lunev
@ 2015-06-30 11:33 ` Denis V. Lunev
2015-07-01 0:14 ` Peter Hornyack
2015-07-01 15:00 ` Paolo Bonzini
2015-06-30 11:33 ` [Qemu-devel] [PATCH 4/9] kvm/x86: added hyper-v crash msrs into kvm hyperv context Denis V. Lunev
` (7 subsequent siblings)
10 siblings, 2 replies; 31+ messages in thread
From: Denis V. Lunev @ 2015-06-30 11:33 UTC (permalink / raw)
Cc: kvm, Gleb Natapov, qemu-devel, Paolo Bonzini, Andrey Smetanin,
Denis V. Lunev
From: Andrey Smetanin <asmetanin@virtuozzo.com>
Added Hyper-V crash msrs values - HV_X64_MSR_CRASH*.
Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Gleb Natapov <gleb@kernel.org>
---
arch/x86/include/uapi/asm/hyperv.h | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/arch/x86/include/uapi/asm/hyperv.h b/arch/x86/include/uapi/asm/hyperv.h
index ce6068d..3ed7a5c 100644
--- a/arch/x86/include/uapi/asm/hyperv.h
+++ b/arch/x86/include/uapi/asm/hyperv.h
@@ -199,6 +199,21 @@
#define HV_X64_MSR_STIMER3_CONFIG 0x400000B6
#define HV_X64_MSR_STIMER3_COUNT 0x400000B7
+/* Hyper-V guest crash notification MSR's */
+#define HV_X64_MSR_CRASH_P0 0x40000100
+#define HV_X64_MSR_CRASH_P1 0x40000101
+#define HV_X64_MSR_CRASH_P2 0x40000102
+#define HV_X64_MSR_CRASH_P3 0x40000103
+#define HV_X64_MSR_CRASH_P4 0x40000104
+#define HV_X64_MSR_CRASH_CTL 0x40000105
+#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_ENABLE 0x00000001
#define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT 12
#define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_MASK \
--
2.1.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PATCH 4/9] kvm/x86: added hyper-v crash msrs into kvm hyperv context
2015-06-30 11:33 [Qemu-devel] [PATCH v3 0/9] HyperV equivalent of pvpanic driver Denis V. Lunev
` (2 preceding siblings ...)
2015-06-30 11:33 ` [Qemu-devel] [PATCH 3/9] kvm: add hyper-v crash msrs values Denis V. Lunev
@ 2015-06-30 11:33 ` Denis V. Lunev
2015-07-01 0:14 ` Peter Hornyack
2015-06-30 11:33 ` [Qemu-devel] [PATCH 5/9] kvm: added KVM_REQ_HV_CRASH value to notify qemu about hyper-v crash Denis V. Lunev
` (6 subsequent siblings)
10 siblings, 1 reply; 31+ messages in thread
From: Denis V. Lunev @ 2015-06-30 11:33 UTC (permalink / raw)
Cc: kvm, Gleb Natapov, qemu-devel, Paolo Bonzini, Andrey Smetanin,
Denis V. Lunev
From: Andrey Smetanin <asmetanin@virtuozzo.com>
Added kvm Hyper-V context hv crash variables as storage
of Hyper-V crash msrs.
Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Gleb Natapov <gleb@kernel.org>
---
arch/x86/include/asm/kvm_host.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 78616aa..697c1f3 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -595,6 +595,10 @@ struct kvm_hv {
u64 hv_guest_os_id;
u64 hv_hypercall;
u64 hv_tsc_page;
+
+ /* Hyper-v based guest crash (NT kernel bugcheck) parameters */
+ u64 hv_crash_param[HV_X64_MSR_CRASH_PARAMS];
+ u64 hv_crash_ctl;
};
struct kvm_arch {
--
2.1.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PATCH 5/9] kvm: added KVM_REQ_HV_CRASH value to notify qemu about hyper-v crash
2015-06-30 11:33 [Qemu-devel] [PATCH v3 0/9] HyperV equivalent of pvpanic driver Denis V. Lunev
` (3 preceding siblings ...)
2015-06-30 11:33 ` [Qemu-devel] [PATCH 4/9] kvm/x86: added hyper-v crash msrs into kvm hyperv context Denis V. Lunev
@ 2015-06-30 11:33 ` Denis V. Lunev
2015-07-01 0:14 ` Peter Hornyack
2015-06-30 11:33 ` [Qemu-devel] [PATCH 6/9] kvm/x86: mark hyper-v crash msrs as partition wide Denis V. Lunev
` (5 subsequent siblings)
10 siblings, 1 reply; 31+ messages in thread
From: Denis V. Lunev @ 2015-06-30 11:33 UTC (permalink / raw)
Cc: kvm, Gleb Natapov, qemu-devel, Paolo Bonzini, Andrey Smetanin,
Denis V. Lunev
From: Andrey Smetanin <asmetanin@virtuozzo.com>
Added KVM_REQ_HV_CRASH - vcpu request used for notify user space(QEMU)
about Hyper-V crash.
Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Gleb Natapov <gleb@kernel.org>
---
include/linux/kvm_host.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 2b2edf1..a377e00 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -139,6 +139,7 @@ static inline bool is_error_page(struct page *page)
#define KVM_REQ_DISABLE_IBS 24
#define KVM_REQ_APIC_PAGE_RELOAD 25
#define KVM_REQ_SMI 26
+#define KVM_REQ_HV_CRASH 27
#define KVM_USERSPACE_IRQ_SOURCE_ID 0
#define KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID 1
--
2.1.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PATCH 6/9] kvm/x86: mark hyper-v crash msrs as partition wide
2015-06-30 11:33 [Qemu-devel] [PATCH v3 0/9] HyperV equivalent of pvpanic driver Denis V. Lunev
` (4 preceding siblings ...)
2015-06-30 11:33 ` [Qemu-devel] [PATCH 5/9] kvm: added KVM_REQ_HV_CRASH value to notify qemu about hyper-v crash Denis V. Lunev
@ 2015-06-30 11:33 ` Denis V. Lunev
2015-07-01 0:15 ` Peter Hornyack
2015-06-30 11:33 ` [Qemu-devel] [PATCH 7/9] kvm/x86: added hyper-v crash data and ctl msr's get/set'ers Denis V. Lunev
` (4 subsequent siblings)
10 siblings, 1 reply; 31+ messages in thread
From: Denis V. Lunev @ 2015-06-30 11:33 UTC (permalink / raw)
Cc: kvm, Gleb Natapov, qemu-devel, Paolo Bonzini, Andrey Smetanin,
Denis V. Lunev
From: Andrey Smetanin <asmetanin@virtuozzo.com>
Hyper-V crash msr's are per vm, aren't per vcpu, so mark them
as partition wide.
Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Gleb Natapov <gleb@kernel.org>
---
arch/x86/kvm/hyperv.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 2b49f10..af83c96 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -39,6 +39,8 @@ static bool kvm_hv_msr_partition_wide(u32 msr)
case HV_X64_MSR_HYPERCALL:
case HV_X64_MSR_REFERENCE_TSC:
case HV_X64_MSR_TIME_REF_COUNT:
+ case HV_X64_MSR_CRASH_CTL:
+ case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4:
r = true;
break;
}
--
2.1.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PATCH 7/9] kvm/x86: added hyper-v crash data and ctl msr's get/set'ers
2015-06-30 11:33 [Qemu-devel] [PATCH v3 0/9] HyperV equivalent of pvpanic driver Denis V. Lunev
` (5 preceding siblings ...)
2015-06-30 11:33 ` [Qemu-devel] [PATCH 6/9] kvm/x86: mark hyper-v crash msrs as partition wide Denis V. Lunev
@ 2015-06-30 11:33 ` Denis V. Lunev
2015-07-01 0:15 ` Peter Hornyack
2015-07-01 16:47 ` Paolo Bonzini
2015-06-30 11:33 ` [Qemu-devel] [PATCH 8/9] kvm/x86: add sending hyper-v crash notification to user space Denis V. Lunev
` (3 subsequent siblings)
10 siblings, 2 replies; 31+ messages in thread
From: Denis V. Lunev @ 2015-06-30 11:33 UTC (permalink / raw)
Cc: kvm, Gleb Natapov, qemu-devel, Paolo Bonzini, Andrey Smetanin,
Denis V. Lunev
From: Andrey Smetanin <asmetanin@virtuozzo.com>
Added hyper-v crash msr's(HV_X64_MSR_CRASH*) data and control
geters and setters.
User space allowed to setup Hyper-V crash ctl msr.
This msr should be setup to HV_X64_MSR_CRASH_CTL_NOTIFY
value so Hyper-V guest knows it can send crash data to host.
But Hyper-V guest notifies about crash event by writing
the same HV_X64_MSR_CRASH_CTL_NOTIFY value into crash ctl msr.
So both user space and guest writes inside ctl msr the same value
and this patch distingiush the moment of actual guest crash
by checking host initiated value from msr info. Also patch
prevents modification of crash ctl msr by guest.
Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Gleb Natapov <gleb@kernel.org>
---
arch/x86/kvm/hyperv.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++---
arch/x86/kvm/hyperv.h | 2 +-
arch/x86/kvm/x86.c | 7 ++++-
3 files changed, 78 insertions(+), 5 deletions(-)
diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index af83c96..a860165 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -48,7 +48,63 @@ static bool kvm_hv_msr_partition_wide(u32 msr)
return r;
}
-static int kvm_hv_set_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data)
+static int kvm_hv_msr_get_crash_data(struct kvm_vcpu *vcpu,
+ u32 index, u64 *pdata)
+{
+ struct kvm_hv *hv = &vcpu->kvm->arch.hyperv;
+
+ if (WARN_ON_ONCE(index >= ARRAY_SIZE(hv->hv_crash_param)))
+ return -EINVAL;
+
+ *pdata = hv->hv_crash_param[index];
+ return 0;
+}
+
+static int kvm_hv_msr_get_crash_ctl(struct kvm_vcpu *vcpu, u64 *pdata)
+{
+ struct kvm_hv *hv = &vcpu->kvm->arch.hyperv;
+
+ *pdata = hv->hv_crash_ctl;
+ return 0;
+}
+
+static int kvm_hv_msr_set_crash_ctl(struct kvm_vcpu *vcpu, u64 data, bool host)
+{
+ struct kvm_hv *hv = &vcpu->kvm->arch.hyperv;
+
+ if (host)
+ hv->hv_crash_ctl = data;
+
+ if ((data & HV_X64_MSR_CRASH_CTL_NOTIFY) && !host) {
+
+ vcpu_debug(vcpu, "hv crash (0x%llx 0x%llx 0x%llx 0x%llx 0x%llx)\n",
+ hv->hv_crash_param[0],
+ hv->hv_crash_param[1],
+ hv->hv_crash_param[2],
+ hv->hv_crash_param[3],
+ hv->hv_crash_param[4]);
+
+ /* Send notification about crash to user space */
+ kvm_make_request(KVM_REQ_HV_CRASH, vcpu);
+ }
+
+ return 0;
+}
+
+static int kvm_hv_msr_set_crash_data(struct kvm_vcpu *vcpu,
+ u32 index, u64 data)
+{
+ struct kvm_hv *hv = &vcpu->kvm->arch.hyperv;
+
+ if (WARN_ON_ONCE(index >= ARRAY_SIZE(hv->hv_crash_param)))
+ return -EINVAL;
+
+ hv->hv_crash_param[index] = data;
+ return 0;
+}
+
+static int kvm_hv_set_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data,
+ bool host)
{
struct kvm *kvm = vcpu->kvm;
struct kvm_hv *hv = &kvm->arch.hyperv;
@@ -101,6 +157,12 @@ static int kvm_hv_set_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data)
mark_page_dirty(kvm, gfn);
break;
}
+ case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4:
+ return kvm_hv_msr_set_crash_data(vcpu,
+ msr - HV_X64_MSR_CRASH_P0,
+ data);
+ case HV_X64_MSR_CRASH_CTL:
+ return kvm_hv_msr_set_crash_ctl(vcpu, data, host);
default:
vcpu_unimpl(vcpu, "Hyper-V uhandled wrmsr: 0x%x data 0x%llx\n",
msr, data);
@@ -173,6 +235,12 @@ static int kvm_hv_get_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
case HV_X64_MSR_REFERENCE_TSC:
data = hv->hv_tsc_page;
break;
+ case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4:
+ return kvm_hv_msr_get_crash_data(vcpu,
+ msr - HV_X64_MSR_CRASH_P0,
+ pdata);
+ case HV_X64_MSR_CRASH_CTL:
+ return kvm_hv_msr_get_crash_ctl(vcpu, pdata);
default:
vcpu_unimpl(vcpu, "Hyper-V unhandled rdmsr: 0x%x\n", msr);
return 1;
@@ -217,13 +285,13 @@ static int kvm_hv_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
return 0;
}
-int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
+int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host)
{
if (kvm_hv_msr_partition_wide(msr)) {
int r;
mutex_lock(&vcpu->kvm->lock);
- r = kvm_hv_set_msr_pw(vcpu, msr, data);
+ r = kvm_hv_set_msr_pw(vcpu, msr, data, host);
mutex_unlock(&vcpu->kvm->lock);
return r;
} else
diff --git a/arch/x86/kvm/hyperv.h b/arch/x86/kvm/hyperv.h
index 115c738..c7bce55 100644
--- a/arch/x86/kvm/hyperv.h
+++ b/arch/x86/kvm/hyperv.h
@@ -24,7 +24,7 @@
#ifndef __ARCH_X86_KVM_HYPERV_H__
#define __ARCH_X86_KVM_HYPERV_H__
-int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data);
+int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host);
int kvm_hv_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata);
bool kvm_hv_hypercall_enabled(struct kvm *kvm);
int kvm_hv_hypercall(struct kvm_vcpu *vcpu);
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 301ee01..47b7507 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2103,7 +2103,10 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
*/
break;
case HV_X64_MSR_GUEST_OS_ID ... HV_X64_MSR_SINT15:
- return kvm_hv_set_msr_common(vcpu, msr, data);
+ case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4:
+ case HV_X64_MSR_CRASH_CTL:
+ return kvm_hv_set_msr_common(vcpu, msr, data,
+ msr_info->host_initiated);
case MSR_IA32_BBL_CR_CTL3:
/* Drop writes to this legacy MSR -- see rdmsr
* counterpart for further detail.
@@ -2304,6 +2307,8 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
msr_info->data = 0x20000000;
break;
case HV_X64_MSR_GUEST_OS_ID ... HV_X64_MSR_SINT15:
+ case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4:
+ case HV_X64_MSR_CRASH_CTL:
return kvm_hv_get_msr_common(vcpu,
msr_info->index, &msr_info->data);
break;
--
2.1.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PATCH 8/9] kvm/x86: add sending hyper-v crash notification to user space
2015-06-30 11:33 [Qemu-devel] [PATCH v3 0/9] HyperV equivalent of pvpanic driver Denis V. Lunev
` (6 preceding siblings ...)
2015-06-30 11:33 ` [Qemu-devel] [PATCH 7/9] kvm/x86: added hyper-v crash data and ctl msr's get/set'ers Denis V. Lunev
@ 2015-06-30 11:33 ` Denis V. Lunev
2015-07-01 0:16 ` Peter Hornyack
2015-07-01 15:12 ` Paolo Bonzini
2015-06-30 11:33 ` [Qemu-devel] [PATCH 9/9] qemu/kvm: kvm hyper-v based guest crash event handling Denis V. Lunev
` (2 subsequent siblings)
10 siblings, 2 replies; 31+ messages in thread
From: Denis V. Lunev @ 2015-06-30 11:33 UTC (permalink / raw)
Cc: kvm, Gleb Natapov, qemu-devel, Paolo Bonzini, Andrey Smetanin,
Denis V. Lunev
From: Andrey Smetanin <asmetanin@virtuozzo.com>
Sending of notification is done by exiting vcpu to user space
if KVM_REQ_HV_CRASH is enabled for vcpu. kvm_run structure
will contains system_event with type KVM_SYSTEM_EVENT_CRASH
and flag KVM_SYSTEM_EVENT_FL_HV_CRASH to clarify that
crash occures inside Hyper-V based guest.
Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Gleb Natapov <gleb@kernel.org>
---
arch/x86/kvm/x86.c | 8 ++++++++
include/uapi/linux/kvm.h | 2 ++
2 files changed, 10 insertions(+)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 47b7507..55a4b92 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -6264,6 +6264,14 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
vcpu_scan_ioapic(vcpu);
if (kvm_check_request(KVM_REQ_APIC_PAGE_RELOAD, vcpu))
kvm_vcpu_reload_apic_access_page(vcpu);
+ if (kvm_check_request(KVM_REQ_HV_CRASH, vcpu)) {
+ vcpu->run->exit_reason = KVM_EXIT_SYSTEM_EVENT;
+ vcpu->run->system_event.type = KVM_SYSTEM_EVENT_CRASH;
+ vcpu->run->system_event.flags =
+ KVM_SYSTEM_EVENT_FL_HV_CRASH;
+ r = 0;
+ goto out;
+ }
}
if (kvm_check_request(KVM_REQ_EVENT, vcpu) || req_int_win) {
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 716ad4a..eefb8b9 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/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 << 0)
__u32 type;
__u64 flags;
} system_event;
--
2.1.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [Qemu-devel] [PATCH 9/9] qemu/kvm: kvm hyper-v based guest crash event handling
2015-06-30 11:33 [Qemu-devel] [PATCH v3 0/9] HyperV equivalent of pvpanic driver Denis V. Lunev
` (7 preceding siblings ...)
2015-06-30 11:33 ` [Qemu-devel] [PATCH 8/9] kvm/x86: add sending hyper-v crash notification to user space Denis V. Lunev
@ 2015-06-30 11:33 ` Denis V. Lunev
2015-07-01 15:07 ` Paolo Bonzini
2015-06-30 12:26 ` [Qemu-devel] [PATCH v3 0/9] HyperV equivalent of pvpanic driver Daniel P. Berrange
2015-07-01 14:09 ` Paolo Bonzini
10 siblings, 1 reply; 31+ messages in thread
From: Denis V. Lunev @ 2015-06-30 11:33 UTC (permalink / raw)
Cc: kvm, qemu-devel, Paolo Bonzini, Andrey Smetanin, Denis V. Lunev,
Andreas Färber
From: Andrey Smetanin <asmetanin@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.
Note that it's usually impossible to understand from Hyper-V
crash msr's that crash happened because ctl msr
always contains the same value HV_X64_MSR_CRASH_CTL_NOTIFY.
To solve it add a particular value - hv_crash_occurred
inside CPU state and migrate this value with crash msr's.
Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Andreas Färber <afaerber@suse.de>
---
hw/misc/pvpanic.c | 3 +--
include/sysemu/kvm.h | 2 ++
include/sysemu/sysemu.h | 1 +
kvm-all.c | 5 ++++
| 16 +++++++++++++
| 2 ++
target-arm/kvm.c | 5 ++++
target-i386/cpu-qom.h | 1 +
target-i386/cpu.c | 1 +
target-i386/cpu.h | 4 ++++
target-i386/kvm.c | 53 ++++++++++++++++++++++++++++++++++++++++++
target-i386/machine.c | 24 +++++++++++++++++++
target-mips/kvm.c | 5 ++++
target-ppc/kvm.c | 5 ++++
target-s390x/kvm.c | 16 ++++++-------
vl.c | 6 +++++
16 files changed, 138 insertions(+), 11 deletions(-)
diff --git a/hw/misc/pvpanic.c b/hw/misc/pvpanic.c
index 994f8af..3709488 100644
--- a/hw/misc/pvpanic.c
+++ b/hw/misc/pvpanic.c
@@ -41,8 +41,7 @@ static void handle_event(int event)
}
if (event & PVPANIC_PANICKED) {
- qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_PAUSE, &error_abort);
- vm_stop(RUN_STATE_GUEST_PANICKED);
+ qemu_system_guest_panicked();
return;
}
}
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index f459fbd..c62fd0c 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_crash(CPUState *cpu, struct kvm_run *run);
+
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..d35dc1e 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1844,6 +1844,11 @@ int kvm_cpu_exec(CPUState *cpu)
qemu_system_reset_request();
ret = EXCP_INTERRUPT;
break;
+ case KVM_SYSTEM_EVENT_CRASH:
+ kvm_arch_handle_crash(cpu, run);
+ qemu_system_guest_panicked();
+ ret = 0;
+ break;
default:
DPRINTF("kvm_arch_handle_exit\n");
ret = kvm_arch_handle_exit(cpu, run);
--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 0x400000B6
#define HV_X64_MSR_STIMER3_COUNT 0x400000B7
+/* Hypev-V guest crash notification MSR's */
+#define HV_X64_MSR_CRASH_P0 0x40000100
+#define HV_X64_MSR_CRASH_P1 0x40000101
+#define HV_X64_MSR_CRASH_P2 0x40000102
+#define HV_X64_MSR_CRASH_P3 0x40000103
+#define HV_X64_MSR_CRASH_P4 0x40000104
+#define HV_X64_MSR_CRASH_CTL 0x40000105
+#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_ENABLE 0x00000001
#define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT 12
#define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_MASK \
--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 << 0)
__u32 type;
__u64 flags;
} system_event;
diff --git a/target-arm/kvm.c b/target-arm/kvm.c
index 548bfd7..8cc5571 100644
--- a/target-arm/kvm.c
+++ b/target-arm/kvm.c
@@ -512,6 +512,11 @@ MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run)
return MEMTXATTRS_UNSPECIFIED;
}
+int kvm_arch_handle_crash(CPUState *cs, struct kvm_run *run)
+{
+ return 0;
+}
+
int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
{
return 0;
diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h
index 7a4fddd..c35b624 100644
--- a/target-i386/cpu-qom.h
+++ b/target-i386/cpu-qom.h
@@ -89,6 +89,7 @@ typedef struct X86CPU {
bool hyperv_relaxed_timing;
int hyperv_spinlock_attempts;
bool hyperv_time;
+ bool hyperv_crash;
bool check_cpuid;
bool enforce_cpuid;
bool expose_kvm;
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 36b07f9..04a8408 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -3117,6 +3117,7 @@ static Property x86_cpu_properties[] = {
DEFINE_PROP_BOOL("hv-relaxed", X86CPU, hyperv_relaxed_timing, false),
DEFINE_PROP_BOOL("hv-vapic", X86CPU, hyperv_vapic, false),
DEFINE_PROP_BOOL("hv-time", X86CPU, hyperv_time, false),
+ DEFINE_PROP_BOOL("hv-crash", X86CPU, hyperv_crash, false),
DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, false),
DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false),
DEFINE_PROP_BOOL("kvm", X86CPU, expose_kvm, true),
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 603aaf0..2958cdc 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -21,6 +21,7 @@
#include "config.h"
#include "qemu-common.h"
+#include <asm/hyperv.h>
#ifdef TARGET_X86_64
#define TARGET_LONG_BITS 64
@@ -904,6 +905,9 @@ typedef struct CPUX86State {
uint64_t msr_hv_guest_os_id;
uint64_t msr_hv_vapic;
uint64_t msr_hv_tsc;
+ uint64_t msr_hv_crash_prm[HV_X64_MSR_CRASH_PARAMS];
+ uint64_t msr_hv_crash_ctl;
+ uint8_t hv_crash_occurred;
/* exception/interrupt handling */
int error_code;
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index daced5c..1f887cb 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -79,6 +79,7 @@ static int lm_capable_kernel;
static bool has_msr_hv_hypercall;
static bool has_msr_hv_vapic;
static bool has_msr_hv_tsc;
+static bool has_msr_hv_crash;
static bool has_msr_mtrr;
static bool has_msr_xss;
@@ -515,6 +516,11 @@ int kvm_arch_init_vcpu(CPUState *cs)
c->eax |= 0x200;
has_msr_hv_tsc = true;
}
+ if (cpu->hyperv_crash) {
+ c->edx |= HV_X64_GUEST_CRASH_MSR_AVAILABLE;
+ has_msr_hv_crash = true;
+ }
+
c = &cpuid_data.entries[cpuid_i++];
c->function = HYPERV_CPUID_ENLIGHTMENT_INFO;
if (cpu->hyperv_relaxed_timing) {
@@ -761,6 +767,10 @@ void kvm_arch_reset_vcpu(X86CPU *cpu)
} else {
env->mp_state = KVM_MP_STATE_RUNNABLE;
}
+ if (has_msr_hv_crash) {
+ env->msr_hv_crash_ctl = HV_X64_MSR_CRASH_CTL_NOTIFY;
+ env->hv_crash_occurred = 0;
+ }
}
void kvm_arch_do_init_vcpu(X86CPU *cpu)
@@ -1321,6 +1331,16 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_REFERENCE_TSC,
env->msr_hv_tsc);
}
+ if (has_msr_hv_crash) {
+ int j;
+
+ for (j = 0; j < HV_X64_MSR_CRASH_PARAMS; j++)
+ kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_CRASH_P0 + j,
+ env->msr_hv_crash_prm[j]);
+
+ kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_CRASH_CTL,
+ env->msr_hv_crash_ctl);
+ }
if (has_msr_mtrr) {
kvm_msr_entry_set(&msrs[n++], MSR_MTRRdefType, env->mtrr_deftype);
kvm_msr_entry_set(&msrs[n++],
@@ -1673,6 +1693,14 @@ static int kvm_get_msrs(X86CPU *cpu)
if (has_msr_hv_tsc) {
msrs[n++].index = HV_X64_MSR_REFERENCE_TSC;
}
+ if (has_msr_hv_crash) {
+ int j;
+
+ for (j = 0; j < HV_X64_MSR_CRASH_PARAMS; j++) {
+ msrs[n++].index = HV_X64_MSR_CRASH_P0 + j;
+ }
+ msrs[n++].index = HV_X64_MSR_CRASH_CTL;
+ }
if (has_msr_mtrr) {
msrs[n++].index = MSR_MTRRdefType;
msrs[n++].index = MSR_MTRRfix64K_00000;
@@ -1817,6 +1845,12 @@ static int kvm_get_msrs(X86CPU *cpu)
case HV_X64_MSR_REFERENCE_TSC:
env->msr_hv_tsc = msrs[i].data;
break;
+ case HV_X64_MSR_CRASH_CTL:
+ env->msr_hv_crash_ctl = msrs[i].data;
+ break;
+ 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 MSR_MTRRdefType:
env->mtrr_deftype = msrs[i].data;
break;
@@ -2539,6 +2573,25 @@ static bool host_supports_vmx(void)
return ecx & CPUID_EXT_VMX;
}
+static int kvm_arch_handle_hv_crash(CPUState *cs)
+{
+ X86CPU *cpu = X86_CPU(cs);
+ CPUX86State *env = &cpu->env;
+
+ /* Mark that Hyper-v guest crash occurred */
+ env->hv_crash_occurred = 1;
+
+ return 0;
+}
+
+int kvm_arch_handle_crash(CPUState *cs, struct kvm_run *run)
+{
+ if (run->system_event.flags & KVM_SYSTEM_EVENT_FL_HV_CRASH) {
+ return kvm_arch_handle_hv_crash(cs);
+ }
+ return 0;
+}
+
#define VMX_INVALID_GUEST_STATE 0x80000021
int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
diff --git a/target-i386/machine.c b/target-i386/machine.c
index a0df64b..4f72ba8 100644
--- a/target-i386/machine.c
+++ b/target-i386/machine.c
@@ -661,6 +661,29 @@ static const VMStateDescription vmstate_msr_hyperv_time = {
}
};
+static bool hyperv_crash_enable_needed(void *opaque)
+{
+ X86CPU *cpu = opaque;
+ CPUX86State *env = &cpu->env;
+
+ return (env->msr_hv_crash_ctl & HV_X64_MSR_CRASH_CTL_CONTENTS) ?
+ true : false;
+}
+
+static const VMStateDescription vmstate_msr_hyperv_crash = {
+ .name = "cpu/msr_hyperv_crash",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = hyperv_crash_enable_needed,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT64(env.msr_hv_crash_ctl, X86CPU),
+ VMSTATE_UINT64_ARRAY(env.msr_hv_crash_prm,
+ X86CPU, HV_X64_MSR_CRASH_PARAMS),
+ VMSTATE_UINT8(env.hv_crash_occurred, X86CPU),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static bool avx512_needed(void *opaque)
{
X86CPU *cpu = opaque;
@@ -842,6 +865,7 @@ VMStateDescription vmstate_x86_cpu = {
&vmstate_msr_hypercall_hypercall,
&vmstate_msr_hyperv_vapic,
&vmstate_msr_hyperv_time,
+ &vmstate_msr_hyperv_crash,
&vmstate_avx512,
&vmstate_xss,
NULL
diff --git a/target-mips/kvm.c b/target-mips/kvm.c
index 948619f..01a6350 100644
--- a/target-mips/kvm.c
+++ b/target-mips/kvm.c
@@ -122,6 +122,11 @@ int kvm_arch_process_async_events(CPUState *cs)
return cs->halted;
}
+int kvm_arch_handle_crash(CPUState *cs, struct kvm_run *run)
+{
+ return 0;
+}
+
int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
{
int ret;
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index afb4696..6b53a85 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -1564,6 +1564,11 @@ static int kvm_handle_debug(PowerPCCPU *cpu, struct kvm_run *run)
return handle;
}
+int kvm_arch_handle_crash(CPUState *cs, struct kvm_run *run)
+{
+ return 0;
+}
+
int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
{
PowerPCCPU *cpu = POWERPC_CPU(cs);
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 135111a..79317c8 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -1796,13 +1796,6 @@ static bool is_special_wait_psw(CPUState *cs)
return cs->kvm_run->psw_addr == 0xfffUL;
}
-static void guest_panicked(void)
-{
- qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_PAUSE,
- &error_abort);
- vm_stop(RUN_STATE_GUEST_PANICKED);
-}
-
static void unmanageable_intercept(S390CPU *cpu, const char *str, int pswoffset)
{
CPUState *cs = CPU(cpu);
@@ -1811,7 +1804,7 @@ static void unmanageable_intercept(S390CPU *cpu, const char *str, int pswoffset)
str, cs->cpu_index, ldq_phys(cs->as, cpu->env.psa + pswoffset),
ldq_phys(cs->as, cpu->env.psa + pswoffset + 8));
s390_cpu_halt(cpu);
- guest_panicked();
+ qemu_system_guest_panicked();
}
static int handle_intercept(S390CPU *cpu)
@@ -1844,7 +1837,7 @@ static int handle_intercept(S390CPU *cpu)
if (is_special_wait_psw(cs)) {
qemu_system_shutdown_request();
} else {
- guest_panicked();
+ qemu_system_guest_panicked();
}
}
r = EXCP_HALTED;
@@ -2002,6 +1995,11 @@ static int kvm_arch_handle_debug_exit(S390CPU *cpu)
return ret;
}
+int kvm_arch_handle_crash(CPUState *cs, struct kvm_run *run)
+{
+ return 0;
+}
+
int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
{
S390CPU *cpu = S390_CPU(cs);
diff --git a/vl.c b/vl.c
index 69ad90c..38eee1f 100644
--- a/vl.c
+++ b/vl.c
@@ -1721,6 +1721,12 @@ void qemu_system_reset(bool report)
cpu_synchronize_all_post_reset();
}
+void qemu_system_guest_panicked(void)
+{
+ qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_PAUSE, &error_abort);
+ vm_stop(RUN_STATE_GUEST_PANICKED);
+}
+
void qemu_system_reset_request(void)
{
if (no_reboot) {
--
2.1.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] [PATCH v3 0/9] HyperV equivalent of pvpanic driver
2015-06-30 11:33 [Qemu-devel] [PATCH v3 0/9] HyperV equivalent of pvpanic driver Denis V. Lunev
` (8 preceding siblings ...)
2015-06-30 11:33 ` [Qemu-devel] [PATCH 9/9] qemu/kvm: kvm hyper-v based guest crash event handling Denis V. Lunev
@ 2015-06-30 12:26 ` Daniel P. Berrange
2015-06-30 12:38 ` Denis V. Lunev
2015-07-01 14:09 ` Paolo Bonzini
10 siblings, 1 reply; 31+ messages in thread
From: Daniel P. Berrange @ 2015-06-30 12:26 UTC (permalink / raw)
To: Denis V. Lunev
Cc: Gleb Natapov, Paolo Bonzini, qemu-devel, kvm, Andrey Smetanin
On Tue, Jun 30, 2015 at 02:33:18PM +0300, Denis V. Lunev wrote:
> Windows 2012 guests can notify hypervisor about occurred guest crash
> (Windows bugcheck(BSOD)) by writing specific Hyper-V msrs. This patch does
> handling of this MSR's by KVM and sending notification to user space that
> allows to gather Windows guest crash dump by QEMU/LIBVIRT.
>
> The idea is to provide functionality equal to pvpanic device without
> QEMU guest agent for Windows.
That's nice - do you know if the Linux kernel (or any other non-Win2k12
kernels) have support for notifying hypevisors via this Hyper-V msr,
when running as a guest ?
Regards,
Daniel
--
|: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org -o- http://virt-manager.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] [PATCH v3 0/9] HyperV equivalent of pvpanic driver
2015-06-30 12:26 ` [Qemu-devel] [PATCH v3 0/9] HyperV equivalent of pvpanic driver Daniel P. Berrange
@ 2015-06-30 12:38 ` Denis V. Lunev
0 siblings, 0 replies; 31+ messages in thread
From: Denis V. Lunev @ 2015-06-30 12:38 UTC (permalink / raw)
To: Daniel P. Berrange
Cc: Gleb Natapov, Paolo Bonzini, qemu-devel, kvm, Andrey Smetanin
On 30/06/15 15:26, Daniel P. Berrange wrote:
> On Tue, Jun 30, 2015 at 02:33:18PM +0300, Denis V. Lunev wrote:
>> Windows 2012 guests can notify hypervisor about occurred guest crash
>> (Windows bugcheck(BSOD)) by writing specific Hyper-V msrs. This patch does
>> handling of this MSR's by KVM and sending notification to user space that
>> allows to gather Windows guest crash dump by QEMU/LIBVIRT.
>>
>> The idea is to provide functionality equal to pvpanic device without
>> QEMU guest agent for Windows.
> That's nice - do you know if the Linux kernel (or any other non-Win2k12
> kernels) have support for notifying hypevisors via this Hyper-V msr,
> when running as a guest ?
>
> Regards,
> Daniel
Linux for sure is able to do that if configured to run
on top of Hyper-V
drivers/hv/vmbus_drv.c:
static int hyperv_panic_event(struct notifier_block *nb,
unsigned long event, void *ptr)
{
struct pt_regs *regs;
regs = current_pt_regs();
wrmsrl(HV_X64_MSR_CRASH_P0, regs->ip);
wrmsrl(HV_X64_MSR_CRASH_P1, regs->ax);
wrmsrl(HV_X64_MSR_CRASH_P2, regs->bx);
wrmsrl(HV_X64_MSR_CRASH_P3, regs->cx);
wrmsrl(HV_X64_MSR_CRASH_P4, regs->dx);
/*
* Let Hyper-V know there is crash data available
*/
wrmsrl(HV_X64_MSR_CRASH_CTL, HV_CRASH_CTL_CRASH_NOTIFY);
return NOTIFY_DONE;
}
Regards,
Den
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] [PATCH 1/9] kvm/x86: move Hyper-V MSR's/hypercall code into hyperv.c file
2015-06-30 11:33 ` [Qemu-devel] [PATCH 1/9] kvm/x86: move Hyper-V MSR's/hypercall code into hyperv.c file Denis V. Lunev
@ 2015-07-01 0:11 ` Peter Hornyack
0 siblings, 0 replies; 31+ messages in thread
From: Peter Hornyack @ 2015-07-01 0:11 UTC (permalink / raw)
To: Denis V. Lunev
Cc: Andrey Smetanin, Paolo Bonzini, Gleb Natapov, qemu-devel, kvm
On Tue, Jun 30, 2015 at 4:33 AM, Denis V. Lunev <den@openvz.org> wrote:
> From: Andrey Smetanin <asmetanin@virtuozzo.com>
>
> This patch introduce Hyper-V related source code file - hyperv.c and
> per vm and per vcpu hyperv context structures.
> All Hyper-V MSR's and hypercall code moved into hyperv.c.
> All Hyper-V kvm/vcpu fields moved into appropriate hyperv context
> structures. Copyrights and authors information copied from x86.c
> to hyperv.c.
>
> Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
> Signed-off-by: Denis V. Lunev <den@openvz.org>
> CC: Paolo Bonzini <pbonzini@redhat.com>
> CC: Gleb Natapov <gleb@kernel.org>
Reviewed-by: Peter Hornyack <peterhornyack@google.com>
> ---
> arch/x86/include/asm/kvm_host.h | 20 ++-
> arch/x86/kvm/Makefile | 4 +-
> arch/x86/kvm/hyperv.c | 307 ++++++++++++++++++++++++++++++++++++++++
> arch/x86/kvm/hyperv.h | 32 +++++
> arch/x86/kvm/lapic.h | 2 +-
> arch/x86/kvm/x86.c | 265 +---------------------------------
> arch/x86/kvm/x86.h | 5 +
> 7 files changed, 366 insertions(+), 269 deletions(-)
> create mode 100644 arch/x86/kvm/hyperv.c
> create mode 100644 arch/x86/kvm/hyperv.h
>
> diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
> index c7fa57b..78616aa 100644
> --- a/arch/x86/include/asm/kvm_host.h
> +++ b/arch/x86/include/asm/kvm_host.h
> @@ -358,6 +358,11 @@ struct kvm_mtrr {
> struct list_head head;
> };
>
> +/* Hyper-V per vcpu emulation context */
> +struct kvm_vcpu_hv {
> + u64 hv_vapic;
> +};
> +
> struct kvm_vcpu_arch {
> /*
> * rip and regs accesses must go through
> @@ -514,8 +519,7 @@ struct kvm_vcpu_arch {
> /* used for guest single stepping over the given code position */
> unsigned long singlestep_rip;
>
> - /* fields used by HYPER-V emulation */
> - u64 hv_vapic;
> + struct kvm_vcpu_hv hyperv;
>
> cpumask_var_t wbinvd_dirty_mask;
>
> @@ -586,6 +590,13 @@ struct kvm_apic_map {
> struct kvm_lapic *logical_map[16][16];
> };
>
> +/* Hyper-V emulation context */
> +struct kvm_hv {
> + u64 hv_guest_os_id;
> + u64 hv_hypercall;
> + u64 hv_tsc_page;
> +};
> +
> struct kvm_arch {
> unsigned int n_used_mmu_pages;
> unsigned int n_requested_mmu_pages;
> @@ -643,10 +654,7 @@ struct kvm_arch {
> /* reads protected by irq_srcu, writes by irq_lock */
> struct hlist_head mask_notifier_list;
>
> - /* fields used by HYPER-V emulation */
> - u64 hv_guest_os_id;
> - u64 hv_hypercall;
> - u64 hv_tsc_page;
> + struct kvm_hv hyperv;
>
> #ifdef CONFIG_KVM_MMU_AUDIT
> int audit_point;
> diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile
> index 67d215c..a1ff508 100644
> --- a/arch/x86/kvm/Makefile
> +++ b/arch/x86/kvm/Makefile
> @@ -12,7 +12,9 @@ kvm-y += $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o \
> kvm-$(CONFIG_KVM_ASYNC_PF) += $(KVM)/async_pf.o
>
> kvm-y += x86.o mmu.o emulate.o i8259.o irq.o lapic.o \
> - i8254.o ioapic.o irq_comm.o cpuid.o pmu.o mtrr.o
> + i8254.o ioapic.o irq_comm.o cpuid.o pmu.o mtrr.o \
> + hyperv.o
> +
> kvm-$(CONFIG_KVM_DEVICE_ASSIGNMENT) += assigned-dev.o iommu.o
> kvm-intel-y += vmx.o pmu_intel.o
> kvm-amd-y += svm.o pmu_amd.o
> diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
> new file mode 100644
> index 0000000..2b49f10
> --- /dev/null
> +++ b/arch/x86/kvm/hyperv.c
> @@ -0,0 +1,307 @@
> +/*
> + * KVM Microsoft Hyper-V emulation
> + *
> + * derived from arch/x86/kvm/x86.c
> + *
> + * Copyright (C) 2006 Qumranet, Inc.
> + * Copyright (C) 2008 Qumranet, Inc.
> + * Copyright IBM Corporation, 2008
> + * Copyright 2010 Red Hat, Inc. and/or its affiliates.
> + * Copyright (C) 2015 Andrey Smetanin <asmetanin@virtuozzo.com>
> + *
> + * Authors:
> + * Avi Kivity <avi@qumranet.com>
> + * Yaniv Kamay <yaniv@qumranet.com>
> + * Amit Shah <amit.shah@qumranet.com>
> + * Ben-Ami Yassour <benami@il.ibm.com>
> + * Andrey Smetanin <asmetanin@virtuozzo.com>
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2. See
> + * the COPYING file in the top-level directory.
> + *
> + */
> +
> +#include "x86.h"
> +#include "lapic.h"
> +#include "hyperv.h"
> +
> +#include <linux/kvm_host.h>
> +#include <trace/events/kvm.h>
> +
> +#include "trace.h"
> +
> +static bool kvm_hv_msr_partition_wide(u32 msr)
> +{
> + bool r = false;
> +
> + switch (msr) {
> + case HV_X64_MSR_GUEST_OS_ID:
> + case HV_X64_MSR_HYPERCALL:
> + case HV_X64_MSR_REFERENCE_TSC:
> + case HV_X64_MSR_TIME_REF_COUNT:
> + r = true;
> + break;
> + }
> +
> + return r;
> +}
> +
> +static int kvm_hv_set_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data)
> +{
> + struct kvm *kvm = vcpu->kvm;
> + struct kvm_hv *hv = &kvm->arch.hyperv;
> +
> + switch (msr) {
> + case HV_X64_MSR_GUEST_OS_ID:
> + hv->hv_guest_os_id = data;
> + /* setting guest os id to zero disables hypercall page */
> + if (!hv->hv_guest_os_id)
> + hv->hv_hypercall &= ~HV_X64_MSR_HYPERCALL_ENABLE;
> + break;
> + case HV_X64_MSR_HYPERCALL: {
> + u64 gfn;
> + unsigned long addr;
> + u8 instructions[4];
> +
> + /* if guest os id is not set hypercall should remain disabled */
> + if (!hv->hv_guest_os_id)
> + break;
> + if (!(data & HV_X64_MSR_HYPERCALL_ENABLE)) {
> + hv->hv_hypercall = data;
> + break;
> + }
> + gfn = data >> HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT;
> + addr = gfn_to_hva(kvm, gfn);
> + if (kvm_is_error_hva(addr))
> + return 1;
> + kvm_x86_ops->patch_hypercall(vcpu, instructions);
> + ((unsigned char *)instructions)[3] = 0xc3; /* ret */
> + if (__copy_to_user((void __user *)addr, instructions, 4))
> + return 1;
> + hv->hv_hypercall = data;
> + mark_page_dirty(kvm, gfn);
> + break;
> + }
> + case HV_X64_MSR_REFERENCE_TSC: {
> + u64 gfn;
> + HV_REFERENCE_TSC_PAGE tsc_ref;
> +
> + memset(&tsc_ref, 0, sizeof(tsc_ref));
> + hv->hv_tsc_page = data;
> + if (!(data & HV_X64_MSR_TSC_REFERENCE_ENABLE))
> + break;
> + gfn = data >> HV_X64_MSR_TSC_REFERENCE_ADDRESS_SHIFT;
> + if (kvm_write_guest(
> + kvm,
> + gfn << HV_X64_MSR_TSC_REFERENCE_ADDRESS_SHIFT,
> + &tsc_ref, sizeof(tsc_ref)))
> + return 1;
> + mark_page_dirty(kvm, gfn);
> + break;
> + }
> + default:
> + vcpu_unimpl(vcpu, "Hyper-V uhandled wrmsr: 0x%x data 0x%llx\n",
> + msr, data);
> + return 1;
> + }
> + return 0;
> +}
> +
> +static int kvm_hv_set_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data)
> +{
> + struct kvm_vcpu_hv *hv = &vcpu->arch.hyperv;
> +
> + switch (msr) {
> + case HV_X64_MSR_APIC_ASSIST_PAGE: {
> + u64 gfn;
> + unsigned long addr;
> +
> + if (!(data & HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE)) {
> + hv->hv_vapic = data;
> + if (kvm_lapic_enable_pv_eoi(vcpu, 0))
> + return 1;
> + break;
> + }
> + gfn = data >> HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT;
> + addr = kvm_vcpu_gfn_to_hva(vcpu, gfn);
> + if (kvm_is_error_hva(addr))
> + return 1;
> + if (__clear_user((void __user *)addr, PAGE_SIZE))
> + return 1;
> + hv->hv_vapic = data;
> + kvm_vcpu_mark_page_dirty(vcpu, gfn);
> + if (kvm_lapic_enable_pv_eoi(vcpu,
> + gfn_to_gpa(gfn) | KVM_MSR_ENABLED))
> + return 1;
> + break;
> + }
> + case HV_X64_MSR_EOI:
> + return kvm_hv_vapic_msr_write(vcpu, APIC_EOI, data);
> + case HV_X64_MSR_ICR:
> + return kvm_hv_vapic_msr_write(vcpu, APIC_ICR, data);
> + case HV_X64_MSR_TPR:
> + return kvm_hv_vapic_msr_write(vcpu, APIC_TASKPRI, data);
> + default:
> + vcpu_unimpl(vcpu, "Hyper-V uhandled wrmsr: 0x%x data 0x%llx\n",
> + msr, data);
> + return 1;
> + }
> +
> + return 0;
> +}
> +
> +static int kvm_hv_get_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
> +{
> + u64 data = 0;
> + struct kvm *kvm = vcpu->kvm;
> + struct kvm_hv *hv = &kvm->arch.hyperv;
> +
> + switch (msr) {
> + case HV_X64_MSR_GUEST_OS_ID:
> + data = hv->hv_guest_os_id;
> + break;
> + case HV_X64_MSR_HYPERCALL:
> + data = hv->hv_hypercall;
> + break;
> + case HV_X64_MSR_TIME_REF_COUNT: {
> + data =
> + div_u64(get_kernel_ns() + kvm->arch.kvmclock_offset, 100);
> + break;
> + }
> + case HV_X64_MSR_REFERENCE_TSC:
> + data = hv->hv_tsc_page;
> + break;
> + default:
> + vcpu_unimpl(vcpu, "Hyper-V unhandled rdmsr: 0x%x\n", msr);
> + return 1;
> + }
> +
> + *pdata = data;
> + return 0;
> +}
> +
> +static int kvm_hv_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
> +{
> + u64 data = 0;
> + struct kvm_vcpu_hv *hv = &vcpu->arch.hyperv;
> +
> + switch (msr) {
> + case HV_X64_MSR_VP_INDEX: {
> + int r;
> + struct kvm_vcpu *v;
> +
> + kvm_for_each_vcpu(r, v, vcpu->kvm) {
> + if (v == vcpu) {
> + data = r;
> + break;
> + }
> + }
> + break;
> + }
> + case HV_X64_MSR_EOI:
> + return kvm_hv_vapic_msr_read(vcpu, APIC_EOI, pdata);
> + case HV_X64_MSR_ICR:
> + return kvm_hv_vapic_msr_read(vcpu, APIC_ICR, pdata);
> + case HV_X64_MSR_TPR:
> + return kvm_hv_vapic_msr_read(vcpu, APIC_TASKPRI, pdata);
> + case HV_X64_MSR_APIC_ASSIST_PAGE:
> + data = hv->hv_vapic;
> + break;
> + default:
> + vcpu_unimpl(vcpu, "Hyper-V unhandled rdmsr: 0x%x\n", msr);
> + return 1;
> + }
> + *pdata = data;
> + return 0;
> +}
> +
> +int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
> +{
> + if (kvm_hv_msr_partition_wide(msr)) {
> + int r;
> +
> + mutex_lock(&vcpu->kvm->lock);
> + r = kvm_hv_set_msr_pw(vcpu, msr, data);
> + mutex_unlock(&vcpu->kvm->lock);
> + return r;
> + } else
> + return kvm_hv_set_msr(vcpu, msr, data);
> +}
> +
> +int kvm_hv_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
> +{
> + if (kvm_hv_msr_partition_wide(msr)) {
> + int r;
> +
> + mutex_lock(&vcpu->kvm->lock);
> + r = kvm_hv_get_msr_pw(vcpu, msr, pdata);
> + mutex_unlock(&vcpu->kvm->lock);
> + return r;
> + } else
> + return kvm_hv_get_msr(vcpu, msr, pdata);
> +}
> +
> +bool kvm_hv_hypercall_enabled(struct kvm *kvm)
> +{
> + return kvm->arch.hyperv.hv_hypercall & HV_X64_MSR_HYPERCALL_ENABLE;
> +}
> +
> +int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
> +{
> + u64 param, ingpa, outgpa, ret;
> + uint16_t code, rep_idx, rep_cnt, res = HV_STATUS_SUCCESS, rep_done = 0;
> + bool fast, longmode;
> +
> + /*
> + * hypercall generates UD from non zero cpl and real mode
> + * per HYPER-V spec
> + */
> + if (kvm_x86_ops->get_cpl(vcpu) != 0 || !is_protmode(vcpu)) {
> + kvm_queue_exception(vcpu, UD_VECTOR);
> + return 0;
> + }
> +
> + longmode = is_64_bit_mode(vcpu);
> +
> + if (!longmode) {
> + param = ((u64)kvm_register_read(vcpu, VCPU_REGS_RDX) << 32) |
> + (kvm_register_read(vcpu, VCPU_REGS_RAX) & 0xffffffff);
> + ingpa = ((u64)kvm_register_read(vcpu, VCPU_REGS_RBX) << 32) |
> + (kvm_register_read(vcpu, VCPU_REGS_RCX) & 0xffffffff);
> + outgpa = ((u64)kvm_register_read(vcpu, VCPU_REGS_RDI) << 32) |
> + (kvm_register_read(vcpu, VCPU_REGS_RSI) & 0xffffffff);
> + }
> +#ifdef CONFIG_X86_64
> + else {
> + param = kvm_register_read(vcpu, VCPU_REGS_RCX);
> + ingpa = kvm_register_read(vcpu, VCPU_REGS_RDX);
> + outgpa = kvm_register_read(vcpu, VCPU_REGS_R8);
> + }
> +#endif
> +
> + code = param & 0xffff;
> + fast = (param >> 16) & 0x1;
> + rep_cnt = (param >> 32) & 0xfff;
> + rep_idx = (param >> 48) & 0xfff;
> +
> + trace_kvm_hv_hypercall(code, fast, rep_cnt, rep_idx, ingpa, outgpa);
> +
> + switch (code) {
> + case HV_X64_HV_NOTIFY_LONG_SPIN_WAIT:
> + kvm_vcpu_on_spin(vcpu);
> + break;
> + default:
> + res = HV_STATUS_INVALID_HYPERCALL_CODE;
> + break;
> + }
> +
> + ret = res | (((u64)rep_done & 0xfff) << 32);
> + if (longmode) {
> + kvm_register_write(vcpu, VCPU_REGS_RAX, ret);
> + } else {
> + kvm_register_write(vcpu, VCPU_REGS_RDX, ret >> 32);
> + kvm_register_write(vcpu, VCPU_REGS_RAX, ret & 0xffffffff);
> + }
> +
> + return 1;
> +}
> diff --git a/arch/x86/kvm/hyperv.h b/arch/x86/kvm/hyperv.h
> new file mode 100644
> index 0000000..115c738
> --- /dev/null
> +++ b/arch/x86/kvm/hyperv.h
> @@ -0,0 +1,32 @@
> +/*
> + * KVM Microsoft Hyper-V emulation
> + *
> + * derived from arch/x86/kvm/x86.c
> + *
> + * Copyright (C) 2006 Qumranet, Inc.
> + * Copyright (C) 2008 Qumranet, Inc.
> + * Copyright IBM Corporation, 2008
> + * Copyright 2010 Red Hat, Inc. and/or its affiliates.
> + * Copyright (C) 2015 Andrey Smetanin <asmetanin@virtuozzo.com>
> + *
> + * Authors:
> + * Avi Kivity <avi@qumranet.com>
> + * Yaniv Kamay <yaniv@qumranet.com>
> + * Amit Shah <amit.shah@qumranet.com>
> + * Ben-Ami Yassour <benami@il.ibm.com>
> + * Andrey Smetanin <asmetanin@virtuozzo.com>
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2. See
> + * the COPYING file in the top-level directory.
> + *
> + */
> +
> +#ifndef __ARCH_X86_KVM_HYPERV_H__
> +#define __ARCH_X86_KVM_HYPERV_H__
> +
> +int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data);
> +int kvm_hv_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata);
> +bool kvm_hv_hypercall_enabled(struct kvm *kvm);
> +int kvm_hv_hypercall(struct kvm_vcpu *vcpu);
> +
> +#endif
> diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h
> index f2f4e10..26f7817 100644
> --- a/arch/x86/kvm/lapic.h
> +++ b/arch/x86/kvm/lapic.h
> @@ -90,7 +90,7 @@ int kvm_hv_vapic_msr_read(struct kvm_vcpu *vcpu, u32 msr, u64 *data);
>
> static inline bool kvm_hv_vapic_assist_page_enabled(struct kvm_vcpu *vcpu)
> {
> - return vcpu->arch.hv_vapic & HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE;
> + return vcpu->arch.hyperv.hv_vapic & HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE;
> }
>
> int kvm_lapic_enable_pv_eoi(struct kvm_vcpu *vcpu, u64 data);
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index ac165c2..301ee01 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -29,6 +29,7 @@
> #include "cpuid.h"
> #include "assigned-dev.h"
> #include "pmu.h"
> +#include "hyperv.h"
>
> #include <linux/clocksource.h>
> #include <linux/interrupt.h>
> @@ -1217,11 +1218,6 @@ static void kvm_get_time_scale(uint32_t scaled_khz, uint32_t base_khz,
> __func__, base_khz, scaled_khz, shift, *pmultiplier);
> }
>
> -static inline u64 get_kernel_ns(void)
> -{
> - return ktime_get_boot_ns();
> -}
> -
> #ifdef CONFIG_X86_64
> static atomic_t kvm_guest_has_master_clock = ATOMIC_INIT(0);
> #endif
> @@ -1869,123 +1865,6 @@ out:
> return r;
> }
>
> -static bool kvm_hv_hypercall_enabled(struct kvm *kvm)
> -{
> - return kvm->arch.hv_hypercall & HV_X64_MSR_HYPERCALL_ENABLE;
> -}
> -
> -static bool kvm_hv_msr_partition_wide(u32 msr)
> -{
> - bool r = false;
> - switch (msr) {
> - case HV_X64_MSR_GUEST_OS_ID:
> - case HV_X64_MSR_HYPERCALL:
> - case HV_X64_MSR_REFERENCE_TSC:
> - case HV_X64_MSR_TIME_REF_COUNT:
> - r = true;
> - break;
> - }
> -
> - return r;
> -}
> -
> -static int set_msr_hyperv_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data)
> -{
> - struct kvm *kvm = vcpu->kvm;
> -
> - switch (msr) {
> - case HV_X64_MSR_GUEST_OS_ID:
> - kvm->arch.hv_guest_os_id = data;
> - /* setting guest os id to zero disables hypercall page */
> - if (!kvm->arch.hv_guest_os_id)
> - kvm->arch.hv_hypercall &= ~HV_X64_MSR_HYPERCALL_ENABLE;
> - break;
> - case HV_X64_MSR_HYPERCALL: {
> - u64 gfn;
> - unsigned long addr;
> - u8 instructions[4];
> -
> - /* if guest os id is not set hypercall should remain disabled */
> - if (!kvm->arch.hv_guest_os_id)
> - break;
> - if (!(data & HV_X64_MSR_HYPERCALL_ENABLE)) {
> - kvm->arch.hv_hypercall = data;
> - break;
> - }
> - gfn = data >> HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT;
> - addr = gfn_to_hva(kvm, gfn);
> - if (kvm_is_error_hva(addr))
> - return 1;
> - kvm_x86_ops->patch_hypercall(vcpu, instructions);
> - ((unsigned char *)instructions)[3] = 0xc3; /* ret */
> - if (__copy_to_user((void __user *)addr, instructions, 4))
> - return 1;
> - kvm->arch.hv_hypercall = data;
> - mark_page_dirty(kvm, gfn);
> - break;
> - }
> - case HV_X64_MSR_REFERENCE_TSC: {
> - u64 gfn;
> - HV_REFERENCE_TSC_PAGE tsc_ref;
> - memset(&tsc_ref, 0, sizeof(tsc_ref));
> - kvm->arch.hv_tsc_page = data;
> - if (!(data & HV_X64_MSR_TSC_REFERENCE_ENABLE))
> - break;
> - gfn = data >> HV_X64_MSR_TSC_REFERENCE_ADDRESS_SHIFT;
> - if (kvm_write_guest(kvm, gfn << HV_X64_MSR_TSC_REFERENCE_ADDRESS_SHIFT,
> - &tsc_ref, sizeof(tsc_ref)))
> - return 1;
> - mark_page_dirty(kvm, gfn);
> - break;
> - }
> - default:
> - vcpu_unimpl(vcpu, "HYPER-V unimplemented wrmsr: 0x%x "
> - "data 0x%llx\n", msr, data);
> - return 1;
> - }
> - return 0;
> -}
> -
> -static int set_msr_hyperv(struct kvm_vcpu *vcpu, u32 msr, u64 data)
> -{
> - switch (msr) {
> - case HV_X64_MSR_APIC_ASSIST_PAGE: {
> - u64 gfn;
> - unsigned long addr;
> -
> - if (!(data & HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE)) {
> - vcpu->arch.hv_vapic = data;
> - if (kvm_lapic_enable_pv_eoi(vcpu, 0))
> - return 1;
> - break;
> - }
> - gfn = data >> HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT;
> - addr = kvm_vcpu_gfn_to_hva(vcpu, gfn);
> - if (kvm_is_error_hva(addr))
> - return 1;
> - if (__clear_user((void __user *)addr, PAGE_SIZE))
> - return 1;
> - vcpu->arch.hv_vapic = data;
> - kvm_vcpu_mark_page_dirty(vcpu, gfn);
> - if (kvm_lapic_enable_pv_eoi(vcpu, gfn_to_gpa(gfn) | KVM_MSR_ENABLED))
> - return 1;
> - break;
> - }
> - case HV_X64_MSR_EOI:
> - return kvm_hv_vapic_msr_write(vcpu, APIC_EOI, data);
> - case HV_X64_MSR_ICR:
> - return kvm_hv_vapic_msr_write(vcpu, APIC_ICR, data);
> - case HV_X64_MSR_TPR:
> - return kvm_hv_vapic_msr_write(vcpu, APIC_TASKPRI, data);
> - default:
> - vcpu_unimpl(vcpu, "HYPER-V unimplemented wrmsr: 0x%x "
> - "data 0x%llx\n", msr, data);
> - return 1;
> - }
> -
> - return 0;
> -}
> -
> static int kvm_pv_enable_async_pf(struct kvm_vcpu *vcpu, u64 data)
> {
> gpa_t gpa = data & ~0x3f;
> @@ -2224,15 +2103,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
> */
> break;
> case HV_X64_MSR_GUEST_OS_ID ... HV_X64_MSR_SINT15:
> - if (kvm_hv_msr_partition_wide(msr)) {
> - int r;
> - mutex_lock(&vcpu->kvm->lock);
> - r = set_msr_hyperv_pw(vcpu, msr, data);
> - mutex_unlock(&vcpu->kvm->lock);
> - return r;
> - } else
> - return set_msr_hyperv(vcpu, msr, data);
> - break;
> + return kvm_hv_set_msr_common(vcpu, msr, data);
> case MSR_IA32_BBL_CR_CTL3:
> /* Drop writes to this legacy MSR -- see rdmsr
> * counterpart for further detail.
> @@ -2315,68 +2186,6 @@ static int get_msr_mce(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
> return 0;
> }
>
> -static int get_msr_hyperv_pw(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
> -{
> - u64 data = 0;
> - struct kvm *kvm = vcpu->kvm;
> -
> - switch (msr) {
> - case HV_X64_MSR_GUEST_OS_ID:
> - data = kvm->arch.hv_guest_os_id;
> - break;
> - case HV_X64_MSR_HYPERCALL:
> - data = kvm->arch.hv_hypercall;
> - break;
> - case HV_X64_MSR_TIME_REF_COUNT: {
> - data =
> - div_u64(get_kernel_ns() + kvm->arch.kvmclock_offset, 100);
> - break;
> - }
> - case HV_X64_MSR_REFERENCE_TSC:
> - data = kvm->arch.hv_tsc_page;
> - break;
> - default:
> - vcpu_unimpl(vcpu, "Hyper-V unhandled rdmsr: 0x%x\n", msr);
> - return 1;
> - }
> -
> - *pdata = data;
> - return 0;
> -}
> -
> -static int get_msr_hyperv(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
> -{
> - u64 data = 0;
> -
> - switch (msr) {
> - case HV_X64_MSR_VP_INDEX: {
> - int r;
> - struct kvm_vcpu *v;
> - kvm_for_each_vcpu(r, v, vcpu->kvm) {
> - if (v == vcpu) {
> - data = r;
> - break;
> - }
> - }
> - break;
> - }
> - case HV_X64_MSR_EOI:
> - return kvm_hv_vapic_msr_read(vcpu, APIC_EOI, pdata);
> - case HV_X64_MSR_ICR:
> - return kvm_hv_vapic_msr_read(vcpu, APIC_ICR, pdata);
> - case HV_X64_MSR_TPR:
> - return kvm_hv_vapic_msr_read(vcpu, APIC_TASKPRI, pdata);
> - case HV_X64_MSR_APIC_ASSIST_PAGE:
> - data = vcpu->arch.hv_vapic;
> - break;
> - default:
> - vcpu_unimpl(vcpu, "Hyper-V unhandled rdmsr: 0x%x\n", msr);
> - return 1;
> - }
> - *pdata = data;
> - return 0;
> -}
> -
> int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
> {
> u64 data;
> @@ -2495,14 +2304,8 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
> msr_info->data = 0x20000000;
> break;
> case HV_X64_MSR_GUEST_OS_ID ... HV_X64_MSR_SINT15:
> - if (kvm_hv_msr_partition_wide(msr_info->index)) {
> - int r;
> - mutex_lock(&vcpu->kvm->lock);
> - r = get_msr_hyperv_pw(vcpu, msr_info->index, &msr_info->data);
> - mutex_unlock(&vcpu->kvm->lock);
> - return r;
> - } else
> - return get_msr_hyperv(vcpu, msr_info->index, &msr_info->data);
> + return kvm_hv_get_msr_common(vcpu,
> + msr_info->index, &msr_info->data);
> break;
> case MSR_IA32_BBL_CR_CTL3:
> /* This legacy MSR exists but isn't fully documented in current
> @@ -5885,66 +5688,6 @@ int kvm_emulate_halt(struct kvm_vcpu *vcpu)
> }
> EXPORT_SYMBOL_GPL(kvm_emulate_halt);
>
> -int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
> -{
> - u64 param, ingpa, outgpa, ret;
> - uint16_t code, rep_idx, rep_cnt, res = HV_STATUS_SUCCESS, rep_done = 0;
> - bool fast, longmode;
> -
> - /*
> - * hypercall generates UD from non zero cpl and real mode
> - * per HYPER-V spec
> - */
> - if (kvm_x86_ops->get_cpl(vcpu) != 0 || !is_protmode(vcpu)) {
> - kvm_queue_exception(vcpu, UD_VECTOR);
> - return 0;
> - }
> -
> - longmode = is_64_bit_mode(vcpu);
> -
> - if (!longmode) {
> - param = ((u64)kvm_register_read(vcpu, VCPU_REGS_RDX) << 32) |
> - (kvm_register_read(vcpu, VCPU_REGS_RAX) & 0xffffffff);
> - ingpa = ((u64)kvm_register_read(vcpu, VCPU_REGS_RBX) << 32) |
> - (kvm_register_read(vcpu, VCPU_REGS_RCX) & 0xffffffff);
> - outgpa = ((u64)kvm_register_read(vcpu, VCPU_REGS_RDI) << 32) |
> - (kvm_register_read(vcpu, VCPU_REGS_RSI) & 0xffffffff);
> - }
> -#ifdef CONFIG_X86_64
> - else {
> - param = kvm_register_read(vcpu, VCPU_REGS_RCX);
> - ingpa = kvm_register_read(vcpu, VCPU_REGS_RDX);
> - outgpa = kvm_register_read(vcpu, VCPU_REGS_R8);
> - }
> -#endif
> -
> - code = param & 0xffff;
> - fast = (param >> 16) & 0x1;
> - rep_cnt = (param >> 32) & 0xfff;
> - rep_idx = (param >> 48) & 0xfff;
> -
> - trace_kvm_hv_hypercall(code, fast, rep_cnt, rep_idx, ingpa, outgpa);
> -
> - switch (code) {
> - case HV_X64_HV_NOTIFY_LONG_SPIN_WAIT:
> - kvm_vcpu_on_spin(vcpu);
> - break;
> - default:
> - res = HV_STATUS_INVALID_HYPERCALL_CODE;
> - break;
> - }
> -
> - ret = res | (((u64)rep_done & 0xfff) << 32);
> - if (longmode) {
> - kvm_register_write(vcpu, VCPU_REGS_RAX, ret);
> - } else {
> - kvm_register_write(vcpu, VCPU_REGS_RDX, ret >> 32);
> - kvm_register_write(vcpu, VCPU_REGS_RAX, ret & 0xffffffff);
> - }
> -
> - return 1;
> -}
> -
> /*
> * kvm_pv_kick_cpu_op: Kick a vcpu.
> *
> diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
> index edc8cdc..c04b56b 100644
> --- a/arch/x86/kvm/x86.h
> +++ b/arch/x86/kvm/x86.h
> @@ -147,6 +147,11 @@ static inline void kvm_register_writel(struct kvm_vcpu *vcpu,
> return kvm_register_write(vcpu, reg, val);
> }
>
> +static inline u64 get_kernel_ns(void)
> +{
> + return ktime_get_boot_ns();
> +}
> +
> void kvm_before_handle_nmi(struct kvm_vcpu *vcpu);
> void kvm_after_handle_nmi(struct kvm_vcpu *vcpu);
> void kvm_set_pending_timer(struct kvm_vcpu *vcpu);
> --
> 2.1.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] [PATCH 2/9] kvm: introduce vcpu_debug = kvm_debug + vcpu context
2015-06-30 11:33 ` [Qemu-devel] [PATCH 2/9] kvm: introduce vcpu_debug = kvm_debug + vcpu context Denis V. Lunev
@ 2015-07-01 0:12 ` Peter Hornyack
0 siblings, 0 replies; 31+ messages in thread
From: Peter Hornyack @ 2015-07-01 0:12 UTC (permalink / raw)
To: Denis V. Lunev
Cc: Andrey Smetanin, Paolo Bonzini, Gleb Natapov, qemu-devel, kvm
On Tue, Jun 30, 2015 at 4:33 AM, Denis V. Lunev <den@openvz.org> wrote:
> From: Andrey Smetanin <asmetanin@virtuozzo.com>
>
> vcpu_debug is useful macro like kvm_debug but additionally
> includes vcpu context inside output.
>
> Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
> Signed-off-by: Denis V. Lunev <den@openvz.org>
> CC: Paolo Bonzini <pbonzini@redhat.com>
> CC: Gleb Natapov <gleb@kernel.org>
Reviewed-by: Peter Hornyack <peterhornyack@google.com>
> ---
> include/linux/kvm_host.h | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
> index 9564fd7..2b2edf1 100644
> --- a/include/linux/kvm_host.h
> +++ b/include/linux/kvm_host.h
> @@ -424,6 +424,9 @@ struct kvm {
> #define vcpu_unimpl(vcpu, fmt, ...) \
> kvm_pr_unimpl("vcpu%i " fmt, (vcpu)->vcpu_id, ## __VA_ARGS__)
>
> +#define vcpu_debug(vcpu, fmt, ...) \
> + kvm_debug("vcpu%i " fmt, (vcpu)->vcpu_id, ## __VA_ARGS__)
> +
> static inline struct kvm_vcpu *kvm_get_vcpu(struct kvm *kvm, int i)
> {
> smp_rmb();
> --
> 2.1.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] [PATCH 3/9] kvm: add hyper-v crash msrs values
2015-06-30 11:33 ` [Qemu-devel] [PATCH 3/9] kvm: add hyper-v crash msrs values Denis V. Lunev
@ 2015-07-01 0:14 ` Peter Hornyack
2015-07-01 15:00 ` Paolo Bonzini
1 sibling, 0 replies; 31+ messages in thread
From: Peter Hornyack @ 2015-07-01 0:14 UTC (permalink / raw)
To: Denis V. Lunev
Cc: Andrey Smetanin, Paolo Bonzini, Gleb Natapov, qemu-devel, kvm
On Tue, Jun 30, 2015 at 4:33 AM, Denis V. Lunev <den@openvz.org> wrote:
> From: Andrey Smetanin <asmetanin@virtuozzo.com>
>
> Added Hyper-V crash msrs values - HV_X64_MSR_CRASH*.
>
> Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
> Signed-off-by: Denis V. Lunev <den@openvz.org>
> CC: Paolo Bonzini <pbonzini@redhat.com>
> CC: Gleb Natapov <gleb@kernel.org>
Reviewed-by: Peter Hornyack <peterhornyack@google.com>
> ---
> arch/x86/include/uapi/asm/hyperv.h | 15 +++++++++++++++
> 1 file changed, 15 insertions(+)
>
> diff --git a/arch/x86/include/uapi/asm/hyperv.h b/arch/x86/include/uapi/asm/hyperv.h
> index ce6068d..3ed7a5c 100644
> --- a/arch/x86/include/uapi/asm/hyperv.h
> +++ b/arch/x86/include/uapi/asm/hyperv.h
> @@ -199,6 +199,21 @@
> #define HV_X64_MSR_STIMER3_CONFIG 0x400000B6
> #define HV_X64_MSR_STIMER3_COUNT 0x400000B7
>
> +/* Hyper-V guest crash notification MSR's */
> +#define HV_X64_MSR_CRASH_P0 0x40000100
> +#define HV_X64_MSR_CRASH_P1 0x40000101
> +#define HV_X64_MSR_CRASH_P2 0x40000102
> +#define HV_X64_MSR_CRASH_P3 0x40000103
> +#define HV_X64_MSR_CRASH_P4 0x40000104
> +#define HV_X64_MSR_CRASH_CTL 0x40000105
> +#define HV_X64_MSR_CRASH_CTL_NOTIFY (1ULL << 63)
> +#define HV_X64_MSR_CRASH_CTL_CONTENTS \
This is unused and can be deleted, right?
> + (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_ENABLE 0x00000001
> #define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT 12
> #define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_MASK \
> --
> 2.1.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] [PATCH 4/9] kvm/x86: added hyper-v crash msrs into kvm hyperv context
2015-06-30 11:33 ` [Qemu-devel] [PATCH 4/9] kvm/x86: added hyper-v crash msrs into kvm hyperv context Denis V. Lunev
@ 2015-07-01 0:14 ` Peter Hornyack
0 siblings, 0 replies; 31+ messages in thread
From: Peter Hornyack @ 2015-07-01 0:14 UTC (permalink / raw)
To: Denis V. Lunev
Cc: Andrey Smetanin, Paolo Bonzini, Gleb Natapov, qemu-devel, kvm
On Tue, Jun 30, 2015 at 4:33 AM, Denis V. Lunev <den@openvz.org> wrote:
> From: Andrey Smetanin <asmetanin@virtuozzo.com>
>
> Added kvm Hyper-V context hv crash variables as storage
> of Hyper-V crash msrs.
>
> Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
> Signed-off-by: Denis V. Lunev <den@openvz.org>
> CC: Paolo Bonzini <pbonzini@redhat.com>
> CC: Gleb Natapov <gleb@kernel.org>
Reviewed-by: Peter Hornyack <peterhornyack@google.com>
> ---
> arch/x86/include/asm/kvm_host.h | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
> index 78616aa..697c1f3 100644
> --- a/arch/x86/include/asm/kvm_host.h
> +++ b/arch/x86/include/asm/kvm_host.h
> @@ -595,6 +595,10 @@ struct kvm_hv {
> u64 hv_guest_os_id;
> u64 hv_hypercall;
> u64 hv_tsc_page;
> +
> + /* Hyper-v based guest crash (NT kernel bugcheck) parameters */
> + u64 hv_crash_param[HV_X64_MSR_CRASH_PARAMS];
> + u64 hv_crash_ctl;
> };
>
> struct kvm_arch {
> --
> 2.1.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] [PATCH 5/9] kvm: added KVM_REQ_HV_CRASH value to notify qemu about hyper-v crash
2015-06-30 11:33 ` [Qemu-devel] [PATCH 5/9] kvm: added KVM_REQ_HV_CRASH value to notify qemu about hyper-v crash Denis V. Lunev
@ 2015-07-01 0:14 ` Peter Hornyack
0 siblings, 0 replies; 31+ messages in thread
From: Peter Hornyack @ 2015-07-01 0:14 UTC (permalink / raw)
To: Denis V. Lunev
Cc: Andrey Smetanin, Paolo Bonzini, Gleb Natapov, qemu-devel, kvm
On Tue, Jun 30, 2015 at 4:33 AM, Denis V. Lunev <den@openvz.org> wrote:
> From: Andrey Smetanin <asmetanin@virtuozzo.com>
>
> Added KVM_REQ_HV_CRASH - vcpu request used for notify user space(QEMU)
> about Hyper-V crash.
>
> Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
> Signed-off-by: Denis V. Lunev <den@openvz.org>
> CC: Paolo Bonzini <pbonzini@redhat.com>
> CC: Gleb Natapov <gleb@kernel.org>
Reviewed-by: Peter Hornyack <peterhornyack@google.com>
> ---
> include/linux/kvm_host.h | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
> index 2b2edf1..a377e00 100644
> --- a/include/linux/kvm_host.h
> +++ b/include/linux/kvm_host.h
> @@ -139,6 +139,7 @@ static inline bool is_error_page(struct page *page)
> #define KVM_REQ_DISABLE_IBS 24
> #define KVM_REQ_APIC_PAGE_RELOAD 25
> #define KVM_REQ_SMI 26
> +#define KVM_REQ_HV_CRASH 27
>
> #define KVM_USERSPACE_IRQ_SOURCE_ID 0
> #define KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID 1
> --
> 2.1.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] [PATCH 6/9] kvm/x86: mark hyper-v crash msrs as partition wide
2015-06-30 11:33 ` [Qemu-devel] [PATCH 6/9] kvm/x86: mark hyper-v crash msrs as partition wide Denis V. Lunev
@ 2015-07-01 0:15 ` Peter Hornyack
0 siblings, 0 replies; 31+ messages in thread
From: Peter Hornyack @ 2015-07-01 0:15 UTC (permalink / raw)
To: Denis V. Lunev
Cc: Andrey Smetanin, Paolo Bonzini, Gleb Natapov, qemu-devel, kvm
On Tue, Jun 30, 2015 at 4:33 AM, Denis V. Lunev <den@openvz.org> wrote:
> From: Andrey Smetanin <asmetanin@virtuozzo.com>
>
> Hyper-V crash msr's are per vm, aren't per vcpu, so mark them
> as partition wide.
>
> Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
> Signed-off-by: Denis V. Lunev <den@openvz.org>
> CC: Paolo Bonzini <pbonzini@redhat.com>
> CC: Gleb Natapov <gleb@kernel.org>
Reviewed-by: Peter Hornyack <peterhornyack@google.com>
> ---
> arch/x86/kvm/hyperv.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
> index 2b49f10..af83c96 100644
> --- a/arch/x86/kvm/hyperv.c
> +++ b/arch/x86/kvm/hyperv.c
> @@ -39,6 +39,8 @@ static bool kvm_hv_msr_partition_wide(u32 msr)
> case HV_X64_MSR_HYPERCALL:
> case HV_X64_MSR_REFERENCE_TSC:
> case HV_X64_MSR_TIME_REF_COUNT:
> + case HV_X64_MSR_CRASH_CTL:
> + case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4:
> r = true;
> break;
> }
> --
> 2.1.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] [PATCH 7/9] kvm/x86: added hyper-v crash data and ctl msr's get/set'ers
2015-06-30 11:33 ` [Qemu-devel] [PATCH 7/9] kvm/x86: added hyper-v crash data and ctl msr's get/set'ers Denis V. Lunev
@ 2015-07-01 0:15 ` Peter Hornyack
2015-07-01 16:47 ` Paolo Bonzini
1 sibling, 0 replies; 31+ messages in thread
From: Peter Hornyack @ 2015-07-01 0:15 UTC (permalink / raw)
To: Denis V. Lunev
Cc: Andrey Smetanin, Paolo Bonzini, Gleb Natapov, qemu-devel, kvm
On Tue, Jun 30, 2015 at 4:33 AM, Denis V. Lunev <den@openvz.org> wrote:
> From: Andrey Smetanin <asmetanin@virtuozzo.com>
>
> Added hyper-v crash msr's(HV_X64_MSR_CRASH*) data and control
> geters and setters.
>
> User space allowed to setup Hyper-V crash ctl msr.
> This msr should be setup to HV_X64_MSR_CRASH_CTL_NOTIFY
> value so Hyper-V guest knows it can send crash data to host.
> But Hyper-V guest notifies about crash event by writing
> the same HV_X64_MSR_CRASH_CTL_NOTIFY value into crash ctl msr.
> So both user space and guest writes inside ctl msr the same value
> and this patch distingiush the moment of actual guest crash
> by checking host initiated value from msr info. Also patch
> prevents modification of crash ctl msr by guest.
>
> Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
> Signed-off-by: Denis V. Lunev <den@openvz.org>
> CC: Paolo Bonzini <pbonzini@redhat.com>
> CC: Gleb Natapov <gleb@kernel.org>
Reviewed-by: Peter Hornyack <peterhornyack@google.com>
> ---
> arch/x86/kvm/hyperv.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++---
> arch/x86/kvm/hyperv.h | 2 +-
> arch/x86/kvm/x86.c | 7 ++++-
> 3 files changed, 78 insertions(+), 5 deletions(-)
>
> diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
> index af83c96..a860165 100644
> --- a/arch/x86/kvm/hyperv.c
> +++ b/arch/x86/kvm/hyperv.c
> @@ -48,7 +48,63 @@ static bool kvm_hv_msr_partition_wide(u32 msr)
> return r;
> }
>
> -static int kvm_hv_set_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data)
> +static int kvm_hv_msr_get_crash_data(struct kvm_vcpu *vcpu,
> + u32 index, u64 *pdata)
> +{
> + struct kvm_hv *hv = &vcpu->kvm->arch.hyperv;
> +
> + if (WARN_ON_ONCE(index >= ARRAY_SIZE(hv->hv_crash_param)))
> + return -EINVAL;
> +
> + *pdata = hv->hv_crash_param[index];
> + return 0;
> +}
> +
> +static int kvm_hv_msr_get_crash_ctl(struct kvm_vcpu *vcpu, u64 *pdata)
> +{
> + struct kvm_hv *hv = &vcpu->kvm->arch.hyperv;
> +
> + *pdata = hv->hv_crash_ctl;
> + return 0;
> +}
> +
> +static int kvm_hv_msr_set_crash_ctl(struct kvm_vcpu *vcpu, u64 data, bool host)
> +{
> + struct kvm_hv *hv = &vcpu->kvm->arch.hyperv;
> +
> + if (host)
> + hv->hv_crash_ctl = data;
> +
> + if ((data & HV_X64_MSR_CRASH_CTL_NOTIFY) && !host) {
> +
> + vcpu_debug(vcpu, "hv crash (0x%llx 0x%llx 0x%llx 0x%llx 0x%llx)\n",
> + hv->hv_crash_param[0],
> + hv->hv_crash_param[1],
> + hv->hv_crash_param[2],
> + hv->hv_crash_param[3],
> + hv->hv_crash_param[4]);
> +
> + /* Send notification about crash to user space */
> + kvm_make_request(KVM_REQ_HV_CRASH, vcpu);
> + }
> +
> + return 0;
> +}
> +
> +static int kvm_hv_msr_set_crash_data(struct kvm_vcpu *vcpu,
> + u32 index, u64 data)
> +{
> + struct kvm_hv *hv = &vcpu->kvm->arch.hyperv;
> +
> + if (WARN_ON_ONCE(index >= ARRAY_SIZE(hv->hv_crash_param)))
> + return -EINVAL;
> +
> + hv->hv_crash_param[index] = data;
> + return 0;
> +}
> +
> +static int kvm_hv_set_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data,
> + bool host)
> {
> struct kvm *kvm = vcpu->kvm;
> struct kvm_hv *hv = &kvm->arch.hyperv;
> @@ -101,6 +157,12 @@ static int kvm_hv_set_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data)
> mark_page_dirty(kvm, gfn);
> break;
> }
> + case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4:
> + return kvm_hv_msr_set_crash_data(vcpu,
> + msr - HV_X64_MSR_CRASH_P0,
> + data);
> + case HV_X64_MSR_CRASH_CTL:
> + return kvm_hv_msr_set_crash_ctl(vcpu, data, host);
> default:
> vcpu_unimpl(vcpu, "Hyper-V uhandled wrmsr: 0x%x data 0x%llx\n",
> msr, data);
> @@ -173,6 +235,12 @@ static int kvm_hv_get_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
> case HV_X64_MSR_REFERENCE_TSC:
> data = hv->hv_tsc_page;
> break;
> + case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4:
> + return kvm_hv_msr_get_crash_data(vcpu,
> + msr - HV_X64_MSR_CRASH_P0,
> + pdata);
> + case HV_X64_MSR_CRASH_CTL:
> + return kvm_hv_msr_get_crash_ctl(vcpu, pdata);
> default:
> vcpu_unimpl(vcpu, "Hyper-V unhandled rdmsr: 0x%x\n", msr);
> return 1;
> @@ -217,13 +285,13 @@ static int kvm_hv_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
> return 0;
> }
>
> -int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
> +int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host)
> {
> if (kvm_hv_msr_partition_wide(msr)) {
> int r;
>
> mutex_lock(&vcpu->kvm->lock);
> - r = kvm_hv_set_msr_pw(vcpu, msr, data);
> + r = kvm_hv_set_msr_pw(vcpu, msr, data, host);
> mutex_unlock(&vcpu->kvm->lock);
> return r;
> } else
> diff --git a/arch/x86/kvm/hyperv.h b/arch/x86/kvm/hyperv.h
> index 115c738..c7bce55 100644
> --- a/arch/x86/kvm/hyperv.h
> +++ b/arch/x86/kvm/hyperv.h
> @@ -24,7 +24,7 @@
> #ifndef __ARCH_X86_KVM_HYPERV_H__
> #define __ARCH_X86_KVM_HYPERV_H__
>
> -int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data);
> +int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host);
> int kvm_hv_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata);
> bool kvm_hv_hypercall_enabled(struct kvm *kvm);
> int kvm_hv_hypercall(struct kvm_vcpu *vcpu);
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 301ee01..47b7507 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -2103,7 +2103,10 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
> */
> break;
> case HV_X64_MSR_GUEST_OS_ID ... HV_X64_MSR_SINT15:
> - return kvm_hv_set_msr_common(vcpu, msr, data);
> + case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4:
> + case HV_X64_MSR_CRASH_CTL:
> + return kvm_hv_set_msr_common(vcpu, msr, data,
> + msr_info->host_initiated);
> case MSR_IA32_BBL_CR_CTL3:
> /* Drop writes to this legacy MSR -- see rdmsr
> * counterpart for further detail.
> @@ -2304,6 +2307,8 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
> msr_info->data = 0x20000000;
> break;
> case HV_X64_MSR_GUEST_OS_ID ... HV_X64_MSR_SINT15:
> + case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4:
> + case HV_X64_MSR_CRASH_CTL:
> return kvm_hv_get_msr_common(vcpu,
> msr_info->index, &msr_info->data);
> break;
> --
> 2.1.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] [PATCH 8/9] kvm/x86: add sending hyper-v crash notification to user space
2015-06-30 11:33 ` [Qemu-devel] [PATCH 8/9] kvm/x86: add sending hyper-v crash notification to user space Denis V. Lunev
@ 2015-07-01 0:16 ` Peter Hornyack
2015-07-01 15:12 ` Paolo Bonzini
1 sibling, 0 replies; 31+ messages in thread
From: Peter Hornyack @ 2015-07-01 0:16 UTC (permalink / raw)
To: Denis V. Lunev
Cc: Andrey Smetanin, Paolo Bonzini, Gleb Natapov, qemu-devel, kvm
On Tue, Jun 30, 2015 at 4:33 AM, Denis V. Lunev <den@openvz.org> wrote:
> From: Andrey Smetanin <asmetanin@virtuozzo.com>
>
> Sending of notification is done by exiting vcpu to user space
> if KVM_REQ_HV_CRASH is enabled for vcpu. kvm_run structure
> will contains system_event with type KVM_SYSTEM_EVENT_CRASH
> and flag KVM_SYSTEM_EVENT_FL_HV_CRASH to clarify that
> crash occures inside Hyper-V based guest.
>
> Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
> Signed-off-by: Denis V. Lunev <den@openvz.org>
> CC: Paolo Bonzini <pbonzini@redhat.com>
> CC: Gleb Natapov <gleb@kernel.org>
Reviewed-by: Peter Hornyack <peterhornyack@google.com>
> ---
> arch/x86/kvm/x86.c | 8 ++++++++
> include/uapi/linux/kvm.h | 2 ++
> 2 files changed, 10 insertions(+)
>
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 47b7507..55a4b92 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -6264,6 +6264,14 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
> vcpu_scan_ioapic(vcpu);
> if (kvm_check_request(KVM_REQ_APIC_PAGE_RELOAD, vcpu))
> kvm_vcpu_reload_apic_access_page(vcpu);
> + if (kvm_check_request(KVM_REQ_HV_CRASH, vcpu)) {
> + vcpu->run->exit_reason = KVM_EXIT_SYSTEM_EVENT;
> + vcpu->run->system_event.type = KVM_SYSTEM_EVENT_CRASH;
> + vcpu->run->system_event.flags =
> + KVM_SYSTEM_EVENT_FL_HV_CRASH;
> + r = 0;
> + goto out;
> + }
> }
>
> if (kvm_check_request(KVM_REQ_EVENT, vcpu) || req_int_win) {
> diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
> index 716ad4a..eefb8b9 100644
> --- a/include/uapi/linux/kvm.h
> +++ b/include/uapi/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 << 0)
> __u32 type;
> __u64 flags;
> } system_event;
> --
> 2.1.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] [PATCH v3 0/9] HyperV equivalent of pvpanic driver
2015-06-30 11:33 [Qemu-devel] [PATCH v3 0/9] HyperV equivalent of pvpanic driver Denis V. Lunev
` (9 preceding siblings ...)
2015-06-30 12:26 ` [Qemu-devel] [PATCH v3 0/9] HyperV equivalent of pvpanic driver Daniel P. Berrange
@ 2015-07-01 14:09 ` Paolo Bonzini
2015-07-01 15:55 ` Denis V. Lunev
10 siblings, 1 reply; 31+ messages in thread
From: Paolo Bonzini @ 2015-07-01 14:09 UTC (permalink / raw)
To: Denis V. Lunev; +Cc: Andrey Smetanin, Gleb Natapov, qemu-devel, kvm
On 30/06/2015 13:33, Denis V. Lunev wrote:
> Windows 2012 guests can notify hypervisor about occurred guest crash
> (Windows bugcheck(BSOD)) by writing specific Hyper-V msrs. This patch does
> handling of this MSR's by KVM and sending notification to user space that
> allows to gather Windows guest crash dump by QEMU/LIBVIRT.
>
> 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.
>
> Changes from v2:
> * forbid modification crash ctl msr by guest
> * qemu_system_guest_panicked usage in pvpanic and s390x
> * hyper-v crash handler move from generic kvm to i386
> * hyper-v crash handler: skip fetching crash msrs just mark crash occured
> * sync with linux-next 20150629
> * patch 11 squashed to patch 10
> * patch 9 squashed to patch 7
>
> Changes from v1:
> * hyperv code move to hyperv.c
> * added read handlers of crash data msrs
> * added per vm and per cpu hyperv context structures
> * added saving crash msrs inside qemu cpu state
> * added qemu fetch and update of crash msrs
> * added qemu crash msrs store in cpu state and it's migration
>
> Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
> Signed-off-by: Denis V. Lunev <den@openvz.org>
> CC: Gleb Natapov <gleb@kernel.org>
> CC: Paolo Bonzini <pbonzini@redhat.com>
The patches look good, thanks. I'll queue them as soon as I start
merging 4.3 features.
Paolo
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] [PATCH 3/9] kvm: add hyper-v crash msrs values
2015-06-30 11:33 ` [Qemu-devel] [PATCH 3/9] kvm: add hyper-v crash msrs values Denis V. Lunev
2015-07-01 0:14 ` Peter Hornyack
@ 2015-07-01 15:00 ` Paolo Bonzini
2015-07-01 15:53 ` Denis V. Lunev
1 sibling, 1 reply; 31+ messages in thread
From: Paolo Bonzini @ 2015-07-01 15:00 UTC (permalink / raw)
To: Denis V. Lunev; +Cc: Andrey Smetanin, Gleb Natapov, qemu-devel, kvm
On 30/06/2015 13:33, Denis V. Lunev wrote:
> +#define HV_X64_MSR_CRASH_CTL_NOTIFY (1ULL << 63)
> +#define HV_X64_MSR_CRASH_CTL_CONTENTS \
> + (HV_X64_MSR_CRASH_CTL_NOTIFY)
Why is HV_X64_MSR_CRASH_CTL_CONTENTS needed? Can I just remove it?
Paolo
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] [PATCH 9/9] qemu/kvm: kvm hyper-v based guest crash event handling
2015-06-30 11:33 ` [Qemu-devel] [PATCH 9/9] qemu/kvm: kvm hyper-v based guest crash event handling Denis V. Lunev
@ 2015-07-01 15:07 ` Paolo Bonzini
2015-07-02 13:19 ` Andrey Smetanin
0 siblings, 1 reply; 31+ messages in thread
From: Paolo Bonzini @ 2015-07-01 15:07 UTC (permalink / raw)
To: Denis V. Lunev; +Cc: Andrey Smetanin, qemu-devel, kvm, Andreas Färber
On 30/06/2015 13:33, Denis V. Lunev wrote:
>
> +static int kvm_arch_handle_hv_crash(CPUState *cs)
> +{
> + X86CPU *cpu = X86_CPU(cs);
> + CPUX86State *env = &cpu->env;
> +
> + /* Mark that Hyper-v guest crash occurred */
> + env->hv_crash_occurred = 1;
This need not be a hv crash. You can add crash_occurred to CPUState
directly, and set it in qemu_system_guest_panicked:
if (current_cpu) {
current_cpu->crash_occurred = true;
}
Then you would add two subsections: one for crash_occurred in exec.c
(attached to vmstate_cpu_common), one for hyperv crash params in
target-i386/machine.c.
This also gives an idea about splitting the patch: first the
introduction of qemu_system_guest_panicked and crash_occurred, second
the Hyper-V specific bits.
> + if (cpu->hyperv_crash) {
> + c->edx |= HV_X64_GUEST_CRASH_MSR_AVAILABLE;
> + has_msr_hv_crash = true;
You can only set this to true if the kernel also supports the MSRs.
> + }
> +
> c = &cpuid_data.entries[cpuid_i++];
> c->function = HYPERV_CPUID_ENLIGHTMENT_INFO;
> if (cpu->hyperv_relaxed_timing) {
> @@ -761,6 +767,10 @@ void kvm_arch_reset_vcpu(X86CPU *cpu)
> } else {
> env->mp_state = KVM_MP_STATE_RUNNABLE;
> }
> + if (has_msr_hv_crash) {
> + env->msr_hv_crash_ctl = HV_X64_MSR_CRASH_CTL_NOTIFY;
The value is always host-defined, so I think it doesn't need a field in
CPUX86State. On the other hand, this:
+static bool hyperv_crash_enable_needed(void *opaque)
+{
+ X86CPU *cpu = opaque;
+ CPUX86State *env = &cpu->env;
+
+ return (env->msr_hv_crash_ctl & HV_X64_MSR_CRASH_CTL_CONTENTS) ?
+ true : false;
+}
+
can just check if any of the params fields is nonzero.
Thanks,
Paolo
> + env->hv_crash_occurred = 0;
> + }
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] [PATCH 8/9] kvm/x86: add sending hyper-v crash notification to user space
2015-06-30 11:33 ` [Qemu-devel] [PATCH 8/9] kvm/x86: add sending hyper-v crash notification to user space Denis V. Lunev
2015-07-01 0:16 ` Peter Hornyack
@ 2015-07-01 15:12 ` Paolo Bonzini
1 sibling, 0 replies; 31+ messages in thread
From: Paolo Bonzini @ 2015-07-01 15:12 UTC (permalink / raw)
To: Denis V. Lunev; +Cc: Andrey Smetanin, Gleb Natapov, qemu-devel, kvm
On 30/06/2015 13:33, Denis V. Lunev wrote:
> From: Andrey Smetanin <asmetanin@virtuozzo.com>
>
> Sending of notification is done by exiting vcpu to user space
> if KVM_REQ_HV_CRASH is enabled for vcpu. kvm_run structure
> will contains system_event with type KVM_SYSTEM_EVENT_CRASH
> and flag KVM_SYSTEM_EVENT_FL_HV_CRASH to clarify that
> crash occures inside Hyper-V based guest.
This needs to be documented in Documentation/virtual/kvm/api.txt. Also,
please rename KVM_SYSTEM_EVENT_FL_HV_CRASH to
KVM_SYSTEM_EVENT_FLAG_HV_CRASH and move it to
arch/x86/include/uapi/asm/kvm.h.
You do not need to send the whole series again; just resend this one patch.
Paolo
> Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
> Signed-off-by: Denis V. Lunev <den@openvz.org>
> CC: Paolo Bonzini <pbonzini@redhat.com>
> CC: Gleb Natapov <gleb@kernel.org>
> ---
> arch/x86/kvm/x86.c | 8 ++++++++
> include/uapi/linux/kvm.h | 2 ++
> 2 files changed, 10 insertions(+)
>
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 47b7507..55a4b92 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -6264,6 +6264,14 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
> vcpu_scan_ioapic(vcpu);
> if (kvm_check_request(KVM_REQ_APIC_PAGE_RELOAD, vcpu))
> kvm_vcpu_reload_apic_access_page(vcpu);
> + if (kvm_check_request(KVM_REQ_HV_CRASH, vcpu)) {
> + vcpu->run->exit_reason = KVM_EXIT_SYSTEM_EVENT;
> + vcpu->run->system_event.type = KVM_SYSTEM_EVENT_CRASH;
> + vcpu->run->system_event.flags =
> + KVM_SYSTEM_EVENT_FL_HV_CRASH;
> + r = 0;
> + goto out;
> + }
> }
>
> if (kvm_check_request(KVM_REQ_EVENT, vcpu) || req_int_win) {
> diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
> index 716ad4a..eefb8b9 100644
> --- a/include/uapi/linux/kvm.h
> +++ b/include/uapi/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 << 0)
> __u32 type;
> __u64 flags;
> } system_event;
>
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] [PATCH 3/9] kvm: add hyper-v crash msrs values
2015-07-01 15:00 ` Paolo Bonzini
@ 2015-07-01 15:53 ` Denis V. Lunev
2015-07-01 16:06 ` Peter Hornyack
0 siblings, 1 reply; 31+ messages in thread
From: Denis V. Lunev @ 2015-07-01 15:53 UTC (permalink / raw)
To: Paolo Bonzini
Cc: Andrey Smetanin, Gleb Natapov, qemu-devel, kvm, Peter Hornyack
On 01/07/15 18:00, Paolo Bonzini wrote:
>
> On 30/06/2015 13:33, Denis V. Lunev wrote:
>> +#define HV_X64_MSR_CRASH_CTL_NOTIFY (1ULL << 63)
>> +#define HV_X64_MSR_CRASH_CTL_CONTENTS \
>> + (HV_X64_MSR_CRASH_CTL_NOTIFY)
> Why is HV_X64_MSR_CRASH_CTL_CONTENTS needed? Can I just remove it?
>
> Paolo
this was a direct request from Peter Hornyack <peterhornyack@google.com>
"I suggest here:
#define HV_X64_MSR_CRASH_CTL_CONTENTS \
(HV_CRASH_CTL_CRASH_NOTIFY)
To allow for more crash actions to be added in the future."
Den
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] [PATCH v3 0/9] HyperV equivalent of pvpanic driver
2015-07-01 14:09 ` Paolo Bonzini
@ 2015-07-01 15:55 ` Denis V. Lunev
0 siblings, 0 replies; 31+ messages in thread
From: Denis V. Lunev @ 2015-07-01 15:55 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: Andrey Smetanin, Gleb Natapov, qemu-devel, kvm
On 01/07/15 17:09, Paolo Bonzini wrote:
>
> On 30/06/2015 13:33, Denis V. Lunev wrote:
>> Windows 2012 guests can notify hypervisor about occurred guest crash
>> (Windows bugcheck(BSOD)) by writing specific Hyper-V msrs. This patch does
>> handling of this MSR's by KVM and sending notification to user space that
>> allows to gather Windows guest crash dump by QEMU/LIBVIRT.
>>
>> 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.
>>
>> Changes from v2:
>> * forbid modification crash ctl msr by guest
>> * qemu_system_guest_panicked usage in pvpanic and s390x
>> * hyper-v crash handler move from generic kvm to i386
>> * hyper-v crash handler: skip fetching crash msrs just mark crash occured
>> * sync with linux-next 20150629
>> * patch 11 squashed to patch 10
>> * patch 9 squashed to patch 7
>>
>> Changes from v1:
>> * hyperv code move to hyperv.c
>> * added read handlers of crash data msrs
>> * added per vm and per cpu hyperv context structures
>> * added saving crash msrs inside qemu cpu state
>> * added qemu fetch and update of crash msrs
>> * added qemu crash msrs store in cpu state and it's migration
>>
>> Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
>> Signed-off-by: Denis V. Lunev <den@openvz.org>
>> CC: Gleb Natapov <gleb@kernel.org>
>> CC: Paolo Bonzini <pbonzini@redhat.com>
> The patches look good, thanks. I'll queue them as soon as I start
> merging 4.3 features.
>
> Paolo
that sounds good to me. We'll re-send patch 8 and fork
second thread for QEMU part then.
Den
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] [PATCH 3/9] kvm: add hyper-v crash msrs values
2015-07-01 15:53 ` Denis V. Lunev
@ 2015-07-01 16:06 ` Peter Hornyack
2015-07-01 16:48 ` Paolo Bonzini
0 siblings, 1 reply; 31+ messages in thread
From: Peter Hornyack @ 2015-07-01 16:06 UTC (permalink / raw)
To: Denis V. Lunev
Cc: Andrey Smetanin, Paolo Bonzini, Gleb Natapov, qemu-devel, kvm
If userspace is controlling the crash capabilities then
HV_X64_MSR_CRASH_CTL_CONTENTS is not needed.
On Wed, Jul 1, 2015 at 8:53 AM, Denis V. Lunev <den@openvz.org> wrote:
> On 01/07/15 18:00, Paolo Bonzini wrote:
>>
>>
>> On 30/06/2015 13:33, Denis V. Lunev wrote:
>>>
>>> +#define HV_X64_MSR_CRASH_CTL_NOTIFY (1ULL << 63)
>>> +#define HV_X64_MSR_CRASH_CTL_CONTENTS \
>>> + (HV_X64_MSR_CRASH_CTL_NOTIFY)
>>
>> Why is HV_X64_MSR_CRASH_CTL_CONTENTS needed? Can I just remove it?
>>
>> Paolo
>
> this was a direct request from Peter Hornyack <peterhornyack@google.com>
>
> "I suggest here:
>
> #define HV_X64_MSR_CRASH_CTL_CONTENTS \
> (HV_CRASH_CTL_CRASH_NOTIFY)
>
> To allow for more crash actions to be added in the future."
>
> Den
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] [PATCH 7/9] kvm/x86: added hyper-v crash data and ctl msr's get/set'ers
2015-06-30 11:33 ` [Qemu-devel] [PATCH 7/9] kvm/x86: added hyper-v crash data and ctl msr's get/set'ers Denis V. Lunev
2015-07-01 0:15 ` Peter Hornyack
@ 2015-07-01 16:47 ` Paolo Bonzini
1 sibling, 0 replies; 31+ messages in thread
From: Paolo Bonzini @ 2015-07-01 16:47 UTC (permalink / raw)
To: Denis V. Lunev; +Cc: Andrey Smetanin, Gleb Natapov, qemu-devel, kvm
On 30/06/2015 13:33, Denis V. Lunev wrote:
> +static int kvm_hv_msr_set_crash_ctl(struct kvm_vcpu *vcpu, u64 data, bool host)
> +{
> + struct kvm_hv *hv = &vcpu->kvm->arch.hyperv;
> +
> + if (host)
> + hv->hv_crash_ctl = data;
> +
You need to check against HV_X64_MSR_CRASH_CTL_CONTENTS here (or
HV_X64_MSR_CRASH_CTL_NOTIFY) here.
Paolo
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] [PATCH 3/9] kvm: add hyper-v crash msrs values
2015-07-01 16:06 ` Peter Hornyack
@ 2015-07-01 16:48 ` Paolo Bonzini
0 siblings, 0 replies; 31+ messages in thread
From: Paolo Bonzini @ 2015-07-01 16:48 UTC (permalink / raw)
To: Peter Hornyack, Denis V. Lunev
Cc: Andrey Smetanin, Gleb Natapov, qemu-devel, kvm
On 01/07/2015 18:06, Peter Hornyack wrote:
> If userspace is controlling the crash capabilities then
> HV_X64_MSR_CRASH_CTL_CONTENTS is not needed.
Actually you still need to: userspace cannot write anything but 0 or
(1ULL << 63). However, the name makes less sense, so I'm in favor of
removing the value.
Paolo
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] [PATCH 9/9] qemu/kvm: kvm hyper-v based guest crash event handling
2015-07-01 15:07 ` Paolo Bonzini
@ 2015-07-02 13:19 ` Andrey Smetanin
2015-07-02 13:30 ` Paolo Bonzini
0 siblings, 1 reply; 31+ messages in thread
From: Andrey Smetanin @ 2015-07-02 13:19 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: Denis V. Lunev, qemu-devel, kvm, Andreas Färber
On Wed, 2015-07-01 at 17:07 +0200, Paolo Bonzini wrote:
>
> On 30/06/2015 13:33, Denis V. Lunev wrote:
> >
> > +static int kvm_arch_handle_hv_crash(CPUState *cs)
> > +{
> > + X86CPU *cpu = X86_CPU(cs);
> > + CPUX86State *env = &cpu->env;
> > +
> > + /* Mark that Hyper-v guest crash occurred */
> > + env->hv_crash_occurred = 1;
>
> This need not be a hv crash. You can add crash_occurred to CPUState
> directly, and set it in qemu_system_guest_panicked:
>
> if (current_cpu) {
> current_cpu->crash_occurred = true;
> }
>
> Then you would add two subsections: one for crash_occurred in exec.c
> (attached to vmstate_cpu_common), one for hyperv crash params in
> target-i386/machine.c.
>
> This also gives an idea about splitting the patch: first the
> introduction of qemu_system_guest_panicked and crash_occurred, second
> the Hyper-V specific bits.
>
> > + if (cpu->hyperv_crash) {
> > + c->edx |= HV_X64_GUEST_CRASH_MSR_AVAILABLE;
> > + has_msr_hv_crash = true;
>
> You can only set this to true if the kernel also supports the MSRs.
>
> > + }
> > +
> > c = &cpuid_data.entries[cpuid_i++];
> > c->function = HYPERV_CPUID_ENLIGHTMENT_INFO;
> > if (cpu->hyperv_relaxed_timing) {
> > @@ -761,6 +767,10 @@ void kvm_arch_reset_vcpu(X86CPU *cpu)
> > } else {
> > env->mp_state = KVM_MP_STATE_RUNNABLE;
> > }
> > + if (has_msr_hv_crash) {
> > + env->msr_hv_crash_ctl = HV_X64_MSR_CRASH_CTL_NOTIFY;
>
> The value is always host-defined, so I think it doesn't need a field in
> CPUX86State. On the other hand, this:
Kernel just works with that value, kernel doesn't setup it.
The user space is allowed to setup this msr if qemu option "hv-crash" is
on. So the code "env->msr_hv_crash_ctl = HV_X64_MSR_CRASH_CTL_NOTIFY;"
setups msr in user space at cpu reset. When cpu setup it's registers
these msr's values are uploaded into kernel.
Anyway we need a code that initially set up crash ctl msr with value
HV_X64_MSR_CRASH_CTL_NOTIFY. And I think that code should be user space.
Any objections ?
>
>
> +static bool hyperv_crash_enable_needed(void *opaque)
> +{
> + X86CPU *cpu = opaque;
> + CPUX86State *env = &cpu->env;
> +
> + return (env->msr_hv_crash_ctl & HV_X64_MSR_CRASH_CTL_CONTENTS) ?
> + true : false;
> +}
> +
>
> can just check if any of the params fields is nonzero.
>
If we setup crash ctl msr by user space, we need it to migrate.
> Thanks,
>
> Paolo
>
> > + env->hv_crash_occurred = 0;
> > + }
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [Qemu-devel] [PATCH 9/9] qemu/kvm: kvm hyper-v based guest crash event handling
2015-07-02 13:19 ` Andrey Smetanin
@ 2015-07-02 13:30 ` Paolo Bonzini
0 siblings, 0 replies; 31+ messages in thread
From: Paolo Bonzini @ 2015-07-02 13:30 UTC (permalink / raw)
To: asmetanin; +Cc: Denis V. Lunev, qemu-devel, kvm, Andreas Färber
On 02/07/2015 15:19, Andrey Smetanin wrote:
>>> > > + if (has_msr_hv_crash) {
>>> > > + env->msr_hv_crash_ctl = HV_X64_MSR_CRASH_CTL_NOTIFY;
>> >
>> > The value is always host-defined, so I think it doesn't need a field in
>> > CPUX86State. On the other hand, this:
> Kernel just works with that value, kernel doesn't setup it.
> The user space is allowed to setup this msr if qemu option "hv-crash" is
> on. So the code "env->msr_hv_crash_ctl = HV_X64_MSR_CRASH_CTL_NOTIFY;"
> setups msr in user space at cpu reset. When cpu setup it's registers
> these msr's values are uploaded into kernel.
>
> Anyway we need a code that initially set up crash ctl msr with value
> HV_X64_MSR_CRASH_CTL_NOTIFY. And I think that code should be user space.
> Any objections ?
Yes, that's correct.
What I'm saying, is that the value can be hard-coded and doesn't need a
field in CPUX86State. If you want to leave the field that's also okay,
but even then it should not be part of the migration state.
Paolo
^ permalink raw reply [flat|nested] 31+ messages in thread
end of thread, other threads:[~2015-07-02 13:30 UTC | newest]
Thread overview: 31+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-06-30 11:33 [Qemu-devel] [PATCH v3 0/9] HyperV equivalent of pvpanic driver Denis V. Lunev
2015-06-30 11:33 ` [Qemu-devel] [PATCH 1/9] kvm/x86: move Hyper-V MSR's/hypercall code into hyperv.c file Denis V. Lunev
2015-07-01 0:11 ` Peter Hornyack
2015-06-30 11:33 ` [Qemu-devel] [PATCH 2/9] kvm: introduce vcpu_debug = kvm_debug + vcpu context Denis V. Lunev
2015-07-01 0:12 ` Peter Hornyack
2015-06-30 11:33 ` [Qemu-devel] [PATCH 3/9] kvm: add hyper-v crash msrs values Denis V. Lunev
2015-07-01 0:14 ` Peter Hornyack
2015-07-01 15:00 ` Paolo Bonzini
2015-07-01 15:53 ` Denis V. Lunev
2015-07-01 16:06 ` Peter Hornyack
2015-07-01 16:48 ` Paolo Bonzini
2015-06-30 11:33 ` [Qemu-devel] [PATCH 4/9] kvm/x86: added hyper-v crash msrs into kvm hyperv context Denis V. Lunev
2015-07-01 0:14 ` Peter Hornyack
2015-06-30 11:33 ` [Qemu-devel] [PATCH 5/9] kvm: added KVM_REQ_HV_CRASH value to notify qemu about hyper-v crash Denis V. Lunev
2015-07-01 0:14 ` Peter Hornyack
2015-06-30 11:33 ` [Qemu-devel] [PATCH 6/9] kvm/x86: mark hyper-v crash msrs as partition wide Denis V. Lunev
2015-07-01 0:15 ` Peter Hornyack
2015-06-30 11:33 ` [Qemu-devel] [PATCH 7/9] kvm/x86: added hyper-v crash data and ctl msr's get/set'ers Denis V. Lunev
2015-07-01 0:15 ` Peter Hornyack
2015-07-01 16:47 ` Paolo Bonzini
2015-06-30 11:33 ` [Qemu-devel] [PATCH 8/9] kvm/x86: add sending hyper-v crash notification to user space Denis V. Lunev
2015-07-01 0:16 ` Peter Hornyack
2015-07-01 15:12 ` Paolo Bonzini
2015-06-30 11:33 ` [Qemu-devel] [PATCH 9/9] qemu/kvm: kvm hyper-v based guest crash event handling Denis V. Lunev
2015-07-01 15:07 ` Paolo Bonzini
2015-07-02 13:19 ` Andrey Smetanin
2015-07-02 13:30 ` Paolo Bonzini
2015-06-30 12:26 ` [Qemu-devel] [PATCH v3 0/9] HyperV equivalent of pvpanic driver Daniel P. Berrange
2015-06-30 12:38 ` Denis V. Lunev
2015-07-01 14:09 ` Paolo Bonzini
2015-07-01 15:55 ` Denis V. Lunev
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).