From patchwork Wed Aug 15 01:28:27 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhen Lei X-Patchwork-Id: 144255 Delivered-To: patch@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp249547ljj; Tue, 14 Aug 2018 18:32:40 -0700 (PDT) X-Google-Smtp-Source: AA+uWPwyYHAGIMgdql7cIzxAVjYla635JZgGH+6KS9OvdTrJVD5DlzqJsCmJYH0kl/Z05jOUvEmI X-Received: by 2002:a17:902:47c2:: with SMTP id d2-v6mr22197461plh.139.1534296760343; Tue, 14 Aug 2018 18:32:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1534296760; cv=none; d=google.com; s=arc-20160816; b=A8uvFSTK0K7lMXRzBkcy4uNsU6bycqXpX251r1US/eMBIhGka7+YtvIeKe8iG3zuGc ylYuGsWKrtu/pMtFNmVPCKaykofauCZZziEMTHYODRLigutlRBckr5JHo5/4W/4c96H/ F9Ds1/MXvUSglgoOgrd8VUg0bswc3pVa5v422IMXqgurTCyn/XDAgUpgbSLwVHz1uFfo miKZ8AmfyzksJosap1OCmT7wWvPirO9veDt8mTtKVEKoQxI8sFSYgWbj9Zy0CU8IySBR akrvfapSapWZhBqcGGBxsc3jKhHUJNNXJDgXDNI+Odd8EfRMsgWqy6ICgeQsblmxR8FW cHsw== 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=K13mHjTtmhhRT1dEN7hBy7iI4gd++I7lxeqryHWmrr8=; b=unvfy/7uYQYO32Hx955iZbwt7wVb2/qjBFqHHsJlUBM/sKiDBmnHDJpjUSxqA2SLJp g3igUx1hytWgleQ3+A/1fESAw+TUi3CphuAW02R+ubbAcG3qkRgT5A2ZmTWvDC/yXnHb q/Ior3YwMXXjPSe/d6lrQr1jvMkQpuC8NFbLu6+BQxvYFXcUjt9RwtHO5bxpkhpEwmJw xlZftpQFRuokHbjEjyA6gnzMGfXl1357tomdZbG6PO7cNK5UnZZ+Jr0uEANFD7H5/iyA egmkyO+93RFLQK8n9dBe6ZYImtOLG5evfMWE9G704bICTVFVLHP89GUyrs3i1Dk5HC7x u2KA== 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 q27-v6si22423596pfj.149.2018.08.14.18.32.40; Tue, 14 Aug 2018 18:32:40 -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 S1727055AbeHOEWa (ORCPT + 32 others); Wed, 15 Aug 2018 00:22:30 -0400 Received: from szxga05-in.huawei.com ([45.249.212.191]:10725 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1725847AbeHOEWa (ORCPT ); Wed, 15 Aug 2018 00:22:30 -0400 Received: from DGGEMS412-HUB.china.huawei.com (unknown [172.30.72.58]) by Forcepoint Email with ESMTP id 4AAB8D7ED320D; Wed, 15 Aug 2018 09:32:34 +0800 (CST) Received: from localhost (10.177.23.164) by DGGEMS412-HUB.china.huawei.com (10.3.19.212) with Microsoft SMTP Server id 14.3.399.0; Wed, 15 Aug 2018 09:32:28 +0800 From: Zhen Lei To: Robin Murphy , Will Deacon , Joerg Roedel , linux-arm-kernel , iommu , linux-kernel CC: Zhen Lei , LinuxArm , Hanjun Guo , Libin , "John Garry" Subject: [PATCH v5 2/5] iommu/dma: add support for non-strict mode Date: Wed, 15 Aug 2018 09:28:27 +0800 Message-ID: <1534296510-12888-3-git-send-email-thunder.leizhen@huawei.com> X-Mailer: git-send-email 1.9.5.msysgit.0 In-Reply-To: <1534296510-12888-1-git-send-email-thunder.leizhen@huawei.com> References: <1534296510-12888-1-git-send-email-thunder.leizhen@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.177.23.164] X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 1. Save the related domain pointer in struct iommu_dma_cookie, make iovad capable call domain->ops->flush_iotlb_all to flush TLB. 2. During the iommu domain initialization phase, base on domain->non_strict field to check whether non-strict mode is supported or not. If so, call init_iova_flush_queue to register iovad->flush_cb callback. 3. All unmap(contains iova-free) APIs will finally invoke __iommu_dma_unmap -->iommu_dma_free_iova. If the domain is non-strict, call queue_iova to put off iova freeing, and omit iommu_tlb_sync operation. Signed-off-by: Zhen Lei --- drivers/iommu/dma-iommu.c | 29 ++++++++++++++++++++++++++++- drivers/iommu/iommu.c | 1 + include/linux/iommu.h | 1 + 3 files changed, 30 insertions(+), 1 deletion(-) -- 1.8.3 diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c index ddcbbdb..f0257e9 100644 --- a/drivers/iommu/dma-iommu.c +++ b/drivers/iommu/dma-iommu.c @@ -55,6 +55,9 @@ struct iommu_dma_cookie { }; struct list_head msi_page_list; spinlock_t msi_lock; + + /* Only be assigned in non-strict mode, otherwise it's NULL */ + struct iommu_domain *domain; }; static inline size_t cookie_msi_granule(struct iommu_dma_cookie *cookie) @@ -257,6 +260,17 @@ static int iova_reserve_iommu_regions(struct device *dev, return ret; } +static void iommu_dma_flush_iotlb_all(struct iova_domain *iovad) +{ + struct iommu_dma_cookie *cookie; + struct iommu_domain *domain; + + cookie = container_of(iovad, struct iommu_dma_cookie, iovad); + domain = cookie->domain; + + domain->ops->flush_iotlb_all(domain); +} + /** * iommu_dma_init_domain - Initialise a DMA mapping domain * @domain: IOMMU domain previously prepared by iommu_get_dma_cookie() @@ -308,6 +322,14 @@ int iommu_dma_init_domain(struct iommu_domain *domain, dma_addr_t base, } init_iova_domain(iovad, 1UL << order, base_pfn); + + if (domain->non_strict) { + BUG_ON(!domain->ops->flush_iotlb_all); + + cookie->domain = domain; + init_iova_flush_queue(iovad, iommu_dma_flush_iotlb_all, NULL); + } + if (!dev) return 0; @@ -390,6 +412,9 @@ static void iommu_dma_free_iova(struct iommu_dma_cookie *cookie, /* The MSI case is only ever cleaning up its most recent allocation */ if (cookie->type == IOMMU_DMA_MSI_COOKIE) cookie->msi_iova -= size; + else if (cookie->domain) /* non-strict mode */ + queue_iova(iovad, iova_pfn(iovad, iova), + size >> iova_shift(iovad), 0); else free_iova_fast(iovad, iova_pfn(iovad, iova), size >> iova_shift(iovad)); @@ -405,7 +430,9 @@ static void __iommu_dma_unmap(struct iommu_domain *domain, dma_addr_t dma_addr, dma_addr -= iova_off; size = iova_align(iovad, size + iova_off); - WARN_ON(iommu_unmap(domain, dma_addr, size) != size); + WARN_ON(iommu_unmap_fast(domain, dma_addr, size) != size); + if (!domain->non_strict) + iommu_tlb_sync(domain); iommu_dma_free_iova(cookie, dma_addr, size); } diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 63b3756..6255a69 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -1263,6 +1263,7 @@ static struct iommu_domain *__iommu_domain_alloc(struct bus_type *bus, domain->ops = bus->iommu_ops; domain->type = type; + domain->non_strict = false; /* Assume all sizes by default; the driver may override this later */ domain->pgsize_bitmap = bus->iommu_ops->pgsize_bitmap; diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 19938ee..4bbcf39 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -88,6 +88,7 @@ struct iommu_domain_geometry { struct iommu_domain { unsigned type; + bool non_strict; const struct iommu_ops *ops; unsigned long pgsize_bitmap; /* Bitmap of page sizes in use */ iommu_fault_handler_t handler;