From mboxrd@z Thu Jan 1 00:00:00 1970 From: Carsten Otte Subject: [patch 02/12] [PATCH] kvm-s390-ucontrol: per vcpu address spaces Date: Thu, 01 Dec 2011 13:57:34 +0100 Message-ID: <20111201130409.005720389@de.ibm.com> References: <20111201125732.085553111@de.ibm.com> Cc: Christian Borntraeger , Heiko Carstens , Martin Schwidefsky , Cornelia Huck , KVM , Joachim von Buttlar , Jens Freimann , Constantin Werner To: Avi Kivity , Marcelo Tossati Return-path: Received: from e06smtp16.uk.ibm.com ([195.75.94.112]:55124 "EHLO e06smtp16.uk.ibm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753919Ab1LANEO (ORCPT ); Thu, 1 Dec 2011 08:04:14 -0500 Received: from /spool/local by e06smtp16.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 1 Dec 2011 13:04:13 -0000 Received: from d06av02.portsmouth.uk.ibm.com (d06av02.portsmouth.uk.ibm.com [9.149.37.228]) by d06nrmr1507.portsmouth.uk.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id pB1D49eE2334860 for ; Thu, 1 Dec 2011 13:04:09 GMT Received: from d06av02.portsmouth.uk.ibm.com (loopback [127.0.0.1]) by d06av02.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id pB1D49Tj023061 for ; Thu, 1 Dec 2011 06:04:09 -0700 Content-Disposition: inline; filename=address-spaces.patch Sender: kvm-owner@vger.kernel.org List-ID: This patch introduces two ioctls for virtual cpus, that are only valid for kernel virtual machines that are controlled by userspace. Each virtual cpu has its individual address space in this mode of operation, and each address space is backed by the gmap implementation just like the address space for regular KVM guests. KVM_S390_UCAS_MAP allows to map a part of the user's virtual address space to the vcpu. Starting offset and length in both the user and the vcpu address space need to be aligned to 1M. KVM_S390_UCAS_UNMAP can be used to unmap a range of memory from a virtual cpu in a similar way. Signed-off-by: Carsten Otte --- --- arch/s390/kvm/kvm-s390.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++- include/linux/kvm.h | 7 ++++++ 2 files changed, 56 insertions(+), 1 deletion(-) --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -249,6 +249,10 @@ void kvm_arch_vcpu_destroy(struct kvm_vc (__u64) vcpu->arch.sie_block) vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sda = 0; smp_mb(); + + if (kvm_is_ucontrol(vcpu->kvm)) + gmap_free(vcpu->arch.gmap); + free_page((unsigned long)(vcpu->arch.sie_block)); kvm_vcpu_uninit(vcpu); kfree(vcpu); @@ -279,12 +283,20 @@ void kvm_arch_destroy_vm(struct kvm *kvm kvm_free_vcpus(kvm); free_page((unsigned long)(kvm->arch.sca)); debug_unregister(kvm->arch.dbf); - gmap_free(kvm->arch.gmap); + if (!kvm_is_ucontrol(kvm)) + gmap_free(kvm->arch.gmap); } /* Section: vcpu related */ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) { + if (kvm_is_ucontrol(vcpu->kvm)) { + vcpu->arch.gmap = gmap_alloc(current->mm); + if (!vcpu->arch.gmap) + return -ENOMEM; + return 0; + } + vcpu->arch.gmap = vcpu->kvm->arch.gmap; return 0; } @@ -703,6 +715,42 @@ long kvm_arch_vcpu_ioctl(struct file *fi case KVM_S390_INITIAL_RESET: r = kvm_arch_vcpu_ioctl_initial_reset(vcpu); break; +#ifdef CONFIG_KVM_UCONTROL + case KVM_S390_UCAS_MAP: { + struct kvm_s390_ucas_mapping ucasmap; + + if (copy_from_user(&ucasmap, argp, sizeof(ucasmap))) { + r = -EFAULT; + break; + } + + if (!kvm_is_ucontrol(vcpu->kvm)) { + r = -EINVAL; + break; + } + + r = gmap_map_segment(vcpu->arch.gmap, ucasmap.user_addr, + ucasmap.vcpu_addr, ucasmap.length); + break; + } + case KVM_S390_UCAS_UNMAP: { + struct kvm_s390_ucas_mapping ucasmap; + + if (copy_from_user(&ucasmap, argp, sizeof(ucasmap))) { + r = -EFAULT; + break; + } + + if (!kvm_is_ucontrol(vcpu->kvm)) { + r = -EINVAL; + break; + } + + r = gmap_unmap_segment(vcpu->arch.gmap, ucasmap.vcpu_addr, + ucasmap.length); + break; + } +#endif default: r = -EINVAL; } --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -655,7 +655,14 @@ struct kvm_clock_data { #define KVM_SET_TSS_ADDR _IO(KVMIO, 0x47) #define KVM_SET_IDENTITY_MAP_ADDR _IOW(KVMIO, 0x48, __u64) /* enable ucontrol for s390 */ +struct kvm_s390_ucas_mapping { + unsigned long user_addr; + unsigned long vcpu_addr; + unsigned long length; +}; #define KVM_S390_ENABLE_UCONTROL _IO(KVMIO, 0x49) +#define KVM_S390_UCAS_MAP _IOW(KVMIO, 0x50, struct kvm_s390_ucas_mapping) +#define KVM_S390_UCAS_UNMAP _IOW(KVMIO, 0x51, struct kvm_s390_ucas_mapping) /* Device model IOC */ #define KVM_CREATE_IRQCHIP _IO(KVMIO, 0x60)