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, ®s->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(®s->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(®, 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, ®); 89014eebd91SCarsten Otte else 89114eebd91SCarsten Otte r = kvm_arch_vcpu_ioctl_get_one_reg(vcpu, ®); 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