From patchwork Thu Mar 15 16:35:04 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: 131817 Delivered-To: patch@linaro.org Received: by 10.80.210.197 with SMTP id q5csp1697517edg; Thu, 15 Mar 2018 09:38:16 -0700 (PDT) X-Google-Smtp-Source: AG47ELsiQohzSfKOzxtgGWZNSzbQU3/NHYBbobPlBV7LI1GjeSxUxKvOIfAH+W9neFjso66/sCK4 X-Received: by 10.101.75.202 with SMTP id p10mr4793099pgr.339.1521131896759; Thu, 15 Mar 2018 09:38:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1521131896; cv=none; d=google.com; s=arc-20160816; b=SsubwQt1wLUZ/DcDeMjs92+aXJbt1jE272d72P7GhxunC9EBObohOJUgb+yo4QmeF6 gDqoPYq6HOLd4Jjs1f4Vwd7nw7ZdZwXjUYDI5yl7BXqIiKsT4SwB9uWyqWwenz1rA01p fNrZZXi0qYq7DtYLP4ExE/Qw3CYml74lVbRXYRW7HBv4gTVW2/6IbQI4QCL23PU7cLWD gciEzCoyuvbyTqwdFSWziwcjDTgAB+rQuj1LO+5wRRWdaZB0hMVV1oxIkrPPkrS3sqta bxax3K44fbikKT5WZUTv+c0vJzWXT4EDHqhxxcevJkGITFTUAY8vySLjMxb2O9DoSkUG 0tpg== 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=5VEDN5QIoL7AYLxgPRKMBRuPBsuHugRzTUy5j5up3s0=; b=f+xw7nXNJEl+HMg+V6iJc43NyCRA9sVTYgVoJUA9ygbLO8Zujh5CoWF0S4AU7CBz3u tVTr6qlzh+xMM6F9Fr2a7UghEGTGlb4tU+Mk0TJYMGxqIsmKtzeBkxnXOLVkArrnIYuE O64XN85PBtVVdIg0XYsOzjKcxvlqhE6rkxuzviyS9G9vLsLS9ivAz2K3mtH9L/o834v2 G8/+7EbtIgFW4rgq6AGaTaqSKSIeSac1iSAnwqJrACBcyrjQR6XCCL82KF1aDKRI/9CL +1xd4sRBE2xlEG7AQWg34vCzikSdQuF2eO6XwEaXxgMJo++emwx6RG/nk7dzn9UvqXu7 9Xfg== 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 i5-v6si4301438plr.393.2018.03.15.09.38.16; Thu, 15 Mar 2018 09:38:16 -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 S1752186AbeCOQiM (ORCPT + 28 others); Thu, 15 Mar 2018 12:38:12 -0400 Received: from szxga04-in.huawei.com ([45.249.212.190]:6648 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751982AbeCOQiJ (ORCPT ); Thu, 15 Mar 2018 12:38:09 -0400 Received: from DGGEMS413-HUB.china.huawei.com (unknown [172.30.72.58]) by Forcepoint Email with ESMTP id 7FB443D26B2EE; Fri, 16 Mar 2018 00:37:54 +0800 (CST) Received: from S00345302A-PC.china.huawei.com (10.202.227.237) by DGGEMS413-HUB.china.huawei.com (10.3.19.213) with Microsoft SMTP Server id 14.3.361.1; Fri, 16 Mar 2018 00:37:48 +0800 From: Shameer Kolothum To: , , CC: , , , , , , Shameer Kolothum Subject: [PATCH v5 2/7] vfio/type1: Check reserve region conflict and update iova list Date: Thu, 15 Mar 2018 16:35:04 +0000 Message-ID: <20180315163509.17740-3-shameerali.kolothum.thodi@huawei.com> X-Mailer: git-send-email 2.12.0.windows.1 In-Reply-To: <20180315163509.17740-1-shameerali.kolothum.thodi@huawei.com> References: <20180315163509.17740-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 1123c74..cfe2bb2 100644 --- a/drivers/vfio/vfio_iommu_type1.c +++ b/drivers/vfio/vfio_iommu_type1.c @@ -1313,6 +1313,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; @@ -1366,6 +1442,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); @@ -1444,6 +1521,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) @@ -1454,6 +1538,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); @@ -1514,6 +1602,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; @@ -1522,6 +1611,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);