blob: 630ab65b488b8fb6732ee9d46ee1bfad7beb996e [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>
Christian Borntraegeref50f7a2009-06-23 17:24:07 +020030#include <asm/system.h>
Christian Borntraeger8f2abe62008-03-25 18:47:23 +010031#include "kvm-s390.h"
Heiko Carstensb0c632d2008-03-25 18:47:20 +010032#include "gaccess.h"
33
34#define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU
35
36struct kvm_stats_debugfs_item debugfs_entries[] = {
37 { "userspace_handled", VCPU_STAT(exit_userspace) },
Christian Borntraeger0eaeafa2008-05-07 09:22:53 +020038 { "exit_null", VCPU_STAT(exit_null) },
Christian Borntraeger8f2abe62008-03-25 18:47:23 +010039 { "exit_validity", VCPU_STAT(exit_validity) },
40 { "exit_stop_request", VCPU_STAT(exit_stop_request) },
41 { "exit_external_request", VCPU_STAT(exit_external_request) },
42 { "exit_external_interrupt", VCPU_STAT(exit_external_interrupt) },
Carsten Otteba5c1e92008-03-25 18:47:26 +010043 { "exit_instruction", VCPU_STAT(exit_instruction) },
44 { "exit_program_interruption", VCPU_STAT(exit_program_interruption) },
45 { "exit_instr_and_program_int", VCPU_STAT(exit_instr_and_program) },
Christian Borntraegerf5e10b02008-07-25 15:52:44 +020046 { "instruction_lctlg", VCPU_STAT(instruction_lctlg) },
Carsten Otteba5c1e92008-03-25 18:47:26 +010047 { "instruction_lctl", VCPU_STAT(instruction_lctl) },
48 { "deliver_emergency_signal", VCPU_STAT(deliver_emergency_signal) },
Christian Ehrhardt7697e71f2011-10-18 12:27:15 +020049 { "deliver_external_call", VCPU_STAT(deliver_external_call) },
Carsten Otteba5c1e92008-03-25 18:47:26 +010050 { "deliver_service_signal", VCPU_STAT(deliver_service_signal) },
51 { "deliver_virtio_interrupt", VCPU_STAT(deliver_virtio_interrupt) },
52 { "deliver_stop_signal", VCPU_STAT(deliver_stop_signal) },
53 { "deliver_prefix_signal", VCPU_STAT(deliver_prefix_signal) },
54 { "deliver_restart_signal", VCPU_STAT(deliver_restart_signal) },
55 { "deliver_program_interruption", VCPU_STAT(deliver_program_int) },
56 { "exit_wait_state", VCPU_STAT(exit_wait_state) },
Christian Borntraeger453423d2008-03-25 18:47:29 +010057 { "instruction_stidp", VCPU_STAT(instruction_stidp) },
58 { "instruction_spx", VCPU_STAT(instruction_spx) },
59 { "instruction_stpx", VCPU_STAT(instruction_stpx) },
60 { "instruction_stap", VCPU_STAT(instruction_stap) },
61 { "instruction_storage_key", VCPU_STAT(instruction_storage_key) },
62 { "instruction_stsch", VCPU_STAT(instruction_stsch) },
63 { "instruction_chsc", VCPU_STAT(instruction_chsc) },
64 { "instruction_stsi", VCPU_STAT(instruction_stsi) },
65 { "instruction_stfl", VCPU_STAT(instruction_stfl) },
Christian Borntraegerbb25b9b2011-07-24 10:48:17 +020066 { "instruction_tprot", VCPU_STAT(instruction_tprot) },
Christian Borntraeger5288fbf2008-03-25 18:47:31 +010067 { "instruction_sigp_sense", VCPU_STAT(instruction_sigp_sense) },
Christian Ehrhardt7697e71f2011-10-18 12:27:15 +020068 { "instruction_sigp_external_call", VCPU_STAT(instruction_sigp_external_call) },
Christian Borntraeger5288fbf2008-03-25 18:47:31 +010069 { "instruction_sigp_emergency", VCPU_STAT(instruction_sigp_emergency) },
70 { "instruction_sigp_stop", VCPU_STAT(instruction_sigp_stop) },
71 { "instruction_sigp_set_arch", VCPU_STAT(instruction_sigp_arch) },
72 { "instruction_sigp_set_prefix", VCPU_STAT(instruction_sigp_prefix) },
73 { "instruction_sigp_restart", VCPU_STAT(instruction_sigp_restart) },
Christian Borntraeger388186b2011-10-30 15:17:03 +010074 { "diagnose_10", VCPU_STAT(diagnose_10) },
Christian Borntraegere28acfe2008-03-25 18:47:34 +010075 { "diagnose_44", VCPU_STAT(diagnose_44) },
Heiko Carstensb0c632d2008-03-25 18:47:20 +010076 { NULL }
77};
78
Christian Borntraegeref50f7a2009-06-23 17:24:07 +020079static unsigned long long *facilities;
Heiko Carstensb0c632d2008-03-25 18:47:20 +010080
81/* Section: not file related */
Alexander Graf10474ae2009-09-15 11:37:46 +020082int kvm_arch_hardware_enable(void *garbage)
Heiko Carstensb0c632d2008-03-25 18:47:20 +010083{
84 /* every s390 is virtualization enabled ;-) */
Alexander Graf10474ae2009-09-15 11:37:46 +020085 return 0;
Heiko Carstensb0c632d2008-03-25 18:47:20 +010086}
87
88void kvm_arch_hardware_disable(void *garbage)
89{
90}
91
Heiko Carstensb0c632d2008-03-25 18:47:20 +010092int kvm_arch_hardware_setup(void)
93{
94 return 0;
95}
96
97void kvm_arch_hardware_unsetup(void)
98{
99}
100
101void kvm_arch_check_processor_compat(void *rtn)
102{
103}
104
105int kvm_arch_init(void *opaque)
106{
107 return 0;
108}
109
110void kvm_arch_exit(void)
111{
112}
113
114/* Section: device related */
115long kvm_arch_dev_ioctl(struct file *filp,
116 unsigned int ioctl, unsigned long arg)
117{
118 if (ioctl == KVM_S390_ENABLE_SIE)
119 return s390_enable_sie();
120 return -EINVAL;
121}
122
123int kvm_dev_ioctl_check_extension(long ext)
124{
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100125 int r;
126
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200127 switch (ext) {
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100128 case KVM_CAP_S390_PSW:
Christian Borntraegerb6cf8782011-09-20 17:07:29 +0200129 case KVM_CAP_S390_GMAP:
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100130 r = 1;
131 break;
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200132 default:
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100133 r = 0;
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200134 }
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100135 return r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100136}
137
138/* Section: vm related */
139/*
140 * Get (and clear) the dirty memory log for a memory slot.
141 */
142int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
143 struct kvm_dirty_log *log)
144{
145 return 0;
146}
147
148long kvm_arch_vm_ioctl(struct file *filp,
149 unsigned int ioctl, unsigned long arg)
150{
151 struct kvm *kvm = filp->private_data;
152 void __user *argp = (void __user *)arg;
153 int r;
154
155 switch (ioctl) {
Carsten Otteba5c1e92008-03-25 18:47:26 +0100156 case KVM_S390_INTERRUPT: {
157 struct kvm_s390_interrupt s390int;
158
159 r = -EFAULT;
160 if (copy_from_user(&s390int, argp, sizeof(s390int)))
161 break;
162 r = kvm_s390_inject_vm(kvm, &s390int);
163 break;
164 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100165 default:
Avi Kivity367e1312009-08-26 14:57:07 +0300166 r = -ENOTTY;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100167 }
168
169 return r;
170}
171
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100172int kvm_arch_init_vm(struct kvm *kvm)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100173{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100174 int rc;
175 char debug_name[16];
176
177 rc = s390_enable_sie();
178 if (rc)
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100179 goto out_err;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100180
Carsten Otteb2904112011-10-18 12:27:13 +0200181 rc = -ENOMEM;
182
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100183 kvm->arch.sca = (struct sca_block *) get_zeroed_page(GFP_KERNEL);
184 if (!kvm->arch.sca)
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100185 goto out_err;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100186
187 sprintf(debug_name, "kvm-%u", current->pid);
188
189 kvm->arch.dbf = debug_register(debug_name, 8, 2, 8 * sizeof(long));
190 if (!kvm->arch.dbf)
191 goto out_nodbf;
192
Carsten Otteba5c1e92008-03-25 18:47:26 +0100193 spin_lock_init(&kvm->arch.float_int.lock);
194 INIT_LIST_HEAD(&kvm->arch.float_int.list);
195
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100196 debug_register_view(kvm->arch.dbf, &debug_sprintf_view);
197 VM_EVENT(kvm, 3, "%s", "vm created");
198
Carsten Otte598841c2011-07-24 10:48:21 +0200199 kvm->arch.gmap = gmap_alloc(current->mm);
200 if (!kvm->arch.gmap)
201 goto out_nogmap;
202
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100203 return 0;
Carsten Otte598841c2011-07-24 10:48:21 +0200204out_nogmap:
205 debug_unregister(kvm->arch.dbf);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100206out_nodbf:
207 free_page((unsigned long)(kvm->arch.sca));
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100208out_err:
209 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100210}
211
Christian Borntraegerd329c032008-11-26 14:50:27 +0100212void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
213{
214 VCPU_EVENT(vcpu, 3, "%s", "free cpu");
Christian Borntraegerfc345312010-06-17 23:16:20 +0200215 clear_bit(63 - vcpu->vcpu_id, (unsigned long *) &vcpu->kvm->arch.sca->mcn);
Carsten Otteabf4a712009-05-12 17:21:51 +0200216 if (vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda ==
217 (__u64) vcpu->arch.sie_block)
218 vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda = 0;
219 smp_mb();
Christian Borntraegerd329c032008-11-26 14:50:27 +0100220 free_page((unsigned long)(vcpu->arch.sie_block));
Christian Borntraeger6692cef2008-11-26 14:51:08 +0100221 kvm_vcpu_uninit(vcpu);
Christian Borntraegerd329c032008-11-26 14:50:27 +0100222 kfree(vcpu);
223}
224
225static void kvm_free_vcpus(struct kvm *kvm)
226{
227 unsigned int i;
Gleb Natapov988a2ca2009-06-09 15:56:29 +0300228 struct kvm_vcpu *vcpu;
Christian Borntraegerd329c032008-11-26 14:50:27 +0100229
Gleb Natapov988a2ca2009-06-09 15:56:29 +0300230 kvm_for_each_vcpu(i, vcpu, kvm)
231 kvm_arch_vcpu_destroy(vcpu);
232
233 mutex_lock(&kvm->lock);
234 for (i = 0; i < atomic_read(&kvm->online_vcpus); i++)
235 kvm->vcpus[i] = NULL;
236
237 atomic_set(&kvm->online_vcpus, 0);
238 mutex_unlock(&kvm->lock);
Christian Borntraegerd329c032008-11-26 14:50:27 +0100239}
240
Sheng Yangad8ba2c2009-01-06 10:03:02 +0800241void kvm_arch_sync_events(struct kvm *kvm)
242{
243}
244
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100245void kvm_arch_destroy_vm(struct kvm *kvm)
246{
Christian Borntraegerd329c032008-11-26 14:50:27 +0100247 kvm_free_vcpus(kvm);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100248 free_page((unsigned long)(kvm->arch.sca));
Christian Borntraegerd329c032008-11-26 14:50:27 +0100249 debug_unregister(kvm->arch.dbf);
Carsten Otte598841c2011-07-24 10:48:21 +0200250 gmap_free(kvm->arch.gmap);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100251}
252
253/* Section: vcpu related */
254int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
255{
Carsten Otte598841c2011-07-24 10:48:21 +0200256 vcpu->arch.gmap = vcpu->kvm->arch.gmap;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100257 return 0;
258}
259
260void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
261{
Christian Borntraeger6692cef2008-11-26 14:51:08 +0100262 /* Nothing todo */
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100263}
264
265void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
266{
267 save_fp_regs(&vcpu->arch.host_fpregs);
268 save_access_regs(vcpu->arch.host_acrs);
269 vcpu->arch.guest_fpregs.fpc &= FPC_VALID_MASK;
270 restore_fp_regs(&vcpu->arch.guest_fpregs);
271 restore_access_regs(vcpu->arch.guest_acrs);
Christian Borntraeger480e5922011-09-20 17:07:28 +0200272 gmap_enable(vcpu->arch.gmap);
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100273 atomic_set_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100274}
275
276void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
277{
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100278 atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
Christian Borntraeger480e5922011-09-20 17:07:28 +0200279 gmap_disable(vcpu->arch.gmap);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100280 save_fp_regs(&vcpu->arch.guest_fpregs);
281 save_access_regs(vcpu->arch.guest_acrs);
282 restore_fp_regs(&vcpu->arch.host_fpregs);
283 restore_access_regs(vcpu->arch.host_acrs);
284}
285
286static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu)
287{
288 /* this equals initial cpu reset in pop, but we don't switch to ESA */
289 vcpu->arch.sie_block->gpsw.mask = 0UL;
290 vcpu->arch.sie_block->gpsw.addr = 0UL;
291 vcpu->arch.sie_block->prefix = 0UL;
292 vcpu->arch.sie_block->ihcpu = 0xffff;
293 vcpu->arch.sie_block->cputm = 0UL;
294 vcpu->arch.sie_block->ckc = 0UL;
295 vcpu->arch.sie_block->todpr = 0;
296 memset(vcpu->arch.sie_block->gcr, 0, 16 * sizeof(__u64));
297 vcpu->arch.sie_block->gcr[0] = 0xE0UL;
298 vcpu->arch.sie_block->gcr[14] = 0xC2000000UL;
299 vcpu->arch.guest_fpregs.fpc = 0;
300 asm volatile("lfpc %0" : : "Q" (vcpu->arch.guest_fpregs.fpc));
301 vcpu->arch.sie_block->gbea = 1;
302}
303
304int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
305{
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100306 atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH |
307 CPUSTAT_SM |
308 CPUSTAT_STOPPED);
Christian Borntraegerfc345312010-06-17 23:16:20 +0200309 vcpu->arch.sie_block->ecb = 6;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100310 vcpu->arch.sie_block->eca = 0xC1002001U;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200311 vcpu->arch.sie_block->fac = (int) (long) facilities;
Christian Borntraegerca872302009-05-12 17:21:49 +0200312 hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
313 tasklet_init(&vcpu->arch.tasklet, kvm_s390_tasklet,
314 (unsigned long) vcpu);
315 vcpu->arch.ckc_timer.function = kvm_s390_idle_wakeup;
Christian Borntraeger453423d2008-03-25 18:47:29 +0100316 get_cpu_id(&vcpu->arch.cpu_id);
Christian Borntraeger92e6ecf2009-03-26 15:23:58 +0100317 vcpu->arch.cpu_id.version = 0xff;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100318 return 0;
319}
320
321struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
322 unsigned int id)
323{
Carsten Otte4d475552011-10-18 12:27:12 +0200324 struct kvm_vcpu *vcpu;
325 int rc = -EINVAL;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100326
Carsten Otte4d475552011-10-18 12:27:12 +0200327 if (id >= KVM_MAX_VCPUS)
328 goto out;
329
330 rc = -ENOMEM;
331
332 vcpu = kzalloc(sizeof(struct kvm_vcpu), GFP_KERNEL);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100333 if (!vcpu)
Carsten Otte4d475552011-10-18 12:27:12 +0200334 goto out;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100335
Christian Borntraeger180c12f2008-06-27 15:05:40 +0200336 vcpu->arch.sie_block = (struct kvm_s390_sie_block *)
337 get_zeroed_page(GFP_KERNEL);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100338
339 if (!vcpu->arch.sie_block)
340 goto out_free_cpu;
341
342 vcpu->arch.sie_block->icpua = id;
343 BUG_ON(!kvm->arch.sca);
Carsten Otteabf4a712009-05-12 17:21:51 +0200344 if (!kvm->arch.sca->cpu[id].sda)
345 kvm->arch.sca->cpu[id].sda = (__u64) vcpu->arch.sie_block;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100346 vcpu->arch.sie_block->scaoh = (__u32)(((__u64)kvm->arch.sca) >> 32);
347 vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca;
Christian Borntraegerfc345312010-06-17 23:16:20 +0200348 set_bit(63 - id, (unsigned long *) &kvm->arch.sca->mcn);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100349
Carsten Otteba5c1e92008-03-25 18:47:26 +0100350 spin_lock_init(&vcpu->arch.local_int.lock);
351 INIT_LIST_HEAD(&vcpu->arch.local_int.list);
352 vcpu->arch.local_int.float_int = &kvm->arch.float_int;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200353 spin_lock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100354 kvm->arch.float_int.local_int[id] = &vcpu->arch.local_int;
355 init_waitqueue_head(&vcpu->arch.local_int.wq);
Christian Borntraeger5288fbf2008-03-25 18:47:31 +0100356 vcpu->arch.local_int.cpuflags = &vcpu->arch.sie_block->cpuflags;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200357 spin_unlock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100358
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100359 rc = kvm_vcpu_init(vcpu, kvm, id);
360 if (rc)
Wei Yongjun7b06bf22010-03-09 14:37:53 +0800361 goto out_free_sie_block;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100362 VM_EVENT(kvm, 3, "create cpu %d at %p, sie block at %p", id, vcpu,
363 vcpu->arch.sie_block);
364
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100365 return vcpu;
Wei Yongjun7b06bf22010-03-09 14:37:53 +0800366out_free_sie_block:
367 free_page((unsigned long)(vcpu->arch.sie_block));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100368out_free_cpu:
369 kfree(vcpu);
Carsten Otte4d475552011-10-18 12:27:12 +0200370out:
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100371 return ERR_PTR(rc);
372}
373
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100374int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
375{
376 /* kvm common code refers to this, but never calls it */
377 BUG();
378 return 0;
379}
380
381static int kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu)
382{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100383 kvm_s390_vcpu_initial_reset(vcpu);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100384 return 0;
385}
386
387int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
388{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100389 memcpy(&vcpu->arch.guest_gprs, &regs->gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100390 return 0;
391}
392
393int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
394{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100395 memcpy(&regs->gprs, &vcpu->arch.guest_gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100396 return 0;
397}
398
399int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
400 struct kvm_sregs *sregs)
401{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100402 memcpy(&vcpu->arch.guest_acrs, &sregs->acrs, sizeof(sregs->acrs));
403 memcpy(&vcpu->arch.sie_block->gcr, &sregs->crs, sizeof(sregs->crs));
Carsten Otte7eef87d2011-10-18 12:27:14 +0200404 restore_access_regs(vcpu->arch.guest_acrs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100405 return 0;
406}
407
408int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
409 struct kvm_sregs *sregs)
410{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100411 memcpy(&sregs->acrs, &vcpu->arch.guest_acrs, sizeof(sregs->acrs));
412 memcpy(&sregs->crs, &vcpu->arch.sie_block->gcr, sizeof(sregs->crs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100413 return 0;
414}
415
416int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
417{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100418 memcpy(&vcpu->arch.guest_fpregs.fprs, &fpu->fprs, sizeof(fpu->fprs));
419 vcpu->arch.guest_fpregs.fpc = fpu->fpc;
Carsten Otte7eef87d2011-10-18 12:27:14 +0200420 restore_fp_regs(&vcpu->arch.guest_fpregs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100421 return 0;
422}
423
424int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
425{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100426 memcpy(&fpu->fprs, &vcpu->arch.guest_fpregs.fprs, sizeof(fpu->fprs));
427 fpu->fpc = vcpu->arch.guest_fpregs.fpc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100428 return 0;
429}
430
431static int kvm_arch_vcpu_ioctl_set_initial_psw(struct kvm_vcpu *vcpu, psw_t psw)
432{
433 int rc = 0;
434
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100435 if (!(atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_STOPPED))
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100436 rc = -EBUSY;
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100437 else {
438 vcpu->run->psw_mask = psw.mask;
439 vcpu->run->psw_addr = psw.addr;
440 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100441 return rc;
442}
443
444int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
445 struct kvm_translation *tr)
446{
447 return -EINVAL; /* not implemented yet */
448}
449
Jan Kiszkad0bfb942008-12-15 13:52:10 +0100450int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
451 struct kvm_guest_debug *dbg)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100452{
453 return -EINVAL; /* not implemented yet */
454}
455
Marcelo Tosatti62d9f0d2008-04-11 13:24:45 -0300456int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
457 struct kvm_mp_state *mp_state)
458{
459 return -EINVAL; /* not implemented yet */
460}
461
462int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
463 struct kvm_mp_state *mp_state)
464{
465 return -EINVAL; /* not implemented yet */
466}
467
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100468static void __vcpu_run(struct kvm_vcpu *vcpu)
469{
470 memcpy(&vcpu->arch.sie_block->gg14, &vcpu->arch.guest_gprs[14], 16);
471
472 if (need_resched())
473 schedule();
474
Christian Borntraeger71cde582008-05-21 13:37:34 +0200475 if (test_thread_flag(TIF_MCCK_PENDING))
476 s390_handle_mcck();
477
Carsten Otte0ff31862008-05-21 13:37:37 +0200478 kvm_s390_deliver_pending_interrupts(vcpu);
479
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100480 vcpu->arch.sie_block->icptcode = 0;
481 local_irq_disable();
482 kvm_guest_enter();
483 local_irq_enable();
484 VCPU_EVENT(vcpu, 6, "entering sie flags %x",
485 atomic_read(&vcpu->arch.sie_block->cpuflags));
Carsten Otte1f0d0f02008-05-21 13:37:40 +0200486 if (sie64a(vcpu->arch.sie_block, vcpu->arch.guest_gprs)) {
487 VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction");
488 kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
489 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100490 VCPU_EVENT(vcpu, 6, "exit sie icptcode %d",
491 vcpu->arch.sie_block->icptcode);
492 local_irq_disable();
493 kvm_guest_exit();
494 local_irq_enable();
495
496 memcpy(&vcpu->arch.guest_gprs[14], &vcpu->arch.sie_block->gg14, 16);
497}
498
499int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
500{
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100501 int rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100502 sigset_t sigsaved;
503
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200504rerun_vcpu:
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100505 if (vcpu->sigset_active)
506 sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
507
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100508 atomic_clear_mask(CPUSTAT_STOPPED, &vcpu->arch.sie_block->cpuflags);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100509
Carsten Otteba5c1e92008-03-25 18:47:26 +0100510 BUG_ON(vcpu->kvm->arch.float_int.local_int[vcpu->vcpu_id] == NULL);
511
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100512 switch (kvm_run->exit_reason) {
513 case KVM_EXIT_S390_SIEIC:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100514 case KVM_EXIT_UNKNOWN:
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200515 case KVM_EXIT_INTR:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100516 case KVM_EXIT_S390_RESET:
517 break;
518 default:
519 BUG();
520 }
521
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100522 vcpu->arch.sie_block->gpsw.mask = kvm_run->psw_mask;
523 vcpu->arch.sie_block->gpsw.addr = kvm_run->psw_addr;
524
Heiko Carstensdab4079d2009-06-12 10:26:32 +0200525 might_fault();
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100526
527 do {
528 __vcpu_run(vcpu);
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100529 rc = kvm_handle_sie_intercept(vcpu);
530 } while (!signal_pending(current) && !rc);
531
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200532 if (rc == SIE_INTERCEPT_RERUNVCPU)
533 goto rerun_vcpu;
534
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200535 if (signal_pending(current) && !rc) {
536 kvm_run->exit_reason = KVM_EXIT_INTR;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100537 rc = -EINTR;
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200538 }
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100539
Heiko Carstensb8e660b2010-02-26 22:37:41 +0100540 if (rc == -EOPNOTSUPP) {
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100541 /* intercept cannot be handled in-kernel, prepare kvm-run */
542 kvm_run->exit_reason = KVM_EXIT_S390_SIEIC;
543 kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100544 kvm_run->s390_sieic.ipa = vcpu->arch.sie_block->ipa;
545 kvm_run->s390_sieic.ipb = vcpu->arch.sie_block->ipb;
546 rc = 0;
547 }
548
549 if (rc == -EREMOTE) {
550 /* intercept was handled, but userspace support is needed
551 * kvm_run has been prepared by the handler */
552 rc = 0;
553 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100554
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100555 kvm_run->psw_mask = vcpu->arch.sie_block->gpsw.mask;
556 kvm_run->psw_addr = vcpu->arch.sie_block->gpsw.addr;
557
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100558 if (vcpu->sigset_active)
559 sigprocmask(SIG_SETMASK, &sigsaved, NULL);
560
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100561 vcpu->stat.exit_userspace++;
Heiko Carstens7e8e6ab2008-04-04 15:12:35 +0200562 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100563}
564
Carsten Otte092670c2011-07-24 10:48:22 +0200565static int __guestcopy(struct kvm_vcpu *vcpu, u64 guestdest, void *from,
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100566 unsigned long n, int prefix)
567{
568 if (prefix)
569 return copy_to_guest(vcpu, guestdest, from, n);
570 else
571 return copy_to_guest_absolute(vcpu, guestdest, from, n);
572}
573
574/*
575 * store status at address
576 * we use have two special cases:
577 * KVM_S390_STORE_STATUS_NOADDR: -> 0x1200 on 64 bit
578 * KVM_S390_STORE_STATUS_PREFIXED: -> prefix
579 */
Christian Borntraeger971eb772010-06-12 08:54:13 +0200580int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100581{
Carsten Otte092670c2011-07-24 10:48:22 +0200582 unsigned char archmode = 1;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100583 int prefix;
584
585 if (addr == KVM_S390_STORE_STATUS_NOADDR) {
586 if (copy_to_guest_absolute(vcpu, 163ul, &archmode, 1))
587 return -EFAULT;
588 addr = SAVE_AREA_BASE;
589 prefix = 0;
590 } else if (addr == KVM_S390_STORE_STATUS_PREFIXED) {
591 if (copy_to_guest(vcpu, 163ul, &archmode, 1))
592 return -EFAULT;
593 addr = SAVE_AREA_BASE;
594 prefix = 1;
595 } else
596 prefix = 0;
597
Heiko Carstensf64ca212010-02-26 22:37:32 +0100598 if (__guestcopy(vcpu, addr + offsetof(struct save_area, fp_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100599 vcpu->arch.guest_fpregs.fprs, 128, prefix))
600 return -EFAULT;
601
Heiko Carstensf64ca212010-02-26 22:37:32 +0100602 if (__guestcopy(vcpu, addr + offsetof(struct save_area, gp_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100603 vcpu->arch.guest_gprs, 128, prefix))
604 return -EFAULT;
605
Heiko Carstensf64ca212010-02-26 22:37:32 +0100606 if (__guestcopy(vcpu, addr + offsetof(struct save_area, psw),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100607 &vcpu->arch.sie_block->gpsw, 16, prefix))
608 return -EFAULT;
609
Heiko Carstensf64ca212010-02-26 22:37:32 +0100610 if (__guestcopy(vcpu, addr + offsetof(struct save_area, pref_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100611 &vcpu->arch.sie_block->prefix, 4, prefix))
612 return -EFAULT;
613
614 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100615 addr + offsetof(struct save_area, fp_ctrl_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100616 &vcpu->arch.guest_fpregs.fpc, 4, prefix))
617 return -EFAULT;
618
Heiko Carstensf64ca212010-02-26 22:37:32 +0100619 if (__guestcopy(vcpu, addr + offsetof(struct save_area, tod_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100620 &vcpu->arch.sie_block->todpr, 4, prefix))
621 return -EFAULT;
622
Heiko Carstensf64ca212010-02-26 22:37:32 +0100623 if (__guestcopy(vcpu, addr + offsetof(struct save_area, timer),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100624 &vcpu->arch.sie_block->cputm, 8, prefix))
625 return -EFAULT;
626
Heiko Carstensf64ca212010-02-26 22:37:32 +0100627 if (__guestcopy(vcpu, addr + offsetof(struct save_area, clk_cmp),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100628 &vcpu->arch.sie_block->ckc, 8, prefix))
629 return -EFAULT;
630
Heiko Carstensf64ca212010-02-26 22:37:32 +0100631 if (__guestcopy(vcpu, addr + offsetof(struct save_area, acc_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100632 &vcpu->arch.guest_acrs, 64, prefix))
633 return -EFAULT;
634
635 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100636 addr + offsetof(struct save_area, ctrl_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100637 &vcpu->arch.sie_block->gcr, 128, prefix))
638 return -EFAULT;
639 return 0;
640}
641
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100642long kvm_arch_vcpu_ioctl(struct file *filp,
643 unsigned int ioctl, unsigned long arg)
644{
645 struct kvm_vcpu *vcpu = filp->private_data;
646 void __user *argp = (void __user *)arg;
Avi Kivitybc923cc2010-05-13 12:21:46 +0300647 long r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100648
Avi Kivity93736622010-05-13 12:35:17 +0300649 switch (ioctl) {
650 case KVM_S390_INTERRUPT: {
Carsten Otteba5c1e92008-03-25 18:47:26 +0100651 struct kvm_s390_interrupt s390int;
652
Avi Kivity93736622010-05-13 12:35:17 +0300653 r = -EFAULT;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100654 if (copy_from_user(&s390int, argp, sizeof(s390int)))
Avi Kivity93736622010-05-13 12:35:17 +0300655 break;
656 r = kvm_s390_inject_vcpu(vcpu, &s390int);
657 break;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100658 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100659 case KVM_S390_STORE_STATUS:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300660 r = kvm_s390_vcpu_store_status(vcpu, arg);
661 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100662 case KVM_S390_SET_INITIAL_PSW: {
663 psw_t psw;
664
Avi Kivitybc923cc2010-05-13 12:21:46 +0300665 r = -EFAULT;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100666 if (copy_from_user(&psw, argp, sizeof(psw)))
Avi Kivitybc923cc2010-05-13 12:21:46 +0300667 break;
668 r = kvm_arch_vcpu_ioctl_set_initial_psw(vcpu, psw);
669 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100670 }
671 case KVM_S390_INITIAL_RESET:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300672 r = kvm_arch_vcpu_ioctl_initial_reset(vcpu);
673 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100674 default:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300675 r = -EINVAL;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100676 }
Avi Kivitybc923cc2010-05-13 12:21:46 +0300677 return r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100678}
679
680/* Section: memory related */
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200681int kvm_arch_prepare_memory_region(struct kvm *kvm,
682 struct kvm_memory_slot *memslot,
683 struct kvm_memory_slot old,
684 struct kvm_userspace_memory_region *mem,
685 int user_alloc)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100686{
687 /* A few sanity checks. We can have exactly one memory slot which has
688 to start at guest virtual zero and which has to be located at a
689 page boundary in userland and which has to end at a page boundary.
690 The memory in userland is ok to be fragmented into various different
691 vmas. It is okay to mmap() and munmap() stuff in this slot after
692 doing this call at any time */
693
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200694 if (mem->slot)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100695 return -EINVAL;
696
697 if (mem->guest_phys_addr)
698 return -EINVAL;
699
Carsten Otte598841c2011-07-24 10:48:21 +0200700 if (mem->userspace_addr & 0xffffful)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100701 return -EINVAL;
702
Carsten Otte598841c2011-07-24 10:48:21 +0200703 if (mem->memory_size & 0xffffful)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100704 return -EINVAL;
705
Carsten Otte2668dab2009-05-12 17:21:48 +0200706 if (!user_alloc)
707 return -EINVAL;
708
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200709 return 0;
710}
711
712void kvm_arch_commit_memory_region(struct kvm *kvm,
713 struct kvm_userspace_memory_region *mem,
714 struct kvm_memory_slot old,
715 int user_alloc)
716{
Carsten Ottef7850c92011-07-24 10:48:23 +0200717 int rc;
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200718
Carsten Otte598841c2011-07-24 10:48:21 +0200719
720 rc = gmap_map_segment(kvm->arch.gmap, mem->userspace_addr,
721 mem->guest_phys_addr, mem->memory_size);
722 if (rc)
Carsten Ottef7850c92011-07-24 10:48:23 +0200723 printk(KERN_WARNING "kvm-s390: failed to commit memory region\n");
Carsten Otte598841c2011-07-24 10:48:21 +0200724 return;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100725}
726
Marcelo Tosatti34d4cb82008-07-10 20:49:31 -0300727void kvm_arch_flush_shadow(struct kvm *kvm)
728{
729}
730
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100731static int __init kvm_s390_init(void)
732{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200733 int ret;
Avi Kivity0ee75be2010-04-28 15:39:01 +0300734 ret = kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE);
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200735 if (ret)
736 return ret;
737
738 /*
739 * guests can ask for up to 255+1 double words, we need a full page
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300740 * to hold the maximum amount of facilities. On the other hand, we
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200741 * only set facilities that are known to work in KVM.
742 */
Heiko Carstensc2f0e8c2010-06-08 18:58:09 +0200743 facilities = (unsigned long long *) get_zeroed_page(GFP_KERNEL|GFP_DMA);
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200744 if (!facilities) {
745 kvm_exit();
746 return -ENOMEM;
747 }
Martin Schwidefsky14375bc2010-10-25 16:10:51 +0200748 memcpy(facilities, S390_lowcore.stfle_fac_list, 16);
Christian Borntraeger6d00d002010-10-25 16:10:48 +0200749 facilities[0] &= 0xff00fff3f47c0000ULL;
Christian Borntraeger9950f8b2011-06-06 14:14:39 +0200750 facilities[1] &= 0x201c000000000000ULL;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200751 return 0;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100752}
753
754static void __exit kvm_s390_exit(void)
755{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200756 free_page((unsigned long) facilities);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100757 kvm_exit();
758}
759
760module_init(kvm_s390_init);
761module_exit(kvm_s390_exit);