aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrey Smetanin <asmetanin@virtuozzo.com>2015-07-03 08:01:37 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2015-07-23 02:27:06 -0400
commite7d9513b60e87f62e41090fa3a26eca796924346 (patch)
tree64dd372b95d05dc3107823c4b3b0607e66a2f7c5
parentee86dbc6e327062396748162b95309388c19faab (diff)
kvm/x86: added hyper-v crash msrs into kvm hyperv context
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> Reviewed-by: Peter Hornyack <peterhornyack@google.com> CC: Paolo Bonzini <pbonzini@redhat.com> CC: Gleb Natapov <gleb@kernel.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--arch/x86/include/asm/kvm_host.h4
-rw-r--r--arch/x86/kvm/hyperv.c76
-rw-r--r--arch/x86/kvm/hyperv.h2
-rw-r--r--arch/x86/kvm/x86.c9
4 files changed, 86 insertions, 5 deletions
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 24168822212b..fa32b5314dcd 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -595,6 +595,10 @@ struct kvm_hv {
595 u64 hv_guest_os_id; 595 u64 hv_guest_os_id;
596 u64 hv_hypercall; 596 u64 hv_hypercall;
597 u64 hv_tsc_page; 597 u64 hv_tsc_page;
598
599 /* Hyper-v based guest crash (NT kernel bugcheck) parameters */
600 u64 hv_crash_param[HV_X64_MSR_CRASH_PARAMS];
601 u64 hv_crash_ctl;
598}; 602};
599 603
600struct kvm_arch { 604struct kvm_arch {
diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 2b49f100a698..a8160d2ae362 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)
39 case HV_X64_MSR_HYPERCALL: 39 case HV_X64_MSR_HYPERCALL:
40 case HV_X64_MSR_REFERENCE_TSC: 40 case HV_X64_MSR_REFERENCE_TSC:
41 case HV_X64_MSR_TIME_REF_COUNT: 41 case HV_X64_MSR_TIME_REF_COUNT:
42 case HV_X64_MSR_CRASH_CTL:
43 case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4:
42 r = true; 44 r = true;
43 break; 45 break;
44 } 46 }
@@ -46,7 +48,63 @@ static bool kvm_hv_msr_partition_wide(u32 msr)
46 return r; 48 return r;
47} 49}
48 50
49static int kvm_hv_set_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data) 51static int kvm_hv_msr_get_crash_data(struct kvm_vcpu *vcpu,
52 u32 index, u64 *pdata)
53{
54 struct kvm_hv *hv = &vcpu->kvm->arch.hyperv;
55
56 if (WARN_ON_ONCE(index >= ARRAY_SIZE(hv->hv_crash_param)))
57 return -EINVAL;
58
59 *pdata = hv->hv_crash_param[index];
60 return 0;
61}
62
63static int kvm_hv_msr_get_crash_ctl(struct kvm_vcpu *vcpu, u64 *pdata)
64{
65 struct kvm_hv *hv = &vcpu->kvm->arch.hyperv;
66
67 *pdata = hv->hv_crash_ctl;
68 return 0;
69}
70
71static int kvm_hv_msr_set_crash_ctl(struct kvm_vcpu *vcpu, u64 data, bool host)
72{
73 struct kvm_hv *hv = &vcpu->kvm->arch.hyperv;
74
75 if (host)
76 hv->hv_crash_ctl = data & HV_X64_MSR_CRASH_CTL_NOTIFY;
77
78 if (!host && (data & HV_X64_MSR_CRASH_CTL_NOTIFY)) {
79
80 vcpu_debug(vcpu, "hv crash (0x%llx 0x%llx 0x%llx 0x%llx 0x%llx)\n",
81 hv->hv_crash_param[0],
82 hv->hv_crash_param[1],
83 hv->hv_crash_param[2],
84 hv->hv_crash_param[3],
85 hv->hv_crash_param[4]);
86
87 /* Send notification about crash to user space */
88 kvm_make_request(KVM_REQ_HV_CRASH, vcpu);
89 }
90
91 return 0;
92}
93
94static int kvm_hv_msr_set_crash_data(struct kvm_vcpu *vcpu,
95 u32 index, u64 data)
96{
97 struct kvm_hv *hv = &vcpu->kvm->arch.hyperv;
98
99 if (WARN_ON_ONCE(index >= ARRAY_SIZE(hv->hv_crash_param)))
100 return -EINVAL;
101
102 hv->hv_crash_param[index] = data;
103 return 0;
104}
105
106static int kvm_hv_set_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data,
107 bool host)
50{ 108{
51 struct kvm *kvm = vcpu->kvm; 109 struct kvm *kvm = vcpu->kvm;
52 struct kvm_hv *hv = &kvm->arch.hyperv; 110 struct kvm_hv *hv = &kvm->arch.hyperv;
@@ -99,6 +157,12 @@ static int kvm_hv_set_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data)
99 mark_page_dirty(kvm, gfn); 157 mark_page_dirty(kvm, gfn);
100 break; 158 break;
101 } 159 }
160 case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4:
161 return kvm_hv_msr_set_crash_data(vcpu,
162 msr - HV_X64_MSR_CRASH_P0,
163 data);
164 case HV_X64_MSR_CRASH_CTL:
165 return kvm_hv_msr_set_crash_ctl(vcpu, data, host);
102 default: 166 default:
103 vcpu_unimpl(vcpu, "Hyper-V uhandled wrmsr: 0x%x data 0x%llx\n", 167 vcpu_unimpl(vcpu, "Hyper-V uhandled wrmsr: 0x%x data 0x%llx\n",
104 msr, data); 168 msr, data);
@@ -171,6 +235,12 @@ static int kvm_hv_get_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
171 case HV_X64_MSR_REFERENCE_TSC: 235 case HV_X64_MSR_REFERENCE_TSC:
172 data = hv->hv_tsc_page; 236 data = hv->hv_tsc_page;
173 break; 237 break;
238 case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4:
239 return kvm_hv_msr_get_crash_data(vcpu,
240 msr - HV_X64_MSR_CRASH_P0,
241 pdata);
242 case HV_X64_MSR_CRASH_CTL:
243 return kvm_hv_msr_get_crash_ctl(vcpu, pdata);
174 default: 244 default:
175 vcpu_unimpl(vcpu, "Hyper-V unhandled rdmsr: 0x%x\n", msr); 245 vcpu_unimpl(vcpu, "Hyper-V unhandled rdmsr: 0x%x\n", msr);
176 return 1; 246 return 1;
@@ -215,13 +285,13 @@ static int kvm_hv_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
215 return 0; 285 return 0;
216} 286}
217 287
218int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) 288int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host)
219{ 289{
220 if (kvm_hv_msr_partition_wide(msr)) { 290 if (kvm_hv_msr_partition_wide(msr)) {
221 int r; 291 int r;
222 292
223 mutex_lock(&vcpu->kvm->lock); 293 mutex_lock(&vcpu->kvm->lock);
224 r = kvm_hv_set_msr_pw(vcpu, msr, data); 294 r = kvm_hv_set_msr_pw(vcpu, msr, data, host);
225 mutex_unlock(&vcpu->kvm->lock); 295 mutex_unlock(&vcpu->kvm->lock);
226 return r; 296 return r;
227 } else 297 } else
diff --git a/arch/x86/kvm/hyperv.h b/arch/x86/kvm/hyperv.h
index 115c738ccbe3..c7bce559f67b 100644
--- a/arch/x86/kvm/hyperv.h
+++ b/arch/x86/kvm/hyperv.h
@@ -24,7 +24,7 @@
24#ifndef __ARCH_X86_KVM_HYPERV_H__ 24#ifndef __ARCH_X86_KVM_HYPERV_H__
25#define __ARCH_X86_KVM_HYPERV_H__ 25#define __ARCH_X86_KVM_HYPERV_H__
26 26
27int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data); 27int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host);
28int kvm_hv_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata); 28int kvm_hv_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata);
29bool kvm_hv_hypercall_enabled(struct kvm *kvm); 29bool kvm_hv_hypercall_enabled(struct kvm *kvm);
30int kvm_hv_hypercall(struct kvm_vcpu *vcpu); 30int kvm_hv_hypercall(struct kvm_vcpu *vcpu);
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index d53b10744fba..cfa3e5a7d6be 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -950,6 +950,8 @@ static u32 emulated_msrs[] = {
950 MSR_KVM_SYSTEM_TIME_NEW, MSR_KVM_WALL_CLOCK_NEW, 950 MSR_KVM_SYSTEM_TIME_NEW, MSR_KVM_WALL_CLOCK_NEW,
951 HV_X64_MSR_GUEST_OS_ID, HV_X64_MSR_HYPERCALL, 951 HV_X64_MSR_GUEST_OS_ID, HV_X64_MSR_HYPERCALL,
952 HV_X64_MSR_TIME_REF_COUNT, HV_X64_MSR_REFERENCE_TSC, 952 HV_X64_MSR_TIME_REF_COUNT, HV_X64_MSR_REFERENCE_TSC,
953 HV_X64_MSR_CRASH_P0, HV_X64_MSR_CRASH_P1, HV_X64_MSR_CRASH_P2,
954 HV_X64_MSR_CRASH_P3, HV_X64_MSR_CRASH_P4, HV_X64_MSR_CRASH_CTL,
953 HV_X64_MSR_APIC_ASSIST_PAGE, MSR_KVM_ASYNC_PF_EN, MSR_KVM_STEAL_TIME, 955 HV_X64_MSR_APIC_ASSIST_PAGE, MSR_KVM_ASYNC_PF_EN, MSR_KVM_STEAL_TIME,
954 MSR_KVM_PV_EOI_EN, 956 MSR_KVM_PV_EOI_EN,
955 957
@@ -2103,7 +2105,10 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
2103 */ 2105 */
2104 break; 2106 break;
2105 case HV_X64_MSR_GUEST_OS_ID ... HV_X64_MSR_SINT15: 2107 case HV_X64_MSR_GUEST_OS_ID ... HV_X64_MSR_SINT15:
2106 return kvm_hv_set_msr_common(vcpu, msr, data); 2108 case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4:
2109 case HV_X64_MSR_CRASH_CTL:
2110 return kvm_hv_set_msr_common(vcpu, msr, data,
2111 msr_info->host_initiated);
2107 case MSR_IA32_BBL_CR_CTL3: 2112 case MSR_IA32_BBL_CR_CTL3:
2108 /* Drop writes to this legacy MSR -- see rdmsr 2113 /* Drop writes to this legacy MSR -- see rdmsr
2109 * counterpart for further detail. 2114 * counterpart for further detail.
@@ -2302,6 +2307,8 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
2302 msr_info->data = 0x20000000; 2307 msr_info->data = 0x20000000;
2303 break; 2308 break;
2304 case HV_X64_MSR_GUEST_OS_ID ... HV_X64_MSR_SINT15: 2309 case HV_X64_MSR_GUEST_OS_ID ... HV_X64_MSR_SINT15:
2310 case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4:
2311 case HV_X64_MSR_CRASH_CTL:
2305 return kvm_hv_get_msr_common(vcpu, 2312 return kvm_hv_get_msr_common(vcpu,
2306 msr_info->index, &msr_info->data); 2313 msr_info->index, &msr_info->data);
2307 break; 2314 break;