xref: /linux/arch/s390/kvm/kvm-s390.c (revision dd2887e7c36d0be986ef17a9dbec904e3e334566)
1b0c632dbSHeiko Carstens /*
2a53c8fabSHeiko Carstens  * hosting zSeries kernel virtual machines
3b0c632dbSHeiko Carstens  *
4628eb9b8SChristian Ehrhardt  * Copyright IBM Corp. 2008, 2009
5b0c632dbSHeiko Carstens  *
6b0c632dbSHeiko Carstens  * This program is free software; you can redistribute it and/or modify
7b0c632dbSHeiko Carstens  * it under the terms of the GNU General Public License (version 2 only)
8b0c632dbSHeiko Carstens  * as published by the Free Software Foundation.
9b0c632dbSHeiko Carstens  *
10b0c632dbSHeiko Carstens  *    Author(s): Carsten Otte <cotte@de.ibm.com>
11b0c632dbSHeiko Carstens  *               Christian Borntraeger <borntraeger@de.ibm.com>
12b0c632dbSHeiko Carstens  *               Heiko Carstens <heiko.carstens@de.ibm.com>
13628eb9b8SChristian Ehrhardt  *               Christian Ehrhardt <ehrhardt@de.ibm.com>
14b0c632dbSHeiko Carstens  */
15b0c632dbSHeiko Carstens 
16b0c632dbSHeiko Carstens #include <linux/compiler.h>
17b0c632dbSHeiko Carstens #include <linux/err.h>
18b0c632dbSHeiko Carstens #include <linux/fs.h>
19ca872302SChristian Borntraeger #include <linux/hrtimer.h>
20b0c632dbSHeiko Carstens #include <linux/init.h>
21b0c632dbSHeiko Carstens #include <linux/kvm.h>
22b0c632dbSHeiko Carstens #include <linux/kvm_host.h>
23b0c632dbSHeiko Carstens #include <linux/module.h>
24b0c632dbSHeiko Carstens #include <linux/slab.h>
25ba5c1e9bSCarsten Otte #include <linux/timer.h>
26cbb870c8SHeiko Carstens #include <asm/asm-offsets.h>
27b0c632dbSHeiko Carstens #include <asm/lowcore.h>
28b0c632dbSHeiko Carstens #include <asm/pgtable.h>
29f5daba1dSHeiko Carstens #include <asm/nmi.h>
30a0616cdeSDavid Howells #include <asm/switch_to.h>
311526bf9cSChristian Borntraeger #include <asm/sclp.h>
328f2abe6aSChristian Borntraeger #include "kvm-s390.h"
33b0c632dbSHeiko Carstens #include "gaccess.h"
34b0c632dbSHeiko Carstens 
355786fffaSCornelia Huck #define CREATE_TRACE_POINTS
365786fffaSCornelia Huck #include "trace.h"
37ade38c31SCornelia Huck #include "trace-s390.h"
385786fffaSCornelia Huck 
39b0c632dbSHeiko Carstens #define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU
40b0c632dbSHeiko Carstens 
41b0c632dbSHeiko Carstens struct kvm_stats_debugfs_item debugfs_entries[] = {
42b0c632dbSHeiko Carstens 	{ "userspace_handled", VCPU_STAT(exit_userspace) },
430eaeafa1SChristian Borntraeger 	{ "exit_null", VCPU_STAT(exit_null) },
448f2abe6aSChristian Borntraeger 	{ "exit_validity", VCPU_STAT(exit_validity) },
458f2abe6aSChristian Borntraeger 	{ "exit_stop_request", VCPU_STAT(exit_stop_request) },
468f2abe6aSChristian Borntraeger 	{ "exit_external_request", VCPU_STAT(exit_external_request) },
478f2abe6aSChristian Borntraeger 	{ "exit_external_interrupt", VCPU_STAT(exit_external_interrupt) },
48ba5c1e9bSCarsten Otte 	{ "exit_instruction", VCPU_STAT(exit_instruction) },
49ba5c1e9bSCarsten Otte 	{ "exit_program_interruption", VCPU_STAT(exit_program_interruption) },
50ba5c1e9bSCarsten Otte 	{ "exit_instr_and_program_int", VCPU_STAT(exit_instr_and_program) },
51f5e10b09SChristian Borntraeger 	{ "instruction_lctlg", VCPU_STAT(instruction_lctlg) },
52ba5c1e9bSCarsten Otte 	{ "instruction_lctl", VCPU_STAT(instruction_lctl) },
53ba5c1e9bSCarsten Otte 	{ "deliver_emergency_signal", VCPU_STAT(deliver_emergency_signal) },
547697e71fSChristian Ehrhardt 	{ "deliver_external_call", VCPU_STAT(deliver_external_call) },
55ba5c1e9bSCarsten Otte 	{ "deliver_service_signal", VCPU_STAT(deliver_service_signal) },
56ba5c1e9bSCarsten Otte 	{ "deliver_virtio_interrupt", VCPU_STAT(deliver_virtio_interrupt) },
57ba5c1e9bSCarsten Otte 	{ "deliver_stop_signal", VCPU_STAT(deliver_stop_signal) },
58ba5c1e9bSCarsten Otte 	{ "deliver_prefix_signal", VCPU_STAT(deliver_prefix_signal) },
59ba5c1e9bSCarsten Otte 	{ "deliver_restart_signal", VCPU_STAT(deliver_restart_signal) },
60ba5c1e9bSCarsten Otte 	{ "deliver_program_interruption", VCPU_STAT(deliver_program_int) },
61ba5c1e9bSCarsten Otte 	{ "exit_wait_state", VCPU_STAT(exit_wait_state) },
62453423dcSChristian Borntraeger 	{ "instruction_stidp", VCPU_STAT(instruction_stidp) },
63453423dcSChristian Borntraeger 	{ "instruction_spx", VCPU_STAT(instruction_spx) },
64453423dcSChristian Borntraeger 	{ "instruction_stpx", VCPU_STAT(instruction_stpx) },
65453423dcSChristian Borntraeger 	{ "instruction_stap", VCPU_STAT(instruction_stap) },
66453423dcSChristian Borntraeger 	{ "instruction_storage_key", VCPU_STAT(instruction_storage_key) },
67453423dcSChristian Borntraeger 	{ "instruction_stsch", VCPU_STAT(instruction_stsch) },
68453423dcSChristian Borntraeger 	{ "instruction_chsc", VCPU_STAT(instruction_chsc) },
69453423dcSChristian Borntraeger 	{ "instruction_stsi", VCPU_STAT(instruction_stsi) },
70453423dcSChristian Borntraeger 	{ "instruction_stfl", VCPU_STAT(instruction_stfl) },
71bb25b9baSChristian Borntraeger 	{ "instruction_tprot", VCPU_STAT(instruction_tprot) },
725288fbf0SChristian Borntraeger 	{ "instruction_sigp_sense", VCPU_STAT(instruction_sigp_sense) },
73bd59d3a4SCornelia Huck 	{ "instruction_sigp_sense_running", VCPU_STAT(instruction_sigp_sense_running) },
747697e71fSChristian Ehrhardt 	{ "instruction_sigp_external_call", VCPU_STAT(instruction_sigp_external_call) },
755288fbf0SChristian Borntraeger 	{ "instruction_sigp_emergency", VCPU_STAT(instruction_sigp_emergency) },
765288fbf0SChristian Borntraeger 	{ "instruction_sigp_stop", VCPU_STAT(instruction_sigp_stop) },
775288fbf0SChristian Borntraeger 	{ "instruction_sigp_set_arch", VCPU_STAT(instruction_sigp_arch) },
785288fbf0SChristian Borntraeger 	{ "instruction_sigp_set_prefix", VCPU_STAT(instruction_sigp_prefix) },
795288fbf0SChristian Borntraeger 	{ "instruction_sigp_restart", VCPU_STAT(instruction_sigp_restart) },
80388186bcSChristian Borntraeger 	{ "diagnose_10", VCPU_STAT(diagnose_10) },
81e28acfeaSChristian Borntraeger 	{ "diagnose_44", VCPU_STAT(diagnose_44) },
8241628d33SKonstantin Weitz 	{ "diagnose_9c", VCPU_STAT(diagnose_9c) },
83b0c632dbSHeiko Carstens 	{ NULL }
84b0c632dbSHeiko Carstens };
85b0c632dbSHeiko Carstens 
86ef50f7acSChristian Borntraeger static unsigned long long *facilities;
87b0c632dbSHeiko Carstens 
88b0c632dbSHeiko Carstens /* Section: not file related */
8910474ae8SAlexander Graf int kvm_arch_hardware_enable(void *garbage)
90b0c632dbSHeiko Carstens {
91b0c632dbSHeiko Carstens 	/* every s390 is virtualization enabled ;-) */
9210474ae8SAlexander Graf 	return 0;
93b0c632dbSHeiko Carstens }
94b0c632dbSHeiko Carstens 
95b0c632dbSHeiko Carstens void kvm_arch_hardware_disable(void *garbage)
96b0c632dbSHeiko Carstens {
97b0c632dbSHeiko Carstens }
98b0c632dbSHeiko Carstens 
99b0c632dbSHeiko Carstens int kvm_arch_hardware_setup(void)
100b0c632dbSHeiko Carstens {
101b0c632dbSHeiko Carstens 	return 0;
102b0c632dbSHeiko Carstens }
103b0c632dbSHeiko Carstens 
104b0c632dbSHeiko Carstens void kvm_arch_hardware_unsetup(void)
105b0c632dbSHeiko Carstens {
106b0c632dbSHeiko Carstens }
107b0c632dbSHeiko Carstens 
108b0c632dbSHeiko Carstens void kvm_arch_check_processor_compat(void *rtn)
109b0c632dbSHeiko Carstens {
110b0c632dbSHeiko Carstens }
111b0c632dbSHeiko Carstens 
112b0c632dbSHeiko Carstens int kvm_arch_init(void *opaque)
113b0c632dbSHeiko Carstens {
114b0c632dbSHeiko Carstens 	return 0;
115b0c632dbSHeiko Carstens }
116b0c632dbSHeiko Carstens 
117b0c632dbSHeiko Carstens void kvm_arch_exit(void)
118b0c632dbSHeiko Carstens {
119b0c632dbSHeiko Carstens }
120b0c632dbSHeiko Carstens 
121b0c632dbSHeiko Carstens /* Section: device related */
122b0c632dbSHeiko Carstens long kvm_arch_dev_ioctl(struct file *filp,
123b0c632dbSHeiko Carstens 			unsigned int ioctl, unsigned long arg)
124b0c632dbSHeiko Carstens {
125b0c632dbSHeiko Carstens 	if (ioctl == KVM_S390_ENABLE_SIE)
126b0c632dbSHeiko Carstens 		return s390_enable_sie();
127b0c632dbSHeiko Carstens 	return -EINVAL;
128b0c632dbSHeiko Carstens }
129b0c632dbSHeiko Carstens 
130b0c632dbSHeiko Carstens int kvm_dev_ioctl_check_extension(long ext)
131b0c632dbSHeiko Carstens {
132d7b0b5ebSCarsten Otte 	int r;
133d7b0b5ebSCarsten Otte 
1342bd0ac4eSCarsten Otte 	switch (ext) {
135d7b0b5ebSCarsten Otte 	case KVM_CAP_S390_PSW:
136b6cf8788SChristian Borntraeger 	case KVM_CAP_S390_GMAP:
13752e16b18SChristian Borntraeger 	case KVM_CAP_SYNC_MMU:
1381efd0f59SCarsten Otte #ifdef CONFIG_KVM_S390_UCONTROL
1391efd0f59SCarsten Otte 	case KVM_CAP_S390_UCONTROL:
1401efd0f59SCarsten Otte #endif
14160b413c9SChristian Borntraeger 	case KVM_CAP_SYNC_REGS:
14214eebd91SCarsten Otte 	case KVM_CAP_ONE_REG:
143d6712df9SCornelia Huck 	case KVM_CAP_ENABLE_CAP:
144fa6b7fe9SCornelia Huck 	case KVM_CAP_S390_CSS_SUPPORT:
14510ccaa1eSCornelia Huck 	case KVM_CAP_IOEVENTFD:
146d7b0b5ebSCarsten Otte 		r = 1;
147d7b0b5ebSCarsten Otte 		break;
148e726b1bdSChristian Borntraeger 	case KVM_CAP_NR_VCPUS:
149e726b1bdSChristian Borntraeger 	case KVM_CAP_MAX_VCPUS:
150e726b1bdSChristian Borntraeger 		r = KVM_MAX_VCPUS;
151e726b1bdSChristian Borntraeger 		break;
1521526bf9cSChristian Borntraeger 	case KVM_CAP_S390_COW:
153abf09bedSMartin Schwidefsky 		r = MACHINE_HAS_ESOP;
1541526bf9cSChristian Borntraeger 		break;
1552bd0ac4eSCarsten Otte 	default:
156d7b0b5ebSCarsten Otte 		r = 0;
157b0c632dbSHeiko Carstens 	}
158d7b0b5ebSCarsten Otte 	return r;
1592bd0ac4eSCarsten Otte }
160b0c632dbSHeiko Carstens 
161b0c632dbSHeiko Carstens /* Section: vm related */
162b0c632dbSHeiko Carstens /*
163b0c632dbSHeiko Carstens  * Get (and clear) the dirty memory log for a memory slot.
164b0c632dbSHeiko Carstens  */
165b0c632dbSHeiko Carstens int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
166b0c632dbSHeiko Carstens 			       struct kvm_dirty_log *log)
167b0c632dbSHeiko Carstens {
168b0c632dbSHeiko Carstens 	return 0;
169b0c632dbSHeiko Carstens }
170b0c632dbSHeiko Carstens 
171b0c632dbSHeiko Carstens long kvm_arch_vm_ioctl(struct file *filp,
172b0c632dbSHeiko Carstens 		       unsigned int ioctl, unsigned long arg)
173b0c632dbSHeiko Carstens {
174b0c632dbSHeiko Carstens 	struct kvm *kvm = filp->private_data;
175b0c632dbSHeiko Carstens 	void __user *argp = (void __user *)arg;
176b0c632dbSHeiko Carstens 	int r;
177b0c632dbSHeiko Carstens 
178b0c632dbSHeiko Carstens 	switch (ioctl) {
179ba5c1e9bSCarsten Otte 	case KVM_S390_INTERRUPT: {
180ba5c1e9bSCarsten Otte 		struct kvm_s390_interrupt s390int;
181ba5c1e9bSCarsten Otte 
182ba5c1e9bSCarsten Otte 		r = -EFAULT;
183ba5c1e9bSCarsten Otte 		if (copy_from_user(&s390int, argp, sizeof(s390int)))
184ba5c1e9bSCarsten Otte 			break;
185ba5c1e9bSCarsten Otte 		r = kvm_s390_inject_vm(kvm, &s390int);
186ba5c1e9bSCarsten Otte 		break;
187ba5c1e9bSCarsten Otte 	}
188b0c632dbSHeiko Carstens 	default:
189367e1319SAvi Kivity 		r = -ENOTTY;
190b0c632dbSHeiko Carstens 	}
191b0c632dbSHeiko Carstens 
192b0c632dbSHeiko Carstens 	return r;
193b0c632dbSHeiko Carstens }
194b0c632dbSHeiko Carstens 
195e08b9637SCarsten Otte int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
196b0c632dbSHeiko Carstens {
197b0c632dbSHeiko Carstens 	int rc;
198b0c632dbSHeiko Carstens 	char debug_name[16];
199b0c632dbSHeiko Carstens 
200e08b9637SCarsten Otte 	rc = -EINVAL;
201e08b9637SCarsten Otte #ifdef CONFIG_KVM_S390_UCONTROL
202e08b9637SCarsten Otte 	if (type & ~KVM_VM_S390_UCONTROL)
203e08b9637SCarsten Otte 		goto out_err;
204e08b9637SCarsten Otte 	if ((type & KVM_VM_S390_UCONTROL) && (!capable(CAP_SYS_ADMIN)))
205e08b9637SCarsten Otte 		goto out_err;
206e08b9637SCarsten Otte #else
207e08b9637SCarsten Otte 	if (type)
208e08b9637SCarsten Otte 		goto out_err;
209e08b9637SCarsten Otte #endif
210e08b9637SCarsten Otte 
211b0c632dbSHeiko Carstens 	rc = s390_enable_sie();
212b0c632dbSHeiko Carstens 	if (rc)
213d89f5effSJan Kiszka 		goto out_err;
214b0c632dbSHeiko Carstens 
215b290411aSCarsten Otte 	rc = -ENOMEM;
216b290411aSCarsten Otte 
217b0c632dbSHeiko Carstens 	kvm->arch.sca = (struct sca_block *) get_zeroed_page(GFP_KERNEL);
218b0c632dbSHeiko Carstens 	if (!kvm->arch.sca)
219d89f5effSJan Kiszka 		goto out_err;
220b0c632dbSHeiko Carstens 
221b0c632dbSHeiko Carstens 	sprintf(debug_name, "kvm-%u", current->pid);
222b0c632dbSHeiko Carstens 
223b0c632dbSHeiko Carstens 	kvm->arch.dbf = debug_register(debug_name, 8, 2, 8 * sizeof(long));
224b0c632dbSHeiko Carstens 	if (!kvm->arch.dbf)
225b0c632dbSHeiko Carstens 		goto out_nodbf;
226b0c632dbSHeiko Carstens 
227ba5c1e9bSCarsten Otte 	spin_lock_init(&kvm->arch.float_int.lock);
228ba5c1e9bSCarsten Otte 	INIT_LIST_HEAD(&kvm->arch.float_int.list);
229ba5c1e9bSCarsten Otte 
230b0c632dbSHeiko Carstens 	debug_register_view(kvm->arch.dbf, &debug_sprintf_view);
231b0c632dbSHeiko Carstens 	VM_EVENT(kvm, 3, "%s", "vm created");
232b0c632dbSHeiko Carstens 
233e08b9637SCarsten Otte 	if (type & KVM_VM_S390_UCONTROL) {
234e08b9637SCarsten Otte 		kvm->arch.gmap = NULL;
235e08b9637SCarsten Otte 	} else {
236598841caSCarsten Otte 		kvm->arch.gmap = gmap_alloc(current->mm);
237598841caSCarsten Otte 		if (!kvm->arch.gmap)
238598841caSCarsten Otte 			goto out_nogmap;
239e08b9637SCarsten Otte 	}
240fa6b7fe9SCornelia Huck 
241fa6b7fe9SCornelia Huck 	kvm->arch.css_support = 0;
242fa6b7fe9SCornelia Huck 
243d89f5effSJan Kiszka 	return 0;
244598841caSCarsten Otte out_nogmap:
245598841caSCarsten Otte 	debug_unregister(kvm->arch.dbf);
246b0c632dbSHeiko Carstens out_nodbf:
247b0c632dbSHeiko Carstens 	free_page((unsigned long)(kvm->arch.sca));
248d89f5effSJan Kiszka out_err:
249d89f5effSJan Kiszka 	return rc;
250b0c632dbSHeiko Carstens }
251b0c632dbSHeiko Carstens 
252d329c035SChristian Borntraeger void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
253d329c035SChristian Borntraeger {
254d329c035SChristian Borntraeger 	VCPU_EVENT(vcpu, 3, "%s", "free cpu");
255ade38c31SCornelia Huck 	trace_kvm_s390_destroy_vcpu(vcpu->vcpu_id);
25658f9460bSCarsten Otte 	if (!kvm_is_ucontrol(vcpu->kvm)) {
25758f9460bSCarsten Otte 		clear_bit(63 - vcpu->vcpu_id,
25858f9460bSCarsten Otte 			  (unsigned long *) &vcpu->kvm->arch.sca->mcn);
259abf4a71eSCarsten Otte 		if (vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda ==
260abf4a71eSCarsten Otte 		    (__u64) vcpu->arch.sie_block)
261abf4a71eSCarsten Otte 			vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda = 0;
26258f9460bSCarsten Otte 	}
263abf4a71eSCarsten Otte 	smp_mb();
26427e0393fSCarsten Otte 
26527e0393fSCarsten Otte 	if (kvm_is_ucontrol(vcpu->kvm))
26627e0393fSCarsten Otte 		gmap_free(vcpu->arch.gmap);
26727e0393fSCarsten Otte 
268d329c035SChristian Borntraeger 	free_page((unsigned long)(vcpu->arch.sie_block));
2696692cef3SChristian Borntraeger 	kvm_vcpu_uninit(vcpu);
270d329c035SChristian Borntraeger 	kfree(vcpu);
271d329c035SChristian Borntraeger }
272d329c035SChristian Borntraeger 
273d329c035SChristian Borntraeger static void kvm_free_vcpus(struct kvm *kvm)
274d329c035SChristian Borntraeger {
275d329c035SChristian Borntraeger 	unsigned int i;
276988a2caeSGleb Natapov 	struct kvm_vcpu *vcpu;
277d329c035SChristian Borntraeger 
278988a2caeSGleb Natapov 	kvm_for_each_vcpu(i, vcpu, kvm)
279988a2caeSGleb Natapov 		kvm_arch_vcpu_destroy(vcpu);
280988a2caeSGleb Natapov 
281988a2caeSGleb Natapov 	mutex_lock(&kvm->lock);
282988a2caeSGleb Natapov 	for (i = 0; i < atomic_read(&kvm->online_vcpus); i++)
283d329c035SChristian Borntraeger 		kvm->vcpus[i] = NULL;
284988a2caeSGleb Natapov 
285988a2caeSGleb Natapov 	atomic_set(&kvm->online_vcpus, 0);
286988a2caeSGleb Natapov 	mutex_unlock(&kvm->lock);
287d329c035SChristian Borntraeger }
288d329c035SChristian Borntraeger 
289ad8ba2cdSSheng Yang void kvm_arch_sync_events(struct kvm *kvm)
290ad8ba2cdSSheng Yang {
291ad8ba2cdSSheng Yang }
292ad8ba2cdSSheng Yang 
293b0c632dbSHeiko Carstens void kvm_arch_destroy_vm(struct kvm *kvm)
294b0c632dbSHeiko Carstens {
295d329c035SChristian Borntraeger 	kvm_free_vcpus(kvm);
296b0c632dbSHeiko Carstens 	free_page((unsigned long)(kvm->arch.sca));
297d329c035SChristian Borntraeger 	debug_unregister(kvm->arch.dbf);
29827e0393fSCarsten Otte 	if (!kvm_is_ucontrol(kvm))
299598841caSCarsten Otte 		gmap_free(kvm->arch.gmap);
300b0c632dbSHeiko Carstens }
301b0c632dbSHeiko Carstens 
302b0c632dbSHeiko Carstens /* Section: vcpu related */
303b0c632dbSHeiko Carstens int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
304b0c632dbSHeiko Carstens {
30527e0393fSCarsten Otte 	if (kvm_is_ucontrol(vcpu->kvm)) {
30627e0393fSCarsten Otte 		vcpu->arch.gmap = gmap_alloc(current->mm);
30727e0393fSCarsten Otte 		if (!vcpu->arch.gmap)
30827e0393fSCarsten Otte 			return -ENOMEM;
30927e0393fSCarsten Otte 		return 0;
31027e0393fSCarsten Otte 	}
31127e0393fSCarsten Otte 
312598841caSCarsten Otte 	vcpu->arch.gmap = vcpu->kvm->arch.gmap;
31359674c1aSChristian Borntraeger 	vcpu->run->kvm_valid_regs = KVM_SYNC_PREFIX |
31459674c1aSChristian Borntraeger 				    KVM_SYNC_GPRS |
3159eed0735SChristian Borntraeger 				    KVM_SYNC_ACRS |
3169eed0735SChristian Borntraeger 				    KVM_SYNC_CRS;
317b0c632dbSHeiko Carstens 	return 0;
318b0c632dbSHeiko Carstens }
319b0c632dbSHeiko Carstens 
320b0c632dbSHeiko Carstens void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
321b0c632dbSHeiko Carstens {
3226692cef3SChristian Borntraeger 	/* Nothing todo */
323b0c632dbSHeiko Carstens }
324b0c632dbSHeiko Carstens 
325b0c632dbSHeiko Carstens void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
326b0c632dbSHeiko Carstens {
327b0c632dbSHeiko Carstens 	save_fp_regs(&vcpu->arch.host_fpregs);
328b0c632dbSHeiko Carstens 	save_access_regs(vcpu->arch.host_acrs);
329b0c632dbSHeiko Carstens 	vcpu->arch.guest_fpregs.fpc &= FPC_VALID_MASK;
330b0c632dbSHeiko Carstens 	restore_fp_regs(&vcpu->arch.guest_fpregs);
33159674c1aSChristian Borntraeger 	restore_access_regs(vcpu->run->s.regs.acrs);
332480e5926SChristian Borntraeger 	gmap_enable(vcpu->arch.gmap);
3339e6dabefSCornelia Huck 	atomic_set_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
334b0c632dbSHeiko Carstens }
335b0c632dbSHeiko Carstens 
336b0c632dbSHeiko Carstens void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
337b0c632dbSHeiko Carstens {
3389e6dabefSCornelia Huck 	atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
339480e5926SChristian Borntraeger 	gmap_disable(vcpu->arch.gmap);
340b0c632dbSHeiko Carstens 	save_fp_regs(&vcpu->arch.guest_fpregs);
34159674c1aSChristian Borntraeger 	save_access_regs(vcpu->run->s.regs.acrs);
342b0c632dbSHeiko Carstens 	restore_fp_regs(&vcpu->arch.host_fpregs);
343b0c632dbSHeiko Carstens 	restore_access_regs(vcpu->arch.host_acrs);
344b0c632dbSHeiko Carstens }
345b0c632dbSHeiko Carstens 
346b0c632dbSHeiko Carstens static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu)
347b0c632dbSHeiko Carstens {
348b0c632dbSHeiko Carstens 	/* this equals initial cpu reset in pop, but we don't switch to ESA */
349b0c632dbSHeiko Carstens 	vcpu->arch.sie_block->gpsw.mask = 0UL;
350b0c632dbSHeiko Carstens 	vcpu->arch.sie_block->gpsw.addr = 0UL;
3518d26cf7bSChristian Borntraeger 	kvm_s390_set_prefix(vcpu, 0);
352b0c632dbSHeiko Carstens 	vcpu->arch.sie_block->cputm     = 0UL;
353b0c632dbSHeiko Carstens 	vcpu->arch.sie_block->ckc       = 0UL;
354b0c632dbSHeiko Carstens 	vcpu->arch.sie_block->todpr     = 0;
355b0c632dbSHeiko Carstens 	memset(vcpu->arch.sie_block->gcr, 0, 16 * sizeof(__u64));
356b0c632dbSHeiko Carstens 	vcpu->arch.sie_block->gcr[0]  = 0xE0UL;
357b0c632dbSHeiko Carstens 	vcpu->arch.sie_block->gcr[14] = 0xC2000000UL;
358b0c632dbSHeiko Carstens 	vcpu->arch.guest_fpregs.fpc = 0;
359b0c632dbSHeiko Carstens 	asm volatile("lfpc %0" : : "Q" (vcpu->arch.guest_fpregs.fpc));
360b0c632dbSHeiko Carstens 	vcpu->arch.sie_block->gbea = 1;
36161bde82cSChristian Borntraeger 	atomic_set_mask(CPUSTAT_STOPPED, &vcpu->arch.sie_block->cpuflags);
362b0c632dbSHeiko Carstens }
363b0c632dbSHeiko Carstens 
36442897d86SMarcelo Tosatti int kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
36542897d86SMarcelo Tosatti {
36642897d86SMarcelo Tosatti 	return 0;
36742897d86SMarcelo Tosatti }
36842897d86SMarcelo Tosatti 
369b0c632dbSHeiko Carstens int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
370b0c632dbSHeiko Carstens {
3719e6dabefSCornelia Huck 	atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH |
3729e6dabefSCornelia Huck 						    CPUSTAT_SM |
3739e6dabefSCornelia Huck 						    CPUSTAT_STOPPED);
374fc34531dSChristian Borntraeger 	vcpu->arch.sie_block->ecb   = 6;
375b0c632dbSHeiko Carstens 	vcpu->arch.sie_block->eca   = 0xC1002001U;
376ef50f7acSChristian Borntraeger 	vcpu->arch.sie_block->fac   = (int) (long) facilities;
377ca872302SChristian Borntraeger 	hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
378ca872302SChristian Borntraeger 	tasklet_init(&vcpu->arch.tasklet, kvm_s390_tasklet,
379ba5c1e9bSCarsten Otte 		     (unsigned long) vcpu);
380ca872302SChristian Borntraeger 	vcpu->arch.ckc_timer.function = kvm_s390_idle_wakeup;
381453423dcSChristian Borntraeger 	get_cpu_id(&vcpu->arch.cpu_id);
38292e6ecf3SChristian Borntraeger 	vcpu->arch.cpu_id.version = 0xff;
383b0c632dbSHeiko Carstens 	return 0;
384b0c632dbSHeiko Carstens }
385b0c632dbSHeiko Carstens 
386b0c632dbSHeiko Carstens struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
387b0c632dbSHeiko Carstens 				      unsigned int id)
388b0c632dbSHeiko Carstens {
3894d47555aSCarsten Otte 	struct kvm_vcpu *vcpu;
3904d47555aSCarsten Otte 	int rc = -EINVAL;
391b0c632dbSHeiko Carstens 
3924d47555aSCarsten Otte 	if (id >= KVM_MAX_VCPUS)
3934d47555aSCarsten Otte 		goto out;
3944d47555aSCarsten Otte 
3954d47555aSCarsten Otte 	rc = -ENOMEM;
3964d47555aSCarsten Otte 
3974d47555aSCarsten Otte 	vcpu = kzalloc(sizeof(struct kvm_vcpu), GFP_KERNEL);
398b0c632dbSHeiko Carstens 	if (!vcpu)
3994d47555aSCarsten Otte 		goto out;
400b0c632dbSHeiko Carstens 
401180c12fbSChristian Borntraeger 	vcpu->arch.sie_block = (struct kvm_s390_sie_block *)
402180c12fbSChristian Borntraeger 					get_zeroed_page(GFP_KERNEL);
403b0c632dbSHeiko Carstens 
404b0c632dbSHeiko Carstens 	if (!vcpu->arch.sie_block)
405b0c632dbSHeiko Carstens 		goto out_free_cpu;
406b0c632dbSHeiko Carstens 
407b0c632dbSHeiko Carstens 	vcpu->arch.sie_block->icpua = id;
40858f9460bSCarsten Otte 	if (!kvm_is_ucontrol(kvm)) {
40958f9460bSCarsten Otte 		if (!kvm->arch.sca) {
41058f9460bSCarsten Otte 			WARN_ON_ONCE(1);
41158f9460bSCarsten Otte 			goto out_free_cpu;
41258f9460bSCarsten Otte 		}
413abf4a71eSCarsten Otte 		if (!kvm->arch.sca->cpu[id].sda)
41458f9460bSCarsten Otte 			kvm->arch.sca->cpu[id].sda =
41558f9460bSCarsten Otte 				(__u64) vcpu->arch.sie_block;
41658f9460bSCarsten Otte 		vcpu->arch.sie_block->scaoh =
41758f9460bSCarsten Otte 			(__u32)(((__u64)kvm->arch.sca) >> 32);
418b0c632dbSHeiko Carstens 		vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca;
419fc34531dSChristian Borntraeger 		set_bit(63 - id, (unsigned long *) &kvm->arch.sca->mcn);
42058f9460bSCarsten Otte 	}
421b0c632dbSHeiko Carstens 
422ba5c1e9bSCarsten Otte 	spin_lock_init(&vcpu->arch.local_int.lock);
423ba5c1e9bSCarsten Otte 	INIT_LIST_HEAD(&vcpu->arch.local_int.list);
424ba5c1e9bSCarsten Otte 	vcpu->arch.local_int.float_int = &kvm->arch.float_int;
425b037a4f3SChristian Borntraeger 	spin_lock(&kvm->arch.float_int.lock);
426ba5c1e9bSCarsten Otte 	kvm->arch.float_int.local_int[id] = &vcpu->arch.local_int;
427ba5c1e9bSCarsten Otte 	init_waitqueue_head(&vcpu->arch.local_int.wq);
4285288fbf0SChristian Borntraeger 	vcpu->arch.local_int.cpuflags = &vcpu->arch.sie_block->cpuflags;
429b037a4f3SChristian Borntraeger 	spin_unlock(&kvm->arch.float_int.lock);
430ba5c1e9bSCarsten Otte 
431b0c632dbSHeiko Carstens 	rc = kvm_vcpu_init(vcpu, kvm, id);
432b0c632dbSHeiko Carstens 	if (rc)
4337b06bf2fSWei Yongjun 		goto out_free_sie_block;
434b0c632dbSHeiko Carstens 	VM_EVENT(kvm, 3, "create cpu %d at %p, sie block at %p", id, vcpu,
435b0c632dbSHeiko Carstens 		 vcpu->arch.sie_block);
436ade38c31SCornelia Huck 	trace_kvm_s390_create_vcpu(id, vcpu, vcpu->arch.sie_block);
437b0c632dbSHeiko Carstens 
438b0c632dbSHeiko Carstens 	return vcpu;
4397b06bf2fSWei Yongjun out_free_sie_block:
4407b06bf2fSWei Yongjun 	free_page((unsigned long)(vcpu->arch.sie_block));
441b0c632dbSHeiko Carstens out_free_cpu:
442b0c632dbSHeiko Carstens 	kfree(vcpu);
4434d47555aSCarsten Otte out:
444b0c632dbSHeiko Carstens 	return ERR_PTR(rc);
445b0c632dbSHeiko Carstens }
446b0c632dbSHeiko Carstens 
447b0c632dbSHeiko Carstens int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
448b0c632dbSHeiko Carstens {
449b0c632dbSHeiko Carstens 	/* kvm common code refers to this, but never calls it */
450b0c632dbSHeiko Carstens 	BUG();
451b0c632dbSHeiko Carstens 	return 0;
452b0c632dbSHeiko Carstens }
453b0c632dbSHeiko Carstens 
454b6d33834SChristoffer Dall int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
455b6d33834SChristoffer Dall {
456b6d33834SChristoffer Dall 	/* kvm common code refers to this, but never calls it */
457b6d33834SChristoffer Dall 	BUG();
458b6d33834SChristoffer Dall 	return 0;
459b6d33834SChristoffer Dall }
460b6d33834SChristoffer Dall 
46114eebd91SCarsten Otte static int kvm_arch_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu,
46214eebd91SCarsten Otte 					   struct kvm_one_reg *reg)
46314eebd91SCarsten Otte {
46414eebd91SCarsten Otte 	int r = -EINVAL;
46514eebd91SCarsten Otte 
46614eebd91SCarsten Otte 	switch (reg->id) {
46729b7c71bSCarsten Otte 	case KVM_REG_S390_TODPR:
46829b7c71bSCarsten Otte 		r = put_user(vcpu->arch.sie_block->todpr,
46929b7c71bSCarsten Otte 			     (u32 __user *)reg->addr);
47029b7c71bSCarsten Otte 		break;
47129b7c71bSCarsten Otte 	case KVM_REG_S390_EPOCHDIFF:
47229b7c71bSCarsten Otte 		r = put_user(vcpu->arch.sie_block->epoch,
47329b7c71bSCarsten Otte 			     (u64 __user *)reg->addr);
47429b7c71bSCarsten Otte 		break;
47546a6dd1cSJason J. herne 	case KVM_REG_S390_CPU_TIMER:
47646a6dd1cSJason J. herne 		r = put_user(vcpu->arch.sie_block->cputm,
47746a6dd1cSJason J. herne 			     (u64 __user *)reg->addr);
47846a6dd1cSJason J. herne 		break;
47946a6dd1cSJason J. herne 	case KVM_REG_S390_CLOCK_COMP:
48046a6dd1cSJason J. herne 		r = put_user(vcpu->arch.sie_block->ckc,
48146a6dd1cSJason J. herne 			     (u64 __user *)reg->addr);
48246a6dd1cSJason J. herne 		break;
48314eebd91SCarsten Otte 	default:
48414eebd91SCarsten Otte 		break;
48514eebd91SCarsten Otte 	}
48614eebd91SCarsten Otte 
48714eebd91SCarsten Otte 	return r;
48814eebd91SCarsten Otte }
48914eebd91SCarsten Otte 
49014eebd91SCarsten Otte static int kvm_arch_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu,
49114eebd91SCarsten Otte 					   struct kvm_one_reg *reg)
49214eebd91SCarsten Otte {
49314eebd91SCarsten Otte 	int r = -EINVAL;
49414eebd91SCarsten Otte 
49514eebd91SCarsten Otte 	switch (reg->id) {
49629b7c71bSCarsten Otte 	case KVM_REG_S390_TODPR:
49729b7c71bSCarsten Otte 		r = get_user(vcpu->arch.sie_block->todpr,
49829b7c71bSCarsten Otte 			     (u32 __user *)reg->addr);
49929b7c71bSCarsten Otte 		break;
50029b7c71bSCarsten Otte 	case KVM_REG_S390_EPOCHDIFF:
50129b7c71bSCarsten Otte 		r = get_user(vcpu->arch.sie_block->epoch,
50229b7c71bSCarsten Otte 			     (u64 __user *)reg->addr);
50329b7c71bSCarsten Otte 		break;
50446a6dd1cSJason J. herne 	case KVM_REG_S390_CPU_TIMER:
50546a6dd1cSJason J. herne 		r = get_user(vcpu->arch.sie_block->cputm,
50646a6dd1cSJason J. herne 			     (u64 __user *)reg->addr);
50746a6dd1cSJason J. herne 		break;
50846a6dd1cSJason J. herne 	case KVM_REG_S390_CLOCK_COMP:
50946a6dd1cSJason J. herne 		r = get_user(vcpu->arch.sie_block->ckc,
51046a6dd1cSJason J. herne 			     (u64 __user *)reg->addr);
51146a6dd1cSJason J. herne 		break;
51214eebd91SCarsten Otte 	default:
51314eebd91SCarsten Otte 		break;
51414eebd91SCarsten Otte 	}
51514eebd91SCarsten Otte 
51614eebd91SCarsten Otte 	return r;
51714eebd91SCarsten Otte }
518b6d33834SChristoffer Dall 
519b0c632dbSHeiko Carstens static int kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu)
520b0c632dbSHeiko Carstens {
521b0c632dbSHeiko Carstens 	kvm_s390_vcpu_initial_reset(vcpu);
522b0c632dbSHeiko Carstens 	return 0;
523b0c632dbSHeiko Carstens }
524b0c632dbSHeiko Carstens 
525b0c632dbSHeiko Carstens int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
526b0c632dbSHeiko Carstens {
5275a32c1afSChristian Borntraeger 	memcpy(&vcpu->run->s.regs.gprs, &regs->gprs, sizeof(regs->gprs));
528b0c632dbSHeiko Carstens 	return 0;
529b0c632dbSHeiko Carstens }
530b0c632dbSHeiko Carstens 
531b0c632dbSHeiko Carstens int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
532b0c632dbSHeiko Carstens {
5335a32c1afSChristian Borntraeger 	memcpy(&regs->gprs, &vcpu->run->s.regs.gprs, sizeof(regs->gprs));
534b0c632dbSHeiko Carstens 	return 0;
535b0c632dbSHeiko Carstens }
536b0c632dbSHeiko Carstens 
537b0c632dbSHeiko Carstens int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
538b0c632dbSHeiko Carstens 				  struct kvm_sregs *sregs)
539b0c632dbSHeiko Carstens {
54059674c1aSChristian Borntraeger 	memcpy(&vcpu->run->s.regs.acrs, &sregs->acrs, sizeof(sregs->acrs));
541b0c632dbSHeiko Carstens 	memcpy(&vcpu->arch.sie_block->gcr, &sregs->crs, sizeof(sregs->crs));
54259674c1aSChristian Borntraeger 	restore_access_regs(vcpu->run->s.regs.acrs);
543b0c632dbSHeiko Carstens 	return 0;
544b0c632dbSHeiko Carstens }
545b0c632dbSHeiko Carstens 
546b0c632dbSHeiko Carstens int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
547b0c632dbSHeiko Carstens 				  struct kvm_sregs *sregs)
548b0c632dbSHeiko Carstens {
54959674c1aSChristian Borntraeger 	memcpy(&sregs->acrs, &vcpu->run->s.regs.acrs, sizeof(sregs->acrs));
550b0c632dbSHeiko Carstens 	memcpy(&sregs->crs, &vcpu->arch.sie_block->gcr, sizeof(sregs->crs));
551b0c632dbSHeiko Carstens 	return 0;
552b0c632dbSHeiko Carstens }
553b0c632dbSHeiko Carstens 
554b0c632dbSHeiko Carstens int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
555b0c632dbSHeiko Carstens {
556b0c632dbSHeiko Carstens 	memcpy(&vcpu->arch.guest_fpregs.fprs, &fpu->fprs, sizeof(fpu->fprs));
55785175587SChristian Borntraeger 	vcpu->arch.guest_fpregs.fpc = fpu->fpc & FPC_VALID_MASK;
5587eef87dcSCarsten Otte 	restore_fp_regs(&vcpu->arch.guest_fpregs);
559b0c632dbSHeiko Carstens 	return 0;
560b0c632dbSHeiko Carstens }
561b0c632dbSHeiko Carstens 
562b0c632dbSHeiko Carstens int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
563b0c632dbSHeiko Carstens {
564b0c632dbSHeiko Carstens 	memcpy(&fpu->fprs, &vcpu->arch.guest_fpregs.fprs, sizeof(fpu->fprs));
565b0c632dbSHeiko Carstens 	fpu->fpc = vcpu->arch.guest_fpregs.fpc;
566b0c632dbSHeiko Carstens 	return 0;
567b0c632dbSHeiko Carstens }
568b0c632dbSHeiko Carstens 
569b0c632dbSHeiko Carstens static int kvm_arch_vcpu_ioctl_set_initial_psw(struct kvm_vcpu *vcpu, psw_t psw)
570b0c632dbSHeiko Carstens {
571b0c632dbSHeiko Carstens 	int rc = 0;
572b0c632dbSHeiko Carstens 
5739e6dabefSCornelia Huck 	if (!(atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_STOPPED))
574b0c632dbSHeiko Carstens 		rc = -EBUSY;
575d7b0b5ebSCarsten Otte 	else {
576d7b0b5ebSCarsten Otte 		vcpu->run->psw_mask = psw.mask;
577d7b0b5ebSCarsten Otte 		vcpu->run->psw_addr = psw.addr;
578d7b0b5ebSCarsten Otte 	}
579b0c632dbSHeiko Carstens 	return rc;
580b0c632dbSHeiko Carstens }
581b0c632dbSHeiko Carstens 
582b0c632dbSHeiko Carstens int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
583b0c632dbSHeiko Carstens 				  struct kvm_translation *tr)
584b0c632dbSHeiko Carstens {
585b0c632dbSHeiko Carstens 	return -EINVAL; /* not implemented yet */
586b0c632dbSHeiko Carstens }
587b0c632dbSHeiko Carstens 
588d0bfb940SJan Kiszka int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
589d0bfb940SJan Kiszka 					struct kvm_guest_debug *dbg)
590b0c632dbSHeiko Carstens {
591b0c632dbSHeiko Carstens 	return -EINVAL; /* not implemented yet */
592b0c632dbSHeiko Carstens }
593b0c632dbSHeiko Carstens 
59462d9f0dbSMarcelo Tosatti int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
59562d9f0dbSMarcelo Tosatti 				    struct kvm_mp_state *mp_state)
59662d9f0dbSMarcelo Tosatti {
59762d9f0dbSMarcelo Tosatti 	return -EINVAL; /* not implemented yet */
59862d9f0dbSMarcelo Tosatti }
59962d9f0dbSMarcelo Tosatti 
60062d9f0dbSMarcelo Tosatti int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
60162d9f0dbSMarcelo Tosatti 				    struct kvm_mp_state *mp_state)
60262d9f0dbSMarcelo Tosatti {
60362d9f0dbSMarcelo Tosatti 	return -EINVAL; /* not implemented yet */
60462d9f0dbSMarcelo Tosatti }
60562d9f0dbSMarcelo Tosatti 
606e168bf8dSCarsten Otte static int __vcpu_run(struct kvm_vcpu *vcpu)
607b0c632dbSHeiko Carstens {
608e168bf8dSCarsten Otte 	int rc;
609e168bf8dSCarsten Otte 
6105a32c1afSChristian Borntraeger 	memcpy(&vcpu->arch.sie_block->gg14, &vcpu->run->s.regs.gprs[14], 16);
611b0c632dbSHeiko Carstens 
612b0c632dbSHeiko Carstens 	if (need_resched())
613b0c632dbSHeiko Carstens 		schedule();
614b0c632dbSHeiko Carstens 
61571cde587SChristian Borntraeger 	if (test_thread_flag(TIF_MCCK_PENDING))
61671cde587SChristian Borntraeger 		s390_handle_mcck();
61771cde587SChristian Borntraeger 
618d6b6d166SCarsten Otte 	if (!kvm_is_ucontrol(vcpu->kvm))
6190ff31867SCarsten Otte 		kvm_s390_deliver_pending_interrupts(vcpu);
6200ff31867SCarsten Otte 
621b0c632dbSHeiko Carstens 	vcpu->arch.sie_block->icptcode = 0;
62283987aceSChristian Borntraeger 	preempt_disable();
623b0c632dbSHeiko Carstens 	kvm_guest_enter();
62483987aceSChristian Borntraeger 	preempt_enable();
625b0c632dbSHeiko Carstens 	VCPU_EVENT(vcpu, 6, "entering sie flags %x",
626b0c632dbSHeiko Carstens 		   atomic_read(&vcpu->arch.sie_block->cpuflags));
6275786fffaSCornelia Huck 	trace_kvm_s390_sie_enter(vcpu,
6285786fffaSCornelia Huck 				 atomic_read(&vcpu->arch.sie_block->cpuflags));
6295a32c1afSChristian Borntraeger 	rc = sie64a(vcpu->arch.sie_block, vcpu->run->s.regs.gprs);
630e168bf8dSCarsten Otte 	if (rc) {
631e168bf8dSCarsten Otte 		if (kvm_is_ucontrol(vcpu->kvm)) {
632e168bf8dSCarsten Otte 			rc = SIE_INTERCEPT_UCONTROL;
633e168bf8dSCarsten Otte 		} else {
6341f0d0f09SCarsten Otte 			VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction");
6355786fffaSCornelia Huck 			trace_kvm_s390_sie_fault(vcpu);
636db4a29cbSHeiko Carstens 			rc = kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
637e168bf8dSCarsten Otte 		}
6381f0d0f09SCarsten Otte 	}
639b0c632dbSHeiko Carstens 	VCPU_EVENT(vcpu, 6, "exit sie icptcode %d",
640b0c632dbSHeiko Carstens 		   vcpu->arch.sie_block->icptcode);
6415786fffaSCornelia Huck 	trace_kvm_s390_sie_exit(vcpu, vcpu->arch.sie_block->icptcode);
642b0c632dbSHeiko Carstens 	kvm_guest_exit();
643b0c632dbSHeiko Carstens 
6445a32c1afSChristian Borntraeger 	memcpy(&vcpu->run->s.regs.gprs[14], &vcpu->arch.sie_block->gg14, 16);
645e168bf8dSCarsten Otte 	return rc;
646b0c632dbSHeiko Carstens }
647b0c632dbSHeiko Carstens 
648b0c632dbSHeiko Carstens int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
649b0c632dbSHeiko Carstens {
6508f2abe6aSChristian Borntraeger 	int rc;
651b0c632dbSHeiko Carstens 	sigset_t sigsaved;
652b0c632dbSHeiko Carstens 
6539ace903dSChristian Ehrhardt rerun_vcpu:
654b0c632dbSHeiko Carstens 	if (vcpu->sigset_active)
655b0c632dbSHeiko Carstens 		sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
656b0c632dbSHeiko Carstens 
6579e6dabefSCornelia Huck 	atomic_clear_mask(CPUSTAT_STOPPED, &vcpu->arch.sie_block->cpuflags);
658b0c632dbSHeiko Carstens 
659ba5c1e9bSCarsten Otte 	BUG_ON(vcpu->kvm->arch.float_int.local_int[vcpu->vcpu_id] == NULL);
660ba5c1e9bSCarsten Otte 
6618f2abe6aSChristian Borntraeger 	switch (kvm_run->exit_reason) {
6628f2abe6aSChristian Borntraeger 	case KVM_EXIT_S390_SIEIC:
6638f2abe6aSChristian Borntraeger 	case KVM_EXIT_UNKNOWN:
6649ace903dSChristian Ehrhardt 	case KVM_EXIT_INTR:
6658f2abe6aSChristian Borntraeger 	case KVM_EXIT_S390_RESET:
666e168bf8dSCarsten Otte 	case KVM_EXIT_S390_UCONTROL:
667fa6b7fe9SCornelia Huck 	case KVM_EXIT_S390_TSCH:
6688f2abe6aSChristian Borntraeger 		break;
6698f2abe6aSChristian Borntraeger 	default:
6708f2abe6aSChristian Borntraeger 		BUG();
6718f2abe6aSChristian Borntraeger 	}
6728f2abe6aSChristian Borntraeger 
673d7b0b5ebSCarsten Otte 	vcpu->arch.sie_block->gpsw.mask = kvm_run->psw_mask;
674d7b0b5ebSCarsten Otte 	vcpu->arch.sie_block->gpsw.addr = kvm_run->psw_addr;
67560b413c9SChristian Borntraeger 	if (kvm_run->kvm_dirty_regs & KVM_SYNC_PREFIX) {
67660b413c9SChristian Borntraeger 		kvm_run->kvm_dirty_regs &= ~KVM_SYNC_PREFIX;
67760b413c9SChristian Borntraeger 		kvm_s390_set_prefix(vcpu, kvm_run->s.regs.prefix);
67860b413c9SChristian Borntraeger 	}
6799eed0735SChristian Borntraeger 	if (kvm_run->kvm_dirty_regs & KVM_SYNC_CRS) {
6809eed0735SChristian Borntraeger 		kvm_run->kvm_dirty_regs &= ~KVM_SYNC_CRS;
6819eed0735SChristian Borntraeger 		memcpy(&vcpu->arch.sie_block->gcr, &kvm_run->s.regs.crs, 128);
6829eed0735SChristian Borntraeger 		kvm_s390_set_prefix(vcpu, kvm_run->s.regs.prefix);
6839eed0735SChristian Borntraeger 	}
684d7b0b5ebSCarsten Otte 
685dab4079dSHeiko Carstens 	might_fault();
6868f2abe6aSChristian Borntraeger 
6878f2abe6aSChristian Borntraeger 	do {
688e168bf8dSCarsten Otte 		rc = __vcpu_run(vcpu);
689e168bf8dSCarsten Otte 		if (rc)
690e168bf8dSCarsten Otte 			break;
691c0d744a9SCarsten Otte 		if (kvm_is_ucontrol(vcpu->kvm))
692c0d744a9SCarsten Otte 			rc = -EOPNOTSUPP;
693c0d744a9SCarsten Otte 		else
6948f2abe6aSChristian Borntraeger 			rc = kvm_handle_sie_intercept(vcpu);
6958f2abe6aSChristian Borntraeger 	} while (!signal_pending(current) && !rc);
6968f2abe6aSChristian Borntraeger 
6979ace903dSChristian Ehrhardt 	if (rc == SIE_INTERCEPT_RERUNVCPU)
6989ace903dSChristian Ehrhardt 		goto rerun_vcpu;
6999ace903dSChristian Ehrhardt 
700b1d16c49SChristian Ehrhardt 	if (signal_pending(current) && !rc) {
701b1d16c49SChristian Ehrhardt 		kvm_run->exit_reason = KVM_EXIT_INTR;
7028f2abe6aSChristian Borntraeger 		rc = -EINTR;
703b1d16c49SChristian Ehrhardt 	}
7048f2abe6aSChristian Borntraeger 
705e168bf8dSCarsten Otte #ifdef CONFIG_KVM_S390_UCONTROL
706e168bf8dSCarsten Otte 	if (rc == SIE_INTERCEPT_UCONTROL) {
707e168bf8dSCarsten Otte 		kvm_run->exit_reason = KVM_EXIT_S390_UCONTROL;
708e168bf8dSCarsten Otte 		kvm_run->s390_ucontrol.trans_exc_code =
709e168bf8dSCarsten Otte 			current->thread.gmap_addr;
710e168bf8dSCarsten Otte 		kvm_run->s390_ucontrol.pgm_code = 0x10;
711e168bf8dSCarsten Otte 		rc = 0;
712e168bf8dSCarsten Otte 	}
713e168bf8dSCarsten Otte #endif
714e168bf8dSCarsten Otte 
715b8e660b8SHeiko Carstens 	if (rc == -EOPNOTSUPP) {
7168f2abe6aSChristian Borntraeger 		/* intercept cannot be handled in-kernel, prepare kvm-run */
7178f2abe6aSChristian Borntraeger 		kvm_run->exit_reason         = KVM_EXIT_S390_SIEIC;
7188f2abe6aSChristian Borntraeger 		kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode;
7198f2abe6aSChristian Borntraeger 		kvm_run->s390_sieic.ipa      = vcpu->arch.sie_block->ipa;
7208f2abe6aSChristian Borntraeger 		kvm_run->s390_sieic.ipb      = vcpu->arch.sie_block->ipb;
7218f2abe6aSChristian Borntraeger 		rc = 0;
7228f2abe6aSChristian Borntraeger 	}
7238f2abe6aSChristian Borntraeger 
7248f2abe6aSChristian Borntraeger 	if (rc == -EREMOTE) {
7258f2abe6aSChristian Borntraeger 		/* intercept was handled, but userspace support is needed
7268f2abe6aSChristian Borntraeger 		 * kvm_run has been prepared by the handler */
7278f2abe6aSChristian Borntraeger 		rc = 0;
7288f2abe6aSChristian Borntraeger 	}
7298f2abe6aSChristian Borntraeger 
730d7b0b5ebSCarsten Otte 	kvm_run->psw_mask     = vcpu->arch.sie_block->gpsw.mask;
731d7b0b5ebSCarsten Otte 	kvm_run->psw_addr     = vcpu->arch.sie_block->gpsw.addr;
73260b413c9SChristian Borntraeger 	kvm_run->s.regs.prefix = vcpu->arch.sie_block->prefix;
7339eed0735SChristian Borntraeger 	memcpy(&kvm_run->s.regs.crs, &vcpu->arch.sie_block->gcr, 128);
734d7b0b5ebSCarsten Otte 
735b0c632dbSHeiko Carstens 	if (vcpu->sigset_active)
736b0c632dbSHeiko Carstens 		sigprocmask(SIG_SETMASK, &sigsaved, NULL);
737b0c632dbSHeiko Carstens 
738b0c632dbSHeiko Carstens 	vcpu->stat.exit_userspace++;
7397e8e6ab4SHeiko Carstens 	return rc;
740b0c632dbSHeiko Carstens }
741b0c632dbSHeiko Carstens 
742092670cdSCarsten Otte static int __guestcopy(struct kvm_vcpu *vcpu, u64 guestdest, void *from,
743b0c632dbSHeiko Carstens 		       unsigned long n, int prefix)
744b0c632dbSHeiko Carstens {
745b0c632dbSHeiko Carstens 	if (prefix)
746b0c632dbSHeiko Carstens 		return copy_to_guest(vcpu, guestdest, from, n);
747b0c632dbSHeiko Carstens 	else
748b0c632dbSHeiko Carstens 		return copy_to_guest_absolute(vcpu, guestdest, from, n);
749b0c632dbSHeiko Carstens }
750b0c632dbSHeiko Carstens 
751b0c632dbSHeiko Carstens /*
752b0c632dbSHeiko Carstens  * store status at address
753b0c632dbSHeiko Carstens  * we use have two special cases:
754b0c632dbSHeiko Carstens  * KVM_S390_STORE_STATUS_NOADDR: -> 0x1200 on 64 bit
755b0c632dbSHeiko Carstens  * KVM_S390_STORE_STATUS_PREFIXED: -> prefix
756b0c632dbSHeiko Carstens  */
757971eb77fSChristian Borntraeger int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
758b0c632dbSHeiko Carstens {
759092670cdSCarsten Otte 	unsigned char archmode = 1;
760b0c632dbSHeiko Carstens 	int prefix;
761b0c632dbSHeiko Carstens 
762b0c632dbSHeiko Carstens 	if (addr == KVM_S390_STORE_STATUS_NOADDR) {
763b0c632dbSHeiko Carstens 		if (copy_to_guest_absolute(vcpu, 163ul, &archmode, 1))
764b0c632dbSHeiko Carstens 			return -EFAULT;
765b0c632dbSHeiko Carstens 		addr = SAVE_AREA_BASE;
766b0c632dbSHeiko Carstens 		prefix = 0;
767b0c632dbSHeiko Carstens 	} else if (addr == KVM_S390_STORE_STATUS_PREFIXED) {
768b0c632dbSHeiko Carstens 		if (copy_to_guest(vcpu, 163ul, &archmode, 1))
769b0c632dbSHeiko Carstens 			return -EFAULT;
770b0c632dbSHeiko Carstens 		addr = SAVE_AREA_BASE;
771b0c632dbSHeiko Carstens 		prefix = 1;
772b0c632dbSHeiko Carstens 	} else
773b0c632dbSHeiko Carstens 		prefix = 0;
774b0c632dbSHeiko Carstens 
77515bc8d84SChristian Borntraeger 	/*
77615bc8d84SChristian Borntraeger 	 * The guest FPRS and ACRS are in the host FPRS/ACRS due to the lazy
77715bc8d84SChristian Borntraeger 	 * copying in vcpu load/put. Lets update our copies before we save
77815bc8d84SChristian Borntraeger 	 * it into the save area
77915bc8d84SChristian Borntraeger 	 */
78015bc8d84SChristian Borntraeger 	save_fp_regs(&vcpu->arch.guest_fpregs);
78115bc8d84SChristian Borntraeger 	save_access_regs(vcpu->run->s.regs.acrs);
78215bc8d84SChristian Borntraeger 
783f64ca217SHeiko Carstens 	if (__guestcopy(vcpu, addr + offsetof(struct save_area, fp_regs),
784b0c632dbSHeiko Carstens 			vcpu->arch.guest_fpregs.fprs, 128, prefix))
785b0c632dbSHeiko Carstens 		return -EFAULT;
786b0c632dbSHeiko Carstens 
787f64ca217SHeiko Carstens 	if (__guestcopy(vcpu, addr + offsetof(struct save_area, gp_regs),
7885a32c1afSChristian Borntraeger 			vcpu->run->s.regs.gprs, 128, prefix))
789b0c632dbSHeiko Carstens 		return -EFAULT;
790b0c632dbSHeiko Carstens 
791f64ca217SHeiko Carstens 	if (__guestcopy(vcpu, addr + offsetof(struct save_area, psw),
792b0c632dbSHeiko Carstens 			&vcpu->arch.sie_block->gpsw, 16, prefix))
793b0c632dbSHeiko Carstens 		return -EFAULT;
794b0c632dbSHeiko Carstens 
795f64ca217SHeiko Carstens 	if (__guestcopy(vcpu, addr + offsetof(struct save_area, pref_reg),
796b0c632dbSHeiko Carstens 			&vcpu->arch.sie_block->prefix, 4, prefix))
797b0c632dbSHeiko Carstens 		return -EFAULT;
798b0c632dbSHeiko Carstens 
799b0c632dbSHeiko Carstens 	if (__guestcopy(vcpu,
800f64ca217SHeiko Carstens 			addr + offsetof(struct save_area, fp_ctrl_reg),
801b0c632dbSHeiko Carstens 			&vcpu->arch.guest_fpregs.fpc, 4, prefix))
802b0c632dbSHeiko Carstens 		return -EFAULT;
803b0c632dbSHeiko Carstens 
804f64ca217SHeiko Carstens 	if (__guestcopy(vcpu, addr + offsetof(struct save_area, tod_reg),
805b0c632dbSHeiko Carstens 			&vcpu->arch.sie_block->todpr, 4, prefix))
806b0c632dbSHeiko Carstens 		return -EFAULT;
807b0c632dbSHeiko Carstens 
808f64ca217SHeiko Carstens 	if (__guestcopy(vcpu, addr + offsetof(struct save_area, timer),
809b0c632dbSHeiko Carstens 			&vcpu->arch.sie_block->cputm, 8, prefix))
810b0c632dbSHeiko Carstens 		return -EFAULT;
811b0c632dbSHeiko Carstens 
812f64ca217SHeiko Carstens 	if (__guestcopy(vcpu, addr + offsetof(struct save_area, clk_cmp),
813b0c632dbSHeiko Carstens 			&vcpu->arch.sie_block->ckc, 8, prefix))
814b0c632dbSHeiko Carstens 		return -EFAULT;
815b0c632dbSHeiko Carstens 
816f64ca217SHeiko Carstens 	if (__guestcopy(vcpu, addr + offsetof(struct save_area, acc_regs),
81759674c1aSChristian Borntraeger 			&vcpu->run->s.regs.acrs, 64, prefix))
818b0c632dbSHeiko Carstens 		return -EFAULT;
819b0c632dbSHeiko Carstens 
820b0c632dbSHeiko Carstens 	if (__guestcopy(vcpu,
821f64ca217SHeiko Carstens 			addr + offsetof(struct save_area, ctrl_regs),
822b0c632dbSHeiko Carstens 			&vcpu->arch.sie_block->gcr, 128, prefix))
823b0c632dbSHeiko Carstens 		return -EFAULT;
824b0c632dbSHeiko Carstens 	return 0;
825b0c632dbSHeiko Carstens }
826b0c632dbSHeiko Carstens 
827d6712df9SCornelia Huck static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
828d6712df9SCornelia Huck 				     struct kvm_enable_cap *cap)
829d6712df9SCornelia Huck {
830d6712df9SCornelia Huck 	int r;
831d6712df9SCornelia Huck 
832d6712df9SCornelia Huck 	if (cap->flags)
833d6712df9SCornelia Huck 		return -EINVAL;
834d6712df9SCornelia Huck 
835d6712df9SCornelia Huck 	switch (cap->cap) {
836fa6b7fe9SCornelia Huck 	case KVM_CAP_S390_CSS_SUPPORT:
837fa6b7fe9SCornelia Huck 		if (!vcpu->kvm->arch.css_support) {
838fa6b7fe9SCornelia Huck 			vcpu->kvm->arch.css_support = 1;
839fa6b7fe9SCornelia Huck 			trace_kvm_s390_enable_css(vcpu->kvm);
840fa6b7fe9SCornelia Huck 		}
841fa6b7fe9SCornelia Huck 		r = 0;
842fa6b7fe9SCornelia Huck 		break;
843d6712df9SCornelia Huck 	default:
844d6712df9SCornelia Huck 		r = -EINVAL;
845d6712df9SCornelia Huck 		break;
846d6712df9SCornelia Huck 	}
847d6712df9SCornelia Huck 	return r;
848d6712df9SCornelia Huck }
849d6712df9SCornelia Huck 
850b0c632dbSHeiko Carstens long kvm_arch_vcpu_ioctl(struct file *filp,
851b0c632dbSHeiko Carstens 			 unsigned int ioctl, unsigned long arg)
852b0c632dbSHeiko Carstens {
853b0c632dbSHeiko Carstens 	struct kvm_vcpu *vcpu = filp->private_data;
854b0c632dbSHeiko Carstens 	void __user *argp = (void __user *)arg;
855bc923cc9SAvi Kivity 	long r;
856b0c632dbSHeiko Carstens 
85793736624SAvi Kivity 	switch (ioctl) {
85893736624SAvi Kivity 	case KVM_S390_INTERRUPT: {
859ba5c1e9bSCarsten Otte 		struct kvm_s390_interrupt s390int;
860ba5c1e9bSCarsten Otte 
86193736624SAvi Kivity 		r = -EFAULT;
862ba5c1e9bSCarsten Otte 		if (copy_from_user(&s390int, argp, sizeof(s390int)))
86393736624SAvi Kivity 			break;
86493736624SAvi Kivity 		r = kvm_s390_inject_vcpu(vcpu, &s390int);
86593736624SAvi Kivity 		break;
866ba5c1e9bSCarsten Otte 	}
867b0c632dbSHeiko Carstens 	case KVM_S390_STORE_STATUS:
868bc923cc9SAvi Kivity 		r = kvm_s390_vcpu_store_status(vcpu, arg);
869bc923cc9SAvi Kivity 		break;
870b0c632dbSHeiko Carstens 	case KVM_S390_SET_INITIAL_PSW: {
871b0c632dbSHeiko Carstens 		psw_t psw;
872b0c632dbSHeiko Carstens 
873bc923cc9SAvi Kivity 		r = -EFAULT;
874b0c632dbSHeiko Carstens 		if (copy_from_user(&psw, argp, sizeof(psw)))
875bc923cc9SAvi Kivity 			break;
876bc923cc9SAvi Kivity 		r = kvm_arch_vcpu_ioctl_set_initial_psw(vcpu, psw);
877bc923cc9SAvi Kivity 		break;
878b0c632dbSHeiko Carstens 	}
879b0c632dbSHeiko Carstens 	case KVM_S390_INITIAL_RESET:
880bc923cc9SAvi Kivity 		r = kvm_arch_vcpu_ioctl_initial_reset(vcpu);
881bc923cc9SAvi Kivity 		break;
88214eebd91SCarsten Otte 	case KVM_SET_ONE_REG:
88314eebd91SCarsten Otte 	case KVM_GET_ONE_REG: {
88414eebd91SCarsten Otte 		struct kvm_one_reg reg;
88514eebd91SCarsten Otte 		r = -EFAULT;
88614eebd91SCarsten Otte 		if (copy_from_user(&reg, argp, sizeof(reg)))
88714eebd91SCarsten Otte 			break;
88814eebd91SCarsten Otte 		if (ioctl == KVM_SET_ONE_REG)
88914eebd91SCarsten Otte 			r = kvm_arch_vcpu_ioctl_set_one_reg(vcpu, &reg);
89014eebd91SCarsten Otte 		else
89114eebd91SCarsten Otte 			r = kvm_arch_vcpu_ioctl_get_one_reg(vcpu, &reg);
89214eebd91SCarsten Otte 		break;
89314eebd91SCarsten Otte 	}
89427e0393fSCarsten Otte #ifdef CONFIG_KVM_S390_UCONTROL
89527e0393fSCarsten Otte 	case KVM_S390_UCAS_MAP: {
89627e0393fSCarsten Otte 		struct kvm_s390_ucas_mapping ucasmap;
89727e0393fSCarsten Otte 
89827e0393fSCarsten Otte 		if (copy_from_user(&ucasmap, argp, sizeof(ucasmap))) {
89927e0393fSCarsten Otte 			r = -EFAULT;
90027e0393fSCarsten Otte 			break;
90127e0393fSCarsten Otte 		}
90227e0393fSCarsten Otte 
90327e0393fSCarsten Otte 		if (!kvm_is_ucontrol(vcpu->kvm)) {
90427e0393fSCarsten Otte 			r = -EINVAL;
90527e0393fSCarsten Otte 			break;
90627e0393fSCarsten Otte 		}
90727e0393fSCarsten Otte 
90827e0393fSCarsten Otte 		r = gmap_map_segment(vcpu->arch.gmap, ucasmap.user_addr,
90927e0393fSCarsten Otte 				     ucasmap.vcpu_addr, ucasmap.length);
91027e0393fSCarsten Otte 		break;
91127e0393fSCarsten Otte 	}
91227e0393fSCarsten Otte 	case KVM_S390_UCAS_UNMAP: {
91327e0393fSCarsten Otte 		struct kvm_s390_ucas_mapping ucasmap;
91427e0393fSCarsten Otte 
91527e0393fSCarsten Otte 		if (copy_from_user(&ucasmap, argp, sizeof(ucasmap))) {
91627e0393fSCarsten Otte 			r = -EFAULT;
91727e0393fSCarsten Otte 			break;
91827e0393fSCarsten Otte 		}
91927e0393fSCarsten Otte 
92027e0393fSCarsten Otte 		if (!kvm_is_ucontrol(vcpu->kvm)) {
92127e0393fSCarsten Otte 			r = -EINVAL;
92227e0393fSCarsten Otte 			break;
92327e0393fSCarsten Otte 		}
92427e0393fSCarsten Otte 
92527e0393fSCarsten Otte 		r = gmap_unmap_segment(vcpu->arch.gmap, ucasmap.vcpu_addr,
92627e0393fSCarsten Otte 			ucasmap.length);
92727e0393fSCarsten Otte 		break;
92827e0393fSCarsten Otte 	}
92927e0393fSCarsten Otte #endif
930ccc7910fSCarsten Otte 	case KVM_S390_VCPU_FAULT: {
931ccc7910fSCarsten Otte 		r = gmap_fault(arg, vcpu->arch.gmap);
932ccc7910fSCarsten Otte 		if (!IS_ERR_VALUE(r))
933ccc7910fSCarsten Otte 			r = 0;
934ccc7910fSCarsten Otte 		break;
935ccc7910fSCarsten Otte 	}
936d6712df9SCornelia Huck 	case KVM_ENABLE_CAP:
937d6712df9SCornelia Huck 	{
938d6712df9SCornelia Huck 		struct kvm_enable_cap cap;
939d6712df9SCornelia Huck 		r = -EFAULT;
940d6712df9SCornelia Huck 		if (copy_from_user(&cap, argp, sizeof(cap)))
941d6712df9SCornelia Huck 			break;
942d6712df9SCornelia Huck 		r = kvm_vcpu_ioctl_enable_cap(vcpu, &cap);
943d6712df9SCornelia Huck 		break;
944d6712df9SCornelia Huck 	}
945b0c632dbSHeiko Carstens 	default:
9463e6afcf1SCarsten Otte 		r = -ENOTTY;
947b0c632dbSHeiko Carstens 	}
948bc923cc9SAvi Kivity 	return r;
949b0c632dbSHeiko Carstens }
950b0c632dbSHeiko Carstens 
9515b1c1493SCarsten Otte int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
9525b1c1493SCarsten Otte {
9535b1c1493SCarsten Otte #ifdef CONFIG_KVM_S390_UCONTROL
9545b1c1493SCarsten Otte 	if ((vmf->pgoff == KVM_S390_SIE_PAGE_OFFSET)
9555b1c1493SCarsten Otte 		 && (kvm_is_ucontrol(vcpu->kvm))) {
9565b1c1493SCarsten Otte 		vmf->page = virt_to_page(vcpu->arch.sie_block);
9575b1c1493SCarsten Otte 		get_page(vmf->page);
9585b1c1493SCarsten Otte 		return 0;
9595b1c1493SCarsten Otte 	}
9605b1c1493SCarsten Otte #endif
9615b1c1493SCarsten Otte 	return VM_FAULT_SIGBUS;
9625b1c1493SCarsten Otte }
9635b1c1493SCarsten Otte 
964db3fe4ebSTakuya Yoshikawa void kvm_arch_free_memslot(struct kvm_memory_slot *free,
965db3fe4ebSTakuya Yoshikawa 			   struct kvm_memory_slot *dont)
966db3fe4ebSTakuya Yoshikawa {
967db3fe4ebSTakuya Yoshikawa }
968db3fe4ebSTakuya Yoshikawa 
969db3fe4ebSTakuya Yoshikawa int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages)
970db3fe4ebSTakuya Yoshikawa {
971db3fe4ebSTakuya Yoshikawa 	return 0;
972db3fe4ebSTakuya Yoshikawa }
973db3fe4ebSTakuya Yoshikawa 
974b0c632dbSHeiko Carstens /* Section: memory related */
975f7784b8eSMarcelo Tosatti int kvm_arch_prepare_memory_region(struct kvm *kvm,
976f7784b8eSMarcelo Tosatti 				   struct kvm_memory_slot *memslot,
9777b6195a9STakuya Yoshikawa 				   struct kvm_userspace_memory_region *mem,
9787b6195a9STakuya Yoshikawa 				   enum kvm_mr_change change)
979b0c632dbSHeiko Carstens {
980*dd2887e7SNick Wang 	/* A few sanity checks. We can have memory slots which have to be
981*dd2887e7SNick Wang 	   located/ended at a segment boundary (1MB). The memory in userland is
982*dd2887e7SNick Wang 	   ok to be fragmented into various different vmas. It is okay to mmap()
983*dd2887e7SNick Wang 	   and munmap() stuff in this slot after doing this call at any time */
984b0c632dbSHeiko Carstens 
985598841caSCarsten Otte 	if (mem->userspace_addr & 0xffffful)
986b0c632dbSHeiko Carstens 		return -EINVAL;
987b0c632dbSHeiko Carstens 
988598841caSCarsten Otte 	if (mem->memory_size & 0xffffful)
989b0c632dbSHeiko Carstens 		return -EINVAL;
990b0c632dbSHeiko Carstens 
991f7784b8eSMarcelo Tosatti 	return 0;
992f7784b8eSMarcelo Tosatti }
993f7784b8eSMarcelo Tosatti 
994f7784b8eSMarcelo Tosatti void kvm_arch_commit_memory_region(struct kvm *kvm,
995f7784b8eSMarcelo Tosatti 				struct kvm_userspace_memory_region *mem,
9968482644aSTakuya Yoshikawa 				const struct kvm_memory_slot *old,
9978482644aSTakuya Yoshikawa 				enum kvm_mr_change change)
998f7784b8eSMarcelo Tosatti {
999f7850c92SCarsten Otte 	int rc;
1000f7784b8eSMarcelo Tosatti 
10012cef4debSChristian Borntraeger 	/* If the basics of the memslot do not change, we do not want
10022cef4debSChristian Borntraeger 	 * to update the gmap. Every update causes several unnecessary
10032cef4debSChristian Borntraeger 	 * segment translation exceptions. This is usually handled just
10042cef4debSChristian Borntraeger 	 * fine by the normal fault handler + gmap, but it will also
10052cef4debSChristian Borntraeger 	 * cause faults on the prefix page of running guest CPUs.
10062cef4debSChristian Borntraeger 	 */
10072cef4debSChristian Borntraeger 	if (old->userspace_addr == mem->userspace_addr &&
10082cef4debSChristian Borntraeger 	    old->base_gfn * PAGE_SIZE == mem->guest_phys_addr &&
10092cef4debSChristian Borntraeger 	    old->npages * PAGE_SIZE == mem->memory_size)
10102cef4debSChristian Borntraeger 		return;
1011598841caSCarsten Otte 
1012598841caSCarsten Otte 	rc = gmap_map_segment(kvm->arch.gmap, mem->userspace_addr,
1013598841caSCarsten Otte 		mem->guest_phys_addr, mem->memory_size);
1014598841caSCarsten Otte 	if (rc)
1015f7850c92SCarsten Otte 		printk(KERN_WARNING "kvm-s390: failed to commit memory region\n");
1016598841caSCarsten Otte 	return;
1017b0c632dbSHeiko Carstens }
1018b0c632dbSHeiko Carstens 
10192df72e9bSMarcelo Tosatti void kvm_arch_flush_shadow_all(struct kvm *kvm)
10202df72e9bSMarcelo Tosatti {
10212df72e9bSMarcelo Tosatti }
10222df72e9bSMarcelo Tosatti 
10232df72e9bSMarcelo Tosatti void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
10242df72e9bSMarcelo Tosatti 				   struct kvm_memory_slot *slot)
102534d4cb8fSMarcelo Tosatti {
102634d4cb8fSMarcelo Tosatti }
102734d4cb8fSMarcelo Tosatti 
1028b0c632dbSHeiko Carstens static int __init kvm_s390_init(void)
1029b0c632dbSHeiko Carstens {
1030ef50f7acSChristian Borntraeger 	int ret;
10310ee75beaSAvi Kivity 	ret = kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE);
1032ef50f7acSChristian Borntraeger 	if (ret)
1033ef50f7acSChristian Borntraeger 		return ret;
1034ef50f7acSChristian Borntraeger 
1035ef50f7acSChristian Borntraeger 	/*
1036ef50f7acSChristian Borntraeger 	 * guests can ask for up to 255+1 double words, we need a full page
103725985edcSLucas De Marchi 	 * to hold the maximum amount of facilities. On the other hand, we
1038ef50f7acSChristian Borntraeger 	 * only set facilities that are known to work in KVM.
1039ef50f7acSChristian Borntraeger 	 */
1040c2f0e8c8SHeiko Carstens 	facilities = (unsigned long long *) get_zeroed_page(GFP_KERNEL|GFP_DMA);
1041ef50f7acSChristian Borntraeger 	if (!facilities) {
1042ef50f7acSChristian Borntraeger 		kvm_exit();
1043ef50f7acSChristian Borntraeger 		return -ENOMEM;
1044ef50f7acSChristian Borntraeger 	}
104514375bc4SMartin Schwidefsky 	memcpy(facilities, S390_lowcore.stfle_fac_list, 16);
10466d00d00bSChristian Borntraeger 	facilities[0] &= 0xff00fff3f47c0000ULL;
104787cac8f8SChristian Borntraeger 	facilities[1] &= 0x001c000000000000ULL;
1048ef50f7acSChristian Borntraeger 	return 0;
1049b0c632dbSHeiko Carstens }
1050b0c632dbSHeiko Carstens 
1051b0c632dbSHeiko Carstens static void __exit kvm_s390_exit(void)
1052b0c632dbSHeiko Carstens {
1053ef50f7acSChristian Borntraeger 	free_page((unsigned long) facilities);
1054b0c632dbSHeiko Carstens 	kvm_exit();
1055b0c632dbSHeiko Carstens }
1056b0c632dbSHeiko Carstens 
1057b0c632dbSHeiko Carstens module_init(kvm_s390_init);
1058b0c632dbSHeiko Carstens module_exit(kvm_s390_exit);
1059