blob: 29635678b5ece0a550c198aa227b56ed4a3d6d4b [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:
Christian Borntraegerb6cf8782011-09-20 17:07:29 +0200126 case KVM_CAP_S390_GMAP:
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100127 r = 1;
128 break;
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200129 default:
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100130 r = 0;
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200131 }
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100132 return r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100133}
134
135/* Section: vm related */
136/*
137 * Get (and clear) the dirty memory log for a memory slot.
138 */
139int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
140 struct kvm_dirty_log *log)
141{
142 return 0;
143}
144
145long kvm_arch_vm_ioctl(struct file *filp,
146 unsigned int ioctl, unsigned long arg)
147{
148 struct kvm *kvm = filp->private_data;
149 void __user *argp = (void __user *)arg;
150 int r;
151
152 switch (ioctl) {
Carsten Otteba5c1e92008-03-25 18:47:26 +0100153 case KVM_S390_INTERRUPT: {
154 struct kvm_s390_interrupt s390int;
155
156 r = -EFAULT;
157 if (copy_from_user(&s390int, argp, sizeof(s390int)))
158 break;
159 r = kvm_s390_inject_vm(kvm, &s390int);
160 break;
161 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100162 default:
Avi Kivity367e1312009-08-26 14:57:07 +0300163 r = -ENOTTY;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100164 }
165
166 return r;
167}
168
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100169int kvm_arch_init_vm(struct kvm *kvm)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100170{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100171 int rc;
172 char debug_name[16];
173
174 rc = s390_enable_sie();
175 if (rc)
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100176 goto out_err;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100177
Carsten Otteb2904112011-10-18 12:27:13 +0200178 rc = -ENOMEM;
179
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100180 kvm->arch.sca = (struct sca_block *) get_zeroed_page(GFP_KERNEL);
181 if (!kvm->arch.sca)
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100182 goto out_err;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100183
184 sprintf(debug_name, "kvm-%u", current->pid);
185
186 kvm->arch.dbf = debug_register(debug_name, 8, 2, 8 * sizeof(long));
187 if (!kvm->arch.dbf)
188 goto out_nodbf;
189
Carsten Otteba5c1e92008-03-25 18:47:26 +0100190 spin_lock_init(&kvm->arch.float_int.lock);
191 INIT_LIST_HEAD(&kvm->arch.float_int.list);
192
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100193 debug_register_view(kvm->arch.dbf, &debug_sprintf_view);
194 VM_EVENT(kvm, 3, "%s", "vm created");
195
Carsten Otte598841c2011-07-24 10:48:21 +0200196 kvm->arch.gmap = gmap_alloc(current->mm);
197 if (!kvm->arch.gmap)
198 goto out_nogmap;
199
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100200 return 0;
Carsten Otte598841c2011-07-24 10:48:21 +0200201out_nogmap:
202 debug_unregister(kvm->arch.dbf);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100203out_nodbf:
204 free_page((unsigned long)(kvm->arch.sca));
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100205out_err:
206 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100207}
208
Christian Borntraegerd329c032008-11-26 14:50:27 +0100209void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
210{
211 VCPU_EVENT(vcpu, 3, "%s", "free cpu");
Christian Borntraegerfc345312010-06-17 23:16:20 +0200212 clear_bit(63 - vcpu->vcpu_id, (unsigned long *) &vcpu->kvm->arch.sca->mcn);
Carsten Otteabf4a712009-05-12 17:21:51 +0200213 if (vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda ==
214 (__u64) vcpu->arch.sie_block)
215 vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda = 0;
216 smp_mb();
Christian Borntraegerd329c032008-11-26 14:50:27 +0100217 free_page((unsigned long)(vcpu->arch.sie_block));
Christian Borntraeger6692cef2008-11-26 14:51:08 +0100218 kvm_vcpu_uninit(vcpu);
Christian Borntraegerd329c032008-11-26 14:50:27 +0100219 kfree(vcpu);
220}
221
222static void kvm_free_vcpus(struct kvm *kvm)
223{
224 unsigned int i;
Gleb Natapov988a2ca2009-06-09 15:56:29 +0300225 struct kvm_vcpu *vcpu;
Christian Borntraegerd329c032008-11-26 14:50:27 +0100226
Gleb Natapov988a2ca2009-06-09 15:56:29 +0300227 kvm_for_each_vcpu(i, vcpu, kvm)
228 kvm_arch_vcpu_destroy(vcpu);
229
230 mutex_lock(&kvm->lock);
231 for (i = 0; i < atomic_read(&kvm->online_vcpus); i++)
232 kvm->vcpus[i] = NULL;
233
234 atomic_set(&kvm->online_vcpus, 0);
235 mutex_unlock(&kvm->lock);
Christian Borntraegerd329c032008-11-26 14:50:27 +0100236}
237
Sheng Yangad8ba2c2009-01-06 10:03:02 +0800238void kvm_arch_sync_events(struct kvm *kvm)
239{
240}
241
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100242void kvm_arch_destroy_vm(struct kvm *kvm)
243{
Christian Borntraegerd329c032008-11-26 14:50:27 +0100244 kvm_free_vcpus(kvm);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100245 free_page((unsigned long)(kvm->arch.sca));
Christian Borntraegerd329c032008-11-26 14:50:27 +0100246 debug_unregister(kvm->arch.dbf);
Carsten Otte598841c2011-07-24 10:48:21 +0200247 gmap_free(kvm->arch.gmap);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100248}
249
250/* Section: vcpu related */
251int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
252{
Carsten Otte598841c2011-07-24 10:48:21 +0200253 vcpu->arch.gmap = vcpu->kvm->arch.gmap;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100254 return 0;
255}
256
257void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
258{
Christian Borntraeger6692cef2008-11-26 14:51:08 +0100259 /* Nothing todo */
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100260}
261
262void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
263{
264 save_fp_regs(&vcpu->arch.host_fpregs);
265 save_access_regs(vcpu->arch.host_acrs);
266 vcpu->arch.guest_fpregs.fpc &= FPC_VALID_MASK;
267 restore_fp_regs(&vcpu->arch.guest_fpregs);
268 restore_access_regs(vcpu->arch.guest_acrs);
Christian Borntraeger480e5922011-09-20 17:07:28 +0200269 gmap_enable(vcpu->arch.gmap);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100270}
271
272void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
273{
Christian Borntraeger480e5922011-09-20 17:07:28 +0200274 gmap_disable(vcpu->arch.gmap);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100275 save_fp_regs(&vcpu->arch.guest_fpregs);
276 save_access_regs(vcpu->arch.guest_acrs);
277 restore_fp_regs(&vcpu->arch.host_fpregs);
278 restore_access_regs(vcpu->arch.host_acrs);
279}
280
281static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu)
282{
283 /* this equals initial cpu reset in pop, but we don't switch to ESA */
284 vcpu->arch.sie_block->gpsw.mask = 0UL;
285 vcpu->arch.sie_block->gpsw.addr = 0UL;
286 vcpu->arch.sie_block->prefix = 0UL;
287 vcpu->arch.sie_block->ihcpu = 0xffff;
288 vcpu->arch.sie_block->cputm = 0UL;
289 vcpu->arch.sie_block->ckc = 0UL;
290 vcpu->arch.sie_block->todpr = 0;
291 memset(vcpu->arch.sie_block->gcr, 0, 16 * sizeof(__u64));
292 vcpu->arch.sie_block->gcr[0] = 0xE0UL;
293 vcpu->arch.sie_block->gcr[14] = 0xC2000000UL;
294 vcpu->arch.guest_fpregs.fpc = 0;
295 asm volatile("lfpc %0" : : "Q" (vcpu->arch.guest_fpregs.fpc));
296 vcpu->arch.sie_block->gbea = 1;
297}
298
299int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
300{
Carsten Otte598841c2011-07-24 10:48:21 +0200301 atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH | CPUSTAT_SM);
Christian Borntraegerfc345312010-06-17 23:16:20 +0200302 vcpu->arch.sie_block->ecb = 6;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100303 vcpu->arch.sie_block->eca = 0xC1002001U;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200304 vcpu->arch.sie_block->fac = (int) (long) facilities;
Christian Borntraegerca872302009-05-12 17:21:49 +0200305 hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
306 tasklet_init(&vcpu->arch.tasklet, kvm_s390_tasklet,
307 (unsigned long) vcpu);
308 vcpu->arch.ckc_timer.function = kvm_s390_idle_wakeup;
Christian Borntraeger453423d2008-03-25 18:47:29 +0100309 get_cpu_id(&vcpu->arch.cpu_id);
Christian Borntraeger92e6ecf2009-03-26 15:23:58 +0100310 vcpu->arch.cpu_id.version = 0xff;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100311 return 0;
312}
313
314struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
315 unsigned int id)
316{
Carsten Otte4d475552011-10-18 12:27:12 +0200317 struct kvm_vcpu *vcpu;
318 int rc = -EINVAL;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100319
Carsten Otte4d475552011-10-18 12:27:12 +0200320 if (id >= KVM_MAX_VCPUS)
321 goto out;
322
323 rc = -ENOMEM;
324
325 vcpu = kzalloc(sizeof(struct kvm_vcpu), GFP_KERNEL);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100326 if (!vcpu)
Carsten Otte4d475552011-10-18 12:27:12 +0200327 goto out;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100328
Christian Borntraeger180c12f2008-06-27 15:05:40 +0200329 vcpu->arch.sie_block = (struct kvm_s390_sie_block *)
330 get_zeroed_page(GFP_KERNEL);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100331
332 if (!vcpu->arch.sie_block)
333 goto out_free_cpu;
334
335 vcpu->arch.sie_block->icpua = id;
336 BUG_ON(!kvm->arch.sca);
Carsten Otteabf4a712009-05-12 17:21:51 +0200337 if (!kvm->arch.sca->cpu[id].sda)
338 kvm->arch.sca->cpu[id].sda = (__u64) vcpu->arch.sie_block;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100339 vcpu->arch.sie_block->scaoh = (__u32)(((__u64)kvm->arch.sca) >> 32);
340 vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca;
Christian Borntraegerfc345312010-06-17 23:16:20 +0200341 set_bit(63 - id, (unsigned long *) &kvm->arch.sca->mcn);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100342
Carsten Otteba5c1e92008-03-25 18:47:26 +0100343 spin_lock_init(&vcpu->arch.local_int.lock);
344 INIT_LIST_HEAD(&vcpu->arch.local_int.list);
345 vcpu->arch.local_int.float_int = &kvm->arch.float_int;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200346 spin_lock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100347 kvm->arch.float_int.local_int[id] = &vcpu->arch.local_int;
348 init_waitqueue_head(&vcpu->arch.local_int.wq);
Christian Borntraeger5288fbf2008-03-25 18:47:31 +0100349 vcpu->arch.local_int.cpuflags = &vcpu->arch.sie_block->cpuflags;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200350 spin_unlock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100351
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100352 rc = kvm_vcpu_init(vcpu, kvm, id);
353 if (rc)
Wei Yongjun7b06bf22010-03-09 14:37:53 +0800354 goto out_free_sie_block;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100355 VM_EVENT(kvm, 3, "create cpu %d at %p, sie block at %p", id, vcpu,
356 vcpu->arch.sie_block);
357
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100358 return vcpu;
Wei Yongjun7b06bf22010-03-09 14:37:53 +0800359out_free_sie_block:
360 free_page((unsigned long)(vcpu->arch.sie_block));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100361out_free_cpu:
362 kfree(vcpu);
Carsten Otte4d475552011-10-18 12:27:12 +0200363out:
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100364 return ERR_PTR(rc);
365}
366
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100367int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
368{
369 /* kvm common code refers to this, but never calls it */
370 BUG();
371 return 0;
372}
373
374static int kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu)
375{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100376 kvm_s390_vcpu_initial_reset(vcpu);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100377 return 0;
378}
379
380int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
381{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100382 memcpy(&vcpu->arch.guest_gprs, &regs->gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100383 return 0;
384}
385
386int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
387{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100388 memcpy(&regs->gprs, &vcpu->arch.guest_gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100389 return 0;
390}
391
392int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
393 struct kvm_sregs *sregs)
394{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100395 memcpy(&vcpu->arch.guest_acrs, &sregs->acrs, sizeof(sregs->acrs));
396 memcpy(&vcpu->arch.sie_block->gcr, &sregs->crs, sizeof(sregs->crs));
Carsten Otte7eef87d2011-10-18 12:27:14 +0200397 restore_access_regs(vcpu->arch.guest_acrs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100398 return 0;
399}
400
401int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
402 struct kvm_sregs *sregs)
403{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100404 memcpy(&sregs->acrs, &vcpu->arch.guest_acrs, sizeof(sregs->acrs));
405 memcpy(&sregs->crs, &vcpu->arch.sie_block->gcr, sizeof(sregs->crs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100406 return 0;
407}
408
409int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
410{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100411 memcpy(&vcpu->arch.guest_fpregs.fprs, &fpu->fprs, sizeof(fpu->fprs));
412 vcpu->arch.guest_fpregs.fpc = fpu->fpc;
Carsten Otte7eef87d2011-10-18 12:27:14 +0200413 restore_fp_regs(&vcpu->arch.guest_fpregs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100414 return 0;
415}
416
417int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
418{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100419 memcpy(&fpu->fprs, &vcpu->arch.guest_fpregs.fprs, sizeof(fpu->fprs));
420 fpu->fpc = vcpu->arch.guest_fpregs.fpc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100421 return 0;
422}
423
424static int kvm_arch_vcpu_ioctl_set_initial_psw(struct kvm_vcpu *vcpu, psw_t psw)
425{
426 int rc = 0;
427
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100428 if (atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_RUNNING)
429 rc = -EBUSY;
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100430 else {
431 vcpu->run->psw_mask = psw.mask;
432 vcpu->run->psw_addr = psw.addr;
433 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100434 return rc;
435}
436
437int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
438 struct kvm_translation *tr)
439{
440 return -EINVAL; /* not implemented yet */
441}
442
Jan Kiszkad0bfb942008-12-15 13:52:10 +0100443int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
444 struct kvm_guest_debug *dbg)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100445{
446 return -EINVAL; /* not implemented yet */
447}
448
Marcelo Tosatti62d9f0d2008-04-11 13:24:45 -0300449int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
450 struct kvm_mp_state *mp_state)
451{
452 return -EINVAL; /* not implemented yet */
453}
454
455int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
456 struct kvm_mp_state *mp_state)
457{
458 return -EINVAL; /* not implemented yet */
459}
460
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100461static void __vcpu_run(struct kvm_vcpu *vcpu)
462{
463 memcpy(&vcpu->arch.sie_block->gg14, &vcpu->arch.guest_gprs[14], 16);
464
465 if (need_resched())
466 schedule();
467
Christian Borntraeger71cde582008-05-21 13:37:34 +0200468 if (test_thread_flag(TIF_MCCK_PENDING))
469 s390_handle_mcck();
470
Carsten Otte0ff31862008-05-21 13:37:37 +0200471 kvm_s390_deliver_pending_interrupts(vcpu);
472
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100473 vcpu->arch.sie_block->icptcode = 0;
474 local_irq_disable();
475 kvm_guest_enter();
476 local_irq_enable();
477 VCPU_EVENT(vcpu, 6, "entering sie flags %x",
478 atomic_read(&vcpu->arch.sie_block->cpuflags));
Carsten Otte1f0d0f02008-05-21 13:37:40 +0200479 if (sie64a(vcpu->arch.sie_block, vcpu->arch.guest_gprs)) {
480 VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction");
481 kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
482 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100483 VCPU_EVENT(vcpu, 6, "exit sie icptcode %d",
484 vcpu->arch.sie_block->icptcode);
485 local_irq_disable();
486 kvm_guest_exit();
487 local_irq_enable();
488
489 memcpy(&vcpu->arch.guest_gprs[14], &vcpu->arch.sie_block->gg14, 16);
490}
491
492int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
493{
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100494 int rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100495 sigset_t sigsaved;
496
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200497rerun_vcpu:
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100498 if (vcpu->sigset_active)
499 sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
500
501 atomic_set_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
502
Carsten Otteba5c1e92008-03-25 18:47:26 +0100503 BUG_ON(vcpu->kvm->arch.float_int.local_int[vcpu->vcpu_id] == NULL);
504
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100505 switch (kvm_run->exit_reason) {
506 case KVM_EXIT_S390_SIEIC:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100507 case KVM_EXIT_UNKNOWN:
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200508 case KVM_EXIT_INTR:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100509 case KVM_EXIT_S390_RESET:
510 break;
511 default:
512 BUG();
513 }
514
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100515 vcpu->arch.sie_block->gpsw.mask = kvm_run->psw_mask;
516 vcpu->arch.sie_block->gpsw.addr = kvm_run->psw_addr;
517
Heiko Carstensdab4079d2009-06-12 10:26:32 +0200518 might_fault();
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100519
520 do {
521 __vcpu_run(vcpu);
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100522 rc = kvm_handle_sie_intercept(vcpu);
523 } while (!signal_pending(current) && !rc);
524
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200525 if (rc == SIE_INTERCEPT_RERUNVCPU)
526 goto rerun_vcpu;
527
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200528 if (signal_pending(current) && !rc) {
529 kvm_run->exit_reason = KVM_EXIT_INTR;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100530 rc = -EINTR;
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200531 }
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100532
Heiko Carstensb8e660b2010-02-26 22:37:41 +0100533 if (rc == -EOPNOTSUPP) {
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100534 /* intercept cannot be handled in-kernel, prepare kvm-run */
535 kvm_run->exit_reason = KVM_EXIT_S390_SIEIC;
536 kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100537 kvm_run->s390_sieic.ipa = vcpu->arch.sie_block->ipa;
538 kvm_run->s390_sieic.ipb = vcpu->arch.sie_block->ipb;
539 rc = 0;
540 }
541
542 if (rc == -EREMOTE) {
543 /* intercept was handled, but userspace support is needed
544 * kvm_run has been prepared by the handler */
545 rc = 0;
546 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100547
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100548 kvm_run->psw_mask = vcpu->arch.sie_block->gpsw.mask;
549 kvm_run->psw_addr = vcpu->arch.sie_block->gpsw.addr;
550
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100551 if (vcpu->sigset_active)
552 sigprocmask(SIG_SETMASK, &sigsaved, NULL);
553
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100554 vcpu->stat.exit_userspace++;
Heiko Carstens7e8e6ab2008-04-04 15:12:35 +0200555 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100556}
557
Carsten Otte092670c2011-07-24 10:48:22 +0200558static int __guestcopy(struct kvm_vcpu *vcpu, u64 guestdest, void *from,
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100559 unsigned long n, int prefix)
560{
561 if (prefix)
562 return copy_to_guest(vcpu, guestdest, from, n);
563 else
564 return copy_to_guest_absolute(vcpu, guestdest, from, n);
565}
566
567/*
568 * store status at address
569 * we use have two special cases:
570 * KVM_S390_STORE_STATUS_NOADDR: -> 0x1200 on 64 bit
571 * KVM_S390_STORE_STATUS_PREFIXED: -> prefix
572 */
Christian Borntraeger971eb772010-06-12 08:54:13 +0200573int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100574{
Carsten Otte092670c2011-07-24 10:48:22 +0200575 unsigned char archmode = 1;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100576 int prefix;
577
578 if (addr == KVM_S390_STORE_STATUS_NOADDR) {
579 if (copy_to_guest_absolute(vcpu, 163ul, &archmode, 1))
580 return -EFAULT;
581 addr = SAVE_AREA_BASE;
582 prefix = 0;
583 } else if (addr == KVM_S390_STORE_STATUS_PREFIXED) {
584 if (copy_to_guest(vcpu, 163ul, &archmode, 1))
585 return -EFAULT;
586 addr = SAVE_AREA_BASE;
587 prefix = 1;
588 } else
589 prefix = 0;
590
Heiko Carstensf64ca212010-02-26 22:37:32 +0100591 if (__guestcopy(vcpu, addr + offsetof(struct save_area, fp_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100592 vcpu->arch.guest_fpregs.fprs, 128, prefix))
593 return -EFAULT;
594
Heiko Carstensf64ca212010-02-26 22:37:32 +0100595 if (__guestcopy(vcpu, addr + offsetof(struct save_area, gp_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100596 vcpu->arch.guest_gprs, 128, prefix))
597 return -EFAULT;
598
Heiko Carstensf64ca212010-02-26 22:37:32 +0100599 if (__guestcopy(vcpu, addr + offsetof(struct save_area, psw),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100600 &vcpu->arch.sie_block->gpsw, 16, prefix))
601 return -EFAULT;
602
Heiko Carstensf64ca212010-02-26 22:37:32 +0100603 if (__guestcopy(vcpu, addr + offsetof(struct save_area, pref_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100604 &vcpu->arch.sie_block->prefix, 4, prefix))
605 return -EFAULT;
606
607 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100608 addr + offsetof(struct save_area, fp_ctrl_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100609 &vcpu->arch.guest_fpregs.fpc, 4, prefix))
610 return -EFAULT;
611
Heiko Carstensf64ca212010-02-26 22:37:32 +0100612 if (__guestcopy(vcpu, addr + offsetof(struct save_area, tod_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100613 &vcpu->arch.sie_block->todpr, 4, prefix))
614 return -EFAULT;
615
Heiko Carstensf64ca212010-02-26 22:37:32 +0100616 if (__guestcopy(vcpu, addr + offsetof(struct save_area, timer),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100617 &vcpu->arch.sie_block->cputm, 8, prefix))
618 return -EFAULT;
619
Heiko Carstensf64ca212010-02-26 22:37:32 +0100620 if (__guestcopy(vcpu, addr + offsetof(struct save_area, clk_cmp),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100621 &vcpu->arch.sie_block->ckc, 8, prefix))
622 return -EFAULT;
623
Heiko Carstensf64ca212010-02-26 22:37:32 +0100624 if (__guestcopy(vcpu, addr + offsetof(struct save_area, acc_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100625 &vcpu->arch.guest_acrs, 64, prefix))
626 return -EFAULT;
627
628 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100629 addr + offsetof(struct save_area, ctrl_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100630 &vcpu->arch.sie_block->gcr, 128, prefix))
631 return -EFAULT;
632 return 0;
633}
634
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100635long kvm_arch_vcpu_ioctl(struct file *filp,
636 unsigned int ioctl, unsigned long arg)
637{
638 struct kvm_vcpu *vcpu = filp->private_data;
639 void __user *argp = (void __user *)arg;
Avi Kivitybc923cc2010-05-13 12:21:46 +0300640 long r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100641
Avi Kivity93736622010-05-13 12:35:17 +0300642 switch (ioctl) {
643 case KVM_S390_INTERRUPT: {
Carsten Otteba5c1e92008-03-25 18:47:26 +0100644 struct kvm_s390_interrupt s390int;
645
Avi Kivity93736622010-05-13 12:35:17 +0300646 r = -EFAULT;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100647 if (copy_from_user(&s390int, argp, sizeof(s390int)))
Avi Kivity93736622010-05-13 12:35:17 +0300648 break;
649 r = kvm_s390_inject_vcpu(vcpu, &s390int);
650 break;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100651 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100652 case KVM_S390_STORE_STATUS:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300653 r = kvm_s390_vcpu_store_status(vcpu, arg);
654 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100655 case KVM_S390_SET_INITIAL_PSW: {
656 psw_t psw;
657
Avi Kivitybc923cc2010-05-13 12:21:46 +0300658 r = -EFAULT;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100659 if (copy_from_user(&psw, argp, sizeof(psw)))
Avi Kivitybc923cc2010-05-13 12:21:46 +0300660 break;
661 r = kvm_arch_vcpu_ioctl_set_initial_psw(vcpu, psw);
662 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100663 }
664 case KVM_S390_INITIAL_RESET:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300665 r = kvm_arch_vcpu_ioctl_initial_reset(vcpu);
666 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100667 default:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300668 r = -EINVAL;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100669 }
Avi Kivitybc923cc2010-05-13 12:21:46 +0300670 return r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100671}
672
673/* Section: memory related */
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200674int kvm_arch_prepare_memory_region(struct kvm *kvm,
675 struct kvm_memory_slot *memslot,
676 struct kvm_memory_slot old,
677 struct kvm_userspace_memory_region *mem,
678 int user_alloc)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100679{
680 /* A few sanity checks. We can have exactly one memory slot which has
681 to start at guest virtual zero and which has to be located at a
682 page boundary in userland and which has to end at a page boundary.
683 The memory in userland is ok to be fragmented into various different
684 vmas. It is okay to mmap() and munmap() stuff in this slot after
685 doing this call at any time */
686
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200687 if (mem->slot)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100688 return -EINVAL;
689
690 if (mem->guest_phys_addr)
691 return -EINVAL;
692
Carsten Otte598841c2011-07-24 10:48:21 +0200693 if (mem->userspace_addr & 0xffffful)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100694 return -EINVAL;
695
Carsten Otte598841c2011-07-24 10:48:21 +0200696 if (mem->memory_size & 0xffffful)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100697 return -EINVAL;
698
Carsten Otte2668dab2009-05-12 17:21:48 +0200699 if (!user_alloc)
700 return -EINVAL;
701
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200702 return 0;
703}
704
705void kvm_arch_commit_memory_region(struct kvm *kvm,
706 struct kvm_userspace_memory_region *mem,
707 struct kvm_memory_slot old,
708 int user_alloc)
709{
Carsten Ottef7850c92011-07-24 10:48:23 +0200710 int rc;
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200711
Carsten Otte598841c2011-07-24 10:48:21 +0200712
713 rc = gmap_map_segment(kvm->arch.gmap, mem->userspace_addr,
714 mem->guest_phys_addr, mem->memory_size);
715 if (rc)
Carsten Ottef7850c92011-07-24 10:48:23 +0200716 printk(KERN_WARNING "kvm-s390: failed to commit memory region\n");
Carsten Otte598841c2011-07-24 10:48:21 +0200717 return;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100718}
719
Marcelo Tosatti34d4cb82008-07-10 20:49:31 -0300720void kvm_arch_flush_shadow(struct kvm *kvm)
721{
722}
723
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100724static int __init kvm_s390_init(void)
725{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200726 int ret;
Avi Kivity0ee75be2010-04-28 15:39:01 +0300727 ret = kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE);
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200728 if (ret)
729 return ret;
730
731 /*
732 * guests can ask for up to 255+1 double words, we need a full page
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300733 * to hold the maximum amount of facilities. On the other hand, we
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200734 * only set facilities that are known to work in KVM.
735 */
Heiko Carstensc2f0e8c2010-06-08 18:58:09 +0200736 facilities = (unsigned long long *) get_zeroed_page(GFP_KERNEL|GFP_DMA);
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200737 if (!facilities) {
738 kvm_exit();
739 return -ENOMEM;
740 }
Martin Schwidefsky14375bc2010-10-25 16:10:51 +0200741 memcpy(facilities, S390_lowcore.stfle_fac_list, 16);
Christian Borntraeger6d00d002010-10-25 16:10:48 +0200742 facilities[0] &= 0xff00fff3f47c0000ULL;
Christian Borntraeger9950f8b2011-06-06 14:14:39 +0200743 facilities[1] &= 0x201c000000000000ULL;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200744 return 0;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100745}
746
747static void __exit kvm_s390_exit(void)
748{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200749 free_page((unsigned long) facilities);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100750 kvm_exit();
751}
752
753module_init(kvm_s390_init);
754module_exit(kvm_s390_exit);