blob: 1d65f627716618fc65e137e2ac93eb6525e656ef [file] [log] [blame]
Heiko Carstensb0c632d2008-03-25 18:47:20 +01001/*
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>
Christian Borntraegerca872302009-05-12 17:21:49 +020018#include <linux/hrtimer.h>
Heiko Carstensb0c632d2008-03-25 18:47:20 +010019#include <linux/init.h>
20#include <linux/kvm.h>
21#include <linux/kvm_host.h>
22#include <linux/module.h>
23#include <linux/slab.h>
Carsten Otteba5c1e92008-03-25 18:47:26 +010024#include <linux/timer.h>
Heiko Carstensb0c632d2008-03-25 18:47:20 +010025#include <asm/lowcore.h>
26#include <asm/pgtable.h>
Heiko Carstensf5daba12009-03-26 15:24:01 +010027#include <asm/nmi.h>
Christian Borntraegeref50f7a2009-06-23 17:24:07 +020028#include <asm/system.h>
Christian Borntraeger8f2abe62008-03-25 18:47:23 +010029#include "kvm-s390.h"
Heiko Carstensb0c632d2008-03-25 18:47:20 +010030#include "gaccess.h"
31
32#define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU
33
34struct kvm_stats_debugfs_item debugfs_entries[] = {
35 { "userspace_handled", VCPU_STAT(exit_userspace) },
Christian Borntraeger0eaeafa2008-05-07 09:22:53 +020036 { "exit_null", VCPU_STAT(exit_null) },
Christian Borntraeger8f2abe62008-03-25 18:47:23 +010037 { "exit_validity", VCPU_STAT(exit_validity) },
38 { "exit_stop_request", VCPU_STAT(exit_stop_request) },
39 { "exit_external_request", VCPU_STAT(exit_external_request) },
40 { "exit_external_interrupt", VCPU_STAT(exit_external_interrupt) },
Carsten Otteba5c1e92008-03-25 18:47:26 +010041 { "exit_instruction", VCPU_STAT(exit_instruction) },
42 { "exit_program_interruption", VCPU_STAT(exit_program_interruption) },
43 { "exit_instr_and_program_int", VCPU_STAT(exit_instr_and_program) },
Christian Borntraegerf5e10b02008-07-25 15:52:44 +020044 { "instruction_lctlg", VCPU_STAT(instruction_lctlg) },
Carsten Otteba5c1e92008-03-25 18:47:26 +010045 { "instruction_lctl", VCPU_STAT(instruction_lctl) },
46 { "deliver_emergency_signal", VCPU_STAT(deliver_emergency_signal) },
47 { "deliver_service_signal", VCPU_STAT(deliver_service_signal) },
48 { "deliver_virtio_interrupt", VCPU_STAT(deliver_virtio_interrupt) },
49 { "deliver_stop_signal", VCPU_STAT(deliver_stop_signal) },
50 { "deliver_prefix_signal", VCPU_STAT(deliver_prefix_signal) },
51 { "deliver_restart_signal", VCPU_STAT(deliver_restart_signal) },
52 { "deliver_program_interruption", VCPU_STAT(deliver_program_int) },
53 { "exit_wait_state", VCPU_STAT(exit_wait_state) },
Christian Borntraeger453423d2008-03-25 18:47:29 +010054 { "instruction_stidp", VCPU_STAT(instruction_stidp) },
55 { "instruction_spx", VCPU_STAT(instruction_spx) },
56 { "instruction_stpx", VCPU_STAT(instruction_stpx) },
57 { "instruction_stap", VCPU_STAT(instruction_stap) },
58 { "instruction_storage_key", VCPU_STAT(instruction_storage_key) },
59 { "instruction_stsch", VCPU_STAT(instruction_stsch) },
60 { "instruction_chsc", VCPU_STAT(instruction_chsc) },
61 { "instruction_stsi", VCPU_STAT(instruction_stsi) },
62 { "instruction_stfl", VCPU_STAT(instruction_stfl) },
Christian Borntraeger5288fbf2008-03-25 18:47:31 +010063 { "instruction_sigp_sense", VCPU_STAT(instruction_sigp_sense) },
64 { "instruction_sigp_emergency", VCPU_STAT(instruction_sigp_emergency) },
65 { "instruction_sigp_stop", VCPU_STAT(instruction_sigp_stop) },
66 { "instruction_sigp_set_arch", VCPU_STAT(instruction_sigp_arch) },
67 { "instruction_sigp_set_prefix", VCPU_STAT(instruction_sigp_prefix) },
68 { "instruction_sigp_restart", VCPU_STAT(instruction_sigp_restart) },
Christian Borntraegere28acfe2008-03-25 18:47:34 +010069 { "diagnose_44", VCPU_STAT(diagnose_44) },
Heiko Carstensb0c632d2008-03-25 18:47:20 +010070 { NULL }
71};
72
Christian Borntraegeref50f7a2009-06-23 17:24:07 +020073static unsigned long long *facilities;
Heiko Carstensb0c632d2008-03-25 18:47:20 +010074
75/* Section: not file related */
76void kvm_arch_hardware_enable(void *garbage)
77{
78 /* every s390 is virtualization enabled ;-) */
79}
80
81void kvm_arch_hardware_disable(void *garbage)
82{
83}
84
Heiko Carstensb0c632d2008-03-25 18:47:20 +010085int kvm_arch_hardware_setup(void)
86{
87 return 0;
88}
89
90void kvm_arch_hardware_unsetup(void)
91{
92}
93
94void kvm_arch_check_processor_compat(void *rtn)
95{
96}
97
98int kvm_arch_init(void *opaque)
99{
100 return 0;
101}
102
103void kvm_arch_exit(void)
104{
105}
106
107/* Section: device related */
108long kvm_arch_dev_ioctl(struct file *filp,
109 unsigned int ioctl, unsigned long arg)
110{
111 if (ioctl == KVM_S390_ENABLE_SIE)
112 return s390_enable_sie();
113 return -EINVAL;
114}
115
116int kvm_dev_ioctl_check_extension(long ext)
117{
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200118 switch (ext) {
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200119 default:
120 return 0;
121 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100122}
123
124/* Section: vm related */
125/*
126 * Get (and clear) the dirty memory log for a memory slot.
127 */
128int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
129 struct kvm_dirty_log *log)
130{
131 return 0;
132}
133
134long kvm_arch_vm_ioctl(struct file *filp,
135 unsigned int ioctl, unsigned long arg)
136{
137 struct kvm *kvm = filp->private_data;
138 void __user *argp = (void __user *)arg;
139 int r;
140
141 switch (ioctl) {
Carsten Otteba5c1e92008-03-25 18:47:26 +0100142 case KVM_S390_INTERRUPT: {
143 struct kvm_s390_interrupt s390int;
144
145 r = -EFAULT;
146 if (copy_from_user(&s390int, argp, sizeof(s390int)))
147 break;
148 r = kvm_s390_inject_vm(kvm, &s390int);
149 break;
150 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100151 default:
152 r = -EINVAL;
153 }
154
155 return r;
156}
157
158struct kvm *kvm_arch_create_vm(void)
159{
160 struct kvm *kvm;
161 int rc;
162 char debug_name[16];
163
164 rc = s390_enable_sie();
165 if (rc)
166 goto out_nokvm;
167
168 rc = -ENOMEM;
169 kvm = kzalloc(sizeof(struct kvm), GFP_KERNEL);
170 if (!kvm)
171 goto out_nokvm;
172
173 kvm->arch.sca = (struct sca_block *) get_zeroed_page(GFP_KERNEL);
174 if (!kvm->arch.sca)
175 goto out_nosca;
176
177 sprintf(debug_name, "kvm-%u", current->pid);
178
179 kvm->arch.dbf = debug_register(debug_name, 8, 2, 8 * sizeof(long));
180 if (!kvm->arch.dbf)
181 goto out_nodbf;
182
Carsten Otteba5c1e92008-03-25 18:47:26 +0100183 spin_lock_init(&kvm->arch.float_int.lock);
184 INIT_LIST_HEAD(&kvm->arch.float_int.list);
185
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100186 debug_register_view(kvm->arch.dbf, &debug_sprintf_view);
187 VM_EVENT(kvm, 3, "%s", "vm created");
188
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100189 return kvm;
190out_nodbf:
191 free_page((unsigned long)(kvm->arch.sca));
192out_nosca:
193 kfree(kvm);
194out_nokvm:
195 return ERR_PTR(rc);
196}
197
Christian Borntraegerd329c032008-11-26 14:50:27 +0100198void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
199{
200 VCPU_EVENT(vcpu, 3, "%s", "free cpu");
Carsten Otteabf4a712009-05-12 17:21:51 +0200201 if (vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda ==
202 (__u64) vcpu->arch.sie_block)
203 vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda = 0;
204 smp_mb();
Christian Borntraegerd329c032008-11-26 14:50:27 +0100205 free_page((unsigned long)(vcpu->arch.sie_block));
Christian Borntraeger6692cef2008-11-26 14:51:08 +0100206 kvm_vcpu_uninit(vcpu);
Christian Borntraegerd329c032008-11-26 14:50:27 +0100207 kfree(vcpu);
208}
209
210static void kvm_free_vcpus(struct kvm *kvm)
211{
212 unsigned int i;
213
214 for (i = 0; i < KVM_MAX_VCPUS; ++i) {
215 if (kvm->vcpus[i]) {
216 kvm_arch_vcpu_destroy(kvm->vcpus[i]);
217 kvm->vcpus[i] = NULL;
218 }
219 }
220}
221
Sheng Yangad8ba2c2009-01-06 10:03:02 +0800222void kvm_arch_sync_events(struct kvm *kvm)
223{
224}
225
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100226void kvm_arch_destroy_vm(struct kvm *kvm)
227{
Christian Borntraegerd329c032008-11-26 14:50:27 +0100228 kvm_free_vcpus(kvm);
Carsten Ottedfdded72008-06-27 15:05:34 +0200229 kvm_free_physmem(kvm);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100230 free_page((unsigned long)(kvm->arch.sca));
Christian Borntraegerd329c032008-11-26 14:50:27 +0100231 debug_unregister(kvm->arch.dbf);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100232 kfree(kvm);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100233}
234
235/* Section: vcpu related */
236int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
237{
238 return 0;
239}
240
241void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
242{
Christian Borntraeger6692cef2008-11-26 14:51:08 +0100243 /* Nothing todo */
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100244}
245
246void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
247{
248 save_fp_regs(&vcpu->arch.host_fpregs);
249 save_access_regs(vcpu->arch.host_acrs);
250 vcpu->arch.guest_fpregs.fpc &= FPC_VALID_MASK;
251 restore_fp_regs(&vcpu->arch.guest_fpregs);
252 restore_access_regs(vcpu->arch.guest_acrs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100253}
254
255void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
256{
257 save_fp_regs(&vcpu->arch.guest_fpregs);
258 save_access_regs(vcpu->arch.guest_acrs);
259 restore_fp_regs(&vcpu->arch.host_fpregs);
260 restore_access_regs(vcpu->arch.host_acrs);
261}
262
263static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu)
264{
265 /* this equals initial cpu reset in pop, but we don't switch to ESA */
266 vcpu->arch.sie_block->gpsw.mask = 0UL;
267 vcpu->arch.sie_block->gpsw.addr = 0UL;
268 vcpu->arch.sie_block->prefix = 0UL;
269 vcpu->arch.sie_block->ihcpu = 0xffff;
270 vcpu->arch.sie_block->cputm = 0UL;
271 vcpu->arch.sie_block->ckc = 0UL;
272 vcpu->arch.sie_block->todpr = 0;
273 memset(vcpu->arch.sie_block->gcr, 0, 16 * sizeof(__u64));
274 vcpu->arch.sie_block->gcr[0] = 0xE0UL;
275 vcpu->arch.sie_block->gcr[14] = 0xC2000000UL;
276 vcpu->arch.guest_fpregs.fpc = 0;
277 asm volatile("lfpc %0" : : "Q" (vcpu->arch.guest_fpregs.fpc));
278 vcpu->arch.sie_block->gbea = 1;
279}
280
Christian Borntraeger4da29e92008-06-27 15:05:38 +0200281/* The current code can have up to 256 pages for virtio */
282#define VIRTIODESCSPACE (256ul * 4096ul)
283
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100284int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
285{
286 atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH);
Christian Borntraeger4da29e92008-06-27 15:05:38 +0200287 vcpu->arch.sie_block->gmslm = vcpu->kvm->arch.guest_memsize +
288 vcpu->kvm->arch.guest_origin +
289 VIRTIODESCSPACE - 1ul;
290 vcpu->arch.sie_block->gmsor = vcpu->kvm->arch.guest_origin;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100291 vcpu->arch.sie_block->ecb = 2;
292 vcpu->arch.sie_block->eca = 0xC1002001U;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200293 vcpu->arch.sie_block->fac = (int) (long) facilities;
Christian Borntraegerca872302009-05-12 17:21:49 +0200294 hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
295 tasklet_init(&vcpu->arch.tasklet, kvm_s390_tasklet,
296 (unsigned long) vcpu);
297 vcpu->arch.ckc_timer.function = kvm_s390_idle_wakeup;
Christian Borntraeger453423d2008-03-25 18:47:29 +0100298 get_cpu_id(&vcpu->arch.cpu_id);
Christian Borntraeger92e6ecf2009-03-26 15:23:58 +0100299 vcpu->arch.cpu_id.version = 0xff;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100300 return 0;
301}
302
303struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
304 unsigned int id)
305{
306 struct kvm_vcpu *vcpu = kzalloc(sizeof(struct kvm_vcpu), GFP_KERNEL);
307 int rc = -ENOMEM;
308
309 if (!vcpu)
310 goto out_nomem;
311
Christian Borntraeger180c12f2008-06-27 15:05:40 +0200312 vcpu->arch.sie_block = (struct kvm_s390_sie_block *)
313 get_zeroed_page(GFP_KERNEL);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100314
315 if (!vcpu->arch.sie_block)
316 goto out_free_cpu;
317
318 vcpu->arch.sie_block->icpua = id;
319 BUG_ON(!kvm->arch.sca);
Carsten Otteabf4a712009-05-12 17:21:51 +0200320 if (!kvm->arch.sca->cpu[id].sda)
321 kvm->arch.sca->cpu[id].sda = (__u64) vcpu->arch.sie_block;
322 else
323 BUG_ON(!kvm->vcpus[id]); /* vcpu does already exist */
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100324 vcpu->arch.sie_block->scaoh = (__u32)(((__u64)kvm->arch.sca) >> 32);
325 vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca;
326
Carsten Otteba5c1e92008-03-25 18:47:26 +0100327 spin_lock_init(&vcpu->arch.local_int.lock);
328 INIT_LIST_HEAD(&vcpu->arch.local_int.list);
329 vcpu->arch.local_int.float_int = &kvm->arch.float_int;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200330 spin_lock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100331 kvm->arch.float_int.local_int[id] = &vcpu->arch.local_int;
332 init_waitqueue_head(&vcpu->arch.local_int.wq);
Christian Borntraeger5288fbf2008-03-25 18:47:31 +0100333 vcpu->arch.local_int.cpuflags = &vcpu->arch.sie_block->cpuflags;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200334 spin_unlock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100335
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100336 rc = kvm_vcpu_init(vcpu, kvm, id);
337 if (rc)
338 goto out_free_cpu;
339 VM_EVENT(kvm, 3, "create cpu %d at %p, sie block at %p", id, vcpu,
340 vcpu->arch.sie_block);
341
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100342 return vcpu;
343out_free_cpu:
344 kfree(vcpu);
345out_nomem:
346 return ERR_PTR(rc);
347}
348
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100349int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
350{
351 /* kvm common code refers to this, but never calls it */
352 BUG();
353 return 0;
354}
355
356static int kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu)
357{
358 vcpu_load(vcpu);
359 kvm_s390_vcpu_initial_reset(vcpu);
360 vcpu_put(vcpu);
361 return 0;
362}
363
364int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
365{
366 vcpu_load(vcpu);
367 memcpy(&vcpu->arch.guest_gprs, &regs->gprs, sizeof(regs->gprs));
368 vcpu_put(vcpu);
369 return 0;
370}
371
372int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
373{
374 vcpu_load(vcpu);
375 memcpy(&regs->gprs, &vcpu->arch.guest_gprs, sizeof(regs->gprs));
376 vcpu_put(vcpu);
377 return 0;
378}
379
380int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
381 struct kvm_sregs *sregs)
382{
383 vcpu_load(vcpu);
384 memcpy(&vcpu->arch.guest_acrs, &sregs->acrs, sizeof(sregs->acrs));
385 memcpy(&vcpu->arch.sie_block->gcr, &sregs->crs, sizeof(sregs->crs));
386 vcpu_put(vcpu);
387 return 0;
388}
389
390int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
391 struct kvm_sregs *sregs)
392{
393 vcpu_load(vcpu);
394 memcpy(&sregs->acrs, &vcpu->arch.guest_acrs, sizeof(sregs->acrs));
395 memcpy(&sregs->crs, &vcpu->arch.sie_block->gcr, sizeof(sregs->crs));
396 vcpu_put(vcpu);
397 return 0;
398}
399
400int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
401{
402 vcpu_load(vcpu);
403 memcpy(&vcpu->arch.guest_fpregs.fprs, &fpu->fprs, sizeof(fpu->fprs));
404 vcpu->arch.guest_fpregs.fpc = fpu->fpc;
405 vcpu_put(vcpu);
406 return 0;
407}
408
409int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
410{
411 vcpu_load(vcpu);
412 memcpy(&fpu->fprs, &vcpu->arch.guest_fpregs.fprs, sizeof(fpu->fprs));
413 fpu->fpc = vcpu->arch.guest_fpregs.fpc;
414 vcpu_put(vcpu);
415 return 0;
416}
417
418static int kvm_arch_vcpu_ioctl_set_initial_psw(struct kvm_vcpu *vcpu, psw_t psw)
419{
420 int rc = 0;
421
422 vcpu_load(vcpu);
423 if (atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_RUNNING)
424 rc = -EBUSY;
425 else
426 vcpu->arch.sie_block->gpsw = psw;
427 vcpu_put(vcpu);
428 return rc;
429}
430
431int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
432 struct kvm_translation *tr)
433{
434 return -EINVAL; /* not implemented yet */
435}
436
Jan Kiszkad0bfb942008-12-15 13:52:10 +0100437int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
438 struct kvm_guest_debug *dbg)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100439{
440 return -EINVAL; /* not implemented yet */
441}
442
Marcelo Tosatti62d9f0d2008-04-11 13:24:45 -0300443int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
444 struct kvm_mp_state *mp_state)
445{
446 return -EINVAL; /* not implemented yet */
447}
448
449int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
450 struct kvm_mp_state *mp_state)
451{
452 return -EINVAL; /* not implemented yet */
453}
454
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100455static void __vcpu_run(struct kvm_vcpu *vcpu)
456{
457 memcpy(&vcpu->arch.sie_block->gg14, &vcpu->arch.guest_gprs[14], 16);
458
459 if (need_resched())
460 schedule();
461
Christian Borntraeger71cde582008-05-21 13:37:34 +0200462 if (test_thread_flag(TIF_MCCK_PENDING))
463 s390_handle_mcck();
464
Carsten Otte0ff31862008-05-21 13:37:37 +0200465 kvm_s390_deliver_pending_interrupts(vcpu);
466
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100467 vcpu->arch.sie_block->icptcode = 0;
468 local_irq_disable();
469 kvm_guest_enter();
470 local_irq_enable();
471 VCPU_EVENT(vcpu, 6, "entering sie flags %x",
472 atomic_read(&vcpu->arch.sie_block->cpuflags));
Carsten Otte1f0d0f02008-05-21 13:37:40 +0200473 if (sie64a(vcpu->arch.sie_block, vcpu->arch.guest_gprs)) {
474 VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction");
475 kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
476 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100477 VCPU_EVENT(vcpu, 6, "exit sie icptcode %d",
478 vcpu->arch.sie_block->icptcode);
479 local_irq_disable();
480 kvm_guest_exit();
481 local_irq_enable();
482
483 memcpy(&vcpu->arch.guest_gprs[14], &vcpu->arch.sie_block->gg14, 16);
484}
485
486int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
487{
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100488 int rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100489 sigset_t sigsaved;
490
491 vcpu_load(vcpu);
492
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200493rerun_vcpu:
Carsten Otte51e4d5a2009-05-12 17:21:53 +0200494 /* verify, that memory has been registered */
495 if (!vcpu->kvm->arch.guest_memsize) {
496 vcpu_put(vcpu);
497 return -EINVAL;
498 }
499
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100500 if (vcpu->sigset_active)
501 sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
502
503 atomic_set_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
504
Carsten Otteba5c1e92008-03-25 18:47:26 +0100505 BUG_ON(vcpu->kvm->arch.float_int.local_int[vcpu->vcpu_id] == NULL);
506
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100507 switch (kvm_run->exit_reason) {
508 case KVM_EXIT_S390_SIEIC:
509 vcpu->arch.sie_block->gpsw.mask = kvm_run->s390_sieic.mask;
510 vcpu->arch.sie_block->gpsw.addr = kvm_run->s390_sieic.addr;
511 break;
512 case KVM_EXIT_UNKNOWN:
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200513 case KVM_EXIT_INTR:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100514 case KVM_EXIT_S390_RESET:
515 break;
516 default:
517 BUG();
518 }
519
Heiko Carstensdab4079d2009-06-12 10:26:32 +0200520 might_fault();
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100521
522 do {
523 __vcpu_run(vcpu);
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100524 rc = kvm_handle_sie_intercept(vcpu);
525 } while (!signal_pending(current) && !rc);
526
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200527 if (rc == SIE_INTERCEPT_RERUNVCPU)
528 goto rerun_vcpu;
529
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100530 if (signal_pending(current) && !rc)
531 rc = -EINTR;
532
533 if (rc == -ENOTSUPP) {
534 /* intercept cannot be handled in-kernel, prepare kvm-run */
535 kvm_run->exit_reason = KVM_EXIT_S390_SIEIC;
536 kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode;
537 kvm_run->s390_sieic.mask = vcpu->arch.sie_block->gpsw.mask;
538 kvm_run->s390_sieic.addr = vcpu->arch.sie_block->gpsw.addr;
539 kvm_run->s390_sieic.ipa = vcpu->arch.sie_block->ipa;
540 kvm_run->s390_sieic.ipb = vcpu->arch.sie_block->ipb;
541 rc = 0;
542 }
543
544 if (rc == -EREMOTE) {
545 /* intercept was handled, but userspace support is needed
546 * kvm_run has been prepared by the handler */
547 rc = 0;
548 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100549
550 if (vcpu->sigset_active)
551 sigprocmask(SIG_SETMASK, &sigsaved, NULL);
552
553 vcpu_put(vcpu);
554
555 vcpu->stat.exit_userspace++;
Heiko Carstens7e8e6ab2008-04-04 15:12:35 +0200556 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100557}
558
559static int __guestcopy(struct kvm_vcpu *vcpu, u64 guestdest, const void *from,
560 unsigned long n, int prefix)
561{
562 if (prefix)
563 return copy_to_guest(vcpu, guestdest, from, n);
564 else
565 return copy_to_guest_absolute(vcpu, guestdest, from, n);
566}
567
568/*
569 * store status at address
570 * we use have two special cases:
571 * KVM_S390_STORE_STATUS_NOADDR: -> 0x1200 on 64 bit
572 * KVM_S390_STORE_STATUS_PREFIXED: -> prefix
573 */
574int __kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
575{
576 const unsigned char archmode = 1;
577 int prefix;
578
579 if (addr == KVM_S390_STORE_STATUS_NOADDR) {
580 if (copy_to_guest_absolute(vcpu, 163ul, &archmode, 1))
581 return -EFAULT;
582 addr = SAVE_AREA_BASE;
583 prefix = 0;
584 } else if (addr == KVM_S390_STORE_STATUS_PREFIXED) {
585 if (copy_to_guest(vcpu, 163ul, &archmode, 1))
586 return -EFAULT;
587 addr = SAVE_AREA_BASE;
588 prefix = 1;
589 } else
590 prefix = 0;
591
592 if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, fp_regs),
593 vcpu->arch.guest_fpregs.fprs, 128, prefix))
594 return -EFAULT;
595
596 if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, gp_regs),
597 vcpu->arch.guest_gprs, 128, prefix))
598 return -EFAULT;
599
600 if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, psw),
601 &vcpu->arch.sie_block->gpsw, 16, prefix))
602 return -EFAULT;
603
604 if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, pref_reg),
605 &vcpu->arch.sie_block->prefix, 4, prefix))
606 return -EFAULT;
607
608 if (__guestcopy(vcpu,
609 addr + offsetof(struct save_area_s390x, fp_ctrl_reg),
610 &vcpu->arch.guest_fpregs.fpc, 4, prefix))
611 return -EFAULT;
612
613 if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, tod_reg),
614 &vcpu->arch.sie_block->todpr, 4, prefix))
615 return -EFAULT;
616
617 if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, timer),
618 &vcpu->arch.sie_block->cputm, 8, prefix))
619 return -EFAULT;
620
621 if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, clk_cmp),
622 &vcpu->arch.sie_block->ckc, 8, prefix))
623 return -EFAULT;
624
625 if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, acc_regs),
626 &vcpu->arch.guest_acrs, 64, prefix))
627 return -EFAULT;
628
629 if (__guestcopy(vcpu,
630 addr + offsetof(struct save_area_s390x, ctrl_regs),
631 &vcpu->arch.sie_block->gcr, 128, prefix))
632 return -EFAULT;
633 return 0;
634}
635
636static int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
637{
638 int rc;
639
640 vcpu_load(vcpu);
641 rc = __kvm_s390_vcpu_store_status(vcpu, addr);
642 vcpu_put(vcpu);
643 return rc;
644}
645
646long kvm_arch_vcpu_ioctl(struct file *filp,
647 unsigned int ioctl, unsigned long arg)
648{
649 struct kvm_vcpu *vcpu = filp->private_data;
650 void __user *argp = (void __user *)arg;
651
652 switch (ioctl) {
Carsten Otteba5c1e92008-03-25 18:47:26 +0100653 case KVM_S390_INTERRUPT: {
654 struct kvm_s390_interrupt s390int;
655
656 if (copy_from_user(&s390int, argp, sizeof(s390int)))
657 return -EFAULT;
658 return kvm_s390_inject_vcpu(vcpu, &s390int);
659 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100660 case KVM_S390_STORE_STATUS:
661 return kvm_s390_vcpu_store_status(vcpu, arg);
662 case KVM_S390_SET_INITIAL_PSW: {
663 psw_t psw;
664
665 if (copy_from_user(&psw, argp, sizeof(psw)))
666 return -EFAULT;
667 return kvm_arch_vcpu_ioctl_set_initial_psw(vcpu, psw);
668 }
669 case KVM_S390_INITIAL_RESET:
670 return kvm_arch_vcpu_ioctl_initial_reset(vcpu);
671 default:
672 ;
673 }
674 return -EINVAL;
675}
676
677/* Section: memory related */
678int kvm_arch_set_memory_region(struct kvm *kvm,
679 struct kvm_userspace_memory_region *mem,
680 struct kvm_memory_slot old,
681 int user_alloc)
682{
Carsten Otte2668dab2009-05-12 17:21:48 +0200683 int i;
684
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100685 /* A few sanity checks. We can have exactly one memory slot which has
686 to start at guest virtual zero and which has to be located at a
687 page boundary in userland and which has to end at a page boundary.
688 The memory in userland is ok to be fragmented into various different
689 vmas. It is okay to mmap() and munmap() stuff in this slot after
690 doing this call at any time */
691
Carsten Otte2668dab2009-05-12 17:21:48 +0200692 if (mem->slot || kvm->arch.guest_memsize)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100693 return -EINVAL;
694
695 if (mem->guest_phys_addr)
696 return -EINVAL;
697
698 if (mem->userspace_addr & (PAGE_SIZE - 1))
699 return -EINVAL;
700
701 if (mem->memory_size & (PAGE_SIZE - 1))
702 return -EINVAL;
703
Carsten Otte2668dab2009-05-12 17:21:48 +0200704 if (!user_alloc)
705 return -EINVAL;
706
707 /* lock all vcpus */
708 for (i = 0; i < KVM_MAX_VCPUS; ++i) {
709 if (!kvm->vcpus[i])
710 continue;
711 if (!mutex_trylock(&kvm->vcpus[i]->mutex))
712 goto fail_out;
713 }
714
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100715 kvm->arch.guest_origin = mem->userspace_addr;
716 kvm->arch.guest_memsize = mem->memory_size;
717
Carsten Otte2668dab2009-05-12 17:21:48 +0200718 /* update sie control blocks, and unlock all vcpus */
719 for (i = 0; i < KVM_MAX_VCPUS; ++i) {
720 if (kvm->vcpus[i]) {
721 kvm->vcpus[i]->arch.sie_block->gmsor =
722 kvm->arch.guest_origin;
723 kvm->vcpus[i]->arch.sie_block->gmslm =
724 kvm->arch.guest_memsize +
725 kvm->arch.guest_origin +
726 VIRTIODESCSPACE - 1ul;
727 mutex_unlock(&kvm->vcpus[i]->mutex);
728 }
729 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100730
731 return 0;
Carsten Otte2668dab2009-05-12 17:21:48 +0200732
733fail_out:
734 for (; i >= 0; i--)
735 mutex_unlock(&kvm->vcpus[i]->mutex);
736 return -EINVAL;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100737}
738
Marcelo Tosatti34d4cb82008-07-10 20:49:31 -0300739void kvm_arch_flush_shadow(struct kvm *kvm)
740{
741}
742
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100743gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn)
744{
745 return gfn;
746}
747
748static int __init kvm_s390_init(void)
749{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200750 int ret;
751 ret = kvm_init(NULL, sizeof(struct kvm_vcpu), THIS_MODULE);
752 if (ret)
753 return ret;
754
755 /*
756 * guests can ask for up to 255+1 double words, we need a full page
757 * to hold the maximum amount of facilites. On the other hand, we
758 * only set facilities that are known to work in KVM.
759 */
760 facilities = (unsigned long long *) get_zeroed_page(GFP_DMA);
761 if (!facilities) {
762 kvm_exit();
763 return -ENOMEM;
764 }
765 stfle(facilities, 1);
766 facilities[0] &= 0xff00fff3f0700000ULL;
767 return 0;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100768}
769
770static void __exit kvm_s390_exit(void)
771{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200772 free_page((unsigned long) facilities);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100773 kvm_exit();
774}
775
776module_init(kvm_s390_init);
777module_exit(kvm_s390_exit);