blob: 5a99f342fd0b67418b36c6a4cd174b6006303255 [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) },
49 { "deliver_service_signal", VCPU_STAT(deliver_service_signal) },
50 { "deliver_virtio_interrupt", VCPU_STAT(deliver_virtio_interrupt) },
51 { "deliver_stop_signal", VCPU_STAT(deliver_stop_signal) },
52 { "deliver_prefix_signal", VCPU_STAT(deliver_prefix_signal) },
53 { "deliver_restart_signal", VCPU_STAT(deliver_restart_signal) },
54 { "deliver_program_interruption", VCPU_STAT(deliver_program_int) },
55 { "exit_wait_state", VCPU_STAT(exit_wait_state) },
Christian Borntraeger453423d2008-03-25 18:47:29 +010056 { "instruction_stidp", VCPU_STAT(instruction_stidp) },
57 { "instruction_spx", VCPU_STAT(instruction_spx) },
58 { "instruction_stpx", VCPU_STAT(instruction_stpx) },
59 { "instruction_stap", VCPU_STAT(instruction_stap) },
60 { "instruction_storage_key", VCPU_STAT(instruction_storage_key) },
61 { "instruction_stsch", VCPU_STAT(instruction_stsch) },
62 { "instruction_chsc", VCPU_STAT(instruction_chsc) },
63 { "instruction_stsi", VCPU_STAT(instruction_stsi) },
64 { "instruction_stfl", VCPU_STAT(instruction_stfl) },
Christian Borntraegerbb25b9b2011-07-24 10:48:17 +020065 { "instruction_tprot", VCPU_STAT(instruction_tprot) },
Christian Borntraeger5288fbf2008-03-25 18:47:31 +010066 { "instruction_sigp_sense", VCPU_STAT(instruction_sigp_sense) },
67 { "instruction_sigp_emergency", VCPU_STAT(instruction_sigp_emergency) },
68 { "instruction_sigp_stop", VCPU_STAT(instruction_sigp_stop) },
69 { "instruction_sigp_set_arch", VCPU_STAT(instruction_sigp_arch) },
70 { "instruction_sigp_set_prefix", VCPU_STAT(instruction_sigp_prefix) },
71 { "instruction_sigp_restart", VCPU_STAT(instruction_sigp_restart) },
Christian Borntraegere28acfe2008-03-25 18:47:34 +010072 { "diagnose_44", VCPU_STAT(diagnose_44) },
Heiko Carstensb0c632d2008-03-25 18:47:20 +010073 { NULL }
74};
75
Christian Borntraegeref50f7a2009-06-23 17:24:07 +020076static unsigned long long *facilities;
Heiko Carstensb0c632d2008-03-25 18:47:20 +010077
78/* Section: not file related */
Alexander Graf10474ae2009-09-15 11:37:46 +020079int kvm_arch_hardware_enable(void *garbage)
Heiko Carstensb0c632d2008-03-25 18:47:20 +010080{
81 /* every s390 is virtualization enabled ;-) */
Alexander Graf10474ae2009-09-15 11:37:46 +020082 return 0;
Heiko Carstensb0c632d2008-03-25 18:47:20 +010083}
84
85void kvm_arch_hardware_disable(void *garbage)
86{
87}
88
Heiko Carstensb0c632d2008-03-25 18:47:20 +010089int kvm_arch_hardware_setup(void)
90{
91 return 0;
92}
93
94void kvm_arch_hardware_unsetup(void)
95{
96}
97
98void kvm_arch_check_processor_compat(void *rtn)
99{
100}
101
102int kvm_arch_init(void *opaque)
103{
104 return 0;
105}
106
107void kvm_arch_exit(void)
108{
109}
110
111/* Section: device related */
112long kvm_arch_dev_ioctl(struct file *filp,
113 unsigned int ioctl, unsigned long arg)
114{
115 if (ioctl == KVM_S390_ENABLE_SIE)
116 return s390_enable_sie();
117 return -EINVAL;
118}
119
120int kvm_dev_ioctl_check_extension(long ext)
121{
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100122 int r;
123
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200124 switch (ext) {
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100125 case KVM_CAP_S390_PSW:
126 r = 1;
127 break;
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200128 default:
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100129 r = 0;
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200130 }
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100131 return r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100132}
133
134/* Section: vm related */
135/*
136 * Get (and clear) the dirty memory log for a memory slot.
137 */
138int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
139 struct kvm_dirty_log *log)
140{
141 return 0;
142}
143
144long kvm_arch_vm_ioctl(struct file *filp,
145 unsigned int ioctl, unsigned long arg)
146{
147 struct kvm *kvm = filp->private_data;
148 void __user *argp = (void __user *)arg;
149 int r;
150
151 switch (ioctl) {
Carsten Otteba5c1e92008-03-25 18:47:26 +0100152 case KVM_S390_INTERRUPT: {
153 struct kvm_s390_interrupt s390int;
154
155 r = -EFAULT;
156 if (copy_from_user(&s390int, argp, sizeof(s390int)))
157 break;
158 r = kvm_s390_inject_vm(kvm, &s390int);
159 break;
160 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100161 default:
Avi Kivity367e1312009-08-26 14:57:07 +0300162 r = -ENOTTY;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100163 }
164
165 return r;
166}
167
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100168int kvm_arch_init_vm(struct kvm *kvm)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100169{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100170 int rc;
171 char debug_name[16];
172
173 rc = s390_enable_sie();
174 if (rc)
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100175 goto out_err;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100176
177 kvm->arch.sca = (struct sca_block *) get_zeroed_page(GFP_KERNEL);
178 if (!kvm->arch.sca)
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100179 goto out_err;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100180
181 sprintf(debug_name, "kvm-%u", current->pid);
182
183 kvm->arch.dbf = debug_register(debug_name, 8, 2, 8 * sizeof(long));
184 if (!kvm->arch.dbf)
185 goto out_nodbf;
186
Carsten Otteba5c1e92008-03-25 18:47:26 +0100187 spin_lock_init(&kvm->arch.float_int.lock);
188 INIT_LIST_HEAD(&kvm->arch.float_int.list);
189
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100190 debug_register_view(kvm->arch.dbf, &debug_sprintf_view);
191 VM_EVENT(kvm, 3, "%s", "vm created");
192
Carsten Otte598841c2011-07-24 10:48:21 +0200193 kvm->arch.gmap = gmap_alloc(current->mm);
194 if (!kvm->arch.gmap)
195 goto out_nogmap;
196
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100197 return 0;
Carsten Otte598841c2011-07-24 10:48:21 +0200198out_nogmap:
199 debug_unregister(kvm->arch.dbf);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100200out_nodbf:
201 free_page((unsigned long)(kvm->arch.sca));
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100202out_err:
203 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100204}
205
Christian Borntraegerd329c032008-11-26 14:50:27 +0100206void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
207{
208 VCPU_EVENT(vcpu, 3, "%s", "free cpu");
Christian Borntraegerfc345312010-06-17 23:16:20 +0200209 clear_bit(63 - vcpu->vcpu_id, (unsigned long *) &vcpu->kvm->arch.sca->mcn);
Carsten Otteabf4a712009-05-12 17:21:51 +0200210 if (vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda ==
211 (__u64) vcpu->arch.sie_block)
212 vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda = 0;
213 smp_mb();
Christian Borntraegerd329c032008-11-26 14:50:27 +0100214 free_page((unsigned long)(vcpu->arch.sie_block));
Christian Borntraeger6692cef2008-11-26 14:51:08 +0100215 kvm_vcpu_uninit(vcpu);
Christian Borntraegerd329c032008-11-26 14:50:27 +0100216 kfree(vcpu);
217}
218
219static void kvm_free_vcpus(struct kvm *kvm)
220{
221 unsigned int i;
Gleb Natapov988a2ca2009-06-09 15:56:29 +0300222 struct kvm_vcpu *vcpu;
Christian Borntraegerd329c032008-11-26 14:50:27 +0100223
Gleb Natapov988a2ca2009-06-09 15:56:29 +0300224 kvm_for_each_vcpu(i, vcpu, kvm)
225 kvm_arch_vcpu_destroy(vcpu);
226
227 mutex_lock(&kvm->lock);
228 for (i = 0; i < atomic_read(&kvm->online_vcpus); i++)
229 kvm->vcpus[i] = NULL;
230
231 atomic_set(&kvm->online_vcpus, 0);
232 mutex_unlock(&kvm->lock);
Christian Borntraegerd329c032008-11-26 14:50:27 +0100233}
234
Sheng Yangad8ba2c2009-01-06 10:03:02 +0800235void kvm_arch_sync_events(struct kvm *kvm)
236{
237}
238
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100239void kvm_arch_destroy_vm(struct kvm *kvm)
240{
Christian Borntraegerd329c032008-11-26 14:50:27 +0100241 kvm_free_vcpus(kvm);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100242 free_page((unsigned long)(kvm->arch.sca));
Christian Borntraegerd329c032008-11-26 14:50:27 +0100243 debug_unregister(kvm->arch.dbf);
Carsten Otte598841c2011-07-24 10:48:21 +0200244 gmap_free(kvm->arch.gmap);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100245}
246
247/* Section: vcpu related */
248int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
249{
Carsten Otte598841c2011-07-24 10:48:21 +0200250 vcpu->arch.gmap = vcpu->kvm->arch.gmap;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100251 return 0;
252}
253
254void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
255{
Christian Borntraeger6692cef2008-11-26 14:51:08 +0100256 /* Nothing todo */
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100257}
258
259void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
260{
261 save_fp_regs(&vcpu->arch.host_fpregs);
262 save_access_regs(vcpu->arch.host_acrs);
263 vcpu->arch.guest_fpregs.fpc &= FPC_VALID_MASK;
264 restore_fp_regs(&vcpu->arch.guest_fpregs);
265 restore_access_regs(vcpu->arch.guest_acrs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100266}
267
268void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
269{
270 save_fp_regs(&vcpu->arch.guest_fpregs);
271 save_access_regs(vcpu->arch.guest_acrs);
272 restore_fp_regs(&vcpu->arch.host_fpregs);
273 restore_access_regs(vcpu->arch.host_acrs);
274}
275
276static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu)
277{
278 /* this equals initial cpu reset in pop, but we don't switch to ESA */
279 vcpu->arch.sie_block->gpsw.mask = 0UL;
280 vcpu->arch.sie_block->gpsw.addr = 0UL;
281 vcpu->arch.sie_block->prefix = 0UL;
282 vcpu->arch.sie_block->ihcpu = 0xffff;
283 vcpu->arch.sie_block->cputm = 0UL;
284 vcpu->arch.sie_block->ckc = 0UL;
285 vcpu->arch.sie_block->todpr = 0;
286 memset(vcpu->arch.sie_block->gcr, 0, 16 * sizeof(__u64));
287 vcpu->arch.sie_block->gcr[0] = 0xE0UL;
288 vcpu->arch.sie_block->gcr[14] = 0xC2000000UL;
289 vcpu->arch.guest_fpregs.fpc = 0;
290 asm volatile("lfpc %0" : : "Q" (vcpu->arch.guest_fpregs.fpc));
291 vcpu->arch.sie_block->gbea = 1;
292}
293
294int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
295{
Carsten Otte598841c2011-07-24 10:48:21 +0200296 atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH | CPUSTAT_SM);
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200297 set_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests);
Christian Borntraegerfc345312010-06-17 23:16:20 +0200298 vcpu->arch.sie_block->ecb = 6;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100299 vcpu->arch.sie_block->eca = 0xC1002001U;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200300 vcpu->arch.sie_block->fac = (int) (long) facilities;
Christian Borntraegerca872302009-05-12 17:21:49 +0200301 hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
302 tasklet_init(&vcpu->arch.tasklet, kvm_s390_tasklet,
303 (unsigned long) vcpu);
304 vcpu->arch.ckc_timer.function = kvm_s390_idle_wakeup;
Christian Borntraeger453423d2008-03-25 18:47:29 +0100305 get_cpu_id(&vcpu->arch.cpu_id);
Christian Borntraeger92e6ecf2009-03-26 15:23:58 +0100306 vcpu->arch.cpu_id.version = 0xff;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100307 return 0;
308}
309
310struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
311 unsigned int id)
312{
313 struct kvm_vcpu *vcpu = kzalloc(sizeof(struct kvm_vcpu), GFP_KERNEL);
314 int rc = -ENOMEM;
315
316 if (!vcpu)
317 goto out_nomem;
318
Christian Borntraeger180c12f2008-06-27 15:05:40 +0200319 vcpu->arch.sie_block = (struct kvm_s390_sie_block *)
320 get_zeroed_page(GFP_KERNEL);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100321
322 if (!vcpu->arch.sie_block)
323 goto out_free_cpu;
324
325 vcpu->arch.sie_block->icpua = id;
326 BUG_ON(!kvm->arch.sca);
Carsten Otteabf4a712009-05-12 17:21:51 +0200327 if (!kvm->arch.sca->cpu[id].sda)
328 kvm->arch.sca->cpu[id].sda = (__u64) vcpu->arch.sie_block;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100329 vcpu->arch.sie_block->scaoh = (__u32)(((__u64)kvm->arch.sca) >> 32);
330 vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca;
Christian Borntraegerfc345312010-06-17 23:16:20 +0200331 set_bit(63 - id, (unsigned long *) &kvm->arch.sca->mcn);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100332
Carsten Otteba5c1e92008-03-25 18:47:26 +0100333 spin_lock_init(&vcpu->arch.local_int.lock);
334 INIT_LIST_HEAD(&vcpu->arch.local_int.list);
335 vcpu->arch.local_int.float_int = &kvm->arch.float_int;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200336 spin_lock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100337 kvm->arch.float_int.local_int[id] = &vcpu->arch.local_int;
338 init_waitqueue_head(&vcpu->arch.local_int.wq);
Christian Borntraeger5288fbf2008-03-25 18:47:31 +0100339 vcpu->arch.local_int.cpuflags = &vcpu->arch.sie_block->cpuflags;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200340 spin_unlock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100341
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100342 rc = kvm_vcpu_init(vcpu, kvm, id);
343 if (rc)
Wei Yongjun7b06bf22010-03-09 14:37:53 +0800344 goto out_free_sie_block;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100345 VM_EVENT(kvm, 3, "create cpu %d at %p, sie block at %p", id, vcpu,
346 vcpu->arch.sie_block);
347
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100348 return vcpu;
Wei Yongjun7b06bf22010-03-09 14:37:53 +0800349out_free_sie_block:
350 free_page((unsigned long)(vcpu->arch.sie_block));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100351out_free_cpu:
352 kfree(vcpu);
353out_nomem:
354 return ERR_PTR(rc);
355}
356
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100357int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
358{
359 /* kvm common code refers to this, but never calls it */
360 BUG();
361 return 0;
362}
363
364static int kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu)
365{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100366 kvm_s390_vcpu_initial_reset(vcpu);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100367 return 0;
368}
369
370int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
371{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100372 memcpy(&vcpu->arch.guest_gprs, &regs->gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100373 return 0;
374}
375
376int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
377{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100378 memcpy(&regs->gprs, &vcpu->arch.guest_gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100379 return 0;
380}
381
382int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
383 struct kvm_sregs *sregs)
384{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100385 memcpy(&vcpu->arch.guest_acrs, &sregs->acrs, sizeof(sregs->acrs));
386 memcpy(&vcpu->arch.sie_block->gcr, &sregs->crs, sizeof(sregs->crs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100387 return 0;
388}
389
390int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
391 struct kvm_sregs *sregs)
392{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100393 memcpy(&sregs->acrs, &vcpu->arch.guest_acrs, sizeof(sregs->acrs));
394 memcpy(&sregs->crs, &vcpu->arch.sie_block->gcr, sizeof(sregs->crs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100395 return 0;
396}
397
398int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
399{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100400 memcpy(&vcpu->arch.guest_fpregs.fprs, &fpu->fprs, sizeof(fpu->fprs));
401 vcpu->arch.guest_fpregs.fpc = fpu->fpc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100402 return 0;
403}
404
405int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
406{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100407 memcpy(&fpu->fprs, &vcpu->arch.guest_fpregs.fprs, sizeof(fpu->fprs));
408 fpu->fpc = vcpu->arch.guest_fpregs.fpc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100409 return 0;
410}
411
412static int kvm_arch_vcpu_ioctl_set_initial_psw(struct kvm_vcpu *vcpu, psw_t psw)
413{
414 int rc = 0;
415
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100416 if (atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_RUNNING)
417 rc = -EBUSY;
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100418 else {
419 vcpu->run->psw_mask = psw.mask;
420 vcpu->run->psw_addr = psw.addr;
421 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100422 return rc;
423}
424
425int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
426 struct kvm_translation *tr)
427{
428 return -EINVAL; /* not implemented yet */
429}
430
Jan Kiszkad0bfb942008-12-15 13:52:10 +0100431int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
432 struct kvm_guest_debug *dbg)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100433{
434 return -EINVAL; /* not implemented yet */
435}
436
Marcelo Tosatti62d9f0d2008-04-11 13:24:45 -0300437int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
438 struct kvm_mp_state *mp_state)
439{
440 return -EINVAL; /* not implemented yet */
441}
442
443int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
444 struct kvm_mp_state *mp_state)
445{
446 return -EINVAL; /* not implemented yet */
447}
448
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100449static void __vcpu_run(struct kvm_vcpu *vcpu)
450{
451 memcpy(&vcpu->arch.sie_block->gg14, &vcpu->arch.guest_gprs[14], 16);
452
453 if (need_resched())
454 schedule();
455
Christian Borntraeger71cde582008-05-21 13:37:34 +0200456 if (test_thread_flag(TIF_MCCK_PENDING))
457 s390_handle_mcck();
458
Carsten Otte0ff31862008-05-21 13:37:37 +0200459 kvm_s390_deliver_pending_interrupts(vcpu);
460
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100461 vcpu->arch.sie_block->icptcode = 0;
462 local_irq_disable();
463 kvm_guest_enter();
464 local_irq_enable();
Carsten Otte598841c2011-07-24 10:48:21 +0200465 gmap_enable(vcpu->arch.gmap);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100466 VCPU_EVENT(vcpu, 6, "entering sie flags %x",
467 atomic_read(&vcpu->arch.sie_block->cpuflags));
Carsten Otte1f0d0f02008-05-21 13:37:40 +0200468 if (sie64a(vcpu->arch.sie_block, vcpu->arch.guest_gprs)) {
469 VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction");
470 kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
471 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100472 VCPU_EVENT(vcpu, 6, "exit sie icptcode %d",
473 vcpu->arch.sie_block->icptcode);
Carsten Otte598841c2011-07-24 10:48:21 +0200474 gmap_disable(vcpu->arch.gmap);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100475 local_irq_disable();
476 kvm_guest_exit();
477 local_irq_enable();
478
479 memcpy(&vcpu->arch.guest_gprs[14], &vcpu->arch.sie_block->gg14, 16);
480}
481
482int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
483{
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100484 int rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100485 sigset_t sigsaved;
486
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200487rerun_vcpu:
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200488 if (vcpu->requests)
489 if (test_and_clear_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests))
490 kvm_s390_vcpu_set_mem(vcpu);
491
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100492 if (vcpu->sigset_active)
493 sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
494
495 atomic_set_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
496
Carsten Otteba5c1e92008-03-25 18:47:26 +0100497 BUG_ON(vcpu->kvm->arch.float_int.local_int[vcpu->vcpu_id] == NULL);
498
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100499 switch (kvm_run->exit_reason) {
500 case KVM_EXIT_S390_SIEIC:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100501 case KVM_EXIT_UNKNOWN:
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200502 case KVM_EXIT_INTR:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100503 case KVM_EXIT_S390_RESET:
504 break;
505 default:
506 BUG();
507 }
508
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100509 vcpu->arch.sie_block->gpsw.mask = kvm_run->psw_mask;
510 vcpu->arch.sie_block->gpsw.addr = kvm_run->psw_addr;
511
Heiko Carstensdab4079d2009-06-12 10:26:32 +0200512 might_fault();
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100513
514 do {
515 __vcpu_run(vcpu);
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100516 rc = kvm_handle_sie_intercept(vcpu);
517 } while (!signal_pending(current) && !rc);
518
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200519 if (rc == SIE_INTERCEPT_RERUNVCPU)
520 goto rerun_vcpu;
521
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200522 if (signal_pending(current) && !rc) {
523 kvm_run->exit_reason = KVM_EXIT_INTR;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100524 rc = -EINTR;
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200525 }
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100526
Heiko Carstensb8e660b2010-02-26 22:37:41 +0100527 if (rc == -EOPNOTSUPP) {
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100528 /* intercept cannot be handled in-kernel, prepare kvm-run */
529 kvm_run->exit_reason = KVM_EXIT_S390_SIEIC;
530 kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100531 kvm_run->s390_sieic.ipa = vcpu->arch.sie_block->ipa;
532 kvm_run->s390_sieic.ipb = vcpu->arch.sie_block->ipb;
533 rc = 0;
534 }
535
536 if (rc == -EREMOTE) {
537 /* intercept was handled, but userspace support is needed
538 * kvm_run has been prepared by the handler */
539 rc = 0;
540 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100541
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100542 kvm_run->psw_mask = vcpu->arch.sie_block->gpsw.mask;
543 kvm_run->psw_addr = vcpu->arch.sie_block->gpsw.addr;
544
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100545 if (vcpu->sigset_active)
546 sigprocmask(SIG_SETMASK, &sigsaved, NULL);
547
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100548 vcpu->stat.exit_userspace++;
Heiko Carstens7e8e6ab2008-04-04 15:12:35 +0200549 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100550}
551
Carsten Otte092670c2011-07-24 10:48:22 +0200552static int __guestcopy(struct kvm_vcpu *vcpu, u64 guestdest, void *from,
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100553 unsigned long n, int prefix)
554{
555 if (prefix)
556 return copy_to_guest(vcpu, guestdest, from, n);
557 else
558 return copy_to_guest_absolute(vcpu, guestdest, from, n);
559}
560
561/*
562 * store status at address
563 * we use have two special cases:
564 * KVM_S390_STORE_STATUS_NOADDR: -> 0x1200 on 64 bit
565 * KVM_S390_STORE_STATUS_PREFIXED: -> prefix
566 */
Christian Borntraeger971eb772010-06-12 08:54:13 +0200567int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100568{
Carsten Otte092670c2011-07-24 10:48:22 +0200569 unsigned char archmode = 1;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100570 int prefix;
571
572 if (addr == KVM_S390_STORE_STATUS_NOADDR) {
573 if (copy_to_guest_absolute(vcpu, 163ul, &archmode, 1))
574 return -EFAULT;
575 addr = SAVE_AREA_BASE;
576 prefix = 0;
577 } else if (addr == KVM_S390_STORE_STATUS_PREFIXED) {
578 if (copy_to_guest(vcpu, 163ul, &archmode, 1))
579 return -EFAULT;
580 addr = SAVE_AREA_BASE;
581 prefix = 1;
582 } else
583 prefix = 0;
584
Heiko Carstensf64ca212010-02-26 22:37:32 +0100585 if (__guestcopy(vcpu, addr + offsetof(struct save_area, fp_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100586 vcpu->arch.guest_fpregs.fprs, 128, prefix))
587 return -EFAULT;
588
Heiko Carstensf64ca212010-02-26 22:37:32 +0100589 if (__guestcopy(vcpu, addr + offsetof(struct save_area, gp_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100590 vcpu->arch.guest_gprs, 128, prefix))
591 return -EFAULT;
592
Heiko Carstensf64ca212010-02-26 22:37:32 +0100593 if (__guestcopy(vcpu, addr + offsetof(struct save_area, psw),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100594 &vcpu->arch.sie_block->gpsw, 16, prefix))
595 return -EFAULT;
596
Heiko Carstensf64ca212010-02-26 22:37:32 +0100597 if (__guestcopy(vcpu, addr + offsetof(struct save_area, pref_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100598 &vcpu->arch.sie_block->prefix, 4, prefix))
599 return -EFAULT;
600
601 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100602 addr + offsetof(struct save_area, fp_ctrl_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100603 &vcpu->arch.guest_fpregs.fpc, 4, prefix))
604 return -EFAULT;
605
Heiko Carstensf64ca212010-02-26 22:37:32 +0100606 if (__guestcopy(vcpu, addr + offsetof(struct save_area, tod_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100607 &vcpu->arch.sie_block->todpr, 4, prefix))
608 return -EFAULT;
609
Heiko Carstensf64ca212010-02-26 22:37:32 +0100610 if (__guestcopy(vcpu, addr + offsetof(struct save_area, timer),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100611 &vcpu->arch.sie_block->cputm, 8, prefix))
612 return -EFAULT;
613
Heiko Carstensf64ca212010-02-26 22:37:32 +0100614 if (__guestcopy(vcpu, addr + offsetof(struct save_area, clk_cmp),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100615 &vcpu->arch.sie_block->ckc, 8, prefix))
616 return -EFAULT;
617
Heiko Carstensf64ca212010-02-26 22:37:32 +0100618 if (__guestcopy(vcpu, addr + offsetof(struct save_area, acc_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100619 &vcpu->arch.guest_acrs, 64, prefix))
620 return -EFAULT;
621
622 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100623 addr + offsetof(struct save_area, ctrl_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100624 &vcpu->arch.sie_block->gcr, 128, prefix))
625 return -EFAULT;
626 return 0;
627}
628
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100629long kvm_arch_vcpu_ioctl(struct file *filp,
630 unsigned int ioctl, unsigned long arg)
631{
632 struct kvm_vcpu *vcpu = filp->private_data;
633 void __user *argp = (void __user *)arg;
Avi Kivitybc923cc2010-05-13 12:21:46 +0300634 long r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100635
Avi Kivity937366242010-05-13 12:35:17 +0300636 switch (ioctl) {
637 case KVM_S390_INTERRUPT: {
Carsten Otteba5c1e92008-03-25 18:47:26 +0100638 struct kvm_s390_interrupt s390int;
639
Avi Kivity937366242010-05-13 12:35:17 +0300640 r = -EFAULT;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100641 if (copy_from_user(&s390int, argp, sizeof(s390int)))
Avi Kivity937366242010-05-13 12:35:17 +0300642 break;
643 r = kvm_s390_inject_vcpu(vcpu, &s390int);
644 break;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100645 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100646 case KVM_S390_STORE_STATUS:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300647 r = kvm_s390_vcpu_store_status(vcpu, arg);
648 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100649 case KVM_S390_SET_INITIAL_PSW: {
650 psw_t psw;
651
Avi Kivitybc923cc2010-05-13 12:21:46 +0300652 r = -EFAULT;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100653 if (copy_from_user(&psw, argp, sizeof(psw)))
Avi Kivitybc923cc2010-05-13 12:21:46 +0300654 break;
655 r = kvm_arch_vcpu_ioctl_set_initial_psw(vcpu, psw);
656 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100657 }
658 case KVM_S390_INITIAL_RESET:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300659 r = kvm_arch_vcpu_ioctl_initial_reset(vcpu);
660 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100661 default:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300662 r = -EINVAL;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100663 }
Avi Kivitybc923cc2010-05-13 12:21:46 +0300664 return r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100665}
666
667/* Section: memory related */
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200668int kvm_arch_prepare_memory_region(struct kvm *kvm,
669 struct kvm_memory_slot *memslot,
670 struct kvm_memory_slot old,
671 struct kvm_userspace_memory_region *mem,
672 int user_alloc)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100673{
674 /* A few sanity checks. We can have exactly one memory slot which has
675 to start at guest virtual zero and which has to be located at a
676 page boundary in userland and which has to end at a page boundary.
677 The memory in userland is ok to be fragmented into various different
678 vmas. It is okay to mmap() and munmap() stuff in this slot after
679 doing this call at any time */
680
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200681 if (mem->slot)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100682 return -EINVAL;
683
684 if (mem->guest_phys_addr)
685 return -EINVAL;
686
Carsten Otte598841c2011-07-24 10:48:21 +0200687 if (mem->userspace_addr & 0xffffful)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100688 return -EINVAL;
689
Carsten Otte598841c2011-07-24 10:48:21 +0200690 if (mem->memory_size & 0xffffful)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100691 return -EINVAL;
692
Carsten Otte2668dab2009-05-12 17:21:48 +0200693 if (!user_alloc)
694 return -EINVAL;
695
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200696 return 0;
697}
698
699void kvm_arch_commit_memory_region(struct kvm *kvm,
700 struct kvm_userspace_memory_region *mem,
701 struct kvm_memory_slot old,
702 int user_alloc)
703{
Carsten Otte598841c2011-07-24 10:48:21 +0200704 int i, rc;
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200705 struct kvm_vcpu *vcpu;
706
Carsten Otte598841c2011-07-24 10:48:21 +0200707
708 rc = gmap_map_segment(kvm->arch.gmap, mem->userspace_addr,
709 mem->guest_phys_addr, mem->memory_size);
710 if (rc)
711 return;
712
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200713 /* request update of sie control block for all available vcpus */
Gleb Natapov988a2ca2009-06-09 15:56:29 +0300714 kvm_for_each_vcpu(i, vcpu, kvm) {
715 if (test_and_set_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests))
716 continue;
717 kvm_s390_inject_sigp_stop(vcpu, ACTION_RELOADVCPU_ON_STOP);
Carsten Otte2668dab2009-05-12 17:21:48 +0200718 }
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);