From 6fe4162851b8f568533fd1ae3c1e62e5e296261c Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 29 Mar 2011 20:29:44 +0300 Subject: [PATCH] gpu: pvr: fix error path in MMU_Initialise Add missing frees / unmapping at various failure points. Reported-by: Coverity Signed-off-by: Imre Deak Reviewed-by: Pauli Nieminen --- pvr/mmu.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/pvr/mmu.c b/pvr/mmu.c index 0c68876..8fec04f 100644 --- a/pvr/mmu.c +++ b/pvr/mmu.c @@ -474,6 +474,7 @@ enum PVRSRV_ERROR MMU_Initialise(struct PVRSRV_DEVICE_NODE *psDeviceNode, void *pvPDCpuVAddr; struct IMG_DEV_PHYADDR sPDDevPAddr; struct IMG_CPU_PHYADDR sCpuPAddr; + struct IMG_SYS_PHYADDR sSysPAddr; struct MMU_CONTEXT *psMMUContext; void *hPDOSMemHandle; struct SYS_DATA *psSysData; @@ -508,7 +509,7 @@ enum PVRSRV_ERROR MMU_Initialise(struct PVRSRV_DEVICE_NODE *psDeviceNode, &hPDOSMemHandle) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "MMU_Initialise: " "ERROR call to OSAllocPages failed"); - return PVRSRV_ERROR_GENERIC; + goto err1; } if (pvPDCpuVAddr) @@ -518,14 +519,13 @@ enum PVRSRV_ERROR MMU_Initialise(struct PVRSRV_DEVICE_NODE *psDeviceNode, sPDDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr); } else { - struct IMG_SYS_PHYADDR sSysPAddr; - if (RA_Alloc(psDeviceNode->psLocalDevMemArena, SGX_MMU_PAGE_SIZE, NULL, 0, SGX_MMU_PAGE_SIZE, &(sSysPAddr.uiAddr)) != IMG_TRUE) { PVR_DPF(PVR_DBG_ERROR, "MMU_Initialise: " "ERROR call to RA_Alloc failed"); - return PVRSRV_ERROR_GENERIC; + + goto err1; } sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr); @@ -538,7 +538,8 @@ enum PVRSRV_ERROR MMU_Initialise(struct PVRSRV_DEVICE_NODE *psDeviceNode, if (!pvPDCpuVAddr) { PVR_DPF(PVR_DBG_ERROR, "MMU_Initialise: " "ERROR failed to map page tables"); - return PVRSRV_ERROR_GENERIC; + + goto err2; } } @@ -551,7 +552,7 @@ enum PVRSRV_ERROR MMU_Initialise(struct PVRSRV_DEVICE_NODE *psDeviceNode, } else { PVR_DPF(PVR_DBG_ERROR, "MMU_Initialise: pvPDCpuVAddr invalid"); - return PVRSRV_ERROR_GENERIC; + goto err3; } for (i = 0; i < SGX_MMU_PD_SIZE; i++) @@ -575,6 +576,24 @@ enum PVRSRV_ERROR MMU_Initialise(struct PVRSRV_DEVICE_NODE *psDeviceNode, return PVRSRV_OK; +err3: + if (psDeviceNode->psLocalDevMemArena) + OSUnMapPhysToLin((void __iomem __force *)pvPDCpuVAddr, + SGX_MMU_PAGE_SIZE, PVRSRV_HAP_WRITECOMBINE | + PVRSRV_HAP_KERNEL_ONLY, + hPDOSMemHandle); +err2: + if (!psDeviceNode->psLocalDevMemArena) + OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, + SGX_MMU_PAGE_SIZE, pvPDCpuVAddr, hPDOSMemHandle); + else + RA_Free(psDeviceNode->psLocalDevMemArena, + sSysPAddr.uiAddr, IMG_FALSE); +err1: + OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct MMU_CONTEXT), + psMMUContext, NULL); + + return PVRSRV_ERROR_GENERIC; } void MMU_Finalise(struct MMU_CONTEXT *psMMUContext) -- 2.39.2