From patchwork Mon Feb 8 20:25:40 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ameya Palande X-Patchwork-Id: 77843 X-Patchwork-Delegate: omar.ramirez@ti.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o18KQQUv018046 for ; Mon, 8 Feb 2010 20:26:26 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754864Ab0BHU0X (ORCPT ); Mon, 8 Feb 2010 15:26:23 -0500 Received: from smtp.nokia.com ([192.100.122.233]:41987 "EHLO mgw-mx06.nokia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752676Ab0BHU0W (ORCPT ); Mon, 8 Feb 2010 15:26:22 -0500 Received: from esebh105.NOE.Nokia.com (esebh105.ntc.nokia.com [172.21.138.211]) by mgw-mx06.nokia.com (Switch-3.3.3/Switch-3.3.3) with ESMTP id o18KQ5TL024232; Mon, 8 Feb 2010 22:26:14 +0200 Received: from vaebh104.NOE.Nokia.com ([10.160.244.30]) by esebh105.NOE.Nokia.com with Microsoft SMTPSVC(6.0.3790.3959); Mon, 8 Feb 2010 22:26:13 +0200 Received: from mgw-da02.ext.nokia.com ([147.243.128.26]) by vaebh104.NOE.Nokia.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.3959); Mon, 8 Feb 2010 22:26:09 +0200 Received: from localhost.localdomain (esdhcp041197.research.nokia.com [172.21.41.197]) by mgw-da02.ext.nokia.com (Switch-3.3.3/Switch-3.3.3) with ESMTP id o18KQ4YJ021343; Mon, 8 Feb 2010 22:26:05 +0200 From: Ameya Palande To: linux-omap@vger.kernel.org Cc: omar.ramirez@ti.com, nm@ti.com, deepak.chitriki@ti.com, felipe.contreras@nokia.com, ext-phil.2.carmody@nokia.com Subject: [PATCH] DSPBRIDGE: Prevent memory corruption in DRV_ProcFreeDMMRes Date: Mon, 8 Feb 2010 22:25:40 +0200 Message-Id: <441be695a293805f9de42ad5ce5bf6bca21434fc.1265660264.git.ameya.palande@nokia.com> X-Mailer: git-send-email 1.6.3.3 X-OriginalArrivalTime: 08 Feb 2010 20:26:10.0283 (UTC) FILETIME=[F36ECBB0:01CAA8FC] X-Nokia-AV: Clean Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Mon, 08 Feb 2010 20:26:26 +0000 (UTC) diff --git a/arch/arm/plat-omap/include/dspbridge/drv.h b/arch/arm/plat-omap/include/dspbridge/drv.h index b6a5fd2..ba11359 100644 --- a/arch/arm/plat-omap/include/dspbridge/drv.h +++ b/arch/arm/plat-omap/include/dspbridge/drv.h @@ -384,18 +384,4 @@ struct PROCESS_CONTEXT{ */ extern DSP_STATUS DRV_ReleaseResources(IN u32 dwContext, struct DRV_OBJECT *hDrvObject); - -/* - * ======== DRV_ProcFreeDMMRes ======== - * Purpose: - * Actual DMM De-Allocation. - * Parameters: - * hPCtxt: Path to the driver Registry Key. - * Returns: - * DSP_SOK if success; - */ - - - extern DSP_STATUS DRV_ProcFreeDMMRes(HANDLE hPCtxt); - #endif /* DRV_ */ diff --git a/arch/arm/plat-omap/include/dspbridge/resourcecleanup.h b/arch/arm/plat-omap/include/dspbridge/resourcecleanup.h index ffbcf5e..d399a2e 100644 --- a/arch/arm/plat-omap/include/dspbridge/resourcecleanup.h +++ b/arch/arm/plat-omap/include/dspbridge/resourcecleanup.h @@ -25,13 +25,13 @@ extern DSP_STATUS DRV_GetProcCtxtList(struct PROCESS_CONTEXT **pPctxt, extern DSP_STATUS DRV_InsertProcContext(struct DRV_OBJECT *hDrVObject, HANDLE hPCtxt); -extern DSP_STATUS DRV_RemoveAllDMMResElements(HANDLE pCtxt); +extern DSP_STATUS DRV_Remove_All_DMM_Res_Elements(HANDLE hPCtxt); extern DSP_STATUS DRV_RemoveAllNodeResElements(HANDLE pCtxt); extern DSP_STATUS DRV_ProcSetPID(HANDLE pCtxt, s32 hProcess); -extern DSP_STATUS DRV_RemoveAllResources(HANDLE pPctxt); +extern void DRV_RemoveAllResources(HANDLE pPctxt); extern DSP_STATUS DRV_RemoveProcContext(struct DRV_OBJECT *hDRVObject, HANDLE pr_ctxt); diff --git a/drivers/dsp/bridge/rmgr/drv.c b/drivers/dsp/bridge/rmgr/drv.c index eca46ca..570f8a4 100644 --- a/drivers/dsp/bridge/rmgr/drv.c +++ b/drivers/dsp/bridge/rmgr/drv.c @@ -259,52 +259,39 @@ DSP_STATUS DRV_UpdateDMMResElement(HANDLE hDMMRes, u32 pMpuAddr, u32 ulSize, return status; } -/* Actual DMM De-Allocation */ -DSP_STATUS DRV_ProcFreeDMMRes(HANDLE hPCtxt) +/* Release all DMM resources and its context */ +DSP_STATUS DRV_Remove_All_DMM_Res_Elements(HANDLE hPCtxt) { - struct PROCESS_CONTEXT *pCtxt = (struct PROCESS_CONTEXT *)hPCtxt; + struct PROCESS_CONTEXT *p_ctxt = (struct PROCESS_CONTEXT *)hPCtxt; DSP_STATUS status = DSP_SOK; - struct DMM_RES_OBJECT *pDMMList = pCtxt->pDMMList; - struct DMM_RES_OBJECT *pDMMRes = NULL; - - GT_0trace(curTrace, GT_ENTER, "\nDRV_ProcFreeDMMRes: 1\n"); - while (pDMMList != NULL) { - pDMMRes = pDMMList; - pDMMList = pDMMList->next; - if (pDMMRes->dmmAllocated) { - status = PROC_UnMap(pDMMRes->hProcessor, - (void *)pDMMRes->ulDSPResAddr, pCtxt); + struct DMM_RES_OBJECT *p_dmm_list = p_ctxt->pDMMList; + struct DMM_RES_OBJECT *p_cur_res; + + while (p_dmm_list) { + p_cur_res = p_dmm_list; + p_dmm_list = p_dmm_list->next; + if (p_cur_res->dmmAllocated) { + /* + * PROC_UnMap will free memory allocated to p_cur_res + * pointer. So we need to save following data for the + * execution of PROC_UnReserveMemory() + */ + void *h_processor = p_cur_res->hProcessor; + u32 dsp_res_addr = p_cur_res->ulDSPResAddr; + + status = PROC_UnMap(p_cur_res->hProcessor, + (void *)p_cur_res->ulDSPAddr, p_ctxt); if (DSP_FAILED(status)) pr_debug("%s: PROC_UnMap failed! status =" - " 0x%xn", __func__, status); - status = PROC_UnReserveMemory(pDMMRes->hProcessor, - (void *)pDMMRes->ulDSPResAddr); + " 0x%x\n", __func__, status); + status = PROC_UnReserveMemory(h_processor, + (void *)dsp_res_addr); if (DSP_FAILED(status)) pr_debug("%s: PROC_UnReserveMemory failed!" - " status = 0x%xn", __func__, status); - pDMMRes->dmmAllocated = 0; + " status = 0x%x\n", __func__, status); } } - return status; -} - -/* Release all DMM resources and its context -* This is called from .bridge_release. */ -DSP_STATUS DRV_RemoveAllDMMResElements(HANDLE hPCtxt) -{ - struct PROCESS_CONTEXT *pCtxt = (struct PROCESS_CONTEXT *)hPCtxt; - DSP_STATUS status = DSP_SOK; - struct DMM_RES_OBJECT *pTempDMMRes2 = NULL; - struct DMM_RES_OBJECT *pTempDMMRes = NULL; - - DRV_ProcFreeDMMRes(pCtxt); - pTempDMMRes = pCtxt->pDMMList; - while (pTempDMMRes != NULL) { - pTempDMMRes2 = pTempDMMRes; - pTempDMMRes = pTempDMMRes->next; - MEM_Free(pTempDMMRes2); - } - pCtxt->pDMMList = NULL; + p_ctxt->pDMMList = NULL; return status; } diff --git a/drivers/dsp/bridge/rmgr/drv_interface.c b/drivers/dsp/bridge/rmgr/drv_interface.c index 625f88e..2e56704 100644 --- a/drivers/dsp/bridge/rmgr/drv_interface.c +++ b/drivers/dsp/bridge/rmgr/drv_interface.c @@ -604,15 +604,14 @@ static int bridge_mmap(struct file *filp, struct vm_area_struct *vma) /* To remove all process resources before removing the process from the * process context list*/ -DSP_STATUS DRV_RemoveAllResources(HANDLE hPCtxt) +void DRV_RemoveAllResources(HANDLE hPCtxt) { - DSP_STATUS status = DSP_SOK; struct PROCESS_CONTEXT *pCtxt = (struct PROCESS_CONTEXT *)hPCtxt; DRV_RemoveAllSTRMResElements(pCtxt); DRV_RemoveAllNodeResElements(pCtxt); - DRV_RemoveAllDMMResElements(pCtxt); + DRV_Remove_All_DMM_Res_Elements(pCtxt); pCtxt->resState = PROC_RES_FREED; - return status; + return; } /* Bridge driver initialization and de-initialization functions */