blob: 1868b89a840fc0a68879d10b9b464a9e7d6609a3 [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 Ehrhardt7697e712011-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 Ehrhardt7697e712011-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
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100135 r = 1;
136 break;
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200137 default:
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100138 r = 0;
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200139 }
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100140 return r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100141}
142
143/* Section: vm related */
144/*
145 * Get (and clear) the dirty memory log for a memory slot.
146 */
147int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
148 struct kvm_dirty_log *log)
149{
150 return 0;
151}
152
153long kvm_arch_vm_ioctl(struct file *filp,
154 unsigned int ioctl, unsigned long arg)
155{
156 struct kvm *kvm = filp->private_data;
157 void __user *argp = (void __user *)arg;
158 int r;
159
160 switch (ioctl) {
Carsten Otteba5c1e92008-03-25 18:47:26 +0100161 case KVM_S390_INTERRUPT: {
162 struct kvm_s390_interrupt s390int;
163
164 r = -EFAULT;
165 if (copy_from_user(&s390int, argp, sizeof(s390int)))
166 break;
167 r = kvm_s390_inject_vm(kvm, &s390int);
168 break;
169 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100170 default:
Avi Kivity367e1312009-08-26 14:57:07 +0300171 r = -ENOTTY;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100172 }
173
174 return r;
175}
176
Carsten Ottee08b9632012-01-04 10:25:20 +0100177int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100178{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100179 int rc;
180 char debug_name[16];
181
Carsten Ottee08b9632012-01-04 10:25:20 +0100182 rc = -EINVAL;
183#ifdef CONFIG_KVM_S390_UCONTROL
184 if (type & ~KVM_VM_S390_UCONTROL)
185 goto out_err;
186 if ((type & KVM_VM_S390_UCONTROL) && (!capable(CAP_SYS_ADMIN)))
187 goto out_err;
188#else
189 if (type)
190 goto out_err;
191#endif
192
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100193 rc = s390_enable_sie();
194 if (rc)
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100195 goto out_err;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100196
Carsten Otteb2904112011-10-18 12:27:13 +0200197 rc = -ENOMEM;
198
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100199 kvm->arch.sca = (struct sca_block *) get_zeroed_page(GFP_KERNEL);
200 if (!kvm->arch.sca)
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100201 goto out_err;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100202
203 sprintf(debug_name, "kvm-%u", current->pid);
204
205 kvm->arch.dbf = debug_register(debug_name, 8, 2, 8 * sizeof(long));
206 if (!kvm->arch.dbf)
207 goto out_nodbf;
208
Carsten Otteba5c1e92008-03-25 18:47:26 +0100209 spin_lock_init(&kvm->arch.float_int.lock);
210 INIT_LIST_HEAD(&kvm->arch.float_int.list);
211
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100212 debug_register_view(kvm->arch.dbf, &debug_sprintf_view);
213 VM_EVENT(kvm, 3, "%s", "vm created");
214
Carsten Ottee08b9632012-01-04 10:25:20 +0100215 if (type & KVM_VM_S390_UCONTROL) {
216 kvm->arch.gmap = NULL;
217 } else {
218 kvm->arch.gmap = gmap_alloc(current->mm);
219 if (!kvm->arch.gmap)
220 goto out_nogmap;
221 }
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100222 return 0;
Carsten Otte598841c2011-07-24 10:48:21 +0200223out_nogmap:
224 debug_unregister(kvm->arch.dbf);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100225out_nodbf:
226 free_page((unsigned long)(kvm->arch.sca));
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100227out_err:
228 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100229}
230
Christian Borntraegerd329c032008-11-26 14:50:27 +0100231void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
232{
233 VCPU_EVENT(vcpu, 3, "%s", "free cpu");
Carsten Otte58f94602012-01-04 10:25:27 +0100234 if (!kvm_is_ucontrol(vcpu->kvm)) {
235 clear_bit(63 - vcpu->vcpu_id,
236 (unsigned long *) &vcpu->kvm->arch.sca->mcn);
237 if (vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda ==
238 (__u64) vcpu->arch.sie_block)
239 vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda = 0;
240 }
Carsten Otteabf4a712009-05-12 17:21:51 +0200241 smp_mb();
Carsten Otte27e03932012-01-04 10:25:21 +0100242
243 if (kvm_is_ucontrol(vcpu->kvm))
244 gmap_free(vcpu->arch.gmap);
245
Christian Borntraegerd329c032008-11-26 14:50:27 +0100246 free_page((unsigned long)(vcpu->arch.sie_block));
Christian Borntraeger6692cef2008-11-26 14:51:08 +0100247 kvm_vcpu_uninit(vcpu);
Christian Borntraegerd329c032008-11-26 14:50:27 +0100248 kfree(vcpu);
249}
250
251static void kvm_free_vcpus(struct kvm *kvm)
252{
253 unsigned int i;
Gleb Natapov988a2ca2009-06-09 15:56:29 +0300254 struct kvm_vcpu *vcpu;
Christian Borntraegerd329c032008-11-26 14:50:27 +0100255
Gleb Natapov988a2ca2009-06-09 15:56:29 +0300256 kvm_for_each_vcpu(i, vcpu, kvm)
257 kvm_arch_vcpu_destroy(vcpu);
258
259 mutex_lock(&kvm->lock);
260 for (i = 0; i < atomic_read(&kvm->online_vcpus); i++)
261 kvm->vcpus[i] = NULL;
262
263 atomic_set(&kvm->online_vcpus, 0);
264 mutex_unlock(&kvm->lock);
Christian Borntraegerd329c032008-11-26 14:50:27 +0100265}
266
Sheng Yangad8ba2c2009-01-06 10:03:02 +0800267void kvm_arch_sync_events(struct kvm *kvm)
268{
269}
270
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100271void kvm_arch_destroy_vm(struct kvm *kvm)
272{
Christian Borntraegerd329c032008-11-26 14:50:27 +0100273 kvm_free_vcpus(kvm);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100274 free_page((unsigned long)(kvm->arch.sca));
Christian Borntraegerd329c032008-11-26 14:50:27 +0100275 debug_unregister(kvm->arch.dbf);
Carsten Otte27e03932012-01-04 10:25:21 +0100276 if (!kvm_is_ucontrol(kvm))
277 gmap_free(kvm->arch.gmap);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100278}
279
280/* Section: vcpu related */
281int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
282{
Carsten Otte27e03932012-01-04 10:25:21 +0100283 if (kvm_is_ucontrol(vcpu->kvm)) {
284 vcpu->arch.gmap = gmap_alloc(current->mm);
285 if (!vcpu->arch.gmap)
286 return -ENOMEM;
287 return 0;
288 }
289
Carsten Otte598841c2011-07-24 10:48:21 +0200290 vcpu->arch.gmap = vcpu->kvm->arch.gmap;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100291 return 0;
292}
293
294void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
295{
Christian Borntraeger6692cef2008-11-26 14:51:08 +0100296 /* Nothing todo */
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100297}
298
299void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
300{
301 save_fp_regs(&vcpu->arch.host_fpregs);
302 save_access_regs(vcpu->arch.host_acrs);
303 vcpu->arch.guest_fpregs.fpc &= FPC_VALID_MASK;
304 restore_fp_regs(&vcpu->arch.guest_fpregs);
305 restore_access_regs(vcpu->arch.guest_acrs);
Christian Borntraeger480e5922011-09-20 17:07:28 +0200306 gmap_enable(vcpu->arch.gmap);
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100307 atomic_set_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100308}
309
310void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
311{
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100312 atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
Christian Borntraeger480e5922011-09-20 17:07:28 +0200313 gmap_disable(vcpu->arch.gmap);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100314 save_fp_regs(&vcpu->arch.guest_fpregs);
315 save_access_regs(vcpu->arch.guest_acrs);
316 restore_fp_regs(&vcpu->arch.host_fpregs);
317 restore_access_regs(vcpu->arch.host_acrs);
318}
319
320static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu)
321{
322 /* this equals initial cpu reset in pop, but we don't switch to ESA */
323 vcpu->arch.sie_block->gpsw.mask = 0UL;
324 vcpu->arch.sie_block->gpsw.addr = 0UL;
Christian Borntraeger8d26cf72012-01-11 11:19:32 +0100325 kvm_s390_set_prefix(vcpu, 0);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100326 vcpu->arch.sie_block->cputm = 0UL;
327 vcpu->arch.sie_block->ckc = 0UL;
328 vcpu->arch.sie_block->todpr = 0;
329 memset(vcpu->arch.sie_block->gcr, 0, 16 * sizeof(__u64));
330 vcpu->arch.sie_block->gcr[0] = 0xE0UL;
331 vcpu->arch.sie_block->gcr[14] = 0xC2000000UL;
332 vcpu->arch.guest_fpregs.fpc = 0;
333 asm volatile("lfpc %0" : : "Q" (vcpu->arch.guest_fpregs.fpc));
334 vcpu->arch.sie_block->gbea = 1;
335}
336
337int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
338{
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100339 atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH |
340 CPUSTAT_SM |
341 CPUSTAT_STOPPED);
Christian Borntraegerfc345312010-06-17 23:16:20 +0200342 vcpu->arch.sie_block->ecb = 6;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100343 vcpu->arch.sie_block->eca = 0xC1002001U;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200344 vcpu->arch.sie_block->fac = (int) (long) facilities;
Christian Borntraegerca872302009-05-12 17:21:49 +0200345 hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
346 tasklet_init(&vcpu->arch.tasklet, kvm_s390_tasklet,
347 (unsigned long) vcpu);
348 vcpu->arch.ckc_timer.function = kvm_s390_idle_wakeup;
Christian Borntraeger453423d2008-03-25 18:47:29 +0100349 get_cpu_id(&vcpu->arch.cpu_id);
Christian Borntraeger92e6ecf2009-03-26 15:23:58 +0100350 vcpu->arch.cpu_id.version = 0xff;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100351 return 0;
352}
353
354struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
355 unsigned int id)
356{
Carsten Otte4d475552011-10-18 12:27:12 +0200357 struct kvm_vcpu *vcpu;
358 int rc = -EINVAL;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100359
Carsten Otte4d475552011-10-18 12:27:12 +0200360 if (id >= KVM_MAX_VCPUS)
361 goto out;
362
363 rc = -ENOMEM;
364
365 vcpu = kzalloc(sizeof(struct kvm_vcpu), GFP_KERNEL);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100366 if (!vcpu)
Carsten Otte4d475552011-10-18 12:27:12 +0200367 goto out;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100368
Christian Borntraeger180c12f2008-06-27 15:05:40 +0200369 vcpu->arch.sie_block = (struct kvm_s390_sie_block *)
370 get_zeroed_page(GFP_KERNEL);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100371
372 if (!vcpu->arch.sie_block)
373 goto out_free_cpu;
374
375 vcpu->arch.sie_block->icpua = id;
Carsten Otte58f94602012-01-04 10:25:27 +0100376 if (!kvm_is_ucontrol(kvm)) {
377 if (!kvm->arch.sca) {
378 WARN_ON_ONCE(1);
379 goto out_free_cpu;
380 }
381 if (!kvm->arch.sca->cpu[id].sda)
382 kvm->arch.sca->cpu[id].sda =
383 (__u64) vcpu->arch.sie_block;
384 vcpu->arch.sie_block->scaoh =
385 (__u32)(((__u64)kvm->arch.sca) >> 32);
386 vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca;
387 set_bit(63 - id, (unsigned long *) &kvm->arch.sca->mcn);
388 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100389
Carsten Otteba5c1e92008-03-25 18:47:26 +0100390 spin_lock_init(&vcpu->arch.local_int.lock);
391 INIT_LIST_HEAD(&vcpu->arch.local_int.list);
392 vcpu->arch.local_int.float_int = &kvm->arch.float_int;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200393 spin_lock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100394 kvm->arch.float_int.local_int[id] = &vcpu->arch.local_int;
395 init_waitqueue_head(&vcpu->arch.local_int.wq);
Christian Borntraeger5288fbf2008-03-25 18:47:31 +0100396 vcpu->arch.local_int.cpuflags = &vcpu->arch.sie_block->cpuflags;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200397 spin_unlock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100398
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100399 rc = kvm_vcpu_init(vcpu, kvm, id);
400 if (rc)
Wei Yongjun7b06bf22010-03-09 14:37:53 +0800401 goto out_free_sie_block;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100402 VM_EVENT(kvm, 3, "create cpu %d at %p, sie block at %p", id, vcpu,
403 vcpu->arch.sie_block);
404
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100405 return vcpu;
Wei Yongjun7b06bf22010-03-09 14:37:53 +0800406out_free_sie_block:
407 free_page((unsigned long)(vcpu->arch.sie_block));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100408out_free_cpu:
409 kfree(vcpu);
Carsten Otte4d475552011-10-18 12:27:12 +0200410out:
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100411 return ERR_PTR(rc);
412}
413
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100414int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
415{
416 /* kvm common code refers to this, but never calls it */
417 BUG();
418 return 0;
419}
420
421static int kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu)
422{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100423 kvm_s390_vcpu_initial_reset(vcpu);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100424 return 0;
425}
426
427int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
428{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100429 memcpy(&vcpu->arch.guest_gprs, &regs->gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100430 return 0;
431}
432
433int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
434{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100435 memcpy(&regs->gprs, &vcpu->arch.guest_gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100436 return 0;
437}
438
439int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
440 struct kvm_sregs *sregs)
441{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100442 memcpy(&vcpu->arch.guest_acrs, &sregs->acrs, sizeof(sregs->acrs));
443 memcpy(&vcpu->arch.sie_block->gcr, &sregs->crs, sizeof(sregs->crs));
Carsten Otte7eef87d2011-10-18 12:27:14 +0200444 restore_access_regs(vcpu->arch.guest_acrs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100445 return 0;
446}
447
448int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
449 struct kvm_sregs *sregs)
450{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100451 memcpy(&sregs->acrs, &vcpu->arch.guest_acrs, sizeof(sregs->acrs));
452 memcpy(&sregs->crs, &vcpu->arch.sie_block->gcr, sizeof(sregs->crs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100453 return 0;
454}
455
456int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
457{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100458 memcpy(&vcpu->arch.guest_fpregs.fprs, &fpu->fprs, sizeof(fpu->fprs));
459 vcpu->arch.guest_fpregs.fpc = fpu->fpc;
Carsten Otte7eef87d2011-10-18 12:27:14 +0200460 restore_fp_regs(&vcpu->arch.guest_fpregs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100461 return 0;
462}
463
464int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
465{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100466 memcpy(&fpu->fprs, &vcpu->arch.guest_fpregs.fprs, sizeof(fpu->fprs));
467 fpu->fpc = vcpu->arch.guest_fpregs.fpc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100468 return 0;
469}
470
471static int kvm_arch_vcpu_ioctl_set_initial_psw(struct kvm_vcpu *vcpu, psw_t psw)
472{
473 int rc = 0;
474
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100475 if (!(atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_STOPPED))
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100476 rc = -EBUSY;
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100477 else {
478 vcpu->run->psw_mask = psw.mask;
479 vcpu->run->psw_addr = psw.addr;
480 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100481 return rc;
482}
483
484int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
485 struct kvm_translation *tr)
486{
487 return -EINVAL; /* not implemented yet */
488}
489
Jan Kiszkad0bfb942008-12-15 13:52:10 +0100490int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
491 struct kvm_guest_debug *dbg)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100492{
493 return -EINVAL; /* not implemented yet */
494}
495
Marcelo Tosatti62d9f0d2008-04-11 13:24:45 -0300496int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
497 struct kvm_mp_state *mp_state)
498{
499 return -EINVAL; /* not implemented yet */
500}
501
502int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
503 struct kvm_mp_state *mp_state)
504{
505 return -EINVAL; /* not implemented yet */
506}
507
Carsten Ottee168bf82012-01-04 10:25:22 +0100508static int __vcpu_run(struct kvm_vcpu *vcpu)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100509{
Carsten Ottee168bf82012-01-04 10:25:22 +0100510 int rc;
511
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100512 memcpy(&vcpu->arch.sie_block->gg14, &vcpu->arch.guest_gprs[14], 16);
513
514 if (need_resched())
515 schedule();
516
Christian Borntraeger71cde582008-05-21 13:37:34 +0200517 if (test_thread_flag(TIF_MCCK_PENDING))
518 s390_handle_mcck();
519
Carsten Otted6b6d162012-01-04 10:25:25 +0100520 if (!kvm_is_ucontrol(vcpu->kvm))
521 kvm_s390_deliver_pending_interrupts(vcpu);
Carsten Otte0ff31862008-05-21 13:37:37 +0200522
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100523 vcpu->arch.sie_block->icptcode = 0;
524 local_irq_disable();
525 kvm_guest_enter();
526 local_irq_enable();
527 VCPU_EVENT(vcpu, 6, "entering sie flags %x",
528 atomic_read(&vcpu->arch.sie_block->cpuflags));
Carsten Ottee168bf82012-01-04 10:25:22 +0100529 rc = sie64a(vcpu->arch.sie_block, vcpu->arch.guest_gprs);
530 if (rc) {
531 if (kvm_is_ucontrol(vcpu->kvm)) {
532 rc = SIE_INTERCEPT_UCONTROL;
533 } else {
534 VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction");
535 kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
536 rc = 0;
537 }
Carsten Otte1f0d0f02008-05-21 13:37:40 +0200538 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100539 VCPU_EVENT(vcpu, 6, "exit sie icptcode %d",
540 vcpu->arch.sie_block->icptcode);
541 local_irq_disable();
542 kvm_guest_exit();
543 local_irq_enable();
544
545 memcpy(&vcpu->arch.guest_gprs[14], &vcpu->arch.sie_block->gg14, 16);
Carsten Ottee168bf82012-01-04 10:25:22 +0100546 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100547}
548
549int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
550{
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100551 int rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100552 sigset_t sigsaved;
553
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200554rerun_vcpu:
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100555 if (vcpu->sigset_active)
556 sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
557
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100558 atomic_clear_mask(CPUSTAT_STOPPED, &vcpu->arch.sie_block->cpuflags);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100559
Carsten Otteba5c1e92008-03-25 18:47:26 +0100560 BUG_ON(vcpu->kvm->arch.float_int.local_int[vcpu->vcpu_id] == NULL);
561
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100562 switch (kvm_run->exit_reason) {
563 case KVM_EXIT_S390_SIEIC:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100564 case KVM_EXIT_UNKNOWN:
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200565 case KVM_EXIT_INTR:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100566 case KVM_EXIT_S390_RESET:
Carsten Ottee168bf82012-01-04 10:25:22 +0100567 case KVM_EXIT_S390_UCONTROL:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100568 break;
569 default:
570 BUG();
571 }
572
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100573 vcpu->arch.sie_block->gpsw.mask = kvm_run->psw_mask;
574 vcpu->arch.sie_block->gpsw.addr = kvm_run->psw_addr;
575
Heiko Carstensdab4079d2009-06-12 10:26:32 +0200576 might_fault();
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100577
578 do {
Carsten Ottee168bf82012-01-04 10:25:22 +0100579 rc = __vcpu_run(vcpu);
580 if (rc)
581 break;
Carsten Ottec0d744a2012-01-04 10:25:24 +0100582 if (kvm_is_ucontrol(vcpu->kvm))
583 rc = -EOPNOTSUPP;
584 else
585 rc = kvm_handle_sie_intercept(vcpu);
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100586 } while (!signal_pending(current) && !rc);
587
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200588 if (rc == SIE_INTERCEPT_RERUNVCPU)
589 goto rerun_vcpu;
590
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200591 if (signal_pending(current) && !rc) {
592 kvm_run->exit_reason = KVM_EXIT_INTR;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100593 rc = -EINTR;
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200594 }
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100595
Carsten Ottee168bf82012-01-04 10:25:22 +0100596#ifdef CONFIG_KVM_S390_UCONTROL
597 if (rc == SIE_INTERCEPT_UCONTROL) {
598 kvm_run->exit_reason = KVM_EXIT_S390_UCONTROL;
599 kvm_run->s390_ucontrol.trans_exc_code =
600 current->thread.gmap_addr;
601 kvm_run->s390_ucontrol.pgm_code = 0x10;
602 rc = 0;
603 }
604#endif
605
Heiko Carstensb8e660b2010-02-26 22:37:41 +0100606 if (rc == -EOPNOTSUPP) {
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100607 /* intercept cannot be handled in-kernel, prepare kvm-run */
608 kvm_run->exit_reason = KVM_EXIT_S390_SIEIC;
609 kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100610 kvm_run->s390_sieic.ipa = vcpu->arch.sie_block->ipa;
611 kvm_run->s390_sieic.ipb = vcpu->arch.sie_block->ipb;
612 rc = 0;
613 }
614
615 if (rc == -EREMOTE) {
616 /* intercept was handled, but userspace support is needed
617 * kvm_run has been prepared by the handler */
618 rc = 0;
619 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100620
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100621 kvm_run->psw_mask = vcpu->arch.sie_block->gpsw.mask;
622 kvm_run->psw_addr = vcpu->arch.sie_block->gpsw.addr;
623
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100624 if (vcpu->sigset_active)
625 sigprocmask(SIG_SETMASK, &sigsaved, NULL);
626
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100627 vcpu->stat.exit_userspace++;
Heiko Carstens7e8e6ab2008-04-04 15:12:35 +0200628 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100629}
630
Carsten Otte092670c2011-07-24 10:48:22 +0200631static int __guestcopy(struct kvm_vcpu *vcpu, u64 guestdest, void *from,
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100632 unsigned long n, int prefix)
633{
634 if (prefix)
635 return copy_to_guest(vcpu, guestdest, from, n);
636 else
637 return copy_to_guest_absolute(vcpu, guestdest, from, n);
638}
639
640/*
641 * store status at address
642 * we use have two special cases:
643 * KVM_S390_STORE_STATUS_NOADDR: -> 0x1200 on 64 bit
644 * KVM_S390_STORE_STATUS_PREFIXED: -> prefix
645 */
Christian Borntraeger971eb772010-06-12 08:54:13 +0200646int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100647{
Carsten Otte092670c2011-07-24 10:48:22 +0200648 unsigned char archmode = 1;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100649 int prefix;
650
651 if (addr == KVM_S390_STORE_STATUS_NOADDR) {
652 if (copy_to_guest_absolute(vcpu, 163ul, &archmode, 1))
653 return -EFAULT;
654 addr = SAVE_AREA_BASE;
655 prefix = 0;
656 } else if (addr == KVM_S390_STORE_STATUS_PREFIXED) {
657 if (copy_to_guest(vcpu, 163ul, &archmode, 1))
658 return -EFAULT;
659 addr = SAVE_AREA_BASE;
660 prefix = 1;
661 } else
662 prefix = 0;
663
Heiko Carstensf64ca212010-02-26 22:37:32 +0100664 if (__guestcopy(vcpu, addr + offsetof(struct save_area, fp_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100665 vcpu->arch.guest_fpregs.fprs, 128, prefix))
666 return -EFAULT;
667
Heiko Carstensf64ca212010-02-26 22:37:32 +0100668 if (__guestcopy(vcpu, addr + offsetof(struct save_area, gp_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100669 vcpu->arch.guest_gprs, 128, prefix))
670 return -EFAULT;
671
Heiko Carstensf64ca212010-02-26 22:37:32 +0100672 if (__guestcopy(vcpu, addr + offsetof(struct save_area, psw),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100673 &vcpu->arch.sie_block->gpsw, 16, prefix))
674 return -EFAULT;
675
Heiko Carstensf64ca212010-02-26 22:37:32 +0100676 if (__guestcopy(vcpu, addr + offsetof(struct save_area, pref_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100677 &vcpu->arch.sie_block->prefix, 4, prefix))
678 return -EFAULT;
679
680 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100681 addr + offsetof(struct save_area, fp_ctrl_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100682 &vcpu->arch.guest_fpregs.fpc, 4, prefix))
683 return -EFAULT;
684
Heiko Carstensf64ca212010-02-26 22:37:32 +0100685 if (__guestcopy(vcpu, addr + offsetof(struct save_area, tod_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100686 &vcpu->arch.sie_block->todpr, 4, prefix))
687 return -EFAULT;
688
Heiko Carstensf64ca212010-02-26 22:37:32 +0100689 if (__guestcopy(vcpu, addr + offsetof(struct save_area, timer),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100690 &vcpu->arch.sie_block->cputm, 8, prefix))
691 return -EFAULT;
692
Heiko Carstensf64ca212010-02-26 22:37:32 +0100693 if (__guestcopy(vcpu, addr + offsetof(struct save_area, clk_cmp),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100694 &vcpu->arch.sie_block->ckc, 8, prefix))
695 return -EFAULT;
696
Heiko Carstensf64ca212010-02-26 22:37:32 +0100697 if (__guestcopy(vcpu, addr + offsetof(struct save_area, acc_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100698 &vcpu->arch.guest_acrs, 64, prefix))
699 return -EFAULT;
700
701 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100702 addr + offsetof(struct save_area, ctrl_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100703 &vcpu->arch.sie_block->gcr, 128, prefix))
704 return -EFAULT;
705 return 0;
706}
707
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100708long kvm_arch_vcpu_ioctl(struct file *filp,
709 unsigned int ioctl, unsigned long arg)
710{
711 struct kvm_vcpu *vcpu = filp->private_data;
712 void __user *argp = (void __user *)arg;
Avi Kivitybc923cc2010-05-13 12:21:46 +0300713 long r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100714
Avi Kivity93736622010-05-13 12:35:17 +0300715 switch (ioctl) {
716 case KVM_S390_INTERRUPT: {
Carsten Otteba5c1e92008-03-25 18:47:26 +0100717 struct kvm_s390_interrupt s390int;
718
Avi Kivity93736622010-05-13 12:35:17 +0300719 r = -EFAULT;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100720 if (copy_from_user(&s390int, argp, sizeof(s390int)))
Avi Kivity93736622010-05-13 12:35:17 +0300721 break;
722 r = kvm_s390_inject_vcpu(vcpu, &s390int);
723 break;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100724 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100725 case KVM_S390_STORE_STATUS:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300726 r = kvm_s390_vcpu_store_status(vcpu, arg);
727 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100728 case KVM_S390_SET_INITIAL_PSW: {
729 psw_t psw;
730
Avi Kivitybc923cc2010-05-13 12:21:46 +0300731 r = -EFAULT;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100732 if (copy_from_user(&psw, argp, sizeof(psw)))
Avi Kivitybc923cc2010-05-13 12:21:46 +0300733 break;
734 r = kvm_arch_vcpu_ioctl_set_initial_psw(vcpu, psw);
735 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100736 }
737 case KVM_S390_INITIAL_RESET:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300738 r = kvm_arch_vcpu_ioctl_initial_reset(vcpu);
739 break;
Carsten Otte27e03932012-01-04 10:25:21 +0100740#ifdef CONFIG_KVM_S390_UCONTROL
741 case KVM_S390_UCAS_MAP: {
742 struct kvm_s390_ucas_mapping ucasmap;
743
744 if (copy_from_user(&ucasmap, argp, sizeof(ucasmap))) {
745 r = -EFAULT;
746 break;
747 }
748
749 if (!kvm_is_ucontrol(vcpu->kvm)) {
750 r = -EINVAL;
751 break;
752 }
753
754 r = gmap_map_segment(vcpu->arch.gmap, ucasmap.user_addr,
755 ucasmap.vcpu_addr, ucasmap.length);
756 break;
757 }
758 case KVM_S390_UCAS_UNMAP: {
759 struct kvm_s390_ucas_mapping ucasmap;
760
761 if (copy_from_user(&ucasmap, argp, sizeof(ucasmap))) {
762 r = -EFAULT;
763 break;
764 }
765
766 if (!kvm_is_ucontrol(vcpu->kvm)) {
767 r = -EINVAL;
768 break;
769 }
770
771 r = gmap_unmap_segment(vcpu->arch.gmap, ucasmap.vcpu_addr,
772 ucasmap.length);
773 break;
774 }
775#endif
Carsten Otteccc79102012-01-04 10:25:26 +0100776 case KVM_S390_VCPU_FAULT: {
777 r = gmap_fault(arg, vcpu->arch.gmap);
778 if (!IS_ERR_VALUE(r))
779 r = 0;
780 break;
781 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100782 default:
Carsten Otte3e6afcf2012-01-04 10:25:30 +0100783 r = -ENOTTY;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100784 }
Avi Kivitybc923cc2010-05-13 12:21:46 +0300785 return r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100786}
787
Carsten Otte5b1c1492012-01-04 10:25:23 +0100788int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
789{
790#ifdef CONFIG_KVM_S390_UCONTROL
791 if ((vmf->pgoff == KVM_S390_SIE_PAGE_OFFSET)
792 && (kvm_is_ucontrol(vcpu->kvm))) {
793 vmf->page = virt_to_page(vcpu->arch.sie_block);
794 get_page(vmf->page);
795 return 0;
796 }
797#endif
798 return VM_FAULT_SIGBUS;
799}
800
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100801/* Section: memory related */
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200802int kvm_arch_prepare_memory_region(struct kvm *kvm,
803 struct kvm_memory_slot *memslot,
804 struct kvm_memory_slot old,
805 struct kvm_userspace_memory_region *mem,
806 int user_alloc)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100807{
808 /* A few sanity checks. We can have exactly one memory slot which has
809 to start at guest virtual zero and which has to be located at a
810 page boundary in userland and which has to end at a page boundary.
811 The memory in userland is ok to be fragmented into various different
812 vmas. It is okay to mmap() and munmap() stuff in this slot after
813 doing this call at any time */
814
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200815 if (mem->slot)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100816 return -EINVAL;
817
818 if (mem->guest_phys_addr)
819 return -EINVAL;
820
Carsten Otte598841c2011-07-24 10:48:21 +0200821 if (mem->userspace_addr & 0xffffful)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100822 return -EINVAL;
823
Carsten Otte598841c2011-07-24 10:48:21 +0200824 if (mem->memory_size & 0xffffful)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100825 return -EINVAL;
826
Carsten Otte2668dab2009-05-12 17:21:48 +0200827 if (!user_alloc)
828 return -EINVAL;
829
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200830 return 0;
831}
832
833void kvm_arch_commit_memory_region(struct kvm *kvm,
834 struct kvm_userspace_memory_region *mem,
835 struct kvm_memory_slot old,
836 int user_alloc)
837{
Carsten Ottef7850c92011-07-24 10:48:23 +0200838 int rc;
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200839
Carsten Otte598841c2011-07-24 10:48:21 +0200840
841 rc = gmap_map_segment(kvm->arch.gmap, mem->userspace_addr,
842 mem->guest_phys_addr, mem->memory_size);
843 if (rc)
Carsten Ottef7850c92011-07-24 10:48:23 +0200844 printk(KERN_WARNING "kvm-s390: failed to commit memory region\n");
Carsten Otte598841c2011-07-24 10:48:21 +0200845 return;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100846}
847
Marcelo Tosatti34d4cb82008-07-10 20:49:31 -0300848void kvm_arch_flush_shadow(struct kvm *kvm)
849{
850}
851
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100852static int __init kvm_s390_init(void)
853{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200854 int ret;
Avi Kivity0ee75be2010-04-28 15:39:01 +0300855 ret = kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE);
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200856 if (ret)
857 return ret;
858
859 /*
860 * guests can ask for up to 255+1 double words, we need a full page
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300861 * to hold the maximum amount of facilities. On the other hand, we
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200862 * only set facilities that are known to work in KVM.
863 */
Heiko Carstensc2f0e8c2010-06-08 18:58:09 +0200864 facilities = (unsigned long long *) get_zeroed_page(GFP_KERNEL|GFP_DMA);
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200865 if (!facilities) {
866 kvm_exit();
867 return -ENOMEM;
868 }
Martin Schwidefsky14375bc2010-10-25 16:10:51 +0200869 memcpy(facilities, S390_lowcore.stfle_fac_list, 16);
Christian Borntraeger6d00d002010-10-25 16:10:48 +0200870 facilities[0] &= 0xff00fff3f47c0000ULL;
Christian Borntraeger9950f8b2011-06-06 14:14:39 +0200871 facilities[1] &= 0x201c000000000000ULL;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200872 return 0;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100873}
874
875static void __exit kvm_s390_exit(void)
876{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200877 free_page((unsigned long) facilities);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100878 kvm_exit();
879}
880
881module_init(kvm_s390_init);
882module_exit(kvm_s390_exit);