Hi, > -----Original Message----- > From: Felipe Contreras [mailto:felipe.contreras@xxxxxxxxx] > Sent: Thursday, May 13, 2010 3:47 PM > To: linux-omap > Cc: Ramirez Luna, Omar; Guzman Lugo, Fernando; Hiroshi Doyu; Felipe > Contreras > Subject: [PATCH 1/2] dspbridge: deh: fix corruption on MMU fault > > ... 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); dump_dsp_stack is waiting DSP for dumping the stack, I don't think that you are getting the complete dump with this patch. Regards, Fernando. > 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