blob: 894b3e47b8c18c8a0df74033b891c7866d86e5cf [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 Borntraeger1526bf92012-05-15 14:15:25 +020031#include <asm/sclp.h>
Christian Borntraeger8f2abe62008-03-25 18:47:23 +010032#include "kvm-s390.h"
Heiko Carstensb0c632d2008-03-25 18:47:20 +010033#include "gaccess.h"
34
35#define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU
36
37struct kvm_stats_debugfs_item debugfs_entries[] = {
38 { "userspace_handled", VCPU_STAT(exit_userspace) },
Christian Borntraeger0eaeafa2008-05-07 09:22:53 +020039 { "exit_null", VCPU_STAT(exit_null) },
Christian Borntraeger8f2abe62008-03-25 18:47:23 +010040 { "exit_validity", VCPU_STAT(exit_validity) },
41 { "exit_stop_request", VCPU_STAT(exit_stop_request) },
42 { "exit_external_request", VCPU_STAT(exit_external_request) },
43 { "exit_external_interrupt", VCPU_STAT(exit_external_interrupt) },
Carsten Otteba5c1e92008-03-25 18:47:26 +010044 { "exit_instruction", VCPU_STAT(exit_instruction) },
45 { "exit_program_interruption", VCPU_STAT(exit_program_interruption) },
46 { "exit_instr_and_program_int", VCPU_STAT(exit_instr_and_program) },
Christian Borntraegerf5e10b02008-07-25 15:52:44 +020047 { "instruction_lctlg", VCPU_STAT(instruction_lctlg) },
Carsten Otteba5c1e92008-03-25 18:47:26 +010048 { "instruction_lctl", VCPU_STAT(instruction_lctl) },
49 { "deliver_emergency_signal", VCPU_STAT(deliver_emergency_signal) },
Christian Ehrhardt7697e712011-10-18 12:27:15 +020050 { "deliver_external_call", VCPU_STAT(deliver_external_call) },
Carsten Otteba5c1e92008-03-25 18:47:26 +010051 { "deliver_service_signal", VCPU_STAT(deliver_service_signal) },
52 { "deliver_virtio_interrupt", VCPU_STAT(deliver_virtio_interrupt) },
53 { "deliver_stop_signal", VCPU_STAT(deliver_stop_signal) },
54 { "deliver_prefix_signal", VCPU_STAT(deliver_prefix_signal) },
55 { "deliver_restart_signal", VCPU_STAT(deliver_restart_signal) },
56 { "deliver_program_interruption", VCPU_STAT(deliver_program_int) },
57 { "exit_wait_state", VCPU_STAT(exit_wait_state) },
Christian Borntraeger453423d2008-03-25 18:47:29 +010058 { "instruction_stidp", VCPU_STAT(instruction_stidp) },
59 { "instruction_spx", VCPU_STAT(instruction_spx) },
60 { "instruction_stpx", VCPU_STAT(instruction_stpx) },
61 { "instruction_stap", VCPU_STAT(instruction_stap) },
62 { "instruction_storage_key", VCPU_STAT(instruction_storage_key) },
63 { "instruction_stsch", VCPU_STAT(instruction_stsch) },
64 { "instruction_chsc", VCPU_STAT(instruction_chsc) },
65 { "instruction_stsi", VCPU_STAT(instruction_stsi) },
66 { "instruction_stfl", VCPU_STAT(instruction_stfl) },
Christian Borntraegerbb25b9b2011-07-24 10:48:17 +020067 { "instruction_tprot", VCPU_STAT(instruction_tprot) },
Christian Borntraeger5288fbf2008-03-25 18:47:31 +010068 { "instruction_sigp_sense", VCPU_STAT(instruction_sigp_sense) },
Cornelia Huckbd59d3a2011-11-17 11:00:42 +010069 { "instruction_sigp_sense_running", VCPU_STAT(instruction_sigp_sense_running) },
Christian Ehrhardt7697e712011-10-18 12:27:15 +020070 { "instruction_sigp_external_call", VCPU_STAT(instruction_sigp_external_call) },
Christian Borntraeger5288fbf2008-03-25 18:47:31 +010071 { "instruction_sigp_emergency", VCPU_STAT(instruction_sigp_emergency) },
72 { "instruction_sigp_stop", VCPU_STAT(instruction_sigp_stop) },
73 { "instruction_sigp_set_arch", VCPU_STAT(instruction_sigp_arch) },
74 { "instruction_sigp_set_prefix", VCPU_STAT(instruction_sigp_prefix) },
75 { "instruction_sigp_restart", VCPU_STAT(instruction_sigp_restart) },
Christian Borntraeger388186b2011-10-30 15:17:03 +010076 { "diagnose_10", VCPU_STAT(diagnose_10) },
Christian Borntraegere28acfe2008-03-25 18:47:34 +010077 { "diagnose_44", VCPU_STAT(diagnose_44) },
Konstantin Weitz41628d32012-04-25 15:30:38 +020078 { "diagnose_9c", VCPU_STAT(diagnose_9c) },
Heiko Carstensb0c632d2008-03-25 18:47:20 +010079 { NULL }
80};
81
Christian Borntraegeref50f7a2009-06-23 17:24:07 +020082static unsigned long long *facilities;
Heiko Carstensb0c632d2008-03-25 18:47:20 +010083
84/* Section: not file related */
Alexander Graf10474ae2009-09-15 11:37:46 +020085int kvm_arch_hardware_enable(void *garbage)
Heiko Carstensb0c632d2008-03-25 18:47:20 +010086{
87 /* every s390 is virtualization enabled ;-) */
Alexander Graf10474ae2009-09-15 11:37:46 +020088 return 0;
Heiko Carstensb0c632d2008-03-25 18:47:20 +010089}
90
91void kvm_arch_hardware_disable(void *garbage)
92{
93}
94
Heiko Carstensb0c632d2008-03-25 18:47:20 +010095int kvm_arch_hardware_setup(void)
96{
97 return 0;
98}
99
100void kvm_arch_hardware_unsetup(void)
101{
102}
103
104void kvm_arch_check_processor_compat(void *rtn)
105{
106}
107
108int kvm_arch_init(void *opaque)
109{
110 return 0;
111}
112
113void kvm_arch_exit(void)
114{
115}
116
117/* Section: device related */
118long kvm_arch_dev_ioctl(struct file *filp,
119 unsigned int ioctl, unsigned long arg)
120{
121 if (ioctl == KVM_S390_ENABLE_SIE)
122 return s390_enable_sie();
123 return -EINVAL;
124}
125
126int kvm_dev_ioctl_check_extension(long ext)
127{
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100128 int r;
129
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200130 switch (ext) {
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100131 case KVM_CAP_S390_PSW:
Christian Borntraegerb6cf8782011-09-20 17:07:29 +0200132 case KVM_CAP_S390_GMAP:
Christian Borntraeger52e16b12011-11-17 11:00:44 +0100133 case KVM_CAP_SYNC_MMU:
Carsten Otte1efd0f52012-01-04 10:25:29 +0100134#ifdef CONFIG_KVM_S390_UCONTROL
135 case KVM_CAP_S390_UCONTROL:
136#endif
Christian Borntraeger60b413c2012-01-11 11:20:31 +0100137 case KVM_CAP_SYNC_REGS:
Carsten Otte14eebd92012-05-15 14:15:26 +0200138 case KVM_CAP_ONE_REG:
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100139 r = 1;
140 break;
Christian Borntraegere726b1b2012-05-02 10:50:38 +0200141 case KVM_CAP_NR_VCPUS:
142 case KVM_CAP_MAX_VCPUS:
143 r = KVM_MAX_VCPUS;
144 break;
Christian Borntraeger1526bf92012-05-15 14:15:25 +0200145 case KVM_CAP_S390_COW:
146 r = sclp_get_fac85() & 0x2;
147 break;
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200148 default:
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100149 r = 0;
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200150 }
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100151 return r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100152}
153
154/* Section: vm related */
155/*
156 * Get (and clear) the dirty memory log for a memory slot.
157 */
158int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
159 struct kvm_dirty_log *log)
160{
161 return 0;
162}
163
164long kvm_arch_vm_ioctl(struct file *filp,
165 unsigned int ioctl, unsigned long arg)
166{
167 struct kvm *kvm = filp->private_data;
168 void __user *argp = (void __user *)arg;
169 int r;
170
171 switch (ioctl) {
Carsten Otteba5c1e92008-03-25 18:47:26 +0100172 case KVM_S390_INTERRUPT: {
173 struct kvm_s390_interrupt s390int;
174
175 r = -EFAULT;
176 if (copy_from_user(&s390int, argp, sizeof(s390int)))
177 break;
178 r = kvm_s390_inject_vm(kvm, &s390int);
179 break;
180 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100181 default:
Avi Kivity367e1312009-08-26 14:57:07 +0300182 r = -ENOTTY;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100183 }
184
185 return r;
186}
187
Carsten Ottee08b9632012-01-04 10:25:20 +0100188int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100189{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100190 int rc;
191 char debug_name[16];
192
Carsten Ottee08b9632012-01-04 10:25:20 +0100193 rc = -EINVAL;
194#ifdef CONFIG_KVM_S390_UCONTROL
195 if (type & ~KVM_VM_S390_UCONTROL)
196 goto out_err;
197 if ((type & KVM_VM_S390_UCONTROL) && (!capable(CAP_SYS_ADMIN)))
198 goto out_err;
199#else
200 if (type)
201 goto out_err;
202#endif
203
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100204 rc = s390_enable_sie();
205 if (rc)
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100206 goto out_err;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100207
Carsten Otteb2904112011-10-18 12:27:13 +0200208 rc = -ENOMEM;
209
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100210 kvm->arch.sca = (struct sca_block *) get_zeroed_page(GFP_KERNEL);
211 if (!kvm->arch.sca)
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100212 goto out_err;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100213
214 sprintf(debug_name, "kvm-%u", current->pid);
215
216 kvm->arch.dbf = debug_register(debug_name, 8, 2, 8 * sizeof(long));
217 if (!kvm->arch.dbf)
218 goto out_nodbf;
219
Carsten Otteba5c1e92008-03-25 18:47:26 +0100220 spin_lock_init(&kvm->arch.float_int.lock);
221 INIT_LIST_HEAD(&kvm->arch.float_int.list);
222
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100223 debug_register_view(kvm->arch.dbf, &debug_sprintf_view);
224 VM_EVENT(kvm, 3, "%s", "vm created");
225
Carsten Ottee08b9632012-01-04 10:25:20 +0100226 if (type & KVM_VM_S390_UCONTROL) {
227 kvm->arch.gmap = NULL;
228 } else {
229 kvm->arch.gmap = gmap_alloc(current->mm);
230 if (!kvm->arch.gmap)
231 goto out_nogmap;
232 }
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100233 return 0;
Carsten Otte598841c2011-07-24 10:48:21 +0200234out_nogmap:
235 debug_unregister(kvm->arch.dbf);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100236out_nodbf:
237 free_page((unsigned long)(kvm->arch.sca));
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100238out_err:
239 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100240}
241
Christian Borntraegerd329c032008-11-26 14:50:27 +0100242void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
243{
244 VCPU_EVENT(vcpu, 3, "%s", "free cpu");
Carsten Otte58f94602012-01-04 10:25:27 +0100245 if (!kvm_is_ucontrol(vcpu->kvm)) {
246 clear_bit(63 - vcpu->vcpu_id,
247 (unsigned long *) &vcpu->kvm->arch.sca->mcn);
248 if (vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda ==
249 (__u64) vcpu->arch.sie_block)
250 vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda = 0;
251 }
Carsten Otteabf4a712009-05-12 17:21:51 +0200252 smp_mb();
Carsten Otte27e03932012-01-04 10:25:21 +0100253
254 if (kvm_is_ucontrol(vcpu->kvm))
255 gmap_free(vcpu->arch.gmap);
256
Christian Borntraegerd329c032008-11-26 14:50:27 +0100257 free_page((unsigned long)(vcpu->arch.sie_block));
Christian Borntraeger6692cef2008-11-26 14:51:08 +0100258 kvm_vcpu_uninit(vcpu);
Christian Borntraegerd329c032008-11-26 14:50:27 +0100259 kfree(vcpu);
260}
261
262static void kvm_free_vcpus(struct kvm *kvm)
263{
264 unsigned int i;
Gleb Natapov988a2ca2009-06-09 15:56:29 +0300265 struct kvm_vcpu *vcpu;
Christian Borntraegerd329c032008-11-26 14:50:27 +0100266
Gleb Natapov988a2ca2009-06-09 15:56:29 +0300267 kvm_for_each_vcpu(i, vcpu, kvm)
268 kvm_arch_vcpu_destroy(vcpu);
269
270 mutex_lock(&kvm->lock);
271 for (i = 0; i < atomic_read(&kvm->online_vcpus); i++)
272 kvm->vcpus[i] = NULL;
273
274 atomic_set(&kvm->online_vcpus, 0);
275 mutex_unlock(&kvm->lock);
Christian Borntraegerd329c032008-11-26 14:50:27 +0100276}
277
Sheng Yangad8ba2c2009-01-06 10:03:02 +0800278void kvm_arch_sync_events(struct kvm *kvm)
279{
280}
281
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100282void kvm_arch_destroy_vm(struct kvm *kvm)
283{
Christian Borntraegerd329c032008-11-26 14:50:27 +0100284 kvm_free_vcpus(kvm);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100285 free_page((unsigned long)(kvm->arch.sca));
Christian Borntraegerd329c032008-11-26 14:50:27 +0100286 debug_unregister(kvm->arch.dbf);
Carsten Otte27e03932012-01-04 10:25:21 +0100287 if (!kvm_is_ucontrol(kvm))
288 gmap_free(kvm->arch.gmap);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100289}
290
291/* Section: vcpu related */
292int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
293{
Carsten Otte27e03932012-01-04 10:25:21 +0100294 if (kvm_is_ucontrol(vcpu->kvm)) {
295 vcpu->arch.gmap = gmap_alloc(current->mm);
296 if (!vcpu->arch.gmap)
297 return -ENOMEM;
298 return 0;
299 }
300
Carsten Otte598841c2011-07-24 10:48:21 +0200301 vcpu->arch.gmap = vcpu->kvm->arch.gmap;
Christian Borntraeger59674c12012-01-11 11:20:33 +0100302 vcpu->run->kvm_valid_regs = KVM_SYNC_PREFIX |
303 KVM_SYNC_GPRS |
Christian Borntraeger9eed07352012-02-06 10:59:07 +0100304 KVM_SYNC_ACRS |
305 KVM_SYNC_CRS;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100306 return 0;
307}
308
309void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
310{
Christian Borntraeger6692cef2008-11-26 14:51:08 +0100311 /* Nothing todo */
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100312}
313
314void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
315{
316 save_fp_regs(&vcpu->arch.host_fpregs);
317 save_access_regs(vcpu->arch.host_acrs);
318 vcpu->arch.guest_fpregs.fpc &= FPC_VALID_MASK;
319 restore_fp_regs(&vcpu->arch.guest_fpregs);
Christian Borntraeger59674c12012-01-11 11:20:33 +0100320 restore_access_regs(vcpu->run->s.regs.acrs);
Christian Borntraeger480e5922011-09-20 17:07:28 +0200321 gmap_enable(vcpu->arch.gmap);
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100322 atomic_set_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100323}
324
325void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
326{
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100327 atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
Christian Borntraeger480e5922011-09-20 17:07:28 +0200328 gmap_disable(vcpu->arch.gmap);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100329 save_fp_regs(&vcpu->arch.guest_fpregs);
Christian Borntraeger59674c12012-01-11 11:20:33 +0100330 save_access_regs(vcpu->run->s.regs.acrs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100331 restore_fp_regs(&vcpu->arch.host_fpregs);
332 restore_access_regs(vcpu->arch.host_acrs);
333}
334
335static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu)
336{
337 /* this equals initial cpu reset in pop, but we don't switch to ESA */
338 vcpu->arch.sie_block->gpsw.mask = 0UL;
339 vcpu->arch.sie_block->gpsw.addr = 0UL;
Christian Borntraeger8d26cf72012-01-11 11:19:32 +0100340 kvm_s390_set_prefix(vcpu, 0);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100341 vcpu->arch.sie_block->cputm = 0UL;
342 vcpu->arch.sie_block->ckc = 0UL;
343 vcpu->arch.sie_block->todpr = 0;
344 memset(vcpu->arch.sie_block->gcr, 0, 16 * sizeof(__u64));
345 vcpu->arch.sie_block->gcr[0] = 0xE0UL;
346 vcpu->arch.sie_block->gcr[14] = 0xC2000000UL;
347 vcpu->arch.guest_fpregs.fpc = 0;
348 asm volatile("lfpc %0" : : "Q" (vcpu->arch.guest_fpregs.fpc));
349 vcpu->arch.sie_block->gbea = 1;
350}
351
352int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
353{
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100354 atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH |
355 CPUSTAT_SM |
356 CPUSTAT_STOPPED);
Christian Borntraegerfc345312010-06-17 23:16:20 +0200357 vcpu->arch.sie_block->ecb = 6;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100358 vcpu->arch.sie_block->eca = 0xC1002001U;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200359 vcpu->arch.sie_block->fac = (int) (long) facilities;
Christian Borntraegerca872302009-05-12 17:21:49 +0200360 hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
361 tasklet_init(&vcpu->arch.tasklet, kvm_s390_tasklet,
362 (unsigned long) vcpu);
363 vcpu->arch.ckc_timer.function = kvm_s390_idle_wakeup;
Christian Borntraeger453423d2008-03-25 18:47:29 +0100364 get_cpu_id(&vcpu->arch.cpu_id);
Christian Borntraeger92e6ecf2009-03-26 15:23:58 +0100365 vcpu->arch.cpu_id.version = 0xff;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100366 return 0;
367}
368
369struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
370 unsigned int id)
371{
Carsten Otte4d475552011-10-18 12:27:12 +0200372 struct kvm_vcpu *vcpu;
373 int rc = -EINVAL;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100374
Carsten Otte4d475552011-10-18 12:27:12 +0200375 if (id >= KVM_MAX_VCPUS)
376 goto out;
377
378 rc = -ENOMEM;
379
380 vcpu = kzalloc(sizeof(struct kvm_vcpu), GFP_KERNEL);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100381 if (!vcpu)
Carsten Otte4d475552011-10-18 12:27:12 +0200382 goto out;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100383
Christian Borntraeger180c12f2008-06-27 15:05:40 +0200384 vcpu->arch.sie_block = (struct kvm_s390_sie_block *)
385 get_zeroed_page(GFP_KERNEL);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100386
387 if (!vcpu->arch.sie_block)
388 goto out_free_cpu;
389
390 vcpu->arch.sie_block->icpua = id;
Carsten Otte58f94602012-01-04 10:25:27 +0100391 if (!kvm_is_ucontrol(kvm)) {
392 if (!kvm->arch.sca) {
393 WARN_ON_ONCE(1);
394 goto out_free_cpu;
395 }
396 if (!kvm->arch.sca->cpu[id].sda)
397 kvm->arch.sca->cpu[id].sda =
398 (__u64) vcpu->arch.sie_block;
399 vcpu->arch.sie_block->scaoh =
400 (__u32)(((__u64)kvm->arch.sca) >> 32);
401 vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca;
402 set_bit(63 - id, (unsigned long *) &kvm->arch.sca->mcn);
403 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100404
Carsten Otteba5c1e92008-03-25 18:47:26 +0100405 spin_lock_init(&vcpu->arch.local_int.lock);
406 INIT_LIST_HEAD(&vcpu->arch.local_int.list);
407 vcpu->arch.local_int.float_int = &kvm->arch.float_int;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200408 spin_lock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100409 kvm->arch.float_int.local_int[id] = &vcpu->arch.local_int;
410 init_waitqueue_head(&vcpu->arch.local_int.wq);
Christian Borntraeger5288fbf2008-03-25 18:47:31 +0100411 vcpu->arch.local_int.cpuflags = &vcpu->arch.sie_block->cpuflags;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200412 spin_unlock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100413
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100414 rc = kvm_vcpu_init(vcpu, kvm, id);
415 if (rc)
Wei Yongjun7b06bf22010-03-09 14:37:53 +0800416 goto out_free_sie_block;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100417 VM_EVENT(kvm, 3, "create cpu %d at %p, sie block at %p", id, vcpu,
418 vcpu->arch.sie_block);
419
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100420 return vcpu;
Wei Yongjun7b06bf22010-03-09 14:37:53 +0800421out_free_sie_block:
422 free_page((unsigned long)(vcpu->arch.sie_block));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100423out_free_cpu:
424 kfree(vcpu);
Carsten Otte4d475552011-10-18 12:27:12 +0200425out:
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100426 return ERR_PTR(rc);
427}
428
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100429int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
430{
431 /* kvm common code refers to this, but never calls it */
432 BUG();
433 return 0;
434}
435
Christoffer Dallb6d33832012-03-08 16:44:24 -0500436int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
437{
438 /* kvm common code refers to this, but never calls it */
439 BUG();
440 return 0;
441}
442
Carsten Otte14eebd92012-05-15 14:15:26 +0200443static int kvm_arch_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu,
444 struct kvm_one_reg *reg)
445{
446 int r = -EINVAL;
447
448 switch (reg->id) {
449 default:
450 break;
451 }
452
453 return r;
454}
455
456static int kvm_arch_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu,
457 struct kvm_one_reg *reg)
458{
459 int r = -EINVAL;
460
461 switch (reg->id) {
462 default:
463 break;
464 }
465
466 return r;
467}
Christoffer Dallb6d33832012-03-08 16:44:24 -0500468
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100469static int kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu)
470{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100471 kvm_s390_vcpu_initial_reset(vcpu);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100472 return 0;
473}
474
475int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
476{
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100477 memcpy(&vcpu->run->s.regs.gprs, &regs->gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100478 return 0;
479}
480
481int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
482{
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100483 memcpy(&regs->gprs, &vcpu->run->s.regs.gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100484 return 0;
485}
486
487int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
488 struct kvm_sregs *sregs)
489{
Christian Borntraeger59674c12012-01-11 11:20:33 +0100490 memcpy(&vcpu->run->s.regs.acrs, &sregs->acrs, sizeof(sregs->acrs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100491 memcpy(&vcpu->arch.sie_block->gcr, &sregs->crs, sizeof(sregs->crs));
Christian Borntraeger59674c12012-01-11 11:20:33 +0100492 restore_access_regs(vcpu->run->s.regs.acrs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100493 return 0;
494}
495
496int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
497 struct kvm_sregs *sregs)
498{
Christian Borntraeger59674c12012-01-11 11:20:33 +0100499 memcpy(&sregs->acrs, &vcpu->run->s.regs.acrs, sizeof(sregs->acrs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100500 memcpy(&sregs->crs, &vcpu->arch.sie_block->gcr, sizeof(sregs->crs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100501 return 0;
502}
503
504int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
505{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100506 memcpy(&vcpu->arch.guest_fpregs.fprs, &fpu->fprs, sizeof(fpu->fprs));
Christian Borntraeger85175582012-02-06 10:59:02 +0100507 vcpu->arch.guest_fpregs.fpc = fpu->fpc & FPC_VALID_MASK;
Carsten Otte7eef87d2011-10-18 12:27:14 +0200508 restore_fp_regs(&vcpu->arch.guest_fpregs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100509 return 0;
510}
511
512int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
513{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100514 memcpy(&fpu->fprs, &vcpu->arch.guest_fpregs.fprs, sizeof(fpu->fprs));
515 fpu->fpc = vcpu->arch.guest_fpregs.fpc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100516 return 0;
517}
518
519static int kvm_arch_vcpu_ioctl_set_initial_psw(struct kvm_vcpu *vcpu, psw_t psw)
520{
521 int rc = 0;
522
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100523 if (!(atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_STOPPED))
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100524 rc = -EBUSY;
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100525 else {
526 vcpu->run->psw_mask = psw.mask;
527 vcpu->run->psw_addr = psw.addr;
528 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100529 return rc;
530}
531
532int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
533 struct kvm_translation *tr)
534{
535 return -EINVAL; /* not implemented yet */
536}
537
Jan Kiszkad0bfb942008-12-15 13:52:10 +0100538int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
539 struct kvm_guest_debug *dbg)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100540{
541 return -EINVAL; /* not implemented yet */
542}
543
Marcelo Tosatti62d9f0d2008-04-11 13:24:45 -0300544int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
545 struct kvm_mp_state *mp_state)
546{
547 return -EINVAL; /* not implemented yet */
548}
549
550int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
551 struct kvm_mp_state *mp_state)
552{
553 return -EINVAL; /* not implemented yet */
554}
555
Carsten Ottee168bf82012-01-04 10:25:22 +0100556static int __vcpu_run(struct kvm_vcpu *vcpu)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100557{
Carsten Ottee168bf82012-01-04 10:25:22 +0100558 int rc;
559
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100560 memcpy(&vcpu->arch.sie_block->gg14, &vcpu->run->s.regs.gprs[14], 16);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100561
562 if (need_resched())
563 schedule();
564
Christian Borntraeger71cde582008-05-21 13:37:34 +0200565 if (test_thread_flag(TIF_MCCK_PENDING))
566 s390_handle_mcck();
567
Carsten Otted6b6d162012-01-04 10:25:25 +0100568 if (!kvm_is_ucontrol(vcpu->kvm))
569 kvm_s390_deliver_pending_interrupts(vcpu);
Carsten Otte0ff31862008-05-21 13:37:37 +0200570
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100571 vcpu->arch.sie_block->icptcode = 0;
572 local_irq_disable();
573 kvm_guest_enter();
574 local_irq_enable();
575 VCPU_EVENT(vcpu, 6, "entering sie flags %x",
576 atomic_read(&vcpu->arch.sie_block->cpuflags));
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100577 rc = sie64a(vcpu->arch.sie_block, vcpu->run->s.regs.gprs);
Carsten Ottee168bf82012-01-04 10:25:22 +0100578 if (rc) {
579 if (kvm_is_ucontrol(vcpu->kvm)) {
580 rc = SIE_INTERCEPT_UCONTROL;
581 } else {
582 VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction");
583 kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
584 rc = 0;
585 }
Carsten Otte1f0d0f02008-05-21 13:37:40 +0200586 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100587 VCPU_EVENT(vcpu, 6, "exit sie icptcode %d",
588 vcpu->arch.sie_block->icptcode);
589 local_irq_disable();
590 kvm_guest_exit();
591 local_irq_enable();
592
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100593 memcpy(&vcpu->run->s.regs.gprs[14], &vcpu->arch.sie_block->gg14, 16);
Carsten Ottee168bf82012-01-04 10:25:22 +0100594 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100595}
596
597int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
598{
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100599 int rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100600 sigset_t sigsaved;
601
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200602rerun_vcpu:
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100603 if (vcpu->sigset_active)
604 sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
605
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100606 atomic_clear_mask(CPUSTAT_STOPPED, &vcpu->arch.sie_block->cpuflags);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100607
Carsten Otteba5c1e92008-03-25 18:47:26 +0100608 BUG_ON(vcpu->kvm->arch.float_int.local_int[vcpu->vcpu_id] == NULL);
609
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100610 switch (kvm_run->exit_reason) {
611 case KVM_EXIT_S390_SIEIC:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100612 case KVM_EXIT_UNKNOWN:
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200613 case KVM_EXIT_INTR:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100614 case KVM_EXIT_S390_RESET:
Carsten Ottee168bf82012-01-04 10:25:22 +0100615 case KVM_EXIT_S390_UCONTROL:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100616 break;
617 default:
618 BUG();
619 }
620
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100621 vcpu->arch.sie_block->gpsw.mask = kvm_run->psw_mask;
622 vcpu->arch.sie_block->gpsw.addr = kvm_run->psw_addr;
Christian Borntraeger60b413c2012-01-11 11:20:31 +0100623 if (kvm_run->kvm_dirty_regs & KVM_SYNC_PREFIX) {
624 kvm_run->kvm_dirty_regs &= ~KVM_SYNC_PREFIX;
625 kvm_s390_set_prefix(vcpu, kvm_run->s.regs.prefix);
626 }
Christian Borntraeger9eed07352012-02-06 10:59:07 +0100627 if (kvm_run->kvm_dirty_regs & KVM_SYNC_CRS) {
628 kvm_run->kvm_dirty_regs &= ~KVM_SYNC_CRS;
629 memcpy(&vcpu->arch.sie_block->gcr, &kvm_run->s.regs.crs, 128);
630 kvm_s390_set_prefix(vcpu, kvm_run->s.regs.prefix);
631 }
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100632
Heiko Carstensdab4079d2009-06-12 10:26:32 +0200633 might_fault();
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100634
635 do {
Carsten Ottee168bf82012-01-04 10:25:22 +0100636 rc = __vcpu_run(vcpu);
637 if (rc)
638 break;
Carsten Ottec0d744a2012-01-04 10:25:24 +0100639 if (kvm_is_ucontrol(vcpu->kvm))
640 rc = -EOPNOTSUPP;
641 else
642 rc = kvm_handle_sie_intercept(vcpu);
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100643 } while (!signal_pending(current) && !rc);
644
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200645 if (rc == SIE_INTERCEPT_RERUNVCPU)
646 goto rerun_vcpu;
647
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200648 if (signal_pending(current) && !rc) {
649 kvm_run->exit_reason = KVM_EXIT_INTR;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100650 rc = -EINTR;
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200651 }
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100652
Carsten Ottee168bf82012-01-04 10:25:22 +0100653#ifdef CONFIG_KVM_S390_UCONTROL
654 if (rc == SIE_INTERCEPT_UCONTROL) {
655 kvm_run->exit_reason = KVM_EXIT_S390_UCONTROL;
656 kvm_run->s390_ucontrol.trans_exc_code =
657 current->thread.gmap_addr;
658 kvm_run->s390_ucontrol.pgm_code = 0x10;
659 rc = 0;
660 }
661#endif
662
Heiko Carstensb8e660b2010-02-26 22:37:41 +0100663 if (rc == -EOPNOTSUPP) {
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100664 /* intercept cannot be handled in-kernel, prepare kvm-run */
665 kvm_run->exit_reason = KVM_EXIT_S390_SIEIC;
666 kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100667 kvm_run->s390_sieic.ipa = vcpu->arch.sie_block->ipa;
668 kvm_run->s390_sieic.ipb = vcpu->arch.sie_block->ipb;
669 rc = 0;
670 }
671
672 if (rc == -EREMOTE) {
673 /* intercept was handled, but userspace support is needed
674 * kvm_run has been prepared by the handler */
675 rc = 0;
676 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100677
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100678 kvm_run->psw_mask = vcpu->arch.sie_block->gpsw.mask;
679 kvm_run->psw_addr = vcpu->arch.sie_block->gpsw.addr;
Christian Borntraeger60b413c2012-01-11 11:20:31 +0100680 kvm_run->s.regs.prefix = vcpu->arch.sie_block->prefix;
Christian Borntraeger9eed07352012-02-06 10:59:07 +0100681 memcpy(&kvm_run->s.regs.crs, &vcpu->arch.sie_block->gcr, 128);
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100682
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100683 if (vcpu->sigset_active)
684 sigprocmask(SIG_SETMASK, &sigsaved, NULL);
685
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100686 vcpu->stat.exit_userspace++;
Heiko Carstens7e8e6ab2008-04-04 15:12:35 +0200687 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100688}
689
Carsten Otte092670c2011-07-24 10:48:22 +0200690static int __guestcopy(struct kvm_vcpu *vcpu, u64 guestdest, void *from,
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100691 unsigned long n, int prefix)
692{
693 if (prefix)
694 return copy_to_guest(vcpu, guestdest, from, n);
695 else
696 return copy_to_guest_absolute(vcpu, guestdest, from, n);
697}
698
699/*
700 * store status at address
701 * we use have two special cases:
702 * KVM_S390_STORE_STATUS_NOADDR: -> 0x1200 on 64 bit
703 * KVM_S390_STORE_STATUS_PREFIXED: -> prefix
704 */
Christian Borntraeger971eb772010-06-12 08:54:13 +0200705int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100706{
Carsten Otte092670c2011-07-24 10:48:22 +0200707 unsigned char archmode = 1;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100708 int prefix;
709
710 if (addr == KVM_S390_STORE_STATUS_NOADDR) {
711 if (copy_to_guest_absolute(vcpu, 163ul, &archmode, 1))
712 return -EFAULT;
713 addr = SAVE_AREA_BASE;
714 prefix = 0;
715 } else if (addr == KVM_S390_STORE_STATUS_PREFIXED) {
716 if (copy_to_guest(vcpu, 163ul, &archmode, 1))
717 return -EFAULT;
718 addr = SAVE_AREA_BASE;
719 prefix = 1;
720 } else
721 prefix = 0;
722
Heiko Carstensf64ca212010-02-26 22:37:32 +0100723 if (__guestcopy(vcpu, addr + offsetof(struct save_area, fp_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100724 vcpu->arch.guest_fpregs.fprs, 128, prefix))
725 return -EFAULT;
726
Heiko Carstensf64ca212010-02-26 22:37:32 +0100727 if (__guestcopy(vcpu, addr + offsetof(struct save_area, gp_regs),
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100728 vcpu->run->s.regs.gprs, 128, prefix))
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100729 return -EFAULT;
730
Heiko Carstensf64ca212010-02-26 22:37:32 +0100731 if (__guestcopy(vcpu, addr + offsetof(struct save_area, psw),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100732 &vcpu->arch.sie_block->gpsw, 16, prefix))
733 return -EFAULT;
734
Heiko Carstensf64ca212010-02-26 22:37:32 +0100735 if (__guestcopy(vcpu, addr + offsetof(struct save_area, pref_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100736 &vcpu->arch.sie_block->prefix, 4, prefix))
737 return -EFAULT;
738
739 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100740 addr + offsetof(struct save_area, fp_ctrl_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100741 &vcpu->arch.guest_fpregs.fpc, 4, prefix))
742 return -EFAULT;
743
Heiko Carstensf64ca212010-02-26 22:37:32 +0100744 if (__guestcopy(vcpu, addr + offsetof(struct save_area, tod_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100745 &vcpu->arch.sie_block->todpr, 4, prefix))
746 return -EFAULT;
747
Heiko Carstensf64ca212010-02-26 22:37:32 +0100748 if (__guestcopy(vcpu, addr + offsetof(struct save_area, timer),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100749 &vcpu->arch.sie_block->cputm, 8, prefix))
750 return -EFAULT;
751
Heiko Carstensf64ca212010-02-26 22:37:32 +0100752 if (__guestcopy(vcpu, addr + offsetof(struct save_area, clk_cmp),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100753 &vcpu->arch.sie_block->ckc, 8, prefix))
754 return -EFAULT;
755
Heiko Carstensf64ca212010-02-26 22:37:32 +0100756 if (__guestcopy(vcpu, addr + offsetof(struct save_area, acc_regs),
Christian Borntraeger59674c12012-01-11 11:20:33 +0100757 &vcpu->run->s.regs.acrs, 64, prefix))
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100758 return -EFAULT;
759
760 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100761 addr + offsetof(struct save_area, ctrl_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100762 &vcpu->arch.sie_block->gcr, 128, prefix))
763 return -EFAULT;
764 return 0;
765}
766
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100767long kvm_arch_vcpu_ioctl(struct file *filp,
768 unsigned int ioctl, unsigned long arg)
769{
770 struct kvm_vcpu *vcpu = filp->private_data;
771 void __user *argp = (void __user *)arg;
Avi Kivitybc923cc2010-05-13 12:21:46 +0300772 long r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100773
Avi Kivity93736622010-05-13 12:35:17 +0300774 switch (ioctl) {
775 case KVM_S390_INTERRUPT: {
Carsten Otteba5c1e92008-03-25 18:47:26 +0100776 struct kvm_s390_interrupt s390int;
777
Avi Kivity93736622010-05-13 12:35:17 +0300778 r = -EFAULT;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100779 if (copy_from_user(&s390int, argp, sizeof(s390int)))
Avi Kivity93736622010-05-13 12:35:17 +0300780 break;
781 r = kvm_s390_inject_vcpu(vcpu, &s390int);
782 break;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100783 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100784 case KVM_S390_STORE_STATUS:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300785 r = kvm_s390_vcpu_store_status(vcpu, arg);
786 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100787 case KVM_S390_SET_INITIAL_PSW: {
788 psw_t psw;
789
Avi Kivitybc923cc2010-05-13 12:21:46 +0300790 r = -EFAULT;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100791 if (copy_from_user(&psw, argp, sizeof(psw)))
Avi Kivitybc923cc2010-05-13 12:21:46 +0300792 break;
793 r = kvm_arch_vcpu_ioctl_set_initial_psw(vcpu, psw);
794 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100795 }
796 case KVM_S390_INITIAL_RESET:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300797 r = kvm_arch_vcpu_ioctl_initial_reset(vcpu);
798 break;
Carsten Otte14eebd92012-05-15 14:15:26 +0200799 case KVM_SET_ONE_REG:
800 case KVM_GET_ONE_REG: {
801 struct kvm_one_reg reg;
802 r = -EFAULT;
803 if (copy_from_user(&reg, argp, sizeof(reg)))
804 break;
805 if (ioctl == KVM_SET_ONE_REG)
806 r = kvm_arch_vcpu_ioctl_set_one_reg(vcpu, &reg);
807 else
808 r = kvm_arch_vcpu_ioctl_get_one_reg(vcpu, &reg);
809 break;
810 }
Carsten Otte27e03932012-01-04 10:25:21 +0100811#ifdef CONFIG_KVM_S390_UCONTROL
812 case KVM_S390_UCAS_MAP: {
813 struct kvm_s390_ucas_mapping ucasmap;
814
815 if (copy_from_user(&ucasmap, argp, sizeof(ucasmap))) {
816 r = -EFAULT;
817 break;
818 }
819
820 if (!kvm_is_ucontrol(vcpu->kvm)) {
821 r = -EINVAL;
822 break;
823 }
824
825 r = gmap_map_segment(vcpu->arch.gmap, ucasmap.user_addr,
826 ucasmap.vcpu_addr, ucasmap.length);
827 break;
828 }
829 case KVM_S390_UCAS_UNMAP: {
830 struct kvm_s390_ucas_mapping ucasmap;
831
832 if (copy_from_user(&ucasmap, argp, sizeof(ucasmap))) {
833 r = -EFAULT;
834 break;
835 }
836
837 if (!kvm_is_ucontrol(vcpu->kvm)) {
838 r = -EINVAL;
839 break;
840 }
841
842 r = gmap_unmap_segment(vcpu->arch.gmap, ucasmap.vcpu_addr,
843 ucasmap.length);
844 break;
845 }
846#endif
Carsten Otteccc79102012-01-04 10:25:26 +0100847 case KVM_S390_VCPU_FAULT: {
848 r = gmap_fault(arg, vcpu->arch.gmap);
849 if (!IS_ERR_VALUE(r))
850 r = 0;
851 break;
852 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100853 default:
Carsten Otte3e6afcf2012-01-04 10:25:30 +0100854 r = -ENOTTY;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100855 }
Avi Kivitybc923cc2010-05-13 12:21:46 +0300856 return r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100857}
858
Carsten Otte5b1c1492012-01-04 10:25:23 +0100859int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
860{
861#ifdef CONFIG_KVM_S390_UCONTROL
862 if ((vmf->pgoff == KVM_S390_SIE_PAGE_OFFSET)
863 && (kvm_is_ucontrol(vcpu->kvm))) {
864 vmf->page = virt_to_page(vcpu->arch.sie_block);
865 get_page(vmf->page);
866 return 0;
867 }
868#endif
869 return VM_FAULT_SIGBUS;
870}
871
Takuya Yoshikawadb3fe4e2012-02-08 13:02:18 +0900872void kvm_arch_free_memslot(struct kvm_memory_slot *free,
873 struct kvm_memory_slot *dont)
874{
875}
876
877int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages)
878{
879 return 0;
880}
881
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100882/* Section: memory related */
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200883int kvm_arch_prepare_memory_region(struct kvm *kvm,
884 struct kvm_memory_slot *memslot,
885 struct kvm_memory_slot old,
886 struct kvm_userspace_memory_region *mem,
887 int user_alloc)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100888{
889 /* A few sanity checks. We can have exactly one memory slot which has
890 to start at guest virtual zero and which has to be located at a
891 page boundary in userland and which has to end at a page boundary.
892 The memory in userland is ok to be fragmented into various different
893 vmas. It is okay to mmap() and munmap() stuff in this slot after
894 doing this call at any time */
895
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200896 if (mem->slot)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100897 return -EINVAL;
898
899 if (mem->guest_phys_addr)
900 return -EINVAL;
901
Carsten Otte598841c2011-07-24 10:48:21 +0200902 if (mem->userspace_addr & 0xffffful)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100903 return -EINVAL;
904
Carsten Otte598841c2011-07-24 10:48:21 +0200905 if (mem->memory_size & 0xffffful)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100906 return -EINVAL;
907
Carsten Otte2668dab2009-05-12 17:21:48 +0200908 if (!user_alloc)
909 return -EINVAL;
910
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200911 return 0;
912}
913
914void kvm_arch_commit_memory_region(struct kvm *kvm,
915 struct kvm_userspace_memory_region *mem,
916 struct kvm_memory_slot old,
917 int user_alloc)
918{
Carsten Ottef7850c92011-07-24 10:48:23 +0200919 int rc;
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200920
Carsten Otte598841c2011-07-24 10:48:21 +0200921
922 rc = gmap_map_segment(kvm->arch.gmap, mem->userspace_addr,
923 mem->guest_phys_addr, mem->memory_size);
924 if (rc)
Carsten Ottef7850c92011-07-24 10:48:23 +0200925 printk(KERN_WARNING "kvm-s390: failed to commit memory region\n");
Carsten Otte598841c2011-07-24 10:48:21 +0200926 return;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100927}
928
Marcelo Tosatti34d4cb82008-07-10 20:49:31 -0300929void kvm_arch_flush_shadow(struct kvm *kvm)
930{
931}
932
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100933static int __init kvm_s390_init(void)
934{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200935 int ret;
Avi Kivity0ee75be2010-04-28 15:39:01 +0300936 ret = kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE);
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200937 if (ret)
938 return ret;
939
940 /*
941 * guests can ask for up to 255+1 double words, we need a full page
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300942 * to hold the maximum amount of facilities. On the other hand, we
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200943 * only set facilities that are known to work in KVM.
944 */
Heiko Carstensc2f0e8c2010-06-08 18:58:09 +0200945 facilities = (unsigned long long *) get_zeroed_page(GFP_KERNEL|GFP_DMA);
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200946 if (!facilities) {
947 kvm_exit();
948 return -ENOMEM;
949 }
Martin Schwidefsky14375bc2010-10-25 16:10:51 +0200950 memcpy(facilities, S390_lowcore.stfle_fac_list, 16);
Christian Borntraeger6d00d002010-10-25 16:10:48 +0200951 facilities[0] &= 0xff00fff3f47c0000ULL;
Christian Borntraeger9950f8b2011-06-06 14:14:39 +0200952 facilities[1] &= 0x201c000000000000ULL;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200953 return 0;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100954}
955
956static void __exit kvm_s390_exit(void)
957{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200958 free_page((unsigned long) facilities);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100959 kvm_exit();
960}
961
962module_init(kvm_s390_init);
963module_exit(kvm_s390_exit);