blob: cc4c01322ce4e52bd75347fe272ff29a82721d4e [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;
Carsten Otte14eebd92012-05-15 14:15:26 +0200457 default:
458 break;
459 }
460
461 return r;
462}
463
464static int kvm_arch_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu,
465 struct kvm_one_reg *reg)
466{
467 int r = -EINVAL;
468
469 switch (reg->id) {
Carsten Otte29b7c712012-05-15 14:15:27 +0200470 case KVM_REG_S390_TODPR:
471 r = get_user(vcpu->arch.sie_block->todpr,
472 (u32 __user *)reg->addr);
473 break;
474 case KVM_REG_S390_EPOCHDIFF:
475 r = get_user(vcpu->arch.sie_block->epoch,
476 (u64 __user *)reg->addr);
477 break;
Carsten Otte14eebd92012-05-15 14:15:26 +0200478 default:
479 break;
480 }
481
482 return r;
483}
Christoffer Dallb6d33832012-03-08 16:44:24 -0500484
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100485static int kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu)
486{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100487 kvm_s390_vcpu_initial_reset(vcpu);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100488 return 0;
489}
490
491int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
492{
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100493 memcpy(&vcpu->run->s.regs.gprs, &regs->gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100494 return 0;
495}
496
497int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
498{
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100499 memcpy(&regs->gprs, &vcpu->run->s.regs.gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100500 return 0;
501}
502
503int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
504 struct kvm_sregs *sregs)
505{
Christian Borntraeger59674c12012-01-11 11:20:33 +0100506 memcpy(&vcpu->run->s.regs.acrs, &sregs->acrs, sizeof(sregs->acrs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100507 memcpy(&vcpu->arch.sie_block->gcr, &sregs->crs, sizeof(sregs->crs));
Christian Borntraeger59674c12012-01-11 11:20:33 +0100508 restore_access_regs(vcpu->run->s.regs.acrs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100509 return 0;
510}
511
512int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
513 struct kvm_sregs *sregs)
514{
Christian Borntraeger59674c12012-01-11 11:20:33 +0100515 memcpy(&sregs->acrs, &vcpu->run->s.regs.acrs, sizeof(sregs->acrs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100516 memcpy(&sregs->crs, &vcpu->arch.sie_block->gcr, sizeof(sregs->crs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100517 return 0;
518}
519
520int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
521{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100522 memcpy(&vcpu->arch.guest_fpregs.fprs, &fpu->fprs, sizeof(fpu->fprs));
Christian Borntraeger85175582012-02-06 10:59:02 +0100523 vcpu->arch.guest_fpregs.fpc = fpu->fpc & FPC_VALID_MASK;
Carsten Otte7eef87d2011-10-18 12:27:14 +0200524 restore_fp_regs(&vcpu->arch.guest_fpregs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100525 return 0;
526}
527
528int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
529{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100530 memcpy(&fpu->fprs, &vcpu->arch.guest_fpregs.fprs, sizeof(fpu->fprs));
531 fpu->fpc = vcpu->arch.guest_fpregs.fpc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100532 return 0;
533}
534
535static int kvm_arch_vcpu_ioctl_set_initial_psw(struct kvm_vcpu *vcpu, psw_t psw)
536{
537 int rc = 0;
538
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100539 if (!(atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_STOPPED))
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100540 rc = -EBUSY;
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100541 else {
542 vcpu->run->psw_mask = psw.mask;
543 vcpu->run->psw_addr = psw.addr;
544 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100545 return rc;
546}
547
548int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
549 struct kvm_translation *tr)
550{
551 return -EINVAL; /* not implemented yet */
552}
553
Jan Kiszkad0bfb942008-12-15 13:52:10 +0100554int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
555 struct kvm_guest_debug *dbg)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100556{
557 return -EINVAL; /* not implemented yet */
558}
559
Marcelo Tosatti62d9f0d2008-04-11 13:24:45 -0300560int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
561 struct kvm_mp_state *mp_state)
562{
563 return -EINVAL; /* not implemented yet */
564}
565
566int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
567 struct kvm_mp_state *mp_state)
568{
569 return -EINVAL; /* not implemented yet */
570}
571
Carsten Ottee168bf82012-01-04 10:25:22 +0100572static int __vcpu_run(struct kvm_vcpu *vcpu)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100573{
Carsten Ottee168bf82012-01-04 10:25:22 +0100574 int rc;
575
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100576 memcpy(&vcpu->arch.sie_block->gg14, &vcpu->run->s.regs.gprs[14], 16);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100577
578 if (need_resched())
579 schedule();
580
Christian Borntraeger71cde582008-05-21 13:37:34 +0200581 if (test_thread_flag(TIF_MCCK_PENDING))
582 s390_handle_mcck();
583
Carsten Otted6b6d162012-01-04 10:25:25 +0100584 if (!kvm_is_ucontrol(vcpu->kvm))
585 kvm_s390_deliver_pending_interrupts(vcpu);
Carsten Otte0ff31862008-05-21 13:37:37 +0200586
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100587 vcpu->arch.sie_block->icptcode = 0;
588 local_irq_disable();
589 kvm_guest_enter();
590 local_irq_enable();
591 VCPU_EVENT(vcpu, 6, "entering sie flags %x",
592 atomic_read(&vcpu->arch.sie_block->cpuflags));
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100593 rc = sie64a(vcpu->arch.sie_block, vcpu->run->s.regs.gprs);
Carsten Ottee168bf82012-01-04 10:25:22 +0100594 if (rc) {
595 if (kvm_is_ucontrol(vcpu->kvm)) {
596 rc = SIE_INTERCEPT_UCONTROL;
597 } else {
598 VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction");
599 kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
600 rc = 0;
601 }
Carsten Otte1f0d0f02008-05-21 13:37:40 +0200602 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100603 VCPU_EVENT(vcpu, 6, "exit sie icptcode %d",
604 vcpu->arch.sie_block->icptcode);
605 local_irq_disable();
606 kvm_guest_exit();
607 local_irq_enable();
608
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100609 memcpy(&vcpu->run->s.regs.gprs[14], &vcpu->arch.sie_block->gg14, 16);
Carsten Ottee168bf82012-01-04 10:25:22 +0100610 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100611}
612
613int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
614{
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100615 int rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100616 sigset_t sigsaved;
617
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200618rerun_vcpu:
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100619 if (vcpu->sigset_active)
620 sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
621
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100622 atomic_clear_mask(CPUSTAT_STOPPED, &vcpu->arch.sie_block->cpuflags);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100623
Carsten Otteba5c1e92008-03-25 18:47:26 +0100624 BUG_ON(vcpu->kvm->arch.float_int.local_int[vcpu->vcpu_id] == NULL);
625
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100626 switch (kvm_run->exit_reason) {
627 case KVM_EXIT_S390_SIEIC:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100628 case KVM_EXIT_UNKNOWN:
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200629 case KVM_EXIT_INTR:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100630 case KVM_EXIT_S390_RESET:
Carsten Ottee168bf82012-01-04 10:25:22 +0100631 case KVM_EXIT_S390_UCONTROL:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100632 break;
633 default:
634 BUG();
635 }
636
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100637 vcpu->arch.sie_block->gpsw.mask = kvm_run->psw_mask;
638 vcpu->arch.sie_block->gpsw.addr = kvm_run->psw_addr;
Christian Borntraeger60b413c2012-01-11 11:20:31 +0100639 if (kvm_run->kvm_dirty_regs & KVM_SYNC_PREFIX) {
640 kvm_run->kvm_dirty_regs &= ~KVM_SYNC_PREFIX;
641 kvm_s390_set_prefix(vcpu, kvm_run->s.regs.prefix);
642 }
Christian Borntraeger9eed07352012-02-06 10:59:07 +0100643 if (kvm_run->kvm_dirty_regs & KVM_SYNC_CRS) {
644 kvm_run->kvm_dirty_regs &= ~KVM_SYNC_CRS;
645 memcpy(&vcpu->arch.sie_block->gcr, &kvm_run->s.regs.crs, 128);
646 kvm_s390_set_prefix(vcpu, kvm_run->s.regs.prefix);
647 }
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100648
Heiko Carstensdab4079d2009-06-12 10:26:32 +0200649 might_fault();
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100650
651 do {
Carsten Ottee168bf82012-01-04 10:25:22 +0100652 rc = __vcpu_run(vcpu);
653 if (rc)
654 break;
Carsten Ottec0d744a2012-01-04 10:25:24 +0100655 if (kvm_is_ucontrol(vcpu->kvm))
656 rc = -EOPNOTSUPP;
657 else
658 rc = kvm_handle_sie_intercept(vcpu);
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100659 } while (!signal_pending(current) && !rc);
660
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200661 if (rc == SIE_INTERCEPT_RERUNVCPU)
662 goto rerun_vcpu;
663
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200664 if (signal_pending(current) && !rc) {
665 kvm_run->exit_reason = KVM_EXIT_INTR;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100666 rc = -EINTR;
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200667 }
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100668
Carsten Ottee168bf82012-01-04 10:25:22 +0100669#ifdef CONFIG_KVM_S390_UCONTROL
670 if (rc == SIE_INTERCEPT_UCONTROL) {
671 kvm_run->exit_reason = KVM_EXIT_S390_UCONTROL;
672 kvm_run->s390_ucontrol.trans_exc_code =
673 current->thread.gmap_addr;
674 kvm_run->s390_ucontrol.pgm_code = 0x10;
675 rc = 0;
676 }
677#endif
678
Heiko Carstensb8e660b2010-02-26 22:37:41 +0100679 if (rc == -EOPNOTSUPP) {
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100680 /* intercept cannot be handled in-kernel, prepare kvm-run */
681 kvm_run->exit_reason = KVM_EXIT_S390_SIEIC;
682 kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100683 kvm_run->s390_sieic.ipa = vcpu->arch.sie_block->ipa;
684 kvm_run->s390_sieic.ipb = vcpu->arch.sie_block->ipb;
685 rc = 0;
686 }
687
688 if (rc == -EREMOTE) {
689 /* intercept was handled, but userspace support is needed
690 * kvm_run has been prepared by the handler */
691 rc = 0;
692 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100693
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100694 kvm_run->psw_mask = vcpu->arch.sie_block->gpsw.mask;
695 kvm_run->psw_addr = vcpu->arch.sie_block->gpsw.addr;
Christian Borntraeger60b413c2012-01-11 11:20:31 +0100696 kvm_run->s.regs.prefix = vcpu->arch.sie_block->prefix;
Christian Borntraeger9eed07352012-02-06 10:59:07 +0100697 memcpy(&kvm_run->s.regs.crs, &vcpu->arch.sie_block->gcr, 128);
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100698
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100699 if (vcpu->sigset_active)
700 sigprocmask(SIG_SETMASK, &sigsaved, NULL);
701
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100702 vcpu->stat.exit_userspace++;
Heiko Carstens7e8e6ab2008-04-04 15:12:35 +0200703 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100704}
705
Carsten Otte092670c2011-07-24 10:48:22 +0200706static int __guestcopy(struct kvm_vcpu *vcpu, u64 guestdest, void *from,
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100707 unsigned long n, int prefix)
708{
709 if (prefix)
710 return copy_to_guest(vcpu, guestdest, from, n);
711 else
712 return copy_to_guest_absolute(vcpu, guestdest, from, n);
713}
714
715/*
716 * store status at address
717 * we use have two special cases:
718 * KVM_S390_STORE_STATUS_NOADDR: -> 0x1200 on 64 bit
719 * KVM_S390_STORE_STATUS_PREFIXED: -> prefix
720 */
Christian Borntraeger971eb772010-06-12 08:54:13 +0200721int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100722{
Carsten Otte092670c2011-07-24 10:48:22 +0200723 unsigned char archmode = 1;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100724 int prefix;
725
726 if (addr == KVM_S390_STORE_STATUS_NOADDR) {
727 if (copy_to_guest_absolute(vcpu, 163ul, &archmode, 1))
728 return -EFAULT;
729 addr = SAVE_AREA_BASE;
730 prefix = 0;
731 } else if (addr == KVM_S390_STORE_STATUS_PREFIXED) {
732 if (copy_to_guest(vcpu, 163ul, &archmode, 1))
733 return -EFAULT;
734 addr = SAVE_AREA_BASE;
735 prefix = 1;
736 } else
737 prefix = 0;
738
Heiko Carstensf64ca212010-02-26 22:37:32 +0100739 if (__guestcopy(vcpu, addr + offsetof(struct save_area, fp_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100740 vcpu->arch.guest_fpregs.fprs, 128, prefix))
741 return -EFAULT;
742
Heiko Carstensf64ca212010-02-26 22:37:32 +0100743 if (__guestcopy(vcpu, addr + offsetof(struct save_area, gp_regs),
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100744 vcpu->run->s.regs.gprs, 128, prefix))
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100745 return -EFAULT;
746
Heiko Carstensf64ca212010-02-26 22:37:32 +0100747 if (__guestcopy(vcpu, addr + offsetof(struct save_area, psw),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100748 &vcpu->arch.sie_block->gpsw, 16, prefix))
749 return -EFAULT;
750
Heiko Carstensf64ca212010-02-26 22:37:32 +0100751 if (__guestcopy(vcpu, addr + offsetof(struct save_area, pref_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100752 &vcpu->arch.sie_block->prefix, 4, prefix))
753 return -EFAULT;
754
755 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100756 addr + offsetof(struct save_area, fp_ctrl_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100757 &vcpu->arch.guest_fpregs.fpc, 4, prefix))
758 return -EFAULT;
759
Heiko Carstensf64ca212010-02-26 22:37:32 +0100760 if (__guestcopy(vcpu, addr + offsetof(struct save_area, tod_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100761 &vcpu->arch.sie_block->todpr, 4, prefix))
762 return -EFAULT;
763
Heiko Carstensf64ca212010-02-26 22:37:32 +0100764 if (__guestcopy(vcpu, addr + offsetof(struct save_area, timer),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100765 &vcpu->arch.sie_block->cputm, 8, prefix))
766 return -EFAULT;
767
Heiko Carstensf64ca212010-02-26 22:37:32 +0100768 if (__guestcopy(vcpu, addr + offsetof(struct save_area, clk_cmp),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100769 &vcpu->arch.sie_block->ckc, 8, prefix))
770 return -EFAULT;
771
Heiko Carstensf64ca212010-02-26 22:37:32 +0100772 if (__guestcopy(vcpu, addr + offsetof(struct save_area, acc_regs),
Christian Borntraeger59674c12012-01-11 11:20:33 +0100773 &vcpu->run->s.regs.acrs, 64, prefix))
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100774 return -EFAULT;
775
776 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100777 addr + offsetof(struct save_area, ctrl_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100778 &vcpu->arch.sie_block->gcr, 128, prefix))
779 return -EFAULT;
780 return 0;
781}
782
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100783long kvm_arch_vcpu_ioctl(struct file *filp,
784 unsigned int ioctl, unsigned long arg)
785{
786 struct kvm_vcpu *vcpu = filp->private_data;
787 void __user *argp = (void __user *)arg;
Avi Kivitybc923cc2010-05-13 12:21:46 +0300788 long r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100789
Avi Kivity93736622010-05-13 12:35:17 +0300790 switch (ioctl) {
791 case KVM_S390_INTERRUPT: {
Carsten Otteba5c1e92008-03-25 18:47:26 +0100792 struct kvm_s390_interrupt s390int;
793
Avi Kivity93736622010-05-13 12:35:17 +0300794 r = -EFAULT;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100795 if (copy_from_user(&s390int, argp, sizeof(s390int)))
Avi Kivity93736622010-05-13 12:35:17 +0300796 break;
797 r = kvm_s390_inject_vcpu(vcpu, &s390int);
798 break;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100799 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100800 case KVM_S390_STORE_STATUS:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300801 r = kvm_s390_vcpu_store_status(vcpu, arg);
802 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100803 case KVM_S390_SET_INITIAL_PSW: {
804 psw_t psw;
805
Avi Kivitybc923cc2010-05-13 12:21:46 +0300806 r = -EFAULT;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100807 if (copy_from_user(&psw, argp, sizeof(psw)))
Avi Kivitybc923cc2010-05-13 12:21:46 +0300808 break;
809 r = kvm_arch_vcpu_ioctl_set_initial_psw(vcpu, psw);
810 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100811 }
812 case KVM_S390_INITIAL_RESET:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300813 r = kvm_arch_vcpu_ioctl_initial_reset(vcpu);
814 break;
Carsten Otte14eebd92012-05-15 14:15:26 +0200815 case KVM_SET_ONE_REG:
816 case KVM_GET_ONE_REG: {
817 struct kvm_one_reg reg;
818 r = -EFAULT;
819 if (copy_from_user(&reg, argp, sizeof(reg)))
820 break;
821 if (ioctl == KVM_SET_ONE_REG)
822 r = kvm_arch_vcpu_ioctl_set_one_reg(vcpu, &reg);
823 else
824 r = kvm_arch_vcpu_ioctl_get_one_reg(vcpu, &reg);
825 break;
826 }
Carsten Otte27e03932012-01-04 10:25:21 +0100827#ifdef CONFIG_KVM_S390_UCONTROL
828 case KVM_S390_UCAS_MAP: {
829 struct kvm_s390_ucas_mapping ucasmap;
830
831 if (copy_from_user(&ucasmap, argp, sizeof(ucasmap))) {
832 r = -EFAULT;
833 break;
834 }
835
836 if (!kvm_is_ucontrol(vcpu->kvm)) {
837 r = -EINVAL;
838 break;
839 }
840
841 r = gmap_map_segment(vcpu->arch.gmap, ucasmap.user_addr,
842 ucasmap.vcpu_addr, ucasmap.length);
843 break;
844 }
845 case KVM_S390_UCAS_UNMAP: {
846 struct kvm_s390_ucas_mapping ucasmap;
847
848 if (copy_from_user(&ucasmap, argp, sizeof(ucasmap))) {
849 r = -EFAULT;
850 break;
851 }
852
853 if (!kvm_is_ucontrol(vcpu->kvm)) {
854 r = -EINVAL;
855 break;
856 }
857
858 r = gmap_unmap_segment(vcpu->arch.gmap, ucasmap.vcpu_addr,
859 ucasmap.length);
860 break;
861 }
862#endif
Carsten Otteccc79102012-01-04 10:25:26 +0100863 case KVM_S390_VCPU_FAULT: {
864 r = gmap_fault(arg, vcpu->arch.gmap);
865 if (!IS_ERR_VALUE(r))
866 r = 0;
867 break;
868 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100869 default:
Carsten Otte3e6afcf2012-01-04 10:25:30 +0100870 r = -ENOTTY;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100871 }
Avi Kivitybc923cc2010-05-13 12:21:46 +0300872 return r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100873}
874
Carsten Otte5b1c1492012-01-04 10:25:23 +0100875int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
876{
877#ifdef CONFIG_KVM_S390_UCONTROL
878 if ((vmf->pgoff == KVM_S390_SIE_PAGE_OFFSET)
879 && (kvm_is_ucontrol(vcpu->kvm))) {
880 vmf->page = virt_to_page(vcpu->arch.sie_block);
881 get_page(vmf->page);
882 return 0;
883 }
884#endif
885 return VM_FAULT_SIGBUS;
886}
887
Takuya Yoshikawadb3fe4e2012-02-08 13:02:18 +0900888void kvm_arch_free_memslot(struct kvm_memory_slot *free,
889 struct kvm_memory_slot *dont)
890{
891}
892
893int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages)
894{
895 return 0;
896}
897
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100898/* Section: memory related */
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200899int kvm_arch_prepare_memory_region(struct kvm *kvm,
900 struct kvm_memory_slot *memslot,
901 struct kvm_memory_slot old,
902 struct kvm_userspace_memory_region *mem,
903 int user_alloc)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100904{
905 /* A few sanity checks. We can have exactly one memory slot which has
906 to start at guest virtual zero and which has to be located at a
907 page boundary in userland and which has to end at a page boundary.
908 The memory in userland is ok to be fragmented into various different
909 vmas. It is okay to mmap() and munmap() stuff in this slot after
910 doing this call at any time */
911
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200912 if (mem->slot)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100913 return -EINVAL;
914
915 if (mem->guest_phys_addr)
916 return -EINVAL;
917
Carsten Otte598841c2011-07-24 10:48:21 +0200918 if (mem->userspace_addr & 0xffffful)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100919 return -EINVAL;
920
Carsten Otte598841c2011-07-24 10:48:21 +0200921 if (mem->memory_size & 0xffffful)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100922 return -EINVAL;
923
Carsten Otte2668dab2009-05-12 17:21:48 +0200924 if (!user_alloc)
925 return -EINVAL;
926
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200927 return 0;
928}
929
930void kvm_arch_commit_memory_region(struct kvm *kvm,
931 struct kvm_userspace_memory_region *mem,
932 struct kvm_memory_slot old,
933 int user_alloc)
934{
Carsten Ottef7850c92011-07-24 10:48:23 +0200935 int rc;
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200936
Carsten Otte598841c2011-07-24 10:48:21 +0200937
938 rc = gmap_map_segment(kvm->arch.gmap, mem->userspace_addr,
939 mem->guest_phys_addr, mem->memory_size);
940 if (rc)
Carsten Ottef7850c92011-07-24 10:48:23 +0200941 printk(KERN_WARNING "kvm-s390: failed to commit memory region\n");
Carsten Otte598841c2011-07-24 10:48:21 +0200942 return;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100943}
944
Marcelo Tosatti34d4cb82008-07-10 20:49:31 -0300945void kvm_arch_flush_shadow(struct kvm *kvm)
946{
947}
948
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100949static int __init kvm_s390_init(void)
950{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200951 int ret;
Avi Kivity0ee75be2010-04-28 15:39:01 +0300952 ret = kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE);
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200953 if (ret)
954 return ret;
955
956 /*
957 * guests can ask for up to 255+1 double words, we need a full page
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300958 * to hold the maximum amount of facilities. On the other hand, we
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200959 * only set facilities that are known to work in KVM.
960 */
Heiko Carstensc2f0e8c2010-06-08 18:58:09 +0200961 facilities = (unsigned long long *) get_zeroed_page(GFP_KERNEL|GFP_DMA);
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200962 if (!facilities) {
963 kvm_exit();
964 return -ENOMEM;
965 }
Martin Schwidefsky14375bc2010-10-25 16:10:51 +0200966 memcpy(facilities, S390_lowcore.stfle_fac_list, 16);
Christian Borntraeger6d00d002010-10-25 16:10:48 +0200967 facilities[0] &= 0xff00fff3f47c0000ULL;
Christian Borntraeger9950f8b2011-06-06 14:14:39 +0200968 facilities[1] &= 0x201c000000000000ULL;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200969 return 0;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100970}
971
972static void __exit kvm_s390_exit(void)
973{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200974 free_page((unsigned long) facilities);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100975 kvm_exit();
976}
977
978module_init(kvm_s390_init);
979module_exit(kvm_s390_exit);