blob: d470ccbfabae02e015e206f833a93ec0820941fa [file] [log] [blame]
Heiko Carstensb0c632d2008-03-25 18:47:20 +01001/*
Heiko Carstensa53c8fa2012-07-20 11:15:04 +02002 * hosting zSeries kernel virtual machines
Heiko Carstensb0c632d2008-03-25 18:47:20 +01003 *
Heiko Carstensa53c8fa2012-07-20 11:15:04 +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;
Christian Borntraeger61bde822012-06-11 16:06:57 +0200350 atomic_set_mask(CPUSTAT_STOPPED, &vcpu->arch.sie_block->cpuflags);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100351}
352
353int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
354{
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100355 atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH |
356 CPUSTAT_SM |
357 CPUSTAT_STOPPED);
Christian Borntraegerfc345312010-06-17 23:16:20 +0200358 vcpu->arch.sie_block->ecb = 6;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100359 vcpu->arch.sie_block->eca = 0xC1002001U;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200360 vcpu->arch.sie_block->fac = (int) (long) facilities;
Christian Borntraegerca872302009-05-12 17:21:49 +0200361 hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
362 tasklet_init(&vcpu->arch.tasklet, kvm_s390_tasklet,
363 (unsigned long) vcpu);
364 vcpu->arch.ckc_timer.function = kvm_s390_idle_wakeup;
Christian Borntraeger453423d2008-03-25 18:47:29 +0100365 get_cpu_id(&vcpu->arch.cpu_id);
Christian Borntraeger92e6ecf2009-03-26 15:23:58 +0100366 vcpu->arch.cpu_id.version = 0xff;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100367 return 0;
368}
369
370struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
371 unsigned int id)
372{
Carsten Otte4d475552011-10-18 12:27:12 +0200373 struct kvm_vcpu *vcpu;
374 int rc = -EINVAL;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100375
Carsten Otte4d475552011-10-18 12:27:12 +0200376 if (id >= KVM_MAX_VCPUS)
377 goto out;
378
379 rc = -ENOMEM;
380
381 vcpu = kzalloc(sizeof(struct kvm_vcpu), GFP_KERNEL);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100382 if (!vcpu)
Carsten Otte4d475552011-10-18 12:27:12 +0200383 goto out;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100384
Christian Borntraeger180c12f2008-06-27 15:05:40 +0200385 vcpu->arch.sie_block = (struct kvm_s390_sie_block *)
386 get_zeroed_page(GFP_KERNEL);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100387
388 if (!vcpu->arch.sie_block)
389 goto out_free_cpu;
390
391 vcpu->arch.sie_block->icpua = id;
Carsten Otte58f94602012-01-04 10:25:27 +0100392 if (!kvm_is_ucontrol(kvm)) {
393 if (!kvm->arch.sca) {
394 WARN_ON_ONCE(1);
395 goto out_free_cpu;
396 }
397 if (!kvm->arch.sca->cpu[id].sda)
398 kvm->arch.sca->cpu[id].sda =
399 (__u64) vcpu->arch.sie_block;
400 vcpu->arch.sie_block->scaoh =
401 (__u32)(((__u64)kvm->arch.sca) >> 32);
402 vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca;
403 set_bit(63 - id, (unsigned long *) &kvm->arch.sca->mcn);
404 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100405
Carsten Otteba5c1e92008-03-25 18:47:26 +0100406 spin_lock_init(&vcpu->arch.local_int.lock);
407 INIT_LIST_HEAD(&vcpu->arch.local_int.list);
408 vcpu->arch.local_int.float_int = &kvm->arch.float_int;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200409 spin_lock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100410 kvm->arch.float_int.local_int[id] = &vcpu->arch.local_int;
411 init_waitqueue_head(&vcpu->arch.local_int.wq);
Christian Borntraeger5288fbf2008-03-25 18:47:31 +0100412 vcpu->arch.local_int.cpuflags = &vcpu->arch.sie_block->cpuflags;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200413 spin_unlock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100414
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100415 rc = kvm_vcpu_init(vcpu, kvm, id);
416 if (rc)
Wei Yongjun7b06bf22010-03-09 14:37:53 +0800417 goto out_free_sie_block;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100418 VM_EVENT(kvm, 3, "create cpu %d at %p, sie block at %p", id, vcpu,
419 vcpu->arch.sie_block);
420
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100421 return vcpu;
Wei Yongjun7b06bf22010-03-09 14:37:53 +0800422out_free_sie_block:
423 free_page((unsigned long)(vcpu->arch.sie_block));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100424out_free_cpu:
425 kfree(vcpu);
Carsten Otte4d475552011-10-18 12:27:12 +0200426out:
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100427 return ERR_PTR(rc);
428}
429
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100430int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
431{
432 /* kvm common code refers to this, but never calls it */
433 BUG();
434 return 0;
435}
436
Christoffer Dallb6d33832012-03-08 16:44:24 -0500437int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
438{
439 /* kvm common code refers to this, but never calls it */
440 BUG();
441 return 0;
442}
443
Carsten Otte14eebd92012-05-15 14:15:26 +0200444static int kvm_arch_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu,
445 struct kvm_one_reg *reg)
446{
447 int r = -EINVAL;
448
449 switch (reg->id) {
Carsten Otte29b7c712012-05-15 14:15:27 +0200450 case KVM_REG_S390_TODPR:
451 r = put_user(vcpu->arch.sie_block->todpr,
452 (u32 __user *)reg->addr);
453 break;
454 case KVM_REG_S390_EPOCHDIFF:
455 r = put_user(vcpu->arch.sie_block->epoch,
456 (u64 __user *)reg->addr);
457 break;
Jason J. herne46a6dd12012-05-15 14:15:28 +0200458 case KVM_REG_S390_CPU_TIMER:
459 r = put_user(vcpu->arch.sie_block->cputm,
460 (u64 __user *)reg->addr);
461 break;
462 case KVM_REG_S390_CLOCK_COMP:
463 r = put_user(vcpu->arch.sie_block->ckc,
464 (u64 __user *)reg->addr);
465 break;
Carsten Otte14eebd92012-05-15 14:15:26 +0200466 default:
467 break;
468 }
469
470 return r;
471}
472
473static int kvm_arch_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu,
474 struct kvm_one_reg *reg)
475{
476 int r = -EINVAL;
477
478 switch (reg->id) {
Carsten Otte29b7c712012-05-15 14:15:27 +0200479 case KVM_REG_S390_TODPR:
480 r = get_user(vcpu->arch.sie_block->todpr,
481 (u32 __user *)reg->addr);
482 break;
483 case KVM_REG_S390_EPOCHDIFF:
484 r = get_user(vcpu->arch.sie_block->epoch,
485 (u64 __user *)reg->addr);
486 break;
Jason J. herne46a6dd12012-05-15 14:15:28 +0200487 case KVM_REG_S390_CPU_TIMER:
488 r = get_user(vcpu->arch.sie_block->cputm,
489 (u64 __user *)reg->addr);
490 break;
491 case KVM_REG_S390_CLOCK_COMP:
492 r = get_user(vcpu->arch.sie_block->ckc,
493 (u64 __user *)reg->addr);
494 break;
Carsten Otte14eebd92012-05-15 14:15:26 +0200495 default:
496 break;
497 }
498
499 return r;
500}
Christoffer Dallb6d33832012-03-08 16:44:24 -0500501
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100502static int kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu)
503{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100504 kvm_s390_vcpu_initial_reset(vcpu);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100505 return 0;
506}
507
508int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
509{
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100510 memcpy(&vcpu->run->s.regs.gprs, &regs->gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100511 return 0;
512}
513
514int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
515{
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100516 memcpy(&regs->gprs, &vcpu->run->s.regs.gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100517 return 0;
518}
519
520int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
521 struct kvm_sregs *sregs)
522{
Christian Borntraeger59674c12012-01-11 11:20:33 +0100523 memcpy(&vcpu->run->s.regs.acrs, &sregs->acrs, sizeof(sregs->acrs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100524 memcpy(&vcpu->arch.sie_block->gcr, &sregs->crs, sizeof(sregs->crs));
Christian Borntraeger59674c12012-01-11 11:20:33 +0100525 restore_access_regs(vcpu->run->s.regs.acrs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100526 return 0;
527}
528
529int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
530 struct kvm_sregs *sregs)
531{
Christian Borntraeger59674c12012-01-11 11:20:33 +0100532 memcpy(&sregs->acrs, &vcpu->run->s.regs.acrs, sizeof(sregs->acrs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100533 memcpy(&sregs->crs, &vcpu->arch.sie_block->gcr, sizeof(sregs->crs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100534 return 0;
535}
536
537int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
538{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100539 memcpy(&vcpu->arch.guest_fpregs.fprs, &fpu->fprs, sizeof(fpu->fprs));
Christian Borntraeger85175582012-02-06 10:59:02 +0100540 vcpu->arch.guest_fpregs.fpc = fpu->fpc & FPC_VALID_MASK;
Carsten Otte7eef87d2011-10-18 12:27:14 +0200541 restore_fp_regs(&vcpu->arch.guest_fpregs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100542 return 0;
543}
544
545int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
546{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100547 memcpy(&fpu->fprs, &vcpu->arch.guest_fpregs.fprs, sizeof(fpu->fprs));
548 fpu->fpc = vcpu->arch.guest_fpregs.fpc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100549 return 0;
550}
551
552static int kvm_arch_vcpu_ioctl_set_initial_psw(struct kvm_vcpu *vcpu, psw_t psw)
553{
554 int rc = 0;
555
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100556 if (!(atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_STOPPED))
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100557 rc = -EBUSY;
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100558 else {
559 vcpu->run->psw_mask = psw.mask;
560 vcpu->run->psw_addr = psw.addr;
561 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100562 return rc;
563}
564
565int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
566 struct kvm_translation *tr)
567{
568 return -EINVAL; /* not implemented yet */
569}
570
Jan Kiszkad0bfb942008-12-15 13:52:10 +0100571int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
572 struct kvm_guest_debug *dbg)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100573{
574 return -EINVAL; /* not implemented yet */
575}
576
Marcelo Tosatti62d9f0d2008-04-11 13:24:45 -0300577int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
578 struct kvm_mp_state *mp_state)
579{
580 return -EINVAL; /* not implemented yet */
581}
582
583int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
584 struct kvm_mp_state *mp_state)
585{
586 return -EINVAL; /* not implemented yet */
587}
588
Carsten Ottee168bf82012-01-04 10:25:22 +0100589static int __vcpu_run(struct kvm_vcpu *vcpu)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100590{
Carsten Ottee168bf82012-01-04 10:25:22 +0100591 int rc;
592
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100593 memcpy(&vcpu->arch.sie_block->gg14, &vcpu->run->s.regs.gprs[14], 16);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100594
595 if (need_resched())
596 schedule();
597
Christian Borntraeger71cde582008-05-21 13:37:34 +0200598 if (test_thread_flag(TIF_MCCK_PENDING))
599 s390_handle_mcck();
600
Carsten Otted6b6d162012-01-04 10:25:25 +0100601 if (!kvm_is_ucontrol(vcpu->kvm))
602 kvm_s390_deliver_pending_interrupts(vcpu);
Carsten Otte0ff31862008-05-21 13:37:37 +0200603
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100604 vcpu->arch.sie_block->icptcode = 0;
605 local_irq_disable();
606 kvm_guest_enter();
607 local_irq_enable();
608 VCPU_EVENT(vcpu, 6, "entering sie flags %x",
609 atomic_read(&vcpu->arch.sie_block->cpuflags));
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100610 rc = sie64a(vcpu->arch.sie_block, vcpu->run->s.regs.gprs);
Carsten Ottee168bf82012-01-04 10:25:22 +0100611 if (rc) {
612 if (kvm_is_ucontrol(vcpu->kvm)) {
613 rc = SIE_INTERCEPT_UCONTROL;
614 } else {
615 VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction");
616 kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
617 rc = 0;
618 }
Carsten Otte1f0d0f02008-05-21 13:37:40 +0200619 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100620 VCPU_EVENT(vcpu, 6, "exit sie icptcode %d",
621 vcpu->arch.sie_block->icptcode);
622 local_irq_disable();
623 kvm_guest_exit();
624 local_irq_enable();
625
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100626 memcpy(&vcpu->run->s.regs.gprs[14], &vcpu->arch.sie_block->gg14, 16);
Carsten Ottee168bf82012-01-04 10:25:22 +0100627 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100628}
629
630int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
631{
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100632 int rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100633 sigset_t sigsaved;
634
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200635rerun_vcpu:
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100636 if (vcpu->sigset_active)
637 sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
638
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100639 atomic_clear_mask(CPUSTAT_STOPPED, &vcpu->arch.sie_block->cpuflags);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100640
Carsten Otteba5c1e92008-03-25 18:47:26 +0100641 BUG_ON(vcpu->kvm->arch.float_int.local_int[vcpu->vcpu_id] == NULL);
642
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100643 switch (kvm_run->exit_reason) {
644 case KVM_EXIT_S390_SIEIC:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100645 case KVM_EXIT_UNKNOWN:
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200646 case KVM_EXIT_INTR:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100647 case KVM_EXIT_S390_RESET:
Carsten Ottee168bf82012-01-04 10:25:22 +0100648 case KVM_EXIT_S390_UCONTROL:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100649 break;
650 default:
651 BUG();
652 }
653
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100654 vcpu->arch.sie_block->gpsw.mask = kvm_run->psw_mask;
655 vcpu->arch.sie_block->gpsw.addr = kvm_run->psw_addr;
Christian Borntraeger60b413c2012-01-11 11:20:31 +0100656 if (kvm_run->kvm_dirty_regs & KVM_SYNC_PREFIX) {
657 kvm_run->kvm_dirty_regs &= ~KVM_SYNC_PREFIX;
658 kvm_s390_set_prefix(vcpu, kvm_run->s.regs.prefix);
659 }
Christian Borntraeger9eed07352012-02-06 10:59:07 +0100660 if (kvm_run->kvm_dirty_regs & KVM_SYNC_CRS) {
661 kvm_run->kvm_dirty_regs &= ~KVM_SYNC_CRS;
662 memcpy(&vcpu->arch.sie_block->gcr, &kvm_run->s.regs.crs, 128);
663 kvm_s390_set_prefix(vcpu, kvm_run->s.regs.prefix);
664 }
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100665
Heiko Carstensdab4079d2009-06-12 10:26:32 +0200666 might_fault();
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100667
668 do {
Carsten Ottee168bf82012-01-04 10:25:22 +0100669 rc = __vcpu_run(vcpu);
670 if (rc)
671 break;
Carsten Ottec0d744a2012-01-04 10:25:24 +0100672 if (kvm_is_ucontrol(vcpu->kvm))
673 rc = -EOPNOTSUPP;
674 else
675 rc = kvm_handle_sie_intercept(vcpu);
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100676 } while (!signal_pending(current) && !rc);
677
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200678 if (rc == SIE_INTERCEPT_RERUNVCPU)
679 goto rerun_vcpu;
680
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200681 if (signal_pending(current) && !rc) {
682 kvm_run->exit_reason = KVM_EXIT_INTR;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100683 rc = -EINTR;
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200684 }
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100685
Carsten Ottee168bf82012-01-04 10:25:22 +0100686#ifdef CONFIG_KVM_S390_UCONTROL
687 if (rc == SIE_INTERCEPT_UCONTROL) {
688 kvm_run->exit_reason = KVM_EXIT_S390_UCONTROL;
689 kvm_run->s390_ucontrol.trans_exc_code =
690 current->thread.gmap_addr;
691 kvm_run->s390_ucontrol.pgm_code = 0x10;
692 rc = 0;
693 }
694#endif
695
Heiko Carstensb8e660b2010-02-26 22:37:41 +0100696 if (rc == -EOPNOTSUPP) {
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100697 /* intercept cannot be handled in-kernel, prepare kvm-run */
698 kvm_run->exit_reason = KVM_EXIT_S390_SIEIC;
699 kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100700 kvm_run->s390_sieic.ipa = vcpu->arch.sie_block->ipa;
701 kvm_run->s390_sieic.ipb = vcpu->arch.sie_block->ipb;
702 rc = 0;
703 }
704
705 if (rc == -EREMOTE) {
706 /* intercept was handled, but userspace support is needed
707 * kvm_run has been prepared by the handler */
708 rc = 0;
709 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100710
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100711 kvm_run->psw_mask = vcpu->arch.sie_block->gpsw.mask;
712 kvm_run->psw_addr = vcpu->arch.sie_block->gpsw.addr;
Christian Borntraeger60b413c2012-01-11 11:20:31 +0100713 kvm_run->s.regs.prefix = vcpu->arch.sie_block->prefix;
Christian Borntraeger9eed07352012-02-06 10:59:07 +0100714 memcpy(&kvm_run->s.regs.crs, &vcpu->arch.sie_block->gcr, 128);
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100715
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100716 if (vcpu->sigset_active)
717 sigprocmask(SIG_SETMASK, &sigsaved, NULL);
718
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100719 vcpu->stat.exit_userspace++;
Heiko Carstens7e8e6ab2008-04-04 15:12:35 +0200720 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100721}
722
Carsten Otte092670c2011-07-24 10:48:22 +0200723static int __guestcopy(struct kvm_vcpu *vcpu, u64 guestdest, void *from,
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100724 unsigned long n, int prefix)
725{
726 if (prefix)
727 return copy_to_guest(vcpu, guestdest, from, n);
728 else
729 return copy_to_guest_absolute(vcpu, guestdest, from, n);
730}
731
732/*
733 * store status at address
734 * we use have two special cases:
735 * KVM_S390_STORE_STATUS_NOADDR: -> 0x1200 on 64 bit
736 * KVM_S390_STORE_STATUS_PREFIXED: -> prefix
737 */
Christian Borntraeger971eb772010-06-12 08:54:13 +0200738int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100739{
Carsten Otte092670c2011-07-24 10:48:22 +0200740 unsigned char archmode = 1;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100741 int prefix;
742
743 if (addr == KVM_S390_STORE_STATUS_NOADDR) {
744 if (copy_to_guest_absolute(vcpu, 163ul, &archmode, 1))
745 return -EFAULT;
746 addr = SAVE_AREA_BASE;
747 prefix = 0;
748 } else if (addr == KVM_S390_STORE_STATUS_PREFIXED) {
749 if (copy_to_guest(vcpu, 163ul, &archmode, 1))
750 return -EFAULT;
751 addr = SAVE_AREA_BASE;
752 prefix = 1;
753 } else
754 prefix = 0;
755
Heiko Carstensf64ca212010-02-26 22:37:32 +0100756 if (__guestcopy(vcpu, addr + offsetof(struct save_area, fp_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100757 vcpu->arch.guest_fpregs.fprs, 128, prefix))
758 return -EFAULT;
759
Heiko Carstensf64ca212010-02-26 22:37:32 +0100760 if (__guestcopy(vcpu, addr + offsetof(struct save_area, gp_regs),
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100761 vcpu->run->s.regs.gprs, 128, prefix))
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100762 return -EFAULT;
763
Heiko Carstensf64ca212010-02-26 22:37:32 +0100764 if (__guestcopy(vcpu, addr + offsetof(struct save_area, psw),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100765 &vcpu->arch.sie_block->gpsw, 16, prefix))
766 return -EFAULT;
767
Heiko Carstensf64ca212010-02-26 22:37:32 +0100768 if (__guestcopy(vcpu, addr + offsetof(struct save_area, pref_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100769 &vcpu->arch.sie_block->prefix, 4, prefix))
770 return -EFAULT;
771
772 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100773 addr + offsetof(struct save_area, fp_ctrl_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100774 &vcpu->arch.guest_fpregs.fpc, 4, prefix))
775 return -EFAULT;
776
Heiko Carstensf64ca212010-02-26 22:37:32 +0100777 if (__guestcopy(vcpu, addr + offsetof(struct save_area, tod_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100778 &vcpu->arch.sie_block->todpr, 4, prefix))
779 return -EFAULT;
780
Heiko Carstensf64ca212010-02-26 22:37:32 +0100781 if (__guestcopy(vcpu, addr + offsetof(struct save_area, timer),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100782 &vcpu->arch.sie_block->cputm, 8, prefix))
783 return -EFAULT;
784
Heiko Carstensf64ca212010-02-26 22:37:32 +0100785 if (__guestcopy(vcpu, addr + offsetof(struct save_area, clk_cmp),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100786 &vcpu->arch.sie_block->ckc, 8, prefix))
787 return -EFAULT;
788
Heiko Carstensf64ca212010-02-26 22:37:32 +0100789 if (__guestcopy(vcpu, addr + offsetof(struct save_area, acc_regs),
Christian Borntraeger59674c12012-01-11 11:20:33 +0100790 &vcpu->run->s.regs.acrs, 64, prefix))
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100791 return -EFAULT;
792
793 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100794 addr + offsetof(struct save_area, ctrl_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100795 &vcpu->arch.sie_block->gcr, 128, prefix))
796 return -EFAULT;
797 return 0;
798}
799
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100800long kvm_arch_vcpu_ioctl(struct file *filp,
801 unsigned int ioctl, unsigned long arg)
802{
803 struct kvm_vcpu *vcpu = filp->private_data;
804 void __user *argp = (void __user *)arg;
Avi Kivitybc923cc2010-05-13 12:21:46 +0300805 long r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100806
Avi Kivity93736622010-05-13 12:35:17 +0300807 switch (ioctl) {
808 case KVM_S390_INTERRUPT: {
Carsten Otteba5c1e92008-03-25 18:47:26 +0100809 struct kvm_s390_interrupt s390int;
810
Avi Kivity93736622010-05-13 12:35:17 +0300811 r = -EFAULT;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100812 if (copy_from_user(&s390int, argp, sizeof(s390int)))
Avi Kivity93736622010-05-13 12:35:17 +0300813 break;
814 r = kvm_s390_inject_vcpu(vcpu, &s390int);
815 break;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100816 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100817 case KVM_S390_STORE_STATUS:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300818 r = kvm_s390_vcpu_store_status(vcpu, arg);
819 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100820 case KVM_S390_SET_INITIAL_PSW: {
821 psw_t psw;
822
Avi Kivitybc923cc2010-05-13 12:21:46 +0300823 r = -EFAULT;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100824 if (copy_from_user(&psw, argp, sizeof(psw)))
Avi Kivitybc923cc2010-05-13 12:21:46 +0300825 break;
826 r = kvm_arch_vcpu_ioctl_set_initial_psw(vcpu, psw);
827 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100828 }
829 case KVM_S390_INITIAL_RESET:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300830 r = kvm_arch_vcpu_ioctl_initial_reset(vcpu);
831 break;
Carsten Otte14eebd92012-05-15 14:15:26 +0200832 case KVM_SET_ONE_REG:
833 case KVM_GET_ONE_REG: {
834 struct kvm_one_reg reg;
835 r = -EFAULT;
836 if (copy_from_user(&reg, argp, sizeof(reg)))
837 break;
838 if (ioctl == KVM_SET_ONE_REG)
839 r = kvm_arch_vcpu_ioctl_set_one_reg(vcpu, &reg);
840 else
841 r = kvm_arch_vcpu_ioctl_get_one_reg(vcpu, &reg);
842 break;
843 }
Carsten Otte27e03932012-01-04 10:25:21 +0100844#ifdef CONFIG_KVM_S390_UCONTROL
845 case KVM_S390_UCAS_MAP: {
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_map_segment(vcpu->arch.gmap, ucasmap.user_addr,
859 ucasmap.vcpu_addr, ucasmap.length);
860 break;
861 }
862 case KVM_S390_UCAS_UNMAP: {
863 struct kvm_s390_ucas_mapping ucasmap;
864
865 if (copy_from_user(&ucasmap, argp, sizeof(ucasmap))) {
866 r = -EFAULT;
867 break;
868 }
869
870 if (!kvm_is_ucontrol(vcpu->kvm)) {
871 r = -EINVAL;
872 break;
873 }
874
875 r = gmap_unmap_segment(vcpu->arch.gmap, ucasmap.vcpu_addr,
876 ucasmap.length);
877 break;
878 }
879#endif
Carsten Otteccc79102012-01-04 10:25:26 +0100880 case KVM_S390_VCPU_FAULT: {
881 r = gmap_fault(arg, vcpu->arch.gmap);
882 if (!IS_ERR_VALUE(r))
883 r = 0;
884 break;
885 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100886 default:
Carsten Otte3e6afcf2012-01-04 10:25:30 +0100887 r = -ENOTTY;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100888 }
Avi Kivitybc923cc2010-05-13 12:21:46 +0300889 return r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100890}
891
Carsten Otte5b1c1492012-01-04 10:25:23 +0100892int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
893{
894#ifdef CONFIG_KVM_S390_UCONTROL
895 if ((vmf->pgoff == KVM_S390_SIE_PAGE_OFFSET)
896 && (kvm_is_ucontrol(vcpu->kvm))) {
897 vmf->page = virt_to_page(vcpu->arch.sie_block);
898 get_page(vmf->page);
899 return 0;
900 }
901#endif
902 return VM_FAULT_SIGBUS;
903}
904
Takuya Yoshikawadb3fe4e2012-02-08 13:02:18 +0900905void kvm_arch_free_memslot(struct kvm_memory_slot *free,
906 struct kvm_memory_slot *dont)
907{
908}
909
910int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages)
911{
912 return 0;
913}
914
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100915/* Section: memory related */
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200916int kvm_arch_prepare_memory_region(struct kvm *kvm,
917 struct kvm_memory_slot *memslot,
918 struct kvm_memory_slot old,
919 struct kvm_userspace_memory_region *mem,
920 int user_alloc)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100921{
922 /* A few sanity checks. We can have exactly one memory slot which has
923 to start at guest virtual zero and which has to be located at a
924 page boundary in userland and which has to end at a page boundary.
925 The memory in userland is ok to be fragmented into various different
926 vmas. It is okay to mmap() and munmap() stuff in this slot after
927 doing this call at any time */
928
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200929 if (mem->slot)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100930 return -EINVAL;
931
932 if (mem->guest_phys_addr)
933 return -EINVAL;
934
Carsten Otte598841c2011-07-24 10:48:21 +0200935 if (mem->userspace_addr & 0xffffful)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100936 return -EINVAL;
937
Carsten Otte598841c2011-07-24 10:48:21 +0200938 if (mem->memory_size & 0xffffful)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100939 return -EINVAL;
940
Carsten Otte2668dab2009-05-12 17:21:48 +0200941 if (!user_alloc)
942 return -EINVAL;
943
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200944 return 0;
945}
946
947void kvm_arch_commit_memory_region(struct kvm *kvm,
948 struct kvm_userspace_memory_region *mem,
949 struct kvm_memory_slot old,
950 int user_alloc)
951{
Carsten Ottef7850c92011-07-24 10:48:23 +0200952 int rc;
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200953
Carsten Otte598841c2011-07-24 10:48:21 +0200954
955 rc = gmap_map_segment(kvm->arch.gmap, mem->userspace_addr,
956 mem->guest_phys_addr, mem->memory_size);
957 if (rc)
Carsten Ottef7850c92011-07-24 10:48:23 +0200958 printk(KERN_WARNING "kvm-s390: failed to commit memory region\n");
Carsten Otte598841c2011-07-24 10:48:21 +0200959 return;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100960}
961
Marcelo Tosatti34d4cb82008-07-10 20:49:31 -0300962void kvm_arch_flush_shadow(struct kvm *kvm)
963{
964}
965
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100966static int __init kvm_s390_init(void)
967{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200968 int ret;
Avi Kivity0ee75be2010-04-28 15:39:01 +0300969 ret = kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE);
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200970 if (ret)
971 return ret;
972
973 /*
974 * guests can ask for up to 255+1 double words, we need a full page
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300975 * to hold the maximum amount of facilities. On the other hand, we
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200976 * only set facilities that are known to work in KVM.
977 */
Heiko Carstensc2f0e8c2010-06-08 18:58:09 +0200978 facilities = (unsigned long long *) get_zeroed_page(GFP_KERNEL|GFP_DMA);
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200979 if (!facilities) {
980 kvm_exit();
981 return -ENOMEM;
982 }
Martin Schwidefsky14375bc2010-10-25 16:10:51 +0200983 memcpy(facilities, S390_lowcore.stfle_fac_list, 16);
Christian Borntraeger6d00d002010-10-25 16:10:48 +0200984 facilities[0] &= 0xff00fff3f47c0000ULL;
Christian Borntraeger9950f8b2011-06-06 14:14:39 +0200985 facilities[1] &= 0x201c000000000000ULL;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200986 return 0;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100987}
988
989static void __exit kvm_s390_exit(void)
990{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200991 free_page((unsigned long) facilities);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100992 kvm_exit();
993}
994
995module_init(kvm_s390_init);
996module_exit(kvm_s390_exit);