diff options
Diffstat (limited to 'arch/s390/kvm')
-rw-r--r-- | arch/s390/kvm/Kconfig | 1 | ||||
-rw-r--r-- | arch/s390/kvm/diag.c | 4 | ||||
-rw-r--r-- | arch/s390/kvm/intercept.c | 22 | ||||
-rw-r--r-- | arch/s390/kvm/interrupt.c | 13 | ||||
-rw-r--r-- | arch/s390/kvm/kvm-s390.c | 49 | ||||
-rw-r--r-- | arch/s390/kvm/kvm-s390.h | 10 | ||||
-rw-r--r-- | arch/s390/kvm/priv.c | 3 | ||||
-rw-r--r-- | arch/s390/kvm/sigp.c | 5 |
8 files changed, 62 insertions, 45 deletions
diff --git a/arch/s390/kvm/Kconfig b/arch/s390/kvm/Kconfig index 6ee55ae84ce..a7251580891 100644 --- a/arch/s390/kvm/Kconfig +++ b/arch/s390/kvm/Kconfig @@ -35,6 +35,7 @@ config KVM # OK, it's a little counter-intuitive to do this, but it puts it neatly under # the virtualization menu. +source drivers/vhost/Kconfig source drivers/virtio/Kconfig endif # VIRTUALIZATION diff --git a/arch/s390/kvm/diag.c b/arch/s390/kvm/diag.c index 8300309698f..9e4c84187cf 100644 --- a/arch/s390/kvm/diag.c +++ b/arch/s390/kvm/diag.c @@ -39,7 +39,7 @@ static int __diag_ipl_functions(struct kvm_vcpu *vcpu) vcpu->run->s390_reset_flags = 0; break; default: - return -ENOTSUPP; + return -EOPNOTSUPP; } atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags); @@ -62,6 +62,6 @@ int kvm_s390_handle_diag(struct kvm_vcpu *vcpu) case 0x308: return __diag_ipl_functions(vcpu); default: - return -ENOTSUPP; + return -EOPNOTSUPP; } } diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c index ba9d8a7bc1a..3ddc30895e3 100644 --- a/arch/s390/kvm/intercept.c +++ b/arch/s390/kvm/intercept.c @@ -32,7 +32,7 @@ static int handle_lctlg(struct kvm_vcpu *vcpu) vcpu->stat.instruction_lctlg++; if ((vcpu->arch.sie_block->ipb & 0xff) != 0x2f) - return -ENOTSUPP; + return -EOPNOTSUPP; useraddr = disp2; if (base2) @@ -138,7 +138,7 @@ static int handle_stop(struct kvm_vcpu *vcpu) rc = __kvm_s390_vcpu_store_status(vcpu, KVM_S390_STORE_STATUS_NOADDR); if (rc >= 0) - rc = -ENOTSUPP; + rc = -EOPNOTSUPP; } if (vcpu->arch.local_int.action_bits & ACTION_RELOADVCPU_ON_STOP) { @@ -150,7 +150,7 @@ static int handle_stop(struct kvm_vcpu *vcpu) if (vcpu->arch.local_int.action_bits & ACTION_STOP_ON_STOP) { vcpu->arch.local_int.action_bits &= ~ACTION_STOP_ON_STOP; VCPU_EVENT(vcpu, 3, "%s", "cpu stopped"); - rc = -ENOTSUPP; + rc = -EOPNOTSUPP; } spin_unlock_bh(&vcpu->arch.local_int.lock); @@ -171,9 +171,9 @@ static int handle_validity(struct kvm_vcpu *vcpu) 2*PAGE_SIZE); if (rc) /* user will receive sigsegv, exit to user */ - rc = -ENOTSUPP; + rc = -EOPNOTSUPP; } else - rc = -ENOTSUPP; + rc = -EOPNOTSUPP; if (rc) VCPU_EVENT(vcpu, 2, "unhandled validity intercept code %d", @@ -189,7 +189,7 @@ static int handle_instruction(struct kvm_vcpu *vcpu) handler = instruction_handlers[vcpu->arch.sie_block->ipa >> 8]; if (handler) return handler(vcpu); - return -ENOTSUPP; + return -EOPNOTSUPP; } static int handle_prog(struct kvm_vcpu *vcpu) @@ -206,14 +206,14 @@ static int handle_instruction_and_prog(struct kvm_vcpu *vcpu) rc = handle_instruction(vcpu); rc2 = handle_prog(vcpu); - if (rc == -ENOTSUPP) + if (rc == -EOPNOTSUPP) vcpu->arch.sie_block->icptcode = 0x04; if (rc) return rc; return rc2; } -static const intercept_handler_t intercept_funcs[0x48 >> 2] = { +static const intercept_handler_t intercept_funcs[] = { [0x00 >> 2] = handle_noop, [0x04 >> 2] = handle_instruction, [0x08 >> 2] = handle_prog, @@ -230,10 +230,10 @@ int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu) intercept_handler_t func; u8 code = vcpu->arch.sie_block->icptcode; - if (code & 3 || code > 0x48) - return -ENOTSUPP; + if (code & 3 || (code >> 2) >= ARRAY_SIZE(intercept_funcs)) + return -EOPNOTSUPP; func = intercept_funcs[code >> 2]; if (func) return func(vcpu); - return -ENOTSUPP; + return -EOPNOTSUPP; } diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index 43486c2408e..35c21bf910c 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c @@ -10,12 +10,13 @@ * Author(s): Carsten Otte <cotte@de.ibm.com> */ -#include <asm/lowcore.h> -#include <asm/uaccess.h> -#include <linux/hrtimer.h> #include <linux/interrupt.h> #include <linux/kvm_host.h> +#include <linux/hrtimer.h> #include <linux/signal.h> +#include <linux/slab.h> +#include <asm/asm-offsets.h> +#include <asm/uaccess.h> #include "kvm-s390.h" #include "gaccess.h" @@ -187,8 +188,8 @@ static void __do_deliver_interrupt(struct kvm_vcpu *vcpu, if (rc == -EFAULT) exception = 1; - rc = put_guest_u64(vcpu, __LC_PFAULT_INTPARM, - inti->ext.ext_params2); + rc = put_guest_u64(vcpu, __LC_EXT_PARAMS2, + inti->ext.ext_params2); if (rc == -EFAULT) exception = 1; break; @@ -342,7 +343,7 @@ int kvm_s390_handle_wait(struct kvm_vcpu *vcpu) if (psw_interrupts_disabled(vcpu)) { VCPU_EVENT(vcpu, 3, "%s", "disabled wait"); __unset_cpu_idle(vcpu); - return -ENOTSUPP; /* disabled wait */ + return -EOPNOTSUPP; /* disabled wait */ } if (psw_extint_disabled(vcpu) || diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index f8bcaefd7d3..49292869a5c 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -23,6 +23,7 @@ #include <linux/module.h> #include <linux/slab.h> #include <linux/timer.h> +#include <asm/asm-offsets.h> #include <asm/lowcore.h> #include <asm/pgtable.h> #include <asm/nmi.h> @@ -241,6 +242,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm) kvm_free_physmem(kvm); free_page((unsigned long)(kvm->arch.sca)); debug_unregister(kvm->arch.dbf); + cleanup_srcu_struct(&kvm->srcu); kfree(kvm); } @@ -543,7 +545,7 @@ rerun_vcpu: rc = -EINTR; } - if (rc == -ENOTSUPP) { + if (rc == -EOPNOTSUPP) { /* intercept cannot be handled in-kernel, prepare kvm-run */ kvm_run->exit_reason = KVM_EXIT_S390_SIEIC; kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode; @@ -603,45 +605,45 @@ int __kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr) } else prefix = 0; - if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, fp_regs), + if (__guestcopy(vcpu, addr + offsetof(struct save_area, fp_regs), vcpu->arch.guest_fpregs.fprs, 128, prefix)) return -EFAULT; - if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, gp_regs), + if (__guestcopy(vcpu, addr + offsetof(struct save_area, gp_regs), vcpu->arch.guest_gprs, 128, prefix)) return -EFAULT; - if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, psw), + if (__guestcopy(vcpu, addr + offsetof(struct save_area, psw), &vcpu->arch.sie_block->gpsw, 16, prefix)) return -EFAULT; - if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, pref_reg), + if (__guestcopy(vcpu, addr + offsetof(struct save_area, pref_reg), &vcpu->arch.sie_block->prefix, 4, prefix)) return -EFAULT; if (__guestcopy(vcpu, - addr + offsetof(struct save_area_s390x, fp_ctrl_reg), + addr + offsetof(struct save_area, fp_ctrl_reg), &vcpu->arch.guest_fpregs.fpc, 4, prefix)) return -EFAULT; - if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, tod_reg), + if (__guestcopy(vcpu, addr + offsetof(struct save_area, tod_reg), &vcpu->arch.sie_block->todpr, 4, prefix)) return -EFAULT; - if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, timer), + if (__guestcopy(vcpu, addr + offsetof(struct save_area, timer), &vcpu->arch.sie_block->cputm, 8, prefix)) return -EFAULT; - if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, clk_cmp), + if (__guestcopy(vcpu, addr + offsetof(struct save_area, clk_cmp), &vcpu->arch.sie_block->ckc, 8, prefix)) return -EFAULT; - if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, acc_regs), + if (__guestcopy(vcpu, addr + offsetof(struct save_area, acc_regs), &vcpu->arch.guest_acrs, 64, prefix)) return -EFAULT; if (__guestcopy(vcpu, - addr + offsetof(struct save_area_s390x, ctrl_regs), + addr + offsetof(struct save_area, ctrl_regs), &vcpu->arch.sie_block->gcr, 128, prefix)) return -EFAULT; return 0; @@ -689,14 +691,12 @@ long kvm_arch_vcpu_ioctl(struct file *filp, } /* Section: memory related */ -int kvm_arch_set_memory_region(struct kvm *kvm, - struct kvm_userspace_memory_region *mem, - struct kvm_memory_slot old, - int user_alloc) +int kvm_arch_prepare_memory_region(struct kvm *kvm, + struct kvm_memory_slot *memslot, + struct kvm_memory_slot old, + struct kvm_userspace_memory_region *mem, + int user_alloc) { - int i; - struct kvm_vcpu *vcpu; - /* A few sanity checks. We can have exactly one memory slot which has to start at guest virtual zero and which has to be located at a page boundary in userland and which has to end at a page boundary. @@ -719,14 +719,23 @@ int kvm_arch_set_memory_region(struct kvm *kvm, if (!user_alloc) return -EINVAL; + return 0; +} + +void kvm_arch_commit_memory_region(struct kvm *kvm, + struct kvm_userspace_memory_region *mem, + struct kvm_memory_slot old, + int user_alloc) +{ + int i; + struct kvm_vcpu *vcpu; + /* request update of sie control block for all available vcpus */ kvm_for_each_vcpu(i, vcpu, kvm) { if (test_and_set_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests)) continue; kvm_s390_inject_sigp_stop(vcpu, ACTION_RELOADVCPU_ON_STOP); } - - return 0; } void kvm_arch_flush_shadow(struct kvm *kvm) diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h index 06cce8285ba..60f09ab3672 100644 --- a/arch/s390/kvm/kvm-s390.h +++ b/arch/s390/kvm/kvm-s390.h @@ -67,10 +67,14 @@ static inline long kvm_s390_vcpu_get_memsize(struct kvm_vcpu *vcpu) static inline void kvm_s390_vcpu_set_mem(struct kvm_vcpu *vcpu) { + int idx; struct kvm_memory_slot *mem; + struct kvm_memslots *memslots; - down_read(&vcpu->kvm->slots_lock); - mem = &vcpu->kvm->memslots[0]; + idx = srcu_read_lock(&vcpu->kvm->srcu); + memslots = rcu_dereference(vcpu->kvm->memslots); + + mem = &memslots->memslots[0]; vcpu->arch.sie_block->gmsor = mem->userspace_addr; vcpu->arch.sie_block->gmslm = @@ -78,7 +82,7 @@ static inline void kvm_s390_vcpu_set_mem(struct kvm_vcpu *vcpu) (mem->npages << PAGE_SHIFT) + VIRTIODESCSPACE - 1ul; - up_read(&vcpu->kvm->slots_lock); + srcu_read_unlock(&vcpu->kvm->srcu, idx); } /* implemented in priv.c */ diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c index d426aac8095..44205507717 100644 --- a/arch/s390/kvm/priv.c +++ b/arch/s390/kvm/priv.c @@ -12,6 +12,7 @@ */ #include <linux/kvm.h> +#include <linux/gfp.h> #include <linux/errno.h> #include <asm/current.h> #include <asm/debug.h> @@ -323,5 +324,5 @@ int kvm_s390_handle_b2(struct kvm_vcpu *vcpu) else return handler(vcpu); } - return -ENOTSUPP; + return -EOPNOTSUPP; } diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c index 15ee1111de5..eff3c5989b4 100644 --- a/arch/s390/kvm/sigp.c +++ b/arch/s390/kvm/sigp.c @@ -14,6 +14,7 @@ #include <linux/kvm.h> #include <linux/kvm_host.h> +#include <linux/slab.h> #include "gaccess.h" #include "kvm-s390.h" @@ -172,7 +173,7 @@ static int __sigp_set_arch(struct kvm_vcpu *vcpu, u32 parameter) rc = 0; /* order accepted */ break; default: - rc = -ENOTSUPP; + rc = -EOPNOTSUPP; } return rc; } @@ -293,7 +294,7 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu) vcpu->stat.instruction_sigp_restart++; /* user space must know about restart */ default: - return -ENOTSUPP; + return -EOPNOTSUPP; } if (rc < 0) |