[PATCH 1/2] dspbridge: deh: fix corruption on MMU fault

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



... by removing unnecessary fault handling.

>From the looks of it, when an MMU fault happens, the DSP wants us to
come up with the data that is supposed to be on the faulty address.
Clearly, there's no way to provide that information, and such errors are
fatal, so there's no point in allocating a buffer and mapping it.

Moreover, kmalloc() doesn't return paged memory, so if the DSP tries to
write to an unaligned buffer, memory corruption ensures.

Based on the analysis of Fernando Guzman Lugo and Deepak Chitriki:
http://article.gmane.org/gmane.linux.ports.arm.omap/34207

I tested a similar patch on Nokia custom hardware and memory corruption
was gone. I tested this particular patch on a beagleboard, and although
I was never able to reproduce the corruption, it didn't cause any
further problems.

Signed-off-by: Felipe Contreras <felipe.contreras@xxxxxxxxx>
---
 drivers/dsp/bridge/wmd/ue_deh.c |   28 ----------------------------
 1 files changed, 0 insertions(+), 28 deletions(-)

diff --git a/drivers/dsp/bridge/wmd/ue_deh.c b/drivers/dsp/bridge/wmd/ue_deh.c
index 03b29b6..233ad17 100644
--- a/drivers/dsp/bridge/wmd/ue_deh.c
+++ b/drivers/dsp/bridge/wmd/ue_deh.c
@@ -62,13 +62,6 @@
 /* Max time to check for GP Timer IRQ */
 #define GPTIMER_IRQ_WAIT_MAX_CNT       1000
 
-static struct hw_mmu_map_attrs_t map_attrs = { HW_LITTLE_ENDIAN,
-	HW_ELEM_SIZE16BIT,
-	HW_MMU_CPUES
-};
-
-static void *dummy_va_addr;
-
 static struct omap_dm_timer *timer;
 
 dsp_status bridge_deh_create(struct deh_mgr **ret_deh_mgr,
@@ -84,7 +77,6 @@ dsp_status bridge_deh_create(struct deh_mgr **ret_deh_mgr,
 	/* Get WMD context info. */
 	dev_get_wmd_context(hdev_obj, &hwmd_context);
 	DBC_ASSERT(hwmd_context);
-	dummy_va_addr = NULL;
 	/* Allocate IO manager object: */
 	deh_mgr = kzalloc(sizeof(struct deh_mgr), GFP_KERNEL);
 	if (!deh_mgr) {
@@ -190,12 +182,8 @@ dsp_status bridge_deh_register_notify(struct deh_mgr *deh_mgr, u32 event_mask,
 void bridge_deh_notify(struct deh_mgr *deh_mgr, u32 ulEventMask, u32 dwErrInfo)
 {
 	struct wmd_dev_context *dev_context;
-	dsp_status status = DSP_SOK;
-	u32 mem_physical = 0;
 	u32 hw_mmu_max_tlb_count = 31;
 	extern u32 fault_addr;
-	struct cfg_hostres *resources;
-	hw_status hw_status_obj;
 	u32 cnt = 0;
 
 	if (!deh_mgr)
@@ -203,7 +191,6 @@ void bridge_deh_notify(struct deh_mgr *deh_mgr, u32 ulEventMask, u32 dwErrInfo)
 
 	dev_info(bridge, "%s: device exception\n", __func__);
 	dev_context = (struct wmd_dev_context *)deh_mgr->hwmd_context;
-	resources = dev_context->resources;
 
 	switch (ulEventMask) {
 	case DSP_SYSERROR:
@@ -228,9 +215,6 @@ void bridge_deh_notify(struct deh_mgr *deh_mgr, u32 ulEventMask, u32 dwErrInfo)
 			(unsigned int) deh_mgr->err_info.dw_val1,
 			(unsigned int) deh_mgr->err_info.dw_val2,
 			(unsigned int) fault_addr);
-		dummy_va_addr = kzalloc(sizeof(char) * 0x1000, GFP_ATOMIC);
-		mem_physical =
-			ALIGN_DOWN(virt_to_phys(dummy_va_addr), PAGE_SIZE);
 		dev_context = (struct wmd_dev_context *)
 			deh_mgr->hwmd_context;
 
@@ -247,13 +231,6 @@ void bridge_deh_notify(struct deh_mgr *deh_mgr, u32 ulEventMask, u32 dwErrInfo)
 			dev_context->num_tlb_entries =
 				dev_context->fixed_tlb_entries;
 		}
-		if (DSP_SUCCEEDED(status)) {
-			hw_status_obj =
-				hw_mmu_tlb_add(resources->dw_dmmu_base,
-						mem_physical, fault_addr,
-						HW_PAGE_SIZE4KB, 1,
-						&map_attrs, HW_SET, HW_SET);
-		}
 
 		/*
 		 * Send a GP Timer interrupt to DSP.
@@ -286,9 +263,6 @@ void bridge_deh_notify(struct deh_mgr *deh_mgr, u32 ulEventMask, u32 dwErrInfo)
 			}
 		}
 
-		/* Clear MMU interrupt */
-		hw_mmu_event_ack(resources->dw_dmmu_base,
-				HW_MMU_TRANSLATION_FAULT);
 		dump_dsp_stack(deh_mgr->hwmd_context);
 		omap_dm_timer_disable(timer);
 		break;
@@ -356,6 +330,4 @@ dsp_status bridge_deh_get_info(struct deh_mgr *deh_mgr,
 
 void bridge_deh_release_dummy_mem(void)
 {
-	kfree(dummy_va_addr);
-	dummy_va_addr = NULL;
 }
-- 
1.7.1

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

[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux