blob: 0891926ea953a6446e5b747baccd9db615dc8037 [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) },
Christian Ehrhardt7697e71f2011-10-18 12:27:15 +020049 { "deliver_external_call", VCPU_STAT(deliver_external_call) },
Carsten Otteba5c1e92008-03-25 18:47:26 +010050 { "deliver_service_signal", VCPU_STAT(deliver_service_signal) },
51 { "deliver_virtio_interrupt", VCPU_STAT(deliver_virtio_interrupt) },
52 { "deliver_stop_signal", VCPU_STAT(deliver_stop_signal) },
53 { "deliver_prefix_signal", VCPU_STAT(deliver_prefix_signal) },
54 { "deliver_restart_signal", VCPU_STAT(deliver_restart_signal) },
55 { "deliver_program_interruption", VCPU_STAT(deliver_program_int) },
56 { "exit_wait_state", VCPU_STAT(exit_wait_state) },
Christian Borntraeger453423d2008-03-25 18:47:29 +010057 { "instruction_stidp", VCPU_STAT(instruction_stidp) },
58 { "instruction_spx", VCPU_STAT(instruction_spx) },
59 { "instruction_stpx", VCPU_STAT(instruction_stpx) },
60 { "instruction_stap", VCPU_STAT(instruction_stap) },
61 { "instruction_storage_key", VCPU_STAT(instruction_storage_key) },
62 { "instruction_stsch", VCPU_STAT(instruction_stsch) },
63 { "instruction_chsc", VCPU_STAT(instruction_chsc) },
64 { "instruction_stsi", VCPU_STAT(instruction_stsi) },
65 { "instruction_stfl", VCPU_STAT(instruction_stfl) },
Christian Borntraegerbb25b9b2011-07-24 10:48:17 +020066 { "instruction_tprot", VCPU_STAT(instruction_tprot) },
Christian Borntraeger5288fbf2008-03-25 18:47:31 +010067 { "instruction_sigp_sense", VCPU_STAT(instruction_sigp_sense) },
Cornelia Huckbd59d3a2011-11-17 11:00:42 +010068 { "instruction_sigp_sense_running", VCPU_STAT(instruction_sigp_sense_running) },
Christian Ehrhardt7697e71f2011-10-18 12:27:15 +020069 { "instruction_sigp_external_call", VCPU_STAT(instruction_sigp_external_call) },
Christian Borntraeger5288fbf2008-03-25 18:47:31 +010070 { "instruction_sigp_emergency", VCPU_STAT(instruction_sigp_emergency) },
71 { "instruction_sigp_stop", VCPU_STAT(instruction_sigp_stop) },
72 { "instruction_sigp_set_arch", VCPU_STAT(instruction_sigp_arch) },
73 { "instruction_sigp_set_prefix", VCPU_STAT(instruction_sigp_prefix) },
74 { "instruction_sigp_restart", VCPU_STAT(instruction_sigp_restart) },
Christian Borntraeger388186b2011-10-30 15:17:03 +010075 { "diagnose_10", VCPU_STAT(diagnose_10) },
Christian Borntraegere28acfe2008-03-25 18:47:34 +010076 { "diagnose_44", VCPU_STAT(diagnose_44) },
Heiko Carstensb0c632d2008-03-25 18:47:20 +010077 { NULL }
78};
79
Christian Borntraegeref50f7a2009-06-23 17:24:07 +020080static unsigned long long *facilities;
Heiko Carstensb0c632d2008-03-25 18:47:20 +010081
82/* Section: not file related */
Alexander Graf10474ae2009-09-15 11:37:46 +020083int kvm_arch_hardware_enable(void *garbage)
Heiko Carstensb0c632d2008-03-25 18:47:20 +010084{
85 /* every s390 is virtualization enabled ;-) */
Alexander Graf10474ae2009-09-15 11:37:46 +020086 return 0;
Heiko Carstensb0c632d2008-03-25 18:47:20 +010087}
88
89void kvm_arch_hardware_disable(void *garbage)
90{
91}
92
Heiko Carstensb0c632d2008-03-25 18:47:20 +010093int kvm_arch_hardware_setup(void)
94{
95 return 0;
96}
97
98void kvm_arch_hardware_unsetup(void)
99{
100}
101
102void kvm_arch_check_processor_compat(void *rtn)
103{
104}
105
106int kvm_arch_init(void *opaque)
107{
108 return 0;
109}
110
111void kvm_arch_exit(void)
112{
113}
114
115/* Section: device related */
116long kvm_arch_dev_ioctl(struct file *filp,
117 unsigned int ioctl, unsigned long arg)
118{
119 if (ioctl == KVM_S390_ENABLE_SIE)
120 return s390_enable_sie();
121 return -EINVAL;
122}
123
124int kvm_dev_ioctl_check_extension(long ext)
125{
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100126 int r;
127
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200128 switch (ext) {
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100129 case KVM_CAP_S390_PSW:
Christian Borntraegerb6cf8782011-09-20 17:07:29 +0200130 case KVM_CAP_S390_GMAP:
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100131 r = 1;
132 break;
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200133 default:
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100134 r = 0;
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200135 }
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100136 return r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100137}
138
139/* Section: vm related */
140/*
141 * Get (and clear) the dirty memory log for a memory slot.
142 */
143int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
144 struct kvm_dirty_log *log)
145{
146 return 0;
147}
148
149long kvm_arch_vm_ioctl(struct file *filp,
150 unsigned int ioctl, unsigned long arg)
151{
152 struct kvm *kvm = filp->private_data;
153 void __user *argp = (void __user *)arg;
154 int r;
155
156 switch (ioctl) {
Carsten Otteba5c1e92008-03-25 18:47:26 +0100157 case KVM_S390_INTERRUPT: {
158 struct kvm_s390_interrupt s390int;
159
160 r = -EFAULT;
161 if (copy_from_user(&s390int, argp, sizeof(s390int)))
162 break;
163 r = kvm_s390_inject_vm(kvm, &s390int);
164 break;
165 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100166 default:
Avi Kivity367e1312009-08-26 14:57:07 +0300167 r = -ENOTTY;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100168 }
169
170 return r;
171}
172
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100173int kvm_arch_init_vm(struct kvm *kvm)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100174{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100175 int rc;
176 char debug_name[16];
177
178 rc = s390_enable_sie();
179 if (rc)
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100180 goto out_err;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100181
Carsten Otteb2904112011-10-18 12:27:13 +0200182 rc = -ENOMEM;
183
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100184 kvm->arch.sca = (struct sca_block *) get_zeroed_page(GFP_KERNEL);
185 if (!kvm->arch.sca)
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100186 goto out_err;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100187
188 sprintf(debug_name, "kvm-%u", current->pid);
189
190 kvm->arch.dbf = debug_register(debug_name, 8, 2, 8 * sizeof(long));
191 if (!kvm->arch.dbf)
192 goto out_nodbf;
193
Carsten Otteba5c1e92008-03-25 18:47:26 +0100194 spin_lock_init(&kvm->arch.float_int.lock);
195 INIT_LIST_HEAD(&kvm->arch.float_int.list);
196
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100197 debug_register_view(kvm->arch.dbf, &debug_sprintf_view);
198 VM_EVENT(kvm, 3, "%s", "vm created");
199
Carsten Otte598841c2011-07-24 10:48:21 +0200200 kvm->arch.gmap = gmap_alloc(current->mm);
201 if (!kvm->arch.gmap)
202 goto out_nogmap;
203
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100204 return 0;
Carsten Otte598841c2011-07-24 10:48:21 +0200205out_nogmap:
206 debug_unregister(kvm->arch.dbf);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100207out_nodbf:
208 free_page((unsigned long)(kvm->arch.sca));
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100209out_err:
210 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100211}
212
Christian Borntraegerd329c032008-11-26 14:50:27 +0100213void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
214{
215 VCPU_EVENT(vcpu, 3, "%s", "free cpu");
Christian Borntraegerfc345312010-06-17 23:16:20 +0200216 clear_bit(63 - vcpu->vcpu_id, (unsigned long *) &vcpu->kvm->arch.sca->mcn);
Carsten Otteabf4a712009-05-12 17:21:51 +0200217 if (vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda ==
218 (__u64) vcpu->arch.sie_block)
219 vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda = 0;
220 smp_mb();
Christian Borntraegerd329c032008-11-26 14:50:27 +0100221 free_page((unsigned long)(vcpu->arch.sie_block));
Christian Borntraeger6692cef2008-11-26 14:51:08 +0100222 kvm_vcpu_uninit(vcpu);
Christian Borntraegerd329c032008-11-26 14:50:27 +0100223 kfree(vcpu);
224}
225
226static void kvm_free_vcpus(struct kvm *kvm)
227{
228 unsigned int i;
Gleb Natapov988a2ca2009-06-09 15:56:29 +0300229 struct kvm_vcpu *vcpu;
Christian Borntraegerd329c032008-11-26 14:50:27 +0100230
Gleb Natapov988a2ca2009-06-09 15:56:29 +0300231 kvm_for_each_vcpu(i, vcpu, kvm)
232 kvm_arch_vcpu_destroy(vcpu);
233
234 mutex_lock(&kvm->lock);
235 for (i = 0; i < atomic_read(&kvm->online_vcpus); i++)
236 kvm->vcpus[i] = NULL;
237
238 atomic_set(&kvm->online_vcpus, 0);
239 mutex_unlock(&kvm->lock);
Christian Borntraegerd329c032008-11-26 14:50:27 +0100240}
241
Sheng Yangad8ba2c2009-01-06 10:03:02 +0800242void kvm_arch_sync_events(struct kvm *kvm)
243{
244}
245
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100246void kvm_arch_destroy_vm(struct kvm *kvm)
247{
Christian Borntraegerd329c032008-11-26 14:50:27 +0100248 kvm_free_vcpus(kvm);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100249 free_page((unsigned long)(kvm->arch.sca));
Christian Borntraegerd329c032008-11-26 14:50:27 +0100250 debug_unregister(kvm->arch.dbf);
Carsten Otte598841c2011-07-24 10:48:21 +0200251 gmap_free(kvm->arch.gmap);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100252}
253
254/* Section: vcpu related */
255int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
256{
Carsten Otte598841c2011-07-24 10:48:21 +0200257 vcpu->arch.gmap = vcpu->kvm->arch.gmap;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100258 return 0;
259}
260
261void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
262{
Christian Borntraeger6692cef2008-11-26 14:51:08 +0100263 /* Nothing todo */
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100264}
265
266void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
267{
268 save_fp_regs(&vcpu->arch.host_fpregs);
269 save_access_regs(vcpu->arch.host_acrs);
270 vcpu->arch.guest_fpregs.fpc &= FPC_VALID_MASK;
271 restore_fp_regs(&vcpu->arch.guest_fpregs);
272 restore_access_regs(vcpu->arch.guest_acrs);
Christian Borntraeger480e5922011-09-20 17:07:28 +0200273 gmap_enable(vcpu->arch.gmap);
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100274 atomic_set_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100275}
276
277void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
278{
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100279 atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
Christian Borntraeger480e5922011-09-20 17:07:28 +0200280 gmap_disable(vcpu->arch.gmap);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100281 save_fp_regs(&vcpu->arch.guest_fpregs);
282 save_access_regs(vcpu->arch.guest_acrs);
283 restore_fp_regs(&vcpu->arch.host_fpregs);
284 restore_access_regs(vcpu->arch.host_acrs);
285}
286
287static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu)
288{
289 /* this equals initial cpu reset in pop, but we don't switch to ESA */
290 vcpu->arch.sie_block->gpsw.mask = 0UL;
291 vcpu->arch.sie_block->gpsw.addr = 0UL;
292 vcpu->arch.sie_block->prefix = 0UL;
293 vcpu->arch.sie_block->ihcpu = 0xffff;
294 vcpu->arch.sie_block->cputm = 0UL;
295 vcpu->arch.sie_block->ckc = 0UL;
296 vcpu->arch.sie_block->todpr = 0;
297 memset(vcpu->arch.sie_block->gcr, 0, 16 * sizeof(__u64));
298 vcpu->arch.sie_block->gcr[0] = 0xE0UL;
299 vcpu->arch.sie_block->gcr[14] = 0xC2000000UL;
300 vcpu->arch.guest_fpregs.fpc = 0;
301 asm volatile("lfpc %0" : : "Q" (vcpu->arch.guest_fpregs.fpc));
302 vcpu->arch.sie_block->gbea = 1;
303}
304
305int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
306{
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100307 atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH |
308 CPUSTAT_SM |
309 CPUSTAT_STOPPED);
Christian Borntraegerfc345312010-06-17 23:16:20 +0200310 vcpu->arch.sie_block->ecb = 6;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100311 vcpu->arch.sie_block->eca = 0xC1002001U;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200312 vcpu->arch.sie_block->fac = (int) (long) facilities;
Christian Borntraegerca872302009-05-12 17:21:49 +0200313 hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
314 tasklet_init(&vcpu->arch.tasklet, kvm_s390_tasklet,
315 (unsigned long) vcpu);
316 vcpu->arch.ckc_timer.function = kvm_s390_idle_wakeup;
Christian Borntraeger453423d2008-03-25 18:47:29 +0100317 get_cpu_id(&vcpu->arch.cpu_id);
Christian Borntraeger92e6ecf2009-03-26 15:23:58 +0100318 vcpu->arch.cpu_id.version = 0xff;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100319 return 0;
320}
321
322struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
323 unsigned int id)
324{
Carsten Otte4d475552011-10-18 12:27:12 +0200325 struct kvm_vcpu *vcpu;
326 int rc = -EINVAL;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100327
Carsten Otte4d475552011-10-18 12:27:12 +0200328 if (id >= KVM_MAX_VCPUS)
329 goto out;
330
331 rc = -ENOMEM;
332
333 vcpu = kzalloc(sizeof(struct kvm_vcpu), GFP_KERNEL);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100334 if (!vcpu)
Carsten Otte4d475552011-10-18 12:27:12 +0200335 goto out;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100336
Christian Borntraeger180c12f2008-06-27 15:05:40 +0200337 vcpu->arch.sie_block = (struct kvm_s390_sie_block *)
338 get_zeroed_page(GFP_KERNEL);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100339
340 if (!vcpu->arch.sie_block)
341 goto out_free_cpu;
342
343 vcpu->arch.sie_block->icpua = id;
344 BUG_ON(!kvm->arch.sca);
Carsten Otteabf4a712009-05-12 17:21:51 +0200345 if (!kvm->arch.sca->cpu[id].sda)
346 kvm->arch.sca->cpu[id].sda = (__u64) vcpu->arch.sie_block;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100347 vcpu->arch.sie_block->scaoh = (__u32)(((__u64)kvm->arch.sca) >> 32);
348 vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca;
Christian Borntraegerfc345312010-06-17 23:16:20 +0200349 set_bit(63 - id, (unsigned long *) &kvm->arch.sca->mcn);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100350
Carsten Otteba5c1e92008-03-25 18:47:26 +0100351 spin_lock_init(&vcpu->arch.local_int.lock);
352 INIT_LIST_HEAD(&vcpu->arch.local_int.list);
353 vcpu->arch.local_int.float_int = &kvm->arch.float_int;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200354 spin_lock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100355 kvm->arch.float_int.local_int[id] = &vcpu->arch.local_int;
356 init_waitqueue_head(&vcpu->arch.local_int.wq);
Christian Borntraeger5288fbf2008-03-25 18:47:31 +0100357 vcpu->arch.local_int.cpuflags = &vcpu->arch.sie_block->cpuflags;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200358 spin_unlock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100359
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100360 rc = kvm_vcpu_init(vcpu, kvm, id);
361 if (rc)
Wei Yongjun7b06bf22010-03-09 14:37:53 +0800362 goto out_free_sie_block;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100363 VM_EVENT(kvm, 3, "create cpu %d at %p, sie block at %p", id, vcpu,
364 vcpu->arch.sie_block);
365
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100366 return vcpu;
Wei Yongjun7b06bf22010-03-09 14:37:53 +0800367out_free_sie_block:
368 free_page((unsigned long)(vcpu->arch.sie_block));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100369out_free_cpu:
370 kfree(vcpu);
Carsten Otte4d475552011-10-18 12:27:12 +0200371out:
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100372 return ERR_PTR(rc);
373}
374
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100375int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
376{
377 /* kvm common code refers to this, but never calls it */
378 BUG();
379 return 0;
380}
381
382static int kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu)
383{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100384 kvm_s390_vcpu_initial_reset(vcpu);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100385 return 0;
386}
387
388int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
389{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100390 memcpy(&vcpu->arch.guest_gprs, &regs->gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100391 return 0;
392}
393
394int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
395{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100396 memcpy(&regs->gprs, &vcpu->arch.guest_gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100397 return 0;
398}
399
400int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
401 struct kvm_sregs *sregs)
402{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100403 memcpy(&vcpu->arch.guest_acrs, &sregs->acrs, sizeof(sregs->acrs));
404 memcpy(&vcpu->arch.sie_block->gcr, &sregs->crs, sizeof(sregs->crs));
Carsten Otte7eef87d2011-10-18 12:27:14 +0200405 restore_access_regs(vcpu->arch.guest_acrs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100406 return 0;
407}
408
409int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
410 struct kvm_sregs *sregs)
411{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100412 memcpy(&sregs->acrs, &vcpu->arch.guest_acrs, sizeof(sregs->acrs));
413 memcpy(&sregs->crs, &vcpu->arch.sie_block->gcr, sizeof(sregs->crs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100414 return 0;
415}
416
417int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
418{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100419 memcpy(&vcpu->arch.guest_fpregs.fprs, &fpu->fprs, sizeof(fpu->fprs));
420 vcpu->arch.guest_fpregs.fpc = fpu->fpc;
Carsten Otte7eef87d2011-10-18 12:27:14 +0200421 restore_fp_regs(&vcpu->arch.guest_fpregs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100422 return 0;
423}
424
425int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
426{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100427 memcpy(&fpu->fprs, &vcpu->arch.guest_fpregs.fprs, sizeof(fpu->fprs));
428 fpu->fpc = vcpu->arch.guest_fpregs.fpc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100429 return 0;
430}
431
432static int kvm_arch_vcpu_ioctl_set_initial_psw(struct kvm_vcpu *vcpu, psw_t psw)
433{
434 int rc = 0;
435
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100436 if (!(atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_STOPPED))
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100437 rc = -EBUSY;
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100438 else {
439 vcpu->run->psw_mask = psw.mask;
440 vcpu->run->psw_addr = psw.addr;
441 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100442 return rc;
443}
444
445int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
446 struct kvm_translation *tr)
447{
448 return -EINVAL; /* not implemented yet */
449}
450
Jan Kiszkad0bfb942008-12-15 13:52:10 +0100451int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
452 struct kvm_guest_debug *dbg)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100453{
454 return -EINVAL; /* not implemented yet */
455}
456
Marcelo Tosatti62d9f0d2008-04-11 13:24:45 -0300457int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
458 struct kvm_mp_state *mp_state)
459{
460 return -EINVAL; /* not implemented yet */
461}
462
463int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
464 struct kvm_mp_state *mp_state)
465{
466 return -EINVAL; /* not implemented yet */
467}
468
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100469static void __vcpu_run(struct kvm_vcpu *vcpu)
470{
471 memcpy(&vcpu->arch.sie_block->gg14, &vcpu->arch.guest_gprs[14], 16);
472
473 if (need_resched())
474 schedule();
475
Christian Borntraeger71cde582008-05-21 13:37:34 +0200476 if (test_thread_flag(TIF_MCCK_PENDING))
477 s390_handle_mcck();
478
Carsten Otte0ff31862008-05-21 13:37:37 +0200479 kvm_s390_deliver_pending_interrupts(vcpu);
480
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100481 vcpu->arch.sie_block->icptcode = 0;
482 local_irq_disable();
483 kvm_guest_enter();
484 local_irq_enable();
485 VCPU_EVENT(vcpu, 6, "entering sie flags %x",
486 atomic_read(&vcpu->arch.sie_block->cpuflags));
Carsten Otte1f0d0f02008-05-21 13:37:40 +0200487 if (sie64a(vcpu->arch.sie_block, vcpu->arch.guest_gprs)) {
488 VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction");
489 kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
490 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100491 VCPU_EVENT(vcpu, 6, "exit sie icptcode %d",
492 vcpu->arch.sie_block->icptcode);
493 local_irq_disable();
494 kvm_guest_exit();
495 local_irq_enable();
496
497 memcpy(&vcpu->arch.guest_gprs[14], &vcpu->arch.sie_block->gg14, 16);
498}
499
500int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
501{
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100502 int rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100503 sigset_t sigsaved;
504
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200505rerun_vcpu:
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100506 if (vcpu->sigset_active)
507 sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
508
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100509 atomic_clear_mask(CPUSTAT_STOPPED, &vcpu->arch.sie_block->cpuflags);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100510
Carsten Otteba5c1e92008-03-25 18:47:26 +0100511 BUG_ON(vcpu->kvm->arch.float_int.local_int[vcpu->vcpu_id] == NULL);
512
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100513 switch (kvm_run->exit_reason) {
514 case KVM_EXIT_S390_SIEIC:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100515 case KVM_EXIT_UNKNOWN:
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200516 case KVM_EXIT_INTR:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100517 case KVM_EXIT_S390_RESET:
518 break;
519 default:
520 BUG();
521 }
522
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100523 vcpu->arch.sie_block->gpsw.mask = kvm_run->psw_mask;
524 vcpu->arch.sie_block->gpsw.addr = kvm_run->psw_addr;
525
Heiko Carstensdab4079d2009-06-12 10:26:32 +0200526 might_fault();
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100527
528 do {
529 __vcpu_run(vcpu);
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100530 rc = kvm_handle_sie_intercept(vcpu);
531 } while (!signal_pending(current) && !rc);
532
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200533 if (rc == SIE_INTERCEPT_RERUNVCPU)
534 goto rerun_vcpu;
535
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200536 if (signal_pending(current) && !rc) {
537 kvm_run->exit_reason = KVM_EXIT_INTR;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100538 rc = -EINTR;
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200539 }
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100540
Heiko Carstensb8e660b2010-02-26 22:37:41 +0100541 if (rc == -EOPNOTSUPP) {
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100542 /* intercept cannot be handled in-kernel, prepare kvm-run */
543 kvm_run->exit_reason = KVM_EXIT_S390_SIEIC;
544 kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100545 kvm_run->s390_sieic.ipa = vcpu->arch.sie_block->ipa;
546 kvm_run->s390_sieic.ipb = vcpu->arch.sie_block->ipb;
547 rc = 0;
548 }
549
550 if (rc == -EREMOTE) {
551 /* intercept was handled, but userspace support is needed
552 * kvm_run has been prepared by the handler */
553 rc = 0;
554 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100555
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100556 kvm_run->psw_mask = vcpu->arch.sie_block->gpsw.mask;
557 kvm_run->psw_addr = vcpu->arch.sie_block->gpsw.addr;
558
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100559 if (vcpu->sigset_active)
560 sigprocmask(SIG_SETMASK, &sigsaved, NULL);
561
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100562 vcpu->stat.exit_userspace++;
Heiko Carstens7e8e6ab2008-04-04 15:12:35 +0200563 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100564}
565
Carsten Otte092670c2011-07-24 10:48:22 +0200566static int __guestcopy(struct kvm_vcpu *vcpu, u64 guestdest, void *from,
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100567 unsigned long n, int prefix)
568{
569 if (prefix)
570 return copy_to_guest(vcpu, guestdest, from, n);
571 else
572 return copy_to_guest_absolute(vcpu, guestdest, from, n);
573}
574
575/*
576 * store status at address
577 * we use have two special cases:
578 * KVM_S390_STORE_STATUS_NOADDR: -> 0x1200 on 64 bit
579 * KVM_S390_STORE_STATUS_PREFIXED: -> prefix
580 */
Christian Borntraeger971eb772010-06-12 08:54:13 +0200581int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100582{
Carsten Otte092670c2011-07-24 10:48:22 +0200583 unsigned char archmode = 1;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100584 int prefix;
585
586 if (addr == KVM_S390_STORE_STATUS_NOADDR) {
587 if (copy_to_guest_absolute(vcpu, 163ul, &archmode, 1))
588 return -EFAULT;
589 addr = SAVE_AREA_BASE;
590 prefix = 0;
591 } else if (addr == KVM_S390_STORE_STATUS_PREFIXED) {
592 if (copy_to_guest(vcpu, 163ul, &archmode, 1))
593 return -EFAULT;
594 addr = SAVE_AREA_BASE;
595 prefix = 1;
596 } else
597 prefix = 0;
598
Heiko Carstensf64ca212010-02-26 22:37:32 +0100599 if (__guestcopy(vcpu, addr + offsetof(struct save_area, fp_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100600 vcpu->arch.guest_fpregs.fprs, 128, prefix))
601 return -EFAULT;
602
Heiko Carstensf64ca212010-02-26 22:37:32 +0100603 if (__guestcopy(vcpu, addr + offsetof(struct save_area, gp_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100604 vcpu->arch.guest_gprs, 128, prefix))
605 return -EFAULT;
606
Heiko Carstensf64ca212010-02-26 22:37:32 +0100607 if (__guestcopy(vcpu, addr + offsetof(struct save_area, psw),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100608 &vcpu->arch.sie_block->gpsw, 16, prefix))
609 return -EFAULT;
610
Heiko Carstensf64ca212010-02-26 22:37:32 +0100611 if (__guestcopy(vcpu, addr + offsetof(struct save_area, pref_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100612 &vcpu->arch.sie_block->prefix, 4, prefix))
613 return -EFAULT;
614
615 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100616 addr + offsetof(struct save_area, fp_ctrl_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100617 &vcpu->arch.guest_fpregs.fpc, 4, prefix))
618 return -EFAULT;
619
Heiko Carstensf64ca212010-02-26 22:37:32 +0100620 if (__guestcopy(vcpu, addr + offsetof(struct save_area, tod_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100621 &vcpu->arch.sie_block->todpr, 4, prefix))
622 return -EFAULT;
623
Heiko Carstensf64ca212010-02-26 22:37:32 +0100624 if (__guestcopy(vcpu, addr + offsetof(struct save_area, timer),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100625 &vcpu->arch.sie_block->cputm, 8, prefix))
626 return -EFAULT;
627
Heiko Carstensf64ca212010-02-26 22:37:32 +0100628 if (__guestcopy(vcpu, addr + offsetof(struct save_area, clk_cmp),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100629 &vcpu->arch.sie_block->ckc, 8, prefix))
630 return -EFAULT;
631
Heiko Carstensf64ca212010-02-26 22:37:32 +0100632 if (__guestcopy(vcpu, addr + offsetof(struct save_area, acc_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100633 &vcpu->arch.guest_acrs, 64, prefix))
634 return -EFAULT;
635
636 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100637 addr + offsetof(struct save_area, ctrl_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100638 &vcpu->arch.sie_block->gcr, 128, prefix))
639 return -EFAULT;
640 return 0;
641}
642
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100643long kvm_arch_vcpu_ioctl(struct file *filp,
644 unsigned int ioctl, unsigned long arg)
645{
646 struct kvm_vcpu *vcpu = filp->private_data;
647 void __user *argp = (void __user *)arg;
Avi Kivitybc923cc2010-05-13 12:21:46 +0300648 long r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100649
Avi Kivity93736622010-05-13 12:35:17 +0300650 switch (ioctl) {
651 case KVM_S390_INTERRUPT: {
Carsten Otteba5c1e92008-03-25 18:47:26 +0100652 struct kvm_s390_interrupt s390int;
653
Avi Kivity93736622010-05-13 12:35:17 +0300654 r = -EFAULT;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100655 if (copy_from_user(&s390int, argp, sizeof(s390int)))
Avi Kivity93736622010-05-13 12:35:17 +0300656 break;
657 r = kvm_s390_inject_vcpu(vcpu, &s390int);
658 break;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100659 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100660 case KVM_S390_STORE_STATUS:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300661 r = kvm_s390_vcpu_store_status(vcpu, arg);
662 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100663 case KVM_S390_SET_INITIAL_PSW: {
664 psw_t psw;
665
Avi Kivitybc923cc2010-05-13 12:21:46 +0300666 r = -EFAULT;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100667 if (copy_from_user(&psw, argp, sizeof(psw)))
Avi Kivitybc923cc2010-05-13 12:21:46 +0300668 break;
669 r = kvm_arch_vcpu_ioctl_set_initial_psw(vcpu, psw);
670 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100671 }
672 case KVM_S390_INITIAL_RESET:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300673 r = kvm_arch_vcpu_ioctl_initial_reset(vcpu);
674 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100675 default:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300676 r = -EINVAL;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100677 }
Avi Kivitybc923cc2010-05-13 12:21:46 +0300678 return r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100679}
680
681/* Section: memory related */
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200682int kvm_arch_prepare_memory_region(struct kvm *kvm,
683 struct kvm_memory_slot *memslot,
684 struct kvm_memory_slot old,
685 struct kvm_userspace_memory_region *mem,
686 int user_alloc)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100687{
688 /* A few sanity checks. We can have exactly one memory slot which has
689 to start at guest virtual zero and which has to be located at a
690 page boundary in userland and which has to end at a page boundary.
691 The memory in userland is ok to be fragmented into various different
692 vmas. It is okay to mmap() and munmap() stuff in this slot after
693 doing this call at any time */
694
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200695 if (mem->slot)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100696 return -EINVAL;
697
698 if (mem->guest_phys_addr)
699 return -EINVAL;
700
Carsten Otte598841c2011-07-24 10:48:21 +0200701 if (mem->userspace_addr & 0xffffful)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100702 return -EINVAL;
703
Carsten Otte598841c2011-07-24 10:48:21 +0200704 if (mem->memory_size & 0xffffful)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100705 return -EINVAL;
706
Carsten Otte2668dab2009-05-12 17:21:48 +0200707 if (!user_alloc)
708 return -EINVAL;
709
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200710 return 0;
711}
712
713void kvm_arch_commit_memory_region(struct kvm *kvm,
714 struct kvm_userspace_memory_region *mem,
715 struct kvm_memory_slot old,
716 int user_alloc)
717{
Carsten Ottef7850c92011-07-24 10:48:23 +0200718 int rc;
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200719
Carsten Otte598841c2011-07-24 10:48:21 +0200720
721 rc = gmap_map_segment(kvm->arch.gmap, mem->userspace_addr,
722 mem->guest_phys_addr, mem->memory_size);
723 if (rc)
Carsten Ottef7850c92011-07-24 10:48:23 +0200724 printk(KERN_WARNING "kvm-s390: failed to commit memory region\n");
Carsten Otte598841c2011-07-24 10:48:21 +0200725 return;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100726}
727
Marcelo Tosatti34d4cb82008-07-10 20:49:31 -0300728void kvm_arch_flush_shadow(struct kvm *kvm)
729{
730}
731
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100732static int __init kvm_s390_init(void)
733{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200734 int ret;
Avi Kivity0ee75be2010-04-28 15:39:01 +0300735 ret = kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE);
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200736 if (ret)
737 return ret;
738
739 /*
740 * guests can ask for up to 255+1 double words, we need a full page
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300741 * to hold the maximum amount of facilities. On the other hand, we
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200742 * only set facilities that are known to work in KVM.
743 */
Heiko Carstensc2f0e8c2010-06-08 18:58:09 +0200744 facilities = (unsigned long long *) get_zeroed_page(GFP_KERNEL|GFP_DMA);
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200745 if (!facilities) {
746 kvm_exit();
747 return -ENOMEM;
748 }
Martin Schwidefsky14375bc2010-10-25 16:10:51 +0200749 memcpy(facilities, S390_lowcore.stfle_fac_list, 16);
Christian Borntraeger6d00d002010-10-25 16:10:48 +0200750 facilities[0] &= 0xff00fff3f47c0000ULL;
Christian Borntraeger9950f8b2011-06-06 14:14:39 +0200751 facilities[1] &= 0x201c000000000000ULL;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200752 return 0;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100753}
754
755static void __exit kvm_s390_exit(void)
756{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200757 free_page((unsigned long) facilities);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100758 kvm_exit();
759}
760
761module_init(kvm_s390_init);
762module_exit(kvm_s390_exit);