From patchwork Wed Apr 18 11:40:40 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: 133613 Delivered-To: patch@linaro.org Received: by 10.46.84.18 with SMTP id i18csp5775931ljb; Wed, 18 Apr 2018 04:43:56 -0700 (PDT) X-Google-Smtp-Source: AIpwx49vPqN0s/hrPytW4uA0A+I3leM5fy5KxMYeX2IxihPJSovimbqPOzxAhEfLdAVWH4JcRScJ X-Received: by 2002:a17:902:28a6:: with SMTP id f35-v6mr1805604plb.204.1524051836027; Wed, 18 Apr 2018 04:43:56 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1524051836; cv=none; d=google.com; s=arc-20160816; b=ZorOnMMrkFduszHZDARcYx+aIp40jxo1Hp8rJp0ynRC2gjsKSNBcUIzS0IVRtgq0mF SKqdq5t7T/eJAcmYBr4f5AxGJIgWsevCq8QQlLRRK1Pur2l27+VZMcCu86CZGtCdkZZ0 5r1fymg94zFhEO7aasomiUY1gqoqYVpmAAPYp4XqTAL+ibM2W3SIP7NuJ/yCret2rJHL bYsTe2sJ/un3bbESJw8TXvU0wioxBFnp5dNT509RQCl58xBKEFWb5ZiAICOUpKUN0OJa Iz/RtSvoTFNsLzB4j7lKXPsQaLBkiALUmrSE7uooqOZmegz6OwCxEHgWn2aF44h08pcb 9LIQ== 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=uFKoFyV4lDM3oCNFaGkWQudDxU66OozteUP72VdthPA=; b=nLijKiB84qfgnIsuhJfr4X+kMeB3JT9w4aAz0t90u550EF2mjLpyVnkbPL0mTx2P0l Eh6uYiT2Au7lA8+BLmYmhEiNauxc+7zAkvIVekPZwpCwwz/NPuHIh8bi3jebqzOB//Ky 9b5sMq0Jsz7Nbq0Y3Lm/5chTTYHAiQPQrWR5yYoHI+0sPxpE27DF89SnqnmDDz6gJWbD m8XaHi1KNL2NZNQc6dSinHidQg+1yKGyacXeYvzGLJSOcywd1/7i9jQZ9c6iRMCXaGxL ybcK51Ok0mXiHCKWDJIucy0aPUooDYUIUw+mIoErHWwbVEXYtbu9TVRnPfoA6/8BgeXq vQJQ== 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 91-v6si1084665ply.33.2018.04.18.04.43.55; Wed, 18 Apr 2018 04:43:56 -0700 (PDT) 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 S1754030AbeDRLnv (ORCPT + 29 others); Wed, 18 Apr 2018 07:43:51 -0400 Received: from szxga07-in.huawei.com ([45.249.212.35]:42251 "EHLO huawei.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1753982AbeDRLnt (ORCPT ); Wed, 18 Apr 2018 07:43:49 -0400 Received: from DGGEMS405-HUB.china.huawei.com (unknown [172.30.72.58]) by Forcepoint Email with ESMTP id 21CE1564814C0; Wed, 18 Apr 2018 19:43:46 +0800 (CST) Received: from S00345302A-PC.china.huawei.com (10.202.227.237) by DGGEMS405-HUB.china.huawei.com (10.3.19.205) with Microsoft SMTP Server id 14.3.361.1; Wed, 18 Apr 2018 19:43:39 +0800 From: Shameer Kolothum To: , , CC: , , , , , , Shameer Kolothum Subject: [PATCH v6 2/7] vfio/type1: Check reserve region conflict and update iova list Date: Wed, 18 Apr 2018 12:40:40 +0100 Message-ID: <20180418114045.7968-3-shameerali.kolothum.thodi@huawei.com> X-Mailer: git-send-email 2.12.0.windows.1 In-Reply-To: <20180418114045.7968-1-shameerali.kolothum.thodi@huawei.com> References: <20180418114045.7968-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 775946d..a0a79e1 100644 --- a/drivers/vfio/vfio_iommu_type1.c +++ b/drivers/vfio/vfio_iommu_type1.c @@ -1422,6 +1422,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; @@ -1475,6 +1551,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); @@ -1553,6 +1630,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) @@ -1563,6 +1647,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); @@ -1623,6 +1711,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; @@ -1631,6 +1720,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);