blob: 123ebea72282cb985fec66009467e9ae7ff09069 [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 Borntraegere28acfe2008-03-25 18:47:34 +010072 { "diagnose_44", VCPU_STAT(diagnose_44) },
Heiko Carstensb0c632d2008-03-25 18:47:20 +010073 { NULL }
74};
75
Christian Borntraegeref50f7a2009-06-23 17:24:07 +020076static unsigned long long *facilities;
Heiko Carstensb0c632d2008-03-25 18:47:20 +010077
78/* Section: not file related */
Alexander Graf10474ae2009-09-15 11:37:46 +020079int kvm_arch_hardware_enable(void *garbage)
Heiko Carstensb0c632d2008-03-25 18:47:20 +010080{
81 /* every s390 is virtualization enabled ;-) */
Alexander Graf10474ae2009-09-15 11:37:46 +020082 return 0;
Heiko Carstensb0c632d2008-03-25 18:47:20 +010083}
84
85void kvm_arch_hardware_disable(void *garbage)
86{
87}
88
Heiko Carstensb0c632d2008-03-25 18:47:20 +010089int kvm_arch_hardware_setup(void)
90{
91 return 0;
92}
93
94void kvm_arch_hardware_unsetup(void)
95{
96}
97
98void kvm_arch_check_processor_compat(void *rtn)
99{
100}
101
102int kvm_arch_init(void *opaque)
103{
104 return 0;
105}
106
107void kvm_arch_exit(void)
108{
109}
110
111/* Section: device related */
112long kvm_arch_dev_ioctl(struct file *filp,
113 unsigned int ioctl, unsigned long arg)
114{
115 if (ioctl == KVM_S390_ENABLE_SIE)
116 return s390_enable_sie();
117 return -EINVAL;
118}
119
120int kvm_dev_ioctl_check_extension(long ext)
121{
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100122 int r;
123
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200124 switch (ext) {
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100125 case KVM_CAP_S390_PSW:
126 r = 1;
127 break;
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200128 default:
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100129 r = 0;
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200130 }
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100131 return r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100132}
133
134/* Section: vm related */
135/*
136 * Get (and clear) the dirty memory log for a memory slot.
137 */
138int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
139 struct kvm_dirty_log *log)
140{
141 return 0;
142}
143
144long kvm_arch_vm_ioctl(struct file *filp,
145 unsigned int ioctl, unsigned long arg)
146{
147 struct kvm *kvm = filp->private_data;
148 void __user *argp = (void __user *)arg;
149 int r;
150
151 switch (ioctl) {
Carsten Otteba5c1e92008-03-25 18:47:26 +0100152 case KVM_S390_INTERRUPT: {
153 struct kvm_s390_interrupt s390int;
154
155 r = -EFAULT;
156 if (copy_from_user(&s390int, argp, sizeof(s390int)))
157 break;
158 r = kvm_s390_inject_vm(kvm, &s390int);
159 break;
160 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100161 default:
Avi Kivity367e1312009-08-26 14:57:07 +0300162 r = -ENOTTY;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100163 }
164
165 return r;
166}
167
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100168int kvm_arch_init_vm(struct kvm *kvm)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100169{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100170 int rc;
171 char debug_name[16];
172
173 rc = s390_enable_sie();
174 if (rc)
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100175 goto out_err;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100176
177 kvm->arch.sca = (struct sca_block *) get_zeroed_page(GFP_KERNEL);
178 if (!kvm->arch.sca)
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100179 goto out_err;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100180
181 sprintf(debug_name, "kvm-%u", current->pid);
182
183 kvm->arch.dbf = debug_register(debug_name, 8, 2, 8 * sizeof(long));
184 if (!kvm->arch.dbf)
185 goto out_nodbf;
186
Carsten Otteba5c1e92008-03-25 18:47:26 +0100187 spin_lock_init(&kvm->arch.float_int.lock);
188 INIT_LIST_HEAD(&kvm->arch.float_int.list);
189
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100190 debug_register_view(kvm->arch.dbf, &debug_sprintf_view);
191 VM_EVENT(kvm, 3, "%s", "vm created");
192
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100193 return 0;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100194out_nodbf:
195 free_page((unsigned long)(kvm->arch.sca));
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100196out_err:
197 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100198}
199
Christian Borntraegerd329c032008-11-26 14:50:27 +0100200void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
201{
202 VCPU_EVENT(vcpu, 3, "%s", "free cpu");
Christian Borntraegerfc345312010-06-17 23:16:20 +0200203 clear_bit(63 - vcpu->vcpu_id, (unsigned long *) &vcpu->kvm->arch.sca->mcn);
Carsten Otteabf4a712009-05-12 17:21:51 +0200204 if (vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda ==
205 (__u64) vcpu->arch.sie_block)
206 vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda = 0;
207 smp_mb();
Christian Borntraegerd329c032008-11-26 14:50:27 +0100208 free_page((unsigned long)(vcpu->arch.sie_block));
Christian Borntraeger6692cef2008-11-26 14:51:08 +0100209 kvm_vcpu_uninit(vcpu);
Christian Borntraegerd329c032008-11-26 14:50:27 +0100210 kfree(vcpu);
211}
212
213static void kvm_free_vcpus(struct kvm *kvm)
214{
215 unsigned int i;
Gleb Natapov988a2ca2009-06-09 15:56:29 +0300216 struct kvm_vcpu *vcpu;
Christian Borntraegerd329c032008-11-26 14:50:27 +0100217
Gleb Natapov988a2ca2009-06-09 15:56:29 +0300218 kvm_for_each_vcpu(i, vcpu, kvm)
219 kvm_arch_vcpu_destroy(vcpu);
220
221 mutex_lock(&kvm->lock);
222 for (i = 0; i < atomic_read(&kvm->online_vcpus); i++)
223 kvm->vcpus[i] = NULL;
224
225 atomic_set(&kvm->online_vcpus, 0);
226 mutex_unlock(&kvm->lock);
Christian Borntraegerd329c032008-11-26 14:50:27 +0100227}
228
Sheng Yangad8ba2c2009-01-06 10:03:02 +0800229void kvm_arch_sync_events(struct kvm *kvm)
230{
231}
232
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100233void kvm_arch_destroy_vm(struct kvm *kvm)
234{
Christian Borntraegerd329c032008-11-26 14:50:27 +0100235 kvm_free_vcpus(kvm);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100236 free_page((unsigned long)(kvm->arch.sca));
Christian Borntraegerd329c032008-11-26 14:50:27 +0100237 debug_unregister(kvm->arch.dbf);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100238}
239
240/* Section: vcpu related */
241int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
242{
243 return 0;
244}
245
246void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
247{
Christian Borntraeger6692cef2008-11-26 14:51:08 +0100248 /* Nothing todo */
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100249}
250
251void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
252{
253 save_fp_regs(&vcpu->arch.host_fpregs);
254 save_access_regs(vcpu->arch.host_acrs);
255 vcpu->arch.guest_fpregs.fpc &= FPC_VALID_MASK;
256 restore_fp_regs(&vcpu->arch.guest_fpregs);
257 restore_access_regs(vcpu->arch.guest_acrs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100258}
259
260void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
261{
262 save_fp_regs(&vcpu->arch.guest_fpregs);
263 save_access_regs(vcpu->arch.guest_acrs);
264 restore_fp_regs(&vcpu->arch.host_fpregs);
265 restore_access_regs(vcpu->arch.host_acrs);
266}
267
268static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu)
269{
270 /* this equals initial cpu reset in pop, but we don't switch to ESA */
271 vcpu->arch.sie_block->gpsw.mask = 0UL;
272 vcpu->arch.sie_block->gpsw.addr = 0UL;
273 vcpu->arch.sie_block->prefix = 0UL;
274 vcpu->arch.sie_block->ihcpu = 0xffff;
275 vcpu->arch.sie_block->cputm = 0UL;
276 vcpu->arch.sie_block->ckc = 0UL;
277 vcpu->arch.sie_block->todpr = 0;
278 memset(vcpu->arch.sie_block->gcr, 0, 16 * sizeof(__u64));
279 vcpu->arch.sie_block->gcr[0] = 0xE0UL;
280 vcpu->arch.sie_block->gcr[14] = 0xC2000000UL;
281 vcpu->arch.guest_fpregs.fpc = 0;
282 asm volatile("lfpc %0" : : "Q" (vcpu->arch.guest_fpregs.fpc));
283 vcpu->arch.sie_block->gbea = 1;
284}
285
286int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
287{
288 atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH);
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200289 set_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests);
Christian Borntraegerfc345312010-06-17 23:16:20 +0200290 vcpu->arch.sie_block->ecb = 6;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100291 vcpu->arch.sie_block->eca = 0xC1002001U;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200292 vcpu->arch.sie_block->fac = (int) (long) facilities;
Christian Borntraegerca872302009-05-12 17:21:49 +0200293 hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
294 tasklet_init(&vcpu->arch.tasklet, kvm_s390_tasklet,
295 (unsigned long) vcpu);
296 vcpu->arch.ckc_timer.function = kvm_s390_idle_wakeup;
Christian Borntraeger453423d2008-03-25 18:47:29 +0100297 get_cpu_id(&vcpu->arch.cpu_id);
Christian Borntraeger92e6ecf2009-03-26 15:23:58 +0100298 vcpu->arch.cpu_id.version = 0xff;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100299 return 0;
300}
301
302struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
303 unsigned int id)
304{
305 struct kvm_vcpu *vcpu = kzalloc(sizeof(struct kvm_vcpu), GFP_KERNEL);
306 int rc = -ENOMEM;
307
308 if (!vcpu)
309 goto out_nomem;
310
Christian Borntraeger180c12f2008-06-27 15:05:40 +0200311 vcpu->arch.sie_block = (struct kvm_s390_sie_block *)
312 get_zeroed_page(GFP_KERNEL);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100313
314 if (!vcpu->arch.sie_block)
315 goto out_free_cpu;
316
317 vcpu->arch.sie_block->icpua = id;
318 BUG_ON(!kvm->arch.sca);
Carsten Otteabf4a712009-05-12 17:21:51 +0200319 if (!kvm->arch.sca->cpu[id].sda)
320 kvm->arch.sca->cpu[id].sda = (__u64) vcpu->arch.sie_block;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100321 vcpu->arch.sie_block->scaoh = (__u32)(((__u64)kvm->arch.sca) >> 32);
322 vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca;
Christian Borntraegerfc345312010-06-17 23:16:20 +0200323 set_bit(63 - id, (unsigned long *) &kvm->arch.sca->mcn);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100324
Carsten Otteba5c1e92008-03-25 18:47:26 +0100325 spin_lock_init(&vcpu->arch.local_int.lock);
326 INIT_LIST_HEAD(&vcpu->arch.local_int.list);
327 vcpu->arch.local_int.float_int = &kvm->arch.float_int;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200328 spin_lock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100329 kvm->arch.float_int.local_int[id] = &vcpu->arch.local_int;
330 init_waitqueue_head(&vcpu->arch.local_int.wq);
Christian Borntraeger5288fbf2008-03-25 18:47:31 +0100331 vcpu->arch.local_int.cpuflags = &vcpu->arch.sie_block->cpuflags;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200332 spin_unlock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100333
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100334 rc = kvm_vcpu_init(vcpu, kvm, id);
335 if (rc)
Wei Yongjun7b06bf22010-03-09 14:37:53 +0800336 goto out_free_sie_block;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100337 VM_EVENT(kvm, 3, "create cpu %d at %p, sie block at %p", id, vcpu,
338 vcpu->arch.sie_block);
339
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100340 return vcpu;
Wei Yongjun7b06bf22010-03-09 14:37:53 +0800341out_free_sie_block:
342 free_page((unsigned long)(vcpu->arch.sie_block));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100343out_free_cpu:
344 kfree(vcpu);
345out_nomem:
346 return ERR_PTR(rc);
347}
348
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100349int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
350{
351 /* kvm common code refers to this, but never calls it */
352 BUG();
353 return 0;
354}
355
356static int kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu)
357{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100358 kvm_s390_vcpu_initial_reset(vcpu);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100359 return 0;
360}
361
362int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
363{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100364 memcpy(&vcpu->arch.guest_gprs, &regs->gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100365 return 0;
366}
367
368int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
369{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100370 memcpy(&regs->gprs, &vcpu->arch.guest_gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100371 return 0;
372}
373
374int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
375 struct kvm_sregs *sregs)
376{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100377 memcpy(&vcpu->arch.guest_acrs, &sregs->acrs, sizeof(sregs->acrs));
378 memcpy(&vcpu->arch.sie_block->gcr, &sregs->crs, sizeof(sregs->crs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100379 return 0;
380}
381
382int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
383 struct kvm_sregs *sregs)
384{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100385 memcpy(&sregs->acrs, &vcpu->arch.guest_acrs, sizeof(sregs->acrs));
386 memcpy(&sregs->crs, &vcpu->arch.sie_block->gcr, sizeof(sregs->crs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100387 return 0;
388}
389
390int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
391{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100392 memcpy(&vcpu->arch.guest_fpregs.fprs, &fpu->fprs, sizeof(fpu->fprs));
393 vcpu->arch.guest_fpregs.fpc = fpu->fpc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100394 return 0;
395}
396
397int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
398{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100399 memcpy(&fpu->fprs, &vcpu->arch.guest_fpregs.fprs, sizeof(fpu->fprs));
400 fpu->fpc = vcpu->arch.guest_fpregs.fpc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100401 return 0;
402}
403
404static int kvm_arch_vcpu_ioctl_set_initial_psw(struct kvm_vcpu *vcpu, psw_t psw)
405{
406 int rc = 0;
407
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100408 if (atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_RUNNING)
409 rc = -EBUSY;
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100410 else {
411 vcpu->run->psw_mask = psw.mask;
412 vcpu->run->psw_addr = psw.addr;
413 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100414 return rc;
415}
416
417int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
418 struct kvm_translation *tr)
419{
420 return -EINVAL; /* not implemented yet */
421}
422
Jan Kiszkad0bfb942008-12-15 13:52:10 +0100423int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
424 struct kvm_guest_debug *dbg)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100425{
426 return -EINVAL; /* not implemented yet */
427}
428
Marcelo Tosatti62d9f0d2008-04-11 13:24:45 -0300429int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
430 struct kvm_mp_state *mp_state)
431{
432 return -EINVAL; /* not implemented yet */
433}
434
435int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
436 struct kvm_mp_state *mp_state)
437{
438 return -EINVAL; /* not implemented yet */
439}
440
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100441static void __vcpu_run(struct kvm_vcpu *vcpu)
442{
443 memcpy(&vcpu->arch.sie_block->gg14, &vcpu->arch.guest_gprs[14], 16);
444
445 if (need_resched())
446 schedule();
447
Christian Borntraeger71cde582008-05-21 13:37:34 +0200448 if (test_thread_flag(TIF_MCCK_PENDING))
449 s390_handle_mcck();
450
Carsten Otte0ff31862008-05-21 13:37:37 +0200451 kvm_s390_deliver_pending_interrupts(vcpu);
452
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100453 vcpu->arch.sie_block->icptcode = 0;
454 local_irq_disable();
455 kvm_guest_enter();
456 local_irq_enable();
457 VCPU_EVENT(vcpu, 6, "entering sie flags %x",
458 atomic_read(&vcpu->arch.sie_block->cpuflags));
Carsten Otte1f0d0f02008-05-21 13:37:40 +0200459 if (sie64a(vcpu->arch.sie_block, vcpu->arch.guest_gprs)) {
460 VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction");
461 kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
462 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100463 VCPU_EVENT(vcpu, 6, "exit sie icptcode %d",
464 vcpu->arch.sie_block->icptcode);
465 local_irq_disable();
466 kvm_guest_exit();
467 local_irq_enable();
468
469 memcpy(&vcpu->arch.guest_gprs[14], &vcpu->arch.sie_block->gg14, 16);
470}
471
472int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
473{
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100474 int rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100475 sigset_t sigsaved;
476
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200477rerun_vcpu:
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200478 if (vcpu->requests)
479 if (test_and_clear_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests))
480 kvm_s390_vcpu_set_mem(vcpu);
481
Carsten Otte51e4d5a2009-05-12 17:21:53 +0200482 /* verify, that memory has been registered */
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200483 if (!vcpu->arch.sie_block->gmslm) {
Carsten Otte51e4d5a2009-05-12 17:21:53 +0200484 vcpu_put(vcpu);
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200485 VCPU_EVENT(vcpu, 3, "%s", "no memory registered to run vcpu");
Carsten Otte51e4d5a2009-05-12 17:21:53 +0200486 return -EINVAL;
487 }
488
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
549static int __guestcopy(struct kvm_vcpu *vcpu, u64 guestdest, const void *from,
550 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{
566 const unsigned char archmode = 1;
567 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
684 if (mem->userspace_addr & (PAGE_SIZE - 1))
685 return -EINVAL;
686
687 if (mem->memory_size & (PAGE_SIZE - 1))
688 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{
701 int i;
702 struct kvm_vcpu *vcpu;
703
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200704 /* request update of sie control block for all available vcpus */
Gleb Natapov988a2ca2009-06-09 15:56:29 +0300705 kvm_for_each_vcpu(i, vcpu, kvm) {
706 if (test_and_set_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests))
707 continue;
708 kvm_s390_inject_sigp_stop(vcpu, ACTION_RELOADVCPU_ON_STOP);
Carsten Otte2668dab2009-05-12 17:21:48 +0200709 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100710}
711
Marcelo Tosatti34d4cb82008-07-10 20:49:31 -0300712void kvm_arch_flush_shadow(struct kvm *kvm)
713{
714}
715
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100716static int __init kvm_s390_init(void)
717{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200718 int ret;
Avi Kivity0ee75be2010-04-28 15:39:01 +0300719 ret = kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE);
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200720 if (ret)
721 return ret;
722
723 /*
724 * guests can ask for up to 255+1 double words, we need a full page
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300725 * to hold the maximum amount of facilities. On the other hand, we
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200726 * only set facilities that are known to work in KVM.
727 */
Heiko Carstensc2f0e8c2010-06-08 18:58:09 +0200728 facilities = (unsigned long long *) get_zeroed_page(GFP_KERNEL|GFP_DMA);
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200729 if (!facilities) {
730 kvm_exit();
731 return -ENOMEM;
732 }
Martin Schwidefsky14375bc2010-10-25 16:10:51 +0200733 memcpy(facilities, S390_lowcore.stfle_fac_list, 16);
Christian Borntraeger6d00d002010-10-25 16:10:48 +0200734 facilities[0] &= 0xff00fff3f47c0000ULL;
Christian Borntraeger9950f8b2011-06-06 14:14:39 +0200735 facilities[1] &= 0x201c000000000000ULL;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200736 return 0;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100737}
738
739static void __exit kvm_s390_exit(void)
740{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200741 free_page((unsigned long) facilities);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100742 kvm_exit();
743}
744
745module_init(kvm_s390_init);
746module_exit(kvm_s390_exit);