KVM: s390: sie intercept handling
[deliverable/linux.git] / arch / s390 / kvm / kvm-s390.c
CommitLineData
b0c632db
HC
1/*
2 * s390host.c -- hosting zSeries kernel virtual machines
3 *
4 * Copyright IBM Corp. 2008
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License (version 2 only)
8 * as published by the Free Software Foundation.
9 *
10 * Author(s): Carsten Otte <cotte@de.ibm.com>
11 * Christian Borntraeger <borntraeger@de.ibm.com>
12 * Heiko Carstens <heiko.carstens@de.ibm.com>
13 */
14
15#include <linux/compiler.h>
16#include <linux/err.h>
17#include <linux/fs.h>
18#include <linux/init.h>
19#include <linux/kvm.h>
20#include <linux/kvm_host.h>
21#include <linux/module.h>
22#include <linux/slab.h>
23#include <asm/lowcore.h>
24#include <asm/pgtable.h>
25
8f2abe6a 26#include "kvm-s390.h"
b0c632db
HC
27#include "gaccess.h"
28
29#define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU
30
31struct kvm_stats_debugfs_item debugfs_entries[] = {
32 { "userspace_handled", VCPU_STAT(exit_userspace) },
8f2abe6a
CB
33 { "exit_validity", VCPU_STAT(exit_validity) },
34 { "exit_stop_request", VCPU_STAT(exit_stop_request) },
35 { "exit_external_request", VCPU_STAT(exit_external_request) },
36 { "exit_external_interrupt", VCPU_STAT(exit_external_interrupt) },
b0c632db
HC
37 { NULL }
38};
39
40
41/* Section: not file related */
42void kvm_arch_hardware_enable(void *garbage)
43{
44 /* every s390 is virtualization enabled ;-) */
45}
46
47void kvm_arch_hardware_disable(void *garbage)
48{
49}
50
51void decache_vcpus_on_cpu(int cpu)
52{
53}
54
55int kvm_arch_hardware_setup(void)
56{
57 return 0;
58}
59
60void kvm_arch_hardware_unsetup(void)
61{
62}
63
64void kvm_arch_check_processor_compat(void *rtn)
65{
66}
67
68int kvm_arch_init(void *opaque)
69{
70 return 0;
71}
72
73void kvm_arch_exit(void)
74{
75}
76
77/* Section: device related */
78long kvm_arch_dev_ioctl(struct file *filp,
79 unsigned int ioctl, unsigned long arg)
80{
81 if (ioctl == KVM_S390_ENABLE_SIE)
82 return s390_enable_sie();
83 return -EINVAL;
84}
85
86int kvm_dev_ioctl_check_extension(long ext)
87{
88 return 0;
89}
90
91/* Section: vm related */
92/*
93 * Get (and clear) the dirty memory log for a memory slot.
94 */
95int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
96 struct kvm_dirty_log *log)
97{
98 return 0;
99}
100
101long kvm_arch_vm_ioctl(struct file *filp,
102 unsigned int ioctl, unsigned long arg)
103{
104 struct kvm *kvm = filp->private_data;
105 void __user *argp = (void __user *)arg;
106 int r;
107
108 switch (ioctl) {
109 default:
110 r = -EINVAL;
111 }
112
113 return r;
114}
115
116struct kvm *kvm_arch_create_vm(void)
117{
118 struct kvm *kvm;
119 int rc;
120 char debug_name[16];
121
122 rc = s390_enable_sie();
123 if (rc)
124 goto out_nokvm;
125
126 rc = -ENOMEM;
127 kvm = kzalloc(sizeof(struct kvm), GFP_KERNEL);
128 if (!kvm)
129 goto out_nokvm;
130
131 kvm->arch.sca = (struct sca_block *) get_zeroed_page(GFP_KERNEL);
132 if (!kvm->arch.sca)
133 goto out_nosca;
134
135 sprintf(debug_name, "kvm-%u", current->pid);
136
137 kvm->arch.dbf = debug_register(debug_name, 8, 2, 8 * sizeof(long));
138 if (!kvm->arch.dbf)
139 goto out_nodbf;
140
141 debug_register_view(kvm->arch.dbf, &debug_sprintf_view);
142 VM_EVENT(kvm, 3, "%s", "vm created");
143
144 try_module_get(THIS_MODULE);
145
146 return kvm;
147out_nodbf:
148 free_page((unsigned long)(kvm->arch.sca));
149out_nosca:
150 kfree(kvm);
151out_nokvm:
152 return ERR_PTR(rc);
153}
154
155void kvm_arch_destroy_vm(struct kvm *kvm)
156{
157 debug_unregister(kvm->arch.dbf);
158 free_page((unsigned long)(kvm->arch.sca));
159 kfree(kvm);
160 module_put(THIS_MODULE);
161}
162
163/* Section: vcpu related */
164int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
165{
166 return 0;
167}
168
169void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
170{
171 /* kvm common code refers to this, but does'nt call it */
172 BUG();
173}
174
175void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
176{
177 save_fp_regs(&vcpu->arch.host_fpregs);
178 save_access_regs(vcpu->arch.host_acrs);
179 vcpu->arch.guest_fpregs.fpc &= FPC_VALID_MASK;
180 restore_fp_regs(&vcpu->arch.guest_fpregs);
181 restore_access_regs(vcpu->arch.guest_acrs);
182
183 if (signal_pending(current))
184 atomic_set_mask(CPUSTAT_STOP_INT,
185 &vcpu->arch.sie_block->cpuflags);
186}
187
188void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
189{
190 save_fp_regs(&vcpu->arch.guest_fpregs);
191 save_access_regs(vcpu->arch.guest_acrs);
192 restore_fp_regs(&vcpu->arch.host_fpregs);
193 restore_access_regs(vcpu->arch.host_acrs);
194}
195
196static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu)
197{
198 /* this equals initial cpu reset in pop, but we don't switch to ESA */
199 vcpu->arch.sie_block->gpsw.mask = 0UL;
200 vcpu->arch.sie_block->gpsw.addr = 0UL;
201 vcpu->arch.sie_block->prefix = 0UL;
202 vcpu->arch.sie_block->ihcpu = 0xffff;
203 vcpu->arch.sie_block->cputm = 0UL;
204 vcpu->arch.sie_block->ckc = 0UL;
205 vcpu->arch.sie_block->todpr = 0;
206 memset(vcpu->arch.sie_block->gcr, 0, 16 * sizeof(__u64));
207 vcpu->arch.sie_block->gcr[0] = 0xE0UL;
208 vcpu->arch.sie_block->gcr[14] = 0xC2000000UL;
209 vcpu->arch.guest_fpregs.fpc = 0;
210 asm volatile("lfpc %0" : : "Q" (vcpu->arch.guest_fpregs.fpc));
211 vcpu->arch.sie_block->gbea = 1;
212}
213
214int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
215{
216 atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH);
217 vcpu->arch.sie_block->gmslm = 0xffffffffffUL;
218 vcpu->arch.sie_block->gmsor = 0x000000000000;
219 vcpu->arch.sie_block->ecb = 2;
220 vcpu->arch.sie_block->eca = 0xC1002001U;
221
222 return 0;
223}
224
225struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
226 unsigned int id)
227{
228 struct kvm_vcpu *vcpu = kzalloc(sizeof(struct kvm_vcpu), GFP_KERNEL);
229 int rc = -ENOMEM;
230
231 if (!vcpu)
232 goto out_nomem;
233
234 vcpu->arch.sie_block = (struct sie_block *) get_zeroed_page(GFP_KERNEL);
235
236 if (!vcpu->arch.sie_block)
237 goto out_free_cpu;
238
239 vcpu->arch.sie_block->icpua = id;
240 BUG_ON(!kvm->arch.sca);
241 BUG_ON(kvm->arch.sca->cpu[id].sda);
242 kvm->arch.sca->cpu[id].sda = (__u64) vcpu->arch.sie_block;
243 vcpu->arch.sie_block->scaoh = (__u32)(((__u64)kvm->arch.sca) >> 32);
244 vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca;
245
246 rc = kvm_vcpu_init(vcpu, kvm, id);
247 if (rc)
248 goto out_free_cpu;
249 VM_EVENT(kvm, 3, "create cpu %d at %p, sie block at %p", id, vcpu,
250 vcpu->arch.sie_block);
251
252 try_module_get(THIS_MODULE);
253
254 return vcpu;
255out_free_cpu:
256 kfree(vcpu);
257out_nomem:
258 return ERR_PTR(rc);
259}
260
261void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
262{
263 VCPU_EVENT(vcpu, 3, "%s", "destroy cpu");
264 free_page((unsigned long)(vcpu->arch.sie_block));
265 kfree(vcpu);
266 module_put(THIS_MODULE);
267}
268
269int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
270{
271 /* kvm common code refers to this, but never calls it */
272 BUG();
273 return 0;
274}
275
276static int kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu)
277{
278 vcpu_load(vcpu);
279 kvm_s390_vcpu_initial_reset(vcpu);
280 vcpu_put(vcpu);
281 return 0;
282}
283
284int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
285{
286 vcpu_load(vcpu);
287 memcpy(&vcpu->arch.guest_gprs, &regs->gprs, sizeof(regs->gprs));
288 vcpu_put(vcpu);
289 return 0;
290}
291
292int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
293{
294 vcpu_load(vcpu);
295 memcpy(&regs->gprs, &vcpu->arch.guest_gprs, sizeof(regs->gprs));
296 vcpu_put(vcpu);
297 return 0;
298}
299
300int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
301 struct kvm_sregs *sregs)
302{
303 vcpu_load(vcpu);
304 memcpy(&vcpu->arch.guest_acrs, &sregs->acrs, sizeof(sregs->acrs));
305 memcpy(&vcpu->arch.sie_block->gcr, &sregs->crs, sizeof(sregs->crs));
306 vcpu_put(vcpu);
307 return 0;
308}
309
310int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
311 struct kvm_sregs *sregs)
312{
313 vcpu_load(vcpu);
314 memcpy(&sregs->acrs, &vcpu->arch.guest_acrs, sizeof(sregs->acrs));
315 memcpy(&sregs->crs, &vcpu->arch.sie_block->gcr, sizeof(sregs->crs));
316 vcpu_put(vcpu);
317 return 0;
318}
319
320int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
321{
322 vcpu_load(vcpu);
323 memcpy(&vcpu->arch.guest_fpregs.fprs, &fpu->fprs, sizeof(fpu->fprs));
324 vcpu->arch.guest_fpregs.fpc = fpu->fpc;
325 vcpu_put(vcpu);
326 return 0;
327}
328
329int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
330{
331 vcpu_load(vcpu);
332 memcpy(&fpu->fprs, &vcpu->arch.guest_fpregs.fprs, sizeof(fpu->fprs));
333 fpu->fpc = vcpu->arch.guest_fpregs.fpc;
334 vcpu_put(vcpu);
335 return 0;
336}
337
338static int kvm_arch_vcpu_ioctl_set_initial_psw(struct kvm_vcpu *vcpu, psw_t psw)
339{
340 int rc = 0;
341
342 vcpu_load(vcpu);
343 if (atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_RUNNING)
344 rc = -EBUSY;
345 else
346 vcpu->arch.sie_block->gpsw = psw;
347 vcpu_put(vcpu);
348 return rc;
349}
350
351int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
352 struct kvm_translation *tr)
353{
354 return -EINVAL; /* not implemented yet */
355}
356
357int kvm_arch_vcpu_ioctl_debug_guest(struct kvm_vcpu *vcpu,
358 struct kvm_debug_guest *dbg)
359{
360 return -EINVAL; /* not implemented yet */
361}
362
363static void __vcpu_run(struct kvm_vcpu *vcpu)
364{
365 memcpy(&vcpu->arch.sie_block->gg14, &vcpu->arch.guest_gprs[14], 16);
366
367 if (need_resched())
368 schedule();
369
370 vcpu->arch.sie_block->icptcode = 0;
371 local_irq_disable();
372 kvm_guest_enter();
373 local_irq_enable();
374 VCPU_EVENT(vcpu, 6, "entering sie flags %x",
375 atomic_read(&vcpu->arch.sie_block->cpuflags));
376 sie64a(vcpu->arch.sie_block, vcpu->arch.guest_gprs);
377 VCPU_EVENT(vcpu, 6, "exit sie icptcode %d",
378 vcpu->arch.sie_block->icptcode);
379 local_irq_disable();
380 kvm_guest_exit();
381 local_irq_enable();
382
383 memcpy(&vcpu->arch.guest_gprs[14], &vcpu->arch.sie_block->gg14, 16);
384}
385
386int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
387{
8f2abe6a 388 int rc;
b0c632db
HC
389 sigset_t sigsaved;
390
391 vcpu_load(vcpu);
392
393 if (vcpu->sigset_active)
394 sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
395
396 atomic_set_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
397
8f2abe6a
CB
398 switch (kvm_run->exit_reason) {
399 case KVM_EXIT_S390_SIEIC:
400 vcpu->arch.sie_block->gpsw.mask = kvm_run->s390_sieic.mask;
401 vcpu->arch.sie_block->gpsw.addr = kvm_run->s390_sieic.addr;
402 break;
403 case KVM_EXIT_UNKNOWN:
404 case KVM_EXIT_S390_RESET:
405 break;
406 default:
407 BUG();
408 }
409
410 might_sleep();
411
412 do {
413 __vcpu_run(vcpu);
414
415 rc = kvm_handle_sie_intercept(vcpu);
416 } while (!signal_pending(current) && !rc);
417
418 if (signal_pending(current) && !rc)
419 rc = -EINTR;
420
421 if (rc == -ENOTSUPP) {
422 /* intercept cannot be handled in-kernel, prepare kvm-run */
423 kvm_run->exit_reason = KVM_EXIT_S390_SIEIC;
424 kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode;
425 kvm_run->s390_sieic.mask = vcpu->arch.sie_block->gpsw.mask;
426 kvm_run->s390_sieic.addr = vcpu->arch.sie_block->gpsw.addr;
427 kvm_run->s390_sieic.ipa = vcpu->arch.sie_block->ipa;
428 kvm_run->s390_sieic.ipb = vcpu->arch.sie_block->ipb;
429 rc = 0;
430 }
431
432 if (rc == -EREMOTE) {
433 /* intercept was handled, but userspace support is needed
434 * kvm_run has been prepared by the handler */
435 rc = 0;
436 }
b0c632db
HC
437
438 if (vcpu->sigset_active)
439 sigprocmask(SIG_SETMASK, &sigsaved, NULL);
440
441 vcpu_put(vcpu);
442
443 vcpu->stat.exit_userspace++;
444 return 0;
445}
446
447static int __guestcopy(struct kvm_vcpu *vcpu, u64 guestdest, const void *from,
448 unsigned long n, int prefix)
449{
450 if (prefix)
451 return copy_to_guest(vcpu, guestdest, from, n);
452 else
453 return copy_to_guest_absolute(vcpu, guestdest, from, n);
454}
455
456/*
457 * store status at address
458 * we use have two special cases:
459 * KVM_S390_STORE_STATUS_NOADDR: -> 0x1200 on 64 bit
460 * KVM_S390_STORE_STATUS_PREFIXED: -> prefix
461 */
462int __kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
463{
464 const unsigned char archmode = 1;
465 int prefix;
466
467 if (addr == KVM_S390_STORE_STATUS_NOADDR) {
468 if (copy_to_guest_absolute(vcpu, 163ul, &archmode, 1))
469 return -EFAULT;
470 addr = SAVE_AREA_BASE;
471 prefix = 0;
472 } else if (addr == KVM_S390_STORE_STATUS_PREFIXED) {
473 if (copy_to_guest(vcpu, 163ul, &archmode, 1))
474 return -EFAULT;
475 addr = SAVE_AREA_BASE;
476 prefix = 1;
477 } else
478 prefix = 0;
479
480 if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, fp_regs),
481 vcpu->arch.guest_fpregs.fprs, 128, prefix))
482 return -EFAULT;
483
484 if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, gp_regs),
485 vcpu->arch.guest_gprs, 128, prefix))
486 return -EFAULT;
487
488 if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, psw),
489 &vcpu->arch.sie_block->gpsw, 16, prefix))
490 return -EFAULT;
491
492 if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, pref_reg),
493 &vcpu->arch.sie_block->prefix, 4, prefix))
494 return -EFAULT;
495
496 if (__guestcopy(vcpu,
497 addr + offsetof(struct save_area_s390x, fp_ctrl_reg),
498 &vcpu->arch.guest_fpregs.fpc, 4, prefix))
499 return -EFAULT;
500
501 if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, tod_reg),
502 &vcpu->arch.sie_block->todpr, 4, prefix))
503 return -EFAULT;
504
505 if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, timer),
506 &vcpu->arch.sie_block->cputm, 8, prefix))
507 return -EFAULT;
508
509 if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, clk_cmp),
510 &vcpu->arch.sie_block->ckc, 8, prefix))
511 return -EFAULT;
512
513 if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, acc_regs),
514 &vcpu->arch.guest_acrs, 64, prefix))
515 return -EFAULT;
516
517 if (__guestcopy(vcpu,
518 addr + offsetof(struct save_area_s390x, ctrl_regs),
519 &vcpu->arch.sie_block->gcr, 128, prefix))
520 return -EFAULT;
521 return 0;
522}
523
524static int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
525{
526 int rc;
527
528 vcpu_load(vcpu);
529 rc = __kvm_s390_vcpu_store_status(vcpu, addr);
530 vcpu_put(vcpu);
531 return rc;
532}
533
534long kvm_arch_vcpu_ioctl(struct file *filp,
535 unsigned int ioctl, unsigned long arg)
536{
537 struct kvm_vcpu *vcpu = filp->private_data;
538 void __user *argp = (void __user *)arg;
539
540 switch (ioctl) {
541 case KVM_S390_STORE_STATUS:
542 return kvm_s390_vcpu_store_status(vcpu, arg);
543 case KVM_S390_SET_INITIAL_PSW: {
544 psw_t psw;
545
546 if (copy_from_user(&psw, argp, sizeof(psw)))
547 return -EFAULT;
548 return kvm_arch_vcpu_ioctl_set_initial_psw(vcpu, psw);
549 }
550 case KVM_S390_INITIAL_RESET:
551 return kvm_arch_vcpu_ioctl_initial_reset(vcpu);
552 default:
553 ;
554 }
555 return -EINVAL;
556}
557
558/* Section: memory related */
559int kvm_arch_set_memory_region(struct kvm *kvm,
560 struct kvm_userspace_memory_region *mem,
561 struct kvm_memory_slot old,
562 int user_alloc)
563{
564 /* A few sanity checks. We can have exactly one memory slot which has
565 to start at guest virtual zero and which has to be located at a
566 page boundary in userland and which has to end at a page boundary.
567 The memory in userland is ok to be fragmented into various different
568 vmas. It is okay to mmap() and munmap() stuff in this slot after
569 doing this call at any time */
570
571 if (mem->slot)
572 return -EINVAL;
573
574 if (mem->guest_phys_addr)
575 return -EINVAL;
576
577 if (mem->userspace_addr & (PAGE_SIZE - 1))
578 return -EINVAL;
579
580 if (mem->memory_size & (PAGE_SIZE - 1))
581 return -EINVAL;
582
583 kvm->arch.guest_origin = mem->userspace_addr;
584 kvm->arch.guest_memsize = mem->memory_size;
585
586 /* FIXME: we do want to interrupt running CPUs and update their memory
587 configuration now to avoid race conditions. But hey, changing the
588 memory layout while virtual CPUs are running is usually bad
589 programming practice. */
590
591 return 0;
592}
593
594gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn)
595{
596 return gfn;
597}
598
599static int __init kvm_s390_init(void)
600{
601 return kvm_init(NULL, sizeof(struct kvm_vcpu), THIS_MODULE);
602}
603
604static void __exit kvm_s390_exit(void)
605{
606 kvm_exit();
607}
608
609module_init(kvm_s390_init);
610module_exit(kvm_s390_exit);
This page took 0.067355 seconds and 5 git commands to generate.