Re: [dm-devel] AMD-Vi IO_PAGE_FAULTs and ata3.00: failed command: READ FPDMA QUEUED errors since Linux 4.0
On Sun, Aug 02, 2015 at 08:48:06PM +0200, Andreas Hartmann wrote: > >>https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=34b48db66e08ca1c1bc07cf305d672ac940268dc > >> > >>block: remove artifical max_hw_sectors cap Looking at the patch, it seems to me that it just uncovered a bug elsewhere. It looks like an underlying driver doesn't expect the big io-requests that the patch enables and does not dma-map the whole target buffer, causing the IO_PAGE_FAULTs later. Joerg ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v4 0/6] MT8173 IOMMU SUPPORT
This patch set adds support for m4u(Multimedia Memory Management Unit), Currently it only support the m4u with 2 levels of pagetable on mt8173. It's based on Robin Murphy's arm64 DMA-v5[1] and Robin's allow DMA API use in io-pgtable-arm[2]. The dsti is based on MTK clock patch[3]. Please check the hardware block diagram of Mediatek IOMMU. EMI (External Memory Interface) | m4u (Multimedia Memory Management Unit) | smi (Smart Multimedia Interface) | +---+--- | | | | vdec larb disp larb ... SoCs have different local arbiter(larb). | | | | ++++-+-+ |||| | |... |||| | |... |||| | |... MC PP VLD OVL0 RDMA0 WDMA0 ... There are different ports in each larb. Normally we specify a local arbiter(larb) for each multimedia hardware like display, video decode, video encode and camera. And there are different ports in each larb. Take a example, there are some ports like MC, PP, UFO, VLD, AVC_MV, PRED_RD in video larb, all the ports are according to the video hardware. From the diagram, all the multimedia module connect with m4u via smi. SMI is responsible to enable/disable iommu and control the clocks for each local arbiter. If we should enable the iommu of video decode, it should config the video's ports. And if the video hardware work whether enable/disable iommu, it should enable the clock of its larb's clock. And smi also help bandwidth control for each local. So we add a special driver for smi and locate it drivers/memory. v4: -use only one iommu domain here based on the Robin's DMA-v5. -remove flush_pgtable. -change writel to writel_relaxed. -about Short-descriptor: move dma_map_single into io-pgtable-arm-short. Improve the flow of free pgtable and add NO_XN+NO_PERMS quirk following Will's suggestion. -Change two sytle issues in dtsi according to Daniel's suggestion. v3: http://lists.linuxfoundation.org/pipermail/iommu/2015-July/013632.html -rebased onto v4.2-rc1 -improve iommu flow based on the Robin's DMA v3[4]. -change mtk iommu-cells from 1 to 2. -about Short-descriptor: add split function; add self-test; add some other bits like nG, XN according to the spec; add SUPERSECTION and MTK quirk; move io_pgtable_ops_to_pgtable out from LPAE to the header file. -about SMI: move from driver/soc/mediatek to driver/memory; change the clocks from clk[2] to clk_apb and clk_smi; add pm. -add iommu suspend/resume to backup/restore register. v2: http://lists.linuxfoundation.org/pipermail/iommu/2015-May/013028.html -add arm short descriptor support. -seperate smi common from smi and change the clock-names according to smi HW. -delete the hardcode of the port-names in mt8173. replace this with larb-portes-nr in dtsi. -fix some coding style issues. v1: http://lists.infradead.org/pipermail/linux-mediatek/2015-March/58.html -initial version. [1]: http://lists.linuxfoundation.org/pipermail/iommu/2015-July/013900.html [2]: http://lists.linuxfoundation.org/pipermail/iommu/2015-July/013876.html [3]: http://lists.infradead.org/pipermail/linux-mediatek/2015-July/001800.html [4]: http://lists.linuxfoundation.org/pipermail/iommu/2015-July/013597.html Yong Wu (6): dt-bindings: iommu: Add binding for mediatek IOMMU dt-bindings: mediatek: Add smi dts binding iommu: add ARM short descriptor page table allocator. memory: mediatek: Add SMI driver iommu/mediatek: Add mt8173 IOMMU driver dts: mt8173: Add iommu/smi nodes for mt8173 .../devicetree/bindings/iommu/mediatek,iommu.txt | 61 ++ .../memory-controllers/mediatek,smi-larb.txt | 25 + .../bindings/memory-controllers/mediatek,smi.txt | 24 + arch/arm64/boot/dts/mediatek/mt8173.dtsi | 81 ++ drivers/iommu/Kconfig | 31 + drivers/iommu/Makefile | 2 + drivers/iommu/io-pgtable-arm-short.c | 811 + drivers/iommu/io-pgtable-arm.c | 3 - drivers/iommu/io-pgtable.c | 4 + drivers/iommu/io-pgtable.h | 14 + drivers/iommu/mtk_iommu.c | 714 ++ drivers/memory/Kconfig | 8 + drivers/memory/Makefile| 1 + drivers/memory/mtk-smi.c | 285 include/dt-bindings/memory/mt8173-larb-port.h | 105 +++ include/soc/mediatek/smi.h | 60 ++ 16 files changed, 2226 insertions(+), 3 deletions(-) create mode 100644 Documentation/devicetree/bindings/iommu/mediatek,iommu.txt create mode 100644 Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt create mode 100644 Documentat
[PATCH v4 5/6] iommu/mediatek: Add mt8173 IOMMU driver
This patch adds support for mediatek m4u (MultiMedia Memory Management Unit). Signed-off-by: Yong Wu --- drivers/iommu/Kconfig | 13 + drivers/iommu/Makefile| 1 + drivers/iommu/mtk_iommu.c | 714 ++ 3 files changed, 728 insertions(+) create mode 100644 drivers/iommu/mtk_iommu.c diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index 3abd066..f0ae553e 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -386,4 +386,17 @@ config ARM_SMMU_V3 Say Y here if your system includes an IOMMU device implementing the ARM SMMUv3 architecture. +config MTK_IOMMU + bool "MTK IOMMU Support" + depends on ARCH_MEDIATEK || COMPILE_TEST + select IOMMU_API + select IOMMU_DMA + select IOMMU_IO_PGTABLE_SHORT + select MEMORY + select MTK_SMI + help + Support for the IOMMUs on certain Mediatek SOCs. + + If unsure, say N here. + endif # IOMMU_SUPPORT diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 06df3e6..f4f2f2c 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -21,6 +21,7 @@ obj-$(CONFIG_ROCKCHIP_IOMMU) += rockchip-iommu.o obj-$(CONFIG_TEGRA_IOMMU_GART) += tegra-gart.o obj-$(CONFIG_TEGRA_IOMMU_SMMU) += tegra-smmu.o obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o +obj-$(CONFIG_MTK_IOMMU) += mtk_iommu.o obj-$(CONFIG_SHMOBILE_IOMMU) += shmobile-iommu.o obj-$(CONFIG_SHMOBILE_IPMMU) += shmobile-ipmmu.o obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o fsl_pamu_domain.o diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c new file mode 100644 index 000..3c4f1b5 --- /dev/null +++ b/drivers/iommu/mtk_iommu.c @@ -0,0 +1,714 @@ +/* + * Copyright (c) 2014-2015 MediaTek Inc. + * Author: Yong Wu + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "io-pgtable.h" + +#define REG_MMU_PT_BASE_ADDR 0x000 + +#define REG_MMU_INVALIDATE 0x020 +#define F_ALL_INVLD0x2 +#define F_MMU_INV_RANGE0x1 + +#define REG_MMU_INVLD_START_A 0x024 +#define REG_MMU_INVLD_END_A0x028 + +#define REG_MMU_INV_SEL0x038 +#define F_INVLD_EN0BIT(0) +#define F_INVLD_EN1BIT(1) + +#define REG_MMU_STANDARD_AXI_MODE 0x048 +#define REG_MMU_DCM_DIS0x050 + +#define REG_MMU_CTRL_REG 0x110 +#define F_MMU_PREFETCH_RT_REPLACE_MOD BIT(4) +#define F_MMU_TF_PROTECT_SEL(prot) (((prot) & 0x3) << 5) +#define F_COHERENCE_EN BIT(8) + +#define REG_MMU_IVRP_PADDR 0x114 +#define F_MMU_IVRP_PA_SET(pa) ((pa) >> 1) + +#define REG_MMU_INT_CONTROL0 0x120 +#define F_L2_MULIT_HIT_EN BIT(0) +#define F_TABLE_WALK_FAULT_INT_EN BIT(1) +#define F_PREETCH_FIFO_OVERFLOW_INT_EN BIT(2) +#define F_MISS_FIFO_OVERFLOW_INT_ENBIT(3) +#define F_PREFETCH_FIFO_ERR_INT_EN BIT(5) +#define F_MISS_FIFO_ERR_INT_EN BIT(6) +#define F_INT_L2_CLR_BIT BIT(12) + +#define REG_MMU_INT_MAIN_CONTROL 0x124 +#define F_INT_TRANSLATION_FAULTBIT(0) +#define F_INT_MAIN_MULTI_HIT_FAULT BIT(1) +#define F_INT_INVALID_PA_FAULT BIT(2) +#define F_INT_ENTRY_REPLACEMENT_FAULT BIT(3) +#define F_INT_TLB_MISS_FAULT BIT(4) +#define F_INT_MISS_TRANSATION_FIFO_FAULT BIT(5) +#define F_INT_PRETETCH_TRANSATION_FIFO_FAULT BIT(6) + +#define REG_MMU_CPE_DONE 0x12C + +#define REG_MMU_FAULT_ST1 0x134 + +#define REG_MMU_FAULT_VA 0x13c +#define F_MMU_FAULT_VA_MSK 0xf000 +#define F_MMU_FAULT_VA_WRITE_BIT BIT(1) +#define F_MMU_FAULT_VA_LAYER_BIT BIT(0) + +#define REG_MMU_INVLD_PA 0x140 +#define REG_MMU_INT_ID 0x150 +#define F_MMU0_INT_ID_LARB_ID(a) (((a) >> 7) & 0x7) +#define F_MMU0_INT_ID_PORT_ID(a) (((a) >> 2) & 0x1f) + +#define MTK_PROTECT_PA_ALIGN 128 +#define MTK_IOMMU_LARB_MAX_NR
[PATCH v4 4/6] memory: mediatek: Add SMI driver
This patch add SMI(Smart Multimedia Interface) driver. This driver is responsible to enable/disable iommu and control the clocks of each local arbiter Signed-off-by: Yong Wu --- drivers/memory/Kconfig | 8 ++ drivers/memory/Makefile| 1 + drivers/memory/mtk-smi.c | 285 + include/soc/mediatek/smi.h | 60 ++ 4 files changed, 354 insertions(+) create mode 100644 drivers/memory/mtk-smi.c create mode 100644 include/soc/mediatek/smi.h diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig index 8406c668..c0e1607 100644 --- a/drivers/memory/Kconfig +++ b/drivers/memory/Kconfig @@ -100,6 +100,14 @@ config JZ4780_NEMC the Ingenic JZ4780. This controller is used to handle external memory devices such as NAND and SRAM. +config MTK_SMI + bool + depends on ARCH_MEDIATEK || COMPILE_TEST + help + This driver is for the Memory Controller module in MediaTek SoCs, + mainly help enable/disable iommu and control the clock for each + local arbiter. + source "drivers/memory/tegra/Kconfig" endif diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile index b670441..f854e40 100644 --- a/drivers/memory/Makefile +++ b/drivers/memory/Makefile @@ -14,5 +14,6 @@ obj-$(CONFIG_FSL_IFC) += fsl_ifc.o obj-$(CONFIG_MVEBU_DEVBUS) += mvebu-devbus.o obj-$(CONFIG_TEGRA20_MC) += tegra20-mc.o obj-$(CONFIG_JZ4780_NEMC) += jz4780-nemc.o +obj-$(CONFIG_MTK_SMI) += mtk-smi.o obj-$(CONFIG_TEGRA_MC) += tegra/ diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c new file mode 100644 index 000..e62cceb --- /dev/null +++ b/drivers/memory/mtk-smi.c @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2014-2015 MediaTek Inc. + * Author: Yong Wu + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SMI_LARB_MMU_EN0xf00 +#define F_SMI_MMU_EN(port) BIT(port) + +struct mtk_smi_common { + struct clk *clk_apb; + struct clk *clk_smi; +}; + +struct mtk_smi_larb { + void __iomem*base; + struct clk *clk_apb; + struct clk *clk_smi; + struct device *smi; +}; + +struct mtk_larb_mmu { + u32 mmu; +}; + +static int mtk_smi_common_get(struct device *smidev) +{ + struct mtk_smi_common *smipriv = dev_get_drvdata(smidev); + int ret; + + ret = pm_runtime_get_sync(smidev); + if (ret < 0) + return ret; + + ret = clk_prepare_enable(smipriv->clk_apb); + if (ret) { + dev_err(smidev, "Failed to enable the apb clock\n"); + goto err_put_pm; + } + ret = clk_prepare_enable(smipriv->clk_smi); + if (ret) { + dev_err(smidev, "Failed to enable the smi clock\n"); + goto err_disable_apb; + } + return ret; + +err_disable_apb: + clk_disable_unprepare(smipriv->clk_apb); +err_put_pm: + pm_runtime_put(smidev); + return ret; +} + +static void mtk_smi_common_put(struct device *smidev) +{ + struct mtk_smi_common *smipriv = dev_get_drvdata(smidev); + + clk_disable_unprepare(smipriv->clk_smi); + clk_disable_unprepare(smipriv->clk_apb); + pm_runtime_put(smidev); +} + +int mtk_smi_larb_get(struct device *larbdev) +{ + struct mtk_smi_larb *larbpriv = dev_get_drvdata(larbdev); + struct mtk_larb_mmu *mmucfg = larbdev->archdata.iommu; + int ret; + + ret = mtk_smi_common_get(larbpriv->smi); + if (ret) + return ret; + + ret = pm_runtime_get_sync(larbdev); + if (ret < 0) + goto err_put_smicommon; + + ret = clk_prepare_enable(larbpriv->clk_apb); + if (ret) { + dev_err(larbdev, "Failed to enable the apb clock\n"); + goto err_put_pm; + } + + ret = clk_prepare_enable(larbpriv->clk_smi); + if (ret) { + dev_err(larbdev, "Failed to enable the smi clock\n"); + goto err_disable_apb; + } + + /* config iommu */ + writel_relaxed(mmucfg->mmu, larbpriv->base + SMI_LARB_MMU_EN); + + return ret; + +err_disable_apb: + clk_disable_unprepare(larbpriv->clk_apb); +err_put_pm: + pm_runtime_put(larbdev); +err_put_smicommon: + mtk_smi_common_put(larbpriv->smi); + return ret; +} + +void mtk_smi_larb
[PATCH v4 2/6] dt-bindings: mediatek: Add smi dts binding
This patch add smi binding document. Signed-off-by: Yong Wu --- .../memory-controllers/mediatek,smi-larb.txt | 25 ++ .../bindings/memory-controllers/mediatek,smi.txt | 24 + 2 files changed, 49 insertions(+) create mode 100644 Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt create mode 100644 Documentation/devicetree/bindings/memory-controllers/mediatek,smi.txt diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt new file mode 100644 index 000..55ff3b7 --- /dev/null +++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt @@ -0,0 +1,25 @@ +SMI (Smart Multimedia Interface) Local Arbiter + +The hardware block diagram please check bindings/iommu/mediatek,iommu.txt + +Required properties: +- compatible : must be "mediatek,mt8173-smi-larb" +- reg : the register and size of this local arbiter. +- mediatek,smi : a phandle to the smi_common node. +- power-domains : a phandle to the power domain of this local arbiter. +- clocks : Must contain an entry for each entry in clock-names. +- clock-names: must contain 2 entries, as follows: + - "apb" : Advanced Peripheral Bus clock, It's the clock for setting + the register. + - "smi" : It's the clock for transfer data and command. + +Example: + larb1: larb@1601 { + compatible = "mediatek,mt8173-smi-larb"; + reg = <0 0x1601 0 0x1000>; + mediatek,smi = <&smi_common>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_VDEC>; + clocks = <&vdecsys CLK_VDEC_CKEN>, +<&vdecsys CLK_VDEC_LARB_CKEN>; + clock-names = "apb", "smi"; + }; diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi.txt b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi.txt new file mode 100644 index 000..f54e91c --- /dev/null +++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi.txt @@ -0,0 +1,24 @@ +SMI (Smart Multimedia Interface) + +The hardware block diagram please check bindings/iommu/mediatek,iommu.txt + +Required properties: +- compatible : must be "mediatek,mt8173-smi" +- reg : the register and size of the SMI block. +- power-domains : a phandle to the power domain of this local arbiter. +- clocks : Must contain an entry for each entry in clock-names. +- clock-names : must contain 2 entries, as follows: + - "apb" : Advanced Peripheral Bus clock, It's the clock for setting + the register. + - "smi" : It's the clock for transfer data and command. + They may be the same if both source clock are the same. + +Example: + smi_common: smi@14022000 { + compatible = "mediatek,mt8173-smi"; + reg = <0 0x14022000 0 0x1000>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + clocks = <&mmsys CLK_MM_SMI_COMMON>, +<&mmsys CLK_MM_SMI_COMMON>; + clock-names = "apb", "smi"; + }; -- 1.8.1.1.dirty ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v4 1/6] dt-bindings: iommu: Add binding for mediatek IOMMU
This patch add mediatek iommu dts binding document. Signed-off-by: Yong Wu --- .../devicetree/bindings/iommu/mediatek,iommu.txt | 61 include/dt-bindings/memory/mt8173-larb-port.h | 105 + 2 files changed, 166 insertions(+) create mode 100644 Documentation/devicetree/bindings/iommu/mediatek,iommu.txt create mode 100644 include/dt-bindings/memory/mt8173-larb-port.h diff --git a/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt b/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt new file mode 100644 index 000..691739a --- /dev/null +++ b/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt @@ -0,0 +1,61 @@ +* Mediatek IOMMU Architecture Implementation + + Mediatek Socs may contain a implementation of Multimedia Memory +Management Unit(M4U),which use ARM Short-descriptor translation table +to achieve address translation. + + The IOMMU Hardware Block Diagram, please check below: + + EMI (External Memory Interface) + | + m4u (Multimedia Memory Management Unit) + | + smi (Smart Multimedia Interface) + | ++---+--- +| | +| | +vdec larb disp larb ... SoCs have different local arbiter(larb). +| | +| | + ++++-+-+ + |||| | |... + |||| | |... + |||| | |... + MC PP VLD OVL0 RDMA0 WDMA0 ... There are different ports in each larb. + + As above, The Multimedia HW will go through SMI and M4U while it +access EMI. SMI is a brige between m4u and the Multimedia HW. It contain +smi local arbiter and smi common. It will control whether the Multimedia +HW should go though the m4u for translation or bypass it and talk +directly with EMI. And also SMI help control the clocks for each +local arbiter. + Normally we specify a local arbiter(larb) for each multimedia HW +like display, video decode, and camera. And there are different ports +in each larb. Take a example, There are some ports like MC, PP, VLD in the +video decode local arbiter, all the ports are according to the video HW. + +Required properties: +- compatible : must be "mediatek,mt8173-m4u". +- reg : m4u register base and size. +- interrupts : the interrupt of m4u. +- clocks : must contain one entry for each clock-names. +- clock-names : must be "bclk", It is the block clock of m4u. +- mediatek,larb : List of phandle to the local arbiters in the current Socs. + Refer to bindings/memory-controllers/mediatek,smi-larb.txt. It must sort + according to the local arbiter index, like larb0, larb1, larb2... +- iommu-cells : must be 2. There are 2 cells needed to enable/disable iommu. + The first one is local arbiter index(larbid), and the other is port + index(portid) within local arbiter. Specifies the larbid and portid as + defined in dt-binding/memory/mt8173-larb-port.h. + +Example: + iommu: mmsys_iommu@10205000 { + compatible = "mediatek,mt8173-m4u"; + reg = <0 0x10205000 0 0x1000>; + interrupts = ; + clocks = <&infracfg CLK_INFRA_M4U>; + clock-names = "bclk"; + mediatek,larb = <&larb0 &larb1 &larb2 &larb3 &larb4 &larb5>; + #iommu-cells = <2>; + }; diff --git a/include/dt-bindings/memory/mt8173-larb-port.h b/include/dt-bindings/memory/mt8173-larb-port.h new file mode 100644 index 000..7517087 --- /dev/null +++ b/include/dt-bindings/memory/mt8173-larb-port.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2014-2015 MediaTek Inc. + * Author: Yong Wu + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __DTS_IOMMU_PORT_MT8173_H +#define __DTS_IOMMU_PORT_MT8173_H + +#define M4U_LARB0_ID 0 +#define M4U_LARB1_ID 1 +#define M4U_LARB2_ID 2 +#define M4U_LARB3_ID 3 +#define M4U_LARB4_ID 4 +#define M4U_LARB5_ID 5 + +/* larb0 */ +#defineM4U_PORT_DISP_OVL0 0 +#defineM4U_PORT_DISP_RDMA0 1 +#defineM4U_PORT_DISP_WDMA0 2 +#defineM4U_PORT_DISP_OD_R 3 +#defineM4U_PORT_DISP_OD_W 4 +#defineM4U_PORT_MDP_RDMA0 5 +#defineM4U_PORT_MDP_WDMA 6 +#defineM4U_PORT_MDP_WROT0 7 + +/* larb1 */ +#defineM4U_PO
[PATCH v4 3/6] iommu: add ARM short descriptor page table allocator.
This patch is for ARM Short Descriptor Format. Signed-off-by: Yong Wu --- drivers/iommu/Kconfig| 18 + drivers/iommu/Makefile | 1 + drivers/iommu/io-pgtable-arm-short.c | 813 +++ drivers/iommu/io-pgtable-arm.c | 3 - drivers/iommu/io-pgtable.c | 4 + drivers/iommu/io-pgtable.h | 14 + 6 files changed, 850 insertions(+), 3 deletions(-) create mode 100644 drivers/iommu/io-pgtable-arm-short.c diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index f1fb1d3..3abd066 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -39,6 +39,24 @@ config IOMMU_IO_PGTABLE_LPAE_SELFTEST If unsure, say N here. +config IOMMU_IO_PGTABLE_SHORT + bool "ARMv7/v8 Short Descriptor Format" + select IOMMU_IO_PGTABLE + depends on ARM || ARM64 || COMPILE_TEST + help + Enable support for the ARM Short-descriptor pagetable format. + This allocator supports 2 levels translation tables which supports + a memory map based on memory sections or pages. + +config IOMMU_IO_PGTABLE_SHORT_SELFTEST + bool "Short Descriptor selftests" + depends on IOMMU_IO_PGTABLE_SHORT + help + Enable self-tests for Short-descriptor page table allocator. + This performs a series of page-table consistency checks during boot. + + If unsure, say N here. + endmenu config IOMMU_IOVA diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index c6dcc51..06df3e6 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -3,6 +3,7 @@ obj-$(CONFIG_IOMMU_API) += iommu-traces.o obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o obj-$(CONFIG_IOMMU_IO_PGTABLE_LPAE) += io-pgtable-arm.o +obj-$(CONFIG_IOMMU_IO_PGTABLE_SHORT) += io-pgtable-arm-short.o obj-$(CONFIG_IOMMU_IOVA) += iova.o obj-$(CONFIG_OF_IOMMU) += of_iommu.o obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o msm_iommu_dev.o diff --git a/drivers/iommu/io-pgtable-arm-short.c b/drivers/iommu/io-pgtable-arm-short.c new file mode 100644 index 000..56f5480 --- /dev/null +++ b/drivers/iommu/io-pgtable-arm-short.c @@ -0,0 +1,813 @@ +/* + * Copyright (c) 2014-2015 MediaTek Inc. + * Author: Yong Wu + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#define pr_fmt(fmt)"arm-short-desc io-pgtable: "fmt + +#include +#include +#include +#include +#include "io-pgtable.h" + +typedef u32 arm_short_iopte; + +struct arm_short_io_pgtable { + struct io_pgtable iop; + struct kmem_cache *pgtable_cached; + size_t pgd_size; + void*pgd; +}; + +#define io_pgtable_to_data(x) \ + container_of((x), struct arm_short_io_pgtable, iop) + +#define io_pgtable_ops_to_data(x) \ + io_pgtable_to_data(io_pgtable_ops_to_pgtable(x)) + +#define io_pgtable_cfg_to_pgtable(x) \ + container_of((x), struct io_pgtable, cfg) + +#define io_pgtable_cfg_to_data(x) \ + io_pgtable_to_data(io_pgtable_cfg_to_pgtable(x)) + +#define ARM_SHORT_PGDIR_SHIFT 20 +#define ARM_SHORT_PAGE_SHIFT 12 +#define ARM_SHORT_PTRS_PER_PTE \ + (1 << (ARM_SHORT_PGDIR_SHIFT - ARM_SHORT_PAGE_SHIFT)) +#define ARM_SHORT_BYTES_PER_PTE\ + (ARM_SHORT_PTRS_PER_PTE * sizeof(arm_short_iopte)) + +/* level 1 pagetable */ +#define ARM_SHORT_PGD_TYPE_PGTABLE BIT(0) +#define ARM_SHORT_PGD_TYPE_SECTION BIT(1) +#define ARM_SHORT_PGD_BBIT(2) +#define ARM_SHORT_PGD_CBIT(3) +#define ARM_SHORT_PGD_PGTABLE_NS BIT(3) +#define ARM_SHORT_PGD_SECTION_XN BIT(4) +#define ARM_SHORT_PGD_IMPLEBIT(9) +#define ARM_SHORT_PGD_RD_WR(3 << 10) +#define ARM_SHORT_PGD_RDONLY BIT(15) +#define ARM_SHORT_PGD_SBIT(16) +#define ARM_SHORT_PGD_nG BIT(17) +#define ARM_SHORT_PGD_SUPERSECTION BIT(18) +#define ARM_SHORT_PGD_SECTION_NS BIT(19) + +#define ARM_SHORT_PGD_TYPE_SUPERSECTION\ + (ARM_SHORT_PGD_TYPE_SECTION | ARM_SHORT_PGD_SUPERSECTION) +#define ARM_SHORT_PGD_SECTION_TYPE_MSK \ + (ARM_SHORT_PGD_TYPE_SECTION | ARM_SHORT_PGD_SUPERSECTION) +#define ARM_SHORT_PGD_PGTABLE_TYPE_MSK \ + (ARM_SHORT_PGD_TYPE_SECTION | ARM_SHORT_PGD_TYPE_P
[PATCH v4 6/6] dts: mt8173: Add iommu/smi nodes for mt8173
This patch add the iommu/larbs nodes for mt8173 Signed-off-by: Yong Wu --- arch/arm64/boot/dts/mediatek/mt8173.dtsi | 81 1 file changed, 81 insertions(+) diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi index 6c3f047..a92956d 100644 --- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include "mt8173-pinfunc.h" @@ -265,6 +266,17 @@ reg = <0 0x10200620 0 0x20>; }; + iommu: iommu@10205000 { + compatible = "mediatek,mt8173-m4u"; + reg = <0 0x10205000 0 0x1000>; + interrupts = ; + clocks = <&infracfg CLK_INFRA_M4U>; + clock-names = "bclk"; + mediatek,larb = <&larb0 &larb1 &larb2 +&larb3 &larb4 &larb5>; + #iommu-cells = <2>; + }; + apmixedsys: clock-controller@10209000 { compatible = "mediatek,mt8173-apmixedsys"; reg = <0 0x10209000 0 0x1000>; @@ -501,29 +513,98 @@ #clock-cells = <1>; }; + larb0: larb@14021000 { + compatible = "mediatek,mt8173-smi-larb"; + reg = <0 0x14021000 0 0x1000>; + mediatek,smi = <&smi_common>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + clocks = <&mmsys CLK_MM_SMI_LARB0>, +<&mmsys CLK_MM_SMI_LARB0>; + clock-names = "apb", "smi"; + }; + + smi_common: smi@14022000 { + compatible = "mediatek,mt8173-smi"; + reg = <0 0x14022000 0 0x1000>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + clocks = <&mmsys CLK_MM_SMI_COMMON>, +<&mmsys CLK_MM_SMI_COMMON>; + clock-names = "apb", "smi"; + }; + + larb4: larb@14027000 { + compatible = "mediatek,mt8173-smi-larb"; + reg = <0 0x14027000 0 0x1000>; + mediatek,smi = <&smi_common>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + clocks = <&mmsys CLK_MM_SMI_LARB4>, +<&mmsys CLK_MM_SMI_LARB4>; + clock-names = "apb", "smi"; + }; + imgsys: clock-controller@1500 { compatible = "mediatek,mt8173-imgsys", "syscon"; reg = <0 0x1500 0 0x1000>; #clock-cells = <1>; }; + larb2: larb@15001000 { + compatible = "mediatek,mt8173-smi-larb"; + reg = <0 0x15001000 0 0x1000>; + mediatek,smi = <&smi_common>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_ISP>; + clocks = <&imgsys CLK_IMG_LARB2_SMI>, +<&imgsys CLK_IMG_LARB2_SMI>; + clock-names = "apb", "smi"; + }; + vdecsys: clock-controller@1600 { compatible = "mediatek,mt8173-vdecsys", "syscon"; reg = <0 0x1600 0 0x1000>; #clock-cells = <1>; }; + larb1: larb@1601 { + compatible = "mediatek,mt8173-smi-larb"; + reg = <0 0x1601 0 0x1000>; + mediatek,smi = <&smi_common>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_VDEC>; + clocks = <&vdecsys CLK_VDEC_CKEN>, +<&vdecsys CLK_VDEC_LARB_CKEN>; + clock-names = "apb", "smi"; + }; + vencsys: clock-controller@1800 { compatible = "mediatek,mt8173-vencsys", "syscon"; reg = <0 0x1800 0 0x1000>; #clock-cells = <1>; }; + larb3: larb@18001000 { + compatible = "mediatek,mt8173-smi-larb"; + reg = <0 0x18001000 0 0x1000>; + mediatek,smi = <&smi_common>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_VENC>; + clocks = <&vencsys CLK_VENC_CKE1>, +<&vencsys CLK_VENC_CKE0>; + clock-names = "apb", "smi"; + }; + vencltsys: clock-controller@1
Re: [PATCH 1/3] Docs: dt: add generic MSI bindings
On 27/07/15 10:46, Mark Rutland wrote: > On Mon, Jul 27, 2015 at 09:02:46AM +0100, Marc Zyngier wrote: >> Hi Mark, > > Hi, > >> On 23/07/15 17:52, Mark Rutland wrote: >>> Currently msi-parent is used in a couple of drivers despite being fairly >>> underspecified. This patch adds a generic binding for MSIs (including >>> the existing msi-parent property) enabling the description of platform >>> devices capable of using MSIs. >>> >>> While MSIs are primarily distinguished by doorbell and payload, some MSI >>> controllers (e.g. the GICv3 ITS) also use side-band information >>> accompanying the write to identify the master which originated the MSI, >>> to allow for sandboxing. This sideband information is non-probeable and >>> needs to be described in the DT. Other MSI controllers may have >>> additional configuration details which need to be described per-master. >>> >>> This patch adds a generic msi-parent binding document, extending the >>> de-facto standard with a new (optional) #msi-cells which can be used to >>> express any per-master configuration and/or sideband data. This is >>> sufficient to describe non-hotpluggable devices. >>> >>> For busses where sideband data may be derived from some bus-specific >>> master ID scheme, other properties will be required to describe the >>> mapping. >>> >>> Signed-off-by: Mark Rutland >>> --- >>> .../bindings/interrupt-controller/msi.txt | 135 >>> + >>> 1 file changed, 135 insertions(+) >>> create mode 100644 >>> Documentation/devicetree/bindings/interrupt-controller/msi.txt >>> >>> diff --git a/Documentation/devicetree/bindings/interrupt-controller/msi.txt >>> b/Documentation/devicetree/bindings/interrupt-controller/msi.txt >>> new file mode 100644 >>> index 000..c60c034 >>> --- /dev/null >>> +++ b/Documentation/devicetree/bindings/interrupt-controller/msi.txt >>> @@ -0,0 +1,135 @@ >>> +This document describes the generic device tree binding for MSI >>> controllers and >>> +their master(s). >>> + >>> +Message Signaled Interrupts (MSIs) are a class of interrupts generated by a >>> +write to an MMIO address. >>> + >>> +MSIs were originally specified by PCI (and are used with PCIe), but may >>> also be >>> +used with other busses, and hence a mechanism is required to relate >>> devices on >>> +those busses to the MSI controllers which they are capable of using, >>> +potentially including additional information. >>> + >>> +MSIs are distinguished by some combination of: >>> + >>> +- The doorbell (the MMIO address written to). >>> + >>> + Devices may be configured by software to write to arbitrary doorbells >>> which >>> + they can address. An MSI controller may feature a number of doorbells. >>> + >>> +- The payload (the value written to the doorbell). >>> + >>> + Devices may be configured to write an arbitrary payload chosen by >>> software. >>> + MSI controllers may have restrictions on permitted payloads. >>> + >>> +- Sideband information accompanying the write. >>> + >>> + Typically this is neither configurable nor probeable, and depends on the >>> path >>> + taken through the memory system (i.e. it is a property of the >>> combination of >>> + MSI controller and device rather than a property of either in isolation). >>> + >>> + >>> +MSI controllers: >>> + >>> + >>> +An MSI controller signals interrupts to a CPU when a write is made to an >>> MMIO >>> +address by some master. An MSI controller may feature a number of >>> doorbells. >>> + >>> +Required properties: >>> + >>> + >>> +- msi-controller: Identifies the node as an MSI controller. >>> + >>> +Optional properties: >>> + >>> + >>> +- #msi-cells: The number of cells in an msi-specifier, required if not >>> zero. >>> + >>> + Typically this will encode information related to sideband data, and will >>> + not encode doorbells or payloads as these can be configured dynamically. >>> + >>> + The meaning of the msi-specifier is defined by the device tree binding of >>> + the specific MSI controller. >>> + >>> + >>> +MSI clients >>> +=== >>> + >>> +MSI clients are devices which generate MSIs. For each MSI they wish to >>> +generate, the doorbell and payload may be configured, though sideband >>> +information may not be configurable. >>> + >>> +Required properties: >>> + >>> + >>> +- msi-parent: A list of phandle + msi-specifier pairs, one for each MSI >>> + controller which the device is capable of using. >>> + >>> + This property is unordered, and MSIs may be allocated from any >>> combination of >>> + MSI controllers listed in the msi-parent property. >>> + >>> + If a device has restrictions on the allocation of MSIs, these >>> restrictions >>> + must be described with additional properties. >>> + >>> + When #msi-cells is non-zero, busses with an msi-parent will require >>> + additional properties to describe the relationship between devices on >>> the bus
Re: [PATCH 00/18] Clean up exposure of arch-internal code
Hey Thierry, On Mon, Jul 27, 2015 at 04:09:06PM +0200, Thierry Reding wrote: > What's the plan for merging this? Should it all go in through Joerg's > tree so that potentially other driver conversions can go in on top of > this, or would you prefer to take it through the ARM tree? So it would be great if you can work in your review comments and send me a pull request with the result. I'll put it into the iommu-tree for v4.3 then. Joerg ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [RFC PATCH 0/1] iommu: Detach device from domain when removed from group
On Tue, 28 Jul 2015 19:55:55 +0200 Gerald Schaefer wrote: > Hi, > > during IOMMU API function testing on s390 I hit the following scenario: > > After binding a device to vfio-pci, the user completes the VFIO_SET_IOMMU > ioctl and stops, see the sample C program below. Now the device is manually > removed via "echo 1 > /sys/bus/pci/devices/.../remove". > > Although the SET_IOMMU ioctl triggered the attach_dev callback in the > underlying IOMMU API, removing the device in this way won't trigger the > detach_dev callback, neither during remove nor when the user program > continues with closing group/container. > > On s390, this eventually leads to a kernel panic when binding the device > again to its non-vfio PCI driver, because of the missing arch-specific > cleanup in detach_dev. On x86, the detach_dev callback will also not be > called directly, but there is a notifier that will catch > BUS_NOTIFY_REMOVED_DEVICE and eventually do the cleanup. Other > architectures w/o the notifier probably have at least some kind of memory > leak in this scenario, so a general fix would be nice. > > My first approach was to try and fix this in VFIO code, but Alex Williamson > pointed me to some asymmetry in the IOMMU code: iommu_group_add_device() > will invoke the attach_dev callback, but iommu_group_remove_device() won't > trigger detach_dev. Fixing this asymmetry would fix the issue for me, but > is this the correct fix? Any thoughts? Ping. The suggested fix may be completely wrong, but not having detach_dev called seems like like a serious issue, any feedback would be greatly appreciated. > > Regards, > Gerald > > > Here is the sample C program to trigger the ioctl: > > #include > #include > #include > > int main(void) > { > int container, group, rc; > > container = open("/dev/vfio/vfio", O_RDWR); > if (container < 0) { > perror("open /dev/vfio/vfio\n"); > return -1; > } > > group = open("/dev/vfio/0", O_RDWR); > if (group < 0) { > perror("open /dev/vfio/0\n"); > return -1; > } > > rc = ioctl(group, VFIO_GROUP_SET_CONTAINER, &container); > if (rc) { > perror("ioctl VFIO_GROUP_SET_CONTAINER\n"); > return -1; > } > > rc = ioctl(container, VFIO_SET_IOMMU, VFIO_TYPE1_IOMMU); > if (rc) { > perror("ioctl VFIO_SET_IOMMU\n"); > return -1; > } > > printf("Try device remove...\n"); > getchar(); > > close(group); > close(container); > return 0; > } > > Gerald Schaefer (1): > iommu: Detach device from domain when removed from group > > drivers/iommu/iommu.c | 5 + > 1 file changed, 5 insertions(+) > ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
RE: [PATCH v2] iommu/fsl: Really fix init section(s) content
Hi Joerg, This patch doesn't seem to be applied to the PAMU driver. Regards Varun > -Original Message- > From: iommu-boun...@lists.linux-foundation.org [mailto:iommu- > boun...@lists.linux-foundation.org] On Behalf Of Emil Medve > Sent: Wednesday, March 25, 2015 10:59 AM > To: iommu@lists.linux-foundation.org; j...@8bytes.org > Cc: sta...@vger.kernel.org; Medve Emilian-EMMEDVE1 > Subject: [PATCH v2] iommu/fsl: Really fix init section(s) content > > '0f1fb99 iommu/fsl: Fix section mismatch' was intended to address the > modpost warning and the potential crash. Crash which is actually easy to > trigger with a 'unbind' followed by a 'bind' sequence. The fix is wrong as > fsl_of_pamu_driver.driver gets added by bus_add_driver() to a couple of > klist(s) which become invalid/corrupted as soon as the init sections are > freed. > Depending on when/how the init sections storage is reused various/random > errors and crashes will happen > > 'cd70d46 iommu/fsl: Various cleanups' contains annotations that go further > down the wrong path laid by '0f1fb99 iommu/fsl: Fix section mismatch' > > Now remove all the incorrect annotations from the above mentioned > patches (not exactly a revert) and those previously existing in the code, This > fixes the modpost warning(s), the unbind/bind sequence crashes and the > random errors/crashes > > Fixes: 0f1fb99b62ce ("iommu/fsl: Fix section mismatch") > Fixes: cd70d4659ff3 ("iommu/fsl: Various cleanups") > Signed-off-by: Emil Medve > Acked-by: Varun Sethi > Cc: sta...@vger.kernel.org > --- > drivers/iommu/fsl_pamu.c | 26 +- > 1 file changed, 13 insertions(+), 13 deletions(-) > > diff --git a/drivers/iommu/fsl_pamu.c b/drivers/iommu/fsl_pamu.c index > abeedc9..2570f2a 100644 > --- a/drivers/iommu/fsl_pamu.c > +++ b/drivers/iommu/fsl_pamu.c > @@ -41,7 +41,6 @@ struct pamu_isr_data { > > static struct paace *ppaact; > static struct paace *spaact; > -static struct ome *omt __initdata; > > /* > * Table for matching compatible strings, for device tree @@ -50,7 +49,7 @@ > static struct ome *omt __initdata; > * SOCs. For the older SOCs "fsl,qoriq-device-config-1.0" > * string would be used. > */ > -static const struct of_device_id guts_device_ids[] __initconst = { > +static const struct of_device_id guts_device_ids[] = { > { .compatible = "fsl,qoriq-device-config-1.0", }, > { .compatible = "fsl,qoriq-device-config-2.0", }, > {} > @@ -599,7 +598,7 @@ found_cpu_node: > * Memory accesses to QMAN and BMAN private memory need not be > coherent, so > * clear the PAACE entry coherency attribute for them. > */ > -static void __init setup_qbman_paace(struct paace *ppaace, int > paace_type) > +static void setup_qbman_paace(struct paace *ppaace, int paace_type) > { > switch (paace_type) { > case QMAN_PAACE: > @@ -629,7 +628,7 @@ static void __init setup_qbman_paace(struct paace > *ppaace, int paace_type) > * this table to translate device transaction to appropriate corenet > * transaction. > */ > -static void __init setup_omt(struct ome *omt) > +static void setup_omt(struct ome *omt) > { > struct ome *ome; > > @@ -666,7 +665,7 @@ static void __init setup_omt(struct ome *omt) > * Get the maximum number of PAACT table entries > * and subwindows supported by PAMU > */ > -static void __init get_pamu_cap_values(unsigned long pamu_reg_base) > +static void get_pamu_cap_values(unsigned long pamu_reg_base) > { > u32 pc_val; > > @@ -676,9 +675,9 @@ static void __init get_pamu_cap_values(unsigned > long pamu_reg_base) } > > /* Setup PAMU registers pointing to PAACT, SPAACT and OMT */ -static int > __init setup_one_pamu(unsigned long pamu_reg_base, unsigned long > pamu_reg_size, > - phys_addr_t ppaact_phys, phys_addr_t > spaact_phys, > - phys_addr_t omt_phys) > +static int setup_one_pamu(unsigned long pamu_reg_base, unsigned long > pamu_reg_size, > + phys_addr_t ppaact_phys, phys_addr_t > spaact_phys, > + phys_addr_t omt_phys) > { > u32 *pc; > struct pamu_mmap_regs *pamu_regs; > @@ -720,7 +719,7 @@ static int __init setup_one_pamu(unsigned long > pamu_reg_base, unsigned long pamu } > > /* Enable all device LIODNS */ > -static void __init setup_liodns(void) > +static void setup_liodns(void) > { > int i, len; > struct paace *ppaace; > @@ -846,7 +845,7 @@ struct ccsr_law { > /* > * Create a coherence subdomain for a given memory block. > */ > -static int __init create_csd(phys_addr_t phys, size_t size, u32 csd_port_id) > +static int create_csd(phys_addr_t phys, size_t size, u32 csd_port_id) > { > struct device_node *np; > const __be32 *iprop; > @@ -988,7 +987,7 @@ error: > static const struct { > u32 svr; > u32 port_id; > -} port_id_map[] __initconst = { > +} port_id_map[] = { > {(SVR_P2040 << 8) | 0x10, 0xFF00}, /* P20
[PATCH 10/13] iommu/arm-smmu: Remove arm_smmu_flush_pgtable()
From: Robin Murphy With the io-pgtable code now enforcing its own appropriate sync points, the vestigial flush_pgtable callback becomes entirely redundant, so remove it altogether. Signed-off-by: Robin Murphy Signed-off-by: Will Deacon --- drivers/iommu/arm-smmu.c | 13 - 1 file changed, 13 deletions(-) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 5770ab98fa38..48a39dfa9777 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -608,23 +608,10 @@ static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size, } } -static void arm_smmu_flush_pgtable(void *addr, size_t size, void *cookie) -{ - struct arm_smmu_domain *smmu_domain = cookie; - - /* -* Ensure new page tables are visible to a coherent hardware walker. -* The page table code deals with flushing for the non-coherent case. -*/ - if (smmu_domain->smmu->features & ARM_SMMU_FEAT_COHERENT_WALK) - dsb(ishst); -} - static struct iommu_gather_ops arm_smmu_gather_ops = { .tlb_flush_all = arm_smmu_tlb_inv_context, .tlb_add_flush = arm_smmu_tlb_inv_range_nosync, .tlb_sync = arm_smmu_tlb_sync, - .flush_pgtable = arm_smmu_flush_pgtable, }; static irqreturn_t arm_smmu_context_fault(int irq, void *dev) -- 2.1.4 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 07/13] iommu/arm-smmu: Clean up DMA API usage
From: Robin Murphy With the correct DMA API calls now integrated into the io-pgtable code, let that handle the flushing of non-coherent page table updates. Signed-off-by: Robin Murphy Signed-off-by: Will Deacon --- drivers/iommu/arm-smmu-v3.c | 18 +++--- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 4f093373f4c3..38a891e28e13 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -1334,23 +1334,10 @@ static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size, static void arm_smmu_flush_pgtable(void *addr, size_t size, void *cookie) { struct arm_smmu_domain *smmu_domain = cookie; - struct arm_smmu_device *smmu = smmu_domain->smmu; - unsigned long offset = (unsigned long)addr & ~PAGE_MASK; - if (smmu->features & ARM_SMMU_FEAT_COHERENCY) { + /* The page table code handles flushing in the non-coherent case */ + if (smmu_domain->smmu->features & ARM_SMMU_FEAT_COHERENCY) dsb(ishst); - } else { - dma_addr_t dma_addr; - struct device *dev = smmu->dev; - - dma_addr = dma_map_page(dev, virt_to_page(addr), offset, size, - DMA_TO_DEVICE); - - if (dma_mapping_error(dev, dma_addr)) - dev_err(dev, "failed to flush pgtable at %p\n", addr); - else - dma_unmap_page(dev, dma_addr, size, DMA_TO_DEVICE); - } } static struct iommu_gather_ops arm_smmu_gather_ops = { @@ -1532,6 +1519,7 @@ static int arm_smmu_domain_finalise(struct iommu_domain *domain) .ias= ias, .oas= oas, .tlb= &arm_smmu_gather_ops, + .iommu_dev = smmu->dev, }; pgtbl_ops = alloc_io_pgtable_ops(fmt, &pgtbl_cfg, smmu_domain); -- 2.1.4 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 03/13] iommu/arm-smmu: Limit 2-level strtab allocation for small SID sizes
If the StreamIDs in a system can all be resolved by a single level-2 stream table (i.e. SIDSIZE < SPLIT), then we currently get our maths wrong and allocate the largest strtab we support, thanks to unsigned overflow in our calculation. This patch fixes the issue by checking the SIDSIZE explicitly when calculating the size of our first-level stream table. Reported-by: Matt Evans Signed-off-by: Will Deacon --- drivers/iommu/arm-smmu-v3.c | 14 +++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index c2c1ad8915d9..4f093373f4c3 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -2054,9 +2054,17 @@ static int arm_smmu_init_strtab_2lvl(struct arm_smmu_device *smmu) int ret; struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg; - /* Calculate the L1 size, capped to the SIDSIZE */ - size = STRTAB_L1_SZ_SHIFT - (ilog2(STRTAB_L1_DESC_DWORDS) + 3); - size = min(size, smmu->sid_bits - STRTAB_SPLIT); + /* +* If we can resolve everything with a single L2 table, then we +* just need a single L1 descriptor. Otherwise, calculate the L1 +* size, capped to the SIDSIZE. +*/ + if (smmu->sid_bits < STRTAB_SPLIT) { + size = 0; + } else { + size = STRTAB_L1_SZ_SHIFT - (ilog2(STRTAB_L1_DESC_DWORDS) + 3); + size = min(size, smmu->sid_bits - STRTAB_SPLIT); + } cfg->num_l1_ents = 1 << size; size += STRTAB_SPLIT; -- 2.1.4 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 05/13] iommu/io-pgtable-arm: Allow appropriate DMA API use
From: Robin Murphy Currently, users of the LPAE page table code are (ab)using dma_map_page() as a means to flush page table updates for non-coherent IOMMUs. Since from the CPU's point of view, creating IOMMU page tables *is* passing DMA buffers to a device (the IOMMU's page table walker), there's little reason not to use the DMA API correctly. Allow IOMMU drivers to opt into DMA API operations for page table allocation and updates by providing their appropriate device pointer. The expectation is that an LPAE IOMMU should have a full view of system memory, so use streaming mappings to avoid unnecessary pressure on ZONE_DMA, and treat any DMA translation as a warning sign. Signed-off-by: Robin Murphy Signed-off-by: Will Deacon --- drivers/iommu/Kconfig | 3 +- drivers/iommu/io-pgtable-arm.c | 107 - drivers/iommu/io-pgtable.h | 3 ++ 3 files changed, 89 insertions(+), 24 deletions(-) diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index f1fb1d3ccc56..d77a848d50de 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -23,7 +23,8 @@ config IOMMU_IO_PGTABLE config IOMMU_IO_PGTABLE_LPAE bool "ARMv7/v8 Long Descriptor Format" select IOMMU_IO_PGTABLE - depends on ARM || ARM64 || COMPILE_TEST + # SWIOTLB guarantees a dma_to_phys() implementation + depends on ARM || ARM64 || (COMPILE_TEST && SWIOTLB) help Enable support for the ARM long descriptor pagetable format. This allocator supports 4K/2M/1G, 16K/32M and 64K/512M page diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c index 4e460216bd16..28cca8a652f9 100644 --- a/drivers/iommu/io-pgtable-arm.c +++ b/drivers/iommu/io-pgtable-arm.c @@ -200,12 +200,76 @@ typedef u64 arm_lpae_iopte; static bool selftest_running = false; +static dma_addr_t __arm_lpae_dma_addr(struct device *dev, void *pages) +{ + return phys_to_dma(dev, virt_to_phys(pages)); +} + +static void *__arm_lpae_alloc_pages(size_t size, gfp_t gfp, + struct io_pgtable_cfg *cfg) +{ + struct device *dev = cfg->iommu_dev; + dma_addr_t dma; + void *pages = alloc_pages_exact(size, gfp | __GFP_ZERO); + + if (!pages) + return NULL; + + if (dev) { + dma = dma_map_single(dev, pages, size, DMA_TO_DEVICE); + if (dma_mapping_error(dev, dma)) + goto out_free; + /* +* We depend on the IOMMU being able to work with any physical +* address directly, so if the DMA layer suggests it can't by +* giving us back some translation, that bodes very badly... +*/ + if (dma != __arm_lpae_dma_addr(dev, pages)) + goto out_unmap; + } + + return pages; + +out_unmap: + dev_err(dev, "Cannot accommodate DMA translation for IOMMU page tables\n"); + dma_unmap_single(dev, dma, size, DMA_TO_DEVICE); +out_free: + free_pages_exact(pages, size); + return NULL; +} + +static void __arm_lpae_free_pages(void *pages, size_t size, + struct io_pgtable_cfg *cfg) +{ + struct device *dev = cfg->iommu_dev; + + if (dev) + dma_unmap_single(dev, __arm_lpae_dma_addr(dev, pages), +size, DMA_TO_DEVICE); + free_pages_exact(pages, size); +} + +static void __arm_lpae_set_pte(arm_lpae_iopte *ptep, arm_lpae_iopte pte, + struct io_pgtable_cfg *cfg, void *cookie) +{ + struct device *dev = cfg->iommu_dev; + + *ptep = pte; + + if (dev) + dma_sync_single_for_device(dev, __arm_lpae_dma_addr(dev, ptep), + sizeof(pte), DMA_TO_DEVICE); + else if (cfg->tlb->flush_pgtable) + cfg->tlb->flush_pgtable(ptep, sizeof(pte), cookie); +} + static int arm_lpae_init_pte(struct arm_lpae_io_pgtable *data, unsigned long iova, phys_addr_t paddr, arm_lpae_iopte prot, int lvl, arm_lpae_iopte *ptep) { arm_lpae_iopte pte = prot; + struct io_pgtable_cfg *cfg = &data->iop.cfg; /* We require an unmap first */ if (iopte_leaf(*ptep, lvl)) { @@ -213,7 +277,7 @@ static int arm_lpae_init_pte(struct arm_lpae_io_pgtable *data, return -EEXIST; } - if (data->iop.cfg.quirks & IO_PGTABLE_QUIRK_ARM_NS) + if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_NS) pte |= ARM_LPAE_PTE_NS; if (lvl == ARM_LPAE_MAX_LEVELS - 1) @@ -224,8 +288,7 @@ static int arm_lpae_init_pte(struct arm_lpae_io_pgtable *data, pte |= ARM_LPAE_PTE_AF | ARM_LPAE_PTE_SH_IS; pte |= pfn_to_iopte(paddr >> data->pg_shift, data); - *ptep = pte; - data->iop.cfg.tlb->flush_pgtab
[PATCH 00/13] iommu/arm-smmu: Updates for 4.3
Hi all, This is the ARM SMMU driver queue I currently have for 4.3. The diffstat is slightly noisy since Robin cleaned up the DMA API usage in the io-pgtable code so the client drivers no longer need to perform dma_map_page hacks in order to clean the CPU caches on non-coherent systems. Other changes include some MSI prep., a couple of minor fixes for SMMUv3 and honouring of the dma-coherent property for SMMUv1/2. In the absence of any issues, I plan to send a pull request to Joerg later this week. Cheers, Will --->8 Marc Zyngier (2): iommu/arm-smmu: Fix enabling of PRIQ interrupt iommu/arm-smmu: Fix MSI memory attributes to match specification Robin Murphy (9): iommu/arm-smmu: Sort out coherency iommu/io-pgtable-arm: Allow appropriate DMA API use iommu/arm-smmu: Clean up DMA API usage iommu/arm-smmu: Clean up DMA API usage iommu/ipmmu-vmsa: Clean up DMA API usage iommu/io-pgtable-arm: Centralise sync points iommu/arm-smmu: Remove arm_smmu_flush_pgtable() iommu/arm-smmu: Remove arm_smmu_flush_pgtable() iommu/io-pgtable: Remove flush_pgtable callback Will Deacon (2): iommu/arm-smmu: Limit 2-level strtab allocation for small SID sizes iommu/arm-smmu: Treat unknown OAS as 48-bit .../devicetree/bindings/iommu/arm,smmu.txt | 6 + drivers/iommu/Kconfig | 3 +- drivers/iommu/arm-smmu-v3.c| 65 +-- drivers/iommu/arm-smmu.c | 45 +++- drivers/iommu/io-pgtable-arm.c | 126 +++-- drivers/iommu/io-pgtable.h | 9 +- drivers/iommu/ipmmu-vmsa.c | 19 +--- 7 files changed, 156 insertions(+), 117 deletions(-) -- 2.1.4 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 06/13] iommu/arm-smmu: Clean up DMA API usage
From: Robin Murphy With the correct DMA API calls now integrated into the io-pgtable code, let that handle the flushing of non-coherent page table updates. Signed-off-by: Robin Murphy Signed-off-by: Will Deacon --- drivers/iommu/arm-smmu.c | 22 ++ 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 0583ed2f33c0..5770ab98fa38 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -611,24 +611,13 @@ static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size, static void arm_smmu_flush_pgtable(void *addr, size_t size, void *cookie) { struct arm_smmu_domain *smmu_domain = cookie; - struct arm_smmu_device *smmu = smmu_domain->smmu; - unsigned long offset = (unsigned long)addr & ~PAGE_MASK; - - /* Ensure new page tables are visible to the hardware walker */ - if (smmu->features & ARM_SMMU_FEAT_COHERENT_WALK) { + /* +* Ensure new page tables are visible to a coherent hardware walker. +* The page table code deals with flushing for the non-coherent case. +*/ + if (smmu_domain->smmu->features & ARM_SMMU_FEAT_COHERENT_WALK) dsb(ishst); - } else { - /* -* If the SMMU can't walk tables in the CPU caches, treat them -* like non-coherent DMA since we need to flush the new entries -* all the way out to memory. There's no possibility of -* recursion here as the SMMU table walker will not be wired -* through another SMMU. -*/ - dma_map_page(smmu->dev, virt_to_page(addr), offset, size, -DMA_TO_DEVICE); - } } static struct iommu_gather_ops arm_smmu_gather_ops = { @@ -899,6 +888,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, .ias= ias, .oas= oas, .tlb= &arm_smmu_gather_ops, + .iommu_dev = smmu->dev, }; smmu_domain->smmu = smmu; -- 2.1.4 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 11/13] iommu/arm-smmu: Remove arm_smmu_flush_pgtable()
From: Robin Murphy With the io-pgtable code now enforcing its own appropriate sync points, the vestigial flush_pgtable callback becomes entirely redundant, so remove it altogether. Signed-off-by: Robin Murphy Signed-off-by: Will Deacon --- drivers/iommu/arm-smmu-v3.c | 10 -- 1 file changed, 10 deletions(-) diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 38a891e28e13..15fb669282b4 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -1331,20 +1331,10 @@ static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size, arm_smmu_cmdq_issue_cmd(smmu, &cmd); } -static void arm_smmu_flush_pgtable(void *addr, size_t size, void *cookie) -{ - struct arm_smmu_domain *smmu_domain = cookie; - - /* The page table code handles flushing in the non-coherent case */ - if (smmu_domain->smmu->features & ARM_SMMU_FEAT_COHERENCY) - dsb(ishst); -} - static struct iommu_gather_ops arm_smmu_gather_ops = { .tlb_flush_all = arm_smmu_tlb_inv_context, .tlb_add_flush = arm_smmu_tlb_inv_range_nosync, .tlb_sync = arm_smmu_tlb_sync, - .flush_pgtable = arm_smmu_flush_pgtable, }; /* IOMMU API */ -- 2.1.4 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 01/13] iommu/arm-smmu: Fix enabling of PRIQ interrupt
From: Marc Zyngier When an ARM SMMUv3 instance supports PRI, the driver registers an interrupt handler, but fails to enable the generation of such interrupt at the SMMU level. This patches simply moves the enable flags to a variable that gets updated by the PRI handling code before being written to the SMMU register. Signed-off-by: Marc Zyngier Signed-off-by: Will Deacon --- drivers/iommu/arm-smmu-v3.c | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index da902baaa794..5d2cbdab5afa 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -118,6 +118,7 @@ #define ARM_SMMU_IRQ_CTRL 0x50 #define IRQ_CTRL_EVTQ_IRQEN(1 << 2) +#define IRQ_CTRL_PRIQ_IRQEN(1 << 1) #define IRQ_CTRL_GERROR_IRQEN (1 << 0) #define ARM_SMMU_IRQ_CTRLACK 0x54 @@ -2198,6 +2199,7 @@ static int arm_smmu_write_reg_sync(struct arm_smmu_device *smmu, u32 val, static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) { int ret, irq; + u32 irqen_flags = IRQ_CTRL_EVTQ_IRQEN | IRQ_CTRL_GERROR_IRQEN; /* Disable IRQs first */ ret = arm_smmu_write_reg_sync(smmu, 0, ARM_SMMU_IRQ_CTRL, @@ -2252,13 +2254,13 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu) if (IS_ERR_VALUE(ret)) dev_warn(smmu->dev, "failed to enable priq irq\n"); + else + irqen_flags |= IRQ_CTRL_PRIQ_IRQEN; } } /* Enable interrupt generation on the SMMU */ - ret = arm_smmu_write_reg_sync(smmu, - IRQ_CTRL_EVTQ_IRQEN | - IRQ_CTRL_GERROR_IRQEN, + ret = arm_smmu_write_reg_sync(smmu, irqen_flags, ARM_SMMU_IRQ_CTRL, ARM_SMMU_IRQ_CTRLACK); if (ret) dev_warn(smmu->dev, "failed to enable irqs\n"); -- 2.1.4 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 09/13] iommu/io-pgtable-arm: Centralise sync points
From: Robin Murphy With all current users now opted in to DMA API operations, make the iommu_dev pointer mandatory, rendering the flush_pgtable callback redundant for cache maintenance. However, since the DMA calls could be nops in the case of a coherent IOMMU, we still need to ensure the page table updates are fully synchronised against a subsequent page table walk. In the unmap path, the TLB sync will usually need to do this anyway, so just cement that requirement; in the map path which may consist solely of cacheable memory writes (in the coherent case), insert an appropriate barrier at the end of the operation, and obviate the need to call flush_pgtable on every individual update for synchronisation. Signed-off-by: Robin Murphy [will: slight clarification to tlb_sync comment] Signed-off-by: Will Deacon --- drivers/iommu/io-pgtable-arm.c | 43 +++--- drivers/iommu/io-pgtable.h | 4 +++- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c index 28cca8a652f9..06176872fb78 100644 --- a/drivers/iommu/io-pgtable-arm.c +++ b/drivers/iommu/io-pgtable-arm.c @@ -26,6 +26,8 @@ #include #include +#include + #include "io-pgtable.h" #define ARM_LPAE_MAX_ADDR_BITS 48 @@ -215,7 +217,7 @@ static void *__arm_lpae_alloc_pages(size_t size, gfp_t gfp, if (!pages) return NULL; - if (dev) { + if (!selftest_running) { dma = dma_map_single(dev, pages, size, DMA_TO_DEVICE); if (dma_mapping_error(dev, dma)) goto out_free; @@ -243,24 +245,22 @@ static void __arm_lpae_free_pages(void *pages, size_t size, { struct device *dev = cfg->iommu_dev; - if (dev) + if (!selftest_running) dma_unmap_single(dev, __arm_lpae_dma_addr(dev, pages), size, DMA_TO_DEVICE); free_pages_exact(pages, size); } static void __arm_lpae_set_pte(arm_lpae_iopte *ptep, arm_lpae_iopte pte, - struct io_pgtable_cfg *cfg, void *cookie) + struct io_pgtable_cfg *cfg) { struct device *dev = cfg->iommu_dev; *ptep = pte; - if (dev) + if (!selftest_running) dma_sync_single_for_device(dev, __arm_lpae_dma_addr(dev, ptep), sizeof(pte), DMA_TO_DEVICE); - else if (cfg->tlb->flush_pgtable) - cfg->tlb->flush_pgtable(ptep, sizeof(pte), cookie); } static int arm_lpae_init_pte(struct arm_lpae_io_pgtable *data, @@ -288,7 +288,7 @@ static int arm_lpae_init_pte(struct arm_lpae_io_pgtable *data, pte |= ARM_LPAE_PTE_AF | ARM_LPAE_PTE_SH_IS; pte |= pfn_to_iopte(paddr >> data->pg_shift, data); - __arm_lpae_set_pte(ptep, pte, cfg, data->iop.cookie); + __arm_lpae_set_pte(ptep, pte, cfg); return 0; } @@ -297,7 +297,6 @@ static int __arm_lpae_map(struct arm_lpae_io_pgtable *data, unsigned long iova, int lvl, arm_lpae_iopte *ptep) { arm_lpae_iopte *cptep, pte; - void *cookie = data->iop.cookie; size_t block_size = ARM_LPAE_BLOCK_SIZE(lvl, data); struct io_pgtable_cfg *cfg = &data->iop.cfg; @@ -323,7 +322,7 @@ static int __arm_lpae_map(struct arm_lpae_io_pgtable *data, unsigned long iova, pte = __pa(cptep) | ARM_LPAE_PTE_TYPE_TABLE; if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_NS) pte |= ARM_LPAE_PTE_NSTABLE; - __arm_lpae_set_pte(ptep, pte, cfg, cookie); + __arm_lpae_set_pte(ptep, pte, cfg); } else { cptep = iopte_deref(pte, data); } @@ -370,7 +369,7 @@ static int arm_lpae_map(struct io_pgtable_ops *ops, unsigned long iova, { struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops); arm_lpae_iopte *ptep = data->pgd; - int lvl = ARM_LPAE_START_LVL(data); + int ret, lvl = ARM_LPAE_START_LVL(data); arm_lpae_iopte prot; /* If no access, then nothing to do */ @@ -378,7 +377,14 @@ static int arm_lpae_map(struct io_pgtable_ops *ops, unsigned long iova, return 0; prot = arm_lpae_prot_to_pte(data, iommu_prot); - return __arm_lpae_map(data, iova, paddr, size, prot, lvl, ptep); + ret = __arm_lpae_map(data, iova, paddr, size, prot, lvl, ptep); + /* +* Synchronise all PTE updates for the new mapping before there's +* a chance for anything to kick off a table walk for the new iova. +*/ + wmb(); + + return ret; } static void __arm_lpae_free_pgtable(struct arm_lpae_io_pgtable *data, int lvl, @@ -428,7 +434,6 @@ static int arm_lpae_split_blk_unmap(struct arm_lpae_io_pgtable *data, phys_addr_t blk_paddr; arm_lpae_iopte table = 0; struct io_pgtable_cfg *cfg
[PATCH 13/13] iommu/arm-smmu: Treat unknown OAS as 48-bit
A late change to the SMMUv3 architecture ensures that the OAS field will be monotonically increasing, so we can assume that an unknown OAS is at least 48-bit and use that, rather than fail the device probe. Signed-off-by: Will Deacon --- drivers/iommu/arm-smmu-v3.c | 7 +++ 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 15fb669282b4..a435e706226a 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -2528,12 +2528,11 @@ static int arm_smmu_device_probe(struct arm_smmu_device *smmu) case IDR5_OAS_44_BIT: smmu->oas = 44; break; + default: + dev_info(smmu->dev, + "unknown output address size. Truncating to 48-bit\n"); case IDR5_OAS_48_BIT: smmu->oas = 48; - break; - default: - dev_err(smmu->dev, "unknown output address size!\n"); - return -ENXIO; } /* Set the DMA mask for our table walker */ -- 2.1.4 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 02/13] iommu/arm-smmu: Fix MSI memory attributes to match specification
From: Marc Zyngier The MSI memory attributes in the SMMUv3 driver are from an older revision of the spec, which doesn't match the current implementations. Out with the old, in with the new. Signed-off-by: Marc Zyngier Signed-off-by: Will Deacon --- drivers/iommu/arm-smmu-v3.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 5d2cbdab5afa..c2c1ad8915d9 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -174,14 +174,14 @@ #define ARM_SMMU_PRIQ_IRQ_CFG2 0xdc /* Common MSI config fields */ -#define MSI_CFG0_SH_SHIFT 60 -#define MSI_CFG0_SH_NSH(0UL << MSI_CFG0_SH_SHIFT) -#define MSI_CFG0_SH_OSH(2UL << MSI_CFG0_SH_SHIFT) -#define MSI_CFG0_SH_ISH(3UL << MSI_CFG0_SH_SHIFT) -#define MSI_CFG0_MEMATTR_SHIFT 56 -#define MSI_CFG0_MEMATTR_DEVICE_nGnRE (0x1 << MSI_CFG0_MEMATTR_SHIFT) #define MSI_CFG0_ADDR_SHIFT2 #define MSI_CFG0_ADDR_MASK 0x3fffUL +#define MSI_CFG2_SH_SHIFT 4 +#define MSI_CFG2_SH_NSH(0UL << MSI_CFG2_SH_SHIFT) +#define MSI_CFG2_SH_OSH(2UL << MSI_CFG2_SH_SHIFT) +#define MSI_CFG2_SH_ISH(3UL << MSI_CFG2_SH_SHIFT) +#define MSI_CFG2_MEMATTR_SHIFT 0 +#define MSI_CFG2_MEMATTR_DEVICE_nGnRE (0x1 << MSI_CFG2_MEMATTR_SHIFT) #define Q_IDX(q, p)((p) & ((1 << (q)->max_n_shift) - 1)) #define Q_WRP(q, p)((p) & (1 << (q)->max_n_shift)) -- 2.1.4 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 04/13] iommu/arm-smmu: Sort out coherency
From: Robin Murphy Currently, we detect whether the SMMU has coherent page table walk capability from the IDR0.CTTW field, and base our cache maintenance decisions on that. In preparation for fixing the bogus DMA API usage, however, we need to ensure that the DMA API agrees about this, which necessitates deferring to the dma-coherent property in the device tree for the final say. As an added bonus, since systems exist where an external CTTW signal has been tied off incorrectly at integration, allowing DT to override it offers a neat workaround for coherency issues with such SMMUs. Signed-off-by: Robin Murphy Signed-off-by: Will Deacon --- Documentation/devicetree/bindings/iommu/arm,smmu.txt | 6 ++ drivers/iommu/arm-smmu.c | 20 +--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt b/Documentation/devicetree/bindings/iommu/arm,smmu.txt index 06760503a819..718074501fcb 100644 --- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt +++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt @@ -43,6 +43,12 @@ conditions. ** System MMU optional properties: +- dma-coherent : Present if page table walks made by the SMMU are + cache coherent with the CPU. + + NOTE: this only applies to the SMMU itself, not + masters connected upstream of the SMMU. + - calxeda,smmu-secure-config-access : Enable proper handling of buggy implementations that always use secure access to SMMU configuration registers. In this case non-secure diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 4cd0c29cb585..0583ed2f33c0 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -1532,6 +1533,7 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu) unsigned long size; void __iomem *gr0_base = ARM_SMMU_GR0(smmu); u32 id; + bool cttw_dt, cttw_reg; dev_notice(smmu->dev, "probing hardware configuration...\n"); dev_notice(smmu->dev, "SMMUv%d with:\n", smmu->version); @@ -1571,10 +1573,22 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu) dev_notice(smmu->dev, "\taddress translation ops\n"); } - if (id & ID0_CTTW) { + /* +* In order for DMA API calls to work properly, we must defer to what +* the DT says about coherency, regardless of what the hardware claims. +* Fortunately, this also opens up a workaround for systems where the +* ID register value has ended up configured incorrectly. +*/ + cttw_dt = of_dma_is_coherent(smmu->dev->of_node); + cttw_reg = !!(id & ID0_CTTW); + if (cttw_dt) smmu->features |= ARM_SMMU_FEAT_COHERENT_WALK; - dev_notice(smmu->dev, "\tcoherent table walk\n"); - } + if (cttw_dt || cttw_reg) + dev_notice(smmu->dev, "\t%scoherent table walk\n", + cttw_dt ? "" : "non-"); + if (cttw_dt != cttw_reg) + dev_notice(smmu->dev, + "\t(IDR0.CTTW overridden by dma-coherent property)\n"); if (id & ID0_SMS) { u32 smr, sid, mask; -- 2.1.4 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 08/13] iommu/ipmmu-vmsa: Clean up DMA API usage
From: Robin Murphy With the correct DMA API calls now integrated into the io-pgtable code, let that handle the flushing of non-coherent page table updates. Signed-off-by: Robin Murphy Signed-off-by: Will Deacon --- drivers/iommu/ipmmu-vmsa.c | 19 +-- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c index 1a67c531a07e..8cf605fa9946 100644 --- a/drivers/iommu/ipmmu-vmsa.c +++ b/drivers/iommu/ipmmu-vmsa.c @@ -283,24 +283,10 @@ static void ipmmu_tlb_add_flush(unsigned long iova, size_t size, bool leaf, /* The hardware doesn't support selective TLB flush. */ } -static void ipmmu_flush_pgtable(void *ptr, size_t size, void *cookie) -{ - unsigned long offset = (unsigned long)ptr & ~PAGE_MASK; - struct ipmmu_vmsa_domain *domain = cookie; - - /* -* TODO: Add support for coherent walk through CCI with DVM and remove -* cache handling. -*/ - dma_map_page(domain->mmu->dev, virt_to_page(ptr), offset, size, -DMA_TO_DEVICE); -} - static struct iommu_gather_ops ipmmu_gather_ops = { .tlb_flush_all = ipmmu_tlb_flush_all, .tlb_add_flush = ipmmu_tlb_add_flush, .tlb_sync = ipmmu_tlb_flush_all, - .flush_pgtable = ipmmu_flush_pgtable, }; /* - @@ -327,6 +313,11 @@ static int ipmmu_domain_init_context(struct ipmmu_vmsa_domain *domain) domain->cfg.ias = 32; domain->cfg.oas = 40; domain->cfg.tlb = &ipmmu_gather_ops; + /* +* TODO: Add support for coherent walk through CCI with DVM and remove +* cache handling. For now, delegate it to the io-pgtable code. +*/ + domain->cfg.iommu_dev = domain->mmu->dev; domain->iop = alloc_io_pgtable_ops(ARM_32_LPAE_S1, &domain->cfg, domain); -- 2.1.4 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 12/13] iommu/io-pgtable: Remove flush_pgtable callback
From: Robin Murphy With the users fully converted to DMA API operations, it's dead, Jim. Signed-off-by: Robin Murphy Signed-off-by: Will Deacon --- drivers/iommu/io-pgtable-arm.c | 6 -- drivers/iommu/io-pgtable.h | 2 -- 2 files changed, 8 deletions(-) diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c index 06176872fb78..e4bc2b23ab96 100644 --- a/drivers/iommu/io-pgtable-arm.c +++ b/drivers/iommu/io-pgtable-arm.c @@ -884,16 +884,10 @@ static void dummy_tlb_sync(void *cookie) WARN_ON(cookie != cfg_cookie); } -static void dummy_flush_pgtable(void *ptr, size_t size, void *cookie) -{ - WARN_ON(cookie != cfg_cookie); -} - static struct iommu_gather_ops dummy_tlb_ops __initdata = { .tlb_flush_all = dummy_tlb_flush_all, .tlb_add_flush = dummy_tlb_add_flush, .tlb_sync = dummy_tlb_sync, - .flush_pgtable = dummy_flush_pgtable, }; static void __init arm_lpae_dump_ops(struct io_pgtable_ops *ops) diff --git a/drivers/iommu/io-pgtable.h b/drivers/iommu/io-pgtable.h index e8fadb012ed2..48538a35d078 100644 --- a/drivers/iommu/io-pgtable.h +++ b/drivers/iommu/io-pgtable.h @@ -20,7 +20,6 @@ enum io_pgtable_fmt { * @tlb_sync: Ensure any queued TLB invalidation has taken effect, and * any corresponding page table updates are visible to the * IOMMU. - * @flush_pgtable: Ensure page table updates are visible to the IOMMU. * * Note that these can all be called in atomic context and must therefore * not block. @@ -30,7 +29,6 @@ struct iommu_gather_ops { void (*tlb_add_flush)(unsigned long iova, size_t size, bool leaf, void *cookie); void (*tlb_sync)(void *cookie); - void (*flush_pgtable)(void *ptr, size_t size, void *cookie); }; /** -- 2.1.4 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH 00/11] Some OMAP IOMMU cleanup patches
On Mon, Jul 20, 2015 at 05:33:22PM -0500, Suman Anna wrote: > Suman Anna (11): > Documentation: dt: Add #iommu-cells info to OMAP iommu bindings > iommu/omap: Remove all module references > iommu/omap: Move debugfs functions to omap-iommu-debug.c > iommu/omap: Protect omap-iopgtable.h against double inclusion > iommu/omap: Remove unused union fields > iommu/omap: Remove trailing semi-colon from a macro > iommu/omap: Remove unnecessary error traces on alloc failures > iommu/omap: Use BIT(x) macros in omap-iopgtable.h > iommu/omap: Use BIT(x) macros in omap-iommu.h > iommu/omap: Align code with open parenthesis Applied these patches to arm/omap. > iommu/omap: Split multiple assignments into separate lines Did not apply this one, there is nothing wrong with multiple assignments. Joerg ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH] of: iommu: Silence misleading warning
On Wed, Jul 22, 2015 at 06:47:00PM +0100, Robin Murphy wrote: > Printing "IOMMU is currently not supported for PCI" for every PCI device > probed on a DT-based system proves to be both irritatingly noisy and > confusing to users who have misinterpreted it to mean they can no longer > use VFIO device assignment. > > Since configuring DMA masks for PCI devices via of_dma_configure() has > not in fact changed anything with regard to IOMMUs there really is nothing > to warn about here; shut it up. > > Signed-off-by: Robin Murphy > --- > drivers/iommu/of_iommu.c | 8 +--- > 1 file changed, 5 insertions(+), 3 deletions(-) Applied, thanks. ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH] iommu: avoid format string leaks into iommu_device_create
On Fri, Jul 24, 2015 at 04:27:57PM -0700, Kees Cook wrote: > This makes sure it won't be possible to accidentally leak format > strings into iommu device names. Current name allocations are safe, > but this makes the "%s" explicit. > > Signed-off-by: Kees Cook > --- > drivers/iommu/dmar.c| 2 +- > drivers/iommu/intel-iommu.c | 2 +- > 2 files changed, 2 insertions(+), 2 deletions(-) Applied, thanks. ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH 2/2] iommu/vt-d: Report superpage support in sysfs
On Tue, Jul 14, 2015 at 03:25:04PM -0600, Alex Williamson wrote: > We already have the VT-d capability register printed raw, but it > typically involves a trip to the code or the spec to figure out > whether superpages are supported. Make this easier with "2M_pages" > and "1G_pages" sysfs entries that clearly report Y/N. > > Signed-off-by: Alex Williamson > --- > drivers/iommu/intel-iommu.c | 22 ++ > 1 file changed, 22 insertions(+) Can we make this a generic entry for all iommu types and export a pagesize bitmap instead? Joerg ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH 1/2] iommu/vt-d: Report domain usage in sysfs
On Tue, Jul 14, 2015 at 03:24:53PM -0600, Alex Williamson wrote: > Debugging domain ID leakage typically requires long running tests in > order to exhaust the domain ID space or kernel instrumentation to > track the setting and clearing of bits. A couple trivial intel-iommu > specific sysfs extensions make it much easier to expose the IOMMU > capabilities and current usage. > > Signed-off-by: Alex Williamson > --- > drivers/iommu/intel-iommu.c | 21 + > 1 file changed, 21 insertions(+) Applied, thanks Alex. ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH 2/2] iommu/vt-d: Report superpage support in sysfs
On Mon, 2015-08-03 at 16:30 +0200, Joerg Roedel wrote: > On Tue, Jul 14, 2015 at 03:25:04PM -0600, Alex Williamson wrote: > > We already have the VT-d capability register printed raw, but it > > typically involves a trip to the code or the spec to figure out > > whether superpages are supported. Make this easier with "2M_pages" > > and "1G_pages" sysfs entries that clearly report Y/N. > > > > Signed-off-by: Alex Williamson > > --- > > drivers/iommu/intel-iommu.c | 22 ++ > > 1 file changed, 22 insertions(+) > > Can we make this a generic entry for all iommu types and export a > pagesize bitmap instead? As long as we don't further entrench the current abomination of advertising all page sizes which are a multiple of 4KiB, which we do to work around KVM brain damage. I think I did manage to fix that once, with a patch that would abuse pg ->freelist when tearing down the mappings from KVM. Which ISTR was the main problem with fixing the API. I'll see if I can recover enough of my addled memory and revive that... -- David WoodhouseOpen Source Technology Centre david.woodho...@intel.com Intel Corporation smime.p7s Description: S/MIME cryptographic signature ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH 2/2] iommu/vt-d: Report superpage support in sysfs
On Mon, 2015-08-03 at 16:30 +0200, Joerg Roedel wrote: > On Tue, Jul 14, 2015 at 03:25:04PM -0600, Alex Williamson wrote: > > We already have the VT-d capability register printed raw, but it > > typically involves a trip to the code or the spec to figure out > > whether superpages are supported. Make this easier with "2M_pages" > > and "1G_pages" sysfs entries that clearly report Y/N. > > > > Signed-off-by: Alex Williamson > > --- > > drivers/iommu/intel-iommu.c | 22 ++ > > 1 file changed, 22 insertions(+) > > Can we make this a generic entry for all iommu types and export a > pagesize bitmap instead? Are you suggesting a bitmap in order to have a consistent interface, independently implemented by each IOMMU driver, or are you suggesting a common interface implemented by iommu_ops.pgsize_bitmap? The latter is pretty well broken already. It can't represent different IOMMU hardware units having different capabilities, and it's broken by drivers like intel-iommu that don't expose native hardware page sizes, but anything that can be broken down into native hardware page size, so ~(4k-1). Programatically, a bitmap is a concise way to expose multiple page sizes, but for human consumption, it's not an ideal solution. Thanks, Alex ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH] iommu/omap: Fix debug_read_tlb() to use seq_printf()
On Thu, Jul 23, 2015 at 02:26:19PM +0200, Salva Peiró wrote: > The debug_read_tlb() uses the sprintf() functions directly on the buffer > allocated by buf = kmalloc(count), without taking into account the size > of the buffer, with the consequence corrupting the heap, depending on > the count requested by the user. > > The patch fixes the issue replacing sprintf() by seq_printf(). > > Signed-off-by: Salva Peiró > --- > drivers/iommu/omap-iommu-debug.c | 26 +++--- > drivers/iommu/omap-iommu.c | 28 +++- > drivers/iommu/omap-iommu.h | 3 +-- > 3 files changed, 19 insertions(+), 38 deletions(-) Applied, thanks. I had to rebase it on top of Suman's changes, but that wasn't too hard. ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [RFC PATCH 0/1] iommu: Detach device from domain when removed from group
On Tue, Jul 28, 2015 at 07:55:55PM +0200, Gerald Schaefer wrote: > On s390, this eventually leads to a kernel panic when binding the device > again to its non-vfio PCI driver, because of the missing arch-specific > cleanup in detach_dev. On x86, the detach_dev callback will also not be > called directly, but there is a notifier that will catch > BUS_NOTIFY_REMOVED_DEVICE and eventually do the cleanup. Other > architectures w/o the notifier probably have at least some kind of memory > leak in this scenario, so a general fix would be nice. This notifier is not arch-specific, but registered against the bus the iommu-ops are set for. Why does it not run on s390? Joerg ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH 00/11] Some OMAP IOMMU cleanup patches
On 08/03/2015 08:55 AM, Joerg Roedel wrote: > On Mon, Jul 20, 2015 at 05:33:22PM -0500, Suman Anna wrote: >> Suman Anna (11): >> Documentation: dt: Add #iommu-cells info to OMAP iommu bindings >> iommu/omap: Remove all module references >> iommu/omap: Move debugfs functions to omap-iommu-debug.c >> iommu/omap: Protect omap-iopgtable.h against double inclusion >> iommu/omap: Remove unused union fields >> iommu/omap: Remove trailing semi-colon from a macro >> iommu/omap: Remove unnecessary error traces on alloc failures >> iommu/omap: Use BIT(x) macros in omap-iopgtable.h >> iommu/omap: Use BIT(x) macros in omap-iommu.h >> iommu/omap: Align code with open parenthesis > > Applied these patches to arm/omap. Thanks Joerg. > >> iommu/omap: Split multiple assignments into separate lines > > Did not apply this one, there is nothing wrong with multiple > assignments. Yeah, that was just to satisfy checkpatch --strict. regards Suman ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH 0/2] DRA7 DSP MMU config support
On Tue, Jul 21, 2015 at 06:55:34PM -0500, Suman Anna wrote: > The patches are baselined on 4.2-rc3 + the recent OMAP IOMMU > cleanup series [1]. I will post the DTS patches separately to > allow Tony to pick them up independently. >From the discussion it looks like some more work is necessary here. Before you repost, please also test on older omap hardware to make sure nothing breaks there. Please also describe the testing you did in the repost. Joerg ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH 0/2] DRA7 DSP MMU config support
On 08/03/2015 11:31 AM, Joerg Roedel wrote: > On Tue, Jul 21, 2015 at 06:55:34PM -0500, Suman Anna wrote: >> The patches are baselined on 4.2-rc3 + the recent OMAP IOMMU >> cleanup series [1]. I will post the DTS patches separately to >> allow Tony to pick them up independently. > > From the discussion it looks like some more work is necessary here. > Before you repost, please also test on older omap hardware to make sure > nothing breaks there. Please also describe the testing you did in the > repost. Yes, sure will do. I will repost once the next -rc1 is out. regards Suman ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH char-misc-next 10/19] lib: convert iova.c into a library
On Tue, Jul 28 2015 at 01:40:19 PM, Andrew Morton wrote: > On Mon, 27 Jul 2015 16:57:32 -0700 Ashutosh Dixit > wrote: > >> From: Harish Chegondi >> >> This patch converts iova.c into a library, moving it from >> drivers/iommu/ to lib/, and exports its virtual address allocation >> and management functions so that other modules can reuse them. > > From the following emails it is unclear to me whether we'll actually > be going ahead with this, but whatever. It's a chance to do some code > reading. Thanks for the review. Either us or the IOMMU team will submit a patch incorporating your suggestions. Ashutosh ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH char-misc-next 10/19] lib: convert iova.c into a library
From: Harish Chegondi This patch converts iova.c into a library, moving it from drivers/iommu/ to lib/, and exports its virtual address allocation and management functions so that other modules can reuse them. Cc: Joerg Roedel Reviewed-by: Anil S Keshavamurthy Reviewed-by: Sudeep Dutt Signed-off-by: Harish Chegondi --- drivers/iommu/Kconfig | 5 + drivers/iommu/Makefile| 1 - lib/Kconfig | 6 ++ lib/Makefile | 2 ++ {drivers/iommu => lib}/iova.c | 9 + 5 files changed, 18 insertions(+), 5 deletions(-) rename {drivers/iommu => lib}/iova.c (97%) diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index f1fb1d3..c711889 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -41,9 +41,6 @@ config IOMMU_IO_PGTABLE_LPAE_SELFTEST endmenu -config IOMMU_IOVA - bool - config OF_IOMMU def_bool y depends on OF && IOMMU_API @@ -125,8 +122,8 @@ config INTEL_IOMMU bool "Support for Intel IOMMU using DMA Remapping Devices" depends on PCI_MSI && ACPI && (X86 || IA64_GENERIC) select IOMMU_API - select IOMMU_IOVA select DMAR_TABLE + select IOVA help DMA remapping (DMAR) devices support enables independent address translations for Direct Memory Access (DMA) from devices. diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index c6dcc51..fbb1372 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -3,7 +3,6 @@ obj-$(CONFIG_IOMMU_API) += iommu-traces.o obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o obj-$(CONFIG_IOMMU_IO_PGTABLE_LPAE) += io-pgtable-arm.o -obj-$(CONFIG_IOMMU_IOVA) += iova.o obj-$(CONFIG_OF_IOMMU) += of_iommu.o obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o msm_iommu_dev.o obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o diff --git a/lib/Kconfig b/lib/Kconfig index 3a2ef67..62ba145 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -62,6 +62,12 @@ config ARCH_USE_CMPXCHG_LOCKREF config ARCH_HAS_FAST_MULTIPLIER bool +config IOVA + bool + help + This option enables a 64 bit virtual address allocation and management + library. + config CRC_CCITT tristate "CRC-CCITT functions" help diff --git a/lib/Makefile b/lib/Makefile index 6897b52..058722d 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -205,3 +205,5 @@ quiet_cmd_build_OID_registry = GEN $@ clean-files+= oid_registry_data.c obj-$(CONFIG_UCS2_STRING) += ucs2_string.o + +obj-$(CONFIG_IOVA) += iova.o diff --git a/drivers/iommu/iova.c b/lib/iova.c similarity index 97% rename from drivers/iommu/iova.c rename to lib/iova.c index b7c3d92..7753006 100644 --- a/drivers/iommu/iova.c +++ b/lib/iova.c @@ -72,6 +72,7 @@ init_iova_domain(struct iova_domain *iovad, unsigned long granule, iovad->start_pfn = start_pfn; iovad->dma_32bit_pfn = pfn_32bit; } +EXPORT_SYMBOL_GPL(init_iova_domain); static struct rb_node * __get_cached_rbnode(struct iova_domain *iovad, unsigned long *limit_pfn) @@ -281,6 +282,7 @@ alloc_iova(struct iova_domain *iovad, unsigned long size, return new_iova; } +EXPORT_SYMBOL_GPL(alloc_iova); /** * find_iova - find's an iova for a given pfn @@ -321,6 +323,7 @@ struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn) spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags); return NULL; } +EXPORT_SYMBOL_GPL(find_iova); /** * __free_iova - frees the given iova @@ -339,6 +342,7 @@ __free_iova(struct iova_domain *iovad, struct iova *iova) spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags); free_iova_mem(iova); } +EXPORT_SYMBOL_GPL(__free_iova); /** * free_iova - finds and frees the iova for a given pfn @@ -356,6 +360,7 @@ free_iova(struct iova_domain *iovad, unsigned long pfn) __free_iova(iovad, iova); } +EXPORT_SYMBOL_GPL(free_iova); /** * put_iova_domain - destroys the iova doamin @@ -378,6 +383,7 @@ void put_iova_domain(struct iova_domain *iovad) } spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags); } +EXPORT_SYMBOL_GPL(put_iova_domain); static int __is_range_overlap(struct rb_node *node, @@ -467,6 +473,7 @@ finish: spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags); return iova; } +EXPORT_SYMBOL_GPL(reserve_iova); /** * copy_reserved_iova - copies the reserved between domains @@ -493,6 +500,7 @@ copy_reserved_iova(struct iova_domain *from, struct iova_domain *to) } spin_unlock_irqrestore(&from->iova_rbtree_lock, flags); } +EXPORT_SYMBOL_GPL(copy_reserved_iova); struct iova * split_and_remove_iova(struct iova_domain *iovad, struct iova *iova, @@ -534,3 +542,4 @@ error: free_iova_mem(prev); return NULL; } +EXPORT_SYMBOL_GPL(split_and_remove_iova); -- 2.0.0.rc3.2.g998f840 ___
Re: [dm-devel] AMD-Vi IO_PAGE_FAULTs and ata3.00: failed command: READ FPDMA QUEUED errors since Linux 4.0
On Sun, 2 Aug 2015, Andreas Hartmann wrote: > On 08/01/2015 at 04:20 PM Andreas Hartmann wrote: > > On 07/28/2015 at 09:29 PM, Mike Snitzer wrote: > > [...] > >> Mikulas was saying to biect what is causing ATA to fail. > > > > Some good news and some bad news. The good news first: > > > > Your patchset > > > > f3396c58fd8442850e759843457d78b6ec3a9589, > > cf2f1abfbd0dba701f7f16ef619e4d2485de3366, > > 7145c241a1bf2841952c3e297c4080b357b3e52d, > > 94f5e0243c48aa01441c987743dc468e2d6eaca2, > > dc2676210c425ee8e5cb1bec5bc84d004ddf4179, > > 0f5d8e6ee758f7023e4353cca75d785b2d4f6abe, > > b3c5fd3052492f1b8d060799d4f18be5a5438add > > > > seems to work fine w/ 3.18.19 !! > > > > Why did I test it with 3.18.x now? Because I suddenly got two ata errors > > (ata1 and ata2) with clean 3.19.8 (w/o the AMD-Vi IO_PAGE_FAULTs) during > > normal operation. This means: 3.19 must already be broken, too. > > > > Therefore, I applied your patchset to 3.18.x and it seems to work like a > > charme - I don't get any AMD-Vi IO_PAGE_FAULTs on boot and no ata errors > > (until now). > > > > > > Next I did: I tried to bisect between 3.18 and 3.19 with your patchset > > applied, because w/ this patchset applied, the problem can be seen > > easily and directly on boot. Unfortunately, this does work only a few > > git bisect rounds until I got stuck because of interferences with your > > extra patches applied: > > [Resolved the problems written at the last post.] > > Bisecting ended here: > > https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=34b48db66e08ca1c1bc07cf305d672ac940268dc > > block: remove artifical max_hw_sectors cap > > > Removing this patch on 3.19 and 4.1 make things working again. Didn't > test 4.0, but I think it's the same. No more AMD-Vi IO_PAGE_FAULTS with > that patch reverted. > > > Please check why this patch triggers AMD-Vi IO_PAGE_FAULTS. > > > Thanks, > kind regards, > Andreas Hartmann I would submit this bug to maintainers of AMD-Vi. They understand the hardware, so they should tell why do large I/O requests result in IO_PAGE_FAULTs. It is probably bug either in AMD-Vi driver or in hardware. Mikulas ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH] iommu/arm-smmu-v2: ThunderX(errata-23399) mis-extends 64bit registers
From: Tirumalesh Chalamarla The SMMU architecture defines two different behaviors when 64-bit registers are written with 32-bit writes. The first behavior causes zero extension into the upper 32-bits. The second behavior splits a 64-bit register into "normal" 32-bit register pairs. On some passes of ThunderX, the following registers incorrectly zero extended when they should instead behave as normal 32-bit register pairs: SMMU()_(S)GFAR SMMU()_NSGFAR SMMU()_CB()_TTBR0 SMMU()_CB()_TTBR1 SMMU()_CB()_FAR Signed-off-by: Tirumalesh Chalamarla --- drivers/iommu/arm-smmu.c | 51 ++-- 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 66a803b..7a3cf7f 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -290,6 +290,7 @@ struct arm_smmu_device { u32 features; #define ARM_SMMU_OPT_SECURE_CFG_ACCESS (1 << 0) +#define ARM_SMMU_OPT_64BIT_WRITES_ONLY (1 << 1) u32 options; enum arm_smmu_arch_version version; @@ -351,6 +352,8 @@ struct arm_smmu_option_prop { static struct arm_smmu_option_prop arm_smmu_options[] = { { ARM_SMMU_OPT_SECURE_CFG_ACCESS, "calxeda,smmu-secure-config-access" }, + /* ThunderX errata 23399 */ + { ARM_SMMU_OPT_64BIT_WRITES_ONLY, "thunderx,smmu-64-bit-writes-only" }, { 0, NULL}, }; @@ -719,6 +722,7 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain, struct io_pgtable_cfg *pgtbl_cfg) { u32 reg; + u64 reg64; bool stage1; struct arm_smmu_cfg *cfg = &smmu_domain->cfg; struct arm_smmu_device *smmu = smmu_domain->smmu; @@ -762,22 +766,39 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain, /* TTBRs */ if (stage1) { - reg = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0]; - writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_LO); - reg = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0] >> 32; - reg |= ARM_SMMU_CB_ASID(cfg) << TTBRn_HI_ASID_SHIFT; - writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_HI); - - reg = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[1]; - writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR1_LO); - reg = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[1] >> 32; - reg |= ARM_SMMU_CB_ASID(cfg) << TTBRn_HI_ASID_SHIFT; - writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR1_HI); + if (smmu->options & ARM_SMMU_OPT_64BIT_WRITES_ONLY) { + reg64 = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0]; + reg64 |= ((u64) ARM_SMMU_CB_ASID(cfg)) << + (TTBRn_HI_ASID_SHIFT + 32); + writeq_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_LO); + + reg64 = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[1]; + reg64 |= ((u64)ARM_SMMU_CB_ASID(cfg)) << + (TTBRn_HI_ASID_SHIFT + 32); + writeq_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR1_LO); + } else { + reg = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0]; + writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_LO); + reg = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0] >> 32; + reg |= ARM_SMMU_CB_ASID(cfg) << TTBRn_HI_ASID_SHIFT; + writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_HI); + + reg = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[1]; + writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR1_LO); + reg = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[1] >> 32; + reg |= ARM_SMMU_CB_ASID(cfg) << TTBRn_HI_ASID_SHIFT; + writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR1_HI); + } } else { - reg = pgtbl_cfg->arm_lpae_s2_cfg.vttbr; - writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_LO); - reg = pgtbl_cfg->arm_lpae_s2_cfg.vttbr >> 32; - writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_HI); + if (smmu->options & ARM_SMMU_OPT_64BIT_WRITES_ONLY) { + reg64 = pgtbl_cfg->arm_lpae_s2_cfg.vttbr; + writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_LO); + } else { + reg = pgtbl_cfg->arm_lpae_s2_cfg.vttbr; + writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_LO); + reg = pgtbl_cfg->arm_lpae_s2_cfg.vttbr >> 32; + writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_HI); + } } /* TTBCR */ -- 2.1.0 ___ iommu mailing list iommu@lists.lin
Re: [RFC PATCH 0/1] iommu: Detach device from domain when removed from group
On Mon, 3 Aug 2015 17:48:55 +0200 Joerg Roedel wrote: > On Tue, Jul 28, 2015 at 07:55:55PM +0200, Gerald Schaefer wrote: > > On s390, this eventually leads to a kernel panic when binding the device > > again to its non-vfio PCI driver, because of the missing arch-specific > > cleanup in detach_dev. On x86, the detach_dev callback will also not be > > called directly, but there is a notifier that will catch > > BUS_NOTIFY_REMOVED_DEVICE and eventually do the cleanup. Other > > architectures w/o the notifier probably have at least some kind of memory > > leak in this scenario, so a general fix would be nice. > > This notifier is not arch-specific, but registered against the bus the > iommu-ops are set for. Why does it not run on s390? Adding the notifier would of course also work on s390 (and all other affected architectures). However, it seems that the "missing detach_dev" issue in this scenario is not fundamentally fixed by using this notifier, it just seems to hide the symptom by chance. Adding the otherwise unneeded notifier just to work around this issue somehow doesn't seem right, also given that x86 is so far the only user of it. At least I thought it would be cleaner to fix it in common code and for all architectures. Not sure what's wrong with fixing the asymmetry as suggested in my patch, but I guess there are good reasons for having this asymmetry. For now, I'll just add the notifier to my s390 implementation and post it soon. > > > Joerg > > -- > To unsubscribe from this list: send the line "unsubscribe linux-pci" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v5 2/3] arm64: Add IOMMU dma_ops
On Fri, Jul 31, 2015 at 06:18:28PM +0100, Robin Murphy wrote: > Taking some inspiration from the arch/arm code, implement the > arch-specific side of the DMA mapping ops using the new IOMMU-DMA layer. > > Unfortunately the device setup code has to start out as a big ugly mess > in order to work usefully right now, as 'proper' operation depends on > changes to device probe and DMA configuration ordering, IOMMU groups for > platform devices, and default domain support in arm/arm64 IOMMU drivers. > The workarounds here need only exist until that work is finished. > > Signed-off-by: Robin Murphy Reviewed-by: Catalin Marinas ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v5 1/3] iommu: Implement common IOMMU ops for DMA mapping
On Fri, Jul 31, 2015 at 06:18:27PM +0100, Robin Murphy wrote: > Taking inspiration from the existing arch/arm code, break out some > generic functions to interface the DMA-API to the IOMMU-API. This will > do the bulk of the heavy lifting for IOMMU-backed dma-mapping. > > Signed-off-by: Robin Murphy Acked-by: Catalin Marinas ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH 13/13] iommu/arm-smmu: Treat unknown OAS as 48-bit
Hello. On 08/03/2015 04:25 PM, Will Deacon wrote: A late change to the SMMUv3 architecture ensures that the OAS field will be monotonically increasing, so we can assume that an unknown OAS is at least 48-bit and use that, rather than fail the device probe. Signed-off-by: Will Deacon --- drivers/iommu/arm-smmu-v3.c | 7 +++ 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 15fb669282b4..a435e706226a 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -2528,12 +2528,11 @@ static int arm_smmu_device_probe(struct arm_smmu_device *smmu) case IDR5_OAS_44_BIT: smmu->oas = 44; break; + default: + dev_info(smmu->dev, + "unknown output address size. Truncating to 48-bit\n"); Please add a comment like /* FALLTHRU */ here. case IDR5_OAS_48_BIT: smmu->oas = 48; - break; - default: - dev_err(smmu->dev, "unknown output address size!\n"); - return -ENXIO; } /* Set the DMA mask for our table walker */ MBR, Sergei ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu