From mboxrd@z Thu Jan 1 00:00:00 1970 From: Dong Jia Shi Subject: Re: [PATCH v11 09/22] vfio iommu type1: Add task structure to vfio_dma Date: Thu, 10 Nov 2016 16:24:28 +0800 Message-ID: <41208.4362273619$1505294409@news.gmane.org> References: <1478293856-8191-1-git-send-email-kwankhede@nvidia.com> <1478293856-8191-10-git-send-email-kwankhede@nvidia.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Cc: kevin.tian@intel.com, cjia@nvidia.com, kvm@vger.kernel.org, qemu-devel@nongnu.org, linux-kernel@vger.kernel.org, jike.song@intel.com, alex.williamson@redhat.com, kraxel@redhat.com, pbonzini@redhat.com, bjsdjshi@linux.vnet.ibm.com To: Kirti Wankhede Return-path: Content-Disposition: inline In-Reply-To: <1478293856-8191-10-git-send-email-kwankhede@nvidia.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+gceq-qemu-devel=gmane.org@nongnu.org Sender: "Qemu-devel" List-Id: kvm.vger.kernel.org * Kirti Wankhede [2016-11-05 02:40:43 +0530]: Hi Kirti, [...] > static int vfio_dma_do_map(struct vfio_iommu *iommu, > struct vfio_iommu_type1_dma_map *map) > { > dma_addr_t iova = map->iova; > unsigned long vaddr = map->vaddr; > size_t size = map->size; > - long npage; > int ret = 0, prot = 0; > uint64_t mask; > struct vfio_dma *dma; > - unsigned long pfn; > + struct vfio_addr_space *addr_space; > + struct mm_struct *mm; > + bool free_addr_space_on_err = false; > > /* Verify that none of our __u64 fields overflow */ > if (map->size != size || map->vaddr != vaddr || map->iova != iova) > @@ -608,47 +685,56 @@ static int vfio_dma_do_map(struct vfio_iommu *iommu, > mutex_lock(&iommu->lock); > > if (vfio_find_dma(iommu, iova, size)) { > - mutex_unlock(&iommu->lock); > - return -EEXIST; > + ret = -EEXIST; > + goto do_map_err; > + } > + > + mm = get_task_mm(current); > + if (!mm) { > + ret = -ENODEV; > + goto do_map_err; > + } > + > + addr_space = vfio_find_addr_space(iommu, mm); > + if (addr_space) { > + atomic_inc(&addr_space->ref_count); > + mmput(mm); > + } else { > + addr_space = kzalloc(sizeof(*addr_space), GFP_KERNEL); > + if (!addr_space) { > + ret = -ENOMEM; No need to call (?): mmput(mm); > + goto do_map_err; > + } > + addr_space->mm = mm; > + atomic_set(&addr_space->ref_count, 1); > + list_add(&addr_space->next, &iommu->addr_space_list); > + free_addr_space_on_err = true; > } > > dma = kzalloc(sizeof(*dma), GFP_KERNEL); > if (!dma) { > - mutex_unlock(&iommu->lock); > - return -ENOMEM; > + if (free_addr_space_on_err) { > + mmput(mm); > + list_del(&addr_space->next); > + kfree(addr_space); > + } > + ret = -ENOMEM; > + goto do_map_err; > } > > dma->iova = iova; > dma->vaddr = vaddr; > dma->prot = prot; > + dma->addr_space = addr_space; > + get_task_struct(current); > + dma->task = current; > + dma->mlock_cap = capable(CAP_IPC_LOCK); > > /* Insert zero-sized and grow as we map chunks of it */ > vfio_link_dma(iommu, dma); > > - while (size) { > - /* Pin a contiguous chunk of memory */ > - npage = __vfio_pin_pages_remote(vaddr + dma->size, > - size >> PAGE_SHIFT, prot, &pfn); > - if (npage <= 0) { > - WARN_ON(!npage); > - ret = (int)npage; > - break; > - } > - > - /* Map it! */ > - ret = vfio_iommu_map(iommu, iova + dma->size, pfn, npage, prot); > - if (ret) { > - __vfio_unpin_pages_remote(pfn, npage, prot, true); > - break; > - } > - > - size -= npage << PAGE_SHIFT; > - dma->size += npage << PAGE_SHIFT; > - } > - > - if (ret) > - vfio_remove_dma(iommu, dma); > - > + ret = vfio_pin_map_dma(iommu, dma, size); > +do_map_err: > mutex_unlock(&iommu->lock); > return ret; > } > -- > 2.7.0 > -- Dong Jia