* [RFC/PATCH 0/3] IOMMU fault callback support
@ 2011-02-12 10:42 David Cohen
2011-02-12 10:42 ` [RFC/PATCH 1/3] OMAP: IOMMU: Add generic IOMMU errors code David Cohen
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: David Cohen @ 2011-02-12 10:42 UTC (permalink / raw)
To: Hiroshi.DOYU; +Cc: linux-omap, David Cohen
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(-)
^ permalink raw reply [flat|nested] 6+ messages in thread
* [RFC/PATCH 1/3] OMAP: IOMMU: Add generic IOMMU errors code
2011-02-12 10:42 [RFC/PATCH 0/3] IOMMU fault callback support David Cohen
@ 2011-02-12 10:42 ` David Cohen
2011-02-13 22:33 ` Varadarajan, Charulatha
2011-02-12 10:42 ` [RFC/PATCH 2/3] OMAP2+: IOMMU: change OMAP2+ error message to dev_dbg() David Cohen
2011-02-12 10:42 ` [RFC/PATCH 3/3] OMAP: IOMMU: add support to callback during fault handling David Cohen
2 siblings, 1 reply; 6+ messages in thread
From: David Cohen @ 2011-02-12 10:42 UTC (permalink / raw)
To: Hiroshi.DOYU; +Cc: linux-omap, David Cohen
Generic IOMMU errors code are necessary to handle errors on generic
layer.
Signed-off-by: David Cohen <dacohen@gmail.com>
---
arch/arm/plat-omap/include/plat/iommu.h | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/arch/arm/plat-omap/include/plat/iommu.h b/arch/arm/plat-omap/include/plat/iommu.h
index 69230d6..71f369d 100644
--- a/arch/arm/plat-omap/include/plat/iommu.h
+++ b/arch/arm/plat-omap/include/plat/iommu.h
@@ -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
--
1.7.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [RFC/PATCH 2/3] OMAP2+: IOMMU: change OMAP2+ error message to dev_dbg()
2011-02-12 10:42 [RFC/PATCH 0/3] IOMMU fault callback support David Cohen
2011-02-12 10:42 ` [RFC/PATCH 1/3] OMAP: IOMMU: Add generic IOMMU errors code David Cohen
@ 2011-02-12 10:42 ` David Cohen
2011-02-12 10:42 ` [RFC/PATCH 3/3] OMAP: IOMMU: add support to callback during fault handling David Cohen
2 siblings, 0 replies; 6+ messages in thread
From: David Cohen @ 2011-02-12 10:42 UTC (permalink / raw)
To: Hiroshi.DOYU; +Cc: linux-omap, David Cohen
IOMMU upper layer is already printing error message. OMAP2+ specific
layer may print error message only for debug purpose.
Signed-off-by: David Cohen <dacohen@gmail.com>
---
arch/arm/mach-omap2/iommu2.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-omap2/iommu2.c b/arch/arm/mach-omap2/iommu2.c
index 14ee686..641f54a 100644
--- a/arch/arm/mach-omap2/iommu2.c
+++ b/arch/arm/mach-omap2/iommu2.c
@@ -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))
--
1.7.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [RFC/PATCH 3/3] OMAP: IOMMU: add support to callback during fault handling
2011-02-12 10:42 [RFC/PATCH 0/3] IOMMU fault callback support David Cohen
2011-02-12 10:42 ` [RFC/PATCH 1/3] OMAP: IOMMU: Add generic IOMMU errors code David Cohen
2011-02-12 10:42 ` [RFC/PATCH 2/3] OMAP2+: IOMMU: change OMAP2+ error message to dev_dbg() David Cohen
@ 2011-02-12 10:42 ` David Cohen
2 siblings, 0 replies; 6+ messages in thread
From: David Cohen @ 2011-02-12 10:42 UTC (permalink / raw)
To: Hiroshi.DOYU; +Cc: linux-omap, 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.
Signed-off-by: David Cohen <dacohen@gmail.com>
---
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(-)
diff --git a/arch/arm/mach-omap2/iommu2.c b/arch/arm/mach-omap2/iommu2.c
index 641f54a..d3f7871 100644
--- a/arch/arm/mach-omap2/iommu2.c
+++ b/arch/arm/mach-omap2/iommu2.c
@@ -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;
diff --git a/arch/arm/plat-omap/include/plat/iommu.h b/arch/arm/plat-omap/include/plat/iommu.h
index 71f369d..9e8c104 100644
--- a/arch/arm/plat-omap/include/plat/iommu.h
+++ b/arch/arm/plat-omap/include/plat/iommu.h
@@ -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);
diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c
index f55f458..7761eab 100644
--- a/arch/arm/plat-omap/iommu.c
+++ b/arch/arm/plat-omap/iommu.c
@@ -163,9 +163,9 @@ static u32 get_iopte_attr(struct iotlb_entry *e)
return arch_iommu->get_pte_attr(e);
}
-static u32 iommu_report_fault(struct iommu *obj, u32 *da)
+static u32 iommu_report_fault(struct iommu *obj, u32 *da, u32 *iommu_errs)
{
- return arch_iommu->fault_isr(obj, da);
+ return arch_iommu->fault_isr(obj, da, iommu_errs);
}
static void iotlb_lock_get(struct iommu *obj, struct iotlb_lock *l)
@@ -780,7 +780,7 @@ static void iopgtable_clear_entry_all(struct iommu *obj)
*/
static irqreturn_t iommu_fault_handler(int irq, void *data)
{
- u32 stat, da;
+ u32 stat, da, errs;
u32 *iopgd, *iopte;
int err = -EIO;
struct iommu *obj = data;
@@ -796,11 +796,17 @@ static irqreturn_t iommu_fault_handler(int irq, void *data)
return IRQ_HANDLED;
clk_enable(obj->clk);
- stat = iommu_report_fault(obj, &da);
+ stat = iommu_report_fault(obj, &da, &errs);
clk_disable(obj->clk);
if (!stat)
return IRQ_HANDLED;
+ if (obj->fault_cb) {
+ obj->fault_cb(obj, da, errs, obj->fault_cb_priv);
+ /* No need to print error message as callback is called */
+ return IRQ_NONE;
+ }
+
iommu_disable(obj);
iopgd = iopgd_offset(obj, da);
@@ -917,6 +923,33 @@ void iommu_put(struct iommu *obj)
}
EXPORT_SYMBOL_GPL(iommu_put);
+int iommu_set_fault_callback(const char *name,
+ void (*fault_cb)(struct iommu *obj, u32 da,
+ u32 iommu_errs, void *priv),
+ void *fault_cb_priv)
+{
+ struct device *dev;
+ struct iommu *obj;
+
+ dev = driver_find_device(&omap_iommu_driver.driver, NULL, (void *)name,
+ device_match_by_alias);
+ if (!dev)
+ return -ENODEV;
+
+ obj = to_iommu(dev);
+ mutex_lock(&obj->iommu_lock);
+ if (obj->refcount != 0) {
+ mutex_unlock(&obj->iommu_lock);
+ return -EBUSY;
+ }
+ obj->fault_cb = fault_cb;
+ obj->fault_cb_priv = fault_cb_priv;
+ mutex_unlock(&obj->iommu_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(iommu_set_fault_callback);
+
/*
* OMAP Device MMU(IOMMU) detection
*/
--
1.7.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [RFC/PATCH 1/3] OMAP: IOMMU: Add generic IOMMU errors code
2011-02-12 10:42 ` [RFC/PATCH 1/3] OMAP: IOMMU: Add generic IOMMU errors code David Cohen
@ 2011-02-13 22:33 ` Varadarajan, Charulatha
2011-02-14 11:28 ` David Cohen
0 siblings, 1 reply; 6+ messages in thread
From: Varadarajan, Charulatha @ 2011-02-13 22:33 UTC (permalink / raw)
To: David Cohen; +Cc: Hiroshi.DOYU, linux-omap
On Sat, Feb 12, 2011 at 18:42, David Cohen <dacohen@gmail.com> wrote:
> Generic IOMMU errors code are necessary to handle errors on generic
> layer.
>
> Signed-off-by: David Cohen <dacohen@gmail.com>
> ---
> arch/arm/plat-omap/include/plat/iommu.h | 7 +++++++
> 1 files changed, 7 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/plat-omap/include/plat/iommu.h b/arch/arm/plat-omap/include/plat/iommu.h
> index 69230d6..71f369d 100644
> --- a/arch/arm/plat-omap/include/plat/iommu.h
> +++ b/arch/arm/plat-omap/include/plat/iommu.h
> @@ -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.
> +
> #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 majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [RFC/PATCH 1/3] OMAP: IOMMU: Add generic IOMMU errors code
2011-02-13 22:33 ` Varadarajan, Charulatha
@ 2011-02-14 11:28 ` David Cohen
0 siblings, 0 replies; 6+ messages in thread
From: David Cohen @ 2011-02-14 11:28 UTC (permalink / raw)
To: Varadarajan, Charulatha; +Cc: Hiroshi.DOYU, linux-omap
On Mon, Feb 14, 2011 at 12:33 AM, Varadarajan, Charulatha <charu@ti.com> wrote:
> On Sat, Feb 12, 2011 at 18:42, David Cohen <dacohen@gmail.com> wrote:
>> Generic IOMMU errors code are necessary to handle errors on generic
>> layer.
>>
>> Signed-off-by: David Cohen <dacohen@gmail.com>
>> ---
>> arch/arm/plat-omap/include/plat/iommu.h | 7 +++++++
>> 1 files changed, 7 insertions(+), 0 deletions(-)
>>
>> diff --git a/arch/arm/plat-omap/include/plat/iommu.h b/arch/arm/plat-omap/include/plat/iommu.h
>> index 69230d6..71f369d 100644
>> --- a/arch/arm/plat-omap/include/plat/iommu.h
>> +++ b/arch/arm/plat-omap/include/plat/iommu.h
>> @@ -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.
That's fine for me. I can merge patches 1 and 3.
Regards,
David
>
>> +
>> #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 majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2011-02-14 11:28 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-02-12 10:42 [RFC/PATCH 0/3] IOMMU fault callback support David Cohen
2011-02-12 10:42 ` [RFC/PATCH 1/3] OMAP: IOMMU: Add generic IOMMU errors code David Cohen
2011-02-13 22:33 ` Varadarajan, Charulatha
2011-02-14 11:28 ` David Cohen
2011-02-12 10:42 ` [RFC/PATCH 2/3] OMAP2+: IOMMU: change OMAP2+ error message to dev_dbg() David Cohen
2011-02-12 10:42 ` [RFC/PATCH 3/3] OMAP: IOMMU: add support to callback during fault handling David Cohen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox