blob: f0937552175b11be23a44bff6815aac82ed83a17 [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();
Christian Borntraegerd329c032008-11-26 14:50:27 +0100236 free_page((unsigned long)(vcpu->arch.sie_block));
Christian Borntraeger6692cef2008-11-26 14:51:08 +0100237 kvm_vcpu_uninit(vcpu);
Christian Borntraegerd329c032008-11-26 14:50:27 +0100238 kfree(vcpu);
239}
240
241static void kvm_free_vcpus(struct kvm *kvm)
242{
243 unsigned int i;
Gleb Natapov988a2ca2009-06-09 15:56:29 +0300244 struct kvm_vcpu *vcpu;
Christian Borntraegerd329c032008-11-26 14:50:27 +0100245
Gleb Natapov988a2ca2009-06-09 15:56:29 +0300246 kvm_for_each_vcpu(i, vcpu, kvm)
247 kvm_arch_vcpu_destroy(vcpu);
248
249 mutex_lock(&kvm->lock);
250 for (i = 0; i < atomic_read(&kvm->online_vcpus); i++)
251 kvm->vcpus[i] = NULL;
252
253 atomic_set(&kvm->online_vcpus, 0);
254 mutex_unlock(&kvm->lock);
Christian Borntraegerd329c032008-11-26 14:50:27 +0100255}
256
Sheng Yangad8ba2c2009-01-06 10:03:02 +0800257void kvm_arch_sync_events(struct kvm *kvm)
258{
259}
260
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100261void kvm_arch_destroy_vm(struct kvm *kvm)
262{
Christian Borntraegerd329c032008-11-26 14:50:27 +0100263 kvm_free_vcpus(kvm);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100264 free_page((unsigned long)(kvm->arch.sca));
Christian Borntraegerd329c032008-11-26 14:50:27 +0100265 debug_unregister(kvm->arch.dbf);
Carsten Otte598841c2011-07-24 10:48:21 +0200266 gmap_free(kvm->arch.gmap);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100267}
268
269/* Section: vcpu related */
270int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
271{
Carsten Otte598841c2011-07-24 10:48:21 +0200272 vcpu->arch.gmap = vcpu->kvm->arch.gmap;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100273 return 0;
274}
275
276void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
277{
Christian Borntraeger6692cef2008-11-26 14:51:08 +0100278 /* Nothing todo */
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100279}
280
281void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
282{
283 save_fp_regs(&vcpu->arch.host_fpregs);
284 save_access_regs(vcpu->arch.host_acrs);
285 vcpu->arch.guest_fpregs.fpc &= FPC_VALID_MASK;
286 restore_fp_regs(&vcpu->arch.guest_fpregs);
287 restore_access_regs(vcpu->arch.guest_acrs);
Christian Borntraeger480e5922011-09-20 17:07:28 +0200288 gmap_enable(vcpu->arch.gmap);
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100289 atomic_set_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100290}
291
292void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
293{
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100294 atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
Christian Borntraeger480e5922011-09-20 17:07:28 +0200295 gmap_disable(vcpu->arch.gmap);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100296 save_fp_regs(&vcpu->arch.guest_fpregs);
297 save_access_regs(vcpu->arch.guest_acrs);
298 restore_fp_regs(&vcpu->arch.host_fpregs);
299 restore_access_regs(vcpu->arch.host_acrs);
300}
301
302static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu)
303{
304 /* this equals initial cpu reset in pop, but we don't switch to ESA */
305 vcpu->arch.sie_block->gpsw.mask = 0UL;
306 vcpu->arch.sie_block->gpsw.addr = 0UL;
307 vcpu->arch.sie_block->prefix = 0UL;
308 vcpu->arch.sie_block->ihcpu = 0xffff;
309 vcpu->arch.sie_block->cputm = 0UL;
310 vcpu->arch.sie_block->ckc = 0UL;
311 vcpu->arch.sie_block->todpr = 0;
312 memset(vcpu->arch.sie_block->gcr, 0, 16 * sizeof(__u64));
313 vcpu->arch.sie_block->gcr[0] = 0xE0UL;
314 vcpu->arch.sie_block->gcr[14] = 0xC2000000UL;
315 vcpu->arch.guest_fpregs.fpc = 0;
316 asm volatile("lfpc %0" : : "Q" (vcpu->arch.guest_fpregs.fpc));
317 vcpu->arch.sie_block->gbea = 1;
318}
319
320int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
321{
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100322 atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH |
323 CPUSTAT_SM |
324 CPUSTAT_STOPPED);
Christian Borntraegerfc345312010-06-17 23:16:20 +0200325 vcpu->arch.sie_block->ecb = 6;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100326 vcpu->arch.sie_block->eca = 0xC1002001U;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200327 vcpu->arch.sie_block->fac = (int) (long) facilities;
Christian Borntraegerca872302009-05-12 17:21:49 +0200328 hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
329 tasklet_init(&vcpu->arch.tasklet, kvm_s390_tasklet,
330 (unsigned long) vcpu);
331 vcpu->arch.ckc_timer.function = kvm_s390_idle_wakeup;
Christian Borntraeger453423d2008-03-25 18:47:29 +0100332 get_cpu_id(&vcpu->arch.cpu_id);
Christian Borntraeger92e6ecf2009-03-26 15:23:58 +0100333 vcpu->arch.cpu_id.version = 0xff;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100334 return 0;
335}
336
337struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
338 unsigned int id)
339{
Carsten Otte4d475552011-10-18 12:27:12 +0200340 struct kvm_vcpu *vcpu;
341 int rc = -EINVAL;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100342
Carsten Otte4d475552011-10-18 12:27:12 +0200343 if (id >= KVM_MAX_VCPUS)
344 goto out;
345
346 rc = -ENOMEM;
347
348 vcpu = kzalloc(sizeof(struct kvm_vcpu), GFP_KERNEL);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100349 if (!vcpu)
Carsten Otte4d475552011-10-18 12:27:12 +0200350 goto out;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100351
Christian Borntraeger180c12f2008-06-27 15:05:40 +0200352 vcpu->arch.sie_block = (struct kvm_s390_sie_block *)
353 get_zeroed_page(GFP_KERNEL);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100354
355 if (!vcpu->arch.sie_block)
356 goto out_free_cpu;
357
358 vcpu->arch.sie_block->icpua = id;
359 BUG_ON(!kvm->arch.sca);
Carsten Otteabf4a712009-05-12 17:21:51 +0200360 if (!kvm->arch.sca->cpu[id].sda)
361 kvm->arch.sca->cpu[id].sda = (__u64) vcpu->arch.sie_block;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100362 vcpu->arch.sie_block->scaoh = (__u32)(((__u64)kvm->arch.sca) >> 32);
363 vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca;
Christian Borntraegerfc345312010-06-17 23:16:20 +0200364 set_bit(63 - id, (unsigned long *) &kvm->arch.sca->mcn);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100365
Carsten Otteba5c1e92008-03-25 18:47:26 +0100366 spin_lock_init(&vcpu->arch.local_int.lock);
367 INIT_LIST_HEAD(&vcpu->arch.local_int.list);
368 vcpu->arch.local_int.float_int = &kvm->arch.float_int;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200369 spin_lock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100370 kvm->arch.float_int.local_int[id] = &vcpu->arch.local_int;
371 init_waitqueue_head(&vcpu->arch.local_int.wq);
Christian Borntraeger5288fbf2008-03-25 18:47:31 +0100372 vcpu->arch.local_int.cpuflags = &vcpu->arch.sie_block->cpuflags;
Christian Borntraegerb037a4f2009-05-12 17:21:50 +0200373 spin_unlock(&kvm->arch.float_int.lock);
Carsten Otteba5c1e92008-03-25 18:47:26 +0100374
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100375 rc = kvm_vcpu_init(vcpu, kvm, id);
376 if (rc)
Wei Yongjun7b06bf22010-03-09 14:37:53 +0800377 goto out_free_sie_block;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100378 VM_EVENT(kvm, 3, "create cpu %d at %p, sie block at %p", id, vcpu,
379 vcpu->arch.sie_block);
380
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100381 return vcpu;
Wei Yongjun7b06bf22010-03-09 14:37:53 +0800382out_free_sie_block:
383 free_page((unsigned long)(vcpu->arch.sie_block));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100384out_free_cpu:
385 kfree(vcpu);
Carsten Otte4d475552011-10-18 12:27:12 +0200386out:
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100387 return ERR_PTR(rc);
388}
389
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100390int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
391{
392 /* kvm common code refers to this, but never calls it */
393 BUG();
394 return 0;
395}
396
397static int kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu)
398{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100399 kvm_s390_vcpu_initial_reset(vcpu);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100400 return 0;
401}
402
403int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
404{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100405 memcpy(&vcpu->arch.guest_gprs, &regs->gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100406 return 0;
407}
408
409int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
410{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100411 memcpy(&regs->gprs, &vcpu->arch.guest_gprs, sizeof(regs->gprs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100412 return 0;
413}
414
415int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
416 struct kvm_sregs *sregs)
417{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100418 memcpy(&vcpu->arch.guest_acrs, &sregs->acrs, sizeof(sregs->acrs));
419 memcpy(&vcpu->arch.sie_block->gcr, &sregs->crs, sizeof(sregs->crs));
Carsten Otte7eef87d2011-10-18 12:27:14 +0200420 restore_access_regs(vcpu->arch.guest_acrs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100421 return 0;
422}
423
424int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
425 struct kvm_sregs *sregs)
426{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100427 memcpy(&sregs->acrs, &vcpu->arch.guest_acrs, sizeof(sregs->acrs));
428 memcpy(&sregs->crs, &vcpu->arch.sie_block->gcr, sizeof(sregs->crs));
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100429 return 0;
430}
431
432int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
433{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100434 memcpy(&vcpu->arch.guest_fpregs.fprs, &fpu->fprs, sizeof(fpu->fprs));
435 vcpu->arch.guest_fpregs.fpc = fpu->fpc;
Carsten Otte7eef87d2011-10-18 12:27:14 +0200436 restore_fp_regs(&vcpu->arch.guest_fpregs);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100437 return 0;
438}
439
440int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
441{
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100442 memcpy(&fpu->fprs, &vcpu->arch.guest_fpregs.fprs, sizeof(fpu->fprs));
443 fpu->fpc = vcpu->arch.guest_fpregs.fpc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100444 return 0;
445}
446
447static int kvm_arch_vcpu_ioctl_set_initial_psw(struct kvm_vcpu *vcpu, psw_t psw)
448{
449 int rc = 0;
450
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100451 if (!(atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_STOPPED))
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100452 rc = -EBUSY;
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100453 else {
454 vcpu->run->psw_mask = psw.mask;
455 vcpu->run->psw_addr = psw.addr;
456 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100457 return rc;
458}
459
460int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
461 struct kvm_translation *tr)
462{
463 return -EINVAL; /* not implemented yet */
464}
465
Jan Kiszkad0bfb942008-12-15 13:52:10 +0100466int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
467 struct kvm_guest_debug *dbg)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100468{
469 return -EINVAL; /* not implemented yet */
470}
471
Marcelo Tosatti62d9f0d2008-04-11 13:24:45 -0300472int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
473 struct kvm_mp_state *mp_state)
474{
475 return -EINVAL; /* not implemented yet */
476}
477
478int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
479 struct kvm_mp_state *mp_state)
480{
481 return -EINVAL; /* not implemented yet */
482}
483
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100484static void __vcpu_run(struct kvm_vcpu *vcpu)
485{
486 memcpy(&vcpu->arch.sie_block->gg14, &vcpu->arch.guest_gprs[14], 16);
487
488 if (need_resched())
489 schedule();
490
Christian Borntraeger71cde582008-05-21 13:37:34 +0200491 if (test_thread_flag(TIF_MCCK_PENDING))
492 s390_handle_mcck();
493
Carsten Otte0ff31862008-05-21 13:37:37 +0200494 kvm_s390_deliver_pending_interrupts(vcpu);
495
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100496 vcpu->arch.sie_block->icptcode = 0;
497 local_irq_disable();
498 kvm_guest_enter();
499 local_irq_enable();
500 VCPU_EVENT(vcpu, 6, "entering sie flags %x",
501 atomic_read(&vcpu->arch.sie_block->cpuflags));
Carsten Otte1f0d0f02008-05-21 13:37:40 +0200502 if (sie64a(vcpu->arch.sie_block, vcpu->arch.guest_gprs)) {
503 VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction");
504 kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
505 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100506 VCPU_EVENT(vcpu, 6, "exit sie icptcode %d",
507 vcpu->arch.sie_block->icptcode);
508 local_irq_disable();
509 kvm_guest_exit();
510 local_irq_enable();
511
512 memcpy(&vcpu->arch.guest_gprs[14], &vcpu->arch.sie_block->gg14, 16);
513}
514
515int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
516{
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100517 int rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100518 sigset_t sigsaved;
519
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200520rerun_vcpu:
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100521 if (vcpu->sigset_active)
522 sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
523
Cornelia Huck9e6dabe2011-11-17 11:00:41 +0100524 atomic_clear_mask(CPUSTAT_STOPPED, &vcpu->arch.sie_block->cpuflags);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100525
Carsten Otteba5c1e92008-03-25 18:47:26 +0100526 BUG_ON(vcpu->kvm->arch.float_int.local_int[vcpu->vcpu_id] == NULL);
527
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100528 switch (kvm_run->exit_reason) {
529 case KVM_EXIT_S390_SIEIC:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100530 case KVM_EXIT_UNKNOWN:
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200531 case KVM_EXIT_INTR:
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100532 case KVM_EXIT_S390_RESET:
533 break;
534 default:
535 BUG();
536 }
537
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100538 vcpu->arch.sie_block->gpsw.mask = kvm_run->psw_mask;
539 vcpu->arch.sie_block->gpsw.addr = kvm_run->psw_addr;
540
Heiko Carstensdab4079d2009-06-12 10:26:32 +0200541 might_fault();
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100542
543 do {
544 __vcpu_run(vcpu);
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100545 rc = kvm_handle_sie_intercept(vcpu);
546 } while (!signal_pending(current) && !rc);
547
Christian Ehrhardt9ace9032009-05-20 15:34:55 +0200548 if (rc == SIE_INTERCEPT_RERUNVCPU)
549 goto rerun_vcpu;
550
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200551 if (signal_pending(current) && !rc) {
552 kvm_run->exit_reason = KVM_EXIT_INTR;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100553 rc = -EINTR;
Christian Ehrhardtb1d16c42009-05-20 15:34:56 +0200554 }
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100555
Heiko Carstensb8e660b2010-02-26 22:37:41 +0100556 if (rc == -EOPNOTSUPP) {
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100557 /* intercept cannot be handled in-kernel, prepare kvm-run */
558 kvm_run->exit_reason = KVM_EXIT_S390_SIEIC;
559 kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode;
Christian Borntraeger8f2abe62008-03-25 18:47:23 +0100560 kvm_run->s390_sieic.ipa = vcpu->arch.sie_block->ipa;
561 kvm_run->s390_sieic.ipb = vcpu->arch.sie_block->ipb;
562 rc = 0;
563 }
564
565 if (rc == -EREMOTE) {
566 /* intercept was handled, but userspace support is needed
567 * kvm_run has been prepared by the handler */
568 rc = 0;
569 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100570
Carsten Otted7b0b5e2009-11-19 14:21:16 +0100571 kvm_run->psw_mask = vcpu->arch.sie_block->gpsw.mask;
572 kvm_run->psw_addr = vcpu->arch.sie_block->gpsw.addr;
573
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100574 if (vcpu->sigset_active)
575 sigprocmask(SIG_SETMASK, &sigsaved, NULL);
576
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100577 vcpu->stat.exit_userspace++;
Heiko Carstens7e8e6ab2008-04-04 15:12:35 +0200578 return rc;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100579}
580
Carsten Otte092670c2011-07-24 10:48:22 +0200581static int __guestcopy(struct kvm_vcpu *vcpu, u64 guestdest, void *from,
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100582 unsigned long n, int prefix)
583{
584 if (prefix)
585 return copy_to_guest(vcpu, guestdest, from, n);
586 else
587 return copy_to_guest_absolute(vcpu, guestdest, from, n);
588}
589
590/*
591 * store status at address
592 * we use have two special cases:
593 * KVM_S390_STORE_STATUS_NOADDR: -> 0x1200 on 64 bit
594 * KVM_S390_STORE_STATUS_PREFIXED: -> prefix
595 */
Christian Borntraeger971eb772010-06-12 08:54:13 +0200596int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100597{
Carsten Otte092670c2011-07-24 10:48:22 +0200598 unsigned char archmode = 1;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100599 int prefix;
600
601 if (addr == KVM_S390_STORE_STATUS_NOADDR) {
602 if (copy_to_guest_absolute(vcpu, 163ul, &archmode, 1))
603 return -EFAULT;
604 addr = SAVE_AREA_BASE;
605 prefix = 0;
606 } else if (addr == KVM_S390_STORE_STATUS_PREFIXED) {
607 if (copy_to_guest(vcpu, 163ul, &archmode, 1))
608 return -EFAULT;
609 addr = SAVE_AREA_BASE;
610 prefix = 1;
611 } else
612 prefix = 0;
613
Heiko Carstensf64ca212010-02-26 22:37:32 +0100614 if (__guestcopy(vcpu, addr + offsetof(struct save_area, fp_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100615 vcpu->arch.guest_fpregs.fprs, 128, prefix))
616 return -EFAULT;
617
Heiko Carstensf64ca212010-02-26 22:37:32 +0100618 if (__guestcopy(vcpu, addr + offsetof(struct save_area, gp_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100619 vcpu->arch.guest_gprs, 128, prefix))
620 return -EFAULT;
621
Heiko Carstensf64ca212010-02-26 22:37:32 +0100622 if (__guestcopy(vcpu, addr + offsetof(struct save_area, psw),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100623 &vcpu->arch.sie_block->gpsw, 16, prefix))
624 return -EFAULT;
625
Heiko Carstensf64ca212010-02-26 22:37:32 +0100626 if (__guestcopy(vcpu, addr + offsetof(struct save_area, pref_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100627 &vcpu->arch.sie_block->prefix, 4, prefix))
628 return -EFAULT;
629
630 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100631 addr + offsetof(struct save_area, fp_ctrl_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100632 &vcpu->arch.guest_fpregs.fpc, 4, prefix))
633 return -EFAULT;
634
Heiko Carstensf64ca212010-02-26 22:37:32 +0100635 if (__guestcopy(vcpu, addr + offsetof(struct save_area, tod_reg),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100636 &vcpu->arch.sie_block->todpr, 4, prefix))
637 return -EFAULT;
638
Heiko Carstensf64ca212010-02-26 22:37:32 +0100639 if (__guestcopy(vcpu, addr + offsetof(struct save_area, timer),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100640 &vcpu->arch.sie_block->cputm, 8, prefix))
641 return -EFAULT;
642
Heiko Carstensf64ca212010-02-26 22:37:32 +0100643 if (__guestcopy(vcpu, addr + offsetof(struct save_area, clk_cmp),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100644 &vcpu->arch.sie_block->ckc, 8, prefix))
645 return -EFAULT;
646
Heiko Carstensf64ca212010-02-26 22:37:32 +0100647 if (__guestcopy(vcpu, addr + offsetof(struct save_area, acc_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100648 &vcpu->arch.guest_acrs, 64, prefix))
649 return -EFAULT;
650
651 if (__guestcopy(vcpu,
Heiko Carstensf64ca212010-02-26 22:37:32 +0100652 addr + offsetof(struct save_area, ctrl_regs),
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100653 &vcpu->arch.sie_block->gcr, 128, prefix))
654 return -EFAULT;
655 return 0;
656}
657
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100658long kvm_arch_vcpu_ioctl(struct file *filp,
659 unsigned int ioctl, unsigned long arg)
660{
661 struct kvm_vcpu *vcpu = filp->private_data;
662 void __user *argp = (void __user *)arg;
Avi Kivitybc923cc2010-05-13 12:21:46 +0300663 long r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100664
Avi Kivity93736622010-05-13 12:35:17 +0300665 switch (ioctl) {
666 case KVM_S390_INTERRUPT: {
Carsten Otteba5c1e92008-03-25 18:47:26 +0100667 struct kvm_s390_interrupt s390int;
668
Avi Kivity93736622010-05-13 12:35:17 +0300669 r = -EFAULT;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100670 if (copy_from_user(&s390int, argp, sizeof(s390int)))
Avi Kivity93736622010-05-13 12:35:17 +0300671 break;
672 r = kvm_s390_inject_vcpu(vcpu, &s390int);
673 break;
Carsten Otteba5c1e92008-03-25 18:47:26 +0100674 }
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100675 case KVM_S390_STORE_STATUS:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300676 r = kvm_s390_vcpu_store_status(vcpu, arg);
677 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100678 case KVM_S390_SET_INITIAL_PSW: {
679 psw_t psw;
680
Avi Kivitybc923cc2010-05-13 12:21:46 +0300681 r = -EFAULT;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100682 if (copy_from_user(&psw, argp, sizeof(psw)))
Avi Kivitybc923cc2010-05-13 12:21:46 +0300683 break;
684 r = kvm_arch_vcpu_ioctl_set_initial_psw(vcpu, psw);
685 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100686 }
687 case KVM_S390_INITIAL_RESET:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300688 r = kvm_arch_vcpu_ioctl_initial_reset(vcpu);
689 break;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100690 default:
Avi Kivitybc923cc2010-05-13 12:21:46 +0300691 r = -EINVAL;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100692 }
Avi Kivitybc923cc2010-05-13 12:21:46 +0300693 return r;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100694}
695
696/* Section: memory related */
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200697int kvm_arch_prepare_memory_region(struct kvm *kvm,
698 struct kvm_memory_slot *memslot,
699 struct kvm_memory_slot old,
700 struct kvm_userspace_memory_region *mem,
701 int user_alloc)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100702{
703 /* A few sanity checks. We can have exactly one memory slot which has
704 to start at guest virtual zero and which has to be located at a
705 page boundary in userland and which has to end at a page boundary.
706 The memory in userland is ok to be fragmented into various different
707 vmas. It is okay to mmap() and munmap() stuff in this slot after
708 doing this call at any time */
709
Christian Ehrhardt628eb9b2009-05-25 13:40:51 +0200710 if (mem->slot)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100711 return -EINVAL;
712
713 if (mem->guest_phys_addr)
714 return -EINVAL;
715
Carsten Otte598841c2011-07-24 10:48:21 +0200716 if (mem->userspace_addr & 0xffffful)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100717 return -EINVAL;
718
Carsten Otte598841c2011-07-24 10:48:21 +0200719 if (mem->memory_size & 0xffffful)
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100720 return -EINVAL;
721
Carsten Otte2668dab2009-05-12 17:21:48 +0200722 if (!user_alloc)
723 return -EINVAL;
724
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200725 return 0;
726}
727
728void kvm_arch_commit_memory_region(struct kvm *kvm,
729 struct kvm_userspace_memory_region *mem,
730 struct kvm_memory_slot old,
731 int user_alloc)
732{
Carsten Ottef7850c92011-07-24 10:48:23 +0200733 int rc;
Marcelo Tosattif7784b82009-12-23 14:35:18 -0200734
Carsten Otte598841c2011-07-24 10:48:21 +0200735
736 rc = gmap_map_segment(kvm->arch.gmap, mem->userspace_addr,
737 mem->guest_phys_addr, mem->memory_size);
738 if (rc)
Carsten Ottef7850c92011-07-24 10:48:23 +0200739 printk(KERN_WARNING "kvm-s390: failed to commit memory region\n");
Carsten Otte598841c2011-07-24 10:48:21 +0200740 return;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100741}
742
Marcelo Tosatti34d4cb82008-07-10 20:49:31 -0300743void kvm_arch_flush_shadow(struct kvm *kvm)
744{
745}
746
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100747static int __init kvm_s390_init(void)
748{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200749 int ret;
Avi Kivity0ee75be2010-04-28 15:39:01 +0300750 ret = kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE);
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200751 if (ret)
752 return ret;
753
754 /*
755 * guests can ask for up to 255+1 double words, we need a full page
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300756 * to hold the maximum amount of facilities. On the other hand, we
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200757 * only set facilities that are known to work in KVM.
758 */
Heiko Carstensc2f0e8c2010-06-08 18:58:09 +0200759 facilities = (unsigned long long *) get_zeroed_page(GFP_KERNEL|GFP_DMA);
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200760 if (!facilities) {
761 kvm_exit();
762 return -ENOMEM;
763 }
Martin Schwidefsky14375bc2010-10-25 16:10:51 +0200764 memcpy(facilities, S390_lowcore.stfle_fac_list, 16);
Christian Borntraeger6d00d002010-10-25 16:10:48 +0200765 facilities[0] &= 0xff00fff3f47c0000ULL;
Christian Borntraeger9950f8b2011-06-06 14:14:39 +0200766 facilities[1] &= 0x201c000000000000ULL;
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200767 return 0;
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100768}
769
770static void __exit kvm_s390_exit(void)
771{
Christian Borntraegeref50f7a2009-06-23 17:24:07 +0200772 free_page((unsigned long) facilities);
Heiko Carstensb0c632d2008-03-25 18:47:20 +0100773 kvm_exit();
774}
775
776module_init(kvm_s390_init);
777module_exit(kvm_s390_exit);