Received: by 2002:ac0:a582:0:0:0:0:0 with SMTP id m2-v6csp4863211imm; Tue, 9 Oct 2018 06:26:50 -0700 (PDT) X-Google-Smtp-Source: ACcGV62EREvLPzaYpmZ1iWoUM3nSrHtxp9H/DeAuCU5lZxiCKeV7NLpAbVRt9vCPmkCmmTJ4hyfw X-Received: by 2002:a17:902:7c96:: with SMTP id y22-v6mr28696359pll.321.1539091610003; Tue, 09 Oct 2018 06:26:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1539091609; cv=none; d=google.com; s=arc-20160816; b=EsMrdQh4DNsgKTI/pVVnngJT1Af8qcV6IsHVrvYFe+FxN68E4O3YMy/akO+Wdh51XB DhBxlaQQqvrOZNNxAwskC25etlc50Gd5uBrT/ddIJAUtK6uDfhALGIwkxXXUvDYtPrO0 ncOAyiIiyang+Wjs4/bPZwsOSJxngb9tFbUtGzaK/xxuxhrAaUP7WX1wdQ6RvzAD1o+C z28AnJ5gAEXUXwxzwoPbQI5Gq8R8DIu2Ecl9FLvSRNPEhlpEWITm8mJHahLVRA30V8nk y224LzeQcjhTLymp1zaJenZhlWXfqTfCIrNDWRSK3FhtOGd1bv111iL8Dm/RsjI0vxBD 9W+g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=8XXesnZgyqra9gNm5NWYp3vrx3JH2lusaZA3YDbzupg=; b=X30UbyxRm6nWqm3C0Sn6/rYNGHRumdMTsjrHTpzs03LInZaAw28LkV2Y3A3358h+ui 9ovZGaP63KrPU0PR0aKWlrICqdgeEQWXvHyUonE5lMj1pB4tpHFnkgz76C2T3vkdGw60 wQ0LtpYUtf0cLiM1/7KqLJv2UtBOnF2imZDqbFRVtIYVcCgp2kh4t8Wrpjby/uza5NbM hEoRYruCZY4xdzwZ5lQnxDYy64dDb+ka5k7hLAw7qHdwzrIK5gH6OsUDjSoa5Xxm0UuP 90mrfKlsrvrcPlW9V6JcYS46DGTMuNeJq7Z9ymQtoRNAkMiFDulM2SmGyOInppuaPxjK bgQQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@infradead.org header.s=bombadil.20170209 header.b=qTOoNAR1; 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 s63-v6si12006910pfb.217.2018.10.09.06.26.34; Tue, 09 Oct 2018 06:26:49 -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; dkim=fail header.i=@infradead.org header.s=bombadil.20170209 header.b=qTOoNAR1; 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 S1727271AbeJIUmu (ORCPT + 99 others); Tue, 9 Oct 2018 16:42:50 -0400 Received: from bombadil.infradead.org ([198.137.202.133]:48776 "EHLO bombadil.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726664AbeJIUmt (ORCPT ); Tue, 9 Oct 2018 16:42:49 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20170209; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From :Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=8XXesnZgyqra9gNm5NWYp3vrx3JH2lusaZA3YDbzupg=; b=qTOoNAR18soyj1I+UmCdgEYnAo PcmXv00IVqlqFY2nzgm7VxvEW8nxkGexVaBpuGYofVYNk8VtILjIG+bmr9Y0Uk7uOjZ/KzYHi+dly BV8f97JT8WWHpTy4szWFK/7CLAJL/Vtl8fssej204XokIyDmNfHFXuUURTW0jdN27xNw9qvdP4fnK U814v+O3c+T6UfqtD9IeczbJ+PlMwpTg1yLIaBtAievxjPwuJIddOTBXXwSWuoxhLDbQrh7EZVo+u YSWxPHNGRpab8S0yUontLNtHWLxeACEq5y+OTAwag3bGzkFufH8Yrv1Y/qRMVet2l9q6sEFRyyRpi T40XhVsg==; Received: from clnet-p19-102.ikbnet.co.at ([83.175.77.102] helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.90_1 #2 (Red Hat Linux)) id 1g9s0w-0001AF-N9; Tue, 09 Oct 2018 13:25:31 +0000 From: Christoph Hellwig To: Benjamin Herrenschmidt , Paul Mackerras , Michael Ellerman Cc: linuxppc-dev@lists.ozlabs.org, iommu@lists.linux-foundation.org, linux-mm@kvack.org, linux-arch@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 12/33] powerpc/cell: use the generic iommu bypass code Date: Tue, 9 Oct 2018 15:24:39 +0200 Message-Id: <20181009132500.17643-13-hch@lst.de> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181009132500.17643-1-hch@lst.de> References: <20181009132500.17643-1-hch@lst.de> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This gets rid of a lot of clumsy code and finally allows us to mark dma_iommu_ops const. Signed-off-by: Christoph Hellwig --- arch/powerpc/include/asm/dma-mapping.h | 2 +- arch/powerpc/include/asm/iommu.h | 6 ++ arch/powerpc/kernel/dma-iommu.c | 7 +- arch/powerpc/platforms/cell/iommu.c | 143 ++----------------------- 4 files changed, 22 insertions(+), 136 deletions(-) diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h index 27283eb68c50..59c090b7eaac 100644 --- a/arch/powerpc/include/asm/dma-mapping.h +++ b/arch/powerpc/include/asm/dma-mapping.h @@ -73,7 +73,7 @@ static inline unsigned long device_to_mask(struct device *dev) * Available generic sets of operations */ #ifdef CONFIG_PPC64 -extern struct dma_map_ops dma_iommu_ops; +extern const struct dma_map_ops dma_iommu_ops; #endif extern const struct dma_map_ops dma_nommu_ops; diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h index 26b7cc176a99..264d04f1dcd1 100644 --- a/arch/powerpc/include/asm/iommu.h +++ b/arch/powerpc/include/asm/iommu.h @@ -328,5 +328,11 @@ extern void iommu_release_ownership(struct iommu_table *tbl); extern enum dma_data_direction iommu_tce_direction(unsigned long tce); extern unsigned long iommu_direction_to_tce_perm(enum dma_data_direction dir); +#ifdef CONFIG_PPC_CELL_NATIVE +extern bool iommu_fixed_is_weak; +#else +#define iommu_fixed_is_weak false +#endif + #endif /* __KERNEL__ */ #endif /* _ASM_IOMMU_H */ diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c index c865e15ad024..7fa3636636fa 100644 --- a/arch/powerpc/kernel/dma-iommu.c +++ b/arch/powerpc/kernel/dma-iommu.c @@ -20,14 +20,15 @@ */ static inline bool dma_iommu_alloc_bypass(struct device *dev) { - return dev->archdata.iommu_bypass && + return dev->archdata.iommu_bypass && !iommu_fixed_is_weak && dma_nommu_dma_supported(dev, dev->coherent_dma_mask); } static inline bool dma_iommu_map_bypass(struct device *dev, unsigned long attrs) { - return dev->archdata.iommu_bypass; + return dev->archdata.iommu_bypass && + (!iommu_fixed_is_weak || (attrs & DMA_ATTR_WEAK_ORDERING)); } /* Allocates a contiguous real buffer and creates mappings over it. @@ -168,7 +169,7 @@ int dma_iommu_mapping_error(struct device *dev, dma_addr_t dma_addr) return dma_addr == IOMMU_MAPPING_ERROR; } -struct dma_map_ops dma_iommu_ops = { +const struct dma_map_ops dma_iommu_ops = { .alloc = dma_iommu_alloc_coherent, .free = dma_iommu_free_coherent, .mmap = dma_nommu_mmap_coherent, diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index cce5bf9515e5..fb51f78035ce 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c @@ -546,7 +546,7 @@ static unsigned long cell_dma_nommu_offset; static unsigned long dma_iommu_fixed_base; /* iommu_fixed_is_weak is set if booted with iommu_fixed=weak */ -static int iommu_fixed_is_weak; +bool iommu_fixed_is_weak; static struct iommu_table *cell_get_iommu_table(struct device *dev) { @@ -568,95 +568,6 @@ static struct iommu_table *cell_get_iommu_table(struct device *dev) return &window->table; } -/* A coherent allocation implies strong ordering */ - -static void *dma_fixed_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flag, - unsigned long attrs) -{ - if (iommu_fixed_is_weak) - return iommu_alloc_coherent(dev, cell_get_iommu_table(dev), - size, dma_handle, - device_to_mask(dev), flag, - dev_to_node(dev)); - else - return dma_nommu_ops.alloc(dev, size, dma_handle, flag, - attrs); -} - -static void dma_fixed_free_coherent(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_handle, - unsigned long attrs) -{ - if (iommu_fixed_is_weak) - iommu_free_coherent(cell_get_iommu_table(dev), size, vaddr, - dma_handle); - else - dma_nommu_ops.free(dev, size, vaddr, dma_handle, attrs); -} - -static dma_addr_t dma_fixed_map_page(struct device *dev, struct page *page, - unsigned long offset, size_t size, - enum dma_data_direction direction, - unsigned long attrs) -{ - if (iommu_fixed_is_weak == (attrs & DMA_ATTR_WEAK_ORDERING)) - return dma_nommu_ops.map_page(dev, page, offset, size, - direction, attrs); - else - return iommu_map_page(dev, cell_get_iommu_table(dev), page, - offset, size, device_to_mask(dev), - direction, attrs); -} - -static void dma_fixed_unmap_page(struct device *dev, dma_addr_t dma_addr, - size_t size, enum dma_data_direction direction, - unsigned long attrs) -{ - if (iommu_fixed_is_weak == (attrs & DMA_ATTR_WEAK_ORDERING)) - dma_nommu_ops.unmap_page(dev, dma_addr, size, direction, - attrs); - else - iommu_unmap_page(cell_get_iommu_table(dev), dma_addr, size, - direction, attrs); -} - -static int dma_fixed_map_sg(struct device *dev, struct scatterlist *sg, - int nents, enum dma_data_direction direction, - unsigned long attrs) -{ - if (iommu_fixed_is_weak == (attrs & DMA_ATTR_WEAK_ORDERING)) - return dma_nommu_ops.map_sg(dev, sg, nents, direction, attrs); - else - return ppc_iommu_map_sg(dev, cell_get_iommu_table(dev), sg, - nents, device_to_mask(dev), - direction, attrs); -} - -static void dma_fixed_unmap_sg(struct device *dev, struct scatterlist *sg, - int nents, enum dma_data_direction direction, - unsigned long attrs) -{ - if (iommu_fixed_is_weak == (attrs & DMA_ATTR_WEAK_ORDERING)) - dma_nommu_ops.unmap_sg(dev, sg, nents, direction, attrs); - else - ppc_iommu_unmap_sg(cell_get_iommu_table(dev), sg, nents, - direction, attrs); -} - -static int dma_suported_and_switch(struct device *dev, u64 dma_mask); - -static const struct dma_map_ops dma_iommu_fixed_ops = { - .alloc = dma_fixed_alloc_coherent, - .free = dma_fixed_free_coherent, - .map_sg = dma_fixed_map_sg, - .unmap_sg = dma_fixed_unmap_sg, - .dma_supported = dma_suported_and_switch, - .map_page = dma_fixed_map_page, - .unmap_page = dma_fixed_unmap_page, - .mapping_error = dma_iommu_mapping_error, -}; - static u64 cell_iommu_get_fixed_address(struct device *dev); static void cell_dma_dev_setup(struct device *dev) @@ -953,22 +864,10 @@ static u64 cell_iommu_get_fixed_address(struct device *dev) return dev_addr; } -static int dma_suported_and_switch(struct device *dev, u64 dma_mask) +static bool cell_pci_iommu_bypass_supported(struct pci_dev *pdev, u64 mask) { - if (dma_mask == DMA_BIT_MASK(64) && - cell_iommu_get_fixed_address(dev) != OF_BAD_ADDR) { - dev_dbg(dev, "iommu: 64-bit OK, using fixed ops\n"); - set_dma_ops(dev, &dma_iommu_fixed_ops); - return 1; - } - - if (dma_iommu_dma_supported(dev, dma_mask)) { - dev_dbg(dev, "iommu: not 64-bit, using default ops\n"); - set_dma_ops(dev, &dma_iommu_ops); - return 1; - } - - return 0; + return mask == DMA_BIT_MASK(64) && + cell_iommu_get_fixed_address(&pdev->dev) != OF_BAD_ADDR; } static void insert_16M_pte(unsigned long addr, unsigned long *ptab, @@ -1122,9 +1021,6 @@ static int __init cell_iommu_fixed_mapping_init(void) cell_iommu_setup_window(iommu, np, dbase, dsize, 0); } - dma_iommu_ops.dma_supported = dma_suported_and_switch; - set_pci_dma_ops(&dma_iommu_ops); - return 0; } @@ -1145,7 +1041,7 @@ static int __init setup_iommu_fixed(char *str) pciep = of_find_node_by_type(NULL, "pcie-endpoint"); if (strcmp(str, "weak") == 0 || (pciep && strcmp(str, "strong") != 0)) - iommu_fixed_is_weak = DMA_ATTR_WEAK_ORDERING; + iommu_fixed_is_weak = true; of_node_put(pciep); @@ -1153,26 +1049,6 @@ static int __init setup_iommu_fixed(char *str) } __setup("iommu_fixed=", setup_iommu_fixed); -static u64 cell_dma_get_required_mask(struct device *dev) -{ - const struct dma_map_ops *dma_ops; - - if (!dev->dma_mask) - return 0; - - if (!iommu_fixed_disabled && - cell_iommu_get_fixed_address(dev) != OF_BAD_ADDR) - return DMA_BIT_MASK(64); - - dma_ops = get_dma_ops(dev); - if (dma_ops->get_required_mask) - return dma_ops->get_required_mask(dev); - - WARN_ONCE(1, "no get_required_mask in %p ops", dma_ops); - - return DMA_BIT_MASK(64); -} - static int __init cell_iommu_init(void) { struct device_node *np; @@ -1189,10 +1065,9 @@ static int __init cell_iommu_init(void) /* Setup various callbacks */ cell_pci_controller_ops.dma_dev_setup = cell_pci_dma_dev_setup; - ppc_md.dma_get_required_mask = cell_dma_get_required_mask; if (!iommu_fixed_disabled && cell_iommu_fixed_mapping_init() == 0) - goto bail; + goto done; /* Create an iommu for each /axon node. */ for_each_node_by_name(np, "axon") { @@ -1209,8 +1084,12 @@ static int __init cell_iommu_init(void) continue; cell_iommu_init_one(np, SPIDER_DMA_OFFSET); } - + done: /* Setup default PCI iommu ops */ + if (!iommu_fixed_disabled) { + cell_pci_controller_ops.iommu_bypass_supported = + cell_pci_iommu_bypass_supported; + } set_pci_dma_ops(&dma_iommu_ops); bail: -- 2.19.0