To modify Ixia port numbers and IP in pod.yaml
[kvmfornfv.git] / kernel / arch / x86 / kvm / hyperv.c
1 /*
2  * KVM Microsoft Hyper-V emulation
3  *
4  * derived from arch/x86/kvm/x86.c
5  *
6  * Copyright (C) 2006 Qumranet, Inc.
7  * Copyright (C) 2008 Qumranet, Inc.
8  * Copyright IBM Corporation, 2008
9  * Copyright 2010 Red Hat, Inc. and/or its affiliates.
10  * Copyright (C) 2015 Andrey Smetanin <asmetanin@virtuozzo.com>
11  *
12  * Authors:
13  *   Avi Kivity   <avi@qumranet.com>
14  *   Yaniv Kamay  <yaniv@qumranet.com>
15  *   Amit Shah    <amit.shah@qumranet.com>
16  *   Ben-Ami Yassour <benami@il.ibm.com>
17  *   Andrey Smetanin <asmetanin@virtuozzo.com>
18  *
19  * This work is licensed under the terms of the GNU GPL, version 2.  See
20  * the COPYING file in the top-level directory.
21  *
22  */
23
24 #include "x86.h"
25 #include "lapic.h"
26 #include "hyperv.h"
27
28 #include <linux/kvm_host.h>
29 #include <trace/events/kvm.h>
30
31 #include "trace.h"
32
33 static bool kvm_hv_msr_partition_wide(u32 msr)
34 {
35         bool r = false;
36
37         switch (msr) {
38         case HV_X64_MSR_GUEST_OS_ID:
39         case HV_X64_MSR_HYPERCALL:
40         case HV_X64_MSR_REFERENCE_TSC:
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:
44         case HV_X64_MSR_RESET:
45                 r = true;
46                 break;
47         }
48
49         return r;
50 }
51
52 static int kvm_hv_msr_get_crash_data(struct kvm_vcpu *vcpu,
53                                      u32 index, u64 *pdata)
54 {
55         struct kvm_hv *hv = &vcpu->kvm->arch.hyperv;
56
57         if (WARN_ON_ONCE(index >= ARRAY_SIZE(hv->hv_crash_param)))
58                 return -EINVAL;
59
60         *pdata = hv->hv_crash_param[index];
61         return 0;
62 }
63
64 static int kvm_hv_msr_get_crash_ctl(struct kvm_vcpu *vcpu, u64 *pdata)
65 {
66         struct kvm_hv *hv = &vcpu->kvm->arch.hyperv;
67
68         *pdata = hv->hv_crash_ctl;
69         return 0;
70 }
71
72 static int kvm_hv_msr_set_crash_ctl(struct kvm_vcpu *vcpu, u64 data, bool host)
73 {
74         struct kvm_hv *hv = &vcpu->kvm->arch.hyperv;
75
76         if (host)
77                 hv->hv_crash_ctl = data & HV_X64_MSR_CRASH_CTL_NOTIFY;
78
79         if (!host && (data & HV_X64_MSR_CRASH_CTL_NOTIFY)) {
80
81                 vcpu_debug(vcpu, "hv crash (0x%llx 0x%llx 0x%llx 0x%llx 0x%llx)\n",
82                           hv->hv_crash_param[0],
83                           hv->hv_crash_param[1],
84                           hv->hv_crash_param[2],
85                           hv->hv_crash_param[3],
86                           hv->hv_crash_param[4]);
87
88                 /* Send notification about crash to user space */
89                 kvm_make_request(KVM_REQ_HV_CRASH, vcpu);
90         }
91
92         return 0;
93 }
94
95 static int kvm_hv_msr_set_crash_data(struct kvm_vcpu *vcpu,
96                                      u32 index, u64 data)
97 {
98         struct kvm_hv *hv = &vcpu->kvm->arch.hyperv;
99
100         if (WARN_ON_ONCE(index >= ARRAY_SIZE(hv->hv_crash_param)))
101                 return -EINVAL;
102
103         hv->hv_crash_param[index] = data;
104         return 0;
105 }
106
107 static int kvm_hv_set_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 data,
108                              bool host)
109 {
110         struct kvm *kvm = vcpu->kvm;
111         struct kvm_hv *hv = &kvm->arch.hyperv;
112
113         switch (msr) {
114         case HV_X64_MSR_GUEST_OS_ID:
115                 hv->hv_guest_os_id = data;
116                 /* setting guest os id to zero disables hypercall page */
117                 if (!hv->hv_guest_os_id)
118                         hv->hv_hypercall &= ~HV_X64_MSR_HYPERCALL_ENABLE;
119                 break;
120         case HV_X64_MSR_HYPERCALL: {
121                 u64 gfn;
122                 unsigned long addr;
123                 u8 instructions[4];
124
125                 /* if guest os id is not set hypercall should remain disabled */
126                 if (!hv->hv_guest_os_id)
127                         break;
128                 if (!(data & HV_X64_MSR_HYPERCALL_ENABLE)) {
129                         hv->hv_hypercall = data;
130                         break;
131                 }
132                 gfn = data >> HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT;
133                 addr = gfn_to_hva(kvm, gfn);
134                 if (kvm_is_error_hva(addr))
135                         return 1;
136                 kvm_x86_ops->patch_hypercall(vcpu, instructions);
137                 ((unsigned char *)instructions)[3] = 0xc3; /* ret */
138                 if (__copy_to_user((void __user *)addr, instructions, 4))
139                         return 1;
140                 hv->hv_hypercall = data;
141                 mark_page_dirty(kvm, gfn);
142                 break;
143         }
144         case HV_X64_MSR_REFERENCE_TSC: {
145                 u64 gfn;
146                 HV_REFERENCE_TSC_PAGE tsc_ref;
147
148                 memset(&tsc_ref, 0, sizeof(tsc_ref));
149                 hv->hv_tsc_page = data;
150                 if (!(data & HV_X64_MSR_TSC_REFERENCE_ENABLE))
151                         break;
152                 gfn = data >> HV_X64_MSR_TSC_REFERENCE_ADDRESS_SHIFT;
153                 if (kvm_write_guest(
154                                 kvm,
155                                 gfn << HV_X64_MSR_TSC_REFERENCE_ADDRESS_SHIFT,
156                                 &tsc_ref, sizeof(tsc_ref)))
157                         return 1;
158                 mark_page_dirty(kvm, gfn);
159                 break;
160         }
161         case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4:
162                 return kvm_hv_msr_set_crash_data(vcpu,
163                                                  msr - HV_X64_MSR_CRASH_P0,
164                                                  data);
165         case HV_X64_MSR_CRASH_CTL:
166                 return kvm_hv_msr_set_crash_ctl(vcpu, data, host);
167         case HV_X64_MSR_RESET:
168                 if (data == 1) {
169                         vcpu_debug(vcpu, "hyper-v reset requested\n");
170                         kvm_make_request(KVM_REQ_HV_RESET, vcpu);
171                 }
172                 break;
173         default:
174                 vcpu_unimpl(vcpu, "Hyper-V uhandled wrmsr: 0x%x data 0x%llx\n",
175                             msr, data);
176                 return 1;
177         }
178         return 0;
179 }
180
181 /* Calculate cpu time spent by current task in 100ns units */
182 static u64 current_task_runtime_100ns(void)
183 {
184         cputime_t utime, stime;
185
186         task_cputime_adjusted(current, &utime, &stime);
187         return div_u64(cputime_to_nsecs(utime + stime), 100);
188 }
189
190 static int kvm_hv_set_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host)
191 {
192         struct kvm_vcpu_hv *hv = &vcpu->arch.hyperv;
193
194         switch (msr) {
195         case HV_X64_MSR_APIC_ASSIST_PAGE: {
196                 u64 gfn;
197                 unsigned long addr;
198
199                 if (!(data & HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE)) {
200                         hv->hv_vapic = data;
201                         if (kvm_lapic_enable_pv_eoi(vcpu, 0))
202                                 return 1;
203                         break;
204                 }
205                 gfn = data >> HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT;
206                 addr = kvm_vcpu_gfn_to_hva(vcpu, gfn);
207                 if (kvm_is_error_hva(addr))
208                         return 1;
209                 if (__clear_user((void __user *)addr, PAGE_SIZE))
210                         return 1;
211                 hv->hv_vapic = data;
212                 kvm_vcpu_mark_page_dirty(vcpu, gfn);
213                 if (kvm_lapic_enable_pv_eoi(vcpu,
214                                             gfn_to_gpa(gfn) | KVM_MSR_ENABLED))
215                         return 1;
216                 break;
217         }
218         case HV_X64_MSR_EOI:
219                 return kvm_hv_vapic_msr_write(vcpu, APIC_EOI, data);
220         case HV_X64_MSR_ICR:
221                 return kvm_hv_vapic_msr_write(vcpu, APIC_ICR, data);
222         case HV_X64_MSR_TPR:
223                 return kvm_hv_vapic_msr_write(vcpu, APIC_TASKPRI, data);
224         case HV_X64_MSR_VP_RUNTIME:
225                 if (!host)
226                         return 1;
227                 hv->runtime_offset = data - current_task_runtime_100ns();
228                 break;
229         default:
230                 vcpu_unimpl(vcpu, "Hyper-V uhandled wrmsr: 0x%x data 0x%llx\n",
231                             msr, data);
232                 return 1;
233         }
234
235         return 0;
236 }
237
238 static int kvm_hv_get_msr_pw(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
239 {
240         u64 data = 0;
241         struct kvm *kvm = vcpu->kvm;
242         struct kvm_hv *hv = &kvm->arch.hyperv;
243
244         switch (msr) {
245         case HV_X64_MSR_GUEST_OS_ID:
246                 data = hv->hv_guest_os_id;
247                 break;
248         case HV_X64_MSR_HYPERCALL:
249                 data = hv->hv_hypercall;
250                 break;
251         case HV_X64_MSR_TIME_REF_COUNT: {
252                 data =
253                      div_u64(get_kernel_ns() + kvm->arch.kvmclock_offset, 100);
254                 break;
255         }
256         case HV_X64_MSR_REFERENCE_TSC:
257                 data = hv->hv_tsc_page;
258                 break;
259         case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4:
260                 return kvm_hv_msr_get_crash_data(vcpu,
261                                                  msr - HV_X64_MSR_CRASH_P0,
262                                                  pdata);
263         case HV_X64_MSR_CRASH_CTL:
264                 return kvm_hv_msr_get_crash_ctl(vcpu, pdata);
265         case HV_X64_MSR_RESET:
266                 data = 0;
267                 break;
268         default:
269                 vcpu_unimpl(vcpu, "Hyper-V unhandled rdmsr: 0x%x\n", msr);
270                 return 1;
271         }
272
273         *pdata = data;
274         return 0;
275 }
276
277 static int kvm_hv_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
278 {
279         u64 data = 0;
280         struct kvm_vcpu_hv *hv = &vcpu->arch.hyperv;
281
282         switch (msr) {
283         case HV_X64_MSR_VP_INDEX: {
284                 int r;
285                 struct kvm_vcpu *v;
286
287                 kvm_for_each_vcpu(r, v, vcpu->kvm) {
288                         if (v == vcpu) {
289                                 data = r;
290                                 break;
291                         }
292                 }
293                 break;
294         }
295         case HV_X64_MSR_EOI:
296                 return kvm_hv_vapic_msr_read(vcpu, APIC_EOI, pdata);
297         case HV_X64_MSR_ICR:
298                 return kvm_hv_vapic_msr_read(vcpu, APIC_ICR, pdata);
299         case HV_X64_MSR_TPR:
300                 return kvm_hv_vapic_msr_read(vcpu, APIC_TASKPRI, pdata);
301         case HV_X64_MSR_APIC_ASSIST_PAGE:
302                 data = hv->hv_vapic;
303                 break;
304         case HV_X64_MSR_VP_RUNTIME:
305                 data = current_task_runtime_100ns() + hv->runtime_offset;
306                 break;
307         default:
308                 vcpu_unimpl(vcpu, "Hyper-V unhandled rdmsr: 0x%x\n", msr);
309                 return 1;
310         }
311         *pdata = data;
312         return 0;
313 }
314
315 int kvm_hv_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data, bool host)
316 {
317         if (kvm_hv_msr_partition_wide(msr)) {
318                 int r;
319
320                 mutex_lock(&vcpu->kvm->lock);
321                 r = kvm_hv_set_msr_pw(vcpu, msr, data, host);
322                 mutex_unlock(&vcpu->kvm->lock);
323                 return r;
324         } else
325                 return kvm_hv_set_msr(vcpu, msr, data, host);
326 }
327
328 int kvm_hv_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
329 {
330         if (kvm_hv_msr_partition_wide(msr)) {
331                 int r;
332
333                 mutex_lock(&vcpu->kvm->lock);
334                 r = kvm_hv_get_msr_pw(vcpu, msr, pdata);
335                 mutex_unlock(&vcpu->kvm->lock);
336                 return r;
337         } else
338                 return kvm_hv_get_msr(vcpu, msr, pdata);
339 }
340
341 bool kvm_hv_hypercall_enabled(struct kvm *kvm)
342 {
343         return kvm->arch.hyperv.hv_hypercall & HV_X64_MSR_HYPERCALL_ENABLE;
344 }
345
346 int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
347 {
348         u64 param, ingpa, outgpa, ret;
349         uint16_t code, rep_idx, rep_cnt, res = HV_STATUS_SUCCESS, rep_done = 0;
350         bool fast, longmode;
351
352         /*
353          * hypercall generates UD from non zero cpl and real mode
354          * per HYPER-V spec
355          */
356         if (kvm_x86_ops->get_cpl(vcpu) != 0 || !is_protmode(vcpu)) {
357                 kvm_queue_exception(vcpu, UD_VECTOR);
358                 return 0;
359         }
360
361         longmode = is_64_bit_mode(vcpu);
362
363         if (!longmode) {
364                 param = ((u64)kvm_register_read(vcpu, VCPU_REGS_RDX) << 32) |
365                         (kvm_register_read(vcpu, VCPU_REGS_RAX) & 0xffffffff);
366                 ingpa = ((u64)kvm_register_read(vcpu, VCPU_REGS_RBX) << 32) |
367                         (kvm_register_read(vcpu, VCPU_REGS_RCX) & 0xffffffff);
368                 outgpa = ((u64)kvm_register_read(vcpu, VCPU_REGS_RDI) << 32) |
369                         (kvm_register_read(vcpu, VCPU_REGS_RSI) & 0xffffffff);
370         }
371 #ifdef CONFIG_X86_64
372         else {
373                 param = kvm_register_read(vcpu, VCPU_REGS_RCX);
374                 ingpa = kvm_register_read(vcpu, VCPU_REGS_RDX);
375                 outgpa = kvm_register_read(vcpu, VCPU_REGS_R8);
376         }
377 #endif
378
379         code = param & 0xffff;
380         fast = (param >> 16) & 0x1;
381         rep_cnt = (param >> 32) & 0xfff;
382         rep_idx = (param >> 48) & 0xfff;
383
384         trace_kvm_hv_hypercall(code, fast, rep_cnt, rep_idx, ingpa, outgpa);
385
386         switch (code) {
387         case HV_X64_HV_NOTIFY_LONG_SPIN_WAIT:
388                 kvm_vcpu_on_spin(vcpu);
389                 break;
390         default:
391                 res = HV_STATUS_INVALID_HYPERCALL_CODE;
392                 break;
393         }
394
395         ret = res | (((u64)rep_done & 0xfff) << 32);
396         if (longmode) {
397                 kvm_register_write(vcpu, VCPU_REGS_RAX, ret);
398         } else {
399                 kvm_register_write(vcpu, VCPU_REGS_RDX, ret >> 32);
400                 kvm_register_write(vcpu, VCPU_REGS_RAX, ret & 0xffffffff);
401         }
402
403         return 1;
404 }