blob: d30c8350b9493f748030caeb728c6d8b8537c6d5 [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>
David Howellsa0616cd2012-03-28 18:30:02 +010030#include <asm/switch_to.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:
Christian Borntraeger52e16b12011-11-17 11:00:44 +0100131 case KVM_CAP_SYNC_MMU:
Carsten Otte1efd0f52012-01-04 10:25:29 +0100132#ifdef CONFIG_KVM_S390_UCONTROL
133 case KVM_CAP_S390_UCONTROL:
134#endif
Christian Borntraeger60b413c2012-01-11 11:20:31 +0100135 case KVM_CAP_SYNC_REGS:
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100136 r = 1;
137 break;
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200138 default:
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100139 r = 0;
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200140 }
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100141 return r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100142}
143
144/* Section: vm related */
145/*
146 * Get (and clear) the dirty memory log for a memory slot.
147 */
148int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
149 struct kvm_dirty_log *log)
150{
151 return 0;
152}
153
154long kvm_arch_vm_ioctl(struct file *filp,
155 unsigned int ioctl, unsigned long arg)
156{
157 struct kvm *kvm = filp->private_data;
158 void __user *argp = (void __user *)arg;
159 int r;
160
161 switch (ioctl) {
Carsten Otteba5c1e92008-03-25 18:47:26 +0100162 case KVM_S390_INTERRUPT: {
163 struct kvm_s390_interrupt s390int;
164
165 r = -EFAULT;
166 if (copy_from_user(&s390int, argp, sizeof(s390int)))
167 break;
168 r = kvm_s390_inject_vm(kvm, &s390int);
169 break;
170 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100171 default:
Avi Kivity367e1312009-08-26 14:57:07 +0300172 r = -ENOTTY;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100173 }
174
175 return r;
176}
177
Carsten Ottee08b9632012-01-04 10:25:20 +0100178int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100179{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100180 int rc;
181 char debug_name[16];
182
Carsten Ottee08b9632012-01-04 10:25:20 +0100183 rc = -EINVAL;
184#ifdef CONFIG_KVM_S390_UCONTROL
185 if (type & ~KVM_VM_S390_UCONTROL)
186 goto out_err;
187 if ((type & KVM_VM_S390_UCONTROL) && (!capable(CAP_SYS_ADMIN)))
188 goto out_err;
189#else
190 if (type)
191 goto out_err;
192#endif
193
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100194 rc = s390_enable_sie();
195 if (rc)
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100196 goto out_err;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100197
Carsten Otteb2904112011-10-18 12:27:13 +0200198 rc = -ENOMEM;
199
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100200 kvm->arch.sca = (struct sca_block *) get_zeroed_page(GFP_KERNEL);
201 if (!kvm->arch.sca)
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100202 goto out_err;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100203
204 sprintf(debug_name, "kvm-%u", current->pid);
205
206 kvm->arch.dbf = debug_register(debug_name, 8, 2, 8 * sizeof(long));
207 if (!kvm->arch.dbf)
208 goto out_nodbf;
209
Carsten Otteba5c1e92008-03-25 18:47:26 +0100210 spin_lock_init(&kvm->arch.float_int.lock);
211 INIT_LIST_HEAD(&kvm->arch.float_int.list);
212
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100213 debug_register_view(kvm->arch.dbf, &debug_sprintf_view);
214 VM_EVENT(kvm, 3, "%s", "vm created");
215
Carsten Ottee08b9632012-01-04 10:25:20 +0100216 if (type & KVM_VM_S390_UCONTROL) {
217 kvm->arch.gmap = NULL;
218 } else {
219 kvm->arch.gmap = gmap_alloc(current->mm);
220 if (!kvm->arch.gmap)
221 goto out_nogmap;
222 }
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100223 return 0;
Carsten Otte598841c2011-07-24 10:48:21 +0200224out_nogmap:
225 debug_unregister(kvm->arch.dbf);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100226out_nodbf:
227 free_page((unsigned long)(kvm->arch.sca));
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100228out_err:
229 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100230}
231
Christian Borntraegerd329c032008-11-26 14:50:27 +0100232void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
233{
234 VCPU_EVENT(vcpu, 3, "%s", "free cpu");
Carsten Otte58f94602012-01-04 10:25:27 +0100235 if (!kvm_is_ucontrol(vcpu->kvm)) {
236 clear_bit(63 - vcpu->vcpu_id,
237 (unsigned long *) &vcpu->kvm->arch.sca->mcn);
238 if (vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda ==
239 (__u64) vcpu->arch.sie_block)
240 vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda = 0;
241 }
Carsten Otteabf4a712009-05-12 17:21:51 +0200242 smp_mb();
Carsten Otte27e03932012-01-04 10:25:21 +0100243
244 if (kvm_is_ucontrol(vcpu->kvm))
245 gmap_free(vcpu->arch.gmap);
246
Christian Borntraegerd329c032008-11-26 14:50:27 +0100247 free_page((unsigned long)(vcpu->arch.sie_block));
Christian Borntraeger6692cef2008-11-26 14:51:08 +0100248 kvm_vcpu_uninit(vcpu);
Christian Borntraegerd329c032008-11-26 14:50:27 +0100249 kfree(vcpu);
250}
251
252static void kvm_free_vcpus(struct kvm *kvm)
253{
254 unsigned int i;
Gleb Natapov988a2ca2009-06-09 15:56:29 +0300255 struct kvm_vcpu *vcpu;
Christian Borntraegerd329c032008-11-26 14:50:27 +0100256
Gleb Natapov988a2ca2009-06-09 15:56:29 +0300257 kvm_for_each_vcpu(i, vcpu, kvm)
258 kvm_arch_vcpu_destroy(vcpu);
259
260 mutex_lock(&kvm->lock);
261 for (i = 0; i < atomic_read(&kvm->online_vcpus); i++)
262 kvm->vcpus[i] = NULL;
263
264 atomic_set(&kvm->online_vcpus, 0);
265 mutex_unlock(&kvm->lock);
Christian Borntraegerd329c032008-11-26 14:50:27 +0100266}
267
Sheng Yangad8ba2c2009-01-06 10:03:02 +0800268void kvm_arch_sync_events(struct kvm *kvm)
269{
270}
271
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100272void kvm_arch_destroy_vm(struct kvm *kvm)
273{
Christian Borntraegerd329c032008-11-26 14:50:27 +0100274 kvm_free_vcpus(kvm);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100275 free_page((unsigned long)(kvm->arch.sca));
Christian Borntraegerd329c032008-11-26 14:50:27 +0100276 debug_unregister(kvm->arch.dbf);
Carsten Otte27e03932012-01-04 10:25:21 +0100277 if (!kvm_is_ucontrol(kvm))
278 gmap_free(kvm->arch.gmap);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100279}
280
281/* Section: vcpu related */
282int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
283{
Carsten Otte27e03932012-01-04 10:25:21 +0100284 if (kvm_is_ucontrol(vcpu->kvm)) {
285 vcpu->arch.gmap = gmap_alloc(current->mm);
286 if (!vcpu->arch.gmap)
287 return -ENOMEM;
288 return 0;
289 }
290
Carsten Otte598841c2011-07-24 10:48:21 +0200291 vcpu->arch.gmap = vcpu->kvm->arch.gmap;
Christian Borntraeger59674c12012-01-11 11:20:33 +0100292 vcpu->run->kvm_valid_regs = KVM_SYNC_PREFIX |
293 KVM_SYNC_GPRS |
Christian Borntraeger9eed07352012-02-06 10:59:07 +0100294 KVM_SYNC_ACRS |
295 KVM_SYNC_CRS;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100296 return 0;
297}
298
299void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
300{
Christian Borntraeger6692cef2008-11-26 14:51:08 +0100301 /* Nothing todo */
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100302}
303
304void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
305{
306 save_fp_regs(&vcpu->arch.host_fpregs);
307 save_access_regs(vcpu->arch.host_acrs);
308 vcpu->arch.guest_fpregs.fpc &= FPC_VALID_MASK;
309 restore_fp_regs(&vcpu->arch.guest_fpregs);
Christian Borntraeger59674c12012-01-11 11:20:33 +0100310 restore_access_regs(vcpu->run->s.regs.acrs);
Christian Borntraeger480e5922011-09-20 17:07:28 +0200311 gmap_enable(vcpu->arch.gmap);
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100312 atomic_set_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100313}
314
315void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
316{
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100317 atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
Christian Borntraeger480e5922011-09-20 17:07:28 +0200318 gmap_disable(vcpu->arch.gmap);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100319 save_fp_regs(&vcpu->arch.guest_fpregs);
Christian Borntraeger59674c12012-01-11 11:20:33 +0100320 save_access_regs(vcpu->run->s.regs.acrs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100321 restore_fp_regs(&vcpu->arch.host_fpregs);
322 restore_access_regs(vcpu->arch.host_acrs);
323}
324
325static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu)
326{
327 /* this equals initial cpu reset in pop, but we don't switch to ESA */
328 vcpu->arch.sie_block->gpsw.mask = 0UL;
329 vcpu->arch.sie_block->gpsw.addr = 0UL;
Christian Borntraeger8d26cf72012-01-11 11:19:32 +0100330 kvm_s390_set_prefix(vcpu, 0);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100331 vcpu->arch.sie_block->cputm = 0UL;
332 vcpu->arch.sie_block->ckc = 0UL;
333 vcpu->arch.sie_block->todpr = 0;
334 memset(vcpu->arch.sie_block->gcr, 0, 16 * sizeof(__u64));
335 vcpu->arch.sie_block->gcr[0] = 0xE0UL;
336 vcpu->arch.sie_block->gcr[14] = 0xC2000000UL;
337 vcpu->arch.guest_fpregs.fpc = 0;
338 asm volatile("lfpc %0" : : "Q" (vcpu->arch.guest_fpregs.fpc));
339 vcpu->arch.sie_block->gbea = 1;
340}
341
342int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
343{
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100344 atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH |
345 CPUSTAT_SM |
346 CPUSTAT_STOPPED);
Christian Borntraegerfc345312010-06-17 23:16:20 +0200347 vcpu->arch.sie_block->ecb = 6;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100348 vcpu->arch.sie_block->eca = 0xC1002001U;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200349 vcpu->arch.sie_block->fac = (int) (long) facilities;
Christian Borntraegerca872302009-05-12 17:21:49 +0200350 hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
351 tasklet_init(&vcpu->arch.tasklet, kvm_s390_tasklet,
352 (unsigned long) vcpu);
353 vcpu->arch.ckc_timer.function = kvm_s390_idle_wakeup;
Christian Borntraeger453423d2008-03-25 18:47:29 +0100354 get_cpu_id(&vcpu->arch.cpu_id);
Christian Borntraeger92e6ecf2009-03-26 15:23:58 +0100355 vcpu->arch.cpu_id.version = 0xff;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100356 return 0;
357}
358
359struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
360 unsigned int id)
361{
Carsten Otte4d475552011-10-18 12:27:12 +0200362 struct kvm_vcpu *vcpu;
363 int rc = -EINVAL;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100364
Carsten Otte4d475552011-10-18 12:27:12 +0200365 if (id >= KVM_MAX_VCPUS)
366 goto out;
367
368 rc = -ENOMEM;
369
370 vcpu = kzalloc(sizeof(struct kvm_vcpu), GFP_KERNEL);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100371 if (!vcpu)
Carsten Otte4d475552011-10-18 12:27:12 +0200372 goto out;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100373
Christian Borntraeger180c12f2008-06-27 15:05:40 +0200374 vcpu->arch.sie_block = (struct kvm_s390_sie_block *)
375 get_zeroed_page(GFP_KERNEL);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100376
377 if (!vcpu->arch.sie_block)
378 goto out_free_cpu;
379
380 vcpu->arch.sie_block->icpua = id;
Carsten Otte58f94602012-01-04 10:25:27 +0100381 if (!kvm_is_ucontrol(kvm)) {
382 if (!kvm->arch.sca) {
383 WARN_ON_ONCE(1);
384 goto out_free_cpu;
385 }
386 if (!kvm->arch.sca->cpu[id].sda)
387 kvm->arch.sca->cpu[id].sda =
388 (__u64) vcpu->arch.sie_block;
389 vcpu->arch.sie_block->scaoh =
390 (__u32)(((__u64)kvm->arch.sca) >> 32);
391 vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca;
392 set_bit(63 - id, (unsigned long *) &kvm->arch.sca->mcn);
393 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100394
Carsten Otteba5c1e92008-03-25 18:47:26 +0100395 spin_lock_init(&vcpu->arch.local_int.lock);
396 INIT_LIST_HEAD(&vcpu->arch.local_int.list);
397 vcpu->arch.local_int.float_int = &kvm->arch.float_int;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200398 spin_lock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100399 kvm->arch.float_int.local_int[id] = &vcpu->arch.local_int;
400 init_waitqueue_head(&vcpu->arch.local_int.wq);
Christian Borntraeger5288fbf2008-03-25 18:47:31 +0100401 vcpu->arch.local_int.cpuflags = &vcpu->arch.sie_block->cpuflags;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200402 spin_unlock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100403
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100404 rc = kvm_vcpu_init(vcpu, kvm, id);
405 if (rc)
Wei Yongjun7b06bf22010-03-09 14:37:53 +0800406 goto out_free_sie_block;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100407 VM_EVENT(kvm, 3, "create cpu %d at %p, sie block at %p", id, vcpu,
408 vcpu->arch.sie_block);
409
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100410 return vcpu;
Wei Yongjun7b06bf22010-03-09 14:37:53 +0800411out_free_sie_block:
412 free_page((unsigned long)(vcpu->arch.sie_block));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100413out_free_cpu:
414 kfree(vcpu);
Carsten Otte4d475552011-10-18 12:27:12 +0200415out:
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100416 return ERR_PTR(rc);
417}
418
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100419int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
420{
421 /* kvm common code refers to this, but never calls it */
422 BUG();
423 return 0;
424}
425
Christoffer Dallb6d33832012-03-08 16:44:24 -0500426int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
427{
428 /* kvm common code refers to this, but never calls it */
429 BUG();
430 return 0;
431}
432
433
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100434static int kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu)
435{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100436 kvm_s390_vcpu_initial_reset(vcpu);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100437 return 0;
438}
439
440int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
441{
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100442 memcpy(&vcpu->run->s.regs.gprs, &regs->gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100443 return 0;
444}
445
446int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
447{
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100448 memcpy(&regs->gprs, &vcpu->run->s.regs.gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100449 return 0;
450}
451
452int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
453 struct kvm_sregs *sregs)
454{
Christian Borntraeger59674c12012-01-11 11:20:33 +0100455 memcpy(&vcpu->run->s.regs.acrs, &sregs->acrs, sizeof(sregs->acrs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100456 memcpy(&vcpu->arch.sie_block->gcr, &sregs->crs, sizeof(sregs->crs));
Christian Borntraeger59674c12012-01-11 11:20:33 +0100457 restore_access_regs(vcpu->run->s.regs.acrs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100458 return 0;
459}
460
461int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
462 struct kvm_sregs *sregs)
463{
Christian Borntraeger59674c12012-01-11 11:20:33 +0100464 memcpy(&sregs->acrs, &vcpu->run->s.regs.acrs, sizeof(sregs->acrs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100465 memcpy(&sregs->crs, &vcpu->arch.sie_block->gcr, sizeof(sregs->crs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100466 return 0;
467}
468
469int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
470{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100471 memcpy(&vcpu->arch.guest_fpregs.fprs, &fpu->fprs, sizeof(fpu->fprs));
Christian Borntraeger85175582012-02-06 10:59:02 +0100472 vcpu->arch.guest_fpregs.fpc = fpu->fpc & FPC_VALID_MASK;
Carsten Otte7eef87d2011-10-18 12:27:14 +0200473 restore_fp_regs(&vcpu->arch.guest_fpregs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100474 return 0;
475}
476
477int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
478{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100479 memcpy(&fpu->fprs, &vcpu->arch.guest_fpregs.fprs, sizeof(fpu->fprs));
480 fpu->fpc = vcpu->arch.guest_fpregs.fpc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100481 return 0;
482}
483
484static int kvm_arch_vcpu_ioctl_set_initial_psw(struct kvm_vcpu *vcpu, psw_t psw)
485{
486 int rc = 0;
487
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100488 if (!(atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_STOPPED))
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100489 rc = -EBUSY;
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100490 else {
491 vcpu->run->psw_mask = psw.mask;
492 vcpu->run->psw_addr = psw.addr;
493 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100494 return rc;
495}
496
497int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
498 struct kvm_translation *tr)
499{
500 return -EINVAL; /* not implemented yet */
501}
502
Jan Kiszkad0bfb942008-12-15 13:52:10 +0100503int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
504 struct kvm_guest_debug *dbg)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100505{
506 return -EINVAL; /* not implemented yet */
507}
508
Marcelo Tosatti62d9f0d2008-04-11 13:24:45 -0300509int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
510 struct kvm_mp_state *mp_state)
511{
512 return -EINVAL; /* not implemented yet */
513}
514
515int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
516 struct kvm_mp_state *mp_state)
517{
518 return -EINVAL; /* not implemented yet */
519}
520
Carsten Ottee168bf82012-01-04 10:25:22 +0100521static int __vcpu_run(struct kvm_vcpu *vcpu)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100522{
Carsten Ottee168bf82012-01-04 10:25:22 +0100523 int rc;
524
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100525 memcpy(&vcpu->arch.sie_block->gg14, &vcpu->run->s.regs.gprs[14], 16);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100526
527 if (need_resched())
528 schedule();
529
Christian Borntraeger71cde582008-05-21 13:37:34 +0200530 if (test_thread_flag(TIF_MCCK_PENDING))
531 s390_handle_mcck();
532
Carsten Otted6b6d162012-01-04 10:25:25 +0100533 if (!kvm_is_ucontrol(vcpu->kvm))
534 kvm_s390_deliver_pending_interrupts(vcpu);
Carsten Otte0ff31862008-05-21 13:37:37 +0200535
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100536 vcpu->arch.sie_block->icptcode = 0;
537 local_irq_disable();
538 kvm_guest_enter();
539 local_irq_enable();
540 VCPU_EVENT(vcpu, 6, "entering sie flags %x",
541 atomic_read(&vcpu->arch.sie_block->cpuflags));
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100542 rc = sie64a(vcpu->arch.sie_block, vcpu->run->s.regs.gprs);
Carsten Ottee168bf82012-01-04 10:25:22 +0100543 if (rc) {
544 if (kvm_is_ucontrol(vcpu->kvm)) {
545 rc = SIE_INTERCEPT_UCONTROL;
546 } else {
547 VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction");
548 kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
549 rc = 0;
550 }
Carsten Otte1f0d0f02008-05-21 13:37:40 +0200551 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100552 VCPU_EVENT(vcpu, 6, "exit sie icptcode %d",
553 vcpu->arch.sie_block->icptcode);
554 local_irq_disable();
555 kvm_guest_exit();
556 local_irq_enable();
557
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100558 memcpy(&vcpu->run->s.regs.gprs[14], &vcpu->arch.sie_block->gg14, 16);
Carsten Ottee168bf82012-01-04 10:25:22 +0100559 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100560}
561
562int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
563{
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100564 int rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100565 sigset_t sigsaved;
566
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200567rerun_vcpu:
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100568 if (vcpu->sigset_active)
569 sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
570
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100571 atomic_clear_mask(CPUSTAT_STOPPED, &vcpu->arch.sie_block->cpuflags);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100572
Carsten Otteba5c1e92008-03-25 18:47:26 +0100573 BUG_ON(vcpu->kvm->arch.float_int.local_int[vcpu->vcpu_id] == NULL);
574
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100575 switch (kvm_run->exit_reason) {
576 case KVM_EXIT_S390_SIEIC:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100577 case KVM_EXIT_UNKNOWN:
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200578 case KVM_EXIT_INTR:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100579 case KVM_EXIT_S390_RESET:
Carsten Ottee168bf82012-01-04 10:25:22 +0100580 case KVM_EXIT_S390_UCONTROL:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100581 break;
582 default:
583 BUG();
584 }
585
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100586 vcpu->arch.sie_block->gpsw.mask = kvm_run->psw_mask;
587 vcpu->arch.sie_block->gpsw.addr = kvm_run->psw_addr;
Christian Borntraeger60b413c2012-01-11 11:20:31 +0100588 if (kvm_run->kvm_dirty_regs & KVM_SYNC_PREFIX) {
589 kvm_run->kvm_dirty_regs &= ~KVM_SYNC_PREFIX;
590 kvm_s390_set_prefix(vcpu, kvm_run->s.regs.prefix);
591 }
Christian Borntraeger9eed07352012-02-06 10:59:07 +0100592 if (kvm_run->kvm_dirty_regs & KVM_SYNC_CRS) {
593 kvm_run->kvm_dirty_regs &= ~KVM_SYNC_CRS;
594 memcpy(&vcpu->arch.sie_block->gcr, &kvm_run->s.regs.crs, 128);
595 kvm_s390_set_prefix(vcpu, kvm_run->s.regs.prefix);
596 }
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100597
Heiko Carstensdab4079d2009-06-12 10:26:32 +0200598 might_fault();
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100599
600 do {
Carsten Ottee168bf82012-01-04 10:25:22 +0100601 rc = __vcpu_run(vcpu);
602 if (rc)
603 break;
Carsten Ottec0d744a2012-01-04 10:25:24 +0100604 if (kvm_is_ucontrol(vcpu->kvm))
605 rc = -EOPNOTSUPP;
606 else
607 rc = kvm_handle_sie_intercept(vcpu);
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100608 } while (!signal_pending(current) && !rc);
609
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200610 if (rc == SIE_INTERCEPT_RERUNVCPU)
611 goto rerun_vcpu;
612
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200613 if (signal_pending(current) && !rc) {
614 kvm_run->exit_reason = KVM_EXIT_INTR;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100615 rc = -EINTR;
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200616 }
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100617
Carsten Ottee168bf82012-01-04 10:25:22 +0100618#ifdef CONFIG_KVM_S390_UCONTROL
619 if (rc == SIE_INTERCEPT_UCONTROL) {
620 kvm_run->exit_reason = KVM_EXIT_S390_UCONTROL;
621 kvm_run->s390_ucontrol.trans_exc_code =
622 current->thread.gmap_addr;
623 kvm_run->s390_ucontrol.pgm_code = 0x10;
624 rc = 0;
625 }
626#endif
627
Heiko Carstensb8e660b2010-02-26 22:37:41 +0100628 if (rc == -EOPNOTSUPP) {
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100629 /* intercept cannot be handled in-kernel, prepare kvm-run */
630 kvm_run->exit_reason = KVM_EXIT_S390_SIEIC;
631 kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100632 kvm_run->s390_sieic.ipa = vcpu->arch.sie_block->ipa;
633 kvm_run->s390_sieic.ipb = vcpu->arch.sie_block->ipb;
634 rc = 0;
635 }
636
637 if (rc == -EREMOTE) {
638 /* intercept was handled, but userspace support is needed
639 * kvm_run has been prepared by the handler */
640 rc = 0;
641 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100642
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100643 kvm_run->psw_mask = vcpu->arch.sie_block->gpsw.mask;
644 kvm_run->psw_addr = vcpu->arch.sie_block->gpsw.addr;
Christian Borntraeger60b413c2012-01-11 11:20:31 +0100645 kvm_run->s.regs.prefix = vcpu->arch.sie_block->prefix;
Christian Borntraeger9eed07352012-02-06 10:59:07 +0100646 memcpy(&kvm_run->s.regs.crs, &vcpu->arch.sie_block->gcr, 128);
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100647
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100648 if (vcpu->sigset_active)
649 sigprocmask(SIG_SETMASK, &sigsaved, NULL);
650
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100651 vcpu->stat.exit_userspace++;
Heiko Carstens7e8e6ab2008-04-04 15:12:35 +0200652 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100653}
654
Carsten Otte092670c2011-07-24 10:48:22 +0200655static int __guestcopy(struct kvm_vcpu *vcpu, u64 guestdest, void *from,
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100656 unsigned long n, int prefix)
657{
658 if (prefix)
659 return copy_to_guest(vcpu, guestdest, from, n);
660 else
661 return copy_to_guest_absolute(vcpu, guestdest, from, n);
662}
663
664/*
665 * store status at address
666 * we use have two special cases:
667 * KVM_S390_STORE_STATUS_NOADDR: -> 0x1200 on 64 bit
668 * KVM_S390_STORE_STATUS_PREFIXED: -> prefix
669 */
Christian Borntraeger971eb772010-06-12 08:54:13 +0200670int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100671{
Carsten Otte092670c2011-07-24 10:48:22 +0200672 unsigned char archmode = 1;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100673 int prefix;
674
675 if (addr == KVM_S390_STORE_STATUS_NOADDR) {
676 if (copy_to_guest_absolute(vcpu, 163ul, &archmode, 1))
677 return -EFAULT;
678 addr = SAVE_AREA_BASE;
679 prefix = 0;
680 } else if (addr == KVM_S390_STORE_STATUS_PREFIXED) {
681 if (copy_to_guest(vcpu, 163ul, &archmode, 1))
682 return -EFAULT;
683 addr = SAVE_AREA_BASE;
684 prefix = 1;
685 } else
686 prefix = 0;
687
Heiko Carstensf64ca212010-02-26 22:37:32 +0100688 if (__guestcopy(vcpu, addr + offsetof(struct save_area, fp_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100689 vcpu->arch.guest_fpregs.fprs, 128, prefix))
690 return -EFAULT;
691
Heiko Carstensf64ca212010-02-26 22:37:32 +0100692 if (__guestcopy(vcpu, addr + offsetof(struct save_area, gp_regs),
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100693 vcpu->run->s.regs.gprs, 128, prefix))
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100694 return -EFAULT;
695
Heiko Carstensf64ca212010-02-26 22:37:32 +0100696 if (__guestcopy(vcpu, addr + offsetof(struct save_area, psw),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100697 &vcpu->arch.sie_block->gpsw, 16, prefix))
698 return -EFAULT;
699
Heiko Carstensf64ca212010-02-26 22:37:32 +0100700 if (__guestcopy(vcpu, addr + offsetof(struct save_area, pref_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100701 &vcpu->arch.sie_block->prefix, 4, prefix))
702 return -EFAULT;
703
704 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100705 addr + offsetof(struct save_area, fp_ctrl_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100706 &vcpu->arch.guest_fpregs.fpc, 4, prefix))
707 return -EFAULT;
708
Heiko Carstensf64ca212010-02-26 22:37:32 +0100709 if (__guestcopy(vcpu, addr + offsetof(struct save_area, tod_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100710 &vcpu->arch.sie_block->todpr, 4, prefix))
711 return -EFAULT;
712
Heiko Carstensf64ca212010-02-26 22:37:32 +0100713 if (__guestcopy(vcpu, addr + offsetof(struct save_area, timer),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100714 &vcpu->arch.sie_block->cputm, 8, prefix))
715 return -EFAULT;
716
Heiko Carstensf64ca212010-02-26 22:37:32 +0100717 if (__guestcopy(vcpu, addr + offsetof(struct save_area, clk_cmp),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100718 &vcpu->arch.sie_block->ckc, 8, prefix))
719 return -EFAULT;
720
Heiko Carstensf64ca212010-02-26 22:37:32 +0100721 if (__guestcopy(vcpu, addr + offsetof(struct save_area, acc_regs),
Christian Borntraeger59674c12012-01-11 11:20:33 +0100722 &vcpu->run->s.regs.acrs, 64, prefix))
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100723 return -EFAULT;
724
725 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100726 addr + offsetof(struct save_area, ctrl_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100727 &vcpu->arch.sie_block->gcr, 128, prefix))
728 return -EFAULT;
729 return 0;
730}
731
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100732long kvm_arch_vcpu_ioctl(struct file *filp,
733 unsigned int ioctl, unsigned long arg)
734{
735 struct kvm_vcpu *vcpu = filp->private_data;
736 void __user *argp = (void __user *)arg;
Avi Kivitybc923cc2010-05-13 12:21:46 +0300737 long r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100738
Avi Kivity93736622010-05-13 12:35:17 +0300739 switch (ioctl) {
740 case KVM_S390_INTERRUPT: {
Carsten Otteba5c1e92008-03-25 18:47:26 +0100741 struct kvm_s390_interrupt s390int;
742
Avi Kivity93736622010-05-13 12:35:17 +0300743 r = -EFAULT;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100744 if (copy_from_user(&s390int, argp, sizeof(s390int)))
Avi Kivity93736622010-05-13 12:35:17 +0300745 break;
746 r = kvm_s390_inject_vcpu(vcpu, &s390int);
747 break;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100748 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100749 case KVM_S390_STORE_STATUS:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300750 r = kvm_s390_vcpu_store_status(vcpu, arg);
751 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100752 case KVM_S390_SET_INITIAL_PSW: {
753 psw_t psw;
754
Avi Kivitybc923cc2010-05-13 12:21:46 +0300755 r = -EFAULT;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100756 if (copy_from_user(&psw, argp, sizeof(psw)))
Avi Kivitybc923cc2010-05-13 12:21:46 +0300757 break;
758 r = kvm_arch_vcpu_ioctl_set_initial_psw(vcpu, psw);
759 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100760 }
761 case KVM_S390_INITIAL_RESET:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300762 r = kvm_arch_vcpu_ioctl_initial_reset(vcpu);
763 break;
Carsten Otte27e03932012-01-04 10:25:21 +0100764#ifdef CONFIG_KVM_S390_UCONTROL
765 case KVM_S390_UCAS_MAP: {
766 struct kvm_s390_ucas_mapping ucasmap;
767
768 if (copy_from_user(&ucasmap, argp, sizeof(ucasmap))) {
769 r = -EFAULT;
770 break;
771 }
772
773 if (!kvm_is_ucontrol(vcpu->kvm)) {
774 r = -EINVAL;
775 break;
776 }
777
778 r = gmap_map_segment(vcpu->arch.gmap, ucasmap.user_addr,
779 ucasmap.vcpu_addr, ucasmap.length);
780 break;
781 }
782 case KVM_S390_UCAS_UNMAP: {
783 struct kvm_s390_ucas_mapping ucasmap;
784
785 if (copy_from_user(&ucasmap, argp, sizeof(ucasmap))) {
786 r = -EFAULT;
787 break;
788 }
789
790 if (!kvm_is_ucontrol(vcpu->kvm)) {
791 r = -EINVAL;
792 break;
793 }
794
795 r = gmap_unmap_segment(vcpu->arch.gmap, ucasmap.vcpu_addr,
796 ucasmap.length);
797 break;
798 }
799#endif
Carsten Otteccc79102012-01-04 10:25:26 +0100800 case KVM_S390_VCPU_FAULT: {
801 r = gmap_fault(arg, vcpu->arch.gmap);
802 if (!IS_ERR_VALUE(r))
803 r = 0;
804 break;
805 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100806 default:
Carsten Otte3e6afcf2012-01-04 10:25:30 +0100807 r = -ENOTTY;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100808 }
Avi Kivitybc923cc2010-05-13 12:21:46 +0300809 return r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100810}
811
Carsten Otte5b1c1492012-01-04 10:25:23 +0100812int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
813{
814#ifdef CONFIG_KVM_S390_UCONTROL
815 if ((vmf->pgoff == KVM_S390_SIE_PAGE_OFFSET)
816 && (kvm_is_ucontrol(vcpu->kvm))) {
817 vmf->page = virt_to_page(vcpu->arch.sie_block);
818 get_page(vmf->page);
819 return 0;
820 }
821#endif
822 return VM_FAULT_SIGBUS;
823}
824
Takuya Yoshikawadb3fe4e2012-02-08 13:02:18 +0900825void kvm_arch_free_memslot(struct kvm_memory_slot *free,
826 struct kvm_memory_slot *dont)
827{
828}
829
830int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages)
831{
832 return 0;
833}
834
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100835/* Section: memory related */
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200836int kvm_arch_prepare_memory_region(struct kvm *kvm,
837 struct kvm_memory_slot *memslot,
838 struct kvm_memory_slot old,
839 struct kvm_userspace_memory_region *mem,
840 int user_alloc)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100841{
842 /* A few sanity checks. We can have exactly one memory slot which has
843 to start at guest virtual zero and which has to be located at a
844 page boundary in userland and which has to end at a page boundary.
845 The memory in userland is ok to be fragmented into various different
846 vmas. It is okay to mmap() and munmap() stuff in this slot after
847 doing this call at any time */
848
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200849 if (mem->slot)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100850 return -EINVAL;
851
852 if (mem->guest_phys_addr)
853 return -EINVAL;
854
Carsten Otte598841c2011-07-24 10:48:21 +0200855 if (mem->userspace_addr & 0xffffful)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100856 return -EINVAL;
857
Carsten Otte598841c2011-07-24 10:48:21 +0200858 if (mem->memory_size & 0xffffful)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100859 return -EINVAL;
860
Carsten Otte2668dab2009-05-12 17:21:48 +0200861 if (!user_alloc)
862 return -EINVAL;
863
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200864 return 0;
865}
866
867void kvm_arch_commit_memory_region(struct kvm *kvm,
868 struct kvm_userspace_memory_region *mem,
869 struct kvm_memory_slot old,
870 int user_alloc)
871{
Carsten Ottef7850c92011-07-24 10:48:23 +0200872 int rc;
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200873
Carsten Otte598841c2011-07-24 10:48:21 +0200874
875 rc = gmap_map_segment(kvm->arch.gmap, mem->userspace_addr,
876 mem->guest_phys_addr, mem->memory_size);
877 if (rc)
Carsten Ottef7850c92011-07-24 10:48:23 +0200878 printk(KERN_WARNING "kvm-s390: failed to commit memory region\n");
Carsten Otte598841c2011-07-24 10:48:21 +0200879 return;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100880}
881
Marcelo Tosatti34d4cb82008-07-10 20:49:31 -0300882void kvm_arch_flush_shadow(struct kvm *kvm)
883{
884}
885
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100886static int __init kvm_s390_init(void)
887{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200888 int ret;
Avi Kivity0ee75be2010-04-28 15:39:01 +0300889 ret = kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE);
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200890 if (ret)
891 return ret;
892
893 /*
894 * guests can ask for up to 255+1 double words, we need a full page
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300895 * to hold the maximum amount of facilities. On the other hand, we
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200896 * only set facilities that are known to work in KVM.
897 */
Heiko Carstensc2f0e8c2010-06-08 18:58:09 +0200898 facilities = (unsigned long long *) get_zeroed_page(GFP_KERNEL|GFP_DMA);
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200899 if (!facilities) {
900 kvm_exit();
901 return -ENOMEM;
902 }
Martin Schwidefsky14375bc2010-10-25 16:10:51 +0200903 memcpy(facilities, S390_lowcore.stfle_fac_list, 16);
Christian Borntraeger6d00d002010-10-25 16:10:48 +0200904 facilities[0] &= 0xff00fff3f47c0000ULL;
Christian Borntraeger9950f8b2011-06-06 14:14:39 +0200905 facilities[1] &= 0x201c000000000000ULL;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200906 return 0;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100907}
908
909static void __exit kvm_s390_exit(void)
910{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200911 free_page((unsigned long) facilities);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100912 kvm_exit();
913}
914
915module_init(kvm_s390_init);
916module_exit(kvm_s390_exit);