Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp3861126pxj; Tue, 15 Jun 2021 10:10:57 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwBezEvMqBqMaSuHaHaQPCTveWlnG3g358bxIGcScBMkXsOhrPx1D/Rtw6FtoYfcfQRH7r7 X-Received: by 2002:a17:906:7842:: with SMTP id p2mr542759ejm.487.1623777057590; Tue, 15 Jun 2021 10:10:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1623777057; cv=none; d=google.com; s=arc-20160816; b=Q/Yue9TMB+YHcIikCIsw/xS+4NJs17WaXUYwUEosLRtNFG5ffzAwUSrDKiUbQsGz66 BDdyTsHfhjskLKBC/h2cxN9Pl2Z/g/1OO2njvtDHo6OjNnLNnF0vY2NWY+AmgMSo2oiW 3j5+91UoRqd+2M+creHOvYng1ir0BWGVFCqQw85xg67dpvHz60DZgNIcUQ3Hq4FQi3KQ mLMAYQIzcs00vOaUmj26Cmrw2CDijrAQ8gz1755SwIrGvoYdVbqnpccdlRi3GfCPMQTd zh8AZT6nBhNhPzCCYRAEqnET3fK6RMP7VMzfQAZUYun8PtQ33iQNJFnJ//QUHBIt0Fg7 dwkg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=QdDlU1BXQqFpnsM+x6g+COCPY7J30v/vmpzA297tlFk=; b=xoV/sZziCm205RK9GCzqgF5MtNGi2oEW40cdymhYMRfHksyCbBNUJf8EYbOeCxRuEm d8EyTI/QtlxbhphKuUHD+CNquWCgcucH9bOFl2bLeXrInLDRM77ZFHQ6hgcmHMlxlAeV in8mohsNz0PCYIZCCtF8CpM3UJy3rlLbw4tmut1+wTOH4j9ayUZVQ2XKQXreVkzhO0GH GnlyMMOZii85N6mIRyhhOz309XcZ+g5IFddm0/8HZpFag06fJZzvBvCjUYMK61hoT1aF a/JEIQqQmegzqX4wigJ3FTD/tZhJFMDcCovYifXLTk5W4wP3QcxuR7Fz1/H4t3mTst1a m1lg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@quicinc.com header.s=qcdkim header.b=IAbnUsnX; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=quicinc.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id i9si10574504edf.46.2021.06.15.10.10.34; Tue, 15 Jun 2021 10:10:57 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=fail header.i=@quicinc.com header.s=qcdkim header.b=IAbnUsnX; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=quicinc.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231515AbhFORLO (ORCPT + 99 others); Tue, 15 Jun 2021 13:11:14 -0400 Received: from alexa-out-sd-01.qualcomm.com ([199.106.114.38]:10212 "EHLO alexa-out-sd-01.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231173AbhFORK5 (ORCPT ); Tue, 15 Jun 2021 13:10:57 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1623776932; x=1655312932; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=LGJGpnuG0uMt0y87eWE3gLIkYnYBQba4VrRy65O7wqg=; b=IAbnUsnXk4p0LZsSjPJC8x1/hIiL+DJgfKaZJzVMis72MPUP7TWJqKVy 0RYDk6yQCCzszACC2UXcMN0W0DY++Rrw9h0WUJ7qZkFdLhCvF84TIDIyf uP7TjcEv6JBE/DZhUh/ETjhY6/vAUD8eb6aaxkq3HdHjp8MoFlBYnCPiK 8=; Received: from unknown (HELO ironmsg02-sd.qualcomm.com) ([10.53.140.142]) by alexa-out-sd-01.qualcomm.com with ESMTP; 15 Jun 2021 10:08:52 -0700 X-QCInternal: smtphost Received: from nasanexm03e.na.qualcomm.com ([10.85.0.48]) by ironmsg02-sd.qualcomm.com with ESMTP/TLS/AES256-SHA; 15 Jun 2021 10:08:52 -0700 Received: from th-lint-040.qualcomm.com (10.80.80.8) by nasanexm03e.na.qualcomm.com (10.85.0.48) with Microsoft SMTP Server (TLS) id 15.0.1497.18; Tue, 15 Jun 2021 10:08:51 -0700 From: Georgi Djakov To: , CC: , , , , , , , Subject: [PATCH v6 08/15] iommu: Add support for the map_pages() callback Date: Tue, 15 Jun 2021 10:08:26 -0700 Message-ID: <1623776913-390160-9-git-send-email-quic_c_gdjako@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1623776913-390160-1-git-send-email-quic_c_gdjako@quicinc.com> References: <1623776913-390160-1-git-send-email-quic_c_gdjako@quicinc.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nasanexm03e.na.qualcomm.com (10.85.0.48) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: "Isaac J. Manjarres" Since iommu_pgsize can calculate how many pages of the same size can be mapped/unmapped before the next largest page size boundary, add support for invoking an IOMMU driver's map_pages() callback, if it provides one. Signed-off-by: Isaac J. Manjarres Suggested-by: Will Deacon Signed-off-by: Georgi Djakov --- drivers/iommu/iommu.c | 43 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 725622c7e603..89f8ab6a72a9 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -2429,6 +2429,30 @@ static size_t iommu_pgsize(struct iommu_domain *domain, unsigned long iova, return pgsize; } +static int __iommu_map_pages(struct iommu_domain *domain, unsigned long iova, + phys_addr_t paddr, size_t size, int prot, + gfp_t gfp, size_t *mapped) +{ + const struct iommu_ops *ops = domain->ops; + size_t pgsize, count; + int ret; + + pgsize = iommu_pgsize(domain, iova, paddr, size, &count); + + pr_debug("mapping: iova 0x%lx pa %pa pgsize 0x%zx count %ld\n", + iova, &paddr, pgsize, count); + + if (ops->map_pages) { + ret = ops->map_pages(domain, iova, paddr, pgsize, count, prot, + gfp, mapped); + } else { + ret = ops->map(domain, iova, paddr, pgsize, prot, gfp); + *mapped = ret ? 0 : pgsize; + } + + return ret; +} + static int __iommu_map(struct iommu_domain *domain, unsigned long iova, phys_addr_t paddr, size_t size, int prot, gfp_t gfp) { @@ -2439,7 +2463,7 @@ static int __iommu_map(struct iommu_domain *domain, unsigned long iova, phys_addr_t orig_paddr = paddr; int ret = 0; - if (unlikely(ops->map == NULL || + if (unlikely(!(ops->map || ops->map_pages) || domain->pgsize_bitmap == 0UL)) return -ENODEV; @@ -2463,18 +2487,21 @@ static int __iommu_map(struct iommu_domain *domain, unsigned long iova, pr_debug("map: iova 0x%lx pa %pa size 0x%zx\n", iova, &paddr, size); while (size) { - size_t pgsize = iommu_pgsize(domain, iova, paddr, size, NULL); + size_t mapped = 0; - pr_debug("mapping: iova 0x%lx pa %pa pgsize 0x%zx\n", - iova, &paddr, pgsize); - ret = ops->map(domain, iova, paddr, pgsize, prot, gfp); + ret = __iommu_map_pages(domain, iova, paddr, size, prot, gfp, + &mapped); + /* + * Some pages may have been mapped, even if an error occurred, + * so we should account for those so they can be unmapped. + */ + size -= mapped; if (ret) break; - iova += pgsize; - paddr += pgsize; - size -= pgsize; + iova += mapped; + paddr += mapped; } /* unroll mapping in case something went wrong */