blob: 664766d0c83c6a8461634c4dfd31679cf74c7b02 [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 Ehrhardt7697e71f2011-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 Ehrhardt7697e71f2011-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) {
Carsten Otte29b7c712012-05-15 14:15:27 +0200449 case KVM_REG_S390_TODPR:
450 r = put_user(vcpu->arch.sie_block->todpr,
451 (u32 __user *)reg->addr);
452 break;
453 case KVM_REG_S390_EPOCHDIFF:
454 r = put_user(vcpu->arch.sie_block->epoch,
455 (u64 __user *)reg->addr);
456 break;
Jason J. herne46a6dd12012-05-15 14:15:28 +0200457 case KVM_REG_S390_CPU_TIMER:
458 r = put_user(vcpu->arch.sie_block->cputm,
459 (u64 __user *)reg->addr);
460 break;
461 case KVM_REG_S390_CLOCK_COMP:
462 r = put_user(vcpu->arch.sie_block->ckc,
463 (u64 __user *)reg->addr);
464 break;
Carsten Otte14eebd92012-05-15 14:15:26 +0200465 default:
466 break;
467 }
468
469 return r;
470}
471
472static int kvm_arch_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu,
473 struct kvm_one_reg *reg)
474{
475 int r = -EINVAL;
476
477 switch (reg->id) {
Carsten Otte29b7c712012-05-15 14:15:27 +0200478 case KVM_REG_S390_TODPR:
479 r = get_user(vcpu->arch.sie_block->todpr,
480 (u32 __user *)reg->addr);
481 break;
482 case KVM_REG_S390_EPOCHDIFF:
483 r = get_user(vcpu->arch.sie_block->epoch,
484 (u64 __user *)reg->addr);
485 break;
Jason J. herne46a6dd12012-05-15 14:15:28 +0200486 case KVM_REG_S390_CPU_TIMER:
487 r = get_user(vcpu->arch.sie_block->cputm,
488 (u64 __user *)reg->addr);
489 break;
490 case KVM_REG_S390_CLOCK_COMP:
491 r = get_user(vcpu->arch.sie_block->ckc,
492 (u64 __user *)reg->addr);
493 break;
Carsten Otte14eebd92012-05-15 14:15:26 +0200494 default:
495 break;
496 }
497
498 return r;
499}
Christoffer Dallb6d33832012-03-08 16:44:24 -0500500
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100501static int kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu)
502{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100503 kvm_s390_vcpu_initial_reset(vcpu);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100504 return 0;
505}
506
507int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
508{
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100509 memcpy(&vcpu->run->s.regs.gprs, &regs->gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100510 return 0;
511}
512
513int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
514{
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100515 memcpy(&regs->gprs, &vcpu->run->s.regs.gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100516 return 0;
517}
518
519int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
520 struct kvm_sregs *sregs)
521{
Christian Borntraeger59674c12012-01-11 11:20:33 +0100522 memcpy(&vcpu->run->s.regs.acrs, &sregs->acrs, sizeof(sregs->acrs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100523 memcpy(&vcpu->arch.sie_block->gcr, &sregs->crs, sizeof(sregs->crs));
Christian Borntraeger59674c12012-01-11 11:20:33 +0100524 restore_access_regs(vcpu->run->s.regs.acrs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100525 return 0;
526}
527
528int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
529 struct kvm_sregs *sregs)
530{
Christian Borntraeger59674c12012-01-11 11:20:33 +0100531 memcpy(&sregs->acrs, &vcpu->run->s.regs.acrs, sizeof(sregs->acrs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100532 memcpy(&sregs->crs, &vcpu->arch.sie_block->gcr, sizeof(sregs->crs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100533 return 0;
534}
535
536int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
537{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100538 memcpy(&vcpu->arch.guest_fpregs.fprs, &fpu->fprs, sizeof(fpu->fprs));
Christian Borntraeger85175582012-02-06 10:59:02 +0100539 vcpu->arch.guest_fpregs.fpc = fpu->fpc & FPC_VALID_MASK;
Carsten Otte7eef87d2011-10-18 12:27:14 +0200540 restore_fp_regs(&vcpu->arch.guest_fpregs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100541 return 0;
542}
543
544int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
545{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100546 memcpy(&fpu->fprs, &vcpu->arch.guest_fpregs.fprs, sizeof(fpu->fprs));
547 fpu->fpc = vcpu->arch.guest_fpregs.fpc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100548 return 0;
549}
550
551static int kvm_arch_vcpu_ioctl_set_initial_psw(struct kvm_vcpu *vcpu, psw_t psw)
552{
553 int rc = 0;
554
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100555 if (!(atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_STOPPED))
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100556 rc = -EBUSY;
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100557 else {
558 vcpu->run->psw_mask = psw.mask;
559 vcpu->run->psw_addr = psw.addr;
560 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100561 return rc;
562}
563
564int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
565 struct kvm_translation *tr)
566{
567 return -EINVAL; /* not implemented yet */
568}
569
Jan Kiszkad0bfb942008-12-15 13:52:10 +0100570int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
571 struct kvm_guest_debug *dbg)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100572{
573 return -EINVAL; /* not implemented yet */
574}
575
Marcelo Tosatti62d9f0d2008-04-11 13:24:45 -0300576int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
577 struct kvm_mp_state *mp_state)
578{
579 return -EINVAL; /* not implemented yet */
580}
581
582int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
583 struct kvm_mp_state *mp_state)
584{
585 return -EINVAL; /* not implemented yet */
586}
587
Carsten Ottee168bf82012-01-04 10:25:22 +0100588static int __vcpu_run(struct kvm_vcpu *vcpu)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100589{
Carsten Ottee168bf82012-01-04 10:25:22 +0100590 int rc;
591
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100592 memcpy(&vcpu->arch.sie_block->gg14, &vcpu->run->s.regs.gprs[14], 16);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100593
594 if (need_resched())
595 schedule();
596
Christian Borntraeger71cde582008-05-21 13:37:34 +0200597 if (test_thread_flag(TIF_MCCK_PENDING))
598 s390_handle_mcck();
599
Carsten Otted6b6d162012-01-04 10:25:25 +0100600 if (!kvm_is_ucontrol(vcpu->kvm))
601 kvm_s390_deliver_pending_interrupts(vcpu);
Carsten Otte0ff31862008-05-21 13:37:37 +0200602
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100603 vcpu->arch.sie_block->icptcode = 0;
604 local_irq_disable();
605 kvm_guest_enter();
606 local_irq_enable();
607 VCPU_EVENT(vcpu, 6, "entering sie flags %x",
608 atomic_read(&vcpu->arch.sie_block->cpuflags));
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100609 rc = sie64a(vcpu->arch.sie_block, vcpu->run->s.regs.gprs);
Carsten Ottee168bf82012-01-04 10:25:22 +0100610 if (rc) {
611 if (kvm_is_ucontrol(vcpu->kvm)) {
612 rc = SIE_INTERCEPT_UCONTROL;
613 } else {
614 VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction");
615 kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
616 rc = 0;
617 }
Carsten Otte1f0d0f02008-05-21 13:37:40 +0200618 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100619 VCPU_EVENT(vcpu, 6, "exit sie icptcode %d",
620 vcpu->arch.sie_block->icptcode);
621 local_irq_disable();
622 kvm_guest_exit();
623 local_irq_enable();
624
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100625 memcpy(&vcpu->run->s.regs.gprs[14], &vcpu->arch.sie_block->gg14, 16);
Carsten Ottee168bf82012-01-04 10:25:22 +0100626 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100627}
628
629int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
630{
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100631 int rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100632 sigset_t sigsaved;
633
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200634rerun_vcpu:
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100635 if (vcpu->sigset_active)
636 sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
637
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100638 atomic_clear_mask(CPUSTAT_STOPPED, &vcpu->arch.sie_block->cpuflags);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100639
Carsten Otteba5c1e92008-03-25 18:47:26 +0100640 BUG_ON(vcpu->kvm->arch.float_int.local_int[vcpu->vcpu_id] == NULL);
641
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100642 switch (kvm_run->exit_reason) {
643 case KVM_EXIT_S390_SIEIC:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100644 case KVM_EXIT_UNKNOWN:
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200645 case KVM_EXIT_INTR:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100646 case KVM_EXIT_S390_RESET:
Carsten Ottee168bf82012-01-04 10:25:22 +0100647 case KVM_EXIT_S390_UCONTROL:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100648 break;
649 default:
650 BUG();
651 }
652
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100653 vcpu->arch.sie_block->gpsw.mask = kvm_run->psw_mask;
654 vcpu->arch.sie_block->gpsw.addr = kvm_run->psw_addr;
Christian Borntraeger60b413c2012-01-11 11:20:31 +0100655 if (kvm_run->kvm_dirty_regs & KVM_SYNC_PREFIX) {
656 kvm_run->kvm_dirty_regs &= ~KVM_SYNC_PREFIX;
657 kvm_s390_set_prefix(vcpu, kvm_run->s.regs.prefix);
658 }
Christian Borntraeger9eed07352012-02-06 10:59:07 +0100659 if (kvm_run->kvm_dirty_regs & KVM_SYNC_CRS) {
660 kvm_run->kvm_dirty_regs &= ~KVM_SYNC_CRS;
661 memcpy(&vcpu->arch.sie_block->gcr, &kvm_run->s.regs.crs, 128);
662 kvm_s390_set_prefix(vcpu, kvm_run->s.regs.prefix);
663 }
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100664
Heiko Carstensdab4079d2009-06-12 10:26:32 +0200665 might_fault();
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100666
667 do {
Carsten Ottee168bf82012-01-04 10:25:22 +0100668 rc = __vcpu_run(vcpu);
669 if (rc)
670 break;
Carsten Ottec0d744a2012-01-04 10:25:24 +0100671 if (kvm_is_ucontrol(vcpu->kvm))
672 rc = -EOPNOTSUPP;
673 else
674 rc = kvm_handle_sie_intercept(vcpu);
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100675 } while (!signal_pending(current) && !rc);
676
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200677 if (rc == SIE_INTERCEPT_RERUNVCPU)
678 goto rerun_vcpu;
679
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200680 if (signal_pending(current) && !rc) {
681 kvm_run->exit_reason = KVM_EXIT_INTR;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100682 rc = -EINTR;
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200683 }
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100684
Carsten Ottee168bf82012-01-04 10:25:22 +0100685#ifdef CONFIG_KVM_S390_UCONTROL
686 if (rc == SIE_INTERCEPT_UCONTROL) {
687 kvm_run->exit_reason = KVM_EXIT_S390_UCONTROL;
688 kvm_run->s390_ucontrol.trans_exc_code =
689 current->thread.gmap_addr;
690 kvm_run->s390_ucontrol.pgm_code = 0x10;
691 rc = 0;
692 }
693#endif
694
Heiko Carstensb8e660b2010-02-26 22:37:41 +0100695 if (rc == -EOPNOTSUPP) {
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100696 /* intercept cannot be handled in-kernel, prepare kvm-run */
697 kvm_run->exit_reason = KVM_EXIT_S390_SIEIC;
698 kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100699 kvm_run->s390_sieic.ipa = vcpu->arch.sie_block->ipa;
700 kvm_run->s390_sieic.ipb = vcpu->arch.sie_block->ipb;
701 rc = 0;
702 }
703
704 if (rc == -EREMOTE) {
705 /* intercept was handled, but userspace support is needed
706 * kvm_run has been prepared by the handler */
707 rc = 0;
708 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100709
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100710 kvm_run->psw_mask = vcpu->arch.sie_block->gpsw.mask;
711 kvm_run->psw_addr = vcpu->arch.sie_block->gpsw.addr;
Christian Borntraeger60b413c2012-01-11 11:20:31 +0100712 kvm_run->s.regs.prefix = vcpu->arch.sie_block->prefix;
Christian Borntraeger9eed07352012-02-06 10:59:07 +0100713 memcpy(&kvm_run->s.regs.crs, &vcpu->arch.sie_block->gcr, 128);
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100714
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100715 if (vcpu->sigset_active)
716 sigprocmask(SIG_SETMASK, &sigsaved, NULL);
717
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100718 vcpu->stat.exit_userspace++;
Heiko Carstens7e8e6ab2008-04-04 15:12:35 +0200719 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100720}
721
Carsten Otte092670c2011-07-24 10:48:22 +0200722static int __guestcopy(struct kvm_vcpu *vcpu, u64 guestdest, void *from,
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100723 unsigned long n, int prefix)
724{
725 if (prefix)
726 return copy_to_guest(vcpu, guestdest, from, n);
727 else
728 return copy_to_guest_absolute(vcpu, guestdest, from, n);
729}
730
731/*
732 * store status at address
733 * we use have two special cases:
734 * KVM_S390_STORE_STATUS_NOADDR: -> 0x1200 on 64 bit
735 * KVM_S390_STORE_STATUS_PREFIXED: -> prefix
736 */
Christian Borntraeger971eb772010-06-12 08:54:13 +0200737int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100738{
Carsten Otte092670c2011-07-24 10:48:22 +0200739 unsigned char archmode = 1;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100740 int prefix;
741
742 if (addr == KVM_S390_STORE_STATUS_NOADDR) {
743 if (copy_to_guest_absolute(vcpu, 163ul, &archmode, 1))
744 return -EFAULT;
745 addr = SAVE_AREA_BASE;
746 prefix = 0;
747 } else if (addr == KVM_S390_STORE_STATUS_PREFIXED) {
748 if (copy_to_guest(vcpu, 163ul, &archmode, 1))
749 return -EFAULT;
750 addr = SAVE_AREA_BASE;
751 prefix = 1;
752 } else
753 prefix = 0;
754
Heiko Carstensf64ca212010-02-26 22:37:32 +0100755 if (__guestcopy(vcpu, addr + offsetof(struct save_area, fp_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100756 vcpu->arch.guest_fpregs.fprs, 128, prefix))
757 return -EFAULT;
758
Heiko Carstensf64ca212010-02-26 22:37:32 +0100759 if (__guestcopy(vcpu, addr + offsetof(struct save_area, gp_regs),
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100760 vcpu->run->s.regs.gprs, 128, prefix))
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100761 return -EFAULT;
762
Heiko Carstensf64ca212010-02-26 22:37:32 +0100763 if (__guestcopy(vcpu, addr + offsetof(struct save_area, psw),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100764 &vcpu->arch.sie_block->gpsw, 16, prefix))
765 return -EFAULT;
766
Heiko Carstensf64ca212010-02-26 22:37:32 +0100767 if (__guestcopy(vcpu, addr + offsetof(struct save_area, pref_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100768 &vcpu->arch.sie_block->prefix, 4, prefix))
769 return -EFAULT;
770
771 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100772 addr + offsetof(struct save_area, fp_ctrl_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100773 &vcpu->arch.guest_fpregs.fpc, 4, prefix))
774 return -EFAULT;
775
Heiko Carstensf64ca212010-02-26 22:37:32 +0100776 if (__guestcopy(vcpu, addr + offsetof(struct save_area, tod_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100777 &vcpu->arch.sie_block->todpr, 4, prefix))
778 return -EFAULT;
779
Heiko Carstensf64ca212010-02-26 22:37:32 +0100780 if (__guestcopy(vcpu, addr + offsetof(struct save_area, timer),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100781 &vcpu->arch.sie_block->cputm, 8, prefix))
782 return -EFAULT;
783
Heiko Carstensf64ca212010-02-26 22:37:32 +0100784 if (__guestcopy(vcpu, addr + offsetof(struct save_area, clk_cmp),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100785 &vcpu->arch.sie_block->ckc, 8, prefix))
786 return -EFAULT;
787
Heiko Carstensf64ca212010-02-26 22:37:32 +0100788 if (__guestcopy(vcpu, addr + offsetof(struct save_area, acc_regs),
Christian Borntraeger59674c12012-01-11 11:20:33 +0100789 &vcpu->run->s.regs.acrs, 64, prefix))
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100790 return -EFAULT;
791
792 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100793 addr + offsetof(struct save_area, ctrl_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100794 &vcpu->arch.sie_block->gcr, 128, prefix))
795 return -EFAULT;
796 return 0;
797}
798
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100799long kvm_arch_vcpu_ioctl(struct file *filp,
800 unsigned int ioctl, unsigned long arg)
801{
802 struct kvm_vcpu *vcpu = filp->private_data;
803 void __user *argp = (void __user *)arg;
Avi Kivitybc923cc2010-05-13 12:21:46 +0300804 long r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100805
Avi Kivity937366242010-05-13 12:35:17 +0300806 switch (ioctl) {
807 case KVM_S390_INTERRUPT: {
Carsten Otteba5c1e92008-03-25 18:47:26 +0100808 struct kvm_s390_interrupt s390int;
809
Avi Kivity937366242010-05-13 12:35:17 +0300810 r = -EFAULT;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100811 if (copy_from_user(&s390int, argp, sizeof(s390int)))
Avi Kivity937366242010-05-13 12:35:17 +0300812 break;
813 r = kvm_s390_inject_vcpu(vcpu, &s390int);
814 break;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100815 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100816 case KVM_S390_STORE_STATUS:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300817 r = kvm_s390_vcpu_store_status(vcpu, arg);
818 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100819 case KVM_S390_SET_INITIAL_PSW: {
820 psw_t psw;
821
Avi Kivitybc923cc2010-05-13 12:21:46 +0300822 r = -EFAULT;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100823 if (copy_from_user(&psw, argp, sizeof(psw)))
Avi Kivitybc923cc2010-05-13 12:21:46 +0300824 break;
825 r = kvm_arch_vcpu_ioctl_set_initial_psw(vcpu, psw);
826 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100827 }
828 case KVM_S390_INITIAL_RESET:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300829 r = kvm_arch_vcpu_ioctl_initial_reset(vcpu);
830 break;
Carsten Otte14eebd92012-05-15 14:15:26 +0200831 case KVM_SET_ONE_REG:
832 case KVM_GET_ONE_REG: {
833 struct kvm_one_reg reg;
834 r = -EFAULT;
835 if (copy_from_user(&reg, argp, sizeof(reg)))
836 break;
837 if (ioctl == KVM_SET_ONE_REG)
838 r = kvm_arch_vcpu_ioctl_set_one_reg(vcpu, &reg);
839 else
840 r = kvm_arch_vcpu_ioctl_get_one_reg(vcpu, &reg);
841 break;
842 }
Carsten Otte27e03932012-01-04 10:25:21 +0100843#ifdef CONFIG_KVM_S390_UCONTROL
844 case KVM_S390_UCAS_MAP: {
845 struct kvm_s390_ucas_mapping ucasmap;
846
847 if (copy_from_user(&ucasmap, argp, sizeof(ucasmap))) {
848 r = -EFAULT;
849 break;
850 }
851
852 if (!kvm_is_ucontrol(vcpu->kvm)) {
853 r = -EINVAL;
854 break;
855 }
856
857 r = gmap_map_segment(vcpu->arch.gmap, ucasmap.user_addr,
858 ucasmap.vcpu_addr, ucasmap.length);
859 break;
860 }
861 case KVM_S390_UCAS_UNMAP: {
862 struct kvm_s390_ucas_mapping ucasmap;
863
864 if (copy_from_user(&ucasmap, argp, sizeof(ucasmap))) {
865 r = -EFAULT;
866 break;
867 }
868
869 if (!kvm_is_ucontrol(vcpu->kvm)) {
870 r = -EINVAL;
871 break;
872 }
873
874 r = gmap_unmap_segment(vcpu->arch.gmap, ucasmap.vcpu_addr,
875 ucasmap.length);
876 break;
877 }
878#endif
Carsten Otteccc79102012-01-04 10:25:26 +0100879 case KVM_S390_VCPU_FAULT: {
880 r = gmap_fault(arg, vcpu->arch.gmap);
881 if (!IS_ERR_VALUE(r))
882 r = 0;
883 break;
884 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100885 default:
Carsten Otte3e6afcf2012-01-04 10:25:30 +0100886 r = -ENOTTY;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100887 }
Avi Kivitybc923cc2010-05-13 12:21:46 +0300888 return r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100889}
890
Carsten Otte5b1c1492012-01-04 10:25:23 +0100891int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
892{
893#ifdef CONFIG_KVM_S390_UCONTROL
894 if ((vmf->pgoff == KVM_S390_SIE_PAGE_OFFSET)
895 && (kvm_is_ucontrol(vcpu->kvm))) {
896 vmf->page = virt_to_page(vcpu->arch.sie_block);
897 get_page(vmf->page);
898 return 0;
899 }
900#endif
901 return VM_FAULT_SIGBUS;
902}
903
Takuya Yoshikawadb3fe4e2012-02-08 13:02:18 +0900904void kvm_arch_free_memslot(struct kvm_memory_slot *free,
905 struct kvm_memory_slot *dont)
906{
907}
908
909int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages)
910{
911 return 0;
912}
913
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100914/* Section: memory related */
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200915int kvm_arch_prepare_memory_region(struct kvm *kvm,
916 struct kvm_memory_slot *memslot,
917 struct kvm_memory_slot old,
918 struct kvm_userspace_memory_region *mem,
919 int user_alloc)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100920{
921 /* A few sanity checks. We can have exactly one memory slot which has
922 to start at guest virtual zero and which has to be located at a
923 page boundary in userland and which has to end at a page boundary.
924 The memory in userland is ok to be fragmented into various different
925 vmas. It is okay to mmap() and munmap() stuff in this slot after
926 doing this call at any time */
927
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200928 if (mem->slot)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100929 return -EINVAL;
930
931 if (mem->guest_phys_addr)
932 return -EINVAL;
933
Carsten Otte598841c2011-07-24 10:48:21 +0200934 if (mem->userspace_addr & 0xffffful)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100935 return -EINVAL;
936
Carsten Otte598841c2011-07-24 10:48:21 +0200937 if (mem->memory_size & 0xffffful)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100938 return -EINVAL;
939
Carsten Otte2668dab2009-05-12 17:21:48 +0200940 if (!user_alloc)
941 return -EINVAL;
942
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200943 return 0;
944}
945
946void kvm_arch_commit_memory_region(struct kvm *kvm,
947 struct kvm_userspace_memory_region *mem,
948 struct kvm_memory_slot old,
949 int user_alloc)
950{
Carsten Ottef7850c92011-07-24 10:48:23 +0200951 int rc;
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200952
Carsten Otte598841c2011-07-24 10:48:21 +0200953
954 rc = gmap_map_segment(kvm->arch.gmap, mem->userspace_addr,
955 mem->guest_phys_addr, mem->memory_size);
956 if (rc)
Carsten Ottef7850c92011-07-24 10:48:23 +0200957 printk(KERN_WARNING "kvm-s390: failed to commit memory region\n");
Carsten Otte598841c2011-07-24 10:48:21 +0200958 return;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100959}
960
Marcelo Tosatti34d4cb82008-07-10 20:49:31 -0300961void kvm_arch_flush_shadow(struct kvm *kvm)
962{
963}
964
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100965static int __init kvm_s390_init(void)
966{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200967 int ret;
Avi Kivity0ee75be2010-04-28 15:39:01 +0300968 ret = kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE);
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200969 if (ret)
970 return ret;
971
972 /*
973 * guests can ask for up to 255+1 double words, we need a full page
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300974 * to hold the maximum amount of facilities. On the other hand, we
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200975 * only set facilities that are known to work in KVM.
976 */
Heiko Carstensc2f0e8c2010-06-08 18:58:09 +0200977 facilities = (unsigned long long *) get_zeroed_page(GFP_KERNEL|GFP_DMA);
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200978 if (!facilities) {
979 kvm_exit();
980 return -ENOMEM;
981 }
Martin Schwidefsky14375bc2010-10-25 16:10:51 +0200982 memcpy(facilities, S390_lowcore.stfle_fac_list, 16);
Christian Borntraeger6d00d002010-10-25 16:10:48 +0200983 facilities[0] &= 0xff00fff3f47c0000ULL;
Christian Borntraeger9950f8b2011-06-06 14:14:39 +0200984 facilities[1] &= 0x201c000000000000ULL;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200985 return 0;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100986}
987
988static void __exit kvm_s390_exit(void)
989{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200990 free_page((unsigned long) facilities);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100991 kvm_exit();
992}
993
994module_init(kvm_s390_init);
995module_exit(kvm_s390_exit);