diff options
author | Andrey Smetanin <asmetanin@virtuozzo.com> | 2015-07-03 08:01:37 -0400 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2015-07-23 02:27:06 -0400 |
commit | e7d9513b60e87f62e41090fa3a26eca796924346 (patch) | |
tree | 64dd372b95d05dc3107823c4b3b0607e66a2f7c5 | |
parent | ee86dbc6e327062396748162b95309388c19faab (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.h | 4 | ||||
-rw-r--r-- | arch/x86/kvm/hyperv.c | 76 | ||||
-rw-r--r-- | arch/x86/kvm/hyperv.h | 2 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 9 |
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 | ||
600 | struct kvm_arch { | 604 | struct 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 | ||
49 | static int kvm_hv_set_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data) | 51 | static 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 | |||
63 | static 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 | |||
71 | static 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 | |||
94 | static 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 | |||
106 | static 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 | ||
218 | int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) | 288 | int 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 | ||
27 | int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data); | 27 | int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host); |
28 | int kvm_hv_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata); | 28 | int kvm_hv_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata); |
29 | bool kvm_hv_hypercall_enabled(struct kvm *kvm); | 29 | bool kvm_hv_hypercall_enabled(struct kvm *kvm); |
30 | int kvm_hv_hypercall(struct kvm_vcpu *vcpu); | 30 | int 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; |