blob: 098bfa6fbdf6da191997df568a531daa582004ef [file] [log] [blame]
Heiko Carstensb0c632d2008-03-25 18:47:20 +01001/*
2 * s390host.c -- hosting zSeries kernel virtual machines
3 *
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +02004 * Copyright IBM Corp. 2008,2009
Heiko Carstensb0c632d2008-03-25 18:47:20 +01005 *
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>
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +020013 * Christian Ehrhardt <ehrhardt@de.ibm.com>
Heiko Carstensb0c632d2008-03-25 18:47:20 +010014 */
15
16#include <linux/compiler.h>
17#include <linux/err.h>
18#include <linux/fs.h>
Christian Borntraegerca872302009-05-12 17:21:49 +020019#include <linux/hrtimer.h>
Heiko Carstensb0c632d2008-03-25 18:47:20 +010020#include <linux/init.h>
21#include <linux/kvm.h>
22#include <linux/kvm_host.h>
23#include <linux/module.h>
24#include <linux/slab.h>
Carsten Otteba5c1e92008-03-25 18:47:26 +010025#include <linux/timer.h>
Heiko Carstensb0c632d2008-03-25 18:47:20 +010026#include <asm/lowcore.h>
27#include <asm/pgtable.h>
Heiko Carstensf5daba12009-03-26 15:24:01 +010028#include <asm/nmi.h>
Christian Borntraegeref50f7a2009-06-23 17:24:07 +020029#include <asm/system.h>
Christian Borntraeger8f2abe62008-03-25 18:47:23 +010030#include "kvm-s390.h"
Heiko Carstensb0c632d2008-03-25 18:47:20 +010031#include "gaccess.h"
32
33#define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU
34
35struct kvm_stats_debugfs_item debugfs_entries[] = {
36 { "userspace_handled", VCPU_STAT(exit_userspace) },
Christian Borntraeger0eaeafa2008-05-07 09:22:53 +020037 { "exit_null", VCPU_STAT(exit_null) },
Christian Borntraeger8f2abe62008-03-25 18:47:23 +010038 { "exit_validity", VCPU_STAT(exit_validity) },
39 { "exit_stop_request", VCPU_STAT(exit_stop_request) },
40 { "exit_external_request", VCPU_STAT(exit_external_request) },
41 { "exit_external_interrupt", VCPU_STAT(exit_external_interrupt) },
Carsten Otteba5c1e92008-03-25 18:47:26 +010042 { "exit_instruction", VCPU_STAT(exit_instruction) },
43 { "exit_program_interruption", VCPU_STAT(exit_program_interruption) },
44 { "exit_instr_and_program_int", VCPU_STAT(exit_instr_and_program) },
Christian Borntraegerf5e10b02008-07-25 15:52:44 +020045 { "instruction_lctlg", VCPU_STAT(instruction_lctlg) },
Carsten Otteba5c1e92008-03-25 18:47:26 +010046 { "instruction_lctl", VCPU_STAT(instruction_lctl) },
47 { "deliver_emergency_signal", VCPU_STAT(deliver_emergency_signal) },
48 { "deliver_service_signal", VCPU_STAT(deliver_service_signal) },
49 { "deliver_virtio_interrupt", VCPU_STAT(deliver_virtio_interrupt) },
50 { "deliver_stop_signal", VCPU_STAT(deliver_stop_signal) },
51 { "deliver_prefix_signal", VCPU_STAT(deliver_prefix_signal) },
52 { "deliver_restart_signal", VCPU_STAT(deliver_restart_signal) },
53 { "deliver_program_interruption", VCPU_STAT(deliver_program_int) },
54 { "exit_wait_state", VCPU_STAT(exit_wait_state) },
Christian Borntraeger453423d2008-03-25 18:47:29 +010055 { "instruction_stidp", VCPU_STAT(instruction_stidp) },
56 { "instruction_spx", VCPU_STAT(instruction_spx) },
57 { "instruction_stpx", VCPU_STAT(instruction_stpx) },
58 { "instruction_stap", VCPU_STAT(instruction_stap) },
59 { "instruction_storage_key", VCPU_STAT(instruction_storage_key) },
60 { "instruction_stsch", VCPU_STAT(instruction_stsch) },
61 { "instruction_chsc", VCPU_STAT(instruction_chsc) },
62 { "instruction_stsi", VCPU_STAT(instruction_stsi) },
63 { "instruction_stfl", VCPU_STAT(instruction_stfl) },
Christian Borntraeger5288fbf2008-03-25 18:47:31 +010064 { "instruction_sigp_sense", VCPU_STAT(instruction_sigp_sense) },
65 { "instruction_sigp_emergency", VCPU_STAT(instruction_sigp_emergency) },
66 { "instruction_sigp_stop", VCPU_STAT(instruction_sigp_stop) },
67 { "instruction_sigp_set_arch", VCPU_STAT(instruction_sigp_arch) },
68 { "instruction_sigp_set_prefix", VCPU_STAT(instruction_sigp_prefix) },
69 { "instruction_sigp_restart", VCPU_STAT(instruction_sigp_restart) },
Christian Borntraegere28acfe2008-03-25 18:47:34 +010070 { "diagnose_44", VCPU_STAT(diagnose_44) },
Heiko Carstensb0c632d2008-03-25 18:47:20 +010071 { NULL }
72};
73
Christian Borntraegeref50f7a2009-06-23 17:24:07 +020074static unsigned long long *facilities;
Heiko Carstensb0c632d2008-03-25 18:47:20 +010075
76/* Section: not file related */
77void kvm_arch_hardware_enable(void *garbage)
78{
79 /* every s390 is virtualization enabled ;-) */
80}
81
82void kvm_arch_hardware_disable(void *garbage)
83{
84}
85
Heiko Carstensb0c632d2008-03-25 18:47:20 +010086int kvm_arch_hardware_setup(void)
87{
88 return 0;
89}
90
91void kvm_arch_hardware_unsetup(void)
92{
93}
94
95void kvm_arch_check_processor_compat(void *rtn)
96{
97}
98
99int kvm_arch_init(void *opaque)
100{
101 return 0;
102}
103
104void kvm_arch_exit(void)
105{
106}
107
108/* Section: device related */
109long kvm_arch_dev_ioctl(struct file *filp,
110 unsigned int ioctl, unsigned long arg)
111{
112 if (ioctl == KVM_S390_ENABLE_SIE)
113 return s390_enable_sie();
114 return -EINVAL;
115}
116
117int kvm_dev_ioctl_check_extension(long ext)
118{
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200119 switch (ext) {
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200120 default:
121 return 0;
122 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100123}
124
125/* Section: vm related */
126/*
127 * Get (and clear) the dirty memory log for a memory slot.
128 */
129int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
130 struct kvm_dirty_log *log)
131{
132 return 0;
133}
134
135long kvm_arch_vm_ioctl(struct file *filp,
136 unsigned int ioctl, unsigned long arg)
137{
138 struct kvm *kvm = filp->private_data;
139 void __user *argp = (void __user *)arg;
140 int r;
141
142 switch (ioctl) {
Carsten Otteba5c1e92008-03-25 18:47:26 +0100143 case KVM_S390_INTERRUPT: {
144 struct kvm_s390_interrupt s390int;
145
146 r = -EFAULT;
147 if (copy_from_user(&s390int, argp, sizeof(s390int)))
148 break;
149 r = kvm_s390_inject_vm(kvm, &s390int);
150 break;
151 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100152 default:
153 r = -EINVAL;
154 }
155
156 return r;
157}
158
159struct kvm *kvm_arch_create_vm(void)
160{
161 struct kvm *kvm;
162 int rc;
163 char debug_name[16];
164
165 rc = s390_enable_sie();
166 if (rc)
167 goto out_nokvm;
168
169 rc = -ENOMEM;
170 kvm = kzalloc(sizeof(struct kvm), GFP_KERNEL);
171 if (!kvm)
172 goto out_nokvm;
173
174 kvm->arch.sca = (struct sca_block *) get_zeroed_page(GFP_KERNEL);
175 if (!kvm->arch.sca)
176 goto out_nosca;
177
178 sprintf(debug_name, "kvm-%u", current->pid);
179
180 kvm->arch.dbf = debug_register(debug_name, 8, 2, 8 * sizeof(long));
181 if (!kvm->arch.dbf)
182 goto out_nodbf;
183
Carsten Otteba5c1e92008-03-25 18:47:26 +0100184 spin_lock_init(&kvm->arch.float_int.lock);
185 INIT_LIST_HEAD(&kvm->arch.float_int.list);
186
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100187 debug_register_view(kvm->arch.dbf, &debug_sprintf_view);
188 VM_EVENT(kvm, 3, "%s", "vm created");
189
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100190 return kvm;
191out_nodbf:
192 free_page((unsigned long)(kvm->arch.sca));
193out_nosca:
194 kfree(kvm);
195out_nokvm:
196 return ERR_PTR(rc);
197}
198
Christian Borntraegerd329c032008-11-26 14:50:27 +0100199void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
200{
201 VCPU_EVENT(vcpu, 3, "%s", "free cpu");
Carsten Otteabf4a712009-05-12 17:21:51 +0200202 if (vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda ==
203 (__u64) vcpu->arch.sie_block)
204 vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda = 0;
205 smp_mb();
Christian Borntraegerd329c032008-11-26 14:50:27 +0100206 free_page((unsigned long)(vcpu->arch.sie_block));
Christian Borntraeger6692cef2008-11-26 14:51:08 +0100207 kvm_vcpu_uninit(vcpu);
Christian Borntraegerd329c032008-11-26 14:50:27 +0100208 kfree(vcpu);
209}
210
211static void kvm_free_vcpus(struct kvm *kvm)
212{
213 unsigned int i;
214
215 for (i = 0; i < KVM_MAX_VCPUS; ++i) {
216 if (kvm->vcpus[i]) {
217 kvm_arch_vcpu_destroy(kvm->vcpus[i]);
218 kvm->vcpus[i] = NULL;
219 }
220 }
221}
222
Sheng Yangad8ba2c2009-01-06 10:03:02 +0800223void kvm_arch_sync_events(struct kvm *kvm)
224{
225}
226
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100227void kvm_arch_destroy_vm(struct kvm *kvm)
228{
Christian Borntraegerd329c032008-11-26 14:50:27 +0100229 kvm_free_vcpus(kvm);
Carsten Ottedfdded72008-06-27 15:05:34 +0200230 kvm_free_physmem(kvm);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100231 free_page((unsigned long)(kvm->arch.sca));
Christian Borntraegerd329c032008-11-26 14:50:27 +0100232 debug_unregister(kvm->arch.dbf);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100233 kfree(kvm);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100234}
235
236/* Section: vcpu related */
237int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
238{
239 return 0;
240}
241
242void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
243{
Christian Borntraeger6692cef2008-11-26 14:51:08 +0100244 /* Nothing todo */
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100245}
246
247void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
248{
249 save_fp_regs(&vcpu->arch.host_fpregs);
250 save_access_regs(vcpu->arch.host_acrs);
251 vcpu->arch.guest_fpregs.fpc &= FPC_VALID_MASK;
252 restore_fp_regs(&vcpu->arch.guest_fpregs);
253 restore_access_regs(vcpu->arch.guest_acrs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100254}
255
256void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
257{
258 save_fp_regs(&vcpu->arch.guest_fpregs);
259 save_access_regs(vcpu->arch.guest_acrs);
260 restore_fp_regs(&vcpu->arch.host_fpregs);
261 restore_access_regs(vcpu->arch.host_acrs);
262}
263
264static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu)
265{
266 /* this equals initial cpu reset in pop, but we don't switch to ESA */
267 vcpu->arch.sie_block->gpsw.mask = 0UL;
268 vcpu->arch.sie_block->gpsw.addr = 0UL;
269 vcpu->arch.sie_block->prefix = 0UL;
270 vcpu->arch.sie_block->ihcpu = 0xffff;
271 vcpu->arch.sie_block->cputm = 0UL;
272 vcpu->arch.sie_block->ckc = 0UL;
273 vcpu->arch.sie_block->todpr = 0;
274 memset(vcpu->arch.sie_block->gcr, 0, 16 * sizeof(__u64));
275 vcpu->arch.sie_block->gcr[0] = 0xE0UL;
276 vcpu->arch.sie_block->gcr[14] = 0xC2000000UL;
277 vcpu->arch.guest_fpregs.fpc = 0;
278 asm volatile("lfpc %0" : : "Q" (vcpu->arch.guest_fpregs.fpc));
279 vcpu->arch.sie_block->gbea = 1;
280}
281
282int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
283{
284 atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH);
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200285 set_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100286 vcpu->arch.sie_block->ecb = 2;
287 vcpu->arch.sie_block->eca = 0xC1002001U;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200288 vcpu->arch.sie_block->fac = (int) (long) facilities;
Christian Borntraegerca872302009-05-12 17:21:49 +0200289 hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
290 tasklet_init(&vcpu->arch.tasklet, kvm_s390_tasklet,
291 (unsigned long) vcpu);
292 vcpu->arch.ckc_timer.function = kvm_s390_idle_wakeup;
Christian Borntraeger453423d2008-03-25 18:47:29 +0100293 get_cpu_id(&vcpu->arch.cpu_id);
Christian Borntraeger92e6ecf2009-03-26 15:23:58 +0100294 vcpu->arch.cpu_id.version = 0xff;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100295 return 0;
296}
297
298struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
299 unsigned int id)
300{
301 struct kvm_vcpu *vcpu = kzalloc(sizeof(struct kvm_vcpu), GFP_KERNEL);
302 int rc = -ENOMEM;
303
304 if (!vcpu)
305 goto out_nomem;
306
Christian Borntraeger180c12f2008-06-27 15:05:40 +0200307 vcpu->arch.sie_block = (struct kvm_s390_sie_block *)
308 get_zeroed_page(GFP_KERNEL);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100309
310 if (!vcpu->arch.sie_block)
311 goto out_free_cpu;
312
313 vcpu->arch.sie_block->icpua = id;
314 BUG_ON(!kvm->arch.sca);
Carsten Otteabf4a712009-05-12 17:21:51 +0200315 if (!kvm->arch.sca->cpu[id].sda)
316 kvm->arch.sca->cpu[id].sda = (__u64) vcpu->arch.sie_block;
317 else
318 BUG_ON(!kvm->vcpus[id]); /* vcpu does already exist */
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100319 vcpu->arch.sie_block->scaoh = (__u32)(((__u64)kvm->arch.sca) >> 32);
320 vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca;
321
Carsten Otteba5c1e92008-03-25 18:47:26 +0100322 spin_lock_init(&vcpu->arch.local_int.lock);
323 INIT_LIST_HEAD(&vcpu->arch.local_int.list);
324 vcpu->arch.local_int.float_int = &kvm->arch.float_int;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200325 spin_lock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100326 kvm->arch.float_int.local_int[id] = &vcpu->arch.local_int;
327 init_waitqueue_head(&vcpu->arch.local_int.wq);
Christian Borntraeger5288fbf2008-03-25 18:47:31 +0100328 vcpu->arch.local_int.cpuflags = &vcpu->arch.sie_block->cpuflags;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200329 spin_unlock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100330
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100331 rc = kvm_vcpu_init(vcpu, kvm, id);
332 if (rc)
333 goto out_free_cpu;
334 VM_EVENT(kvm, 3, "create cpu %d at %p, sie block at %p", id, vcpu,
335 vcpu->arch.sie_block);
336
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100337 return vcpu;
338out_free_cpu:
339 kfree(vcpu);
340out_nomem:
341 return ERR_PTR(rc);
342}
343
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100344int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
345{
346 /* kvm common code refers to this, but never calls it */
347 BUG();
348 return 0;
349}
350
351static int kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu)
352{
353 vcpu_load(vcpu);
354 kvm_s390_vcpu_initial_reset(vcpu);
355 vcpu_put(vcpu);
356 return 0;
357}
358
359int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
360{
361 vcpu_load(vcpu);
362 memcpy(&vcpu->arch.guest_gprs, &regs->gprs, sizeof(regs->gprs));
363 vcpu_put(vcpu);
364 return 0;
365}
366
367int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
368{
369 vcpu_load(vcpu);
370 memcpy(&regs->gprs, &vcpu->arch.guest_gprs, sizeof(regs->gprs));
371 vcpu_put(vcpu);
372 return 0;
373}
374
375int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
376 struct kvm_sregs *sregs)
377{
378 vcpu_load(vcpu);
379 memcpy(&vcpu->arch.guest_acrs, &sregs->acrs, sizeof(sregs->acrs));
380 memcpy(&vcpu->arch.sie_block->gcr, &sregs->crs, sizeof(sregs->crs));
381 vcpu_put(vcpu);
382 return 0;
383}
384
385int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
386 struct kvm_sregs *sregs)
387{
388 vcpu_load(vcpu);
389 memcpy(&sregs->acrs, &vcpu->arch.guest_acrs, sizeof(sregs->acrs));
390 memcpy(&sregs->crs, &vcpu->arch.sie_block->gcr, sizeof(sregs->crs));
391 vcpu_put(vcpu);
392 return 0;
393}
394
395int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
396{
397 vcpu_load(vcpu);
398 memcpy(&vcpu->arch.guest_fpregs.fprs, &fpu->fprs, sizeof(fpu->fprs));
399 vcpu->arch.guest_fpregs.fpc = fpu->fpc;
400 vcpu_put(vcpu);
401 return 0;
402}
403
404int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
405{
406 vcpu_load(vcpu);
407 memcpy(&fpu->fprs, &vcpu->arch.guest_fpregs.fprs, sizeof(fpu->fprs));
408 fpu->fpc = vcpu->arch.guest_fpregs.fpc;
409 vcpu_put(vcpu);
410 return 0;
411}
412
413static int kvm_arch_vcpu_ioctl_set_initial_psw(struct kvm_vcpu *vcpu, psw_t psw)
414{
415 int rc = 0;
416
417 vcpu_load(vcpu);
418 if (atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_RUNNING)
419 rc = -EBUSY;
420 else
421 vcpu->arch.sie_block->gpsw = psw;
422 vcpu_put(vcpu);
423 return rc;
424}
425
426int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
427 struct kvm_translation *tr)
428{
429 return -EINVAL; /* not implemented yet */
430}
431
Jan Kiszkad0bfb942008-12-15 13:52:10 +0100432int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
433 struct kvm_guest_debug *dbg)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100434{
435 return -EINVAL; /* not implemented yet */
436}
437
Marcelo Tosatti62d9f0d2008-04-11 13:24:45 -0300438int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
439 struct kvm_mp_state *mp_state)
440{
441 return -EINVAL; /* not implemented yet */
442}
443
444int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
445 struct kvm_mp_state *mp_state)
446{
447 return -EINVAL; /* not implemented yet */
448}
449
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100450static void __vcpu_run(struct kvm_vcpu *vcpu)
451{
452 memcpy(&vcpu->arch.sie_block->gg14, &vcpu->arch.guest_gprs[14], 16);
453
454 if (need_resched())
455 schedule();
456
Christian Borntraeger71cde582008-05-21 13:37:34 +0200457 if (test_thread_flag(TIF_MCCK_PENDING))
458 s390_handle_mcck();
459
Carsten Otte0ff31862008-05-21 13:37:37 +0200460 kvm_s390_deliver_pending_interrupts(vcpu);
461
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100462 vcpu->arch.sie_block->icptcode = 0;
463 local_irq_disable();
464 kvm_guest_enter();
465 local_irq_enable();
466 VCPU_EVENT(vcpu, 6, "entering sie flags %x",
467 atomic_read(&vcpu->arch.sie_block->cpuflags));
Carsten Otte1f0d0f02008-05-21 13:37:40 +0200468 if (sie64a(vcpu->arch.sie_block, vcpu->arch.guest_gprs)) {
469 VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction");
470 kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
471 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100472 VCPU_EVENT(vcpu, 6, "exit sie icptcode %d",
473 vcpu->arch.sie_block->icptcode);
474 local_irq_disable();
475 kvm_guest_exit();
476 local_irq_enable();
477
478 memcpy(&vcpu->arch.guest_gprs[14], &vcpu->arch.sie_block->gg14, 16);
479}
480
481int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
482{
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100483 int rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100484 sigset_t sigsaved;
485
486 vcpu_load(vcpu);
487
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200488rerun_vcpu:
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200489 if (vcpu->requests)
490 if (test_and_clear_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests))
491 kvm_s390_vcpu_set_mem(vcpu);
492
Carsten Otte51e4d5a2009-05-12 17:21:53 +0200493 /* verify, that memory has been registered */
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200494 if (!vcpu->arch.sie_block->gmslm) {
Carsten Otte51e4d5a2009-05-12 17:21:53 +0200495 vcpu_put(vcpu);
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200496 VCPU_EVENT(vcpu, 3, "%s", "no memory registered to run vcpu");
Carsten Otte51e4d5a2009-05-12 17:21:53 +0200497 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 Ehrhardtb1d16c42009-05-20 15:34:56 +0200530 if (signal_pending(current) && !rc) {
531 kvm_run->exit_reason = KVM_EXIT_INTR;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100532 rc = -EINTR;
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200533 }
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100534
535 if (rc == -ENOTSUPP) {
536 /* intercept cannot be handled in-kernel, prepare kvm-run */
537 kvm_run->exit_reason = KVM_EXIT_S390_SIEIC;
538 kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode;
539 kvm_run->s390_sieic.mask = vcpu->arch.sie_block->gpsw.mask;
540 kvm_run->s390_sieic.addr = vcpu->arch.sie_block->gpsw.addr;
541 kvm_run->s390_sieic.ipa = vcpu->arch.sie_block->ipa;
542 kvm_run->s390_sieic.ipb = vcpu->arch.sie_block->ipb;
543 rc = 0;
544 }
545
546 if (rc == -EREMOTE) {
547 /* intercept was handled, but userspace support is needed
548 * kvm_run has been prepared by the handler */
549 rc = 0;
550 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100551
552 if (vcpu->sigset_active)
553 sigprocmask(SIG_SETMASK, &sigsaved, NULL);
554
555 vcpu_put(vcpu);
556
557 vcpu->stat.exit_userspace++;
Heiko Carstens7e8e6ab2008-04-04 15:12:35 +0200558 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100559}
560
561static int __guestcopy(struct kvm_vcpu *vcpu, u64 guestdest, const void *from,
562 unsigned long n, int prefix)
563{
564 if (prefix)
565 return copy_to_guest(vcpu, guestdest, from, n);
566 else
567 return copy_to_guest_absolute(vcpu, guestdest, from, n);
568}
569
570/*
571 * store status at address
572 * we use have two special cases:
573 * KVM_S390_STORE_STATUS_NOADDR: -> 0x1200 on 64 bit
574 * KVM_S390_STORE_STATUS_PREFIXED: -> prefix
575 */
576int __kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
577{
578 const unsigned char archmode = 1;
579 int prefix;
580
581 if (addr == KVM_S390_STORE_STATUS_NOADDR) {
582 if (copy_to_guest_absolute(vcpu, 163ul, &archmode, 1))
583 return -EFAULT;
584 addr = SAVE_AREA_BASE;
585 prefix = 0;
586 } else if (addr == KVM_S390_STORE_STATUS_PREFIXED) {
587 if (copy_to_guest(vcpu, 163ul, &archmode, 1))
588 return -EFAULT;
589 addr = SAVE_AREA_BASE;
590 prefix = 1;
591 } else
592 prefix = 0;
593
594 if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, fp_regs),
595 vcpu->arch.guest_fpregs.fprs, 128, prefix))
596 return -EFAULT;
597
598 if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, gp_regs),
599 vcpu->arch.guest_gprs, 128, prefix))
600 return -EFAULT;
601
602 if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, psw),
603 &vcpu->arch.sie_block->gpsw, 16, prefix))
604 return -EFAULT;
605
606 if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, pref_reg),
607 &vcpu->arch.sie_block->prefix, 4, prefix))
608 return -EFAULT;
609
610 if (__guestcopy(vcpu,
611 addr + offsetof(struct save_area_s390x, fp_ctrl_reg),
612 &vcpu->arch.guest_fpregs.fpc, 4, prefix))
613 return -EFAULT;
614
615 if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, tod_reg),
616 &vcpu->arch.sie_block->todpr, 4, prefix))
617 return -EFAULT;
618
619 if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, timer),
620 &vcpu->arch.sie_block->cputm, 8, prefix))
621 return -EFAULT;
622
623 if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, clk_cmp),
624 &vcpu->arch.sie_block->ckc, 8, prefix))
625 return -EFAULT;
626
627 if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, acc_regs),
628 &vcpu->arch.guest_acrs, 64, prefix))
629 return -EFAULT;
630
631 if (__guestcopy(vcpu,
632 addr + offsetof(struct save_area_s390x, ctrl_regs),
633 &vcpu->arch.sie_block->gcr, 128, prefix))
634 return -EFAULT;
635 return 0;
636}
637
638static int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
639{
640 int rc;
641
642 vcpu_load(vcpu);
643 rc = __kvm_s390_vcpu_store_status(vcpu, addr);
644 vcpu_put(vcpu);
645 return rc;
646}
647
648long kvm_arch_vcpu_ioctl(struct file *filp,
649 unsigned int ioctl, unsigned long arg)
650{
651 struct kvm_vcpu *vcpu = filp->private_data;
652 void __user *argp = (void __user *)arg;
653
654 switch (ioctl) {
Carsten Otteba5c1e92008-03-25 18:47:26 +0100655 case KVM_S390_INTERRUPT: {
656 struct kvm_s390_interrupt s390int;
657
658 if (copy_from_user(&s390int, argp, sizeof(s390int)))
659 return -EFAULT;
660 return kvm_s390_inject_vcpu(vcpu, &s390int);
661 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100662 case KVM_S390_STORE_STATUS:
663 return kvm_s390_vcpu_store_status(vcpu, arg);
664 case KVM_S390_SET_INITIAL_PSW: {
665 psw_t psw;
666
667 if (copy_from_user(&psw, argp, sizeof(psw)))
668 return -EFAULT;
669 return kvm_arch_vcpu_ioctl_set_initial_psw(vcpu, psw);
670 }
671 case KVM_S390_INITIAL_RESET:
672 return kvm_arch_vcpu_ioctl_initial_reset(vcpu);
673 default:
674 ;
675 }
676 return -EINVAL;
677}
678
679/* Section: memory related */
680int kvm_arch_set_memory_region(struct kvm *kvm,
681 struct kvm_userspace_memory_region *mem,
682 struct kvm_memory_slot old,
683 int user_alloc)
684{
Carsten Otte2668dab2009-05-12 17:21:48 +0200685 int i;
686
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100687 /* A few sanity checks. We can have exactly one memory slot which has
688 to start at guest virtual zero and which has to be located at a
689 page boundary in userland and which has to end at a page boundary.
690 The memory in userland is ok to be fragmented into various different
691 vmas. It is okay to mmap() and munmap() stuff in this slot after
692 doing this call at any time */
693
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200694 if (mem->slot)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100695 return -EINVAL;
696
697 if (mem->guest_phys_addr)
698 return -EINVAL;
699
700 if (mem->userspace_addr & (PAGE_SIZE - 1))
701 return -EINVAL;
702
703 if (mem->memory_size & (PAGE_SIZE - 1))
704 return -EINVAL;
705
Carsten Otte2668dab2009-05-12 17:21:48 +0200706 if (!user_alloc)
707 return -EINVAL;
708
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200709 /* request update of sie control block for all available vcpus */
Carsten Otte2668dab2009-05-12 17:21:48 +0200710 for (i = 0; i < KVM_MAX_VCPUS; ++i) {
711 if (kvm->vcpus[i]) {
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200712 if (test_and_set_bit(KVM_REQ_MMU_RELOAD,
713 &kvm->vcpus[i]->requests))
714 continue;
715 kvm_s390_inject_sigp_stop(kvm->vcpus[i],
716 ACTION_RELOADVCPU_ON_STOP);
Carsten Otte2668dab2009-05-12 17:21:48 +0200717 }
718 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100719
720 return 0;
721}
722
Marcelo Tosatti34d4cb82008-07-10 20:49:31 -0300723void kvm_arch_flush_shadow(struct kvm *kvm)
724{
725}
726
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100727gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn)
728{
729 return gfn;
730}
731
732static int __init kvm_s390_init(void)
733{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200734 int ret;
735 ret = kvm_init(NULL, sizeof(struct kvm_vcpu), THIS_MODULE);
736 if (ret)
737 return ret;
738
739 /*
740 * guests can ask for up to 255+1 double words, we need a full page
741 * to hold the maximum amount of facilites. On the other hand, we
742 * only set facilities that are known to work in KVM.
743 */
744 facilities = (unsigned long long *) get_zeroed_page(GFP_DMA);
745 if (!facilities) {
746 kvm_exit();
747 return -ENOMEM;
748 }
749 stfle(facilities, 1);
750 facilities[0] &= 0xff00fff3f0700000ULL;
751 return 0;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100752}
753
754static void __exit kvm_s390_exit(void)
755{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200756 free_page((unsigned long) facilities);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100757 kvm_exit();
758}
759
760module_init(kvm_s390_init);
761module_exit(kvm_s390_exit);