blob: 9610ba41b974310df032813e94bd1f870e18c1a0 [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 Borntraegere28acfe2008-03-25 18:47:34 +010074 { "diagnose_44", VCPU_STAT(diagnose_44) },
Heiko Carstensb0c632d2008-03-25 18:47:20 +010075 { NULL }
76};
77
Christian Borntraegeref50f7a2009-06-23 17:24:07 +020078static unsigned long long *facilities;
Heiko Carstensb0c632d2008-03-25 18:47:20 +010079
80/* Section: not file related */
Alexander Graf10474ae2009-09-15 11:37:46 +020081int kvm_arch_hardware_enable(void *garbage)
Heiko Carstensb0c632d2008-03-25 18:47:20 +010082{
83 /* every s390 is virtualization enabled ;-) */
Alexander Graf10474ae2009-09-15 11:37:46 +020084 return 0;
Heiko Carstensb0c632d2008-03-25 18:47:20 +010085}
86
87void kvm_arch_hardware_disable(void *garbage)
88{
89}
90
Heiko Carstensb0c632d2008-03-25 18:47:20 +010091int kvm_arch_hardware_setup(void)
92{
93 return 0;
94}
95
96void kvm_arch_hardware_unsetup(void)
97{
98}
99
100void kvm_arch_check_processor_compat(void *rtn)
101{
102}
103
104int kvm_arch_init(void *opaque)
105{
106 return 0;
107}
108
109void kvm_arch_exit(void)
110{
111}
112
113/* Section: device related */
114long kvm_arch_dev_ioctl(struct file *filp,
115 unsigned int ioctl, unsigned long arg)
116{
117 if (ioctl == KVM_S390_ENABLE_SIE)
118 return s390_enable_sie();
119 return -EINVAL;
120}
121
122int kvm_dev_ioctl_check_extension(long ext)
123{
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100124 int r;
125
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200126 switch (ext) {
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100127 case KVM_CAP_S390_PSW:
Christian Borntraegerb6cf8782011-09-20 17:07:29 +0200128 case KVM_CAP_S390_GMAP:
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100129 r = 1;
130 break;
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200131 default:
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100132 r = 0;
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200133 }
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100134 return r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100135}
136
137/* Section: vm related */
138/*
139 * Get (and clear) the dirty memory log for a memory slot.
140 */
141int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
142 struct kvm_dirty_log *log)
143{
144 return 0;
145}
146
147long kvm_arch_vm_ioctl(struct file *filp,
148 unsigned int ioctl, unsigned long arg)
149{
150 struct kvm *kvm = filp->private_data;
151 void __user *argp = (void __user *)arg;
152 int r;
153
154 switch (ioctl) {
Carsten Otteba5c1e92008-03-25 18:47:26 +0100155 case KVM_S390_INTERRUPT: {
156 struct kvm_s390_interrupt s390int;
157
158 r = -EFAULT;
159 if (copy_from_user(&s390int, argp, sizeof(s390int)))
160 break;
161 r = kvm_s390_inject_vm(kvm, &s390int);
162 break;
163 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100164 default:
Avi Kivity367e1312009-08-26 14:57:07 +0300165 r = -ENOTTY;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100166 }
167
168 return r;
169}
170
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100171int kvm_arch_init_vm(struct kvm *kvm)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100172{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100173 int rc;
174 char debug_name[16];
175
176 rc = s390_enable_sie();
177 if (rc)
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100178 goto out_err;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100179
Carsten Otteb2904112011-10-18 12:27:13 +0200180 rc = -ENOMEM;
181
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100182 kvm->arch.sca = (struct sca_block *) get_zeroed_page(GFP_KERNEL);
183 if (!kvm->arch.sca)
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100184 goto out_err;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100185
186 sprintf(debug_name, "kvm-%u", current->pid);
187
188 kvm->arch.dbf = debug_register(debug_name, 8, 2, 8 * sizeof(long));
189 if (!kvm->arch.dbf)
190 goto out_nodbf;
191
Carsten Otteba5c1e92008-03-25 18:47:26 +0100192 spin_lock_init(&kvm->arch.float_int.lock);
193 INIT_LIST_HEAD(&kvm->arch.float_int.list);
194
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100195 debug_register_view(kvm->arch.dbf, &debug_sprintf_view);
196 VM_EVENT(kvm, 3, "%s", "vm created");
197
Carsten Otte598841c2011-07-24 10:48:21 +0200198 kvm->arch.gmap = gmap_alloc(current->mm);
199 if (!kvm->arch.gmap)
200 goto out_nogmap;
201
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100202 return 0;
Carsten Otte598841c2011-07-24 10:48:21 +0200203out_nogmap:
204 debug_unregister(kvm->arch.dbf);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100205out_nodbf:
206 free_page((unsigned long)(kvm->arch.sca));
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100207out_err:
208 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100209}
210
Christian Borntraegerd329c032008-11-26 14:50:27 +0100211void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
212{
213 VCPU_EVENT(vcpu, 3, "%s", "free cpu");
Christian Borntraegerfc345312010-06-17 23:16:20 +0200214 clear_bit(63 - vcpu->vcpu_id, (unsigned long *) &vcpu->kvm->arch.sca->mcn);
Carsten Otteabf4a712009-05-12 17:21:51 +0200215 if (vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda ==
216 (__u64) vcpu->arch.sie_block)
217 vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda = 0;
218 smp_mb();
Christian Borntraegerd329c032008-11-26 14:50:27 +0100219 free_page((unsigned long)(vcpu->arch.sie_block));
Christian Borntraeger6692cef2008-11-26 14:51:08 +0100220 kvm_vcpu_uninit(vcpu);
Christian Borntraegerd329c032008-11-26 14:50:27 +0100221 kfree(vcpu);
222}
223
224static void kvm_free_vcpus(struct kvm *kvm)
225{
226 unsigned int i;
Gleb Natapov988a2ca2009-06-09 15:56:29 +0300227 struct kvm_vcpu *vcpu;
Christian Borntraegerd329c032008-11-26 14:50:27 +0100228
Gleb Natapov988a2ca2009-06-09 15:56:29 +0300229 kvm_for_each_vcpu(i, vcpu, kvm)
230 kvm_arch_vcpu_destroy(vcpu);
231
232 mutex_lock(&kvm->lock);
233 for (i = 0; i < atomic_read(&kvm->online_vcpus); i++)
234 kvm->vcpus[i] = NULL;
235
236 atomic_set(&kvm->online_vcpus, 0);
237 mutex_unlock(&kvm->lock);
Christian Borntraegerd329c032008-11-26 14:50:27 +0100238}
239
Sheng Yangad8ba2c2009-01-06 10:03:02 +0800240void kvm_arch_sync_events(struct kvm *kvm)
241{
242}
243
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100244void kvm_arch_destroy_vm(struct kvm *kvm)
245{
Christian Borntraegerd329c032008-11-26 14:50:27 +0100246 kvm_free_vcpus(kvm);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100247 free_page((unsigned long)(kvm->arch.sca));
Christian Borntraegerd329c032008-11-26 14:50:27 +0100248 debug_unregister(kvm->arch.dbf);
Carsten Otte598841c2011-07-24 10:48:21 +0200249 gmap_free(kvm->arch.gmap);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100250}
251
252/* Section: vcpu related */
253int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
254{
Carsten Otte598841c2011-07-24 10:48:21 +0200255 vcpu->arch.gmap = vcpu->kvm->arch.gmap;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100256 return 0;
257}
258
259void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
260{
Christian Borntraeger6692cef2008-11-26 14:51:08 +0100261 /* Nothing todo */
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100262}
263
264void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
265{
266 save_fp_regs(&vcpu->arch.host_fpregs);
267 save_access_regs(vcpu->arch.host_acrs);
268 vcpu->arch.guest_fpregs.fpc &= FPC_VALID_MASK;
269 restore_fp_regs(&vcpu->arch.guest_fpregs);
270 restore_access_regs(vcpu->arch.guest_acrs);
Christian Borntraeger480e5922011-09-20 17:07:28 +0200271 gmap_enable(vcpu->arch.gmap);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100272}
273
274void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
275{
Christian Borntraeger480e5922011-09-20 17:07:28 +0200276 gmap_disable(vcpu->arch.gmap);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100277 save_fp_regs(&vcpu->arch.guest_fpregs);
278 save_access_regs(vcpu->arch.guest_acrs);
279 restore_fp_regs(&vcpu->arch.host_fpregs);
280 restore_access_regs(vcpu->arch.host_acrs);
281}
282
283static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu)
284{
285 /* this equals initial cpu reset in pop, but we don't switch to ESA */
286 vcpu->arch.sie_block->gpsw.mask = 0UL;
287 vcpu->arch.sie_block->gpsw.addr = 0UL;
288 vcpu->arch.sie_block->prefix = 0UL;
289 vcpu->arch.sie_block->ihcpu = 0xffff;
290 vcpu->arch.sie_block->cputm = 0UL;
291 vcpu->arch.sie_block->ckc = 0UL;
292 vcpu->arch.sie_block->todpr = 0;
293 memset(vcpu->arch.sie_block->gcr, 0, 16 * sizeof(__u64));
294 vcpu->arch.sie_block->gcr[0] = 0xE0UL;
295 vcpu->arch.sie_block->gcr[14] = 0xC2000000UL;
296 vcpu->arch.guest_fpregs.fpc = 0;
297 asm volatile("lfpc %0" : : "Q" (vcpu->arch.guest_fpregs.fpc));
298 vcpu->arch.sie_block->gbea = 1;
299}
300
301int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
302{
Carsten Otte598841c2011-07-24 10:48:21 +0200303 atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH | CPUSTAT_SM);
Christian Borntraegerfc345312010-06-17 23:16:20 +0200304 vcpu->arch.sie_block->ecb = 6;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100305 vcpu->arch.sie_block->eca = 0xC1002001U;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200306 vcpu->arch.sie_block->fac = (int) (long) facilities;
Christian Borntraegerca872302009-05-12 17:21:49 +0200307 hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
308 tasklet_init(&vcpu->arch.tasklet, kvm_s390_tasklet,
309 (unsigned long) vcpu);
310 vcpu->arch.ckc_timer.function = kvm_s390_idle_wakeup;
Christian Borntraeger453423d2008-03-25 18:47:29 +0100311 get_cpu_id(&vcpu->arch.cpu_id);
Christian Borntraeger92e6ecf2009-03-26 15:23:58 +0100312 vcpu->arch.cpu_id.version = 0xff;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100313 return 0;
314}
315
316struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
317 unsigned int id)
318{
Carsten Otte4d475552011-10-18 12:27:12 +0200319 struct kvm_vcpu *vcpu;
320 int rc = -EINVAL;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100321
Carsten Otte4d475552011-10-18 12:27:12 +0200322 if (id >= KVM_MAX_VCPUS)
323 goto out;
324
325 rc = -ENOMEM;
326
327 vcpu = kzalloc(sizeof(struct kvm_vcpu), GFP_KERNEL);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100328 if (!vcpu)
Carsten Otte4d475552011-10-18 12:27:12 +0200329 goto out;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100330
Christian Borntraeger180c12f2008-06-27 15:05:40 +0200331 vcpu->arch.sie_block = (struct kvm_s390_sie_block *)
332 get_zeroed_page(GFP_KERNEL);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100333
334 if (!vcpu->arch.sie_block)
335 goto out_free_cpu;
336
337 vcpu->arch.sie_block->icpua = id;
338 BUG_ON(!kvm->arch.sca);
Carsten Otteabf4a712009-05-12 17:21:51 +0200339 if (!kvm->arch.sca->cpu[id].sda)
340 kvm->arch.sca->cpu[id].sda = (__u64) vcpu->arch.sie_block;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100341 vcpu->arch.sie_block->scaoh = (__u32)(((__u64)kvm->arch.sca) >> 32);
342 vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca;
Christian Borntraegerfc345312010-06-17 23:16:20 +0200343 set_bit(63 - id, (unsigned long *) &kvm->arch.sca->mcn);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100344
Carsten Otteba5c1e92008-03-25 18:47:26 +0100345 spin_lock_init(&vcpu->arch.local_int.lock);
346 INIT_LIST_HEAD(&vcpu->arch.local_int.list);
347 vcpu->arch.local_int.float_int = &kvm->arch.float_int;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200348 spin_lock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100349 kvm->arch.float_int.local_int[id] = &vcpu->arch.local_int;
350 init_waitqueue_head(&vcpu->arch.local_int.wq);
Christian Borntraeger5288fbf2008-03-25 18:47:31 +0100351 vcpu->arch.local_int.cpuflags = &vcpu->arch.sie_block->cpuflags;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200352 spin_unlock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100353
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100354 rc = kvm_vcpu_init(vcpu, kvm, id);
355 if (rc)
Wei Yongjun7b06bf22010-03-09 14:37:53 +0800356 goto out_free_sie_block;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100357 VM_EVENT(kvm, 3, "create cpu %d at %p, sie block at %p", id, vcpu,
358 vcpu->arch.sie_block);
359
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100360 return vcpu;
Wei Yongjun7b06bf22010-03-09 14:37:53 +0800361out_free_sie_block:
362 free_page((unsigned long)(vcpu->arch.sie_block));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100363out_free_cpu:
364 kfree(vcpu);
Carsten Otte4d475552011-10-18 12:27:12 +0200365out:
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100366 return ERR_PTR(rc);
367}
368
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100369int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
370{
371 /* kvm common code refers to this, but never calls it */
372 BUG();
373 return 0;
374}
375
376static int kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu)
377{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100378 kvm_s390_vcpu_initial_reset(vcpu);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100379 return 0;
380}
381
382int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
383{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100384 memcpy(&vcpu->arch.guest_gprs, &regs->gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100385 return 0;
386}
387
388int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
389{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100390 memcpy(&regs->gprs, &vcpu->arch.guest_gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100391 return 0;
392}
393
394int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
395 struct kvm_sregs *sregs)
396{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100397 memcpy(&vcpu->arch.guest_acrs, &sregs->acrs, sizeof(sregs->acrs));
398 memcpy(&vcpu->arch.sie_block->gcr, &sregs->crs, sizeof(sregs->crs));
Carsten Otte7eef87d2011-10-18 12:27:14 +0200399 restore_access_regs(vcpu->arch.guest_acrs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100400 return 0;
401}
402
403int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
404 struct kvm_sregs *sregs)
405{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100406 memcpy(&sregs->acrs, &vcpu->arch.guest_acrs, sizeof(sregs->acrs));
407 memcpy(&sregs->crs, &vcpu->arch.sie_block->gcr, sizeof(sregs->crs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100408 return 0;
409}
410
411int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
412{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100413 memcpy(&vcpu->arch.guest_fpregs.fprs, &fpu->fprs, sizeof(fpu->fprs));
414 vcpu->arch.guest_fpregs.fpc = fpu->fpc;
Carsten Otte7eef87d2011-10-18 12:27:14 +0200415 restore_fp_regs(&vcpu->arch.guest_fpregs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100416 return 0;
417}
418
419int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
420{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100421 memcpy(&fpu->fprs, &vcpu->arch.guest_fpregs.fprs, sizeof(fpu->fprs));
422 fpu->fpc = vcpu->arch.guest_fpregs.fpc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100423 return 0;
424}
425
426static int kvm_arch_vcpu_ioctl_set_initial_psw(struct kvm_vcpu *vcpu, psw_t psw)
427{
428 int rc = 0;
429
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100430 if (atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_RUNNING)
431 rc = -EBUSY;
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100432 else {
433 vcpu->run->psw_mask = psw.mask;
434 vcpu->run->psw_addr = psw.addr;
435 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100436 return rc;
437}
438
439int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
440 struct kvm_translation *tr)
441{
442 return -EINVAL; /* not implemented yet */
443}
444
Jan Kiszkad0bfb942008-12-15 13:52:10 +0100445int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
446 struct kvm_guest_debug *dbg)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100447{
448 return -EINVAL; /* not implemented yet */
449}
450
Marcelo Tosatti62d9f0d2008-04-11 13:24:45 -0300451int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
452 struct kvm_mp_state *mp_state)
453{
454 return -EINVAL; /* not implemented yet */
455}
456
457int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
458 struct kvm_mp_state *mp_state)
459{
460 return -EINVAL; /* not implemented yet */
461}
462
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100463static void __vcpu_run(struct kvm_vcpu *vcpu)
464{
465 memcpy(&vcpu->arch.sie_block->gg14, &vcpu->arch.guest_gprs[14], 16);
466
467 if (need_resched())
468 schedule();
469
Christian Borntraeger71cde582008-05-21 13:37:34 +0200470 if (test_thread_flag(TIF_MCCK_PENDING))
471 s390_handle_mcck();
472
Carsten Otte0ff31862008-05-21 13:37:37 +0200473 kvm_s390_deliver_pending_interrupts(vcpu);
474
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100475 vcpu->arch.sie_block->icptcode = 0;
476 local_irq_disable();
477 kvm_guest_enter();
478 local_irq_enable();
479 VCPU_EVENT(vcpu, 6, "entering sie flags %x",
480 atomic_read(&vcpu->arch.sie_block->cpuflags));
Carsten Otte1f0d0f02008-05-21 13:37:40 +0200481 if (sie64a(vcpu->arch.sie_block, vcpu->arch.guest_gprs)) {
482 VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction");
483 kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
484 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100485 VCPU_EVENT(vcpu, 6, "exit sie icptcode %d",
486 vcpu->arch.sie_block->icptcode);
487 local_irq_disable();
488 kvm_guest_exit();
489 local_irq_enable();
490
491 memcpy(&vcpu->arch.guest_gprs[14], &vcpu->arch.sie_block->gg14, 16);
492}
493
494int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
495{
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100496 int rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100497 sigset_t sigsaved;
498
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200499rerun_vcpu:
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100500 if (vcpu->sigset_active)
501 sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
502
503 atomic_set_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
504
Carsten Otteba5c1e92008-03-25 18:47:26 +0100505 BUG_ON(vcpu->kvm->arch.float_int.local_int[vcpu->vcpu_id] == NULL);
506
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100507 switch (kvm_run->exit_reason) {
508 case KVM_EXIT_S390_SIEIC:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100509 case KVM_EXIT_UNKNOWN:
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200510 case KVM_EXIT_INTR:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100511 case KVM_EXIT_S390_RESET:
512 break;
513 default:
514 BUG();
515 }
516
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100517 vcpu->arch.sie_block->gpsw.mask = kvm_run->psw_mask;
518 vcpu->arch.sie_block->gpsw.addr = kvm_run->psw_addr;
519
Heiko Carstensdab4079d2009-06-12 10:26:32 +0200520 might_fault();
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100521
522 do {
523 __vcpu_run(vcpu);
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100524 rc = kvm_handle_sie_intercept(vcpu);
525 } while (!signal_pending(current) && !rc);
526
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200527 if (rc == SIE_INTERCEPT_RERUNVCPU)
528 goto rerun_vcpu;
529
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200530 if (signal_pending(current) && !rc) {
531 kvm_run->exit_reason = KVM_EXIT_INTR;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100532 rc = -EINTR;
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200533 }
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100534
Heiko Carstensb8e660b2010-02-26 22:37:41 +0100535 if (rc == -EOPNOTSUPP) {
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100536 /* intercept cannot be handled in-kernel, prepare kvm-run */
537 kvm_run->exit_reason = KVM_EXIT_S390_SIEIC;
538 kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100539 kvm_run->s390_sieic.ipa = vcpu->arch.sie_block->ipa;
540 kvm_run->s390_sieic.ipb = vcpu->arch.sie_block->ipb;
541 rc = 0;
542 }
543
544 if (rc == -EREMOTE) {
545 /* intercept was handled, but userspace support is needed
546 * kvm_run has been prepared by the handler */
547 rc = 0;
548 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100549
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100550 kvm_run->psw_mask = vcpu->arch.sie_block->gpsw.mask;
551 kvm_run->psw_addr = vcpu->arch.sie_block->gpsw.addr;
552
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100553 if (vcpu->sigset_active)
554 sigprocmask(SIG_SETMASK, &sigsaved, NULL);
555
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100556 vcpu->stat.exit_userspace++;
Heiko Carstens7e8e6ab2008-04-04 15:12:35 +0200557 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100558}
559
Carsten Otte092670c2011-07-24 10:48:22 +0200560static int __guestcopy(struct kvm_vcpu *vcpu, u64 guestdest, void *from,
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100561 unsigned long n, int prefix)
562{
563 if (prefix)
564 return copy_to_guest(vcpu, guestdest, from, n);
565 else
566 return copy_to_guest_absolute(vcpu, guestdest, from, n);
567}
568
569/*
570 * store status at address
571 * we use have two special cases:
572 * KVM_S390_STORE_STATUS_NOADDR: -> 0x1200 on 64 bit
573 * KVM_S390_STORE_STATUS_PREFIXED: -> prefix
574 */
Christian Borntraeger971eb772010-06-12 08:54:13 +0200575int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100576{
Carsten Otte092670c2011-07-24 10:48:22 +0200577 unsigned char archmode = 1;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100578 int prefix;
579
580 if (addr == KVM_S390_STORE_STATUS_NOADDR) {
581 if (copy_to_guest_absolute(vcpu, 163ul, &archmode, 1))
582 return -EFAULT;
583 addr = SAVE_AREA_BASE;
584 prefix = 0;
585 } else if (addr == KVM_S390_STORE_STATUS_PREFIXED) {
586 if (copy_to_guest(vcpu, 163ul, &archmode, 1))
587 return -EFAULT;
588 addr = SAVE_AREA_BASE;
589 prefix = 1;
590 } else
591 prefix = 0;
592
Heiko Carstensf64ca212010-02-26 22:37:32 +0100593 if (__guestcopy(vcpu, addr + offsetof(struct save_area, fp_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100594 vcpu->arch.guest_fpregs.fprs, 128, prefix))
595 return -EFAULT;
596
Heiko Carstensf64ca212010-02-26 22:37:32 +0100597 if (__guestcopy(vcpu, addr + offsetof(struct save_area, gp_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100598 vcpu->arch.guest_gprs, 128, prefix))
599 return -EFAULT;
600
Heiko Carstensf64ca212010-02-26 22:37:32 +0100601 if (__guestcopy(vcpu, addr + offsetof(struct save_area, psw),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100602 &vcpu->arch.sie_block->gpsw, 16, prefix))
603 return -EFAULT;
604
Heiko Carstensf64ca212010-02-26 22:37:32 +0100605 if (__guestcopy(vcpu, addr + offsetof(struct save_area, pref_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100606 &vcpu->arch.sie_block->prefix, 4, prefix))
607 return -EFAULT;
608
609 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100610 addr + offsetof(struct save_area, fp_ctrl_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100611 &vcpu->arch.guest_fpregs.fpc, 4, prefix))
612 return -EFAULT;
613
Heiko Carstensf64ca212010-02-26 22:37:32 +0100614 if (__guestcopy(vcpu, addr + offsetof(struct save_area, tod_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100615 &vcpu->arch.sie_block->todpr, 4, prefix))
616 return -EFAULT;
617
Heiko Carstensf64ca212010-02-26 22:37:32 +0100618 if (__guestcopy(vcpu, addr + offsetof(struct save_area, timer),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100619 &vcpu->arch.sie_block->cputm, 8, prefix))
620 return -EFAULT;
621
Heiko Carstensf64ca212010-02-26 22:37:32 +0100622 if (__guestcopy(vcpu, addr + offsetof(struct save_area, clk_cmp),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100623 &vcpu->arch.sie_block->ckc, 8, prefix))
624 return -EFAULT;
625
Heiko Carstensf64ca212010-02-26 22:37:32 +0100626 if (__guestcopy(vcpu, addr + offsetof(struct save_area, acc_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100627 &vcpu->arch.guest_acrs, 64, prefix))
628 return -EFAULT;
629
630 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100631 addr + offsetof(struct save_area, ctrl_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100632 &vcpu->arch.sie_block->gcr, 128, prefix))
633 return -EFAULT;
634 return 0;
635}
636
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100637long kvm_arch_vcpu_ioctl(struct file *filp,
638 unsigned int ioctl, unsigned long arg)
639{
640 struct kvm_vcpu *vcpu = filp->private_data;
641 void __user *argp = (void __user *)arg;
Avi Kivitybc923cc2010-05-13 12:21:46 +0300642 long r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100643
Avi Kivity93736622010-05-13 12:35:17 +0300644 switch (ioctl) {
645 case KVM_S390_INTERRUPT: {
Carsten Otteba5c1e92008-03-25 18:47:26 +0100646 struct kvm_s390_interrupt s390int;
647
Avi Kivity93736622010-05-13 12:35:17 +0300648 r = -EFAULT;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100649 if (copy_from_user(&s390int, argp, sizeof(s390int)))
Avi Kivity93736622010-05-13 12:35:17 +0300650 break;
651 r = kvm_s390_inject_vcpu(vcpu, &s390int);
652 break;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100653 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100654 case KVM_S390_STORE_STATUS:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300655 r = kvm_s390_vcpu_store_status(vcpu, arg);
656 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100657 case KVM_S390_SET_INITIAL_PSW: {
658 psw_t psw;
659
Avi Kivitybc923cc2010-05-13 12:21:46 +0300660 r = -EFAULT;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100661 if (copy_from_user(&psw, argp, sizeof(psw)))
Avi Kivitybc923cc2010-05-13 12:21:46 +0300662 break;
663 r = kvm_arch_vcpu_ioctl_set_initial_psw(vcpu, psw);
664 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100665 }
666 case KVM_S390_INITIAL_RESET:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300667 r = kvm_arch_vcpu_ioctl_initial_reset(vcpu);
668 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100669 default:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300670 r = -EINVAL;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100671 }
Avi Kivitybc923cc2010-05-13 12:21:46 +0300672 return r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100673}
674
675/* Section: memory related */
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200676int kvm_arch_prepare_memory_region(struct kvm *kvm,
677 struct kvm_memory_slot *memslot,
678 struct kvm_memory_slot old,
679 struct kvm_userspace_memory_region *mem,
680 int user_alloc)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100681{
682 /* A few sanity checks. We can have exactly one memory slot which has
683 to start at guest virtual zero and which has to be located at a
684 page boundary in userland and which has to end at a page boundary.
685 The memory in userland is ok to be fragmented into various different
686 vmas. It is okay to mmap() and munmap() stuff in this slot after
687 doing this call at any time */
688
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200689 if (mem->slot)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100690 return -EINVAL;
691
692 if (mem->guest_phys_addr)
693 return -EINVAL;
694
Carsten Otte598841c2011-07-24 10:48:21 +0200695 if (mem->userspace_addr & 0xffffful)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100696 return -EINVAL;
697
Carsten Otte598841c2011-07-24 10:48:21 +0200698 if (mem->memory_size & 0xffffful)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100699 return -EINVAL;
700
Carsten Otte2668dab2009-05-12 17:21:48 +0200701 if (!user_alloc)
702 return -EINVAL;
703
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200704 return 0;
705}
706
707void kvm_arch_commit_memory_region(struct kvm *kvm,
708 struct kvm_userspace_memory_region *mem,
709 struct kvm_memory_slot old,
710 int user_alloc)
711{
Carsten Ottef7850c92011-07-24 10:48:23 +0200712 int rc;
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200713
Carsten Otte598841c2011-07-24 10:48:21 +0200714
715 rc = gmap_map_segment(kvm->arch.gmap, mem->userspace_addr,
716 mem->guest_phys_addr, mem->memory_size);
717 if (rc)
Carsten Ottef7850c92011-07-24 10:48:23 +0200718 printk(KERN_WARNING "kvm-s390: failed to commit memory region\n");
Carsten Otte598841c2011-07-24 10:48:21 +0200719 return;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100720}
721
Marcelo Tosatti34d4cb82008-07-10 20:49:31 -0300722void kvm_arch_flush_shadow(struct kvm *kvm)
723{
724}
725
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100726static int __init kvm_s390_init(void)
727{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200728 int ret;
Avi Kivity0ee75be2010-04-28 15:39:01 +0300729 ret = kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE);
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200730 if (ret)
731 return ret;
732
733 /*
734 * guests can ask for up to 255+1 double words, we need a full page
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300735 * to hold the maximum amount of facilities. On the other hand, we
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200736 * only set facilities that are known to work in KVM.
737 */
Heiko Carstensc2f0e8c2010-06-08 18:58:09 +0200738 facilities = (unsigned long long *) get_zeroed_page(GFP_KERNEL|GFP_DMA);
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200739 if (!facilities) {
740 kvm_exit();
741 return -ENOMEM;
742 }
Martin Schwidefsky14375bc2010-10-25 16:10:51 +0200743 memcpy(facilities, S390_lowcore.stfle_fac_list, 16);
Christian Borntraeger6d00d002010-10-25 16:10:48 +0200744 facilities[0] &= 0xff00fff3f47c0000ULL;
Christian Borntraeger9950f8b2011-06-06 14:14:39 +0200745 facilities[1] &= 0x201c000000000000ULL;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200746 return 0;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100747}
748
749static void __exit kvm_s390_exit(void)
750{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200751 free_page((unsigned long) facilities);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100752 kvm_exit();
753}
754
755module_init(kvm_s390_init);
756module_exit(kvm_s390_exit);