blob: b4eced131e5ce4d628ebef5f87573a316d6b8e96 [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);
Christian Borntraeger480e5922011-09-20 17:07:28 +0200266 gmap_enable(vcpu->arch.gmap);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100267}
268
269void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
270{
Christian Borntraeger480e5922011-09-20 17:07:28 +0200271 gmap_disable(vcpu->arch.gmap);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100272 save_fp_regs(&vcpu->arch.guest_fpregs);
273 save_access_regs(vcpu->arch.guest_acrs);
274 restore_fp_regs(&vcpu->arch.host_fpregs);
275 restore_access_regs(vcpu->arch.host_acrs);
276}
277
278static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu)
279{
280 /* this equals initial cpu reset in pop, but we don't switch to ESA */
281 vcpu->arch.sie_block->gpsw.mask = 0UL;
282 vcpu->arch.sie_block->gpsw.addr = 0UL;
283 vcpu->arch.sie_block->prefix = 0UL;
284 vcpu->arch.sie_block->ihcpu = 0xffff;
285 vcpu->arch.sie_block->cputm = 0UL;
286 vcpu->arch.sie_block->ckc = 0UL;
287 vcpu->arch.sie_block->todpr = 0;
288 memset(vcpu->arch.sie_block->gcr, 0, 16 * sizeof(__u64));
289 vcpu->arch.sie_block->gcr[0] = 0xE0UL;
290 vcpu->arch.sie_block->gcr[14] = 0xC2000000UL;
291 vcpu->arch.guest_fpregs.fpc = 0;
292 asm volatile("lfpc %0" : : "Q" (vcpu->arch.guest_fpregs.fpc));
293 vcpu->arch.sie_block->gbea = 1;
294}
295
296int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
297{
Carsten Otte598841c2011-07-24 10:48:21 +0200298 atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH | CPUSTAT_SM);
Christian Borntraegerfc345312010-06-17 23:16:20 +0200299 vcpu->arch.sie_block->ecb = 6;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100300 vcpu->arch.sie_block->eca = 0xC1002001U;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200301 vcpu->arch.sie_block->fac = (int) (long) facilities;
Christian Borntraegerca872302009-05-12 17:21:49 +0200302 hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
303 tasklet_init(&vcpu->arch.tasklet, kvm_s390_tasklet,
304 (unsigned long) vcpu);
305 vcpu->arch.ckc_timer.function = kvm_s390_idle_wakeup;
Christian Borntraeger453423d2008-03-25 18:47:29 +0100306 get_cpu_id(&vcpu->arch.cpu_id);
Christian Borntraeger92e6ecf2009-03-26 15:23:58 +0100307 vcpu->arch.cpu_id.version = 0xff;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100308 return 0;
309}
310
311struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
312 unsigned int id)
313{
314 struct kvm_vcpu *vcpu = kzalloc(sizeof(struct kvm_vcpu), GFP_KERNEL);
315 int rc = -ENOMEM;
316
317 if (!vcpu)
318 goto out_nomem;
319
Christian Borntraeger180c12f2008-06-27 15:05:40 +0200320 vcpu->arch.sie_block = (struct kvm_s390_sie_block *)
321 get_zeroed_page(GFP_KERNEL);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100322
323 if (!vcpu->arch.sie_block)
324 goto out_free_cpu;
325
326 vcpu->arch.sie_block->icpua = id;
327 BUG_ON(!kvm->arch.sca);
Carsten Otteabf4a712009-05-12 17:21:51 +0200328 if (!kvm->arch.sca->cpu[id].sda)
329 kvm->arch.sca->cpu[id].sda = (__u64) vcpu->arch.sie_block;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100330 vcpu->arch.sie_block->scaoh = (__u32)(((__u64)kvm->arch.sca) >> 32);
331 vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca;
Christian Borntraegerfc345312010-06-17 23:16:20 +0200332 set_bit(63 - id, (unsigned long *) &kvm->arch.sca->mcn);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100333
Carsten Otteba5c1e92008-03-25 18:47:26 +0100334 spin_lock_init(&vcpu->arch.local_int.lock);
335 INIT_LIST_HEAD(&vcpu->arch.local_int.list);
336 vcpu->arch.local_int.float_int = &kvm->arch.float_int;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200337 spin_lock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100338 kvm->arch.float_int.local_int[id] = &vcpu->arch.local_int;
339 init_waitqueue_head(&vcpu->arch.local_int.wq);
Christian Borntraeger5288fbf2008-03-25 18:47:31 +0100340 vcpu->arch.local_int.cpuflags = &vcpu->arch.sie_block->cpuflags;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200341 spin_unlock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100342
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100343 rc = kvm_vcpu_init(vcpu, kvm, id);
344 if (rc)
Wei Yongjun7b06bf22010-03-09 14:37:53 +0800345 goto out_free_sie_block;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100346 VM_EVENT(kvm, 3, "create cpu %d at %p, sie block at %p", id, vcpu,
347 vcpu->arch.sie_block);
348
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100349 return vcpu;
Wei Yongjun7b06bf22010-03-09 14:37:53 +0800350out_free_sie_block:
351 free_page((unsigned long)(vcpu->arch.sie_block));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100352out_free_cpu:
353 kfree(vcpu);
354out_nomem:
355 return ERR_PTR(rc);
356}
357
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100358int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
359{
360 /* kvm common code refers to this, but never calls it */
361 BUG();
362 return 0;
363}
364
365static int kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu)
366{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100367 kvm_s390_vcpu_initial_reset(vcpu);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100368 return 0;
369}
370
371int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
372{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100373 memcpy(&vcpu->arch.guest_gprs, &regs->gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100374 return 0;
375}
376
377int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
378{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100379 memcpy(&regs->gprs, &vcpu->arch.guest_gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100380 return 0;
381}
382
383int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
384 struct kvm_sregs *sregs)
385{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100386 memcpy(&vcpu->arch.guest_acrs, &sregs->acrs, sizeof(sregs->acrs));
387 memcpy(&vcpu->arch.sie_block->gcr, &sregs->crs, sizeof(sregs->crs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100388 return 0;
389}
390
391int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
392 struct kvm_sregs *sregs)
393{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100394 memcpy(&sregs->acrs, &vcpu->arch.guest_acrs, sizeof(sregs->acrs));
395 memcpy(&sregs->crs, &vcpu->arch.sie_block->gcr, sizeof(sregs->crs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100396 return 0;
397}
398
399int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
400{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100401 memcpy(&vcpu->arch.guest_fpregs.fprs, &fpu->fprs, sizeof(fpu->fprs));
402 vcpu->arch.guest_fpregs.fpc = fpu->fpc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100403 return 0;
404}
405
406int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
407{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100408 memcpy(&fpu->fprs, &vcpu->arch.guest_fpregs.fprs, sizeof(fpu->fprs));
409 fpu->fpc = vcpu->arch.guest_fpregs.fpc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100410 return 0;
411}
412
413static int kvm_arch_vcpu_ioctl_set_initial_psw(struct kvm_vcpu *vcpu, psw_t psw)
414{
415 int rc = 0;
416
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100417 if (atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_RUNNING)
418 rc = -EBUSY;
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100419 else {
420 vcpu->run->psw_mask = psw.mask;
421 vcpu->run->psw_addr = psw.addr;
422 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100423 return rc;
424}
425
426int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
427 struct kvm_translation *tr)
428{
429 return -EINVAL; /* not implemented yet */
430}
431
Jan Kiszkad0bfb942008-12-15 13:52:10 +0100432int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
433 struct kvm_guest_debug *dbg)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100434{
435 return -EINVAL; /* not implemented yet */
436}
437
Marcelo Tosatti62d9f0d2008-04-11 13:24:45 -0300438int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
439 struct kvm_mp_state *mp_state)
440{
441 return -EINVAL; /* not implemented yet */
442}
443
444int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
445 struct kvm_mp_state *mp_state)
446{
447 return -EINVAL; /* not implemented yet */
448}
449
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100450static void __vcpu_run(struct kvm_vcpu *vcpu)
451{
452 memcpy(&vcpu->arch.sie_block->gg14, &vcpu->arch.guest_gprs[14], 16);
453
454 if (need_resched())
455 schedule();
456
Christian Borntraeger71cde582008-05-21 13:37:34 +0200457 if (test_thread_flag(TIF_MCCK_PENDING))
458 s390_handle_mcck();
459
Carsten Otte0ff31862008-05-21 13:37:37 +0200460 kvm_s390_deliver_pending_interrupts(vcpu);
461
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100462 vcpu->arch.sie_block->icptcode = 0;
463 local_irq_disable();
464 kvm_guest_enter();
465 local_irq_enable();
466 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);
474 local_irq_disable();
475 kvm_guest_exit();
476 local_irq_enable();
477
478 memcpy(&vcpu->arch.guest_gprs[14], &vcpu->arch.sie_block->gg14, 16);
479}
480
481int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
482{
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100483 int rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100484 sigset_t sigsaved;
485
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200486rerun_vcpu:
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100487 if (vcpu->sigset_active)
488 sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
489
490 atomic_set_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
491
Carsten Otteba5c1e92008-03-25 18:47:26 +0100492 BUG_ON(vcpu->kvm->arch.float_int.local_int[vcpu->vcpu_id] == NULL);
493
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100494 switch (kvm_run->exit_reason) {
495 case KVM_EXIT_S390_SIEIC:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100496 case KVM_EXIT_UNKNOWN:
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200497 case KVM_EXIT_INTR:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100498 case KVM_EXIT_S390_RESET:
499 break;
500 default:
501 BUG();
502 }
503
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100504 vcpu->arch.sie_block->gpsw.mask = kvm_run->psw_mask;
505 vcpu->arch.sie_block->gpsw.addr = kvm_run->psw_addr;
506
Heiko Carstensdab4079d2009-06-12 10:26:32 +0200507 might_fault();
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100508
509 do {
510 __vcpu_run(vcpu);
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100511 rc = kvm_handle_sie_intercept(vcpu);
512 } while (!signal_pending(current) && !rc);
513
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200514 if (rc == SIE_INTERCEPT_RERUNVCPU)
515 goto rerun_vcpu;
516
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200517 if (signal_pending(current) && !rc) {
518 kvm_run->exit_reason = KVM_EXIT_INTR;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100519 rc = -EINTR;
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200520 }
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100521
Heiko Carstensb8e660b2010-02-26 22:37:41 +0100522 if (rc == -EOPNOTSUPP) {
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100523 /* intercept cannot be handled in-kernel, prepare kvm-run */
524 kvm_run->exit_reason = KVM_EXIT_S390_SIEIC;
525 kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100526 kvm_run->s390_sieic.ipa = vcpu->arch.sie_block->ipa;
527 kvm_run->s390_sieic.ipb = vcpu->arch.sie_block->ipb;
528 rc = 0;
529 }
530
531 if (rc == -EREMOTE) {
532 /* intercept was handled, but userspace support is needed
533 * kvm_run has been prepared by the handler */
534 rc = 0;
535 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100536
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100537 kvm_run->psw_mask = vcpu->arch.sie_block->gpsw.mask;
538 kvm_run->psw_addr = vcpu->arch.sie_block->gpsw.addr;
539
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100540 if (vcpu->sigset_active)
541 sigprocmask(SIG_SETMASK, &sigsaved, NULL);
542
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100543 vcpu->stat.exit_userspace++;
Heiko Carstens7e8e6ab2008-04-04 15:12:35 +0200544 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100545}
546
Carsten Otte092670c2011-07-24 10:48:22 +0200547static int __guestcopy(struct kvm_vcpu *vcpu, u64 guestdest, void *from,
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100548 unsigned long n, int prefix)
549{
550 if (prefix)
551 return copy_to_guest(vcpu, guestdest, from, n);
552 else
553 return copy_to_guest_absolute(vcpu, guestdest, from, n);
554}
555
556/*
557 * store status at address
558 * we use have two special cases:
559 * KVM_S390_STORE_STATUS_NOADDR: -> 0x1200 on 64 bit
560 * KVM_S390_STORE_STATUS_PREFIXED: -> prefix
561 */
Christian Borntraeger971eb772010-06-12 08:54:13 +0200562int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100563{
Carsten Otte092670c2011-07-24 10:48:22 +0200564 unsigned char archmode = 1;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100565 int prefix;
566
567 if (addr == KVM_S390_STORE_STATUS_NOADDR) {
568 if (copy_to_guest_absolute(vcpu, 163ul, &archmode, 1))
569 return -EFAULT;
570 addr = SAVE_AREA_BASE;
571 prefix = 0;
572 } else if (addr == KVM_S390_STORE_STATUS_PREFIXED) {
573 if (copy_to_guest(vcpu, 163ul, &archmode, 1))
574 return -EFAULT;
575 addr = SAVE_AREA_BASE;
576 prefix = 1;
577 } else
578 prefix = 0;
579
Heiko Carstensf64ca212010-02-26 22:37:32 +0100580 if (__guestcopy(vcpu, addr + offsetof(struct save_area, fp_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100581 vcpu->arch.guest_fpregs.fprs, 128, prefix))
582 return -EFAULT;
583
Heiko Carstensf64ca212010-02-26 22:37:32 +0100584 if (__guestcopy(vcpu, addr + offsetof(struct save_area, gp_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100585 vcpu->arch.guest_gprs, 128, prefix))
586 return -EFAULT;
587
Heiko Carstensf64ca212010-02-26 22:37:32 +0100588 if (__guestcopy(vcpu, addr + offsetof(struct save_area, psw),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100589 &vcpu->arch.sie_block->gpsw, 16, prefix))
590 return -EFAULT;
591
Heiko Carstensf64ca212010-02-26 22:37:32 +0100592 if (__guestcopy(vcpu, addr + offsetof(struct save_area, pref_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100593 &vcpu->arch.sie_block->prefix, 4, prefix))
594 return -EFAULT;
595
596 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100597 addr + offsetof(struct save_area, fp_ctrl_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100598 &vcpu->arch.guest_fpregs.fpc, 4, prefix))
599 return -EFAULT;
600
Heiko Carstensf64ca212010-02-26 22:37:32 +0100601 if (__guestcopy(vcpu, addr + offsetof(struct save_area, tod_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100602 &vcpu->arch.sie_block->todpr, 4, prefix))
603 return -EFAULT;
604
Heiko Carstensf64ca212010-02-26 22:37:32 +0100605 if (__guestcopy(vcpu, addr + offsetof(struct save_area, timer),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100606 &vcpu->arch.sie_block->cputm, 8, prefix))
607 return -EFAULT;
608
Heiko Carstensf64ca212010-02-26 22:37:32 +0100609 if (__guestcopy(vcpu, addr + offsetof(struct save_area, clk_cmp),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100610 &vcpu->arch.sie_block->ckc, 8, prefix))
611 return -EFAULT;
612
Heiko Carstensf64ca212010-02-26 22:37:32 +0100613 if (__guestcopy(vcpu, addr + offsetof(struct save_area, acc_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100614 &vcpu->arch.guest_acrs, 64, prefix))
615 return -EFAULT;
616
617 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100618 addr + offsetof(struct save_area, ctrl_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100619 &vcpu->arch.sie_block->gcr, 128, prefix))
620 return -EFAULT;
621 return 0;
622}
623
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100624long kvm_arch_vcpu_ioctl(struct file *filp,
625 unsigned int ioctl, unsigned long arg)
626{
627 struct kvm_vcpu *vcpu = filp->private_data;
628 void __user *argp = (void __user *)arg;
Avi Kivitybc923cc2010-05-13 12:21:46 +0300629 long r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100630
Avi Kivity93736622010-05-13 12:35:17 +0300631 switch (ioctl) {
632 case KVM_S390_INTERRUPT: {
Carsten Otteba5c1e92008-03-25 18:47:26 +0100633 struct kvm_s390_interrupt s390int;
634
Avi Kivity93736622010-05-13 12:35:17 +0300635 r = -EFAULT;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100636 if (copy_from_user(&s390int, argp, sizeof(s390int)))
Avi Kivity93736622010-05-13 12:35:17 +0300637 break;
638 r = kvm_s390_inject_vcpu(vcpu, &s390int);
639 break;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100640 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100641 case KVM_S390_STORE_STATUS:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300642 r = kvm_s390_vcpu_store_status(vcpu, arg);
643 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100644 case KVM_S390_SET_INITIAL_PSW: {
645 psw_t psw;
646
Avi Kivitybc923cc2010-05-13 12:21:46 +0300647 r = -EFAULT;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100648 if (copy_from_user(&psw, argp, sizeof(psw)))
Avi Kivitybc923cc2010-05-13 12:21:46 +0300649 break;
650 r = kvm_arch_vcpu_ioctl_set_initial_psw(vcpu, psw);
651 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100652 }
653 case KVM_S390_INITIAL_RESET:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300654 r = kvm_arch_vcpu_ioctl_initial_reset(vcpu);
655 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100656 default:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300657 r = -EINVAL;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100658 }
Avi Kivitybc923cc2010-05-13 12:21:46 +0300659 return r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100660}
661
662/* Section: memory related */
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200663int kvm_arch_prepare_memory_region(struct kvm *kvm,
664 struct kvm_memory_slot *memslot,
665 struct kvm_memory_slot old,
666 struct kvm_userspace_memory_region *mem,
667 int user_alloc)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100668{
669 /* A few sanity checks. We can have exactly one memory slot which has
670 to start at guest virtual zero and which has to be located at a
671 page boundary in userland and which has to end at a page boundary.
672 The memory in userland is ok to be fragmented into various different
673 vmas. It is okay to mmap() and munmap() stuff in this slot after
674 doing this call at any time */
675
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200676 if (mem->slot)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100677 return -EINVAL;
678
679 if (mem->guest_phys_addr)
680 return -EINVAL;
681
Carsten Otte598841c2011-07-24 10:48:21 +0200682 if (mem->userspace_addr & 0xffffful)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100683 return -EINVAL;
684
Carsten Otte598841c2011-07-24 10:48:21 +0200685 if (mem->memory_size & 0xffffful)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100686 return -EINVAL;
687
Carsten Otte2668dab2009-05-12 17:21:48 +0200688 if (!user_alloc)
689 return -EINVAL;
690
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200691 return 0;
692}
693
694void kvm_arch_commit_memory_region(struct kvm *kvm,
695 struct kvm_userspace_memory_region *mem,
696 struct kvm_memory_slot old,
697 int user_alloc)
698{
Carsten Ottef7850c92011-07-24 10:48:23 +0200699 int rc;
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200700
Carsten Otte598841c2011-07-24 10:48:21 +0200701
702 rc = gmap_map_segment(kvm->arch.gmap, mem->userspace_addr,
703 mem->guest_phys_addr, mem->memory_size);
704 if (rc)
Carsten Ottef7850c92011-07-24 10:48:23 +0200705 printk(KERN_WARNING "kvm-s390: failed to commit memory region\n");
Carsten Otte598841c2011-07-24 10:48:21 +0200706 return;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100707}
708
Marcelo Tosatti34d4cb82008-07-10 20:49:31 -0300709void kvm_arch_flush_shadow(struct kvm *kvm)
710{
711}
712
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100713static int __init kvm_s390_init(void)
714{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200715 int ret;
Avi Kivity0ee75be2010-04-28 15:39:01 +0300716 ret = kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE);
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200717 if (ret)
718 return ret;
719
720 /*
721 * guests can ask for up to 255+1 double words, we need a full page
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300722 * to hold the maximum amount of facilities. On the other hand, we
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200723 * only set facilities that are known to work in KVM.
724 */
Heiko Carstensc2f0e8c2010-06-08 18:58:09 +0200725 facilities = (unsigned long long *) get_zeroed_page(GFP_KERNEL|GFP_DMA);
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200726 if (!facilities) {
727 kvm_exit();
728 return -ENOMEM;
729 }
Martin Schwidefsky14375bc2010-10-25 16:10:51 +0200730 memcpy(facilities, S390_lowcore.stfle_fac_list, 16);
Christian Borntraeger6d00d002010-10-25 16:10:48 +0200731 facilities[0] &= 0xff00fff3f47c0000ULL;
Christian Borntraeger9950f8b2011-06-06 14:14:39 +0200732 facilities[1] &= 0x201c000000000000ULL;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200733 return 0;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100734}
735
736static void __exit kvm_s390_exit(void)
737{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200738 free_page((unsigned long) facilities);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100739 kvm_exit();
740}
741
742module_init(kvm_s390_init);
743module_exit(kvm_s390_exit);