blob: e5e3800b0125c3b904bdc5943857cec755f3999f [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) },
Konstantin Weitz41628d32012-04-25 15:30:38 +020077 { "diagnose_9c", VCPU_STAT(diagnose_9c) },
Heiko Carstensb0c632d2008-03-25 18:47:20 +010078 { NULL }
79};
80
Christian Borntraegeref50f7a2009-06-23 17:24:07 +020081static unsigned long long *facilities;
Heiko Carstensb0c632d2008-03-25 18:47:20 +010082
83/* Section: not file related */
Alexander Graf10474ae2009-09-15 11:37:46 +020084int kvm_arch_hardware_enable(void *garbage)
Heiko Carstensb0c632d2008-03-25 18:47:20 +010085{
86 /* every s390 is virtualization enabled ;-) */
Alexander Graf10474ae2009-09-15 11:37:46 +020087 return 0;
Heiko Carstensb0c632d2008-03-25 18:47:20 +010088}
89
90void kvm_arch_hardware_disable(void *garbage)
91{
92}
93
Heiko Carstensb0c632d2008-03-25 18:47:20 +010094int kvm_arch_hardware_setup(void)
95{
96 return 0;
97}
98
99void kvm_arch_hardware_unsetup(void)
100{
101}
102
103void kvm_arch_check_processor_compat(void *rtn)
104{
105}
106
107int kvm_arch_init(void *opaque)
108{
109 return 0;
110}
111
112void kvm_arch_exit(void)
113{
114}
115
116/* Section: device related */
117long kvm_arch_dev_ioctl(struct file *filp,
118 unsigned int ioctl, unsigned long arg)
119{
120 if (ioctl == KVM_S390_ENABLE_SIE)
121 return s390_enable_sie();
122 return -EINVAL;
123}
124
125int kvm_dev_ioctl_check_extension(long ext)
126{
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100127 int r;
128
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200129 switch (ext) {
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100130 case KVM_CAP_S390_PSW:
Christian Borntraegerb6cf8782011-09-20 17:07:29 +0200131 case KVM_CAP_S390_GMAP:
Christian Borntraeger52e16b12011-11-17 11:00:44 +0100132 case KVM_CAP_SYNC_MMU:
Carsten Otte1efd0f52012-01-04 10:25:29 +0100133#ifdef CONFIG_KVM_S390_UCONTROL
134 case KVM_CAP_S390_UCONTROL:
135#endif
Christian Borntraeger60b413c2012-01-11 11:20:31 +0100136 case KVM_CAP_SYNC_REGS:
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100137 r = 1;
138 break;
Christian Borntraegere726b1b2012-05-02 10:50:38 +0200139 case KVM_CAP_NR_VCPUS:
140 case KVM_CAP_MAX_VCPUS:
141 r = KVM_MAX_VCPUS;
142 break;
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200143 default:
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100144 r = 0;
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200145 }
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100146 return r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100147}
148
149/* Section: vm related */
150/*
151 * Get (and clear) the dirty memory log for a memory slot.
152 */
153int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
154 struct kvm_dirty_log *log)
155{
156 return 0;
157}
158
159long kvm_arch_vm_ioctl(struct file *filp,
160 unsigned int ioctl, unsigned long arg)
161{
162 struct kvm *kvm = filp->private_data;
163 void __user *argp = (void __user *)arg;
164 int r;
165
166 switch (ioctl) {
Carsten Otteba5c1e92008-03-25 18:47:26 +0100167 case KVM_S390_INTERRUPT: {
168 struct kvm_s390_interrupt s390int;
169
170 r = -EFAULT;
171 if (copy_from_user(&s390int, argp, sizeof(s390int)))
172 break;
173 r = kvm_s390_inject_vm(kvm, &s390int);
174 break;
175 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100176 default:
Avi Kivity367e1312009-08-26 14:57:07 +0300177 r = -ENOTTY;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100178 }
179
180 return r;
181}
182
Carsten Ottee08b9632012-01-04 10:25:20 +0100183int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100184{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100185 int rc;
186 char debug_name[16];
187
Carsten Ottee08b9632012-01-04 10:25:20 +0100188 rc = -EINVAL;
189#ifdef CONFIG_KVM_S390_UCONTROL
190 if (type & ~KVM_VM_S390_UCONTROL)
191 goto out_err;
192 if ((type & KVM_VM_S390_UCONTROL) && (!capable(CAP_SYS_ADMIN)))
193 goto out_err;
194#else
195 if (type)
196 goto out_err;
197#endif
198
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100199 rc = s390_enable_sie();
200 if (rc)
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100201 goto out_err;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100202
Carsten Otteb2904112011-10-18 12:27:13 +0200203 rc = -ENOMEM;
204
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100205 kvm->arch.sca = (struct sca_block *) get_zeroed_page(GFP_KERNEL);
206 if (!kvm->arch.sca)
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100207 goto out_err;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100208
209 sprintf(debug_name, "kvm-%u", current->pid);
210
211 kvm->arch.dbf = debug_register(debug_name, 8, 2, 8 * sizeof(long));
212 if (!kvm->arch.dbf)
213 goto out_nodbf;
214
Carsten Otteba5c1e92008-03-25 18:47:26 +0100215 spin_lock_init(&kvm->arch.float_int.lock);
216 INIT_LIST_HEAD(&kvm->arch.float_int.list);
217
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100218 debug_register_view(kvm->arch.dbf, &debug_sprintf_view);
219 VM_EVENT(kvm, 3, "%s", "vm created");
220
Carsten Ottee08b9632012-01-04 10:25:20 +0100221 if (type & KVM_VM_S390_UCONTROL) {
222 kvm->arch.gmap = NULL;
223 } else {
224 kvm->arch.gmap = gmap_alloc(current->mm);
225 if (!kvm->arch.gmap)
226 goto out_nogmap;
227 }
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100228 return 0;
Carsten Otte598841c2011-07-24 10:48:21 +0200229out_nogmap:
230 debug_unregister(kvm->arch.dbf);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100231out_nodbf:
232 free_page((unsigned long)(kvm->arch.sca));
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100233out_err:
234 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100235}
236
Christian Borntraegerd329c032008-11-26 14:50:27 +0100237void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
238{
239 VCPU_EVENT(vcpu, 3, "%s", "free cpu");
Carsten Otte58f94602012-01-04 10:25:27 +0100240 if (!kvm_is_ucontrol(vcpu->kvm)) {
241 clear_bit(63 - vcpu->vcpu_id,
242 (unsigned long *) &vcpu->kvm->arch.sca->mcn);
243 if (vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda ==
244 (__u64) vcpu->arch.sie_block)
245 vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda = 0;
246 }
Carsten Otteabf4a712009-05-12 17:21:51 +0200247 smp_mb();
Carsten Otte27e03932012-01-04 10:25:21 +0100248
249 if (kvm_is_ucontrol(vcpu->kvm))
250 gmap_free(vcpu->arch.gmap);
251
Christian Borntraegerd329c032008-11-26 14:50:27 +0100252 free_page((unsigned long)(vcpu->arch.sie_block));
Christian Borntraeger6692cef2008-11-26 14:51:08 +0100253 kvm_vcpu_uninit(vcpu);
Christian Borntraegerd329c032008-11-26 14:50:27 +0100254 kfree(vcpu);
255}
256
257static void kvm_free_vcpus(struct kvm *kvm)
258{
259 unsigned int i;
Gleb Natapov988a2ca2009-06-09 15:56:29 +0300260 struct kvm_vcpu *vcpu;
Christian Borntraegerd329c032008-11-26 14:50:27 +0100261
Gleb Natapov988a2ca2009-06-09 15:56:29 +0300262 kvm_for_each_vcpu(i, vcpu, kvm)
263 kvm_arch_vcpu_destroy(vcpu);
264
265 mutex_lock(&kvm->lock);
266 for (i = 0; i < atomic_read(&kvm->online_vcpus); i++)
267 kvm->vcpus[i] = NULL;
268
269 atomic_set(&kvm->online_vcpus, 0);
270 mutex_unlock(&kvm->lock);
Christian Borntraegerd329c032008-11-26 14:50:27 +0100271}
272
Sheng Yangad8ba2c2009-01-06 10:03:02 +0800273void kvm_arch_sync_events(struct kvm *kvm)
274{
275}
276
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100277void kvm_arch_destroy_vm(struct kvm *kvm)
278{
Christian Borntraegerd329c032008-11-26 14:50:27 +0100279 kvm_free_vcpus(kvm);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100280 free_page((unsigned long)(kvm->arch.sca));
Christian Borntraegerd329c032008-11-26 14:50:27 +0100281 debug_unregister(kvm->arch.dbf);
Carsten Otte27e03932012-01-04 10:25:21 +0100282 if (!kvm_is_ucontrol(kvm))
283 gmap_free(kvm->arch.gmap);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100284}
285
286/* Section: vcpu related */
287int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
288{
Carsten Otte27e03932012-01-04 10:25:21 +0100289 if (kvm_is_ucontrol(vcpu->kvm)) {
290 vcpu->arch.gmap = gmap_alloc(current->mm);
291 if (!vcpu->arch.gmap)
292 return -ENOMEM;
293 return 0;
294 }
295
Carsten Otte598841c2011-07-24 10:48:21 +0200296 vcpu->arch.gmap = vcpu->kvm->arch.gmap;
Christian Borntraeger59674c12012-01-11 11:20:33 +0100297 vcpu->run->kvm_valid_regs = KVM_SYNC_PREFIX |
298 KVM_SYNC_GPRS |
Christian Borntraeger9eed07352012-02-06 10:59:07 +0100299 KVM_SYNC_ACRS |
300 KVM_SYNC_CRS;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100301 return 0;
302}
303
304void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
305{
Christian Borntraeger6692cef2008-11-26 14:51:08 +0100306 /* Nothing todo */
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100307}
308
309void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
310{
311 save_fp_regs(&vcpu->arch.host_fpregs);
312 save_access_regs(vcpu->arch.host_acrs);
313 vcpu->arch.guest_fpregs.fpc &= FPC_VALID_MASK;
314 restore_fp_regs(&vcpu->arch.guest_fpregs);
Christian Borntraeger59674c12012-01-11 11:20:33 +0100315 restore_access_regs(vcpu->run->s.regs.acrs);
Christian Borntraeger480e5922011-09-20 17:07:28 +0200316 gmap_enable(vcpu->arch.gmap);
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100317 atomic_set_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100318}
319
320void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
321{
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100322 atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
Christian Borntraeger480e5922011-09-20 17:07:28 +0200323 gmap_disable(vcpu->arch.gmap);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100324 save_fp_regs(&vcpu->arch.guest_fpregs);
Christian Borntraeger59674c12012-01-11 11:20:33 +0100325 save_access_regs(vcpu->run->s.regs.acrs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100326 restore_fp_regs(&vcpu->arch.host_fpregs);
327 restore_access_regs(vcpu->arch.host_acrs);
328}
329
330static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu)
331{
332 /* this equals initial cpu reset in pop, but we don't switch to ESA */
333 vcpu->arch.sie_block->gpsw.mask = 0UL;
334 vcpu->arch.sie_block->gpsw.addr = 0UL;
Christian Borntraeger8d26cf72012-01-11 11:19:32 +0100335 kvm_s390_set_prefix(vcpu, 0);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100336 vcpu->arch.sie_block->cputm = 0UL;
337 vcpu->arch.sie_block->ckc = 0UL;
338 vcpu->arch.sie_block->todpr = 0;
339 memset(vcpu->arch.sie_block->gcr, 0, 16 * sizeof(__u64));
340 vcpu->arch.sie_block->gcr[0] = 0xE0UL;
341 vcpu->arch.sie_block->gcr[14] = 0xC2000000UL;
342 vcpu->arch.guest_fpregs.fpc = 0;
343 asm volatile("lfpc %0" : : "Q" (vcpu->arch.guest_fpregs.fpc));
344 vcpu->arch.sie_block->gbea = 1;
345}
346
347int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
348{
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100349 atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH |
350 CPUSTAT_SM |
351 CPUSTAT_STOPPED);
Christian Borntraegerfc345312010-06-17 23:16:20 +0200352 vcpu->arch.sie_block->ecb = 6;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100353 vcpu->arch.sie_block->eca = 0xC1002001U;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200354 vcpu->arch.sie_block->fac = (int) (long) facilities;
Christian Borntraegerca872302009-05-12 17:21:49 +0200355 hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
356 tasklet_init(&vcpu->arch.tasklet, kvm_s390_tasklet,
357 (unsigned long) vcpu);
358 vcpu->arch.ckc_timer.function = kvm_s390_idle_wakeup;
Christian Borntraeger453423d2008-03-25 18:47:29 +0100359 get_cpu_id(&vcpu->arch.cpu_id);
Christian Borntraeger92e6ecf2009-03-26 15:23:58 +0100360 vcpu->arch.cpu_id.version = 0xff;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100361 return 0;
362}
363
364struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
365 unsigned int id)
366{
Carsten Otte4d475552011-10-18 12:27:12 +0200367 struct kvm_vcpu *vcpu;
368 int rc = -EINVAL;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100369
Carsten Otte4d475552011-10-18 12:27:12 +0200370 if (id >= KVM_MAX_VCPUS)
371 goto out;
372
373 rc = -ENOMEM;
374
375 vcpu = kzalloc(sizeof(struct kvm_vcpu), GFP_KERNEL);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100376 if (!vcpu)
Carsten Otte4d475552011-10-18 12:27:12 +0200377 goto out;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100378
Christian Borntraeger180c12f2008-06-27 15:05:40 +0200379 vcpu->arch.sie_block = (struct kvm_s390_sie_block *)
380 get_zeroed_page(GFP_KERNEL);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100381
382 if (!vcpu->arch.sie_block)
383 goto out_free_cpu;
384
385 vcpu->arch.sie_block->icpua = id;
Carsten Otte58f94602012-01-04 10:25:27 +0100386 if (!kvm_is_ucontrol(kvm)) {
387 if (!kvm->arch.sca) {
388 WARN_ON_ONCE(1);
389 goto out_free_cpu;
390 }
391 if (!kvm->arch.sca->cpu[id].sda)
392 kvm->arch.sca->cpu[id].sda =
393 (__u64) vcpu->arch.sie_block;
394 vcpu->arch.sie_block->scaoh =
395 (__u32)(((__u64)kvm->arch.sca) >> 32);
396 vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca;
397 set_bit(63 - id, (unsigned long *) &kvm->arch.sca->mcn);
398 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100399
Carsten Otteba5c1e92008-03-25 18:47:26 +0100400 spin_lock_init(&vcpu->arch.local_int.lock);
401 INIT_LIST_HEAD(&vcpu->arch.local_int.list);
402 vcpu->arch.local_int.float_int = &kvm->arch.float_int;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200403 spin_lock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100404 kvm->arch.float_int.local_int[id] = &vcpu->arch.local_int;
405 init_waitqueue_head(&vcpu->arch.local_int.wq);
Christian Borntraeger5288fbf2008-03-25 18:47:31 +0100406 vcpu->arch.local_int.cpuflags = &vcpu->arch.sie_block->cpuflags;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200407 spin_unlock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100408
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100409 rc = kvm_vcpu_init(vcpu, kvm, id);
410 if (rc)
Wei Yongjun7b06bf22010-03-09 14:37:53 +0800411 goto out_free_sie_block;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100412 VM_EVENT(kvm, 3, "create cpu %d at %p, sie block at %p", id, vcpu,
413 vcpu->arch.sie_block);
414
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100415 return vcpu;
Wei Yongjun7b06bf22010-03-09 14:37:53 +0800416out_free_sie_block:
417 free_page((unsigned long)(vcpu->arch.sie_block));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100418out_free_cpu:
419 kfree(vcpu);
Carsten Otte4d475552011-10-18 12:27:12 +0200420out:
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100421 return ERR_PTR(rc);
422}
423
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100424int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
425{
426 /* kvm common code refers to this, but never calls it */
427 BUG();
428 return 0;
429}
430
Christoffer Dallb6d33832012-03-08 16:44:24 -0500431int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
432{
433 /* kvm common code refers to this, but never calls it */
434 BUG();
435 return 0;
436}
437
438
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100439static int kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu)
440{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100441 kvm_s390_vcpu_initial_reset(vcpu);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100442 return 0;
443}
444
445int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
446{
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100447 memcpy(&vcpu->run->s.regs.gprs, &regs->gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100448 return 0;
449}
450
451int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
452{
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100453 memcpy(&regs->gprs, &vcpu->run->s.regs.gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100454 return 0;
455}
456
457int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
458 struct kvm_sregs *sregs)
459{
Christian Borntraeger59674c12012-01-11 11:20:33 +0100460 memcpy(&vcpu->run->s.regs.acrs, &sregs->acrs, sizeof(sregs->acrs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100461 memcpy(&vcpu->arch.sie_block->gcr, &sregs->crs, sizeof(sregs->crs));
Christian Borntraeger59674c12012-01-11 11:20:33 +0100462 restore_access_regs(vcpu->run->s.regs.acrs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100463 return 0;
464}
465
466int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
467 struct kvm_sregs *sregs)
468{
Christian Borntraeger59674c12012-01-11 11:20:33 +0100469 memcpy(&sregs->acrs, &vcpu->run->s.regs.acrs, sizeof(sregs->acrs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100470 memcpy(&sregs->crs, &vcpu->arch.sie_block->gcr, sizeof(sregs->crs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100471 return 0;
472}
473
474int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
475{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100476 memcpy(&vcpu->arch.guest_fpregs.fprs, &fpu->fprs, sizeof(fpu->fprs));
Christian Borntraeger85175582012-02-06 10:59:02 +0100477 vcpu->arch.guest_fpregs.fpc = fpu->fpc & FPC_VALID_MASK;
Carsten Otte7eef87d2011-10-18 12:27:14 +0200478 restore_fp_regs(&vcpu->arch.guest_fpregs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100479 return 0;
480}
481
482int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
483{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100484 memcpy(&fpu->fprs, &vcpu->arch.guest_fpregs.fprs, sizeof(fpu->fprs));
485 fpu->fpc = vcpu->arch.guest_fpregs.fpc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100486 return 0;
487}
488
489static int kvm_arch_vcpu_ioctl_set_initial_psw(struct kvm_vcpu *vcpu, psw_t psw)
490{
491 int rc = 0;
492
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100493 if (!(atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_STOPPED))
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100494 rc = -EBUSY;
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100495 else {
496 vcpu->run->psw_mask = psw.mask;
497 vcpu->run->psw_addr = psw.addr;
498 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100499 return rc;
500}
501
502int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
503 struct kvm_translation *tr)
504{
505 return -EINVAL; /* not implemented yet */
506}
507
Jan Kiszkad0bfb942008-12-15 13:52:10 +0100508int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
509 struct kvm_guest_debug *dbg)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100510{
511 return -EINVAL; /* not implemented yet */
512}
513
Marcelo Tosatti62d9f0d2008-04-11 13:24:45 -0300514int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
515 struct kvm_mp_state *mp_state)
516{
517 return -EINVAL; /* not implemented yet */
518}
519
520int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
521 struct kvm_mp_state *mp_state)
522{
523 return -EINVAL; /* not implemented yet */
524}
525
Carsten Ottee168bf82012-01-04 10:25:22 +0100526static int __vcpu_run(struct kvm_vcpu *vcpu)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100527{
Carsten Ottee168bf82012-01-04 10:25:22 +0100528 int rc;
529
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100530 memcpy(&vcpu->arch.sie_block->gg14, &vcpu->run->s.regs.gprs[14], 16);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100531
532 if (need_resched())
533 schedule();
534
Christian Borntraeger71cde582008-05-21 13:37:34 +0200535 if (test_thread_flag(TIF_MCCK_PENDING))
536 s390_handle_mcck();
537
Carsten Otted6b6d162012-01-04 10:25:25 +0100538 if (!kvm_is_ucontrol(vcpu->kvm))
539 kvm_s390_deliver_pending_interrupts(vcpu);
Carsten Otte0ff31862008-05-21 13:37:37 +0200540
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100541 vcpu->arch.sie_block->icptcode = 0;
542 local_irq_disable();
543 kvm_guest_enter();
544 local_irq_enable();
545 VCPU_EVENT(vcpu, 6, "entering sie flags %x",
546 atomic_read(&vcpu->arch.sie_block->cpuflags));
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100547 rc = sie64a(vcpu->arch.sie_block, vcpu->run->s.regs.gprs);
Carsten Ottee168bf82012-01-04 10:25:22 +0100548 if (rc) {
549 if (kvm_is_ucontrol(vcpu->kvm)) {
550 rc = SIE_INTERCEPT_UCONTROL;
551 } else {
552 VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction");
553 kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
554 rc = 0;
555 }
Carsten Otte1f0d0f02008-05-21 13:37:40 +0200556 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100557 VCPU_EVENT(vcpu, 6, "exit sie icptcode %d",
558 vcpu->arch.sie_block->icptcode);
559 local_irq_disable();
560 kvm_guest_exit();
561 local_irq_enable();
562
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100563 memcpy(&vcpu->run->s.regs.gprs[14], &vcpu->arch.sie_block->gg14, 16);
Carsten Ottee168bf82012-01-04 10:25:22 +0100564 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100565}
566
567int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
568{
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100569 int rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100570 sigset_t sigsaved;
571
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200572rerun_vcpu:
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100573 if (vcpu->sigset_active)
574 sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
575
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100576 atomic_clear_mask(CPUSTAT_STOPPED, &vcpu->arch.sie_block->cpuflags);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100577
Carsten Otteba5c1e92008-03-25 18:47:26 +0100578 BUG_ON(vcpu->kvm->arch.float_int.local_int[vcpu->vcpu_id] == NULL);
579
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100580 switch (kvm_run->exit_reason) {
581 case KVM_EXIT_S390_SIEIC:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100582 case KVM_EXIT_UNKNOWN:
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200583 case KVM_EXIT_INTR:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100584 case KVM_EXIT_S390_RESET:
Carsten Ottee168bf82012-01-04 10:25:22 +0100585 case KVM_EXIT_S390_UCONTROL:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100586 break;
587 default:
588 BUG();
589 }
590
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100591 vcpu->arch.sie_block->gpsw.mask = kvm_run->psw_mask;
592 vcpu->arch.sie_block->gpsw.addr = kvm_run->psw_addr;
Christian Borntraeger60b413c2012-01-11 11:20:31 +0100593 if (kvm_run->kvm_dirty_regs & KVM_SYNC_PREFIX) {
594 kvm_run->kvm_dirty_regs &= ~KVM_SYNC_PREFIX;
595 kvm_s390_set_prefix(vcpu, kvm_run->s.regs.prefix);
596 }
Christian Borntraeger9eed07352012-02-06 10:59:07 +0100597 if (kvm_run->kvm_dirty_regs & KVM_SYNC_CRS) {
598 kvm_run->kvm_dirty_regs &= ~KVM_SYNC_CRS;
599 memcpy(&vcpu->arch.sie_block->gcr, &kvm_run->s.regs.crs, 128);
600 kvm_s390_set_prefix(vcpu, kvm_run->s.regs.prefix);
601 }
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100602
Heiko Carstensdab4079d2009-06-12 10:26:32 +0200603 might_fault();
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100604
605 do {
Carsten Ottee168bf82012-01-04 10:25:22 +0100606 rc = __vcpu_run(vcpu);
607 if (rc)
608 break;
Carsten Ottec0d744a2012-01-04 10:25:24 +0100609 if (kvm_is_ucontrol(vcpu->kvm))
610 rc = -EOPNOTSUPP;
611 else
612 rc = kvm_handle_sie_intercept(vcpu);
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100613 } while (!signal_pending(current) && !rc);
614
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200615 if (rc == SIE_INTERCEPT_RERUNVCPU)
616 goto rerun_vcpu;
617
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200618 if (signal_pending(current) && !rc) {
619 kvm_run->exit_reason = KVM_EXIT_INTR;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100620 rc = -EINTR;
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200621 }
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100622
Carsten Ottee168bf82012-01-04 10:25:22 +0100623#ifdef CONFIG_KVM_S390_UCONTROL
624 if (rc == SIE_INTERCEPT_UCONTROL) {
625 kvm_run->exit_reason = KVM_EXIT_S390_UCONTROL;
626 kvm_run->s390_ucontrol.trans_exc_code =
627 current->thread.gmap_addr;
628 kvm_run->s390_ucontrol.pgm_code = 0x10;
629 rc = 0;
630 }
631#endif
632
Heiko Carstensb8e660b2010-02-26 22:37:41 +0100633 if (rc == -EOPNOTSUPP) {
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100634 /* intercept cannot be handled in-kernel, prepare kvm-run */
635 kvm_run->exit_reason = KVM_EXIT_S390_SIEIC;
636 kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100637 kvm_run->s390_sieic.ipa = vcpu->arch.sie_block->ipa;
638 kvm_run->s390_sieic.ipb = vcpu->arch.sie_block->ipb;
639 rc = 0;
640 }
641
642 if (rc == -EREMOTE) {
643 /* intercept was handled, but userspace support is needed
644 * kvm_run has been prepared by the handler */
645 rc = 0;
646 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100647
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100648 kvm_run->psw_mask = vcpu->arch.sie_block->gpsw.mask;
649 kvm_run->psw_addr = vcpu->arch.sie_block->gpsw.addr;
Christian Borntraeger60b413c2012-01-11 11:20:31 +0100650 kvm_run->s.regs.prefix = vcpu->arch.sie_block->prefix;
Christian Borntraeger9eed07352012-02-06 10:59:07 +0100651 memcpy(&kvm_run->s.regs.crs, &vcpu->arch.sie_block->gcr, 128);
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100652
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100653 if (vcpu->sigset_active)
654 sigprocmask(SIG_SETMASK, &sigsaved, NULL);
655
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100656 vcpu->stat.exit_userspace++;
Heiko Carstens7e8e6ab2008-04-04 15:12:35 +0200657 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100658}
659
Carsten Otte092670c2011-07-24 10:48:22 +0200660static int __guestcopy(struct kvm_vcpu *vcpu, u64 guestdest, void *from,
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100661 unsigned long n, int prefix)
662{
663 if (prefix)
664 return copy_to_guest(vcpu, guestdest, from, n);
665 else
666 return copy_to_guest_absolute(vcpu, guestdest, from, n);
667}
668
669/*
670 * store status at address
671 * we use have two special cases:
672 * KVM_S390_STORE_STATUS_NOADDR: -> 0x1200 on 64 bit
673 * KVM_S390_STORE_STATUS_PREFIXED: -> prefix
674 */
Christian Borntraeger971eb772010-06-12 08:54:13 +0200675int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100676{
Carsten Otte092670c2011-07-24 10:48:22 +0200677 unsigned char archmode = 1;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100678 int prefix;
679
680 if (addr == KVM_S390_STORE_STATUS_NOADDR) {
681 if (copy_to_guest_absolute(vcpu, 163ul, &archmode, 1))
682 return -EFAULT;
683 addr = SAVE_AREA_BASE;
684 prefix = 0;
685 } else if (addr == KVM_S390_STORE_STATUS_PREFIXED) {
686 if (copy_to_guest(vcpu, 163ul, &archmode, 1))
687 return -EFAULT;
688 addr = SAVE_AREA_BASE;
689 prefix = 1;
690 } else
691 prefix = 0;
692
Heiko Carstensf64ca212010-02-26 22:37:32 +0100693 if (__guestcopy(vcpu, addr + offsetof(struct save_area, fp_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100694 vcpu->arch.guest_fpregs.fprs, 128, prefix))
695 return -EFAULT;
696
Heiko Carstensf64ca212010-02-26 22:37:32 +0100697 if (__guestcopy(vcpu, addr + offsetof(struct save_area, gp_regs),
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100698 vcpu->run->s.regs.gprs, 128, prefix))
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100699 return -EFAULT;
700
Heiko Carstensf64ca212010-02-26 22:37:32 +0100701 if (__guestcopy(vcpu, addr + offsetof(struct save_area, psw),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100702 &vcpu->arch.sie_block->gpsw, 16, prefix))
703 return -EFAULT;
704
Heiko Carstensf64ca212010-02-26 22:37:32 +0100705 if (__guestcopy(vcpu, addr + offsetof(struct save_area, pref_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100706 &vcpu->arch.sie_block->prefix, 4, prefix))
707 return -EFAULT;
708
709 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100710 addr + offsetof(struct save_area, fp_ctrl_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100711 &vcpu->arch.guest_fpregs.fpc, 4, prefix))
712 return -EFAULT;
713
Heiko Carstensf64ca212010-02-26 22:37:32 +0100714 if (__guestcopy(vcpu, addr + offsetof(struct save_area, tod_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100715 &vcpu->arch.sie_block->todpr, 4, prefix))
716 return -EFAULT;
717
Heiko Carstensf64ca212010-02-26 22:37:32 +0100718 if (__guestcopy(vcpu, addr + offsetof(struct save_area, timer),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100719 &vcpu->arch.sie_block->cputm, 8, prefix))
720 return -EFAULT;
721
Heiko Carstensf64ca212010-02-26 22:37:32 +0100722 if (__guestcopy(vcpu, addr + offsetof(struct save_area, clk_cmp),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100723 &vcpu->arch.sie_block->ckc, 8, prefix))
724 return -EFAULT;
725
Heiko Carstensf64ca212010-02-26 22:37:32 +0100726 if (__guestcopy(vcpu, addr + offsetof(struct save_area, acc_regs),
Christian Borntraeger59674c12012-01-11 11:20:33 +0100727 &vcpu->run->s.regs.acrs, 64, prefix))
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100728 return -EFAULT;
729
730 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100731 addr + offsetof(struct save_area, ctrl_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100732 &vcpu->arch.sie_block->gcr, 128, prefix))
733 return -EFAULT;
734 return 0;
735}
736
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100737long kvm_arch_vcpu_ioctl(struct file *filp,
738 unsigned int ioctl, unsigned long arg)
739{
740 struct kvm_vcpu *vcpu = filp->private_data;
741 void __user *argp = (void __user *)arg;
Avi Kivitybc923cc2010-05-13 12:21:46 +0300742 long r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100743
Avi Kivity937366242010-05-13 12:35:17 +0300744 switch (ioctl) {
745 case KVM_S390_INTERRUPT: {
Carsten Otteba5c1e92008-03-25 18:47:26 +0100746 struct kvm_s390_interrupt s390int;
747
Avi Kivity937366242010-05-13 12:35:17 +0300748 r = -EFAULT;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100749 if (copy_from_user(&s390int, argp, sizeof(s390int)))
Avi Kivity937366242010-05-13 12:35:17 +0300750 break;
751 r = kvm_s390_inject_vcpu(vcpu, &s390int);
752 break;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100753 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100754 case KVM_S390_STORE_STATUS:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300755 r = kvm_s390_vcpu_store_status(vcpu, arg);
756 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100757 case KVM_S390_SET_INITIAL_PSW: {
758 psw_t psw;
759
Avi Kivitybc923cc2010-05-13 12:21:46 +0300760 r = -EFAULT;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100761 if (copy_from_user(&psw, argp, sizeof(psw)))
Avi Kivitybc923cc2010-05-13 12:21:46 +0300762 break;
763 r = kvm_arch_vcpu_ioctl_set_initial_psw(vcpu, psw);
764 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100765 }
766 case KVM_S390_INITIAL_RESET:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300767 r = kvm_arch_vcpu_ioctl_initial_reset(vcpu);
768 break;
Carsten Otte27e03932012-01-04 10:25:21 +0100769#ifdef CONFIG_KVM_S390_UCONTROL
770 case KVM_S390_UCAS_MAP: {
771 struct kvm_s390_ucas_mapping ucasmap;
772
773 if (copy_from_user(&ucasmap, argp, sizeof(ucasmap))) {
774 r = -EFAULT;
775 break;
776 }
777
778 if (!kvm_is_ucontrol(vcpu->kvm)) {
779 r = -EINVAL;
780 break;
781 }
782
783 r = gmap_map_segment(vcpu->arch.gmap, ucasmap.user_addr,
784 ucasmap.vcpu_addr, ucasmap.length);
785 break;
786 }
787 case KVM_S390_UCAS_UNMAP: {
788 struct kvm_s390_ucas_mapping ucasmap;
789
790 if (copy_from_user(&ucasmap, argp, sizeof(ucasmap))) {
791 r = -EFAULT;
792 break;
793 }
794
795 if (!kvm_is_ucontrol(vcpu->kvm)) {
796 r = -EINVAL;
797 break;
798 }
799
800 r = gmap_unmap_segment(vcpu->arch.gmap, ucasmap.vcpu_addr,
801 ucasmap.length);
802 break;
803 }
804#endif
Carsten Otteccc79102012-01-04 10:25:26 +0100805 case KVM_S390_VCPU_FAULT: {
806 r = gmap_fault(arg, vcpu->arch.gmap);
807 if (!IS_ERR_VALUE(r))
808 r = 0;
809 break;
810 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100811 default:
Carsten Otte3e6afcf2012-01-04 10:25:30 +0100812 r = -ENOTTY;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100813 }
Avi Kivitybc923cc2010-05-13 12:21:46 +0300814 return r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100815}
816
Carsten Otte5b1c1492012-01-04 10:25:23 +0100817int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
818{
819#ifdef CONFIG_KVM_S390_UCONTROL
820 if ((vmf->pgoff == KVM_S390_SIE_PAGE_OFFSET)
821 && (kvm_is_ucontrol(vcpu->kvm))) {
822 vmf->page = virt_to_page(vcpu->arch.sie_block);
823 get_page(vmf->page);
824 return 0;
825 }
826#endif
827 return VM_FAULT_SIGBUS;
828}
829
Takuya Yoshikawadb3fe4e2012-02-08 13:02:18 +0900830void kvm_arch_free_memslot(struct kvm_memory_slot *free,
831 struct kvm_memory_slot *dont)
832{
833}
834
835int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages)
836{
837 return 0;
838}
839
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100840/* Section: memory related */
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200841int kvm_arch_prepare_memory_region(struct kvm *kvm,
842 struct kvm_memory_slot *memslot,
843 struct kvm_memory_slot old,
844 struct kvm_userspace_memory_region *mem,
845 int user_alloc)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100846{
847 /* A few sanity checks. We can have exactly one memory slot which has
848 to start at guest virtual zero and which has to be located at a
849 page boundary in userland and which has to end at a page boundary.
850 The memory in userland is ok to be fragmented into various different
851 vmas. It is okay to mmap() and munmap() stuff in this slot after
852 doing this call at any time */
853
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200854 if (mem->slot)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100855 return -EINVAL;
856
857 if (mem->guest_phys_addr)
858 return -EINVAL;
859
Carsten Otte598841c2011-07-24 10:48:21 +0200860 if (mem->userspace_addr & 0xffffful)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100861 return -EINVAL;
862
Carsten Otte598841c2011-07-24 10:48:21 +0200863 if (mem->memory_size & 0xffffful)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100864 return -EINVAL;
865
Carsten Otte2668dab2009-05-12 17:21:48 +0200866 if (!user_alloc)
867 return -EINVAL;
868
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200869 return 0;
870}
871
872void kvm_arch_commit_memory_region(struct kvm *kvm,
873 struct kvm_userspace_memory_region *mem,
874 struct kvm_memory_slot old,
875 int user_alloc)
876{
Carsten Ottef7850c92011-07-24 10:48:23 +0200877 int rc;
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200878
Carsten Otte598841c2011-07-24 10:48:21 +0200879
880 rc = gmap_map_segment(kvm->arch.gmap, mem->userspace_addr,
881 mem->guest_phys_addr, mem->memory_size);
882 if (rc)
Carsten Ottef7850c92011-07-24 10:48:23 +0200883 printk(KERN_WARNING "kvm-s390: failed to commit memory region\n");
Carsten Otte598841c2011-07-24 10:48:21 +0200884 return;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100885}
886
Marcelo Tosatti34d4cb82008-07-10 20:49:31 -0300887void kvm_arch_flush_shadow(struct kvm *kvm)
888{
889}
890
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100891static int __init kvm_s390_init(void)
892{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200893 int ret;
Avi Kivity0ee75be2010-04-28 15:39:01 +0300894 ret = kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE);
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200895 if (ret)
896 return ret;
897
898 /*
899 * guests can ask for up to 255+1 double words, we need a full page
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300900 * to hold the maximum amount of facilities. On the other hand, we
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200901 * only set facilities that are known to work in KVM.
902 */
Heiko Carstensc2f0e8c2010-06-08 18:58:09 +0200903 facilities = (unsigned long long *) get_zeroed_page(GFP_KERNEL|GFP_DMA);
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200904 if (!facilities) {
905 kvm_exit();
906 return -ENOMEM;
907 }
Martin Schwidefsky14375bc2010-10-25 16:10:51 +0200908 memcpy(facilities, S390_lowcore.stfle_fac_list, 16);
Christian Borntraeger6d00d002010-10-25 16:10:48 +0200909 facilities[0] &= 0xff00fff3f47c0000ULL;
Christian Borntraeger9950f8b2011-06-06 14:14:39 +0200910 facilities[1] &= 0x201c000000000000ULL;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200911 return 0;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100912}
913
914static void __exit kvm_s390_exit(void)
915{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200916 free_page((unsigned long) facilities);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100917 kvm_exit();
918}
919
920module_init(kvm_s390_init);
921module_exit(kvm_s390_exit);