blob: 121316ef2e15cbb34442800de2aa505ce5cdf1cc [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:
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 |
294 KVM_SYNC_ACRS;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100295 return 0;
296}
297
298void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
299{
Christian Borntraeger6692cef2008-11-26 14:51:08 +0100300 /* Nothing todo */
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100301}
302
303void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
304{
305 save_fp_regs(&vcpu->arch.host_fpregs);
306 save_access_regs(vcpu->arch.host_acrs);
307 vcpu->arch.guest_fpregs.fpc &= FPC_VALID_MASK;
308 restore_fp_regs(&vcpu->arch.guest_fpregs);
Christian Borntraeger59674c12012-01-11 11:20:33 +0100309 restore_access_regs(vcpu->run->s.regs.acrs);
Christian Borntraeger480e5922011-09-20 17:07:28 +0200310 gmap_enable(vcpu->arch.gmap);
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100311 atomic_set_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100312}
313
314void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
315{
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100316 atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
Christian Borntraeger480e5922011-09-20 17:07:28 +0200317 gmap_disable(vcpu->arch.gmap);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100318 save_fp_regs(&vcpu->arch.guest_fpregs);
Christian Borntraeger59674c12012-01-11 11:20:33 +0100319 save_access_regs(vcpu->run->s.regs.acrs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100320 restore_fp_regs(&vcpu->arch.host_fpregs);
321 restore_access_regs(vcpu->arch.host_acrs);
322}
323
324static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu)
325{
326 /* this equals initial cpu reset in pop, but we don't switch to ESA */
327 vcpu->arch.sie_block->gpsw.mask = 0UL;
328 vcpu->arch.sie_block->gpsw.addr = 0UL;
Christian Borntraeger8d26cf72012-01-11 11:19:32 +0100329 kvm_s390_set_prefix(vcpu, 0);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100330 vcpu->arch.sie_block->cputm = 0UL;
331 vcpu->arch.sie_block->ckc = 0UL;
332 vcpu->arch.sie_block->todpr = 0;
333 memset(vcpu->arch.sie_block->gcr, 0, 16 * sizeof(__u64));
334 vcpu->arch.sie_block->gcr[0] = 0xE0UL;
335 vcpu->arch.sie_block->gcr[14] = 0xC2000000UL;
336 vcpu->arch.guest_fpregs.fpc = 0;
337 asm volatile("lfpc %0" : : "Q" (vcpu->arch.guest_fpregs.fpc));
338 vcpu->arch.sie_block->gbea = 1;
339}
340
341int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
342{
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100343 atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH |
344 CPUSTAT_SM |
345 CPUSTAT_STOPPED);
Christian Borntraegerfc345312010-06-17 23:16:20 +0200346 vcpu->arch.sie_block->ecb = 6;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100347 vcpu->arch.sie_block->eca = 0xC1002001U;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200348 vcpu->arch.sie_block->fac = (int) (long) facilities;
Christian Borntraegerca872302009-05-12 17:21:49 +0200349 hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
350 tasklet_init(&vcpu->arch.tasklet, kvm_s390_tasklet,
351 (unsigned long) vcpu);
352 vcpu->arch.ckc_timer.function = kvm_s390_idle_wakeup;
Christian Borntraeger453423d2008-03-25 18:47:29 +0100353 get_cpu_id(&vcpu->arch.cpu_id);
Christian Borntraeger92e6ecf2009-03-26 15:23:58 +0100354 vcpu->arch.cpu_id.version = 0xff;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100355 return 0;
356}
357
358struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
359 unsigned int id)
360{
Carsten Otte4d475552011-10-18 12:27:12 +0200361 struct kvm_vcpu *vcpu;
362 int rc = -EINVAL;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100363
Carsten Otte4d475552011-10-18 12:27:12 +0200364 if (id >= KVM_MAX_VCPUS)
365 goto out;
366
367 rc = -ENOMEM;
368
369 vcpu = kzalloc(sizeof(struct kvm_vcpu), GFP_KERNEL);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100370 if (!vcpu)
Carsten Otte4d475552011-10-18 12:27:12 +0200371 goto out;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100372
Christian Borntraeger180c12f2008-06-27 15:05:40 +0200373 vcpu->arch.sie_block = (struct kvm_s390_sie_block *)
374 get_zeroed_page(GFP_KERNEL);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100375
376 if (!vcpu->arch.sie_block)
377 goto out_free_cpu;
378
379 vcpu->arch.sie_block->icpua = id;
Carsten Otte58f94602012-01-04 10:25:27 +0100380 if (!kvm_is_ucontrol(kvm)) {
381 if (!kvm->arch.sca) {
382 WARN_ON_ONCE(1);
383 goto out_free_cpu;
384 }
385 if (!kvm->arch.sca->cpu[id].sda)
386 kvm->arch.sca->cpu[id].sda =
387 (__u64) vcpu->arch.sie_block;
388 vcpu->arch.sie_block->scaoh =
389 (__u32)(((__u64)kvm->arch.sca) >> 32);
390 vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca;
391 set_bit(63 - id, (unsigned long *) &kvm->arch.sca->mcn);
392 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100393
Carsten Otteba5c1e92008-03-25 18:47:26 +0100394 spin_lock_init(&vcpu->arch.local_int.lock);
395 INIT_LIST_HEAD(&vcpu->arch.local_int.list);
396 vcpu->arch.local_int.float_int = &kvm->arch.float_int;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200397 spin_lock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100398 kvm->arch.float_int.local_int[id] = &vcpu->arch.local_int;
399 init_waitqueue_head(&vcpu->arch.local_int.wq);
Christian Borntraeger5288fbf2008-03-25 18:47:31 +0100400 vcpu->arch.local_int.cpuflags = &vcpu->arch.sie_block->cpuflags;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200401 spin_unlock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100402
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100403 rc = kvm_vcpu_init(vcpu, kvm, id);
404 if (rc)
Wei Yongjun7b06bf22010-03-09 14:37:53 +0800405 goto out_free_sie_block;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100406 VM_EVENT(kvm, 3, "create cpu %d at %p, sie block at %p", id, vcpu,
407 vcpu->arch.sie_block);
408
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100409 return vcpu;
Wei Yongjun7b06bf22010-03-09 14:37:53 +0800410out_free_sie_block:
411 free_page((unsigned long)(vcpu->arch.sie_block));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100412out_free_cpu:
413 kfree(vcpu);
Carsten Otte4d475552011-10-18 12:27:12 +0200414out:
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100415 return ERR_PTR(rc);
416}
417
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100418int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
419{
420 /* kvm common code refers to this, but never calls it */
421 BUG();
422 return 0;
423}
424
425static int kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu)
426{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100427 kvm_s390_vcpu_initial_reset(vcpu);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100428 return 0;
429}
430
431int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
432{
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100433 memcpy(&vcpu->run->s.regs.gprs, &regs->gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100434 return 0;
435}
436
437int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
438{
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100439 memcpy(&regs->gprs, &vcpu->run->s.regs.gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100440 return 0;
441}
442
443int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
444 struct kvm_sregs *sregs)
445{
Christian Borntraeger59674c12012-01-11 11:20:33 +0100446 memcpy(&vcpu->run->s.regs.acrs, &sregs->acrs, sizeof(sregs->acrs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100447 memcpy(&vcpu->arch.sie_block->gcr, &sregs->crs, sizeof(sregs->crs));
Christian Borntraeger59674c12012-01-11 11:20:33 +0100448 restore_access_regs(vcpu->run->s.regs.acrs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100449 return 0;
450}
451
452int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
453 struct kvm_sregs *sregs)
454{
Christian Borntraeger59674c12012-01-11 11:20:33 +0100455 memcpy(&sregs->acrs, &vcpu->run->s.regs.acrs, sizeof(sregs->acrs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100456 memcpy(&sregs->crs, &vcpu->arch.sie_block->gcr, sizeof(sregs->crs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100457 return 0;
458}
459
460int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
461{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100462 memcpy(&vcpu->arch.guest_fpregs.fprs, &fpu->fprs, sizeof(fpu->fprs));
Christian Borntraeger85175582012-02-06 10:59:02 +0100463 vcpu->arch.guest_fpregs.fpc = fpu->fpc & FPC_VALID_MASK;
Carsten Otte7eef87d2011-10-18 12:27:14 +0200464 restore_fp_regs(&vcpu->arch.guest_fpregs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100465 return 0;
466}
467
468int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
469{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100470 memcpy(&fpu->fprs, &vcpu->arch.guest_fpregs.fprs, sizeof(fpu->fprs));
471 fpu->fpc = vcpu->arch.guest_fpregs.fpc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100472 return 0;
473}
474
475static int kvm_arch_vcpu_ioctl_set_initial_psw(struct kvm_vcpu *vcpu, psw_t psw)
476{
477 int rc = 0;
478
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100479 if (!(atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_STOPPED))
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100480 rc = -EBUSY;
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100481 else {
482 vcpu->run->psw_mask = psw.mask;
483 vcpu->run->psw_addr = psw.addr;
484 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100485 return rc;
486}
487
488int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
489 struct kvm_translation *tr)
490{
491 return -EINVAL; /* not implemented yet */
492}
493
Jan Kiszkad0bfb942008-12-15 13:52:10 +0100494int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
495 struct kvm_guest_debug *dbg)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100496{
497 return -EINVAL; /* not implemented yet */
498}
499
Marcelo Tosatti62d9f0d2008-04-11 13:24:45 -0300500int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
501 struct kvm_mp_state *mp_state)
502{
503 return -EINVAL; /* not implemented yet */
504}
505
506int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
507 struct kvm_mp_state *mp_state)
508{
509 return -EINVAL; /* not implemented yet */
510}
511
Carsten Ottee168bf82012-01-04 10:25:22 +0100512static int __vcpu_run(struct kvm_vcpu *vcpu)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100513{
Carsten Ottee168bf82012-01-04 10:25:22 +0100514 int rc;
515
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100516 memcpy(&vcpu->arch.sie_block->gg14, &vcpu->run->s.regs.gprs[14], 16);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100517
518 if (need_resched())
519 schedule();
520
Christian Borntraeger71cde582008-05-21 13:37:34 +0200521 if (test_thread_flag(TIF_MCCK_PENDING))
522 s390_handle_mcck();
523
Carsten Otted6b6d162012-01-04 10:25:25 +0100524 if (!kvm_is_ucontrol(vcpu->kvm))
525 kvm_s390_deliver_pending_interrupts(vcpu);
Carsten Otte0ff31862008-05-21 13:37:37 +0200526
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100527 vcpu->arch.sie_block->icptcode = 0;
528 local_irq_disable();
529 kvm_guest_enter();
530 local_irq_enable();
531 VCPU_EVENT(vcpu, 6, "entering sie flags %x",
532 atomic_read(&vcpu->arch.sie_block->cpuflags));
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100533 rc = sie64a(vcpu->arch.sie_block, vcpu->run->s.regs.gprs);
Carsten Ottee168bf82012-01-04 10:25:22 +0100534 if (rc) {
535 if (kvm_is_ucontrol(vcpu->kvm)) {
536 rc = SIE_INTERCEPT_UCONTROL;
537 } else {
538 VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction");
539 kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
540 rc = 0;
541 }
Carsten Otte1f0d0f02008-05-21 13:37:40 +0200542 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100543 VCPU_EVENT(vcpu, 6, "exit sie icptcode %d",
544 vcpu->arch.sie_block->icptcode);
545 local_irq_disable();
546 kvm_guest_exit();
547 local_irq_enable();
548
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100549 memcpy(&vcpu->run->s.regs.gprs[14], &vcpu->arch.sie_block->gg14, 16);
Carsten Ottee168bf82012-01-04 10:25:22 +0100550 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100551}
552
553int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
554{
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100555 int rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100556 sigset_t sigsaved;
557
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200558rerun_vcpu:
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100559 if (vcpu->sigset_active)
560 sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
561
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100562 atomic_clear_mask(CPUSTAT_STOPPED, &vcpu->arch.sie_block->cpuflags);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100563
Carsten Otteba5c1e92008-03-25 18:47:26 +0100564 BUG_ON(vcpu->kvm->arch.float_int.local_int[vcpu->vcpu_id] == NULL);
565
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100566 switch (kvm_run->exit_reason) {
567 case KVM_EXIT_S390_SIEIC:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100568 case KVM_EXIT_UNKNOWN:
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200569 case KVM_EXIT_INTR:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100570 case KVM_EXIT_S390_RESET:
Carsten Ottee168bf82012-01-04 10:25:22 +0100571 case KVM_EXIT_S390_UCONTROL:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100572 break;
573 default:
574 BUG();
575 }
576
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100577 vcpu->arch.sie_block->gpsw.mask = kvm_run->psw_mask;
578 vcpu->arch.sie_block->gpsw.addr = kvm_run->psw_addr;
Christian Borntraeger60b413c2012-01-11 11:20:31 +0100579 if (kvm_run->kvm_dirty_regs & KVM_SYNC_PREFIX) {
580 kvm_run->kvm_dirty_regs &= ~KVM_SYNC_PREFIX;
581 kvm_s390_set_prefix(vcpu, kvm_run->s.regs.prefix);
582 }
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100583
Heiko Carstensdab4079d2009-06-12 10:26:32 +0200584 might_fault();
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100585
586 do {
Carsten Ottee168bf82012-01-04 10:25:22 +0100587 rc = __vcpu_run(vcpu);
588 if (rc)
589 break;
Carsten Ottec0d744a2012-01-04 10:25:24 +0100590 if (kvm_is_ucontrol(vcpu->kvm))
591 rc = -EOPNOTSUPP;
592 else
593 rc = kvm_handle_sie_intercept(vcpu);
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100594 } while (!signal_pending(current) && !rc);
595
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200596 if (rc == SIE_INTERCEPT_RERUNVCPU)
597 goto rerun_vcpu;
598
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200599 if (signal_pending(current) && !rc) {
600 kvm_run->exit_reason = KVM_EXIT_INTR;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100601 rc = -EINTR;
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200602 }
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100603
Carsten Ottee168bf82012-01-04 10:25:22 +0100604#ifdef CONFIG_KVM_S390_UCONTROL
605 if (rc == SIE_INTERCEPT_UCONTROL) {
606 kvm_run->exit_reason = KVM_EXIT_S390_UCONTROL;
607 kvm_run->s390_ucontrol.trans_exc_code =
608 current->thread.gmap_addr;
609 kvm_run->s390_ucontrol.pgm_code = 0x10;
610 rc = 0;
611 }
612#endif
613
Heiko Carstensb8e660b2010-02-26 22:37:41 +0100614 if (rc == -EOPNOTSUPP) {
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100615 /* intercept cannot be handled in-kernel, prepare kvm-run */
616 kvm_run->exit_reason = KVM_EXIT_S390_SIEIC;
617 kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100618 kvm_run->s390_sieic.ipa = vcpu->arch.sie_block->ipa;
619 kvm_run->s390_sieic.ipb = vcpu->arch.sie_block->ipb;
620 rc = 0;
621 }
622
623 if (rc == -EREMOTE) {
624 /* intercept was handled, but userspace support is needed
625 * kvm_run has been prepared by the handler */
626 rc = 0;
627 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100628
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100629 kvm_run->psw_mask = vcpu->arch.sie_block->gpsw.mask;
630 kvm_run->psw_addr = vcpu->arch.sie_block->gpsw.addr;
Christian Borntraeger60b413c2012-01-11 11:20:31 +0100631 kvm_run->s.regs.prefix = vcpu->arch.sie_block->prefix;
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100632
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100633 if (vcpu->sigset_active)
634 sigprocmask(SIG_SETMASK, &sigsaved, NULL);
635
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100636 vcpu->stat.exit_userspace++;
Heiko Carstens7e8e6ab2008-04-04 15:12:35 +0200637 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100638}
639
Carsten Otte092670c2011-07-24 10:48:22 +0200640static int __guestcopy(struct kvm_vcpu *vcpu, u64 guestdest, void *from,
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100641 unsigned long n, int prefix)
642{
643 if (prefix)
644 return copy_to_guest(vcpu, guestdest, from, n);
645 else
646 return copy_to_guest_absolute(vcpu, guestdest, from, n);
647}
648
649/*
650 * store status at address
651 * we use have two special cases:
652 * KVM_S390_STORE_STATUS_NOADDR: -> 0x1200 on 64 bit
653 * KVM_S390_STORE_STATUS_PREFIXED: -> prefix
654 */
Christian Borntraeger971eb772010-06-12 08:54:13 +0200655int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100656{
Carsten Otte092670c2011-07-24 10:48:22 +0200657 unsigned char archmode = 1;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100658 int prefix;
659
660 if (addr == KVM_S390_STORE_STATUS_NOADDR) {
661 if (copy_to_guest_absolute(vcpu, 163ul, &archmode, 1))
662 return -EFAULT;
663 addr = SAVE_AREA_BASE;
664 prefix = 0;
665 } else if (addr == KVM_S390_STORE_STATUS_PREFIXED) {
666 if (copy_to_guest(vcpu, 163ul, &archmode, 1))
667 return -EFAULT;
668 addr = SAVE_AREA_BASE;
669 prefix = 1;
670 } else
671 prefix = 0;
672
Heiko Carstensf64ca212010-02-26 22:37:32 +0100673 if (__guestcopy(vcpu, addr + offsetof(struct save_area, fp_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100674 vcpu->arch.guest_fpregs.fprs, 128, prefix))
675 return -EFAULT;
676
Heiko Carstensf64ca212010-02-26 22:37:32 +0100677 if (__guestcopy(vcpu, addr + offsetof(struct save_area, gp_regs),
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100678 vcpu->run->s.regs.gprs, 128, prefix))
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100679 return -EFAULT;
680
Heiko Carstensf64ca212010-02-26 22:37:32 +0100681 if (__guestcopy(vcpu, addr + offsetof(struct save_area, psw),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100682 &vcpu->arch.sie_block->gpsw, 16, prefix))
683 return -EFAULT;
684
Heiko Carstensf64ca212010-02-26 22:37:32 +0100685 if (__guestcopy(vcpu, addr + offsetof(struct save_area, pref_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100686 &vcpu->arch.sie_block->prefix, 4, prefix))
687 return -EFAULT;
688
689 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100690 addr + offsetof(struct save_area, fp_ctrl_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100691 &vcpu->arch.guest_fpregs.fpc, 4, prefix))
692 return -EFAULT;
693
Heiko Carstensf64ca212010-02-26 22:37:32 +0100694 if (__guestcopy(vcpu, addr + offsetof(struct save_area, tod_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100695 &vcpu->arch.sie_block->todpr, 4, prefix))
696 return -EFAULT;
697
Heiko Carstensf64ca212010-02-26 22:37:32 +0100698 if (__guestcopy(vcpu, addr + offsetof(struct save_area, timer),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100699 &vcpu->arch.sie_block->cputm, 8, prefix))
700 return -EFAULT;
701
Heiko Carstensf64ca212010-02-26 22:37:32 +0100702 if (__guestcopy(vcpu, addr + offsetof(struct save_area, clk_cmp),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100703 &vcpu->arch.sie_block->ckc, 8, prefix))
704 return -EFAULT;
705
Heiko Carstensf64ca212010-02-26 22:37:32 +0100706 if (__guestcopy(vcpu, addr + offsetof(struct save_area, acc_regs),
Christian Borntraeger59674c12012-01-11 11:20:33 +0100707 &vcpu->run->s.regs.acrs, 64, prefix))
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100708 return -EFAULT;
709
710 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100711 addr + offsetof(struct save_area, ctrl_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100712 &vcpu->arch.sie_block->gcr, 128, prefix))
713 return -EFAULT;
714 return 0;
715}
716
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100717long kvm_arch_vcpu_ioctl(struct file *filp,
718 unsigned int ioctl, unsigned long arg)
719{
720 struct kvm_vcpu *vcpu = filp->private_data;
721 void __user *argp = (void __user *)arg;
Avi Kivitybc923cc2010-05-13 12:21:46 +0300722 long r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100723
Avi Kivity93736622010-05-13 12:35:17 +0300724 switch (ioctl) {
725 case KVM_S390_INTERRUPT: {
Carsten Otteba5c1e92008-03-25 18:47:26 +0100726 struct kvm_s390_interrupt s390int;
727
Avi Kivity93736622010-05-13 12:35:17 +0300728 r = -EFAULT;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100729 if (copy_from_user(&s390int, argp, sizeof(s390int)))
Avi Kivity93736622010-05-13 12:35:17 +0300730 break;
731 r = kvm_s390_inject_vcpu(vcpu, &s390int);
732 break;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100733 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100734 case KVM_S390_STORE_STATUS:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300735 r = kvm_s390_vcpu_store_status(vcpu, arg);
736 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100737 case KVM_S390_SET_INITIAL_PSW: {
738 psw_t psw;
739
Avi Kivitybc923cc2010-05-13 12:21:46 +0300740 r = -EFAULT;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100741 if (copy_from_user(&psw, argp, sizeof(psw)))
Avi Kivitybc923cc2010-05-13 12:21:46 +0300742 break;
743 r = kvm_arch_vcpu_ioctl_set_initial_psw(vcpu, psw);
744 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100745 }
746 case KVM_S390_INITIAL_RESET:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300747 r = kvm_arch_vcpu_ioctl_initial_reset(vcpu);
748 break;
Carsten Otte27e03932012-01-04 10:25:21 +0100749#ifdef CONFIG_KVM_S390_UCONTROL
750 case KVM_S390_UCAS_MAP: {
751 struct kvm_s390_ucas_mapping ucasmap;
752
753 if (copy_from_user(&ucasmap, argp, sizeof(ucasmap))) {
754 r = -EFAULT;
755 break;
756 }
757
758 if (!kvm_is_ucontrol(vcpu->kvm)) {
759 r = -EINVAL;
760 break;
761 }
762
763 r = gmap_map_segment(vcpu->arch.gmap, ucasmap.user_addr,
764 ucasmap.vcpu_addr, ucasmap.length);
765 break;
766 }
767 case KVM_S390_UCAS_UNMAP: {
768 struct kvm_s390_ucas_mapping ucasmap;
769
770 if (copy_from_user(&ucasmap, argp, sizeof(ucasmap))) {
771 r = -EFAULT;
772 break;
773 }
774
775 if (!kvm_is_ucontrol(vcpu->kvm)) {
776 r = -EINVAL;
777 break;
778 }
779
780 r = gmap_unmap_segment(vcpu->arch.gmap, ucasmap.vcpu_addr,
781 ucasmap.length);
782 break;
783 }
784#endif
Carsten Otteccc79102012-01-04 10:25:26 +0100785 case KVM_S390_VCPU_FAULT: {
786 r = gmap_fault(arg, vcpu->arch.gmap);
787 if (!IS_ERR_VALUE(r))
788 r = 0;
789 break;
790 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100791 default:
Carsten Otte3e6afcf2012-01-04 10:25:30 +0100792 r = -ENOTTY;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100793 }
Avi Kivitybc923cc2010-05-13 12:21:46 +0300794 return r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100795}
796
Carsten Otte5b1c1492012-01-04 10:25:23 +0100797int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
798{
799#ifdef CONFIG_KVM_S390_UCONTROL
800 if ((vmf->pgoff == KVM_S390_SIE_PAGE_OFFSET)
801 && (kvm_is_ucontrol(vcpu->kvm))) {
802 vmf->page = virt_to_page(vcpu->arch.sie_block);
803 get_page(vmf->page);
804 return 0;
805 }
806#endif
807 return VM_FAULT_SIGBUS;
808}
809
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100810/* Section: memory related */
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200811int kvm_arch_prepare_memory_region(struct kvm *kvm,
812 struct kvm_memory_slot *memslot,
813 struct kvm_memory_slot old,
814 struct kvm_userspace_memory_region *mem,
815 int user_alloc)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100816{
817 /* A few sanity checks. We can have exactly one memory slot which has
818 to start at guest virtual zero and which has to be located at a
819 page boundary in userland and which has to end at a page boundary.
820 The memory in userland is ok to be fragmented into various different
821 vmas. It is okay to mmap() and munmap() stuff in this slot after
822 doing this call at any time */
823
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200824 if (mem->slot)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100825 return -EINVAL;
826
827 if (mem->guest_phys_addr)
828 return -EINVAL;
829
Carsten Otte598841c2011-07-24 10:48:21 +0200830 if (mem->userspace_addr & 0xffffful)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100831 return -EINVAL;
832
Carsten Otte598841c2011-07-24 10:48:21 +0200833 if (mem->memory_size & 0xffffful)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100834 return -EINVAL;
835
Carsten Otte2668dab2009-05-12 17:21:48 +0200836 if (!user_alloc)
837 return -EINVAL;
838
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200839 return 0;
840}
841
842void kvm_arch_commit_memory_region(struct kvm *kvm,
843 struct kvm_userspace_memory_region *mem,
844 struct kvm_memory_slot old,
845 int user_alloc)
846{
Carsten Ottef7850c92011-07-24 10:48:23 +0200847 int rc;
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200848
Carsten Otte598841c2011-07-24 10:48:21 +0200849
850 rc = gmap_map_segment(kvm->arch.gmap, mem->userspace_addr,
851 mem->guest_phys_addr, mem->memory_size);
852 if (rc)
Carsten Ottef7850c92011-07-24 10:48:23 +0200853 printk(KERN_WARNING "kvm-s390: failed to commit memory region\n");
Carsten Otte598841c2011-07-24 10:48:21 +0200854 return;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100855}
856
Marcelo Tosatti34d4cb82008-07-10 20:49:31 -0300857void kvm_arch_flush_shadow(struct kvm *kvm)
858{
859}
860
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100861static int __init kvm_s390_init(void)
862{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200863 int ret;
Avi Kivity0ee75be2010-04-28 15:39:01 +0300864 ret = kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE);
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200865 if (ret)
866 return ret;
867
868 /*
869 * guests can ask for up to 255+1 double words, we need a full page
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300870 * to hold the maximum amount of facilities. On the other hand, we
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200871 * only set facilities that are known to work in KVM.
872 */
Heiko Carstensc2f0e8c2010-06-08 18:58:09 +0200873 facilities = (unsigned long long *) get_zeroed_page(GFP_KERNEL|GFP_DMA);
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200874 if (!facilities) {
875 kvm_exit();
876 return -ENOMEM;
877 }
Martin Schwidefsky14375bc2010-10-25 16:10:51 +0200878 memcpy(facilities, S390_lowcore.stfle_fac_list, 16);
Christian Borntraeger6d00d002010-10-25 16:10:48 +0200879 facilities[0] &= 0xff00fff3f47c0000ULL;
Christian Borntraeger9950f8b2011-06-06 14:14:39 +0200880 facilities[1] &= 0x201c000000000000ULL;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200881 return 0;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100882}
883
884static void __exit kvm_s390_exit(void)
885{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200886 free_page((unsigned long) facilities);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100887 kvm_exit();
888}
889
890module_init(kvm_s390_init);
891module_exit(kvm_s390_exit);