blob: 5b5c28e471df31861962afe48f9a1505a7ce113c [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) },
Cornelia Huckbd59d3a2011-11-17 11:00:42 +010068 { "instruction_sigp_sense_running", VCPU_STAT(instruction_sigp_sense_running) },
Christian Ehrhardt7697e71f2011-10-18 12:27:15 +020069 { "instruction_sigp_external_call", VCPU_STAT(instruction_sigp_external_call) },
Christian Borntraeger5288fbf2008-03-25 18:47:31 +010070 { "instruction_sigp_emergency", VCPU_STAT(instruction_sigp_emergency) },
71 { "instruction_sigp_stop", VCPU_STAT(instruction_sigp_stop) },
72 { "instruction_sigp_set_arch", VCPU_STAT(instruction_sigp_arch) },
73 { "instruction_sigp_set_prefix", VCPU_STAT(instruction_sigp_prefix) },
74 { "instruction_sigp_restart", VCPU_STAT(instruction_sigp_restart) },
Christian Borntraeger388186b2011-10-30 15:17:03 +010075 { "diagnose_10", VCPU_STAT(diagnose_10) },
Christian Borntraegere28acfe2008-03-25 18:47:34 +010076 { "diagnose_44", VCPU_STAT(diagnose_44) },
Heiko Carstensb0c632d2008-03-25 18:47:20 +010077 { NULL }
78};
79
Christian Borntraegeref50f7a2009-06-23 17:24:07 +020080static unsigned long long *facilities;
Heiko Carstensb0c632d2008-03-25 18:47:20 +010081
82/* Section: not file related */
Alexander Graf10474ae2009-09-15 11:37:46 +020083int kvm_arch_hardware_enable(void *garbage)
Heiko Carstensb0c632d2008-03-25 18:47:20 +010084{
85 /* every s390 is virtualization enabled ;-) */
Alexander Graf10474ae2009-09-15 11:37:46 +020086 return 0;
Heiko Carstensb0c632d2008-03-25 18:47:20 +010087}
88
89void kvm_arch_hardware_disable(void *garbage)
90{
91}
92
Heiko Carstensb0c632d2008-03-25 18:47:20 +010093int kvm_arch_hardware_setup(void)
94{
95 return 0;
96}
97
98void kvm_arch_hardware_unsetup(void)
99{
100}
101
102void kvm_arch_check_processor_compat(void *rtn)
103{
104}
105
106int kvm_arch_init(void *opaque)
107{
108 return 0;
109}
110
111void kvm_arch_exit(void)
112{
113}
114
115/* Section: device related */
116long kvm_arch_dev_ioctl(struct file *filp,
117 unsigned int ioctl, unsigned long arg)
118{
119 if (ioctl == KVM_S390_ENABLE_SIE)
120 return s390_enable_sie();
121 return -EINVAL;
122}
123
124int kvm_dev_ioctl_check_extension(long ext)
125{
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100126 int r;
127
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200128 switch (ext) {
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100129 case KVM_CAP_S390_PSW:
Christian Borntraegerb6cf8782011-09-20 17:07:29 +0200130 case KVM_CAP_S390_GMAP:
Christian Borntraeger52e16b12011-11-17 11:00:44 +0100131 case KVM_CAP_SYNC_MMU:
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100132 r = 1;
133 break;
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200134 default:
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100135 r = 0;
Carsten Otte2bd0ac42008-07-25 15:49:13 +0200136 }
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100137 return r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100138}
139
140/* Section: vm related */
141/*
142 * Get (and clear) the dirty memory log for a memory slot.
143 */
144int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
145 struct kvm_dirty_log *log)
146{
147 return 0;
148}
149
150long kvm_arch_vm_ioctl(struct file *filp,
151 unsigned int ioctl, unsigned long arg)
152{
153 struct kvm *kvm = filp->private_data;
154 void __user *argp = (void __user *)arg;
155 int r;
156
157 switch (ioctl) {
Carsten Otteba5c1e92008-03-25 18:47:26 +0100158 case KVM_S390_INTERRUPT: {
159 struct kvm_s390_interrupt s390int;
160
161 r = -EFAULT;
162 if (copy_from_user(&s390int, argp, sizeof(s390int)))
163 break;
164 r = kvm_s390_inject_vm(kvm, &s390int);
165 break;
166 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100167 default:
Avi Kivity367e1312009-08-26 14:57:07 +0300168 r = -ENOTTY;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100169 }
170
171 return r;
172}
173
Carsten Ottee08b9632012-01-04 10:25:20 +0100174int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100175{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100176 int rc;
177 char debug_name[16];
178
Carsten Ottee08b9632012-01-04 10:25:20 +0100179 rc = -EINVAL;
180#ifdef CONFIG_KVM_S390_UCONTROL
181 if (type & ~KVM_VM_S390_UCONTROL)
182 goto out_err;
183 if ((type & KVM_VM_S390_UCONTROL) && (!capable(CAP_SYS_ADMIN)))
184 goto out_err;
185#else
186 if (type)
187 goto out_err;
188#endif
189
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100190 rc = s390_enable_sie();
191 if (rc)
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100192 goto out_err;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100193
Carsten Otteb2904112011-10-18 12:27:13 +0200194 rc = -ENOMEM;
195
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100196 kvm->arch.sca = (struct sca_block *) get_zeroed_page(GFP_KERNEL);
197 if (!kvm->arch.sca)
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100198 goto out_err;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100199
200 sprintf(debug_name, "kvm-%u", current->pid);
201
202 kvm->arch.dbf = debug_register(debug_name, 8, 2, 8 * sizeof(long));
203 if (!kvm->arch.dbf)
204 goto out_nodbf;
205
Carsten Otteba5c1e92008-03-25 18:47:26 +0100206 spin_lock_init(&kvm->arch.float_int.lock);
207 INIT_LIST_HEAD(&kvm->arch.float_int.list);
208
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100209 debug_register_view(kvm->arch.dbf, &debug_sprintf_view);
210 VM_EVENT(kvm, 3, "%s", "vm created");
211
Carsten Ottee08b9632012-01-04 10:25:20 +0100212 if (type & KVM_VM_S390_UCONTROL) {
213 kvm->arch.gmap = NULL;
214 } else {
215 kvm->arch.gmap = gmap_alloc(current->mm);
216 if (!kvm->arch.gmap)
217 goto out_nogmap;
218 }
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100219 return 0;
Carsten Otte598841c2011-07-24 10:48:21 +0200220out_nogmap:
221 debug_unregister(kvm->arch.dbf);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100222out_nodbf:
223 free_page((unsigned long)(kvm->arch.sca));
Jan Kiszkad89f5ef2010-11-09 17:02:49 +0100224out_err:
225 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100226}
227
Christian Borntraegerd329c032008-11-26 14:50:27 +0100228void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
229{
230 VCPU_EVENT(vcpu, 3, "%s", "free cpu");
Christian Borntraegerfc345312010-06-17 23:16:20 +0200231 clear_bit(63 - vcpu->vcpu_id, (unsigned long *) &vcpu->kvm->arch.sca->mcn);
Carsten Otteabf4a712009-05-12 17:21:51 +0200232 if (vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda ==
233 (__u64) vcpu->arch.sie_block)
234 vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda = 0;
235 smp_mb();
Carsten Otte27e03932012-01-04 10:25:21 +0100236
237 if (kvm_is_ucontrol(vcpu->kvm))
238 gmap_free(vcpu->arch.gmap);
239
Christian Borntraegerd329c032008-11-26 14:50:27 +0100240 free_page((unsigned long)(vcpu->arch.sie_block));
Christian Borntraeger6692cef2008-11-26 14:51:08 +0100241 kvm_vcpu_uninit(vcpu);
Christian Borntraegerd329c032008-11-26 14:50:27 +0100242 kfree(vcpu);
243}
244
245static void kvm_free_vcpus(struct kvm *kvm)
246{
247 unsigned int i;
Gleb Natapov988a2ca2009-06-09 15:56:29 +0300248 struct kvm_vcpu *vcpu;
Christian Borntraegerd329c032008-11-26 14:50:27 +0100249
Gleb Natapov988a2ca2009-06-09 15:56:29 +0300250 kvm_for_each_vcpu(i, vcpu, kvm)
251 kvm_arch_vcpu_destroy(vcpu);
252
253 mutex_lock(&kvm->lock);
254 for (i = 0; i < atomic_read(&kvm->online_vcpus); i++)
255 kvm->vcpus[i] = NULL;
256
257 atomic_set(&kvm->online_vcpus, 0);
258 mutex_unlock(&kvm->lock);
Christian Borntraegerd329c032008-11-26 14:50:27 +0100259}
260
Sheng Yangad8ba2c2009-01-06 10:03:02 +0800261void kvm_arch_sync_events(struct kvm *kvm)
262{
263}
264
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100265void kvm_arch_destroy_vm(struct kvm *kvm)
266{
Christian Borntraegerd329c032008-11-26 14:50:27 +0100267 kvm_free_vcpus(kvm);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100268 free_page((unsigned long)(kvm->arch.sca));
Christian Borntraegerd329c032008-11-26 14:50:27 +0100269 debug_unregister(kvm->arch.dbf);
Carsten Otte27e03932012-01-04 10:25:21 +0100270 if (!kvm_is_ucontrol(kvm))
271 gmap_free(kvm->arch.gmap);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100272}
273
274/* Section: vcpu related */
275int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
276{
Carsten Otte27e03932012-01-04 10:25:21 +0100277 if (kvm_is_ucontrol(vcpu->kvm)) {
278 vcpu->arch.gmap = gmap_alloc(current->mm);
279 if (!vcpu->arch.gmap)
280 return -ENOMEM;
281 return 0;
282 }
283
Carsten Otte598841c2011-07-24 10:48:21 +0200284 vcpu->arch.gmap = vcpu->kvm->arch.gmap;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100285 return 0;
286}
287
288void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
289{
Christian Borntraeger6692cef2008-11-26 14:51:08 +0100290 /* Nothing todo */
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100291}
292
293void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
294{
295 save_fp_regs(&vcpu->arch.host_fpregs);
296 save_access_regs(vcpu->arch.host_acrs);
297 vcpu->arch.guest_fpregs.fpc &= FPC_VALID_MASK;
298 restore_fp_regs(&vcpu->arch.guest_fpregs);
299 restore_access_regs(vcpu->arch.guest_acrs);
Christian Borntraeger480e5922011-09-20 17:07:28 +0200300 gmap_enable(vcpu->arch.gmap);
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100301 atomic_set_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100302}
303
304void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
305{
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100306 atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
Christian Borntraeger480e5922011-09-20 17:07:28 +0200307 gmap_disable(vcpu->arch.gmap);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100308 save_fp_regs(&vcpu->arch.guest_fpregs);
309 save_access_regs(vcpu->arch.guest_acrs);
310 restore_fp_regs(&vcpu->arch.host_fpregs);
311 restore_access_regs(vcpu->arch.host_acrs);
312}
313
314static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu)
315{
316 /* this equals initial cpu reset in pop, but we don't switch to ESA */
317 vcpu->arch.sie_block->gpsw.mask = 0UL;
318 vcpu->arch.sie_block->gpsw.addr = 0UL;
319 vcpu->arch.sie_block->prefix = 0UL;
320 vcpu->arch.sie_block->ihcpu = 0xffff;
321 vcpu->arch.sie_block->cputm = 0UL;
322 vcpu->arch.sie_block->ckc = 0UL;
323 vcpu->arch.sie_block->todpr = 0;
324 memset(vcpu->arch.sie_block->gcr, 0, 16 * sizeof(__u64));
325 vcpu->arch.sie_block->gcr[0] = 0xE0UL;
326 vcpu->arch.sie_block->gcr[14] = 0xC2000000UL;
327 vcpu->arch.guest_fpregs.fpc = 0;
328 asm volatile("lfpc %0" : : "Q" (vcpu->arch.guest_fpregs.fpc));
329 vcpu->arch.sie_block->gbea = 1;
330}
331
332int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
333{
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100334 atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH |
335 CPUSTAT_SM |
336 CPUSTAT_STOPPED);
Christian Borntraegerfc345312010-06-17 23:16:20 +0200337 vcpu->arch.sie_block->ecb = 6;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100338 vcpu->arch.sie_block->eca = 0xC1002001U;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200339 vcpu->arch.sie_block->fac = (int) (long) facilities;
Christian Borntraegerca872302009-05-12 17:21:49 +0200340 hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
341 tasklet_init(&vcpu->arch.tasklet, kvm_s390_tasklet,
342 (unsigned long) vcpu);
343 vcpu->arch.ckc_timer.function = kvm_s390_idle_wakeup;
Christian Borntraeger453423d2008-03-25 18:47:29 +0100344 get_cpu_id(&vcpu->arch.cpu_id);
Christian Borntraeger92e6ecf2009-03-26 15:23:58 +0100345 vcpu->arch.cpu_id.version = 0xff;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100346 return 0;
347}
348
349struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
350 unsigned int id)
351{
Carsten Otte4d475552011-10-18 12:27:12 +0200352 struct kvm_vcpu *vcpu;
353 int rc = -EINVAL;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100354
Carsten Otte4d475552011-10-18 12:27:12 +0200355 if (id >= KVM_MAX_VCPUS)
356 goto out;
357
358 rc = -ENOMEM;
359
360 vcpu = kzalloc(sizeof(struct kvm_vcpu), GFP_KERNEL);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100361 if (!vcpu)
Carsten Otte4d475552011-10-18 12:27:12 +0200362 goto out;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100363
Christian Borntraeger180c12f2008-06-27 15:05:40 +0200364 vcpu->arch.sie_block = (struct kvm_s390_sie_block *)
365 get_zeroed_page(GFP_KERNEL);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100366
367 if (!vcpu->arch.sie_block)
368 goto out_free_cpu;
369
370 vcpu->arch.sie_block->icpua = id;
371 BUG_ON(!kvm->arch.sca);
Carsten Otteabf4a712009-05-12 17:21:51 +0200372 if (!kvm->arch.sca->cpu[id].sda)
373 kvm->arch.sca->cpu[id].sda = (__u64) vcpu->arch.sie_block;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100374 vcpu->arch.sie_block->scaoh = (__u32)(((__u64)kvm->arch.sca) >> 32);
375 vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca;
Christian Borntraegerfc345312010-06-17 23:16:20 +0200376 set_bit(63 - id, (unsigned long *) &kvm->arch.sca->mcn);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100377
Carsten Otteba5c1e92008-03-25 18:47:26 +0100378 spin_lock_init(&vcpu->arch.local_int.lock);
379 INIT_LIST_HEAD(&vcpu->arch.local_int.list);
380 vcpu->arch.local_int.float_int = &kvm->arch.float_int;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200381 spin_lock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100382 kvm->arch.float_int.local_int[id] = &vcpu->arch.local_int;
383 init_waitqueue_head(&vcpu->arch.local_int.wq);
Christian Borntraeger5288fbf2008-03-25 18:47:31 +0100384 vcpu->arch.local_int.cpuflags = &vcpu->arch.sie_block->cpuflags;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200385 spin_unlock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100386
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100387 rc = kvm_vcpu_init(vcpu, kvm, id);
388 if (rc)
Wei Yongjun7b06bf22010-03-09 14:37:53 +0800389 goto out_free_sie_block;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100390 VM_EVENT(kvm, 3, "create cpu %d at %p, sie block at %p", id, vcpu,
391 vcpu->arch.sie_block);
392
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100393 return vcpu;
Wei Yongjun7b06bf22010-03-09 14:37:53 +0800394out_free_sie_block:
395 free_page((unsigned long)(vcpu->arch.sie_block));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100396out_free_cpu:
397 kfree(vcpu);
Carsten Otte4d475552011-10-18 12:27:12 +0200398out:
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100399 return ERR_PTR(rc);
400}
401
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100402int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
403{
404 /* kvm common code refers to this, but never calls it */
405 BUG();
406 return 0;
407}
408
409static int kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu)
410{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100411 kvm_s390_vcpu_initial_reset(vcpu);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100412 return 0;
413}
414
415int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
416{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100417 memcpy(&vcpu->arch.guest_gprs, &regs->gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100418 return 0;
419}
420
421int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
422{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100423 memcpy(&regs->gprs, &vcpu->arch.guest_gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100424 return 0;
425}
426
427int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
428 struct kvm_sregs *sregs)
429{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100430 memcpy(&vcpu->arch.guest_acrs, &sregs->acrs, sizeof(sregs->acrs));
431 memcpy(&vcpu->arch.sie_block->gcr, &sregs->crs, sizeof(sregs->crs));
Carsten Otte7eef87d2011-10-18 12:27:14 +0200432 restore_access_regs(vcpu->arch.guest_acrs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100433 return 0;
434}
435
436int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
437 struct kvm_sregs *sregs)
438{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100439 memcpy(&sregs->acrs, &vcpu->arch.guest_acrs, sizeof(sregs->acrs));
440 memcpy(&sregs->crs, &vcpu->arch.sie_block->gcr, sizeof(sregs->crs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100441 return 0;
442}
443
444int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
445{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100446 memcpy(&vcpu->arch.guest_fpregs.fprs, &fpu->fprs, sizeof(fpu->fprs));
447 vcpu->arch.guest_fpregs.fpc = fpu->fpc;
Carsten Otte7eef87d2011-10-18 12:27:14 +0200448 restore_fp_regs(&vcpu->arch.guest_fpregs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100449 return 0;
450}
451
452int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
453{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100454 memcpy(&fpu->fprs, &vcpu->arch.guest_fpregs.fprs, sizeof(fpu->fprs));
455 fpu->fpc = vcpu->arch.guest_fpregs.fpc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100456 return 0;
457}
458
459static int kvm_arch_vcpu_ioctl_set_initial_psw(struct kvm_vcpu *vcpu, psw_t psw)
460{
461 int rc = 0;
462
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100463 if (!(atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_STOPPED))
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100464 rc = -EBUSY;
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100465 else {
466 vcpu->run->psw_mask = psw.mask;
467 vcpu->run->psw_addr = psw.addr;
468 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100469 return rc;
470}
471
472int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
473 struct kvm_translation *tr)
474{
475 return -EINVAL; /* not implemented yet */
476}
477
Jan Kiszkad0bfb942008-12-15 13:52:10 +0100478int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
479 struct kvm_guest_debug *dbg)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100480{
481 return -EINVAL; /* not implemented yet */
482}
483
Marcelo Tosatti62d9f0d2008-04-11 13:24:45 -0300484int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
485 struct kvm_mp_state *mp_state)
486{
487 return -EINVAL; /* not implemented yet */
488}
489
490int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
491 struct kvm_mp_state *mp_state)
492{
493 return -EINVAL; /* not implemented yet */
494}
495
Carsten Ottee168bf82012-01-04 10:25:22 +0100496static int __vcpu_run(struct kvm_vcpu *vcpu)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100497{
Carsten Ottee168bf82012-01-04 10:25:22 +0100498 int rc;
499
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100500 memcpy(&vcpu->arch.sie_block->gg14, &vcpu->arch.guest_gprs[14], 16);
501
502 if (need_resched())
503 schedule();
504
Christian Borntraeger71cde582008-05-21 13:37:34 +0200505 if (test_thread_flag(TIF_MCCK_PENDING))
506 s390_handle_mcck();
507
Carsten Otted6b6d162012-01-04 10:25:25 +0100508 if (!kvm_is_ucontrol(vcpu->kvm))
509 kvm_s390_deliver_pending_interrupts(vcpu);
Carsten Otte0ff31862008-05-21 13:37:37 +0200510
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100511 vcpu->arch.sie_block->icptcode = 0;
512 local_irq_disable();
513 kvm_guest_enter();
514 local_irq_enable();
515 VCPU_EVENT(vcpu, 6, "entering sie flags %x",
516 atomic_read(&vcpu->arch.sie_block->cpuflags));
Carsten Ottee168bf82012-01-04 10:25:22 +0100517 rc = sie64a(vcpu->arch.sie_block, vcpu->arch.guest_gprs);
518 if (rc) {
519 if (kvm_is_ucontrol(vcpu->kvm)) {
520 rc = SIE_INTERCEPT_UCONTROL;
521 } else {
522 VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction");
523 kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
524 rc = 0;
525 }
Carsten Otte1f0d0f02008-05-21 13:37:40 +0200526 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100527 VCPU_EVENT(vcpu, 6, "exit sie icptcode %d",
528 vcpu->arch.sie_block->icptcode);
529 local_irq_disable();
530 kvm_guest_exit();
531 local_irq_enable();
532
533 memcpy(&vcpu->arch.guest_gprs[14], &vcpu->arch.sie_block->gg14, 16);
Carsten Ottee168bf82012-01-04 10:25:22 +0100534 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100535}
536
537int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
538{
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100539 int rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100540 sigset_t sigsaved;
541
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200542rerun_vcpu:
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100543 if (vcpu->sigset_active)
544 sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
545
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100546 atomic_clear_mask(CPUSTAT_STOPPED, &vcpu->arch.sie_block->cpuflags);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100547
Carsten Otteba5c1e92008-03-25 18:47:26 +0100548 BUG_ON(vcpu->kvm->arch.float_int.local_int[vcpu->vcpu_id] == NULL);
549
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100550 switch (kvm_run->exit_reason) {
551 case KVM_EXIT_S390_SIEIC:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100552 case KVM_EXIT_UNKNOWN:
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200553 case KVM_EXIT_INTR:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100554 case KVM_EXIT_S390_RESET:
Carsten Ottee168bf82012-01-04 10:25:22 +0100555 case KVM_EXIT_S390_UCONTROL:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100556 break;
557 default:
558 BUG();
559 }
560
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100561 vcpu->arch.sie_block->gpsw.mask = kvm_run->psw_mask;
562 vcpu->arch.sie_block->gpsw.addr = kvm_run->psw_addr;
563
Heiko Carstensdab4079d2009-06-12 10:26:32 +0200564 might_fault();
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100565
566 do {
Carsten Ottee168bf82012-01-04 10:25:22 +0100567 rc = __vcpu_run(vcpu);
568 if (rc)
569 break;
Carsten Ottec0d744a2012-01-04 10:25:24 +0100570 if (kvm_is_ucontrol(vcpu->kvm))
571 rc = -EOPNOTSUPP;
572 else
573 rc = kvm_handle_sie_intercept(vcpu);
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100574 } while (!signal_pending(current) && !rc);
575
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200576 if (rc == SIE_INTERCEPT_RERUNVCPU)
577 goto rerun_vcpu;
578
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200579 if (signal_pending(current) && !rc) {
580 kvm_run->exit_reason = KVM_EXIT_INTR;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100581 rc = -EINTR;
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200582 }
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100583
Carsten Ottee168bf82012-01-04 10:25:22 +0100584#ifdef CONFIG_KVM_S390_UCONTROL
585 if (rc == SIE_INTERCEPT_UCONTROL) {
586 kvm_run->exit_reason = KVM_EXIT_S390_UCONTROL;
587 kvm_run->s390_ucontrol.trans_exc_code =
588 current->thread.gmap_addr;
589 kvm_run->s390_ucontrol.pgm_code = 0x10;
590 rc = 0;
591 }
592#endif
593
Heiko Carstensb8e660b2010-02-26 22:37:41 +0100594 if (rc == -EOPNOTSUPP) {
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100595 /* intercept cannot be handled in-kernel, prepare kvm-run */
596 kvm_run->exit_reason = KVM_EXIT_S390_SIEIC;
597 kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100598 kvm_run->s390_sieic.ipa = vcpu->arch.sie_block->ipa;
599 kvm_run->s390_sieic.ipb = vcpu->arch.sie_block->ipb;
600 rc = 0;
601 }
602
603 if (rc == -EREMOTE) {
604 /* intercept was handled, but userspace support is needed
605 * kvm_run has been prepared by the handler */
606 rc = 0;
607 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100608
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100609 kvm_run->psw_mask = vcpu->arch.sie_block->gpsw.mask;
610 kvm_run->psw_addr = vcpu->arch.sie_block->gpsw.addr;
611
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100612 if (vcpu->sigset_active)
613 sigprocmask(SIG_SETMASK, &sigsaved, NULL);
614
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100615 vcpu->stat.exit_userspace++;
Heiko Carstens7e8e6ab2008-04-04 15:12:35 +0200616 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100617}
618
Carsten Otte092670c2011-07-24 10:48:22 +0200619static int __guestcopy(struct kvm_vcpu *vcpu, u64 guestdest, void *from,
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100620 unsigned long n, int prefix)
621{
622 if (prefix)
623 return copy_to_guest(vcpu, guestdest, from, n);
624 else
625 return copy_to_guest_absolute(vcpu, guestdest, from, n);
626}
627
628/*
629 * store status at address
630 * we use have two special cases:
631 * KVM_S390_STORE_STATUS_NOADDR: -> 0x1200 on 64 bit
632 * KVM_S390_STORE_STATUS_PREFIXED: -> prefix
633 */
Christian Borntraeger971eb772010-06-12 08:54:13 +0200634int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100635{
Carsten Otte092670c2011-07-24 10:48:22 +0200636 unsigned char archmode = 1;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100637 int prefix;
638
639 if (addr == KVM_S390_STORE_STATUS_NOADDR) {
640 if (copy_to_guest_absolute(vcpu, 163ul, &archmode, 1))
641 return -EFAULT;
642 addr = SAVE_AREA_BASE;
643 prefix = 0;
644 } else if (addr == KVM_S390_STORE_STATUS_PREFIXED) {
645 if (copy_to_guest(vcpu, 163ul, &archmode, 1))
646 return -EFAULT;
647 addr = SAVE_AREA_BASE;
648 prefix = 1;
649 } else
650 prefix = 0;
651
Heiko Carstensf64ca212010-02-26 22:37:32 +0100652 if (__guestcopy(vcpu, addr + offsetof(struct save_area, fp_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100653 vcpu->arch.guest_fpregs.fprs, 128, prefix))
654 return -EFAULT;
655
Heiko Carstensf64ca212010-02-26 22:37:32 +0100656 if (__guestcopy(vcpu, addr + offsetof(struct save_area, gp_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100657 vcpu->arch.guest_gprs, 128, prefix))
658 return -EFAULT;
659
Heiko Carstensf64ca212010-02-26 22:37:32 +0100660 if (__guestcopy(vcpu, addr + offsetof(struct save_area, psw),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100661 &vcpu->arch.sie_block->gpsw, 16, prefix))
662 return -EFAULT;
663
Heiko Carstensf64ca212010-02-26 22:37:32 +0100664 if (__guestcopy(vcpu, addr + offsetof(struct save_area, pref_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100665 &vcpu->arch.sie_block->prefix, 4, prefix))
666 return -EFAULT;
667
668 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100669 addr + offsetof(struct save_area, fp_ctrl_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100670 &vcpu->arch.guest_fpregs.fpc, 4, prefix))
671 return -EFAULT;
672
Heiko Carstensf64ca212010-02-26 22:37:32 +0100673 if (__guestcopy(vcpu, addr + offsetof(struct save_area, tod_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100674 &vcpu->arch.sie_block->todpr, 4, prefix))
675 return -EFAULT;
676
Heiko Carstensf64ca212010-02-26 22:37:32 +0100677 if (__guestcopy(vcpu, addr + offsetof(struct save_area, timer),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100678 &vcpu->arch.sie_block->cputm, 8, prefix))
679 return -EFAULT;
680
Heiko Carstensf64ca212010-02-26 22:37:32 +0100681 if (__guestcopy(vcpu, addr + offsetof(struct save_area, clk_cmp),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100682 &vcpu->arch.sie_block->ckc, 8, prefix))
683 return -EFAULT;
684
Heiko Carstensf64ca212010-02-26 22:37:32 +0100685 if (__guestcopy(vcpu, addr + offsetof(struct save_area, acc_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100686 &vcpu->arch.guest_acrs, 64, prefix))
687 return -EFAULT;
688
689 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100690 addr + offsetof(struct save_area, ctrl_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100691 &vcpu->arch.sie_block->gcr, 128, prefix))
692 return -EFAULT;
693 return 0;
694}
695
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100696long kvm_arch_vcpu_ioctl(struct file *filp,
697 unsigned int ioctl, unsigned long arg)
698{
699 struct kvm_vcpu *vcpu = filp->private_data;
700 void __user *argp = (void __user *)arg;
Avi Kivitybc923cc2010-05-13 12:21:46 +0300701 long r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100702
Avi Kivity93736622010-05-13 12:35:17 +0300703 switch (ioctl) {
704 case KVM_S390_INTERRUPT: {
Carsten Otteba5c1e92008-03-25 18:47:26 +0100705 struct kvm_s390_interrupt s390int;
706
Avi Kivity93736622010-05-13 12:35:17 +0300707 r = -EFAULT;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100708 if (copy_from_user(&s390int, argp, sizeof(s390int)))
Avi Kivity93736622010-05-13 12:35:17 +0300709 break;
710 r = kvm_s390_inject_vcpu(vcpu, &s390int);
711 break;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100712 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100713 case KVM_S390_STORE_STATUS:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300714 r = kvm_s390_vcpu_store_status(vcpu, arg);
715 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100716 case KVM_S390_SET_INITIAL_PSW: {
717 psw_t psw;
718
Avi Kivitybc923cc2010-05-13 12:21:46 +0300719 r = -EFAULT;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100720 if (copy_from_user(&psw, argp, sizeof(psw)))
Avi Kivitybc923cc2010-05-13 12:21:46 +0300721 break;
722 r = kvm_arch_vcpu_ioctl_set_initial_psw(vcpu, psw);
723 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100724 }
725 case KVM_S390_INITIAL_RESET:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300726 r = kvm_arch_vcpu_ioctl_initial_reset(vcpu);
727 break;
Carsten Otte27e03932012-01-04 10:25:21 +0100728#ifdef CONFIG_KVM_S390_UCONTROL
729 case KVM_S390_UCAS_MAP: {
730 struct kvm_s390_ucas_mapping ucasmap;
731
732 if (copy_from_user(&ucasmap, argp, sizeof(ucasmap))) {
733 r = -EFAULT;
734 break;
735 }
736
737 if (!kvm_is_ucontrol(vcpu->kvm)) {
738 r = -EINVAL;
739 break;
740 }
741
742 r = gmap_map_segment(vcpu->arch.gmap, ucasmap.user_addr,
743 ucasmap.vcpu_addr, ucasmap.length);
744 break;
745 }
746 case KVM_S390_UCAS_UNMAP: {
747 struct kvm_s390_ucas_mapping ucasmap;
748
749 if (copy_from_user(&ucasmap, argp, sizeof(ucasmap))) {
750 r = -EFAULT;
751 break;
752 }
753
754 if (!kvm_is_ucontrol(vcpu->kvm)) {
755 r = -EINVAL;
756 break;
757 }
758
759 r = gmap_unmap_segment(vcpu->arch.gmap, ucasmap.vcpu_addr,
760 ucasmap.length);
761 break;
762 }
763#endif
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100764 default:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300765 r = -EINVAL;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100766 }
Avi Kivitybc923cc2010-05-13 12:21:46 +0300767 return r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100768}
769
Carsten Otte5b1c1492012-01-04 10:25:23 +0100770int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
771{
772#ifdef CONFIG_KVM_S390_UCONTROL
773 if ((vmf->pgoff == KVM_S390_SIE_PAGE_OFFSET)
774 && (kvm_is_ucontrol(vcpu->kvm))) {
775 vmf->page = virt_to_page(vcpu->arch.sie_block);
776 get_page(vmf->page);
777 return 0;
778 }
779#endif
780 return VM_FAULT_SIGBUS;
781}
782
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100783/* Section: memory related */
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200784int kvm_arch_prepare_memory_region(struct kvm *kvm,
785 struct kvm_memory_slot *memslot,
786 struct kvm_memory_slot old,
787 struct kvm_userspace_memory_region *mem,
788 int user_alloc)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100789{
790 /* A few sanity checks. We can have exactly one memory slot which has
791 to start at guest virtual zero and which has to be located at a
792 page boundary in userland and which has to end at a page boundary.
793 The memory in userland is ok to be fragmented into various different
794 vmas. It is okay to mmap() and munmap() stuff in this slot after
795 doing this call at any time */
796
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200797 if (mem->slot)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100798 return -EINVAL;
799
800 if (mem->guest_phys_addr)
801 return -EINVAL;
802
Carsten Otte598841c2011-07-24 10:48:21 +0200803 if (mem->userspace_addr & 0xffffful)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100804 return -EINVAL;
805
Carsten Otte598841c2011-07-24 10:48:21 +0200806 if (mem->memory_size & 0xffffful)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100807 return -EINVAL;
808
Carsten Otte2668dab2009-05-12 17:21:48 +0200809 if (!user_alloc)
810 return -EINVAL;
811
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200812 return 0;
813}
814
815void kvm_arch_commit_memory_region(struct kvm *kvm,
816 struct kvm_userspace_memory_region *mem,
817 struct kvm_memory_slot old,
818 int user_alloc)
819{
Carsten Ottef7850c92011-07-24 10:48:23 +0200820 int rc;
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200821
Carsten Otte598841c2011-07-24 10:48:21 +0200822
823 rc = gmap_map_segment(kvm->arch.gmap, mem->userspace_addr,
824 mem->guest_phys_addr, mem->memory_size);
825 if (rc)
Carsten Ottef7850c92011-07-24 10:48:23 +0200826 printk(KERN_WARNING "kvm-s390: failed to commit memory region\n");
Carsten Otte598841c2011-07-24 10:48:21 +0200827 return;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100828}
829
Marcelo Tosatti34d4cb82008-07-10 20:49:31 -0300830void kvm_arch_flush_shadow(struct kvm *kvm)
831{
832}
833
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100834static int __init kvm_s390_init(void)
835{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200836 int ret;
Avi Kivity0ee75be2010-04-28 15:39:01 +0300837 ret = kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE);
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200838 if (ret)
839 return ret;
840
841 /*
842 * guests can ask for up to 255+1 double words, we need a full page
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300843 * to hold the maximum amount of facilities. On the other hand, we
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200844 * only set facilities that are known to work in KVM.
845 */
Heiko Carstensc2f0e8c2010-06-08 18:58:09 +0200846 facilities = (unsigned long long *) get_zeroed_page(GFP_KERNEL|GFP_DMA);
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200847 if (!facilities) {
848 kvm_exit();
849 return -ENOMEM;
850 }
Martin Schwidefsky14375bc2010-10-25 16:10:51 +0200851 memcpy(facilities, S390_lowcore.stfle_fac_list, 16);
Christian Borntraeger6d00d002010-10-25 16:10:48 +0200852 facilities[0] &= 0xff00fff3f47c0000ULL;
Christian Borntraeger9950f8b2011-06-06 14:14:39 +0200853 facilities[1] &= 0x201c000000000000ULL;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200854 return 0;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100855}
856
857static void __exit kvm_s390_exit(void)
858{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200859 free_page((unsigned long) facilities);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100860 kvm_exit();
861}
862
863module_init(kvm_s390_init);
864module_exit(kvm_s390_exit);