From patchwork Wed Feb 21 12:22:05 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shameerali Kolothum Thodi X-Patchwork-Id: 129054 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp561357ljc; Wed, 21 Feb 2018 04:23:43 -0800 (PST) X-Google-Smtp-Source: AH8x225uvN9SQe7cawLeMDGdnDdJadGSvr8Na7k18AV3b2NtT9ZdFk0XAry+l3mSE++5ny0w06oD X-Received: by 2002:a17:902:5a88:: with SMTP id r8-v6mr3096970pli.426.1519215823411; Wed, 21 Feb 2018 04:23:43 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519215823; cv=none; d=google.com; s=arc-20160816; b=E5fom3KTqyQNg8mYCvRHcP3GqkRGUnSysFQSgJEapIPxkLmBTGGgMvDX1QuCuTvfMp NyfcbWlywWVdsLVa55V0VM+mR+vSHAlG0O/d3C5mzxux7IQSmuBfTZFA8jInT0LIHwjN eJsGZevu4l1oquIsWpGs+I0X4NigLm11vJxk7GTXA9SZUao8qHtcVDRxvzpCZ8hAbJjU WH52/+hqRz4aEpaCznvMiq82Onm8LjbTvsVrEn+d5qLLB+ztv/sks53kwEsdnbnWZOt3 ByY79uRY0PpQHlmP75xWkXq6qql3JpNQlbnqC2n8utCcYYUtKH58d5/j9NNkgW/dTBh+ 3VkQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:arc-authentication-results; bh=9dLnHSI/Ga7Ae6ZFaQoVPEyvWPORngWl7jyok3jLxm8=; b=ZpxF3hdGJ8Eg98g6smHmcnmUwA7P6RwFgu94iP02RNgZbk4lKBPAwGCzCwPkuNkfwb pfj01LbuVVUr2zhsxw+xxpRKXeWbVLuLzRW+WbGrEtOZtopoYAA178eZuN+G+AMQQqiA g5MNveu1PYU1UjX0Ye3SBoDuB+3nUCG8xpcNCKCc2wsfQ9ewbbhQZq0q038qOqbm1cL4 KAbMzd8VC5nCmZlS82oLeUGy0UZp9bVrHCbvjiajB9yMI1KmyEjXTyxDw2ZbFQ8htsnV bijmcrwXSUFb/O+nhysctp1C6alGqpDwMyulZ/rBsTC5h27YfQYCwcJtg/x6jMgL2yrG FlPA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p11si1240291pgs.537.2018.02.21.04.23.43; Wed, 21 Feb 2018 04:23:43 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754142AbeBUMXj (ORCPT + 28 others); Wed, 21 Feb 2018 07:23:39 -0500 Received: from szxga04-in.huawei.com ([45.249.212.190]:5655 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752480AbeBUMXh (ORCPT ); Wed, 21 Feb 2018 07:23:37 -0500 Received: from DGGEMS414-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id 687B967B5E818; Wed, 21 Feb 2018 20:23:20 +0800 (CST) Received: from S00345302A-PC.china.huawei.com (10.202.227.237) by DGGEMS414-HUB.china.huawei.com (10.3.19.214) with Microsoft SMTP Server id 14.3.361.1; Wed, 21 Feb 2018 20:23:12 +0800 From: Shameer Kolothum To: , , CC: , , , , , Shameer Kolothum Subject: [PATCH v4 2/6] vfio/type1: Check reserve region conflict and update iova list Date: Wed, 21 Feb 2018 12:22:05 +0000 Message-ID: <20180221122209.9292-3-shameerali.kolothum.thodi@huawei.com> X-Mailer: git-send-email 2.12.0.windows.1 In-Reply-To: <20180221122209.9292-1-shameerali.kolothum.thodi@huawei.com> References: <20180221122209.9292-1-shameerali.kolothum.thodi@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.202.227.237] X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This retrieves the reserved regions associated with dev group and checks for conflicts with any existing dma mappings. Also update the iova list excluding the reserved regions. Signed-off-by: Shameer Kolothum --- drivers/vfio/vfio_iommu_type1.c | 90 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) -- 2.7.4 diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c index ac6772d..66c57ee 100644 --- a/drivers/vfio/vfio_iommu_type1.c +++ b/drivers/vfio/vfio_iommu_type1.c @@ -1301,6 +1301,82 @@ static int vfio_iommu_aper_resize(struct list_head *iova, return 0; } +/* + * Check reserved region conflicts with existing dma mappings + */ +static bool vfio_iommu_resv_conflict(struct vfio_iommu *iommu, + struct list_head *resv_regions) +{ + struct iommu_resv_region *region; + + /* Check for conflict with existing dma mappings */ + list_for_each_entry(region, resv_regions, list) { + if (vfio_find_dma(iommu, region->start, region->length)) + return true; + } + + return false; +} + +/* + * Check iova region overlap with reserved regions and + * exclude them from the iommu iova range + */ +static int vfio_iommu_resv_exclude(struct list_head *iova, + struct list_head *resv_regions) +{ + struct iommu_resv_region *resv; + struct vfio_iova *n, *next; + + list_for_each_entry(resv, resv_regions, list) { + phys_addr_t start, end; + + start = resv->start; + end = resv->start + resv->length - 1; + + list_for_each_entry_safe(n, next, iova, list) { + int ret = 0; + + /* No overlap */ + if ((start > n->end) || (end < n->start)) + continue; + /* + * Insert a new node if current node overlaps with the + * reserve region to exlude that from valid iova range. + * Note that, new node is inserted before the current + * node and finally the current node is deleted keeping + * the list updated and sorted. + */ + if (start > n->start) + ret = vfio_iommu_iova_insert(&n->list, + n->start, start - 1); + if (!ret && end < n->end) + ret = vfio_iommu_iova_insert(&n->list, + end + 1, n->end); + if (ret) + return ret; + + list_del(&n->list); + kfree(n); + } + } + + if (list_empty(iova)) + return -EINVAL; + + return 0; +} + +static void vfio_iommu_resv_free(struct list_head *resv_regions) +{ + struct iommu_resv_region *n, *next; + + list_for_each_entry_safe(n, next, resv_regions, list) { + list_del(&n->list); + kfree(n); + } +} + static void vfio_iommu_iova_free(struct list_head *iova) { struct vfio_iova *n, *next; @@ -1354,6 +1430,7 @@ static int vfio_iommu_type1_attach_group(void *iommu_data, phys_addr_t resv_msi_base; struct iommu_domain_geometry geo; LIST_HEAD(iova_copy); + LIST_HEAD(group_resv_regions); mutex_lock(&iommu->lock); @@ -1432,6 +1509,13 @@ static int vfio_iommu_type1_attach_group(void *iommu_data, goto out_detach; } + iommu_get_group_resv_regions(iommu_group, &group_resv_regions); + + if (vfio_iommu_resv_conflict(iommu, &group_resv_regions)) { + ret = -EINVAL; + goto out_detach; + } + /* Get a copy of the current iova list and work on it */ ret = vfio_iommu_iova_get_copy(iommu, &iova_copy); if (ret) @@ -1442,6 +1526,10 @@ static int vfio_iommu_type1_attach_group(void *iommu_data, if (ret) goto out_detach; + ret = vfio_iommu_resv_exclude(&iova_copy, &group_resv_regions); + if (ret) + goto out_detach; + resv_msi = vfio_iommu_has_sw_msi(iommu_group, &resv_msi_base); INIT_LIST_HEAD(&domain->group_list); @@ -1502,6 +1590,7 @@ static int vfio_iommu_type1_attach_group(void *iommu_data, /* Delete the old one and insert new iova list */ vfio_iommu_iova_insert_copy(iommu, &iova_copy); mutex_unlock(&iommu->lock); + vfio_iommu_resv_free(&group_resv_regions); return 0; @@ -1510,6 +1599,7 @@ static int vfio_iommu_type1_attach_group(void *iommu_data, out_domain: iommu_domain_free(domain->domain); vfio_iommu_iova_free(&iova_copy); + vfio_iommu_resv_free(&group_resv_regions); out_free: kfree(domain); kfree(group);