Skip to contentSkip to conversation

IOMMU fault callback support

PATCH In review David Cohen 2 participants 6 messages Feb 12, 2011 – Feb 14, 2011

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

cover IOMMU fault callback support

Hi,

These are RFC patches. They're intended to add fault callback support so IOMMU users can debug or react when a fault happens.
IOMMU faults might be very difficult to reproduce and then to figure out the source of the problem. Currently IOMMU driver prints not so useful debug message and does not notice user about such issue.
With a fault callback, IOMMU user may debug much more useful information and/or react to go back to a valid state or, in worse cases, to leave device in a state where it's still possible to use it and proceed with some investigation.

Comments are welcome.

Br,

David
---

David Cohen (3):
OMAP: IOMMU: Add generic IOMMU errors code OMAP2+: IOMMU: change OMAP2+ error message to dev_dbg()
OMAP: IOMMU: add support to callback during fault handling

 arch/arm/mach-omap2/iommu2.c            |   23 ++++++++++++++---
 arch/arm/plat-omap/include/plat/iommu.h |   15 ++++++++++-
 arch/arm/plat-omap/iommu.c              |   41 ++++++++++++++++++++++++++++---
 3 files changed, 70 insertions(+), 9 deletions(-)
#1 lore raw

PATCH 1/3 OMAP: IOMMU: Add generic IOMMU errors code

Generic IOMMU errors code are necessary to handle errors on generic layer.

---
 arch/arm/plat-omap/include/plat/iommu.h |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)
arch/arm/plat-omap/include/plat/iommu.h +7 -0
index 69230d6..71f369d 100644
@@ -109,6 +109,13 @@ struct iommu_platform_data {
 	u32 da_end;
 };
 
+/* IOMMU errors */
+#define OMAP_IOMMU_ERR_TLB_MISS		(1 << 0)
+#define OMAP_IOMMU_ERR_TRANS_FAULT	(1 << 1)
+#define OMAP_IOMMU_ERR_EMU_MISS		(1 << 2)
+#define OMAP_IOMMU_ERR_TBLWALK_FAULT	(1 << 3)
+#define OMAP_IOMMU_ERR_MULTIHIT_FAULT	(1 << 4)
+
 #if defined(CONFIG_ARCH_OMAP1)
 #error "iommu for this processor not implemented yet"
 #else
Signature · 1 line
1.7.1
#2 lore raw

Re: [RFC/PATCH 1/3] OMAP: IOMMU: Add generic IOMMU errors code

Quoted 13 lines · David Cohen

Generic IOMMU errors code are necessary to handle errors on generic layer.

---
 arch/arm/plat-omap/include/plat/iommu.h |    7 +++++++

 1 files changed, 7 insertions(+), 0 deletions(-)
arch/arm/plat-omap/include/plat/iommu.h +0 -0
index 69230d6..71f369d 100644

arch/arm/plat-omap/include/plat/iommu.h struct iommu_platform_data { · line 117

Quoted 9 lines
arch/arm/plat-omap/include/plat/iommu.h +6 -0
@@ -109,6 +109,13 @@ struct iommu_platform_data {
        u32 da_end;
  };
 
+/* IOMMU errors */
+#define OMAP_IOMMU_ERR_TLB_MISS                (1 << 0)
+#define OMAP_IOMMU_ERR_TRANS_FAULT     (1 << 1)
+#define OMAP_IOMMU_ERR_EMU_MISS                (1 << 2)
+#define OMAP_IOMMU_ERR_TBLWALK_FAULT   (1 << 3)
+#define OMAP_IOMMU_ERR_MULTIHIT_FAULT  (1 << 4)

Define these macros in the patch where they are used.

Quoted 7 lines
arch/arm/plat-omap/include/plat/iommu.h +1 -1
+
  #if defined(CONFIG_ARCH_OMAP1)
  #error "iommu for this processor not implemented yet"
  #else
--

1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#3 lore raw

Re: [RFC/PATCH 1/3] OMAP: IOMMU: Add generic IOMMU errors code

Quoted 17 lines · Charulatha
Quoted 16 lines · David Cohen

Generic IOMMU errors code are necessary to handle errors on generic layer.

---
 arch/arm/plat-omap/include/plat/iommu.h |    7 +++++++

 1 files changed, 7 insertions(+), 0 deletions(-)
arch/arm/plat-omap/include/plat/iommu.h +0 -0
index 69230d6..71f369d 100644
@@ -109,6 +109,13 @@ struct iommu_platform_data {
        u32 da_end;
  };
 
Quoted 8 lines

arch/arm/plat-omap/include/plat/iommu.h struct iommu_platform_data { · line 117

Quoted 6 lines
arch/arm/plat-omap/include/plat/iommu.h +6 -0
+/* IOMMU errors */
+#define OMAP_IOMMU_ERR_TLB_MISS                (1 << 0)
+#define OMAP_IOMMU_ERR_TRANS_FAULT     (1 << 1)
+#define OMAP_IOMMU_ERR_EMU_MISS                (1 << 2)
+#define OMAP_IOMMU_ERR_TBLWALK_FAULT   (1 << 3)
+#define OMAP_IOMMU_ERR_MULTIHIT_FAULT  (1 << 4)

Define these macros in the patch where they are used.

That's fine for me. I can merge patches 1 and 3.

Regards,

David

Quoted 9 lines
Quoted 8 lines
arch/arm/plat-omap/include/plat/iommu.h +1 -1
+
  #if defined(CONFIG_ARCH_OMAP1)
  #error "iommu for this processor not implemented yet"
  #else
--

1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#4 lore raw

PATCH 2/3 OMAP2+: IOMMU: change OMAP2+ error message to dev_dbg()

In reply to David Cohen

IOMMU upper layer is already printing error message. OMAP2+ specific layer may print error message only for debug purpose.

---
 arch/arm/mach-omap2/iommu2.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
arch/arm/mach-omap2/iommu2.c +1 -1
index 14ee686..641f54a 100644
@@ -163,7 +163,7 @@ static u32 omap2_iommu_fault_isr(struct iommu *obj, u32 *ra)
 	da = iommu_read_reg(obj, MMU_FAULT_AD);
 	*ra = da;
 
-	dev_err(obj->dev, "%s:\tda:%08x ", __func__, da);
+	dev_dbg(obj->dev, "%s:\tda:%08x ", __func__, da);
 
 	for (i = 0; i < ARRAY_SIZE(err_msg); i++) {
 		if (stat & (1 << i))
Signature · 1 line
1.7.1
#5 lore raw

PATCH 3/3 OMAP: IOMMU: add support to callback during fault handling

In reply to David Cohen

Add support to register a callback for IOMMU fault situations. Drivers using IOMMU module might want to be informed when such errors happen in order to debug it or react.

---
 arch/arm/mach-omap2/iommu2.c            |   21 +++++++++++++--
 arch/arm/plat-omap/include/plat/iommu.h |    8 +++++-
 arch/arm/plat-omap/iommu.c              |   41 ++++++++++++++++++++++++++++---
 3 files changed, 62 insertions(+), 8 deletions(-)
arch/arm/mach-omap2/iommu2.c +18 -3
index 641f54a..d3f7871 100644
@@ -143,10 +143,10 @@ static void omap2_iommu_set_twl(struct iommu *obj, bool on)
 	__iommu_set_twl(obj, false);
 }
 
-static u32 omap2_iommu_fault_isr(struct iommu *obj, u32 *ra)
+static u32 omap2_iommu_fault_isr(struct iommu *obj, u32 *ra, u32 *iommu_errs)
 {
 	int i;
-	u32 stat, da;
+	u32 stat, da, errs;
 	const char *err_msg[] =	{
 		"tlb miss",
 		"translation fault",
@@ -157,8 +157,10 @@ static u32 omap2_iommu_fault_isr(struct iommu *obj, u32 *ra)
 
 	stat = iommu_read_reg(obj, MMU_IRQSTATUS);
 	stat &= MMU_IRQ_MASK;
-	if (!stat)
+	if (!stat) {
+		*iommu_errs = 0;
 		return 0;
+	}
 
 	da = iommu_read_reg(obj, MMU_FAULT_AD);
 	*ra = da;
@@ -171,6 +173,19 @@ static u32 omap2_iommu_fault_isr(struct iommu *obj, u32 *ra)
 	}
 	printk("\n");
 
+	errs = 0;
+	if (stat & MMU_IRQ_TLBMISS)
+		errs |= OMAP_IOMMU_ERR_TLB_MISS;
+	if (stat & MMU_IRQ_TRANSLATIONFAULT)
+		errs |= OMAP_IOMMU_ERR_TRANS_FAULT;
+	if (stat & MMU_IRQ_EMUMISS)
+		errs |= OMAP_IOMMU_ERR_EMU_MISS;
+	if (stat & MMU_IRQ_TABLEWALKFAULT)
+		errs |= OMAP_IOMMU_ERR_TBLWALK_FAULT;
+	if (stat & MMU_IRQ_MULTIHITFAULT)
+		errs |= OMAP_IOMMU_ERR_MULTIHIT_FAULT;
+	*iommu_errs = errs;
+
 	iommu_write_reg(obj, stat, MMU_IRQSTATUS);
 
 	return stat;
arch/arm/plat-omap/include/plat/iommu.h +7 -1
index 71f369d..9e8c104 100644
@@ -31,6 +31,7 @@ struct iommu {
 	struct clk	*clk;
 	void __iomem	*regbase;
 	struct device	*dev;
+	void		*fault_cb_priv;
 
 	unsigned int	refcount;
 	struct mutex	iommu_lock;	/* global for this whole object */
@@ -48,6 +49,7 @@ struct iommu {
 	struct mutex		mmap_lock; /* protect mmap */
 
 	int (*isr)(struct iommu *obj);
+	void (*fault_cb)(struct iommu *obj, u32 da, u32 iommu_errs, void *priv);
 
 	void *ctx; /* iommu context: registres saved area */
 	u32 da_start;
@@ -83,7 +85,7 @@ struct iommu_functions {
 	int (*enable)(struct iommu *obj);
 	void (*disable)(struct iommu *obj);
 	void (*set_twl)(struct iommu *obj, bool on);
-	u32 (*fault_isr)(struct iommu *obj, u32 *ra);
+	u32 (*fault_isr)(struct iommu *obj, u32 *ra, u32 *iommu_errs);
 
 	void (*tlb_read_cr)(struct iommu *obj, struct cr_regs *cr);
 	void (*tlb_load_cr)(struct iommu *obj, struct cr_regs *cr);
@@ -166,6 +168,10 @@ extern size_t iopgtable_clear_entry(struct iommu *obj, u32 iova);
 extern int iommu_set_da_range(struct iommu *obj, u32 start, u32 end);
 extern struct iommu *iommu_get(const char *name);
 extern void iommu_put(struct iommu *obj);
+extern int iommu_set_fault_callback(const char *name,
+				    void (*fault_cb)(struct iommu *obj, u32 da,
+						     u32 errs, void *priv),
+				    void *fault_cb_priv);
 
 extern void iommu_save_ctx(struct iommu *obj);
 extern void iommu_restore_ctx(struct iommu *obj);
arch/arm/plat-omap/iommu.c +37 -4

70 lines not on this page · raw message

Signature · 1 line
1.7.1