blob: 5c761bffa02d5cb1dacba0059b3faa25f55f35ee [file] [log] [blame]
Heiko Carstensb0c632d2008-03-25 18:47:20 +01001/*
2 * s390host.c -- hosting zSeries kernel virtual machines
3 *
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +02004 * Copyright IBM Corp. 2008,2009
Heiko Carstensb0c632d2008-03-25 18:47:20 +01005 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License (version 2 only)
8 * as published by the Free Software Foundation.
9 *
10 * Author(s): Carsten Otte <cotte@de.ibm.com>
11 * Christian Borntraeger <borntraeger@de.ibm.com>
12 * Heiko Carstens <heiko.carstens@de.ibm.com>
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +020013 * Christian Ehrhardt <ehrhardt@de.ibm.com>
Heiko Carstensb0c632d2008-03-25 18:47:20 +010014 */
15
16#include <linux/compiler.h>
17#include <linux/err.h>
18#include <linux/fs.h>
Christian Borntraegerca872302009-05-12 17:21:49 +020019#include <linux/hrtimer.h>
Heiko Carstensb0c632d2008-03-25 18:47:20 +010020#include <linux/init.h>
21#include <linux/kvm.h>
22#include <linux/kvm_host.h>
23#include <linux/module.h>
24#include <linux/slab.h>
Carsten Otteba5c1e92008-03-25 18:47:26 +010025#include <linux/timer.h>
Heiko Carstenscbb870c2010-02-26 22:37:43 +010026#include <asm/asm-offsets.h>
Heiko Carstensb0c632d2008-03-25 18:47:20 +010027#include <asm/lowcore.h>
28#include <asm/pgtable.h>
Heiko Carstensf5daba12009-03-26 15:24:01 +010029#include <asm/nmi.h>
David Howellsa0616cd2012-03-28 18:30:02 +010030#include <asm/switch_to.h>
Christian Borntraeger1526bf92012-05-15 14:15:25 +020031#include <asm/sclp.h>
Christian Borntraeger8f2abe62008-03-25 18:47:23 +010032#include "kvm-s390.h"
Heiko Carstensb0c632d2008-03-25 18:47:20 +010033#include "gaccess.h"
34
35#define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU
36
37struct kvm_stats_debugfs_item debugfs_entries[] = {
38 { "userspace_handled", VCPU_STAT(exit_userspace) },
Christian Borntraeger0eaeafa2008-05-07 09:22:53 +020039 { "exit_null", VCPU_STAT(exit_null) },
Christian Borntraeger8f2abe62008-03-25 18:47:23 +010040 { "exit_validity", VCPU_STAT(exit_validity) },
41 { "exit_stop_request", VCPU_STAT(exit_stop_request) },
42 { "exit_external_request", VCPU_STAT(exit_external_request) },
43 { "exit_external_interrupt", VCPU_STAT(exit_external_interrupt) },
Carsten Otteba5c1e92008-03-25 18:47:26 +010044 { "exit_instruction", VCPU_STAT(exit_instruction) },
45 { "exit_program_interruption", VCPU_STAT(exit_program_interruption) },
46 { "exit_instr_and_program_int", VCPU_STAT(exit_instr_and_program) },
Christian Borntraegerf5e10b02008-07-25 15:52:44 +020047 { "instruction_lctlg", VCPU_STAT(instruction_lctlg) },
Carsten Otteba5c1e92008-03-25 18:47:26 +010048 { "instruction_lctl", VCPU_STAT(instruction_lctl) },
49 { "deliver_emergency_signal", VCPU_STAT(deliver_emergency_signal) },
Christian Ehrhardt7697e712011-10-18 12:27:15 +020050 { "deliver_external_call", VCPU_STAT(deliver_external_call) },
Carsten Otteba5c1e92008-03-25 18:47:26 +010051 { "deliver_service_signal", VCPU_STAT(deliver_service_signal) },
52 { "deliver_virtio_interrupt", VCPU_STAT(deliver_virtio_interrupt) },
53 { "deliver_stop_signal", VCPU_STAT(deliver_stop_signal) },
54 { "deliver_prefix_signal", VCPU_STAT(deliver_prefix_signal) },
55 { "deliver_restart_signal", VCPU_STAT(deliver_restart_signal) },
56 { "deliver_program_interruption", VCPU_STAT(deliver_program_int) },
57 { "exit_wait_state", VCPU_STAT(exit_wait_state) },
Christian Borntraeger453423d2008-03-25 18:47:29 +010058 { "instruction_stidp", VCPU_STAT(instruction_stidp) },
59 { "instruction_spx", VCPU_STAT(instruction_spx) },
60 { "instruction_stpx", VCPU_STAT(instruction_stpx) },
61 { "instruction_stap", VCPU_STAT(instruction_stap) },
62 { "instruction_storage_key", VCPU_STAT(instruction_storage_key) },
63 { "instruction_stsch", VCPU_STAT(instruction_stsch) },
64 { "instruction_chsc", VCPU_STAT(instruction_chsc) },
65 { "instruction_stsi", VCPU_STAT(instruction_stsi) },
66 { "instruction_stfl", VCPU_STAT(instruction_stfl) },
Christian Borntraegerbb25b9b2011-07-24 10:48:17 +020067 { "instruction_tprot", VCPU_STAT(instruction_tprot) },
Christian Borntraeger5288fbf2008-03-25 18:47:31 +010068 { "instruction_sigp_sense", VCPU_STAT(instruction_sigp_sense) },
Cornelia Huckbd59d3a2011-11-17 11:00:42 +010069 { "instruction_sigp_sense_running", VCPU_STAT(instruction_sigp_sense_running) },
Christian Ehrhardt7697e712011-10-18 12:27:15 +020070 { "instruction_sigp_external_call", VCPU_STAT(instruction_sigp_external_call) },
Christian Borntraeger5288fbf2008-03-25 18:47:31 +010071 { "instruction_sigp_emergency", VCPU_STAT(instruction_sigp_emergency) },
72 { "instruction_sigp_stop", VCPU_STAT(instruction_sigp_stop) },
73 { "instruction_sigp_set_arch", VCPU_STAT(instruction_sigp_arch) },
74 { "instruction_sigp_set_prefix", VCPU_STAT(instruction_sigp_prefix) },
75 { "instruction_sigp_restart", VCPU_STAT(instruction_sigp_restart) },
Christian Borntraeger388186b2011-10-30 15:17:03 +010076 { "diagnose_10", VCPU_STAT(diagnose_10) },
Christian Borntraegere28acfe2008-03-25 18:47:34 +010077 { "diagnose_44", VCPU_STAT(diagnose_44) },
Konstantin Weitz41628d32012-04-25 15:30:38 +020078 { "diagnose_9c", VCPU_STAT(diagnose_9c) },
Heiko Carstensb0c632d2008-03-25 18:47:20 +010079 { NULL }
80};
81
Christian Borntraegeref50f7a2009-06-23 17:24:07 +020082static unsigned long long *facilities;
Heiko Carstensb0c632d2008-03-25 18:47:20 +010083
84/* Section: not file related */
Alexander Graf10474ae2009-09-15 11:37:46 +020085int kvm_arch_hardware_enable(void *garbage)
Heiko Carstensb0c632d2008-03-25 18:47:20 +010086{
87 /* every s390 is virtualization enabled ;-) */
Alexander Graf10474ae2009-09-15 11:37:46 +020088 return 0;
Heiko Carstensb0c632d2008-03-25 18:47:20 +010089}
90
91void kvm_arch_hardware_disable(void *garbage)
92{
93}
94
Heiko Carstensb0c632d2008-03-25 18:47:20 +010095int kvm_arch_hardware_setup(void)
96{
97 return 0;
98}
99
100void kvm_arch_hardware_unsetup(void)
101{
102}
103
104void kvm_arch_check_processor_compat(void *rtn)
105{
106}
107
108int kvm_arch_init(void *opaque)
109{
110 return 0;
111}
112
113void kvm_arch_exit(void)
114{
115}
116
117/* Section: device related */
118long kvm_arch_dev_ioctl(struct file *filp,
119 unsigned int ioctl, unsigned long arg)
120{
121 if (ioctl == KVM_S390_ENABLE_SIE)
122 return s390_enable_sie();
123 return -EINVAL;
124}
125
126int kvm_dev_ioctl_check_extension(long ext)
127{
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100128 int r;
129
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200130 switch (ext) {
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100131 case KVM_CAP_S390_PSW:
Christian Borntraegerb6cf8782011-09-20 17:07:29 +0200132 case KVM_CAP_S390_GMAP:
Christian Borntraeger52e16b12011-11-17 11:00:44 +0100133 case KVM_CAP_SYNC_MMU:
Carsten Otte1efd0f52012-01-04 10:25:29 +0100134#ifdef CONFIG_KVM_S390_UCONTROL
135 case KVM_CAP_S390_UCONTROL:
136#endif
Christian Borntraeger60b413c2012-01-11 11:20:31 +0100137 case KVM_CAP_SYNC_REGS:
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100138 r = 1;
139 break;
Christian Borntraegere726b1b2012-05-02 10:50:38 +0200140 case KVM_CAP_NR_VCPUS:
141 case KVM_CAP_MAX_VCPUS:
142 r = KVM_MAX_VCPUS;
143 break;
Christian Borntraeger1526bf92012-05-15 14:15:25 +0200144 case KVM_CAP_S390_COW:
145 r = sclp_get_fac85() & 0x2;
146 break;
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200147 default:
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100148 r = 0;
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200149 }
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100150 return r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100151}
152
153/* Section: vm related */
154/*
155 * Get (and clear) the dirty memory log for a memory slot.
156 */
157int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
158 struct kvm_dirty_log *log)
159{
160 return 0;
161}
162
163long kvm_arch_vm_ioctl(struct file *filp,
164 unsigned int ioctl, unsigned long arg)
165{
166 struct kvm *kvm = filp->private_data;
167 void __user *argp = (void __user *)arg;
168 int r;
169
170 switch (ioctl) {
Carsten Otteba5c1e92008-03-25 18:47:26 +0100171 case KVM_S390_INTERRUPT: {
172 struct kvm_s390_interrupt s390int;
173
174 r = -EFAULT;
175 if (copy_from_user(&s390int, argp, sizeof(s390int)))
176 break;
177 r = kvm_s390_inject_vm(kvm, &s390int);
178 break;
179 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100180 default:
Avi Kivity367e1312009-08-26 14:57:07 +0300181 r = -ENOTTY;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100182 }
183
184 return r;
185}
186
Carsten Ottee08b9632012-01-04 10:25:20 +0100187int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100188{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100189 int rc;
190 char debug_name[16];
191
Carsten Ottee08b9632012-01-04 10:25:20 +0100192 rc = -EINVAL;
193#ifdef CONFIG_KVM_S390_UCONTROL
194 if (type & ~KVM_VM_S390_UCONTROL)
195 goto out_err;
196 if ((type & KVM_VM_S390_UCONTROL) && (!capable(CAP_SYS_ADMIN)))
197 goto out_err;
198#else
199 if (type)
200 goto out_err;
201#endif
202
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100203 rc = s390_enable_sie();
204 if (rc)
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100205 goto out_err;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100206
Carsten Otteb2904112011-10-18 12:27:13 +0200207 rc = -ENOMEM;
208
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100209 kvm->arch.sca = (struct sca_block *) get_zeroed_page(GFP_KERNEL);
210 if (!kvm->arch.sca)
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100211 goto out_err;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100212
213 sprintf(debug_name, "kvm-%u", current->pid);
214
215 kvm->arch.dbf = debug_register(debug_name, 8, 2, 8 * sizeof(long));
216 if (!kvm->arch.dbf)
217 goto out_nodbf;
218
Carsten Otteba5c1e92008-03-25 18:47:26 +0100219 spin_lock_init(&kvm->arch.float_int.lock);
220 INIT_LIST_HEAD(&kvm->arch.float_int.list);
221
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100222 debug_register_view(kvm->arch.dbf, &debug_sprintf_view);
223 VM_EVENT(kvm, 3, "%s", "vm created");
224
Carsten Ottee08b9632012-01-04 10:25:20 +0100225 if (type & KVM_VM_S390_UCONTROL) {
226 kvm->arch.gmap = NULL;
227 } else {
228 kvm->arch.gmap = gmap_alloc(current->mm);
229 if (!kvm->arch.gmap)
230 goto out_nogmap;
231 }
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100232 return 0;
Carsten Otte598841c2011-07-24 10:48:21 +0200233out_nogmap:
234 debug_unregister(kvm->arch.dbf);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100235out_nodbf:
236 free_page((unsigned long)(kvm->arch.sca));
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100237out_err:
238 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100239}
240
Christian Borntraegerd329c032008-11-26 14:50:27 +0100241void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
242{
243 VCPU_EVENT(vcpu, 3, "%s", "free cpu");
Carsten Otte58f94602012-01-04 10:25:27 +0100244 if (!kvm_is_ucontrol(vcpu->kvm)) {
245 clear_bit(63 - vcpu->vcpu_id,
246 (unsigned long *) &vcpu->kvm->arch.sca->mcn);
247 if (vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda ==
248 (__u64) vcpu->arch.sie_block)
249 vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda = 0;
250 }
Carsten Otteabf4a712009-05-12 17:21:51 +0200251 smp_mb();
Carsten Otte27e03932012-01-04 10:25:21 +0100252
253 if (kvm_is_ucontrol(vcpu->kvm))
254 gmap_free(vcpu->arch.gmap);
255
Christian Borntraegerd329c032008-11-26 14:50:27 +0100256 free_page((unsigned long)(vcpu->arch.sie_block));
Christian Borntraeger6692cef2008-11-26 14:51:08 +0100257 kvm_vcpu_uninit(vcpu);
Christian Borntraegerd329c032008-11-26 14:50:27 +0100258 kfree(vcpu);
259}
260
261static void kvm_free_vcpus(struct kvm *kvm)
262{
263 unsigned int i;
Gleb Natapov988a2ca2009-06-09 15:56:29 +0300264 struct kvm_vcpu *vcpu;
Christian Borntraegerd329c032008-11-26 14:50:27 +0100265
Gleb Natapov988a2ca2009-06-09 15:56:29 +0300266 kvm_for_each_vcpu(i, vcpu, kvm)
267 kvm_arch_vcpu_destroy(vcpu);
268
269 mutex_lock(&kvm->lock);
270 for (i = 0; i < atomic_read(&kvm->online_vcpus); i++)
271 kvm->vcpus[i] = NULL;
272
273 atomic_set(&kvm->online_vcpus, 0);
274 mutex_unlock(&kvm->lock);
Christian Borntraegerd329c032008-11-26 14:50:27 +0100275}
276
Sheng Yangad8ba2c2009-01-06 10:03:02 +0800277void kvm_arch_sync_events(struct kvm *kvm)
278{
279}
280
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100281void kvm_arch_destroy_vm(struct kvm *kvm)
282{
Christian Borntraegerd329c032008-11-26 14:50:27 +0100283 kvm_free_vcpus(kvm);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100284 free_page((unsigned long)(kvm->arch.sca));
Christian Borntraegerd329c032008-11-26 14:50:27 +0100285 debug_unregister(kvm->arch.dbf);
Carsten Otte27e03932012-01-04 10:25:21 +0100286 if (!kvm_is_ucontrol(kvm))
287 gmap_free(kvm->arch.gmap);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100288}
289
290/* Section: vcpu related */
291int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
292{
Carsten Otte27e03932012-01-04 10:25:21 +0100293 if (kvm_is_ucontrol(vcpu->kvm)) {
294 vcpu->arch.gmap = gmap_alloc(current->mm);
295 if (!vcpu->arch.gmap)
296 return -ENOMEM;
297 return 0;
298 }
299
Carsten Otte598841c2011-07-24 10:48:21 +0200300 vcpu->arch.gmap = vcpu->kvm->arch.gmap;
Christian Borntraeger59674c12012-01-11 11:20:33 +0100301 vcpu->run->kvm_valid_regs = KVM_SYNC_PREFIX |
302 KVM_SYNC_GPRS |
Christian Borntraeger9eed07352012-02-06 10:59:07 +0100303 KVM_SYNC_ACRS |
304 KVM_SYNC_CRS;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100305 return 0;
306}
307
308void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
309{
Christian Borntraeger6692cef2008-11-26 14:51:08 +0100310 /* Nothing todo */
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100311}
312
313void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
314{
315 save_fp_regs(&vcpu->arch.host_fpregs);
316 save_access_regs(vcpu->arch.host_acrs);
317 vcpu->arch.guest_fpregs.fpc &= FPC_VALID_MASK;
318 restore_fp_regs(&vcpu->arch.guest_fpregs);
Christian Borntraeger59674c12012-01-11 11:20:33 +0100319 restore_access_regs(vcpu->run->s.regs.acrs);
Christian Borntraeger480e5922011-09-20 17:07:28 +0200320 gmap_enable(vcpu->arch.gmap);
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100321 atomic_set_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100322}
323
324void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
325{
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100326 atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
Christian Borntraeger480e5922011-09-20 17:07:28 +0200327 gmap_disable(vcpu->arch.gmap);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100328 save_fp_regs(&vcpu->arch.guest_fpregs);
Christian Borntraeger59674c12012-01-11 11:20:33 +0100329 save_access_regs(vcpu->run->s.regs.acrs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100330 restore_fp_regs(&vcpu->arch.host_fpregs);
331 restore_access_regs(vcpu->arch.host_acrs);
332}
333
334static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu)
335{
336 /* this equals initial cpu reset in pop, but we don't switch to ESA */
337 vcpu->arch.sie_block->gpsw.mask = 0UL;
338 vcpu->arch.sie_block->gpsw.addr = 0UL;
Christian Borntraeger8d26cf72012-01-11 11:19:32 +0100339 kvm_s390_set_prefix(vcpu, 0);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100340 vcpu->arch.sie_block->cputm = 0UL;
341 vcpu->arch.sie_block->ckc = 0UL;
342 vcpu->arch.sie_block->todpr = 0;
343 memset(vcpu->arch.sie_block->gcr, 0, 16 * sizeof(__u64));
344 vcpu->arch.sie_block->gcr[0] = 0xE0UL;
345 vcpu->arch.sie_block->gcr[14] = 0xC2000000UL;
346 vcpu->arch.guest_fpregs.fpc = 0;
347 asm volatile("lfpc %0" : : "Q" (vcpu->arch.guest_fpregs.fpc));
348 vcpu->arch.sie_block->gbea = 1;
349}
350
351int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
352{
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100353 atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH |
354 CPUSTAT_SM |
355 CPUSTAT_STOPPED);
Christian Borntraegerfc345312010-06-17 23:16:20 +0200356 vcpu->arch.sie_block->ecb = 6;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100357 vcpu->arch.sie_block->eca = 0xC1002001U;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200358 vcpu->arch.sie_block->fac = (int) (long) facilities;
Christian Borntraegerca872302009-05-12 17:21:49 +0200359 hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
360 tasklet_init(&vcpu->arch.tasklet, kvm_s390_tasklet,
361 (unsigned long) vcpu);
362 vcpu->arch.ckc_timer.function = kvm_s390_idle_wakeup;
Christian Borntraeger453423d2008-03-25 18:47:29 +0100363 get_cpu_id(&vcpu->arch.cpu_id);
Christian Borntraeger92e6ecf2009-03-26 15:23:58 +0100364 vcpu->arch.cpu_id.version = 0xff;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100365 return 0;
366}
367
368struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
369 unsigned int id)
370{
Carsten Otte4d475552011-10-18 12:27:12 +0200371 struct kvm_vcpu *vcpu;
372 int rc = -EINVAL;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100373
Carsten Otte4d475552011-10-18 12:27:12 +0200374 if (id >= KVM_MAX_VCPUS)
375 goto out;
376
377 rc = -ENOMEM;
378
379 vcpu = kzalloc(sizeof(struct kvm_vcpu), GFP_KERNEL);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100380 if (!vcpu)
Carsten Otte4d475552011-10-18 12:27:12 +0200381 goto out;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100382
Christian Borntraeger180c12f2008-06-27 15:05:40 +0200383 vcpu->arch.sie_block = (struct kvm_s390_sie_block *)
384 get_zeroed_page(GFP_KERNEL);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100385
386 if (!vcpu->arch.sie_block)
387 goto out_free_cpu;
388
389 vcpu->arch.sie_block->icpua = id;
Carsten Otte58f94602012-01-04 10:25:27 +0100390 if (!kvm_is_ucontrol(kvm)) {
391 if (!kvm->arch.sca) {
392 WARN_ON_ONCE(1);
393 goto out_free_cpu;
394 }
395 if (!kvm->arch.sca->cpu[id].sda)
396 kvm->arch.sca->cpu[id].sda =
397 (__u64) vcpu->arch.sie_block;
398 vcpu->arch.sie_block->scaoh =
399 (__u32)(((__u64)kvm->arch.sca) >> 32);
400 vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca;
401 set_bit(63 - id, (unsigned long *) &kvm->arch.sca->mcn);
402 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100403
Carsten Otteba5c1e92008-03-25 18:47:26 +0100404 spin_lock_init(&vcpu->arch.local_int.lock);
405 INIT_LIST_HEAD(&vcpu->arch.local_int.list);
406 vcpu->arch.local_int.float_int = &kvm->arch.float_int;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200407 spin_lock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100408 kvm->arch.float_int.local_int[id] = &vcpu->arch.local_int;
409 init_waitqueue_head(&vcpu->arch.local_int.wq);
Christian Borntraeger5288fbf2008-03-25 18:47:31 +0100410 vcpu->arch.local_int.cpuflags = &vcpu->arch.sie_block->cpuflags;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200411 spin_unlock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100412
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100413 rc = kvm_vcpu_init(vcpu, kvm, id);
414 if (rc)
Wei Yongjun7b06bf22010-03-09 14:37:53 +0800415 goto out_free_sie_block;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100416 VM_EVENT(kvm, 3, "create cpu %d at %p, sie block at %p", id, vcpu,
417 vcpu->arch.sie_block);
418
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100419 return vcpu;
Wei Yongjun7b06bf22010-03-09 14:37:53 +0800420out_free_sie_block:
421 free_page((unsigned long)(vcpu->arch.sie_block));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100422out_free_cpu:
423 kfree(vcpu);
Carsten Otte4d475552011-10-18 12:27:12 +0200424out:
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100425 return ERR_PTR(rc);
426}
427
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100428int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
429{
430 /* kvm common code refers to this, but never calls it */
431 BUG();
432 return 0;
433}
434
Christoffer Dallb6d33832012-03-08 16:44:24 -0500435int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
436{
437 /* kvm common code refers to this, but never calls it */
438 BUG();
439 return 0;
440}
441
442
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100443static int kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu)
444{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100445 kvm_s390_vcpu_initial_reset(vcpu);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100446 return 0;
447}
448
449int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
450{
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100451 memcpy(&vcpu->run->s.regs.gprs, &regs->gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100452 return 0;
453}
454
455int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
456{
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100457 memcpy(&regs->gprs, &vcpu->run->s.regs.gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100458 return 0;
459}
460
461int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
462 struct kvm_sregs *sregs)
463{
Christian Borntraeger59674c12012-01-11 11:20:33 +0100464 memcpy(&vcpu->run->s.regs.acrs, &sregs->acrs, sizeof(sregs->acrs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100465 memcpy(&vcpu->arch.sie_block->gcr, &sregs->crs, sizeof(sregs->crs));
Christian Borntraeger59674c12012-01-11 11:20:33 +0100466 restore_access_regs(vcpu->run->s.regs.acrs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100467 return 0;
468}
469
470int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
471 struct kvm_sregs *sregs)
472{
Christian Borntraeger59674c12012-01-11 11:20:33 +0100473 memcpy(&sregs->acrs, &vcpu->run->s.regs.acrs, sizeof(sregs->acrs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100474 memcpy(&sregs->crs, &vcpu->arch.sie_block->gcr, sizeof(sregs->crs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100475 return 0;
476}
477
478int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
479{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100480 memcpy(&vcpu->arch.guest_fpregs.fprs, &fpu->fprs, sizeof(fpu->fprs));
Christian Borntraeger85175582012-02-06 10:59:02 +0100481 vcpu->arch.guest_fpregs.fpc = fpu->fpc & FPC_VALID_MASK;
Carsten Otte7eef87d2011-10-18 12:27:14 +0200482 restore_fp_regs(&vcpu->arch.guest_fpregs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100483 return 0;
484}
485
486int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
487{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100488 memcpy(&fpu->fprs, &vcpu->arch.guest_fpregs.fprs, sizeof(fpu->fprs));
489 fpu->fpc = vcpu->arch.guest_fpregs.fpc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100490 return 0;
491}
492
493static int kvm_arch_vcpu_ioctl_set_initial_psw(struct kvm_vcpu *vcpu, psw_t psw)
494{
495 int rc = 0;
496
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100497 if (!(atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_STOPPED))
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100498 rc = -EBUSY;
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100499 else {
500 vcpu->run->psw_mask = psw.mask;
501 vcpu->run->psw_addr = psw.addr;
502 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100503 return rc;
504}
505
506int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
507 struct kvm_translation *tr)
508{
509 return -EINVAL; /* not implemented yet */
510}
511
Jan Kiszkad0bfb942008-12-15 13:52:10 +0100512int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
513 struct kvm_guest_debug *dbg)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100514{
515 return -EINVAL; /* not implemented yet */
516}
517
Marcelo Tosatti62d9f0d2008-04-11 13:24:45 -0300518int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
519 struct kvm_mp_state *mp_state)
520{
521 return -EINVAL; /* not implemented yet */
522}
523
524int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
525 struct kvm_mp_state *mp_state)
526{
527 return -EINVAL; /* not implemented yet */
528}
529
Carsten Ottee168bf82012-01-04 10:25:22 +0100530static int __vcpu_run(struct kvm_vcpu *vcpu)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100531{
Carsten Ottee168bf82012-01-04 10:25:22 +0100532 int rc;
533
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100534 memcpy(&vcpu->arch.sie_block->gg14, &vcpu->run->s.regs.gprs[14], 16);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100535
536 if (need_resched())
537 schedule();
538
Christian Borntraeger71cde582008-05-21 13:37:34 +0200539 if (test_thread_flag(TIF_MCCK_PENDING))
540 s390_handle_mcck();
541
Carsten Otted6b6d162012-01-04 10:25:25 +0100542 if (!kvm_is_ucontrol(vcpu->kvm))
543 kvm_s390_deliver_pending_interrupts(vcpu);
Carsten Otte0ff31862008-05-21 13:37:37 +0200544
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100545 vcpu->arch.sie_block->icptcode = 0;
546 local_irq_disable();
547 kvm_guest_enter();
548 local_irq_enable();
549 VCPU_EVENT(vcpu, 6, "entering sie flags %x",
550 atomic_read(&vcpu->arch.sie_block->cpuflags));
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100551 rc = sie64a(vcpu->arch.sie_block, vcpu->run->s.regs.gprs);
Carsten Ottee168bf82012-01-04 10:25:22 +0100552 if (rc) {
553 if (kvm_is_ucontrol(vcpu->kvm)) {
554 rc = SIE_INTERCEPT_UCONTROL;
555 } else {
556 VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction");
557 kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
558 rc = 0;
559 }
Carsten Otte1f0d0f02008-05-21 13:37:40 +0200560 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100561 VCPU_EVENT(vcpu, 6, "exit sie icptcode %d",
562 vcpu->arch.sie_block->icptcode);
563 local_irq_disable();
564 kvm_guest_exit();
565 local_irq_enable();
566
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100567 memcpy(&vcpu->run->s.regs.gprs[14], &vcpu->arch.sie_block->gg14, 16);
Carsten Ottee168bf82012-01-04 10:25:22 +0100568 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100569}
570
571int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
572{
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100573 int rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100574 sigset_t sigsaved;
575
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200576rerun_vcpu:
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100577 if (vcpu->sigset_active)
578 sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
579
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100580 atomic_clear_mask(CPUSTAT_STOPPED, &vcpu->arch.sie_block->cpuflags);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100581
Carsten Otteba5c1e92008-03-25 18:47:26 +0100582 BUG_ON(vcpu->kvm->arch.float_int.local_int[vcpu->vcpu_id] == NULL);
583
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100584 switch (kvm_run->exit_reason) {
585 case KVM_EXIT_S390_SIEIC:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100586 case KVM_EXIT_UNKNOWN:
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200587 case KVM_EXIT_INTR:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100588 case KVM_EXIT_S390_RESET:
Carsten Ottee168bf82012-01-04 10:25:22 +0100589 case KVM_EXIT_S390_UCONTROL:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100590 break;
591 default:
592 BUG();
593 }
594
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100595 vcpu->arch.sie_block->gpsw.mask = kvm_run->psw_mask;
596 vcpu->arch.sie_block->gpsw.addr = kvm_run->psw_addr;
Christian Borntraeger60b413c2012-01-11 11:20:31 +0100597 if (kvm_run->kvm_dirty_regs & KVM_SYNC_PREFIX) {
598 kvm_run->kvm_dirty_regs &= ~KVM_SYNC_PREFIX;
599 kvm_s390_set_prefix(vcpu, kvm_run->s.regs.prefix);
600 }
Christian Borntraeger9eed07352012-02-06 10:59:07 +0100601 if (kvm_run->kvm_dirty_regs & KVM_SYNC_CRS) {
602 kvm_run->kvm_dirty_regs &= ~KVM_SYNC_CRS;
603 memcpy(&vcpu->arch.sie_block->gcr, &kvm_run->s.regs.crs, 128);
604 kvm_s390_set_prefix(vcpu, kvm_run->s.regs.prefix);
605 }
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100606
Heiko Carstensdab4079d2009-06-12 10:26:32 +0200607 might_fault();
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100608
609 do {
Carsten Ottee168bf82012-01-04 10:25:22 +0100610 rc = __vcpu_run(vcpu);
611 if (rc)
612 break;
Carsten Ottec0d744a2012-01-04 10:25:24 +0100613 if (kvm_is_ucontrol(vcpu->kvm))
614 rc = -EOPNOTSUPP;
615 else
616 rc = kvm_handle_sie_intercept(vcpu);
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100617 } while (!signal_pending(current) && !rc);
618
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200619 if (rc == SIE_INTERCEPT_RERUNVCPU)
620 goto rerun_vcpu;
621
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200622 if (signal_pending(current) && !rc) {
623 kvm_run->exit_reason = KVM_EXIT_INTR;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100624 rc = -EINTR;
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200625 }
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100626
Carsten Ottee168bf82012-01-04 10:25:22 +0100627#ifdef CONFIG_KVM_S390_UCONTROL
628 if (rc == SIE_INTERCEPT_UCONTROL) {
629 kvm_run->exit_reason = KVM_EXIT_S390_UCONTROL;
630 kvm_run->s390_ucontrol.trans_exc_code =
631 current->thread.gmap_addr;
632 kvm_run->s390_ucontrol.pgm_code = 0x10;
633 rc = 0;
634 }
635#endif
636
Heiko Carstensb8e660b2010-02-26 22:37:41 +0100637 if (rc == -EOPNOTSUPP) {
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100638 /* intercept cannot be handled in-kernel, prepare kvm-run */
639 kvm_run->exit_reason = KVM_EXIT_S390_SIEIC;
640 kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100641 kvm_run->s390_sieic.ipa = vcpu->arch.sie_block->ipa;
642 kvm_run->s390_sieic.ipb = vcpu->arch.sie_block->ipb;
643 rc = 0;
644 }
645
646 if (rc == -EREMOTE) {
647 /* intercept was handled, but userspace support is needed
648 * kvm_run has been prepared by the handler */
649 rc = 0;
650 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100651
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100652 kvm_run->psw_mask = vcpu->arch.sie_block->gpsw.mask;
653 kvm_run->psw_addr = vcpu->arch.sie_block->gpsw.addr;
Christian Borntraeger60b413c2012-01-11 11:20:31 +0100654 kvm_run->s.regs.prefix = vcpu->arch.sie_block->prefix;
Christian Borntraeger9eed07352012-02-06 10:59:07 +0100655 memcpy(&kvm_run->s.regs.crs, &vcpu->arch.sie_block->gcr, 128);
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100656
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100657 if (vcpu->sigset_active)
658 sigprocmask(SIG_SETMASK, &sigsaved, NULL);
659
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100660 vcpu->stat.exit_userspace++;
Heiko Carstens7e8e6ab2008-04-04 15:12:35 +0200661 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100662}
663
Carsten Otte092670c2011-07-24 10:48:22 +0200664static int __guestcopy(struct kvm_vcpu *vcpu, u64 guestdest, void *from,
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100665 unsigned long n, int prefix)
666{
667 if (prefix)
668 return copy_to_guest(vcpu, guestdest, from, n);
669 else
670 return copy_to_guest_absolute(vcpu, guestdest, from, n);
671}
672
673/*
674 * store status at address
675 * we use have two special cases:
676 * KVM_S390_STORE_STATUS_NOADDR: -> 0x1200 on 64 bit
677 * KVM_S390_STORE_STATUS_PREFIXED: -> prefix
678 */
Christian Borntraeger971eb772010-06-12 08:54:13 +0200679int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100680{
Carsten Otte092670c2011-07-24 10:48:22 +0200681 unsigned char archmode = 1;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100682 int prefix;
683
684 if (addr == KVM_S390_STORE_STATUS_NOADDR) {
685 if (copy_to_guest_absolute(vcpu, 163ul, &archmode, 1))
686 return -EFAULT;
687 addr = SAVE_AREA_BASE;
688 prefix = 0;
689 } else if (addr == KVM_S390_STORE_STATUS_PREFIXED) {
690 if (copy_to_guest(vcpu, 163ul, &archmode, 1))
691 return -EFAULT;
692 addr = SAVE_AREA_BASE;
693 prefix = 1;
694 } else
695 prefix = 0;
696
Heiko Carstensf64ca212010-02-26 22:37:32 +0100697 if (__guestcopy(vcpu, addr + offsetof(struct save_area, fp_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100698 vcpu->arch.guest_fpregs.fprs, 128, prefix))
699 return -EFAULT;
700
Heiko Carstensf64ca212010-02-26 22:37:32 +0100701 if (__guestcopy(vcpu, addr + offsetof(struct save_area, gp_regs),
Christian Borntraeger5a32c1a2012-01-11 11:20:32 +0100702 vcpu->run->s.regs.gprs, 128, prefix))
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100703 return -EFAULT;
704
Heiko Carstensf64ca212010-02-26 22:37:32 +0100705 if (__guestcopy(vcpu, addr + offsetof(struct save_area, psw),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100706 &vcpu->arch.sie_block->gpsw, 16, prefix))
707 return -EFAULT;
708
Heiko Carstensf64ca212010-02-26 22:37:32 +0100709 if (__guestcopy(vcpu, addr + offsetof(struct save_area, pref_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100710 &vcpu->arch.sie_block->prefix, 4, prefix))
711 return -EFAULT;
712
713 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100714 addr + offsetof(struct save_area, fp_ctrl_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100715 &vcpu->arch.guest_fpregs.fpc, 4, prefix))
716 return -EFAULT;
717
Heiko Carstensf64ca212010-02-26 22:37:32 +0100718 if (__guestcopy(vcpu, addr + offsetof(struct save_area, tod_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100719 &vcpu->arch.sie_block->todpr, 4, prefix))
720 return -EFAULT;
721
Heiko Carstensf64ca212010-02-26 22:37:32 +0100722 if (__guestcopy(vcpu, addr + offsetof(struct save_area, timer),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100723 &vcpu->arch.sie_block->cputm, 8, prefix))
724 return -EFAULT;
725
Heiko Carstensf64ca212010-02-26 22:37:32 +0100726 if (__guestcopy(vcpu, addr + offsetof(struct save_area, clk_cmp),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100727 &vcpu->arch.sie_block->ckc, 8, prefix))
728 return -EFAULT;
729
Heiko Carstensf64ca212010-02-26 22:37:32 +0100730 if (__guestcopy(vcpu, addr + offsetof(struct save_area, acc_regs),
Christian Borntraeger59674c12012-01-11 11:20:33 +0100731 &vcpu->run->s.regs.acrs, 64, prefix))
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100732 return -EFAULT;
733
734 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100735 addr + offsetof(struct save_area, ctrl_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100736 &vcpu->arch.sie_block->gcr, 128, prefix))
737 return -EFAULT;
738 return 0;
739}
740
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100741long kvm_arch_vcpu_ioctl(struct file *filp,
742 unsigned int ioctl, unsigned long arg)
743{
744 struct kvm_vcpu *vcpu = filp->private_data;
745 void __user *argp = (void __user *)arg;
Avi Kivitybc923cc2010-05-13 12:21:46 +0300746 long r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100747
Avi Kivity93736622010-05-13 12:35:17 +0300748 switch (ioctl) {
749 case KVM_S390_INTERRUPT: {
Carsten Otteba5c1e92008-03-25 18:47:26 +0100750 struct kvm_s390_interrupt s390int;
751
Avi Kivity93736622010-05-13 12:35:17 +0300752 r = -EFAULT;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100753 if (copy_from_user(&s390int, argp, sizeof(s390int)))
Avi Kivity93736622010-05-13 12:35:17 +0300754 break;
755 r = kvm_s390_inject_vcpu(vcpu, &s390int);
756 break;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100757 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100758 case KVM_S390_STORE_STATUS:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300759 r = kvm_s390_vcpu_store_status(vcpu, arg);
760 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100761 case KVM_S390_SET_INITIAL_PSW: {
762 psw_t psw;
763
Avi Kivitybc923cc2010-05-13 12:21:46 +0300764 r = -EFAULT;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100765 if (copy_from_user(&psw, argp, sizeof(psw)))
Avi Kivitybc923cc2010-05-13 12:21:46 +0300766 break;
767 r = kvm_arch_vcpu_ioctl_set_initial_psw(vcpu, psw);
768 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100769 }
770 case KVM_S390_INITIAL_RESET:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300771 r = kvm_arch_vcpu_ioctl_initial_reset(vcpu);
772 break;
Carsten Otte27e03932012-01-04 10:25:21 +0100773#ifdef CONFIG_KVM_S390_UCONTROL
774 case KVM_S390_UCAS_MAP: {
775 struct kvm_s390_ucas_mapping ucasmap;
776
777 if (copy_from_user(&ucasmap, argp, sizeof(ucasmap))) {
778 r = -EFAULT;
779 break;
780 }
781
782 if (!kvm_is_ucontrol(vcpu->kvm)) {
783 r = -EINVAL;
784 break;
785 }
786
787 r = gmap_map_segment(vcpu->arch.gmap, ucasmap.user_addr,
788 ucasmap.vcpu_addr, ucasmap.length);
789 break;
790 }
791 case KVM_S390_UCAS_UNMAP: {
792 struct kvm_s390_ucas_mapping ucasmap;
793
794 if (copy_from_user(&ucasmap, argp, sizeof(ucasmap))) {
795 r = -EFAULT;
796 break;
797 }
798
799 if (!kvm_is_ucontrol(vcpu->kvm)) {
800 r = -EINVAL;
801 break;
802 }
803
804 r = gmap_unmap_segment(vcpu->arch.gmap, ucasmap.vcpu_addr,
805 ucasmap.length);
806 break;
807 }
808#endif
Carsten Otteccc79102012-01-04 10:25:26 +0100809 case KVM_S390_VCPU_FAULT: {
810 r = gmap_fault(arg, vcpu->arch.gmap);
811 if (!IS_ERR_VALUE(r))
812 r = 0;
813 break;
814 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100815 default:
Carsten Otte3e6afcf2012-01-04 10:25:30 +0100816 r = -ENOTTY;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100817 }
Avi Kivitybc923cc2010-05-13 12:21:46 +0300818 return r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100819}
820
Carsten Otte5b1c1492012-01-04 10:25:23 +0100821int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
822{
823#ifdef CONFIG_KVM_S390_UCONTROL
824 if ((vmf->pgoff == KVM_S390_SIE_PAGE_OFFSET)
825 && (kvm_is_ucontrol(vcpu->kvm))) {
826 vmf->page = virt_to_page(vcpu->arch.sie_block);
827 get_page(vmf->page);
828 return 0;
829 }
830#endif
831 return VM_FAULT_SIGBUS;
832}
833
Takuya Yoshikawadb3fe4e2012-02-08 13:02:18 +0900834void kvm_arch_free_memslot(struct kvm_memory_slot *free,
835 struct kvm_memory_slot *dont)
836{
837}
838
839int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages)
840{
841 return 0;
842}
843
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100844/* Section: memory related */
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200845int kvm_arch_prepare_memory_region(struct kvm *kvm,
846 struct kvm_memory_slot *memslot,
847 struct kvm_memory_slot old,
848 struct kvm_userspace_memory_region *mem,
849 int user_alloc)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100850{
851 /* A few sanity checks. We can have exactly one memory slot which has
852 to start at guest virtual zero and which has to be located at a
853 page boundary in userland and which has to end at a page boundary.
854 The memory in userland is ok to be fragmented into various different
855 vmas. It is okay to mmap() and munmap() stuff in this slot after
856 doing this call at any time */
857
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200858 if (mem->slot)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100859 return -EINVAL;
860
861 if (mem->guest_phys_addr)
862 return -EINVAL;
863
Carsten Otte598841c2011-07-24 10:48:21 +0200864 if (mem->userspace_addr & 0xffffful)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100865 return -EINVAL;
866
Carsten Otte598841c2011-07-24 10:48:21 +0200867 if (mem->memory_size & 0xffffful)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100868 return -EINVAL;
869
Carsten Otte2668dab2009-05-12 17:21:48 +0200870 if (!user_alloc)
871 return -EINVAL;
872
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200873 return 0;
874}
875
876void kvm_arch_commit_memory_region(struct kvm *kvm,
877 struct kvm_userspace_memory_region *mem,
878 struct kvm_memory_slot old,
879 int user_alloc)
880{
Carsten Ottef7850c92011-07-24 10:48:23 +0200881 int rc;
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200882
Carsten Otte598841c2011-07-24 10:48:21 +0200883
884 rc = gmap_map_segment(kvm->arch.gmap, mem->userspace_addr,
885 mem->guest_phys_addr, mem->memory_size);
886 if (rc)
Carsten Ottef7850c92011-07-24 10:48:23 +0200887 printk(KERN_WARNING "kvm-s390: failed to commit memory region\n");
Carsten Otte598841c2011-07-24 10:48:21 +0200888 return;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100889}
890
Marcelo Tosatti34d4cb82008-07-10 20:49:31 -0300891void kvm_arch_flush_shadow(struct kvm *kvm)
892{
893}
894
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100895static int __init kvm_s390_init(void)
896{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200897 int ret;
Avi Kivity0ee75be2010-04-28 15:39:01 +0300898 ret = kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE);
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200899 if (ret)
900 return ret;
901
902 /*
903 * guests can ask for up to 255+1 double words, we need a full page
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300904 * to hold the maximum amount of facilities. On the other hand, we
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200905 * only set facilities that are known to work in KVM.
906 */
Heiko Carstensc2f0e8c2010-06-08 18:58:09 +0200907 facilities = (unsigned long long *) get_zeroed_page(GFP_KERNEL|GFP_DMA);
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200908 if (!facilities) {
909 kvm_exit();
910 return -ENOMEM;
911 }
Martin Schwidefsky14375bc2010-10-25 16:10:51 +0200912 memcpy(facilities, S390_lowcore.stfle_fac_list, 16);
Christian Borntraeger6d00d002010-10-25 16:10:48 +0200913 facilities[0] &= 0xff00fff3f47c0000ULL;
Christian Borntraeger9950f8b2011-06-06 14:14:39 +0200914 facilities[1] &= 0x201c000000000000ULL;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200915 return 0;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100916}
917
918static void __exit kvm_s390_exit(void)
919{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200920 free_page((unsigned long) facilities);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100921 kvm_exit();
922}
923
924module_init(kvm_s390_init);
925module_exit(kvm_s390_exit);