blob: 4613602e123ebd60e8ab20460ab42554985394a9 [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
Cornelia Huck5786fff2012-07-23 17:20:29 +020035#define CREATE_TRACE_POINTS
36#include "trace.h"
37
Heiko Carstensb0c632d2008-03-25 18:47:20 +010038#define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU
39
40struct kvm_stats_debugfs_item debugfs_entries[] = {
41 { "userspace_handled", VCPU_STAT(exit_userspace) },
Christian Borntraeger0eaeafa2008-05-07 09:22:53 +020042 { "exit_null", VCPU_STAT(exit_null) },
Christian Borntraeger8f2abe62008-03-25 18:47:23 +010043 { "exit_validity", VCPU_STAT(exit_validity) },
44 { "exit_stop_request", VCPU_STAT(exit_stop_request) },
45 { "exit_external_request", VCPU_STAT(exit_external_request) },
46 { "exit_external_interrupt", VCPU_STAT(exit_external_interrupt) },
Carsten Otteba5c1e92008-03-25 18:47:26 +010047 { "exit_instruction", VCPU_STAT(exit_instruction) },
48 { "exit_program_interruption", VCPU_STAT(exit_program_interruption) },
49 { "exit_instr_and_program_int", VCPU_STAT(exit_instr_and_program) },
Christian Borntraegerf5e10b02008-07-25 15:52:44 +020050 { "instruction_lctlg", VCPU_STAT(instruction_lctlg) },
Carsten Otteba5c1e92008-03-25 18:47:26 +010051 { "instruction_lctl", VCPU_STAT(instruction_lctl) },
52 { "deliver_emergency_signal", VCPU_STAT(deliver_emergency_signal) },
Christian Ehrhardt7697e71f2011-10-18 12:27:15 +020053 { "deliver_external_call", VCPU_STAT(deliver_external_call) },
Carsten Otteba5c1e92008-03-25 18:47:26 +010054 { "deliver_service_signal", VCPU_STAT(deliver_service_signal) },
55 { "deliver_virtio_interrupt", VCPU_STAT(deliver_virtio_interrupt) },
56 { "deliver_stop_signal", VCPU_STAT(deliver_stop_signal) },
57 { "deliver_prefix_signal", VCPU_STAT(deliver_prefix_signal) },
58 { "deliver_restart_signal", VCPU_STAT(deliver_restart_signal) },
59 { "deliver_program_interruption", VCPU_STAT(deliver_program_int) },
60 { "exit_wait_state", VCPU_STAT(exit_wait_state) },
Christian Borntraeger453423d2008-03-25 18:47:29 +010061 { "instruction_stidp", VCPU_STAT(instruction_stidp) },
62 { "instruction_spx", VCPU_STAT(instruction_spx) },
63 { "instruction_stpx", VCPU_STAT(instruction_stpx) },
64 { "instruction_stap", VCPU_STAT(instruction_stap) },
65 { "instruction_storage_key", VCPU_STAT(instruction_storage_key) },
66 { "instruction_stsch", VCPU_STAT(instruction_stsch) },
67 { "instruction_chsc", VCPU_STAT(instruction_chsc) },
68 { "instruction_stsi", VCPU_STAT(instruction_stsi) },
69 { "instruction_stfl", VCPU_STAT(instruction_stfl) },
Christian Borntraegerbb25b9b2011-07-24 10:48:17 +020070 { "instruction_tprot", VCPU_STAT(instruction_tprot) },
Christian Borntraeger5288fbf2008-03-25 18:47:31 +010071 { "instruction_sigp_sense", VCPU_STAT(instruction_sigp_sense) },
Cornelia Huckbd59d3a2011-11-17 11:00:42 +010072 { "instruction_sigp_sense_running", VCPU_STAT(instruction_sigp_sense_running) },
Christian Ehrhardt7697e71f2011-10-18 12:27:15 +020073 { "instruction_sigp_external_call", VCPU_STAT(instruction_sigp_external_call) },
Christian Borntraeger5288fbf2008-03-25 18:47:31 +010074 { "instruction_sigp_emergency", VCPU_STAT(instruction_sigp_emergency) },
75 { "instruction_sigp_stop", VCPU_STAT(instruction_sigp_stop) },
76 { "instruction_sigp_set_arch", VCPU_STAT(instruction_sigp_arch) },
77 { "instruction_sigp_set_prefix", VCPU_STAT(instruction_sigp_prefix) },
78 { "instruction_sigp_restart", VCPU_STAT(instruction_sigp_restart) },
Christian Borntraeger388186b2011-10-30 15:17:03 +010079 { "diagnose_10", VCPU_STAT(diagnose_10) },
Christian Borntraegere28acfe2008-03-25 18:47:34 +010080 { "diagnose_44", VCPU_STAT(diagnose_44) },
Konstantin Weitz41628d32012-04-25 15:30:38 +020081 { "diagnose_9c", VCPU_STAT(diagnose_9c) },
Heiko Carstensb0c632d2008-03-25 18:47:20 +010082 { NULL }
83};
84
Christian Borntraegeref50f7a2009-06-23 17:24:07 +020085static unsigned long long *facilities;
Heiko Carstensb0c632d2008-03-25 18:47:20 +010086
87/* Section: not file related */
Alexander Graf10474ae2009-09-15 11:37:46 +020088int kvm_arch_hardware_enable(void *garbage)
Heiko Carstensb0c632d2008-03-25 18:47:20 +010089{
90 /* every s390 is virtualization enabled ;-) */
Alexander Graf10474ae2009-09-15 11:37:46 +020091 return 0;
Heiko Carstensb0c632d2008-03-25 18:47:20 +010092}
93
94void kvm_arch_hardware_disable(void *garbage)
95{
96}
97
Heiko Carstensb0c632d2008-03-25 18:47:20 +010098int kvm_arch_hardware_setup(void)
99{
100 return 0;
101}
102
103void kvm_arch_hardware_unsetup(void)
104{
105}
106
107void kvm_arch_check_processor_compat(void *rtn)
108{
109}
110
111int kvm_arch_init(void *opaque)
112{
113 return 0;
114}
115
116void kvm_arch_exit(void)
117{
118}
119
120/* Section: device related */
121long kvm_arch_dev_ioctl(struct file *filp,
122 unsigned int ioctl, unsigned long arg)
123{
124 if (ioctl == KVM_S390_ENABLE_SIE)
125 return s390_enable_sie();
126 return -EINVAL;
127}
128
129int kvm_dev_ioctl_check_extension(long ext)
130{
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100131 int r;
132
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200133 switch (ext) {
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100134 case KVM_CAP_S390_PSW:
Christian Borntraegerb6cf8782011-09-20 17:07:29 +0200135 case KVM_CAP_S390_GMAP:
Christian Borntraeger52e16b12011-11-17 11:00:44 +0100136 case KVM_CAP_SYNC_MMU:
Carsten Otte1efd0f52012-01-04 10:25:29 +0100137#ifdef CONFIG_KVM_S390_UCONTROL
138 case KVM_CAP_S390_UCONTROL:
139#endif
Christian Borntraeger60b413c2012-01-11 11:20:31 +0100140 case KVM_CAP_SYNC_REGS:
Carsten Otte14eebd92012-05-15 14:15:26 +0200141 case KVM_CAP_ONE_REG:
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100142 r = 1;
143 break;
Christian Borntraegere726b1b2012-05-02 10:50:38 +0200144 case KVM_CAP_NR_VCPUS:
145 case KVM_CAP_MAX_VCPUS:
146 r = KVM_MAX_VCPUS;
147 break;
Christian Borntraeger1526bf92012-05-15 14:15:25 +0200148 case KVM_CAP_S390_COW:
149 r = sclp_get_fac85() & 0x2;
150 break;
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200151 default:
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100152 r = 0;
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200153 }
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100154 return r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100155}
156
157/* Section: vm related */
158/*
159 * Get (and clear) the dirty memory log for a memory slot.
160 */
161int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
162 struct kvm_dirty_log *log)
163{
164 return 0;
165}
166
167long kvm_arch_vm_ioctl(struct file *filp,
168 unsigned int ioctl, unsigned long arg)
169{
170 struct kvm *kvm = filp->private_data;
171 void __user *argp = (void __user *)arg;
172 int r;
173
174 switch (ioctl) {
Carsten Otteba5c1e92008-03-25 18:47:26 +0100175 case KVM_S390_INTERRUPT: {
176 struct kvm_s390_interrupt s390int;
177
178 r = -EFAULT;
179 if (copy_from_user(&s390int, argp, sizeof(s390int)))
180 break;
181 r = kvm_s390_inject_vm(kvm, &s390int);
182 break;
183 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100184 default:
Avi Kivity367e1312009-08-26 14:57:07 +0300185 r = -ENOTTY;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100186 }
187
188 return r;
189}
190
Carsten Ottee08b9632012-01-04 10:25:20 +0100191int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100192{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100193 int rc;
194 char debug_name[16];
195
Carsten Ottee08b9632012-01-04 10:25:20 +0100196 rc = -EINVAL;
197#ifdef CONFIG_KVM_S390_UCONTROL
198 if (type & ~KVM_VM_S390_UCONTROL)
199 goto out_err;
200 if ((type & KVM_VM_S390_UCONTROL) && (!capable(CAP_SYS_ADMIN)))
201 goto out_err;
202#else
203 if (type)
204 goto out_err;
205#endif
206
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100207 rc = s390_enable_sie();
208 if (rc)
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100209 goto out_err;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100210
Carsten Otteb2904112011-10-18 12:27:13 +0200211 rc = -ENOMEM;
212
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100213 kvm->arch.sca = (struct sca_block *) get_zeroed_page(GFP_KERNEL);
214 if (!kvm->arch.sca)
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100215 goto out_err;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100216
217 sprintf(debug_name, "kvm-%u", current->pid);
218
219 kvm->arch.dbf = debug_register(debug_name, 8, 2, 8 * sizeof(long));
220 if (!kvm->arch.dbf)
221 goto out_nodbf;
222
Carsten Otteba5c1e92008-03-25 18:47:26 +0100223 spin_lock_init(&kvm->arch.float_int.lock);
224 INIT_LIST_HEAD(&kvm->arch.float_int.list);
225
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100226 debug_register_view(kvm->arch.dbf, &debug_sprintf_view);
227 VM_EVENT(kvm, 3, "%s", "vm created");
228
Carsten Ottee08b9632012-01-04 10:25:20 +0100229 if (type & KVM_VM_S390_UCONTROL) {
230 kvm->arch.gmap = NULL;
231 } else {
232 kvm->arch.gmap = gmap_alloc(current->mm);
233 if (!kvm->arch.gmap)
234 goto out_nogmap;
235 }
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100236 return 0;
Carsten Otte598841c2011-07-24 10:48:21 +0200237out_nogmap:
238 debug_unregister(kvm->arch.dbf);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100239out_nodbf:
240 free_page((unsigned long)(kvm->arch.sca));
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100241out_err:
242 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100243}
244
Christian Borntraegerd329c032008-11-26 14:50:27 +0100245void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
246{
247 VCPU_EVENT(vcpu, 3, "%s", "free cpu");
Carsten Otte58f94602012-01-04 10:25:27 +0100248 if (!kvm_is_ucontrol(vcpu->kvm)) {
249 clear_bit(63 - vcpu->vcpu_id,
250 (unsigned long *) &vcpu->kvm->arch.sca->mcn);
251 if (vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda ==
252 (__u64) vcpu->arch.sie_block)
253 vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda = 0;
254 }
Carsten Otteabf4a712009-05-12 17:21:51 +0200255 smp_mb();
Carsten Otte27e03932012-01-04 10:25:21 +0100256
257 if (kvm_is_ucontrol(vcpu->kvm))
258 gmap_free(vcpu->arch.gmap);
259
Christian Borntraegerd329c032008-11-26 14:50:27 +0100260 free_page((unsigned long)(vcpu->arch.sie_block));
Christian Borntraeger6692cef2008-11-26 14:51:08 +0100261 kvm_vcpu_uninit(vcpu);
Christian Borntraegerd329c032008-11-26 14:50:27 +0100262 kfree(vcpu);
263}
264
265static void kvm_free_vcpus(struct kvm *kvm)
266{
267 unsigned int i;
Gleb Natapov988a2ca2009-06-09 15:56:29 +0300268 struct kvm_vcpu *vcpu;
Christian Borntraegerd329c032008-11-26 14:50:27 +0100269
Gleb Natapov988a2ca2009-06-09 15:56:29 +0300270 kvm_for_each_vcpu(i, vcpu, kvm)
271 kvm_arch_vcpu_destroy(vcpu);
272
273 mutex_lock(&kvm->lock);
274 for (i = 0; i < atomic_read(&kvm->online_vcpus); i++)
275 kvm->vcpus[i] = NULL;
276
277 atomic_set(&kvm->online_vcpus, 0);
278 mutex_unlock(&kvm->lock);
Christian Borntraegerd329c032008-11-26 14:50:27 +0100279}
280
Sheng Yangad8ba2c2009-01-06 10:03:02 +0800281void kvm_arch_sync_events(struct kvm *kvm)
282{
283}
284
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100285void kvm_arch_destroy_vm(struct kvm *kvm)
286{
Christian Borntraegerd329c032008-11-26 14:50:27 +0100287 kvm_free_vcpus(kvm);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100288 free_page((unsigned long)(kvm->arch.sca));
Christian Borntraegerd329c032008-11-26 14:50:27 +0100289 debug_unregister(kvm->arch.dbf);
Carsten Otte27e03932012-01-04 10:25:21 +0100290 if (!kvm_is_ucontrol(kvm))
291 gmap_free(kvm->arch.gmap);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100292}
293
294/* Section: vcpu related */
295int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
296{
Carsten Otte27e03932012-01-04 10:25:21 +0100297 if (kvm_is_ucontrol(vcpu->kvm)) {
298 vcpu->arch.gmap = gmap_alloc(current->mm);
299 if (!vcpu->arch.gmap)
300 return -ENOMEM;
301 return 0;
302 }
303
Carsten Otte598841c2011-07-24 10:48:21 +0200304 vcpu->arch.gmap = vcpu->kvm->arch.gmap;
Christian Borntraeger59674c12012-01-11 11:20:33 +0100305 vcpu->run->kvm_valid_regs = KVM_SYNC_PREFIX |
306 KVM_SYNC_GPRS |
Christian Borntraeger9eed07352012-02-06 10:59:07 +0100307 KVM_SYNC_ACRS |
308 KVM_SYNC_CRS;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100309 return 0;
310}
311
312void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
313{
Christian Borntraeger6692cef2008-11-26 14:51:08 +0100314 /* Nothing todo */
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100315}
316
317void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
318{
319 save_fp_regs(&vcpu->arch.host_fpregs);
320 save_access_regs(vcpu->arch.host_acrs);
321 vcpu->arch.guest_fpregs.fpc &= FPC_VALID_MASK;
322 restore_fp_regs(&vcpu->arch.guest_fpregs);
Christian Borntraeger59674c12012-01-11 11:20:33 +0100323 restore_access_regs(vcpu->run->s.regs.acrs);
Christian Borntraeger480e5922011-09-20 17:07:28 +0200324 gmap_enable(vcpu->arch.gmap);
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100325 atomic_set_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100326}
327
328void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
329{
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100330 atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
Christian Borntraeger480e5922011-09-20 17:07:28 +0200331 gmap_disable(vcpu->arch.gmap);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100332 save_fp_regs(&vcpu->arch.guest_fpregs);
Christian Borntraeger59674c12012-01-11 11:20:33 +0100333 save_access_regs(vcpu->run->s.regs.acrs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100334 restore_fp_regs(&vcpu->arch.host_fpregs);
335 restore_access_regs(vcpu->arch.host_acrs);
336}
337
338static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu)
339{
340 /* this equals initial cpu reset in pop, but we don't switch to ESA */
341 vcpu->arch.sie_block->gpsw.mask = 0UL;
342 vcpu->arch.sie_block->gpsw.addr = 0UL;
Christian Borntraeger8d26cf72012-01-11 11:19:32 +0100343 kvm_s390_set_prefix(vcpu, 0);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100344 vcpu->arch.sie_block->cputm = 0UL;
345 vcpu->arch.sie_block->ckc = 0UL;
346 vcpu->arch.sie_block->todpr = 0;
347 memset(vcpu->arch.sie_block->gcr, 0, 16 * sizeof(__u64));
348 vcpu->arch.sie_block->gcr[0] = 0xE0UL;
349 vcpu->arch.sie_block->gcr[14] = 0xC2000000UL;
350 vcpu->arch.guest_fpregs.fpc = 0;
351 asm volatile("lfpc %0" : : "Q" (vcpu->arch.guest_fpregs.fpc));
352 vcpu->arch.sie_block->gbea = 1;
Christian Borntraeger61bde822012-06-11 16:06:57 +0200353 atomic_set_mask(CPUSTAT_STOPPED, &vcpu->arch.sie_block->cpuflags);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100354}
355
356int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
357{
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100358 atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH |
359 CPUSTAT_SM |
360 CPUSTAT_STOPPED);
Christian Borntraegerfc345312010-06-17 23:16:20 +0200361 vcpu->arch.sie_block->ecb = 6;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100362 vcpu->arch.sie_block->eca = 0xC1002001U;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200363 vcpu->arch.sie_block->fac = (int) (long) facilities;
Christian Borntraegerca872302009-05-12 17:21:49 +0200364 hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
365 tasklet_init(&vcpu->arch.tasklet, kvm_s390_tasklet,
366 (unsigned long) vcpu);
367 vcpu->arch.ckc_timer.function = kvm_s390_idle_wakeup;
Christian Borntraeger453423d2008-03-25 18:47:29 +0100368 get_cpu_id(&vcpu->arch.cpu_id);
Christian Borntraeger92e6ecf2009-03-26 15:23:58 +0100369 vcpu->arch.cpu_id.version = 0xff;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100370 return 0;
371}
372
373struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
374 unsigned int id)
375{
Carsten Otte4d475552011-10-18 12:27:12 +0200376 struct kvm_vcpu *vcpu;
377 int rc = -EINVAL;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100378
Carsten Otte4d475552011-10-18 12:27:12 +0200379 if (id >= KVM_MAX_VCPUS)
380 goto out;
381
382 rc = -ENOMEM;
383
384 vcpu = kzalloc(sizeof(struct kvm_vcpu), GFP_KERNEL);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100385 if (!vcpu)
Carsten Otte4d475552011-10-18 12:27:12 +0200386 goto out;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100387
Christian Borntraeger180c12f2008-06-27 15:05:40 +0200388 vcpu->arch.sie_block = (struct kvm_s390_sie_block *)
389 get_zeroed_page(GFP_KERNEL);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100390
391 if (!vcpu->arch.sie_block)
392 goto out_free_cpu;
393
394 vcpu->arch.sie_block->icpua = id;
Carsten Otte58f94602012-01-04 10:25:27 +0100395 if (!kvm_is_ucontrol(kvm)) {
396 if (!kvm->arch.sca) {
397 WARN_ON_ONCE(1);
398 goto out_free_cpu;
399 }
400 if (!kvm->arch.sca->cpu[id].sda)
401 kvm->arch.sca->cpu[id].sda =
402 (__u64) vcpu->arch.sie_block;
403 vcpu->arch.sie_block->scaoh =
404 (__u32)(((__u64)kvm->arch.sca) >> 32);
405 vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca;
406 set_bit(63 - id, (unsigned long *) &kvm->arch.sca->mcn);
407 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100408
Carsten Otteba5c1e92008-03-25 18:47:26 +0100409 spin_lock_init(&vcpu->arch.local_int.lock);
410 INIT_LIST_HEAD(&vcpu->arch.local_int.list);
411 vcpu->arch.local_int.float_int = &kvm->arch.float_int;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200412 spin_lock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100413 kvm->arch.float_int.local_int[id] = &vcpu->arch.local_int;
414 init_waitqueue_head(&vcpu->arch.local_int.wq);
Christian Borntraeger5288fbf2008-03-25 18:47:31 +0100415 vcpu->arch.local_int.cpuflags = &vcpu->arch.sie_block->cpuflags;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200416 spin_unlock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100417
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100418 rc = kvm_vcpu_init(vcpu, kvm, id);
419 if (rc)
Wei Yongjun7b06bf22010-03-09 14:37:53 +0800420 goto out_free_sie_block;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100421 VM_EVENT(kvm, 3, "create cpu %d at %p, sie block at %p", id, vcpu,
422 vcpu->arch.sie_block);
423
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100424 return vcpu;
Wei Yongjun7b06bf22010-03-09 14:37:53 +0800425out_free_sie_block:
426 free_page((unsigned long)(vcpu->arch.sie_block));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100427out_free_cpu:
428 kfree(vcpu);
Carsten Otte4d475552011-10-18 12:27:12 +0200429out:
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100430 return ERR_PTR(rc);
431}
432
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100433int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
434{
435 /* kvm common code refers to this, but never calls it */
436 BUG();
437 return 0;
438}
439
Christoffer Dallb6d33832012-03-08 16:44:24 -0500440int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
441{
442 /* kvm common code refers to this, but never calls it */
443 BUG();
444 return 0;
445}
446
Carsten Otte14eebd92012-05-15 14:15:26 +0200447static int kvm_arch_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu,
448 struct kvm_one_reg *reg)
449{
450 int r = -EINVAL;
451
452 switch (reg->id) {
Carsten Otte29b7c712012-05-15 14:15:27 +0200453 case KVM_REG_S390_TODPR:
454 r = put_user(vcpu->arch.sie_block->todpr,
455 (u32 __user *)reg->addr);
456 break;
457 case KVM_REG_S390_EPOCHDIFF:
458 r = put_user(vcpu->arch.sie_block->epoch,
459 (u64 __user *)reg->addr);
460 break;
Jason J. herne46a6dd12012-05-15 14:15:28 +0200461 case KVM_REG_S390_CPU_TIMER:
462 r = put_user(vcpu->arch.sie_block->cputm,
463 (u64 __user *)reg->addr);
464 break;
465 case KVM_REG_S390_CLOCK_COMP:
466 r = put_user(vcpu->arch.sie_block->ckc,
467 (u64 __user *)reg->addr);
468 break;
Carsten Otte14eebd92012-05-15 14:15:26 +0200469 default:
470 break;
471 }
472
473 return r;
474}
475
476static int kvm_arch_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu,
477 struct kvm_one_reg *reg)
478{
479 int r = -EINVAL;
480
481 switch (reg->id) {
Carsten Otte29b7c712012-05-15 14:15:27 +0200482 case KVM_REG_S390_TODPR:
483 r = get_user(vcpu->arch.sie_block->todpr,
484 (u32 __user *)reg->addr);
485 break;
486 case KVM_REG_S390_EPOCHDIFF:
487 r = get_user(vcpu->arch.sie_block->epoch,
488 (u64 __user *)reg->addr);
489 break;
Jason J. herne46a6dd12012-05-15 14:15:28 +0200490 case KVM_REG_S390_CPU_TIMER:
491 r = get_user(vcpu->arch.sie_block->cputm,
492 (u64 __user *)reg->addr);
493 break;
494 case KVM_REG_S390_CLOCK_COMP:
495 r = get_user(vcpu->arch.sie_block->ckc,
496 (u64 __user *)reg->addr);
497 break;
Carsten Otte14eebd92012-05-15 14:15:26 +0200498 default:
499 break;
500 }
501
502 return r;
503}
Christoffer Dallb6d33832012-03-08 16:44:24 -0500504
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100505static int kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu)
506{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100507 kvm_s390_vcpu_initial_reset(vcpu);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100508 return 0;
509}
510
511int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
512{
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100513 memcpy(&vcpu->run->s.regs.gprs, &regs->gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100514 return 0;
515}
516
517int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
518{
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100519 memcpy(&regs->gprs, &vcpu->run->s.regs.gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100520 return 0;
521}
522
523int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
524 struct kvm_sregs *sregs)
525{
Christian Borntraeger59674c12012-01-11 11:20:33 +0100526 memcpy(&vcpu->run->s.regs.acrs, &sregs->acrs, sizeof(sregs->acrs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100527 memcpy(&vcpu->arch.sie_block->gcr, &sregs->crs, sizeof(sregs->crs));
Christian Borntraeger59674c12012-01-11 11:20:33 +0100528 restore_access_regs(vcpu->run->s.regs.acrs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100529 return 0;
530}
531
532int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
533 struct kvm_sregs *sregs)
534{
Christian Borntraeger59674c12012-01-11 11:20:33 +0100535 memcpy(&sregs->acrs, &vcpu->run->s.regs.acrs, sizeof(sregs->acrs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100536 memcpy(&sregs->crs, &vcpu->arch.sie_block->gcr, sizeof(sregs->crs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100537 return 0;
538}
539
540int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
541{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100542 memcpy(&vcpu->arch.guest_fpregs.fprs, &fpu->fprs, sizeof(fpu->fprs));
Christian Borntraeger85175582012-02-06 10:59:02 +0100543 vcpu->arch.guest_fpregs.fpc = fpu->fpc & FPC_VALID_MASK;
Carsten Otte7eef87d2011-10-18 12:27:14 +0200544 restore_fp_regs(&vcpu->arch.guest_fpregs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100545 return 0;
546}
547
548int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
549{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100550 memcpy(&fpu->fprs, &vcpu->arch.guest_fpregs.fprs, sizeof(fpu->fprs));
551 fpu->fpc = vcpu->arch.guest_fpregs.fpc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100552 return 0;
553}
554
555static int kvm_arch_vcpu_ioctl_set_initial_psw(struct kvm_vcpu *vcpu, psw_t psw)
556{
557 int rc = 0;
558
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100559 if (!(atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_STOPPED))
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100560 rc = -EBUSY;
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100561 else {
562 vcpu->run->psw_mask = psw.mask;
563 vcpu->run->psw_addr = psw.addr;
564 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100565 return rc;
566}
567
568int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
569 struct kvm_translation *tr)
570{
571 return -EINVAL; /* not implemented yet */
572}
573
Jan Kiszkad0bfb942008-12-15 13:52:10 +0100574int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
575 struct kvm_guest_debug *dbg)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100576{
577 return -EINVAL; /* not implemented yet */
578}
579
Marcelo Tosatti62d9f0d2008-04-11 13:24:45 -0300580int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
581 struct kvm_mp_state *mp_state)
582{
583 return -EINVAL; /* not implemented yet */
584}
585
586int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
587 struct kvm_mp_state *mp_state)
588{
589 return -EINVAL; /* not implemented yet */
590}
591
Carsten Ottee168bf82012-01-04 10:25:22 +0100592static int __vcpu_run(struct kvm_vcpu *vcpu)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100593{
Carsten Ottee168bf82012-01-04 10:25:22 +0100594 int rc;
595
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100596 memcpy(&vcpu->arch.sie_block->gg14, &vcpu->run->s.regs.gprs[14], 16);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100597
598 if (need_resched())
599 schedule();
600
Christian Borntraeger71cde582008-05-21 13:37:34 +0200601 if (test_thread_flag(TIF_MCCK_PENDING))
602 s390_handle_mcck();
603
Carsten Otted6b6d162012-01-04 10:25:25 +0100604 if (!kvm_is_ucontrol(vcpu->kvm))
605 kvm_s390_deliver_pending_interrupts(vcpu);
Carsten Otte0ff31862008-05-21 13:37:37 +0200606
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100607 vcpu->arch.sie_block->icptcode = 0;
608 local_irq_disable();
609 kvm_guest_enter();
610 local_irq_enable();
611 VCPU_EVENT(vcpu, 6, "entering sie flags %x",
612 atomic_read(&vcpu->arch.sie_block->cpuflags));
Cornelia Huck5786fff2012-07-23 17:20:29 +0200613 trace_kvm_s390_sie_enter(vcpu,
614 atomic_read(&vcpu->arch.sie_block->cpuflags));
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100615 rc = sie64a(vcpu->arch.sie_block, vcpu->run->s.regs.gprs);
Carsten Ottee168bf82012-01-04 10:25:22 +0100616 if (rc) {
617 if (kvm_is_ucontrol(vcpu->kvm)) {
618 rc = SIE_INTERCEPT_UCONTROL;
619 } else {
620 VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction");
Cornelia Huck5786fff2012-07-23 17:20:29 +0200621 trace_kvm_s390_sie_fault(vcpu);
Carsten Ottee168bf82012-01-04 10:25:22 +0100622 kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
623 rc = 0;
624 }
Carsten Otte1f0d0f02008-05-21 13:37:40 +0200625 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100626 VCPU_EVENT(vcpu, 6, "exit sie icptcode %d",
627 vcpu->arch.sie_block->icptcode);
Cornelia Huck5786fff2012-07-23 17:20:29 +0200628 trace_kvm_s390_sie_exit(vcpu, vcpu->arch.sie_block->icptcode);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100629 local_irq_disable();
630 kvm_guest_exit();
631 local_irq_enable();
632
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100633 memcpy(&vcpu->run->s.regs.gprs[14], &vcpu->arch.sie_block->gg14, 16);
Carsten Ottee168bf82012-01-04 10:25:22 +0100634 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100635}
636
637int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
638{
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100639 int rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100640 sigset_t sigsaved;
641
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200642rerun_vcpu:
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100643 if (vcpu->sigset_active)
644 sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
645
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100646 atomic_clear_mask(CPUSTAT_STOPPED, &vcpu->arch.sie_block->cpuflags);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100647
Carsten Otteba5c1e92008-03-25 18:47:26 +0100648 BUG_ON(vcpu->kvm->arch.float_int.local_int[vcpu->vcpu_id] == NULL);
649
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100650 switch (kvm_run->exit_reason) {
651 case KVM_EXIT_S390_SIEIC:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100652 case KVM_EXIT_UNKNOWN:
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200653 case KVM_EXIT_INTR:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100654 case KVM_EXIT_S390_RESET:
Carsten Ottee168bf82012-01-04 10:25:22 +0100655 case KVM_EXIT_S390_UCONTROL:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100656 break;
657 default:
658 BUG();
659 }
660
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100661 vcpu->arch.sie_block->gpsw.mask = kvm_run->psw_mask;
662 vcpu->arch.sie_block->gpsw.addr = kvm_run->psw_addr;
Christian Borntraeger60b413c2012-01-11 11:20:31 +0100663 if (kvm_run->kvm_dirty_regs & KVM_SYNC_PREFIX) {
664 kvm_run->kvm_dirty_regs &= ~KVM_SYNC_PREFIX;
665 kvm_s390_set_prefix(vcpu, kvm_run->s.regs.prefix);
666 }
Christian Borntraeger9eed07352012-02-06 10:59:07 +0100667 if (kvm_run->kvm_dirty_regs & KVM_SYNC_CRS) {
668 kvm_run->kvm_dirty_regs &= ~KVM_SYNC_CRS;
669 memcpy(&vcpu->arch.sie_block->gcr, &kvm_run->s.regs.crs, 128);
670 kvm_s390_set_prefix(vcpu, kvm_run->s.regs.prefix);
671 }
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100672
Heiko Carstensdab4079d2009-06-12 10:26:32 +0200673 might_fault();
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100674
675 do {
Carsten Ottee168bf82012-01-04 10:25:22 +0100676 rc = __vcpu_run(vcpu);
677 if (rc)
678 break;
Carsten Ottec0d744a2012-01-04 10:25:24 +0100679 if (kvm_is_ucontrol(vcpu->kvm))
680 rc = -EOPNOTSUPP;
681 else
682 rc = kvm_handle_sie_intercept(vcpu);
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100683 } while (!signal_pending(current) && !rc);
684
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200685 if (rc == SIE_INTERCEPT_RERUNVCPU)
686 goto rerun_vcpu;
687
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200688 if (signal_pending(current) && !rc) {
689 kvm_run->exit_reason = KVM_EXIT_INTR;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100690 rc = -EINTR;
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200691 }
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100692
Carsten Ottee168bf82012-01-04 10:25:22 +0100693#ifdef CONFIG_KVM_S390_UCONTROL
694 if (rc == SIE_INTERCEPT_UCONTROL) {
695 kvm_run->exit_reason = KVM_EXIT_S390_UCONTROL;
696 kvm_run->s390_ucontrol.trans_exc_code =
697 current->thread.gmap_addr;
698 kvm_run->s390_ucontrol.pgm_code = 0x10;
699 rc = 0;
700 }
701#endif
702
Heiko Carstensb8e660b2010-02-26 22:37:41 +0100703 if (rc == -EOPNOTSUPP) {
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100704 /* intercept cannot be handled in-kernel, prepare kvm-run */
705 kvm_run->exit_reason = KVM_EXIT_S390_SIEIC;
706 kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100707 kvm_run->s390_sieic.ipa = vcpu->arch.sie_block->ipa;
708 kvm_run->s390_sieic.ipb = vcpu->arch.sie_block->ipb;
709 rc = 0;
710 }
711
712 if (rc == -EREMOTE) {
713 /* intercept was handled, but userspace support is needed
714 * kvm_run has been prepared by the handler */
715 rc = 0;
716 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100717
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100718 kvm_run->psw_mask = vcpu->arch.sie_block->gpsw.mask;
719 kvm_run->psw_addr = vcpu->arch.sie_block->gpsw.addr;
Christian Borntraeger60b413c2012-01-11 11:20:31 +0100720 kvm_run->s.regs.prefix = vcpu->arch.sie_block->prefix;
Christian Borntraeger9eed07352012-02-06 10:59:07 +0100721 memcpy(&kvm_run->s.regs.crs, &vcpu->arch.sie_block->gcr, 128);
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100722
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100723 if (vcpu->sigset_active)
724 sigprocmask(SIG_SETMASK, &sigsaved, NULL);
725
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100726 vcpu->stat.exit_userspace++;
Heiko Carstens7e8e6ab2008-04-04 15:12:35 +0200727 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100728}
729
Carsten Otte092670c2011-07-24 10:48:22 +0200730static int __guestcopy(struct kvm_vcpu *vcpu, u64 guestdest, void *from,
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100731 unsigned long n, int prefix)
732{
733 if (prefix)
734 return copy_to_guest(vcpu, guestdest, from, n);
735 else
736 return copy_to_guest_absolute(vcpu, guestdest, from, n);
737}
738
739/*
740 * store status at address
741 * we use have two special cases:
742 * KVM_S390_STORE_STATUS_NOADDR: -> 0x1200 on 64 bit
743 * KVM_S390_STORE_STATUS_PREFIXED: -> prefix
744 */
Christian Borntraeger971eb772010-06-12 08:54:13 +0200745int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100746{
Carsten Otte092670c2011-07-24 10:48:22 +0200747 unsigned char archmode = 1;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100748 int prefix;
749
750 if (addr == KVM_S390_STORE_STATUS_NOADDR) {
751 if (copy_to_guest_absolute(vcpu, 163ul, &archmode, 1))
752 return -EFAULT;
753 addr = SAVE_AREA_BASE;
754 prefix = 0;
755 } else if (addr == KVM_S390_STORE_STATUS_PREFIXED) {
756 if (copy_to_guest(vcpu, 163ul, &archmode, 1))
757 return -EFAULT;
758 addr = SAVE_AREA_BASE;
759 prefix = 1;
760 } else
761 prefix = 0;
762
Heiko Carstensf64ca212010-02-26 22:37:32 +0100763 if (__guestcopy(vcpu, addr + offsetof(struct save_area, fp_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100764 vcpu->arch.guest_fpregs.fprs, 128, prefix))
765 return -EFAULT;
766
Heiko Carstensf64ca212010-02-26 22:37:32 +0100767 if (__guestcopy(vcpu, addr + offsetof(struct save_area, gp_regs),
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100768 vcpu->run->s.regs.gprs, 128, prefix))
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100769 return -EFAULT;
770
Heiko Carstensf64ca212010-02-26 22:37:32 +0100771 if (__guestcopy(vcpu, addr + offsetof(struct save_area, psw),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100772 &vcpu->arch.sie_block->gpsw, 16, prefix))
773 return -EFAULT;
774
Heiko Carstensf64ca212010-02-26 22:37:32 +0100775 if (__guestcopy(vcpu, addr + offsetof(struct save_area, pref_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100776 &vcpu->arch.sie_block->prefix, 4, prefix))
777 return -EFAULT;
778
779 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100780 addr + offsetof(struct save_area, fp_ctrl_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100781 &vcpu->arch.guest_fpregs.fpc, 4, prefix))
782 return -EFAULT;
783
Heiko Carstensf64ca212010-02-26 22:37:32 +0100784 if (__guestcopy(vcpu, addr + offsetof(struct save_area, tod_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100785 &vcpu->arch.sie_block->todpr, 4, prefix))
786 return -EFAULT;
787
Heiko Carstensf64ca212010-02-26 22:37:32 +0100788 if (__guestcopy(vcpu, addr + offsetof(struct save_area, timer),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100789 &vcpu->arch.sie_block->cputm, 8, prefix))
790 return -EFAULT;
791
Heiko Carstensf64ca212010-02-26 22:37:32 +0100792 if (__guestcopy(vcpu, addr + offsetof(struct save_area, clk_cmp),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100793 &vcpu->arch.sie_block->ckc, 8, prefix))
794 return -EFAULT;
795
Heiko Carstensf64ca212010-02-26 22:37:32 +0100796 if (__guestcopy(vcpu, addr + offsetof(struct save_area, acc_regs),
Christian Borntraeger59674c12012-01-11 11:20:33 +0100797 &vcpu->run->s.regs.acrs, 64, prefix))
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100798 return -EFAULT;
799
800 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100801 addr + offsetof(struct save_area, ctrl_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100802 &vcpu->arch.sie_block->gcr, 128, prefix))
803 return -EFAULT;
804 return 0;
805}
806
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100807long kvm_arch_vcpu_ioctl(struct file *filp,
808 unsigned int ioctl, unsigned long arg)
809{
810 struct kvm_vcpu *vcpu = filp->private_data;
811 void __user *argp = (void __user *)arg;
Avi Kivitybc923cc2010-05-13 12:21:46 +0300812 long r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100813
Avi Kivity93736622010-05-13 12:35:17 +0300814 switch (ioctl) {
815 case KVM_S390_INTERRUPT: {
Carsten Otteba5c1e92008-03-25 18:47:26 +0100816 struct kvm_s390_interrupt s390int;
817
Avi Kivity93736622010-05-13 12:35:17 +0300818 r = -EFAULT;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100819 if (copy_from_user(&s390int, argp, sizeof(s390int)))
Avi Kivity93736622010-05-13 12:35:17 +0300820 break;
821 r = kvm_s390_inject_vcpu(vcpu, &s390int);
822 break;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100823 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100824 case KVM_S390_STORE_STATUS:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300825 r = kvm_s390_vcpu_store_status(vcpu, arg);
826 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100827 case KVM_S390_SET_INITIAL_PSW: {
828 psw_t psw;
829
Avi Kivitybc923cc2010-05-13 12:21:46 +0300830 r = -EFAULT;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100831 if (copy_from_user(&psw, argp, sizeof(psw)))
Avi Kivitybc923cc2010-05-13 12:21:46 +0300832 break;
833 r = kvm_arch_vcpu_ioctl_set_initial_psw(vcpu, psw);
834 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100835 }
836 case KVM_S390_INITIAL_RESET:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300837 r = kvm_arch_vcpu_ioctl_initial_reset(vcpu);
838 break;
Carsten Otte14eebd92012-05-15 14:15:26 +0200839 case KVM_SET_ONE_REG:
840 case KVM_GET_ONE_REG: {
841 struct kvm_one_reg reg;
842 r = -EFAULT;
843 if (copy_from_user(&reg, argp, sizeof(reg)))
844 break;
845 if (ioctl == KVM_SET_ONE_REG)
846 r = kvm_arch_vcpu_ioctl_set_one_reg(vcpu, &reg);
847 else
848 r = kvm_arch_vcpu_ioctl_get_one_reg(vcpu, &reg);
849 break;
850 }
Carsten Otte27e03932012-01-04 10:25:21 +0100851#ifdef CONFIG_KVM_S390_UCONTROL
852 case KVM_S390_UCAS_MAP: {
853 struct kvm_s390_ucas_mapping ucasmap;
854
855 if (copy_from_user(&ucasmap, argp, sizeof(ucasmap))) {
856 r = -EFAULT;
857 break;
858 }
859
860 if (!kvm_is_ucontrol(vcpu->kvm)) {
861 r = -EINVAL;
862 break;
863 }
864
865 r = gmap_map_segment(vcpu->arch.gmap, ucasmap.user_addr,
866 ucasmap.vcpu_addr, ucasmap.length);
867 break;
868 }
869 case KVM_S390_UCAS_UNMAP: {
870 struct kvm_s390_ucas_mapping ucasmap;
871
872 if (copy_from_user(&ucasmap, argp, sizeof(ucasmap))) {
873 r = -EFAULT;
874 break;
875 }
876
877 if (!kvm_is_ucontrol(vcpu->kvm)) {
878 r = -EINVAL;
879 break;
880 }
881
882 r = gmap_unmap_segment(vcpu->arch.gmap, ucasmap.vcpu_addr,
883 ucasmap.length);
884 break;
885 }
886#endif
Carsten Otteccc79102012-01-04 10:25:26 +0100887 case KVM_S390_VCPU_FAULT: {
888 r = gmap_fault(arg, vcpu->arch.gmap);
889 if (!IS_ERR_VALUE(r))
890 r = 0;
891 break;
892 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100893 default:
Carsten Otte3e6afcf2012-01-04 10:25:30 +0100894 r = -ENOTTY;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100895 }
Avi Kivitybc923cc2010-05-13 12:21:46 +0300896 return r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100897}
898
Carsten Otte5b1c1492012-01-04 10:25:23 +0100899int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
900{
901#ifdef CONFIG_KVM_S390_UCONTROL
902 if ((vmf->pgoff == KVM_S390_SIE_PAGE_OFFSET)
903 && (kvm_is_ucontrol(vcpu->kvm))) {
904 vmf->page = virt_to_page(vcpu->arch.sie_block);
905 get_page(vmf->page);
906 return 0;
907 }
908#endif
909 return VM_FAULT_SIGBUS;
910}
911
Takuya Yoshikawadb3fe4e2012-02-08 13:02:18 +0900912void kvm_arch_free_memslot(struct kvm_memory_slot *free,
913 struct kvm_memory_slot *dont)
914{
915}
916
917int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages)
918{
919 return 0;
920}
921
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100922/* Section: memory related */
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200923int kvm_arch_prepare_memory_region(struct kvm *kvm,
924 struct kvm_memory_slot *memslot,
925 struct kvm_memory_slot old,
926 struct kvm_userspace_memory_region *mem,
927 int user_alloc)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100928{
929 /* A few sanity checks. We can have exactly one memory slot which has
930 to start at guest virtual zero and which has to be located at a
931 page boundary in userland and which has to end at a page boundary.
932 The memory in userland is ok to be fragmented into various different
933 vmas. It is okay to mmap() and munmap() stuff in this slot after
934 doing this call at any time */
935
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200936 if (mem->slot)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100937 return -EINVAL;
938
939 if (mem->guest_phys_addr)
940 return -EINVAL;
941
Carsten Otte598841c2011-07-24 10:48:21 +0200942 if (mem->userspace_addr & 0xffffful)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100943 return -EINVAL;
944
Carsten Otte598841c2011-07-24 10:48:21 +0200945 if (mem->memory_size & 0xffffful)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100946 return -EINVAL;
947
Carsten Otte2668dab2009-05-12 17:21:48 +0200948 if (!user_alloc)
949 return -EINVAL;
950
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200951 return 0;
952}
953
954void kvm_arch_commit_memory_region(struct kvm *kvm,
955 struct kvm_userspace_memory_region *mem,
956 struct kvm_memory_slot old,
957 int user_alloc)
958{
Carsten Ottef7850c92011-07-24 10:48:23 +0200959 int rc;
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200960
Carsten Otte598841c2011-07-24 10:48:21 +0200961
962 rc = gmap_map_segment(kvm->arch.gmap, mem->userspace_addr,
963 mem->guest_phys_addr, mem->memory_size);
964 if (rc)
Carsten Ottef7850c92011-07-24 10:48:23 +0200965 printk(KERN_WARNING "kvm-s390: failed to commit memory region\n");
Carsten Otte598841c2011-07-24 10:48:21 +0200966 return;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100967}
968
Marcelo Tosatti34d4cb82008-07-10 20:49:31 -0300969void kvm_arch_flush_shadow(struct kvm *kvm)
970{
971}
972
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100973static int __init kvm_s390_init(void)
974{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200975 int ret;
Avi Kivity0ee75be2010-04-28 15:39:01 +0300976 ret = kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE);
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200977 if (ret)
978 return ret;
979
980 /*
981 * guests can ask for up to 255+1 double words, we need a full page
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300982 * to hold the maximum amount of facilities. On the other hand, we
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200983 * only set facilities that are known to work in KVM.
984 */
Heiko Carstensc2f0e8c2010-06-08 18:58:09 +0200985 facilities = (unsigned long long *) get_zeroed_page(GFP_KERNEL|GFP_DMA);
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200986 if (!facilities) {
987 kvm_exit();
988 return -ENOMEM;
989 }
Martin Schwidefsky14375bc2010-10-25 16:10:51 +0200990 memcpy(facilities, S390_lowcore.stfle_fac_list, 16);
Christian Borntraeger6d00d002010-10-25 16:10:48 +0200991 facilities[0] &= 0xff00fff3f47c0000ULL;
Christian Borntraeger9950f8b2011-06-06 14:14:39 +0200992 facilities[1] &= 0x201c000000000000ULL;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200993 return 0;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100994}
995
996static void __exit kvm_s390_exit(void)
997{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200998 free_page((unsigned long) facilities);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100999 kvm_exit();
1000}
1001
1002module_init(kvm_s390_init);
1003module_exit(kvm_s390_exit);