blob: 67345ae7ce8d967a6e952070e2969d10ad7dcd5e [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 Borntraeger5288fbf2008-03-25 18:47:31 +010065 { "instruction_sigp_sense", VCPU_STAT(instruction_sigp_sense) },
66 { "instruction_sigp_emergency", VCPU_STAT(instruction_sigp_emergency) },
67 { "instruction_sigp_stop", VCPU_STAT(instruction_sigp_stop) },
68 { "instruction_sigp_set_arch", VCPU_STAT(instruction_sigp_arch) },
69 { "instruction_sigp_set_prefix", VCPU_STAT(instruction_sigp_prefix) },
70 { "instruction_sigp_restart", VCPU_STAT(instruction_sigp_restart) },
Christian Borntraegere28acfe2008-03-25 18:47:34 +010071 { "diagnose_44", VCPU_STAT(diagnose_44) },
Heiko Carstensb0c632d2008-03-25 18:47:20 +010072 { NULL }
73};
74
Christian Borntraegeref50f7a2009-06-23 17:24:07 +020075static unsigned long long *facilities;
Heiko Carstensb0c632d2008-03-25 18:47:20 +010076
77/* Section: not file related */
Alexander Graf10474ae2009-09-15 11:37:46 +020078int kvm_arch_hardware_enable(void *garbage)
Heiko Carstensb0c632d2008-03-25 18:47:20 +010079{
80 /* every s390 is virtualization enabled ;-) */
Alexander Graf10474ae2009-09-15 11:37:46 +020081 return 0;
Heiko Carstensb0c632d2008-03-25 18:47:20 +010082}
83
84void kvm_arch_hardware_disable(void *garbage)
85{
86}
87
Heiko Carstensb0c632d2008-03-25 18:47:20 +010088int kvm_arch_hardware_setup(void)
89{
90 return 0;
91}
92
93void kvm_arch_hardware_unsetup(void)
94{
95}
96
97void kvm_arch_check_processor_compat(void *rtn)
98{
99}
100
101int kvm_arch_init(void *opaque)
102{
103 return 0;
104}
105
106void kvm_arch_exit(void)
107{
108}
109
110/* Section: device related */
111long kvm_arch_dev_ioctl(struct file *filp,
112 unsigned int ioctl, unsigned long arg)
113{
114 if (ioctl == KVM_S390_ENABLE_SIE)
115 return s390_enable_sie();
116 return -EINVAL;
117}
118
119int kvm_dev_ioctl_check_extension(long ext)
120{
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100121 int r;
122
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200123 switch (ext) {
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100124 case KVM_CAP_S390_PSW:
125 r = 1;
126 break;
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200127 default:
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100128 r = 0;
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200129 }
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100130 return r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100131}
132
133/* Section: vm related */
134/*
135 * Get (and clear) the dirty memory log for a memory slot.
136 */
137int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
138 struct kvm_dirty_log *log)
139{
140 return 0;
141}
142
143long kvm_arch_vm_ioctl(struct file *filp,
144 unsigned int ioctl, unsigned long arg)
145{
146 struct kvm *kvm = filp->private_data;
147 void __user *argp = (void __user *)arg;
148 int r;
149
150 switch (ioctl) {
Carsten Otteba5c1e92008-03-25 18:47:26 +0100151 case KVM_S390_INTERRUPT: {
152 struct kvm_s390_interrupt s390int;
153
154 r = -EFAULT;
155 if (copy_from_user(&s390int, argp, sizeof(s390int)))
156 break;
157 r = kvm_s390_inject_vm(kvm, &s390int);
158 break;
159 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100160 default:
Avi Kivity367e1312009-08-26 14:57:07 +0300161 r = -ENOTTY;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100162 }
163
164 return r;
165}
166
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100167int kvm_arch_init_vm(struct kvm *kvm)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100168{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100169 int rc;
170 char debug_name[16];
171
172 rc = s390_enable_sie();
173 if (rc)
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100174 goto out_err;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100175
176 kvm->arch.sca = (struct sca_block *) get_zeroed_page(GFP_KERNEL);
177 if (!kvm->arch.sca)
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100178 goto out_err;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100179
180 sprintf(debug_name, "kvm-%u", current->pid);
181
182 kvm->arch.dbf = debug_register(debug_name, 8, 2, 8 * sizeof(long));
183 if (!kvm->arch.dbf)
184 goto out_nodbf;
185
Carsten Otteba5c1e92008-03-25 18:47:26 +0100186 spin_lock_init(&kvm->arch.float_int.lock);
187 INIT_LIST_HEAD(&kvm->arch.float_int.list);
188
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100189 debug_register_view(kvm->arch.dbf, &debug_sprintf_view);
190 VM_EVENT(kvm, 3, "%s", "vm created");
191
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100192 return 0;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100193out_nodbf:
194 free_page((unsigned long)(kvm->arch.sca));
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100195out_err:
196 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100197}
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");
Christian Borntraegerfc345312010-06-17 23:16:20 +0200202 clear_bit(63 - vcpu->vcpu_id, (unsigned long *) &vcpu->kvm->arch.sca->mcn);
Carsten Otteabf4a712009-05-12 17:21:51 +0200203 if (vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda ==
204 (__u64) vcpu->arch.sie_block)
205 vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda = 0;
206 smp_mb();
Christian Borntraegerd329c032008-11-26 14:50:27 +0100207 free_page((unsigned long)(vcpu->arch.sie_block));
Christian Borntraeger6692cef2008-11-26 14:51:08 +0100208 kvm_vcpu_uninit(vcpu);
Christian Borntraegerd329c032008-11-26 14:50:27 +0100209 kfree(vcpu);
210}
211
212static void kvm_free_vcpus(struct kvm *kvm)
213{
214 unsigned int i;
Gleb Natapov988a2ca2009-06-09 15:56:29 +0300215 struct kvm_vcpu *vcpu;
Christian Borntraegerd329c032008-11-26 14:50:27 +0100216
Gleb Natapov988a2ca2009-06-09 15:56:29 +0300217 kvm_for_each_vcpu(i, vcpu, kvm)
218 kvm_arch_vcpu_destroy(vcpu);
219
220 mutex_lock(&kvm->lock);
221 for (i = 0; i < atomic_read(&kvm->online_vcpus); i++)
222 kvm->vcpus[i] = NULL;
223
224 atomic_set(&kvm->online_vcpus, 0);
225 mutex_unlock(&kvm->lock);
Christian Borntraegerd329c032008-11-26 14:50:27 +0100226}
227
Sheng Yangad8ba2c2009-01-06 10:03:02 +0800228void kvm_arch_sync_events(struct kvm *kvm)
229{
230}
231
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100232void kvm_arch_destroy_vm(struct kvm *kvm)
233{
Christian Borntraegerd329c032008-11-26 14:50:27 +0100234 kvm_free_vcpus(kvm);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100235 free_page((unsigned long)(kvm->arch.sca));
Christian Borntraegerd329c032008-11-26 14:50:27 +0100236 debug_unregister(kvm->arch.dbf);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100237}
238
239/* Section: vcpu related */
240int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
241{
242 return 0;
243}
244
245void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
246{
Christian Borntraeger6692cef2008-11-26 14:51:08 +0100247 /* Nothing todo */
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100248}
249
250void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
251{
252 save_fp_regs(&vcpu->arch.host_fpregs);
253 save_access_regs(vcpu->arch.host_acrs);
254 vcpu->arch.guest_fpregs.fpc &= FPC_VALID_MASK;
255 restore_fp_regs(&vcpu->arch.guest_fpregs);
256 restore_access_regs(vcpu->arch.guest_acrs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100257}
258
259void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
260{
261 save_fp_regs(&vcpu->arch.guest_fpregs);
262 save_access_regs(vcpu->arch.guest_acrs);
263 restore_fp_regs(&vcpu->arch.host_fpregs);
264 restore_access_regs(vcpu->arch.host_acrs);
265}
266
267static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu)
268{
269 /* this equals initial cpu reset in pop, but we don't switch to ESA */
270 vcpu->arch.sie_block->gpsw.mask = 0UL;
271 vcpu->arch.sie_block->gpsw.addr = 0UL;
272 vcpu->arch.sie_block->prefix = 0UL;
273 vcpu->arch.sie_block->ihcpu = 0xffff;
274 vcpu->arch.sie_block->cputm = 0UL;
275 vcpu->arch.sie_block->ckc = 0UL;
276 vcpu->arch.sie_block->todpr = 0;
277 memset(vcpu->arch.sie_block->gcr, 0, 16 * sizeof(__u64));
278 vcpu->arch.sie_block->gcr[0] = 0xE0UL;
279 vcpu->arch.sie_block->gcr[14] = 0xC2000000UL;
280 vcpu->arch.guest_fpregs.fpc = 0;
281 asm volatile("lfpc %0" : : "Q" (vcpu->arch.guest_fpregs.fpc));
282 vcpu->arch.sie_block->gbea = 1;
283}
284
285int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
286{
287 atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH);
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200288 set_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests);
Christian Borntraegerfc345312010-06-17 23:16:20 +0200289 vcpu->arch.sie_block->ecb = 6;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100290 vcpu->arch.sie_block->eca = 0xC1002001U;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200291 vcpu->arch.sie_block->fac = (int) (long) facilities;
Christian Borntraegerca872302009-05-12 17:21:49 +0200292 hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
293 tasklet_init(&vcpu->arch.tasklet, kvm_s390_tasklet,
294 (unsigned long) vcpu);
295 vcpu->arch.ckc_timer.function = kvm_s390_idle_wakeup;
Christian Borntraeger453423d2008-03-25 18:47:29 +0100296 get_cpu_id(&vcpu->arch.cpu_id);
Christian Borntraeger92e6ecf2009-03-26 15:23:58 +0100297 vcpu->arch.cpu_id.version = 0xff;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100298 return 0;
299}
300
301struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
302 unsigned int id)
303{
304 struct kvm_vcpu *vcpu = kzalloc(sizeof(struct kvm_vcpu), GFP_KERNEL);
305 int rc = -ENOMEM;
306
307 if (!vcpu)
308 goto out_nomem;
309
Christian Borntraeger180c12f2008-06-27 15:05:40 +0200310 vcpu->arch.sie_block = (struct kvm_s390_sie_block *)
311 get_zeroed_page(GFP_KERNEL);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100312
313 if (!vcpu->arch.sie_block)
314 goto out_free_cpu;
315
316 vcpu->arch.sie_block->icpua = id;
317 BUG_ON(!kvm->arch.sca);
Carsten Otteabf4a712009-05-12 17:21:51 +0200318 if (!kvm->arch.sca->cpu[id].sda)
319 kvm->arch.sca->cpu[id].sda = (__u64) vcpu->arch.sie_block;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100320 vcpu->arch.sie_block->scaoh = (__u32)(((__u64)kvm->arch.sca) >> 32);
321 vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca;
Christian Borntraegerfc345312010-06-17 23:16:20 +0200322 set_bit(63 - id, (unsigned long *) &kvm->arch.sca->mcn);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100323
Carsten Otteba5c1e92008-03-25 18:47:26 +0100324 spin_lock_init(&vcpu->arch.local_int.lock);
325 INIT_LIST_HEAD(&vcpu->arch.local_int.list);
326 vcpu->arch.local_int.float_int = &kvm->arch.float_int;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200327 spin_lock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100328 kvm->arch.float_int.local_int[id] = &vcpu->arch.local_int;
329 init_waitqueue_head(&vcpu->arch.local_int.wq);
Christian Borntraeger5288fbf2008-03-25 18:47:31 +0100330 vcpu->arch.local_int.cpuflags = &vcpu->arch.sie_block->cpuflags;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200331 spin_unlock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100332
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100333 rc = kvm_vcpu_init(vcpu, kvm, id);
334 if (rc)
Wei Yongjun7b06bf22010-03-09 14:37:53 +0800335 goto out_free_sie_block;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100336 VM_EVENT(kvm, 3, "create cpu %d at %p, sie block at %p", id, vcpu,
337 vcpu->arch.sie_block);
338
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100339 return vcpu;
Wei Yongjun7b06bf22010-03-09 14:37:53 +0800340out_free_sie_block:
341 free_page((unsigned long)(vcpu->arch.sie_block));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100342out_free_cpu:
343 kfree(vcpu);
344out_nomem:
345 return ERR_PTR(rc);
346}
347
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100348int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
349{
350 /* kvm common code refers to this, but never calls it */
351 BUG();
352 return 0;
353}
354
355static int kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu)
356{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100357 kvm_s390_vcpu_initial_reset(vcpu);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100358 return 0;
359}
360
361int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
362{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100363 memcpy(&vcpu->arch.guest_gprs, &regs->gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100364 return 0;
365}
366
367int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
368{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100369 memcpy(&regs->gprs, &vcpu->arch.guest_gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100370 return 0;
371}
372
373int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
374 struct kvm_sregs *sregs)
375{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100376 memcpy(&vcpu->arch.guest_acrs, &sregs->acrs, sizeof(sregs->acrs));
377 memcpy(&vcpu->arch.sie_block->gcr, &sregs->crs, sizeof(sregs->crs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100378 return 0;
379}
380
381int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
382 struct kvm_sregs *sregs)
383{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100384 memcpy(&sregs->acrs, &vcpu->arch.guest_acrs, sizeof(sregs->acrs));
385 memcpy(&sregs->crs, &vcpu->arch.sie_block->gcr, sizeof(sregs->crs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100386 return 0;
387}
388
389int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
390{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100391 memcpy(&vcpu->arch.guest_fpregs.fprs, &fpu->fprs, sizeof(fpu->fprs));
392 vcpu->arch.guest_fpregs.fpc = fpu->fpc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100393 return 0;
394}
395
396int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
397{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100398 memcpy(&fpu->fprs, &vcpu->arch.guest_fpregs.fprs, sizeof(fpu->fprs));
399 fpu->fpc = vcpu->arch.guest_fpregs.fpc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100400 return 0;
401}
402
403static int kvm_arch_vcpu_ioctl_set_initial_psw(struct kvm_vcpu *vcpu, psw_t psw)
404{
405 int rc = 0;
406
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100407 if (atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_RUNNING)
408 rc = -EBUSY;
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100409 else {
410 vcpu->run->psw_mask = psw.mask;
411 vcpu->run->psw_addr = psw.addr;
412 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100413 return rc;
414}
415
416int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
417 struct kvm_translation *tr)
418{
419 return -EINVAL; /* not implemented yet */
420}
421
Jan Kiszkad0bfb942008-12-15 13:52:10 +0100422int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
423 struct kvm_guest_debug *dbg)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100424{
425 return -EINVAL; /* not implemented yet */
426}
427
Marcelo Tosatti62d9f0d2008-04-11 13:24:45 -0300428int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
429 struct kvm_mp_state *mp_state)
430{
431 return -EINVAL; /* not implemented yet */
432}
433
434int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
435 struct kvm_mp_state *mp_state)
436{
437 return -EINVAL; /* not implemented yet */
438}
439
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100440static void __vcpu_run(struct kvm_vcpu *vcpu)
441{
442 memcpy(&vcpu->arch.sie_block->gg14, &vcpu->arch.guest_gprs[14], 16);
443
444 if (need_resched())
445 schedule();
446
Christian Borntraeger71cde582008-05-21 13:37:34 +0200447 if (test_thread_flag(TIF_MCCK_PENDING))
448 s390_handle_mcck();
449
Carsten Otte0ff31862008-05-21 13:37:37 +0200450 kvm_s390_deliver_pending_interrupts(vcpu);
451
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100452 vcpu->arch.sie_block->icptcode = 0;
453 local_irq_disable();
454 kvm_guest_enter();
455 local_irq_enable();
456 VCPU_EVENT(vcpu, 6, "entering sie flags %x",
457 atomic_read(&vcpu->arch.sie_block->cpuflags));
Carsten Otte1f0d0f02008-05-21 13:37:40 +0200458 if (sie64a(vcpu->arch.sie_block, vcpu->arch.guest_gprs)) {
459 VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction");
460 kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
461 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100462 VCPU_EVENT(vcpu, 6, "exit sie icptcode %d",
463 vcpu->arch.sie_block->icptcode);
464 local_irq_disable();
465 kvm_guest_exit();
466 local_irq_enable();
467
468 memcpy(&vcpu->arch.guest_gprs[14], &vcpu->arch.sie_block->gg14, 16);
469}
470
471int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
472{
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100473 int rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100474 sigset_t sigsaved;
475
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200476rerun_vcpu:
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200477 if (vcpu->requests)
478 if (test_and_clear_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests))
479 kvm_s390_vcpu_set_mem(vcpu);
480
Carsten Otte51e4d5a2009-05-12 17:21:53 +0200481 /* verify, that memory has been registered */
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200482 if (!vcpu->arch.sie_block->gmslm) {
Carsten Otte51e4d5a2009-05-12 17:21:53 +0200483 vcpu_put(vcpu);
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200484 VCPU_EVENT(vcpu, 3, "%s", "no memory registered to run vcpu");
Carsten Otte51e4d5a2009-05-12 17:21:53 +0200485 return -EINVAL;
486 }
487
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100488 if (vcpu->sigset_active)
489 sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
490
491 atomic_set_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
492
Carsten Otteba5c1e92008-03-25 18:47:26 +0100493 BUG_ON(vcpu->kvm->arch.float_int.local_int[vcpu->vcpu_id] == NULL);
494
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100495 switch (kvm_run->exit_reason) {
496 case KVM_EXIT_S390_SIEIC:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100497 case KVM_EXIT_UNKNOWN:
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200498 case KVM_EXIT_INTR:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100499 case KVM_EXIT_S390_RESET:
500 break;
501 default:
502 BUG();
503 }
504
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100505 vcpu->arch.sie_block->gpsw.mask = kvm_run->psw_mask;
506 vcpu->arch.sie_block->gpsw.addr = kvm_run->psw_addr;
507
Heiko Carstensdab4079d2009-06-12 10:26:32 +0200508 might_fault();
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100509
510 do {
511 __vcpu_run(vcpu);
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100512 rc = kvm_handle_sie_intercept(vcpu);
513 } while (!signal_pending(current) && !rc);
514
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200515 if (rc == SIE_INTERCEPT_RERUNVCPU)
516 goto rerun_vcpu;
517
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200518 if (signal_pending(current) && !rc) {
519 kvm_run->exit_reason = KVM_EXIT_INTR;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100520 rc = -EINTR;
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200521 }
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100522
Heiko Carstensb8e660b2010-02-26 22:37:41 +0100523 if (rc == -EOPNOTSUPP) {
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100524 /* intercept cannot be handled in-kernel, prepare kvm-run */
525 kvm_run->exit_reason = KVM_EXIT_S390_SIEIC;
526 kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100527 kvm_run->s390_sieic.ipa = vcpu->arch.sie_block->ipa;
528 kvm_run->s390_sieic.ipb = vcpu->arch.sie_block->ipb;
529 rc = 0;
530 }
531
532 if (rc == -EREMOTE) {
533 /* intercept was handled, but userspace support is needed
534 * kvm_run has been prepared by the handler */
535 rc = 0;
536 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100537
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100538 kvm_run->psw_mask = vcpu->arch.sie_block->gpsw.mask;
539 kvm_run->psw_addr = vcpu->arch.sie_block->gpsw.addr;
540
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100541 if (vcpu->sigset_active)
542 sigprocmask(SIG_SETMASK, &sigsaved, NULL);
543
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100544 vcpu->stat.exit_userspace++;
Heiko Carstens7e8e6ab2008-04-04 15:12:35 +0200545 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100546}
547
548static int __guestcopy(struct kvm_vcpu *vcpu, u64 guestdest, const void *from,
549 unsigned long n, int prefix)
550{
551 if (prefix)
552 return copy_to_guest(vcpu, guestdest, from, n);
553 else
554 return copy_to_guest_absolute(vcpu, guestdest, from, n);
555}
556
557/*
558 * store status at address
559 * we use have two special cases:
560 * KVM_S390_STORE_STATUS_NOADDR: -> 0x1200 on 64 bit
561 * KVM_S390_STORE_STATUS_PREFIXED: -> prefix
562 */
Christian Borntraeger971eb772010-06-12 08:54:13 +0200563int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100564{
565 const unsigned char archmode = 1;
566 int prefix;
567
568 if (addr == KVM_S390_STORE_STATUS_NOADDR) {
569 if (copy_to_guest_absolute(vcpu, 163ul, &archmode, 1))
570 return -EFAULT;
571 addr = SAVE_AREA_BASE;
572 prefix = 0;
573 } else if (addr == KVM_S390_STORE_STATUS_PREFIXED) {
574 if (copy_to_guest(vcpu, 163ul, &archmode, 1))
575 return -EFAULT;
576 addr = SAVE_AREA_BASE;
577 prefix = 1;
578 } else
579 prefix = 0;
580
Heiko Carstensf64ca212010-02-26 22:37:32 +0100581 if (__guestcopy(vcpu, addr + offsetof(struct save_area, fp_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100582 vcpu->arch.guest_fpregs.fprs, 128, prefix))
583 return -EFAULT;
584
Heiko Carstensf64ca212010-02-26 22:37:32 +0100585 if (__guestcopy(vcpu, addr + offsetof(struct save_area, gp_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100586 vcpu->arch.guest_gprs, 128, prefix))
587 return -EFAULT;
588
Heiko Carstensf64ca212010-02-26 22:37:32 +0100589 if (__guestcopy(vcpu, addr + offsetof(struct save_area, psw),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100590 &vcpu->arch.sie_block->gpsw, 16, prefix))
591 return -EFAULT;
592
Heiko Carstensf64ca212010-02-26 22:37:32 +0100593 if (__guestcopy(vcpu, addr + offsetof(struct save_area, pref_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100594 &vcpu->arch.sie_block->prefix, 4, prefix))
595 return -EFAULT;
596
597 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100598 addr + offsetof(struct save_area, fp_ctrl_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100599 &vcpu->arch.guest_fpregs.fpc, 4, prefix))
600 return -EFAULT;
601
Heiko Carstensf64ca212010-02-26 22:37:32 +0100602 if (__guestcopy(vcpu, addr + offsetof(struct save_area, tod_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100603 &vcpu->arch.sie_block->todpr, 4, prefix))
604 return -EFAULT;
605
Heiko Carstensf64ca212010-02-26 22:37:32 +0100606 if (__guestcopy(vcpu, addr + offsetof(struct save_area, timer),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100607 &vcpu->arch.sie_block->cputm, 8, prefix))
608 return -EFAULT;
609
Heiko Carstensf64ca212010-02-26 22:37:32 +0100610 if (__guestcopy(vcpu, addr + offsetof(struct save_area, clk_cmp),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100611 &vcpu->arch.sie_block->ckc, 8, prefix))
612 return -EFAULT;
613
Heiko Carstensf64ca212010-02-26 22:37:32 +0100614 if (__guestcopy(vcpu, addr + offsetof(struct save_area, acc_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100615 &vcpu->arch.guest_acrs, 64, prefix))
616 return -EFAULT;
617
618 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100619 addr + offsetof(struct save_area, ctrl_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100620 &vcpu->arch.sie_block->gcr, 128, prefix))
621 return -EFAULT;
622 return 0;
623}
624
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100625long kvm_arch_vcpu_ioctl(struct file *filp,
626 unsigned int ioctl, unsigned long arg)
627{
628 struct kvm_vcpu *vcpu = filp->private_data;
629 void __user *argp = (void __user *)arg;
Avi Kivitybc923cc2010-05-13 12:21:46 +0300630 long r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100631
Avi Kivity93736622010-05-13 12:35:17 +0300632 switch (ioctl) {
633 case KVM_S390_INTERRUPT: {
Carsten Otteba5c1e92008-03-25 18:47:26 +0100634 struct kvm_s390_interrupt s390int;
635
Avi Kivity93736622010-05-13 12:35:17 +0300636 r = -EFAULT;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100637 if (copy_from_user(&s390int, argp, sizeof(s390int)))
Avi Kivity93736622010-05-13 12:35:17 +0300638 break;
639 r = kvm_s390_inject_vcpu(vcpu, &s390int);
640 break;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100641 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100642 case KVM_S390_STORE_STATUS:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300643 r = kvm_s390_vcpu_store_status(vcpu, arg);
644 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100645 case KVM_S390_SET_INITIAL_PSW: {
646 psw_t psw;
647
Avi Kivitybc923cc2010-05-13 12:21:46 +0300648 r = -EFAULT;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100649 if (copy_from_user(&psw, argp, sizeof(psw)))
Avi Kivitybc923cc2010-05-13 12:21:46 +0300650 break;
651 r = kvm_arch_vcpu_ioctl_set_initial_psw(vcpu, psw);
652 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100653 }
654 case KVM_S390_INITIAL_RESET:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300655 r = kvm_arch_vcpu_ioctl_initial_reset(vcpu);
656 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100657 default:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300658 r = -EINVAL;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100659 }
Avi Kivitybc923cc2010-05-13 12:21:46 +0300660 return r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100661}
662
663/* Section: memory related */
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200664int kvm_arch_prepare_memory_region(struct kvm *kvm,
665 struct kvm_memory_slot *memslot,
666 struct kvm_memory_slot old,
667 struct kvm_userspace_memory_region *mem,
668 int user_alloc)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100669{
670 /* A few sanity checks. We can have exactly one memory slot which has
671 to start at guest virtual zero and which has to be located at a
672 page boundary in userland and which has to end at a page boundary.
673 The memory in userland is ok to be fragmented into various different
674 vmas. It is okay to mmap() and munmap() stuff in this slot after
675 doing this call at any time */
676
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200677 if (mem->slot)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100678 return -EINVAL;
679
680 if (mem->guest_phys_addr)
681 return -EINVAL;
682
683 if (mem->userspace_addr & (PAGE_SIZE - 1))
684 return -EINVAL;
685
686 if (mem->memory_size & (PAGE_SIZE - 1))
687 return -EINVAL;
688
Carsten Otte2668dab2009-05-12 17:21:48 +0200689 if (!user_alloc)
690 return -EINVAL;
691
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200692 return 0;
693}
694
695void kvm_arch_commit_memory_region(struct kvm *kvm,
696 struct kvm_userspace_memory_region *mem,
697 struct kvm_memory_slot old,
698 int user_alloc)
699{
700 int i;
701 struct kvm_vcpu *vcpu;
702
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200703 /* request update of sie control block for all available vcpus */
Gleb Natapov988a2ca2009-06-09 15:56:29 +0300704 kvm_for_each_vcpu(i, vcpu, kvm) {
705 if (test_and_set_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests))
706 continue;
707 kvm_s390_inject_sigp_stop(vcpu, ACTION_RELOADVCPU_ON_STOP);
Carsten Otte2668dab2009-05-12 17:21:48 +0200708 }
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);