blob: 189d6bdcac0818abea2d01eb972af920c2f77573 [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 Carstenscbb870c2010-02-26 22:37:43 +010026#include <asm/asm-offsets.h>
Heiko Carstensb0c632d2008-03-25 18:47:20 +010027#include <asm/lowcore.h>
28#include <asm/pgtable.h>
Heiko Carstensf5daba12009-03-26 15:24:01 +010029#include <asm/nmi.h>
Christian Borntraegeref50f7a2009-06-23 17:24:07 +020030#include <asm/system.h>
Christian Borntraeger8f2abe62008-03-25 18:47:23 +010031#include "kvm-s390.h"
Heiko Carstensb0c632d2008-03-25 18:47:20 +010032#include "gaccess.h"
33
34#define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU
35
36struct kvm_stats_debugfs_item debugfs_entries[] = {
37 { "userspace_handled", VCPU_STAT(exit_userspace) },
Christian Borntraeger0eaeafa2008-05-07 09:22:53 +020038 { "exit_null", VCPU_STAT(exit_null) },
Christian Borntraeger8f2abe62008-03-25 18:47:23 +010039 { "exit_validity", VCPU_STAT(exit_validity) },
40 { "exit_stop_request", VCPU_STAT(exit_stop_request) },
41 { "exit_external_request", VCPU_STAT(exit_external_request) },
42 { "exit_external_interrupt", VCPU_STAT(exit_external_interrupt) },
Carsten Otteba5c1e92008-03-25 18:47:26 +010043 { "exit_instruction", VCPU_STAT(exit_instruction) },
44 { "exit_program_interruption", VCPU_STAT(exit_program_interruption) },
45 { "exit_instr_and_program_int", VCPU_STAT(exit_instr_and_program) },
Christian Borntraegerf5e10b02008-07-25 15:52:44 +020046 { "instruction_lctlg", VCPU_STAT(instruction_lctlg) },
Carsten Otteba5c1e92008-03-25 18:47:26 +010047 { "instruction_lctl", VCPU_STAT(instruction_lctl) },
48 { "deliver_emergency_signal", VCPU_STAT(deliver_emergency_signal) },
49 { "deliver_service_signal", VCPU_STAT(deliver_service_signal) },
50 { "deliver_virtio_interrupt", VCPU_STAT(deliver_virtio_interrupt) },
51 { "deliver_stop_signal", VCPU_STAT(deliver_stop_signal) },
52 { "deliver_prefix_signal", VCPU_STAT(deliver_prefix_signal) },
53 { "deliver_restart_signal", VCPU_STAT(deliver_restart_signal) },
54 { "deliver_program_interruption", VCPU_STAT(deliver_program_int) },
55 { "exit_wait_state", VCPU_STAT(exit_wait_state) },
Christian Borntraeger453423d2008-03-25 18:47:29 +010056 { "instruction_stidp", VCPU_STAT(instruction_stidp) },
57 { "instruction_spx", VCPU_STAT(instruction_spx) },
58 { "instruction_stpx", VCPU_STAT(instruction_stpx) },
59 { "instruction_stap", VCPU_STAT(instruction_stap) },
60 { "instruction_storage_key", VCPU_STAT(instruction_storage_key) },
61 { "instruction_stsch", VCPU_STAT(instruction_stsch) },
62 { "instruction_chsc", VCPU_STAT(instruction_chsc) },
63 { "instruction_stsi", VCPU_STAT(instruction_stsi) },
64 { "instruction_stfl", VCPU_STAT(instruction_stfl) },
Christian Borntraegerbb25b9b2011-07-24 10:48:17 +020065 { "instruction_tprot", VCPU_STAT(instruction_tprot) },
Christian Borntraeger5288fbf2008-03-25 18:47:31 +010066 { "instruction_sigp_sense", VCPU_STAT(instruction_sigp_sense) },
67 { "instruction_sigp_emergency", VCPU_STAT(instruction_sigp_emergency) },
68 { "instruction_sigp_stop", VCPU_STAT(instruction_sigp_stop) },
69 { "instruction_sigp_set_arch", VCPU_STAT(instruction_sigp_arch) },
70 { "instruction_sigp_set_prefix", VCPU_STAT(instruction_sigp_prefix) },
71 { "instruction_sigp_restart", VCPU_STAT(instruction_sigp_restart) },
Christian Borntraeger388186b2011-10-30 15:17:03 +010072 { "diagnose_10", VCPU_STAT(diagnose_10) },
Christian Borntraegere28acfe2008-03-25 18:47:34 +010073 { "diagnose_44", VCPU_STAT(diagnose_44) },
Heiko Carstensb0c632d2008-03-25 18:47:20 +010074 { NULL }
75};
76
Christian Borntraegeref50f7a2009-06-23 17:24:07 +020077static unsigned long long *facilities;
Heiko Carstensb0c632d2008-03-25 18:47:20 +010078
79/* Section: not file related */
Alexander Graf10474ae2009-09-15 11:37:46 +020080int kvm_arch_hardware_enable(void *garbage)
Heiko Carstensb0c632d2008-03-25 18:47:20 +010081{
82 /* every s390 is virtualization enabled ;-) */
Alexander Graf10474ae2009-09-15 11:37:46 +020083 return 0;
Heiko Carstensb0c632d2008-03-25 18:47:20 +010084}
85
86void kvm_arch_hardware_disable(void *garbage)
87{
88}
89
Heiko Carstensb0c632d2008-03-25 18:47:20 +010090int kvm_arch_hardware_setup(void)
91{
92 return 0;
93}
94
95void kvm_arch_hardware_unsetup(void)
96{
97}
98
99void kvm_arch_check_processor_compat(void *rtn)
100{
101}
102
103int kvm_arch_init(void *opaque)
104{
105 return 0;
106}
107
108void kvm_arch_exit(void)
109{
110}
111
112/* Section: device related */
113long kvm_arch_dev_ioctl(struct file *filp,
114 unsigned int ioctl, unsigned long arg)
115{
116 if (ioctl == KVM_S390_ENABLE_SIE)
117 return s390_enable_sie();
118 return -EINVAL;
119}
120
121int kvm_dev_ioctl_check_extension(long ext)
122{
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100123 int r;
124
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200125 switch (ext) {
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100126 case KVM_CAP_S390_PSW:
Christian Borntraegerb6cf8782011-09-20 17:07:29 +0200127 case KVM_CAP_S390_GMAP:
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100128 r = 1;
129 break;
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200130 default:
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100131 r = 0;
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200132 }
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100133 return r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100134}
135
136/* Section: vm related */
137/*
138 * Get (and clear) the dirty memory log for a memory slot.
139 */
140int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
141 struct kvm_dirty_log *log)
142{
143 return 0;
144}
145
146long kvm_arch_vm_ioctl(struct file *filp,
147 unsigned int ioctl, unsigned long arg)
148{
149 struct kvm *kvm = filp->private_data;
150 void __user *argp = (void __user *)arg;
151 int r;
152
153 switch (ioctl) {
Carsten Otteba5c1e92008-03-25 18:47:26 +0100154 case KVM_S390_INTERRUPT: {
155 struct kvm_s390_interrupt s390int;
156
157 r = -EFAULT;
158 if (copy_from_user(&s390int, argp, sizeof(s390int)))
159 break;
160 r = kvm_s390_inject_vm(kvm, &s390int);
161 break;
162 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100163 default:
Avi Kivity367e1312009-08-26 14:57:07 +0300164 r = -ENOTTY;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100165 }
166
167 return r;
168}
169
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100170int kvm_arch_init_vm(struct kvm *kvm)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100171{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100172 int rc;
173 char debug_name[16];
174
175 rc = s390_enable_sie();
176 if (rc)
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100177 goto out_err;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100178
179 kvm->arch.sca = (struct sca_block *) get_zeroed_page(GFP_KERNEL);
180 if (!kvm->arch.sca)
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100181 goto out_err;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100182
183 sprintf(debug_name, "kvm-%u", current->pid);
184
185 kvm->arch.dbf = debug_register(debug_name, 8, 2, 8 * sizeof(long));
186 if (!kvm->arch.dbf)
187 goto out_nodbf;
188
Carsten Otteba5c1e92008-03-25 18:47:26 +0100189 spin_lock_init(&kvm->arch.float_int.lock);
190 INIT_LIST_HEAD(&kvm->arch.float_int.list);
191
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100192 debug_register_view(kvm->arch.dbf, &debug_sprintf_view);
193 VM_EVENT(kvm, 3, "%s", "vm created");
194
Carsten Otte598841c2011-07-24 10:48:21 +0200195 kvm->arch.gmap = gmap_alloc(current->mm);
196 if (!kvm->arch.gmap)
197 goto out_nogmap;
198
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100199 return 0;
Carsten Otte598841c2011-07-24 10:48:21 +0200200out_nogmap:
201 debug_unregister(kvm->arch.dbf);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100202out_nodbf:
203 free_page((unsigned long)(kvm->arch.sca));
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100204out_err:
205 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100206}
207
Christian Borntraegerd329c032008-11-26 14:50:27 +0100208void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
209{
210 VCPU_EVENT(vcpu, 3, "%s", "free cpu");
Christian Borntraegerfc345312010-06-17 23:16:20 +0200211 clear_bit(63 - vcpu->vcpu_id, (unsigned long *) &vcpu->kvm->arch.sca->mcn);
Carsten Otteabf4a712009-05-12 17:21:51 +0200212 if (vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda ==
213 (__u64) vcpu->arch.sie_block)
214 vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda = 0;
215 smp_mb();
Christian Borntraegerd329c032008-11-26 14:50:27 +0100216 free_page((unsigned long)(vcpu->arch.sie_block));
Christian Borntraeger6692cef2008-11-26 14:51:08 +0100217 kvm_vcpu_uninit(vcpu);
Christian Borntraegerd329c032008-11-26 14:50:27 +0100218 kfree(vcpu);
219}
220
221static void kvm_free_vcpus(struct kvm *kvm)
222{
223 unsigned int i;
Gleb Natapov988a2ca2009-06-09 15:56:29 +0300224 struct kvm_vcpu *vcpu;
Christian Borntraegerd329c032008-11-26 14:50:27 +0100225
Gleb Natapov988a2ca2009-06-09 15:56:29 +0300226 kvm_for_each_vcpu(i, vcpu, kvm)
227 kvm_arch_vcpu_destroy(vcpu);
228
229 mutex_lock(&kvm->lock);
230 for (i = 0; i < atomic_read(&kvm->online_vcpus); i++)
231 kvm->vcpus[i] = NULL;
232
233 atomic_set(&kvm->online_vcpus, 0);
234 mutex_unlock(&kvm->lock);
Christian Borntraegerd329c032008-11-26 14:50:27 +0100235}
236
Sheng Yangad8ba2c2009-01-06 10:03:02 +0800237void kvm_arch_sync_events(struct kvm *kvm)
238{
239}
240
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100241void kvm_arch_destroy_vm(struct kvm *kvm)
242{
Christian Borntraegerd329c032008-11-26 14:50:27 +0100243 kvm_free_vcpus(kvm);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100244 free_page((unsigned long)(kvm->arch.sca));
Christian Borntraegerd329c032008-11-26 14:50:27 +0100245 debug_unregister(kvm->arch.dbf);
Carsten Otte598841c2011-07-24 10:48:21 +0200246 gmap_free(kvm->arch.gmap);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100247}
248
249/* Section: vcpu related */
250int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
251{
Carsten Otte598841c2011-07-24 10:48:21 +0200252 vcpu->arch.gmap = vcpu->kvm->arch.gmap;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100253 return 0;
254}
255
256void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
257{
Christian Borntraeger6692cef2008-11-26 14:51:08 +0100258 /* Nothing todo */
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100259}
260
261void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
262{
263 save_fp_regs(&vcpu->arch.host_fpregs);
264 save_access_regs(vcpu->arch.host_acrs);
265 vcpu->arch.guest_fpregs.fpc &= FPC_VALID_MASK;
266 restore_fp_regs(&vcpu->arch.guest_fpregs);
267 restore_access_regs(vcpu->arch.guest_acrs);
Christian Borntraeger480e5922011-09-20 17:07:28 +0200268 gmap_enable(vcpu->arch.gmap);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100269}
270
271void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
272{
Christian Borntraeger480e5922011-09-20 17:07:28 +0200273 gmap_disable(vcpu->arch.gmap);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100274 save_fp_regs(&vcpu->arch.guest_fpregs);
275 save_access_regs(vcpu->arch.guest_acrs);
276 restore_fp_regs(&vcpu->arch.host_fpregs);
277 restore_access_regs(vcpu->arch.host_acrs);
278}
279
280static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu)
281{
282 /* this equals initial cpu reset in pop, but we don't switch to ESA */
283 vcpu->arch.sie_block->gpsw.mask = 0UL;
284 vcpu->arch.sie_block->gpsw.addr = 0UL;
285 vcpu->arch.sie_block->prefix = 0UL;
286 vcpu->arch.sie_block->ihcpu = 0xffff;
287 vcpu->arch.sie_block->cputm = 0UL;
288 vcpu->arch.sie_block->ckc = 0UL;
289 vcpu->arch.sie_block->todpr = 0;
290 memset(vcpu->arch.sie_block->gcr, 0, 16 * sizeof(__u64));
291 vcpu->arch.sie_block->gcr[0] = 0xE0UL;
292 vcpu->arch.sie_block->gcr[14] = 0xC2000000UL;
293 vcpu->arch.guest_fpregs.fpc = 0;
294 asm volatile("lfpc %0" : : "Q" (vcpu->arch.guest_fpregs.fpc));
295 vcpu->arch.sie_block->gbea = 1;
296}
297
298int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
299{
Carsten Otte598841c2011-07-24 10:48:21 +0200300 atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH | CPUSTAT_SM);
Christian Borntraegerfc345312010-06-17 23:16:20 +0200301 vcpu->arch.sie_block->ecb = 6;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100302 vcpu->arch.sie_block->eca = 0xC1002001U;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200303 vcpu->arch.sie_block->fac = (int) (long) facilities;
Christian Borntraegerca872302009-05-12 17:21:49 +0200304 hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
305 tasklet_init(&vcpu->arch.tasklet, kvm_s390_tasklet,
306 (unsigned long) vcpu);
307 vcpu->arch.ckc_timer.function = kvm_s390_idle_wakeup;
Christian Borntraeger453423d2008-03-25 18:47:29 +0100308 get_cpu_id(&vcpu->arch.cpu_id);
Christian Borntraeger92e6ecf2009-03-26 15:23:58 +0100309 vcpu->arch.cpu_id.version = 0xff;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100310 return 0;
311}
312
313struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
314 unsigned int id)
315{
316 struct kvm_vcpu *vcpu = kzalloc(sizeof(struct kvm_vcpu), GFP_KERNEL);
317 int rc = -ENOMEM;
318
319 if (!vcpu)
320 goto out_nomem;
321
Christian Borntraeger180c12f2008-06-27 15:05:40 +0200322 vcpu->arch.sie_block = (struct kvm_s390_sie_block *)
323 get_zeroed_page(GFP_KERNEL);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100324
325 if (!vcpu->arch.sie_block)
326 goto out_free_cpu;
327
328 vcpu->arch.sie_block->icpua = id;
329 BUG_ON(!kvm->arch.sca);
Carsten Otteabf4a712009-05-12 17:21:51 +0200330 if (!kvm->arch.sca->cpu[id].sda)
331 kvm->arch.sca->cpu[id].sda = (__u64) vcpu->arch.sie_block;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100332 vcpu->arch.sie_block->scaoh = (__u32)(((__u64)kvm->arch.sca) >> 32);
333 vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca;
Christian Borntraegerfc345312010-06-17 23:16:20 +0200334 set_bit(63 - id, (unsigned long *) &kvm->arch.sca->mcn);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100335
Carsten Otteba5c1e92008-03-25 18:47:26 +0100336 spin_lock_init(&vcpu->arch.local_int.lock);
337 INIT_LIST_HEAD(&vcpu->arch.local_int.list);
338 vcpu->arch.local_int.float_int = &kvm->arch.float_int;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200339 spin_lock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100340 kvm->arch.float_int.local_int[id] = &vcpu->arch.local_int;
341 init_waitqueue_head(&vcpu->arch.local_int.wq);
Christian Borntraeger5288fbf2008-03-25 18:47:31 +0100342 vcpu->arch.local_int.cpuflags = &vcpu->arch.sie_block->cpuflags;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200343 spin_unlock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100344
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100345 rc = kvm_vcpu_init(vcpu, kvm, id);
346 if (rc)
Wei Yongjun7b06bf22010-03-09 14:37:53 +0800347 goto out_free_sie_block;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100348 VM_EVENT(kvm, 3, "create cpu %d at %p, sie block at %p", id, vcpu,
349 vcpu->arch.sie_block);
350
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100351 return vcpu;
Wei Yongjun7b06bf22010-03-09 14:37:53 +0800352out_free_sie_block:
353 free_page((unsigned long)(vcpu->arch.sie_block));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100354out_free_cpu:
355 kfree(vcpu);
356out_nomem:
357 return ERR_PTR(rc);
358}
359
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100360int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
361{
362 /* kvm common code refers to this, but never calls it */
363 BUG();
364 return 0;
365}
366
367static int kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu)
368{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100369 kvm_s390_vcpu_initial_reset(vcpu);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100370 return 0;
371}
372
373int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
374{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100375 memcpy(&vcpu->arch.guest_gprs, &regs->gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100376 return 0;
377}
378
379int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
380{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100381 memcpy(&regs->gprs, &vcpu->arch.guest_gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100382 return 0;
383}
384
385int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
386 struct kvm_sregs *sregs)
387{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100388 memcpy(&vcpu->arch.guest_acrs, &sregs->acrs, sizeof(sregs->acrs));
389 memcpy(&vcpu->arch.sie_block->gcr, &sregs->crs, sizeof(sregs->crs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100390 return 0;
391}
392
393int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
394 struct kvm_sregs *sregs)
395{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100396 memcpy(&sregs->acrs, &vcpu->arch.guest_acrs, sizeof(sregs->acrs));
397 memcpy(&sregs->crs, &vcpu->arch.sie_block->gcr, sizeof(sregs->crs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100398 return 0;
399}
400
401int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
402{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100403 memcpy(&vcpu->arch.guest_fpregs.fprs, &fpu->fprs, sizeof(fpu->fprs));
404 vcpu->arch.guest_fpregs.fpc = fpu->fpc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100405 return 0;
406}
407
408int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
409{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100410 memcpy(&fpu->fprs, &vcpu->arch.guest_fpregs.fprs, sizeof(fpu->fprs));
411 fpu->fpc = vcpu->arch.guest_fpregs.fpc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100412 return 0;
413}
414
415static int kvm_arch_vcpu_ioctl_set_initial_psw(struct kvm_vcpu *vcpu, psw_t psw)
416{
417 int rc = 0;
418
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100419 if (atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_RUNNING)
420 rc = -EBUSY;
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100421 else {
422 vcpu->run->psw_mask = psw.mask;
423 vcpu->run->psw_addr = psw.addr;
424 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100425 return rc;
426}
427
428int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
429 struct kvm_translation *tr)
430{
431 return -EINVAL; /* not implemented yet */
432}
433
Jan Kiszkad0bfb942008-12-15 13:52:10 +0100434int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
435 struct kvm_guest_debug *dbg)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100436{
437 return -EINVAL; /* not implemented yet */
438}
439
Marcelo Tosatti62d9f0d2008-04-11 13:24:45 -0300440int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
441 struct kvm_mp_state *mp_state)
442{
443 return -EINVAL; /* not implemented yet */
444}
445
446int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
447 struct kvm_mp_state *mp_state)
448{
449 return -EINVAL; /* not implemented yet */
450}
451
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100452static void __vcpu_run(struct kvm_vcpu *vcpu)
453{
454 memcpy(&vcpu->arch.sie_block->gg14, &vcpu->arch.guest_gprs[14], 16);
455
456 if (need_resched())
457 schedule();
458
Christian Borntraeger71cde582008-05-21 13:37:34 +0200459 if (test_thread_flag(TIF_MCCK_PENDING))
460 s390_handle_mcck();
461
Carsten Otte0ff31862008-05-21 13:37:37 +0200462 kvm_s390_deliver_pending_interrupts(vcpu);
463
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100464 vcpu->arch.sie_block->icptcode = 0;
465 local_irq_disable();
466 kvm_guest_enter();
467 local_irq_enable();
468 VCPU_EVENT(vcpu, 6, "entering sie flags %x",
469 atomic_read(&vcpu->arch.sie_block->cpuflags));
Carsten Otte1f0d0f02008-05-21 13:37:40 +0200470 if (sie64a(vcpu->arch.sie_block, vcpu->arch.guest_gprs)) {
471 VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction");
472 kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
473 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100474 VCPU_EVENT(vcpu, 6, "exit sie icptcode %d",
475 vcpu->arch.sie_block->icptcode);
476 local_irq_disable();
477 kvm_guest_exit();
478 local_irq_enable();
479
480 memcpy(&vcpu->arch.guest_gprs[14], &vcpu->arch.sie_block->gg14, 16);
481}
482
483int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
484{
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100485 int rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100486 sigset_t sigsaved;
487
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200488rerun_vcpu:
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100489 if (vcpu->sigset_active)
490 sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
491
492 atomic_set_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
493
Carsten Otteba5c1e92008-03-25 18:47:26 +0100494 BUG_ON(vcpu->kvm->arch.float_int.local_int[vcpu->vcpu_id] == NULL);
495
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100496 switch (kvm_run->exit_reason) {
497 case KVM_EXIT_S390_SIEIC:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100498 case KVM_EXIT_UNKNOWN:
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200499 case KVM_EXIT_INTR:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100500 case KVM_EXIT_S390_RESET:
501 break;
502 default:
503 BUG();
504 }
505
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100506 vcpu->arch.sie_block->gpsw.mask = kvm_run->psw_mask;
507 vcpu->arch.sie_block->gpsw.addr = kvm_run->psw_addr;
508
Heiko Carstensdab4079d2009-06-12 10:26:32 +0200509 might_fault();
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100510
511 do {
512 __vcpu_run(vcpu);
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100513 rc = kvm_handle_sie_intercept(vcpu);
514 } while (!signal_pending(current) && !rc);
515
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200516 if (rc == SIE_INTERCEPT_RERUNVCPU)
517 goto rerun_vcpu;
518
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200519 if (signal_pending(current) && !rc) {
520 kvm_run->exit_reason = KVM_EXIT_INTR;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100521 rc = -EINTR;
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200522 }
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100523
Heiko Carstensb8e660b2010-02-26 22:37:41 +0100524 if (rc == -EOPNOTSUPP) {
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100525 /* intercept cannot be handled in-kernel, prepare kvm-run */
526 kvm_run->exit_reason = KVM_EXIT_S390_SIEIC;
527 kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100528 kvm_run->s390_sieic.ipa = vcpu->arch.sie_block->ipa;
529 kvm_run->s390_sieic.ipb = vcpu->arch.sie_block->ipb;
530 rc = 0;
531 }
532
533 if (rc == -EREMOTE) {
534 /* intercept was handled, but userspace support is needed
535 * kvm_run has been prepared by the handler */
536 rc = 0;
537 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100538
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100539 kvm_run->psw_mask = vcpu->arch.sie_block->gpsw.mask;
540 kvm_run->psw_addr = vcpu->arch.sie_block->gpsw.addr;
541
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100542 if (vcpu->sigset_active)
543 sigprocmask(SIG_SETMASK, &sigsaved, NULL);
544
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100545 vcpu->stat.exit_userspace++;
Heiko Carstens7e8e6ab2008-04-04 15:12:35 +0200546 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100547}
548
Carsten Otte092670c2011-07-24 10:48:22 +0200549static int __guestcopy(struct kvm_vcpu *vcpu, u64 guestdest, void *from,
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100550 unsigned long n, int prefix)
551{
552 if (prefix)
553 return copy_to_guest(vcpu, guestdest, from, n);
554 else
555 return copy_to_guest_absolute(vcpu, guestdest, from, n);
556}
557
558/*
559 * store status at address
560 * we use have two special cases:
561 * KVM_S390_STORE_STATUS_NOADDR: -> 0x1200 on 64 bit
562 * KVM_S390_STORE_STATUS_PREFIXED: -> prefix
563 */
Christian Borntraeger971eb772010-06-12 08:54:13 +0200564int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100565{
Carsten Otte092670c2011-07-24 10:48:22 +0200566 unsigned char archmode = 1;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100567 int prefix;
568
569 if (addr == KVM_S390_STORE_STATUS_NOADDR) {
570 if (copy_to_guest_absolute(vcpu, 163ul, &archmode, 1))
571 return -EFAULT;
572 addr = SAVE_AREA_BASE;
573 prefix = 0;
574 } else if (addr == KVM_S390_STORE_STATUS_PREFIXED) {
575 if (copy_to_guest(vcpu, 163ul, &archmode, 1))
576 return -EFAULT;
577 addr = SAVE_AREA_BASE;
578 prefix = 1;
579 } else
580 prefix = 0;
581
Heiko Carstensf64ca212010-02-26 22:37:32 +0100582 if (__guestcopy(vcpu, addr + offsetof(struct save_area, fp_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100583 vcpu->arch.guest_fpregs.fprs, 128, prefix))
584 return -EFAULT;
585
Heiko Carstensf64ca212010-02-26 22:37:32 +0100586 if (__guestcopy(vcpu, addr + offsetof(struct save_area, gp_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100587 vcpu->arch.guest_gprs, 128, prefix))
588 return -EFAULT;
589
Heiko Carstensf64ca212010-02-26 22:37:32 +0100590 if (__guestcopy(vcpu, addr + offsetof(struct save_area, psw),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100591 &vcpu->arch.sie_block->gpsw, 16, prefix))
592 return -EFAULT;
593
Heiko Carstensf64ca212010-02-26 22:37:32 +0100594 if (__guestcopy(vcpu, addr + offsetof(struct save_area, pref_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100595 &vcpu->arch.sie_block->prefix, 4, prefix))
596 return -EFAULT;
597
598 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100599 addr + offsetof(struct save_area, fp_ctrl_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100600 &vcpu->arch.guest_fpregs.fpc, 4, prefix))
601 return -EFAULT;
602
Heiko Carstensf64ca212010-02-26 22:37:32 +0100603 if (__guestcopy(vcpu, addr + offsetof(struct save_area, tod_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100604 &vcpu->arch.sie_block->todpr, 4, prefix))
605 return -EFAULT;
606
Heiko Carstensf64ca212010-02-26 22:37:32 +0100607 if (__guestcopy(vcpu, addr + offsetof(struct save_area, timer),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100608 &vcpu->arch.sie_block->cputm, 8, prefix))
609 return -EFAULT;
610
Heiko Carstensf64ca212010-02-26 22:37:32 +0100611 if (__guestcopy(vcpu, addr + offsetof(struct save_area, clk_cmp),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100612 &vcpu->arch.sie_block->ckc, 8, prefix))
613 return -EFAULT;
614
Heiko Carstensf64ca212010-02-26 22:37:32 +0100615 if (__guestcopy(vcpu, addr + offsetof(struct save_area, acc_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100616 &vcpu->arch.guest_acrs, 64, prefix))
617 return -EFAULT;
618
619 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100620 addr + offsetof(struct save_area, ctrl_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100621 &vcpu->arch.sie_block->gcr, 128, prefix))
622 return -EFAULT;
623 return 0;
624}
625
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100626long kvm_arch_vcpu_ioctl(struct file *filp,
627 unsigned int ioctl, unsigned long arg)
628{
629 struct kvm_vcpu *vcpu = filp->private_data;
630 void __user *argp = (void __user *)arg;
Avi Kivitybc923cc2010-05-13 12:21:46 +0300631 long r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100632
Avi Kivity93736622010-05-13 12:35:17 +0300633 switch (ioctl) {
634 case KVM_S390_INTERRUPT: {
Carsten Otteba5c1e92008-03-25 18:47:26 +0100635 struct kvm_s390_interrupt s390int;
636
Avi Kivity93736622010-05-13 12:35:17 +0300637 r = -EFAULT;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100638 if (copy_from_user(&s390int, argp, sizeof(s390int)))
Avi Kivity93736622010-05-13 12:35:17 +0300639 break;
640 r = kvm_s390_inject_vcpu(vcpu, &s390int);
641 break;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100642 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100643 case KVM_S390_STORE_STATUS:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300644 r = kvm_s390_vcpu_store_status(vcpu, arg);
645 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100646 case KVM_S390_SET_INITIAL_PSW: {
647 psw_t psw;
648
Avi Kivitybc923cc2010-05-13 12:21:46 +0300649 r = -EFAULT;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100650 if (copy_from_user(&psw, argp, sizeof(psw)))
Avi Kivitybc923cc2010-05-13 12:21:46 +0300651 break;
652 r = kvm_arch_vcpu_ioctl_set_initial_psw(vcpu, psw);
653 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100654 }
655 case KVM_S390_INITIAL_RESET:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300656 r = kvm_arch_vcpu_ioctl_initial_reset(vcpu);
657 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100658 default:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300659 r = -EINVAL;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100660 }
Avi Kivitybc923cc2010-05-13 12:21:46 +0300661 return r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100662}
663
664/* Section: memory related */
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200665int kvm_arch_prepare_memory_region(struct kvm *kvm,
666 struct kvm_memory_slot *memslot,
667 struct kvm_memory_slot old,
668 struct kvm_userspace_memory_region *mem,
669 int user_alloc)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100670{
671 /* A few sanity checks. We can have exactly one memory slot which has
672 to start at guest virtual zero and which has to be located at a
673 page boundary in userland and which has to end at a page boundary.
674 The memory in userland is ok to be fragmented into various different
675 vmas. It is okay to mmap() and munmap() stuff in this slot after
676 doing this call at any time */
677
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200678 if (mem->slot)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100679 return -EINVAL;
680
681 if (mem->guest_phys_addr)
682 return -EINVAL;
683
Carsten Otte598841c2011-07-24 10:48:21 +0200684 if (mem->userspace_addr & 0xffffful)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100685 return -EINVAL;
686
Carsten Otte598841c2011-07-24 10:48:21 +0200687 if (mem->memory_size & 0xffffful)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100688 return -EINVAL;
689
Carsten Otte2668dab2009-05-12 17:21:48 +0200690 if (!user_alloc)
691 return -EINVAL;
692
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200693 return 0;
694}
695
696void kvm_arch_commit_memory_region(struct kvm *kvm,
697 struct kvm_userspace_memory_region *mem,
698 struct kvm_memory_slot old,
699 int user_alloc)
700{
Carsten Ottef7850c92011-07-24 10:48:23 +0200701 int rc;
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200702
Carsten Otte598841c2011-07-24 10:48:21 +0200703
704 rc = gmap_map_segment(kvm->arch.gmap, mem->userspace_addr,
705 mem->guest_phys_addr, mem->memory_size);
706 if (rc)
Carsten Ottef7850c92011-07-24 10:48:23 +0200707 printk(KERN_WARNING "kvm-s390: failed to commit memory region\n");
Carsten Otte598841c2011-07-24 10:48:21 +0200708 return;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100709}
710
Marcelo Tosatti34d4cb82008-07-10 20:49:31 -0300711void kvm_arch_flush_shadow(struct kvm *kvm)
712{
713}
714
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100715static int __init kvm_s390_init(void)
716{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200717 int ret;
Avi Kivity0ee75be2010-04-28 15:39:01 +0300718 ret = kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE);
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200719 if (ret)
720 return ret;
721
722 /*
723 * guests can ask for up to 255+1 double words, we need a full page
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300724 * to hold the maximum amount of facilities. On the other hand, we
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200725 * only set facilities that are known to work in KVM.
726 */
Heiko Carstensc2f0e8c2010-06-08 18:58:09 +0200727 facilities = (unsigned long long *) get_zeroed_page(GFP_KERNEL|GFP_DMA);
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200728 if (!facilities) {
729 kvm_exit();
730 return -ENOMEM;
731 }
Martin Schwidefsky14375bc2010-10-25 16:10:51 +0200732 memcpy(facilities, S390_lowcore.stfle_fac_list, 16);
Christian Borntraeger6d00d002010-10-25 16:10:48 +0200733 facilities[0] &= 0xff00fff3f47c0000ULL;
Christian Borntraeger9950f8b2011-06-06 14:14:39 +0200734 facilities[1] &= 0x201c000000000000ULL;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200735 return 0;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100736}
737
738static void __exit kvm_s390_exit(void)
739{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200740 free_page((unsigned long) facilities);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100741 kvm_exit();
742}
743
744module_init(kvm_s390_init);
745module_exit(kvm_s390_exit);