diff mbox series

[v4,20/24] iommu/mediatek: Support report iova 34bit translation fault in ISR

Message ID 20201111123838.15682-21-yong.wu@mediatek.com (mailing list archive)
State New
Headers show
Series MT8192 IOMMU support | expand

Commit Message

Yong Wu Nov. 11, 2020, 12:38 p.m. UTC
If the iova is over 32bit, the fault status register bit is a little
different. Add a flag for the special register bits.

Signed-off-by: Yong Wu <yong.wu@mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

Comments

kernel test robot Nov. 18, 2020, 2:19 a.m. UTC | #1
Hi Yong,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on iommu/next]
[also build test ERROR on robh/for-next linus/master v5.10-rc4 next-20201117]
[cannot apply to mediatek/for-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Yong-Wu/MT8192-IOMMU-support/20201111-204421
base:   https://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git next
config: arm-randconfig-r003-20201117 (attached as .config)
compiler: arm-linux-gnueabi-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/2ac9ae3e1803f422950cdad221f033bb9ba9503d
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Yong-Wu/MT8192-IOMMU-support/20201111-204421
        git checkout 2ac9ae3e1803f422950cdad221f033bb9ba9503d
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arm 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   drivers/iommu/mtk_iommu.c: In function 'mtk_iommu_isr':
>> drivers/iommu/mtk_iommu.c:289:13: error: implicit declaration of function 'FIELD_GET'; did you mean 'FOLL_GET'? [-Werror=implicit-function-declaration]
     289 |   va34_32 = FIELD_GET(F_MMU_INVAL_VA_34_32_MASK, fault_iova);
         |             ^~~~~~~~~
         |             FOLL_GET
   cc1: some warnings being treated as errors

vim +289 drivers/iommu/mtk_iommu.c

   265	
   266	static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
   267	{
   268		struct mtk_iommu_data *data = dev_id;
   269		struct mtk_iommu_domain *dom = data->m4u_dom;
   270		unsigned int fault_larb, fault_port, sub_comm = 0;
   271		u32 int_state, regval, va34_32, pa34_32;
   272		u64 fault_iova, fault_pa;
   273		bool layer, write;
   274	
   275		/* Read error info from registers */
   276		int_state = readl_relaxed(data->base + REG_MMU_FAULT_ST1);
   277		if (int_state & F_REG_MMU0_FAULT_MASK) {
   278			regval = readl_relaxed(data->base + REG_MMU0_INT_ID);
   279			fault_iova = readl_relaxed(data->base + REG_MMU0_FAULT_VA);
   280			fault_pa = readl_relaxed(data->base + REG_MMU0_INVLD_PA);
   281		} else {
   282			regval = readl_relaxed(data->base + REG_MMU1_INT_ID);
   283			fault_iova = readl_relaxed(data->base + REG_MMU1_FAULT_VA);
   284			fault_pa = readl_relaxed(data->base + REG_MMU1_INVLD_PA);
   285		}
   286		layer = fault_iova & F_MMU_FAULT_VA_LAYER_BIT;
   287		write = fault_iova & F_MMU_FAULT_VA_WRITE_BIT;
   288		if (MTK_IOMMU_HAS_FLAG(data->plat_data, IOVA_34_EN)) {
 > 289			va34_32 = FIELD_GET(F_MMU_INVAL_VA_34_32_MASK, fault_iova);
   290			pa34_32 = FIELD_GET(F_MMU_INVAL_PA_34_32_MASK, fault_iova);
   291			fault_iova = fault_iova & F_MMU_INVAL_VA_31_12_MASK;
   292			fault_iova |=  (u64)va34_32 << 32;
   293			fault_pa |= (u64)pa34_32 << 32;
   294		}
   295	
   296		fault_port = F_MMU_INT_ID_PORT_ID(regval);
   297		if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_SUB_COMM)) {
   298			fault_larb = F_MMU_INT_ID_COMM_ID(regval);
   299			sub_comm = F_MMU_INT_ID_SUB_COMM_ID(regval);
   300		} else {
   301			fault_larb = F_MMU_INT_ID_LARB_ID(regval);
   302		}
   303		fault_larb = data->plat_data->larbid_remap[fault_larb][sub_comm];
   304	
   305		if (report_iommu_fault(&dom->domain, data->dev, fault_iova,
   306				       write ? IOMMU_FAULT_WRITE : IOMMU_FAULT_READ)) {
   307			dev_err_ratelimited(
   308				data->dev,
   309				"fault type=0x%x iova=0x%llx pa=0x%llx larb=%d port=%d layer=%d %s\n",
   310				int_state, fault_iova, fault_pa, fault_larb, fault_port,
   311				layer, write ? "write" : "read");
   312		}
   313	
   314		/* Interrupt clear */
   315		regval = readl_relaxed(data->base + REG_MMU_INT_CONTROL0);
   316		regval |= F_INT_CLR_BIT;
   317		writel_relaxed(regval, data->base + REG_MMU_INT_CONTROL0);
   318	
   319		mtk_iommu_tlb_flush_all(data);
   320	
   321		return IRQ_HANDLED;
   322	}
   323	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
kernel test robot Nov. 18, 2020, 4:32 a.m. UTC | #2
Hi Yong,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on iommu/next]
[also build test ERROR on robh/for-next linus/master v5.10-rc4 next-20201117]
[cannot apply to mediatek/for-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Yong-Wu/MT8192-IOMMU-support/20201111-204421
base:   https://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git next
config: powerpc64-randconfig-r005-20201117 (attached as .config)
compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project ace9653c11c6308401dcda2e8b26bf97e6e66e30)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install powerpc64 cross compiling tool for clang build
        # apt-get install binutils-powerpc64-linux-gnu
        # https://github.com/0day-ci/linux/commit/2ac9ae3e1803f422950cdad221f033bb9ba9503d
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Yong-Wu/MT8192-IOMMU-support/20201111-204421
        git checkout 2ac9ae3e1803f422950cdad221f033bb9ba9503d
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=powerpc64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

>> drivers/iommu/mtk_iommu.c:289:13: error: implicit declaration of function 'FIELD_GET' [-Werror,-Wimplicit-function-declaration]
                   va34_32 = FIELD_GET(F_MMU_INVAL_VA_34_32_MASK, fault_iova);
                             ^
   drivers/iommu/mtk_iommu.c:510:29: warning: result of comparison of constant 5368709120 with expression of type 'phys_addr_t' (aka 'unsigned int') is always false [-Wtautological-constant-out-of-range-compare]
           if (data->enable_4GB && pa >= MTK_IOMMU_4GB_MODE_REMAP_BASE)
                                   ~~ ^  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1 warning and 1 error generated.

vim +/FIELD_GET +289 drivers/iommu/mtk_iommu.c

   265	
   266	static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
   267	{
   268		struct mtk_iommu_data *data = dev_id;
   269		struct mtk_iommu_domain *dom = data->m4u_dom;
   270		unsigned int fault_larb, fault_port, sub_comm = 0;
   271		u32 int_state, regval, va34_32, pa34_32;
   272		u64 fault_iova, fault_pa;
   273		bool layer, write;
   274	
   275		/* Read error info from registers */
   276		int_state = readl_relaxed(data->base + REG_MMU_FAULT_ST1);
   277		if (int_state & F_REG_MMU0_FAULT_MASK) {
   278			regval = readl_relaxed(data->base + REG_MMU0_INT_ID);
   279			fault_iova = readl_relaxed(data->base + REG_MMU0_FAULT_VA);
   280			fault_pa = readl_relaxed(data->base + REG_MMU0_INVLD_PA);
   281		} else {
   282			regval = readl_relaxed(data->base + REG_MMU1_INT_ID);
   283			fault_iova = readl_relaxed(data->base + REG_MMU1_FAULT_VA);
   284			fault_pa = readl_relaxed(data->base + REG_MMU1_INVLD_PA);
   285		}
   286		layer = fault_iova & F_MMU_FAULT_VA_LAYER_BIT;
   287		write = fault_iova & F_MMU_FAULT_VA_WRITE_BIT;
   288		if (MTK_IOMMU_HAS_FLAG(data->plat_data, IOVA_34_EN)) {
 > 289			va34_32 = FIELD_GET(F_MMU_INVAL_VA_34_32_MASK, fault_iova);
   290			pa34_32 = FIELD_GET(F_MMU_INVAL_PA_34_32_MASK, fault_iova);
   291			fault_iova = fault_iova & F_MMU_INVAL_VA_31_12_MASK;
   292			fault_iova |=  (u64)va34_32 << 32;
   293			fault_pa |= (u64)pa34_32 << 32;
   294		}
   295	
   296		fault_port = F_MMU_INT_ID_PORT_ID(regval);
   297		if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_SUB_COMM)) {
   298			fault_larb = F_MMU_INT_ID_COMM_ID(regval);
   299			sub_comm = F_MMU_INT_ID_SUB_COMM_ID(regval);
   300		} else {
   301			fault_larb = F_MMU_INT_ID_LARB_ID(regval);
   302		}
   303		fault_larb = data->plat_data->larbid_remap[fault_larb][sub_comm];
   304	
   305		if (report_iommu_fault(&dom->domain, data->dev, fault_iova,
   306				       write ? IOMMU_FAULT_WRITE : IOMMU_FAULT_READ)) {
   307			dev_err_ratelimited(
   308				data->dev,
   309				"fault type=0x%x iova=0x%llx pa=0x%llx larb=%d port=%d layer=%d %s\n",
   310				int_state, fault_iova, fault_pa, fault_larb, fault_port,
   311				layer, write ? "write" : "read");
   312		}
   313	
   314		/* Interrupt clear */
   315		regval = readl_relaxed(data->base + REG_MMU_INT_CONTROL0);
   316		regval |= F_INT_CLR_BIT;
   317		writel_relaxed(regval, data->base + REG_MMU_INT_CONTROL0);
   318	
   319		mtk_iommu_tlb_flush_all(data);
   320	
   321		return IRQ_HANDLED;
   322	}
   323	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff mbox series

Patch

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 11af0780e4dd..fdf08e2d9ed5 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -89,6 +89,9 @@ 
 #define F_REG_MMU1_FAULT_MASK			GENMASK(13, 7)
 
 #define REG_MMU0_FAULT_VA			0x13c
+#define F_MMU_INVAL_VA_31_12_MASK		GENMASK(31, 12)
+#define F_MMU_INVAL_VA_34_32_MASK		GENMASK(11, 9)
+#define F_MMU_INVAL_PA_34_32_MASK		GENMASK(8, 6)
 #define F_MMU_FAULT_VA_WRITE_BIT		BIT(1)
 #define F_MMU_FAULT_VA_LAYER_BIT		BIT(0)
 
@@ -113,6 +116,7 @@ 
 #define HAS_SUB_COMM			BIT(5)
 #define WR_THROT_EN			BIT(6)
 #define HAS_LEGACY_IVRP_PADDR		BIT(7)
+#define IOVA_34_EN			BIT(8)
 
 #define MTK_IOMMU_HAS_FLAG(pdata, _x) \
 		((((pdata)->flags) & (_x)) == (_x))
@@ -263,8 +267,9 @@  static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
 {
 	struct mtk_iommu_data *data = dev_id;
 	struct mtk_iommu_domain *dom = data->m4u_dom;
-	u32 int_state, regval, fault_iova, fault_pa;
 	unsigned int fault_larb, fault_port, sub_comm = 0;
+	u32 int_state, regval, va34_32, pa34_32;
+	u64 fault_iova, fault_pa;
 	bool layer, write;
 
 	/* Read error info from registers */
@@ -280,6 +285,14 @@  static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
 	}
 	layer = fault_iova & F_MMU_FAULT_VA_LAYER_BIT;
 	write = fault_iova & F_MMU_FAULT_VA_WRITE_BIT;
+	if (MTK_IOMMU_HAS_FLAG(data->plat_data, IOVA_34_EN)) {
+		va34_32 = FIELD_GET(F_MMU_INVAL_VA_34_32_MASK, fault_iova);
+		pa34_32 = FIELD_GET(F_MMU_INVAL_PA_34_32_MASK, fault_iova);
+		fault_iova = fault_iova & F_MMU_INVAL_VA_31_12_MASK;
+		fault_iova |=  (u64)va34_32 << 32;
+		fault_pa |= (u64)pa34_32 << 32;
+	}
+
 	fault_port = F_MMU_INT_ID_PORT_ID(regval);
 	if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_SUB_COMM)) {
 		fault_larb = F_MMU_INT_ID_COMM_ID(regval);
@@ -293,7 +306,7 @@  static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
 			       write ? IOMMU_FAULT_WRITE : IOMMU_FAULT_READ)) {
 		dev_err_ratelimited(
 			data->dev,
-			"fault type=0x%x iova=0x%x pa=0x%x larb=%d port=%d layer=%d %s\n",
+			"fault type=0x%x iova=0x%llx pa=0x%llx larb=%d port=%d layer=%d %s\n",
 			int_state, fault_iova, fault_pa, fault_larb, fault_port,
 			layer, write ? "write" : "read");
 	}