summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierre Peiffer <pierre.peiffer@stericsson.com>2011-07-11 17:39:11 +0200
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-05-22 11:06:56 +0200
commit5fbff99037bb14886591b7fc7876a3fe4dddace5 (patch)
tree37c691019188eef91adefa0782aa2e973bf3668f
parent0f47c95922e04bf0611ae81f24da470affd7d8cc (diff)
U8500 CM: protect driver against MMDSP corruption
The loadmap of the MMDSP components is stored in shared memory (DDR memory shared between ARM and MMDSP). In case of corruption of this memory by some MMDSP firmware, current parsing of this loadmap on ARM side may lead to a kernel Panic. This patch makes the driver tolerant against any corruption ST-Ericsson Linux next: - ST-Ericsson ID: 351745 ST-Ericsson FOSS-OUT ID: Trivial Signed-off-by: Pierre Peiffer <pierre.peiffer@stericsson.com>
-rw-r--r--drivers/staging/nmf-cm/cm/engine/component/inc/instance.h1
-rw-r--r--drivers/staging/nmf-cm/cm/engine/elf/inc/mmdsp-loadmap.h2
-rw-r--r--drivers/staging/nmf-cm/cm/engine/elf/src/mmdsp-debug.c221
-rw-r--r--drivers/staging/nmf-cm/cm/inc/cm_type.h3
4 files changed, 184 insertions, 43 deletions
diff --git a/drivers/staging/nmf-cm/cm/engine/component/inc/instance.h b/drivers/staging/nmf-cm/cm/engine/component/inc/instance.h
index 1bef76501de..9172d99db79 100644
--- a/drivers/staging/nmf-cm/cm/engine/component/inc/instance.h
+++ b/drivers/staging/nmf-cm/cm/engine/component/inc/instance.h
@@ -70,6 +70,7 @@ typedef struct t_component_instance {
t_cm_domain_id domainId; //!< Domain where the component has been installed
struct t_client_of_singleton *clientOfSingleton; //!< Client of singleton list
+ t_memory_handle loadMapHandle; // handle of allocated memory for the loadMap structure and name;
} t_component_instance;
t_component_template* cm_lookupTemplate(t_nmf_core_id dspId, t_dup_char str);
diff --git a/drivers/staging/nmf-cm/cm/engine/elf/inc/mmdsp-loadmap.h b/drivers/staging/nmf-cm/cm/engine/elf/inc/mmdsp-loadmap.h
index 78b00388802..bb65c0b1244 100644
--- a/drivers/staging/nmf-cm/cm/engine/elf/inc/mmdsp-loadmap.h
+++ b/drivers/staging/nmf-cm/cm/engine/elf/inc/mmdsp-loadmap.h
@@ -34,8 +34,6 @@ struct LoadMapItem
struct LoadMapItem* pNextItem;// Pointer on the next list item, NULL if last one.
void* pXROM; // Start address of XROM
void* pYROM; // Start address of YROM
-
- void* memHandle; // handle of allocated memory for this structure and name, local field not use by mmdsp
};
struct LoadMapHdr
diff --git a/drivers/staging/nmf-cm/cm/engine/elf/src/mmdsp-debug.c b/drivers/staging/nmf-cm/cm/engine/elf/src/mmdsp-debug.c
index 0853e2d25b5..8826e727970 100644
--- a/drivers/staging/nmf-cm/cm/engine/elf/src/mmdsp-debug.c
+++ b/drivers/staging/nmf-cm/cm/engine/elf/src/mmdsp-debug.c
@@ -10,12 +10,14 @@
#include <cm/engine/elf/inc/mmdsp.h>
#include <cm/engine/dsp/inc/semaphores_dsp.h>
#include <cm/engine/dsp/mmdsp/inc/mmdsp_hwp.h>
+#include <cm/engine/os_adaptation_layer/inc/os_adaptation_layer.h>
#include <cm/engine/power_mgt/inc/power.h>
#include <cm/engine/utils/inc/string.h>
#include <cm/engine/trace/inc/trace.h>
#include <cm/engine/memory/inc/domain.h>
+#include <cm/engine/component/inc/instance.h>
#include <cm/engine/component/inc/component_type.h>
#include <inc/nmf-limits.h>
@@ -24,6 +26,9 @@
static t_memory_handle headerHandle[NB_CORE_IDS] = {INVALID_MEMORY_HANDLE, };
static struct LoadMapHdr *headerAddresses[NB_CORE_IDS] = {0, };
static t_uint32 headerOffsets[NB_CORE_IDS] = {0, };
+static t_uint32 entryNumber[NB_CORE_IDS] = {0, };
+
+#define myoffsetof(TYPE, MEMBER) ((unsigned int) &((TYPE *)0)->MEMBER)
t_cm_error cm_DSPABI_AddLoadMap(
t_cm_domain_id domainId,
@@ -33,6 +38,8 @@ t_cm_error cm_DSPABI_AddLoadMap(
void *componentHandle)
{
t_nmf_core_id coreId = cm_DM_GetDomainCoreId(domainId);
+ int count=0;
+ struct LoadMapItem* curItem = NULL;
if (headerHandle[coreId] == 0) /* Create loadmap header */
{
@@ -85,20 +92,53 @@ t_cm_error cm_DSPABI_AddLoadMap(
pItem = (struct LoadMapItem*)cm_DSP_GetHostLogicalAddress(handle);
cm_DSP_GetDspAddress(handle, &dspentry);
+ count++;
+ entryNumber[coreId]++;
// Link this new loadmap with the previous one
if(headerAddresses[coreId]->pFirstItem == NULL)
headerAddresses[coreId]->pFirstItem = (struct LoadMapItem *)dspentry;
else
{
- struct LoadMapItem* curItem;
+ const t_dsp_desc* pDspDesc = cm_DSP_GetState(coreId);
+ t_uint32 endSegmentAddr = SDRAMMEM16_BASE_ADDR + pDspDesc->segments[SDRAM_DATA_USER].size / 2;
+ struct LoadMapItem* curItem, *prevItem = NULL;
+ t_uint32 curItemDspAdress;
+
+ if(
+ ((t_uint32)headerAddresses[coreId]->pFirstItem < SDRAMMEM16_BASE_ADDR) ||
+ ((t_uint32)headerAddresses[coreId]->pFirstItem > endSegmentAddr))
+ {
+ ERROR("Memory corruption in MMDSP: at data DSP address=%x or ARM address=%x\n",
+ headerOffsets[coreId], &headerAddresses[coreId]->pFirstItem, 0, 0, 0, 0);
- curItem = headerAddresses[coreId]->pFirstItem;
- curItem = (struct LoadMapItem*)(((t_uint32)curItem - headerOffsets[coreId]) * 2 + (t_uint32)headerAddresses[coreId]); // To ARM address
+ return CM_INVALID_DATA;
+ }
+ curItemDspAdress = (t_uint32)headerAddresses[coreId]->pFirstItem;
+ curItem = (struct LoadMapItem*)((curItemDspAdress - headerOffsets[coreId]) * 2 + (t_uint32)headerAddresses[coreId]); // To ARM address
+ count++;
while(curItem->pNextItem != NULL)
{
- curItem = curItem->pNextItem;
- curItem = (struct LoadMapItem*)(((t_uint32)curItem - headerOffsets[coreId]) * 2 + (t_uint32)headerAddresses[coreId]); // To ARM address
+ if(((t_uint32)curItem->pNextItem < SDRAMMEM16_BASE_ADDR) || ((t_uint32)curItem->pNextItem > endSegmentAddr))
+ {
+ if (prevItem == NULL)
+ ERROR("AddLoadMap: Memory corruption in MMDSP: at data DSP address=%x or ARM address=%x\n"
+ "Previou (first) component name %s<%s>\n",
+ curItemDspAdress + myoffsetof(struct LoadMapItem, pNextItem), &curItem->pNextItem,
+ curItem->pARMThis ? (char*)(((t_component_instance *)&curItem->pARMThis)->pathname) : "<null>",
+ curItem->pARMThis ? (char*)(((t_component_instance *)&curItem->pARMThis)->template->name) : "<null>", 0, 0);
+ else
+ ERROR("AddLoadMap: Memory corruption in MMDSP: at data DSP address=%x or ARM address=%x\n"
+ "Previous valid component name %s<%s>",
+ curItemDspAdress + myoffsetof(struct LoadMapItem, pNextItem), &curItem->pNextItem,
+ prevItem->pARMThis ? (char*)(((t_component_instance *)&prevItem->pARMThis)->pathname) : "<null>",
+ prevItem->pARMThis ? (char*)(((t_component_instance *)&prevItem->pARMThis)->template->name) : "<null>", 0, 0);
+ return CM_INVALID_DATA;
+ }
+ curItemDspAdress = (t_uint32)curItem->pNextItem;
+ prevItem = curItem;
+ curItem = (struct LoadMapItem*)((curItemDspAdress - headerOffsets[coreId]) * 2 + (t_uint32)headerAddresses[coreId]); // To ARM address
+ count++;
}
curItem->pNextItem = (struct LoadMapItem *)dspentry;
}
@@ -211,11 +251,16 @@ t_cm_error cm_DSPABI_AddLoadMap(
/*
* Set memory handle (not used externally)
*/
- pItem->memHandle = (void*)handle;
+ ((t_component_instance *)componentHandle)->loadMapHandle = handle;
}
OSAL_mb();
+ if (count != entryNumber[coreId]) {
+ ERROR("AddLoadMap: corrumption, number of component differs: count=%d, expected %d (last item @ %p)\n",
+ count, entryNumber[coreId], curItem, 0, 0, 0);
+ return CM_INVALID_DATA;
+ }
return CM_OK;
}
@@ -226,62 +271,158 @@ t_cm_error cm_DSPABI_RemoveLoadMap(
const char* localname,
void *componentHandle)
{
- struct LoadMapItem* curItem, **prevItemReference;
+ struct LoadMapItem **prevItemReference;
+ t_uint32 prevItemReferenceDspAddress, curItemDspAdress;
t_nmf_core_id coreId = cm_DM_GetDomainCoreId(domainId);
+ const t_dsp_desc* pDspDesc = cm_DSP_GetState(coreId);
+ t_uint32 endSegmentAddr = SDRAMMEM16_BASE_ADDR + pDspDesc->segments[SDRAM_DATA_USER].size / 2;
+ struct LoadMapItem* curItem = NULL;
CM_ASSERT (headerHandle[coreId] != INVALID_MEMORY_HANDLE);
/* parse list until we find this */
+ prevItemReferenceDspAddress = 0x2; // DSP address of load map head pointer
prevItemReference = &headerAddresses[coreId]->pFirstItem;
- curItem = *prevItemReference;
- while(curItem != NULL)
+ curItemDspAdress = (t_uint32)*prevItemReference;
+ while(curItemDspAdress != 0x0)
{
- curItem = (struct LoadMapItem*)(((t_uint32)curItem - headerOffsets[coreId]) * 2 + (t_uint32)headerAddresses[coreId]); // To ARM address
+ if((curItemDspAdress < SDRAMMEM16_BASE_ADDR) || (curItemDspAdress > endSegmentAddr))
+ {
+ ERROR("Memory corruption in MMDSP: at data DSP address=%x or ARM address=%x\n",
+ prevItemReferenceDspAddress, prevItemReference, 0, 0, 0, 0);
+
+ return CM_OK;
+ }
+
+ curItem = (struct LoadMapItem*)((curItemDspAdress - headerOffsets[coreId]) * 2 + (t_uint32)headerAddresses[coreId]); // To ARM address
if(curItem->pARMThis == componentHandle)
- break;
+ {
+ // Remove component from loadmap
- prevItemReference = &curItem->pNextItem;
- curItem = *prevItemReference;
- }
+ /* take local semaphore */
+ cm_DSP_SEM_Take(coreId,LOADMAP_SEMAPHORE_USE_NB);
+ /* remove element from list */
+ *prevItemReference = curItem->pNextItem;
- // Remove component from loadmap if founded
- if(curItem != NULL)
- {
- /* take local semaphore */
- cm_DSP_SEM_Take(coreId,LOADMAP_SEMAPHORE_USE_NB);
+ /* update nRevision field in header */
+ headerAddresses[coreId]->nRevision++;
- /* remove element from list */
- *prevItemReference = curItem->pNextItem;
+ /* If this is the last item, deallocate !!! */
+ if(headerAddresses[coreId]->pFirstItem == NULL)
+ {
+ // Deallocate memory
+ cm_DM_Free(headerHandle[coreId], TRUE);
+ headerHandle[coreId] = INVALID_MEMORY_HANDLE;
- /* update nRevision field in header */
- headerAddresses[coreId]->nRevision++;
+ //Register Header into XRAM:2
+ cm_DSP_WriteXRamWord(coreId, 2, 0);
+ }
- /* If this is the last item, deallocate !!! */
- if(headerAddresses[coreId]->pFirstItem == NULL)
- {
- // Deallocate memory
- cm_DM_Free(headerHandle[coreId], TRUE);
- headerHandle[coreId] = INVALID_MEMORY_HANDLE;
+ /* deallocate memory */
+ cm_DM_Free(((t_component_instance *)componentHandle)->loadMapHandle, TRUE);
- //Register Header into XRAM:2
- cm_DSP_WriteXRamWord(coreId, 2, 0);
+ /* be sure memory is updated before releasing local semaphore */
+ OSAL_mb();
+
+ /* release local semaphore */
+ cm_DSP_SEM_Give(coreId,LOADMAP_SEMAPHORE_USE_NB);
+
+ entryNumber[coreId]--;
+
+ return CM_OK;
}
- /* deallocate memory */
- cm_DM_Free((t_memory_handle)curItem->memHandle, TRUE);
+ prevItemReferenceDspAddress = curItemDspAdress + myoffsetof(struct LoadMapItem, pNextItem);
+ prevItemReference = &curItem->pNextItem;
+ curItemDspAdress = (t_uint32)*prevItemReference;
+ };
- /* be sure memory is updated before releasing local semaphore */
- OSAL_mb();
+ ERROR("Memory corruption in MMDSP: component not in LoadMap %s\n", localname, 0, 0, 0, 0, 0);
+
+ return CM_OK;
+}
+
+#if 0
+t_cm_error cm_DSPABI_CheckLoadMap_nolock(t_nmf_core_id coreId)
+{
+ int count=0;
+ static int dump = 5;
+ struct LoadMapItem* curItem = NULL;
+
+ if (!dump)
+ return CM_OK;
+ if (headerHandle[coreId] == 0) /* No load map yet */
+ return CM_OK;
- /* release local semaphore */
- cm_DSP_SEM_Give(coreId,LOADMAP_SEMAPHORE_USE_NB);
- }
- else
{
- ERROR("Component not in LoadMap %s, memory corruption????\n", localname, 0, 0, 0, 0, 0);
+ // No entry in loadmap
+ if(headerAddresses[coreId]->pFirstItem == NULL)
+ return CM_OK;
+
+ {
+ const t_dsp_desc* pDspDesc = cm_DSP_GetState(coreId);
+ t_uint32 endSegmentAddr = SDRAMMEM16_BASE_ADDR + pDspDesc->segments[SDRAM_DATA_USER].size / 2;
+ struct LoadMapItem *prevItem=NULL;
+ t_uint32 curItemDspAdress;
+
+ if (((t_uint32)headerAddresses[coreId]->pFirstItem < SDRAMMEM16_BASE_ADDR) ||
+ ((t_uint32)headerAddresses[coreId]->pFirstItem > endSegmentAddr))
+ {
+ ERROR("CheckLoadMap: Memory corruption in MMDSP at first item: at data DSP address=%x or ARM address=%x\n",
+ headerOffsets[coreId], &headerAddresses[coreId]->pFirstItem, 0, 0, 0, 0);
+ dump--;
+ return CM_INVALID_COMPONENT_HANDLE;
+ }
+ curItemDspAdress = (t_uint32)headerAddresses[coreId]->pFirstItem;
+ curItem = (struct LoadMapItem*)((curItemDspAdress - headerOffsets[coreId]) * 2 + (t_uint32)headerAddresses[coreId]);
+ count++;
+ while(curItem->pNextItem != NULL)
+ {
+ if(((t_uint32)curItem->pNextItem < SDRAMMEM16_BASE_ADDR) || ((t_uint32)curItem->pNextItem > endSegmentAddr))
+ {
+ if (!prevItem)
+ ERROR("CheckLoadMap: Memory corruption in MMDSP (count=%d): at data DSP address=%x or ARM address=%x\n"
+ "Previous (first) component name %s<%s>\n",
+ count,
+ curItemDspAdress + myoffsetof(struct LoadMapItem, pNextItem), &curItem->pNextItem,
+ (char*)(((t_component_instance *)&curItem->pARMThis)->pathname),
+ (char*)(((t_component_instance *)&curItem->pARMThis)->template->name), 0);
+ else
+ ERROR("CheckLoadMap: Memory corruption in MMDSP (count=%d): at data DSP address=%x or ARM address=%x\n"
+ "Previous valid component name %s<%s>",
+ count,
+ curItemDspAdress + myoffsetof(struct LoadMapItem, pNextItem), &curItem->pNextItem,
+ (char*)(((t_component_instance *)&prevItem->pARMThis)->pathname),
+ (char*)(((t_component_instance *)&prevItem->pARMThis)->template->name), 0);
+ dump--;
+ return CM_INVALID_COMPONENT_HANDLE;
+ }
+ curItemDspAdress = (t_uint32)curItem->pNextItem;
+ prevItem = curItem;
+ curItem = (struct LoadMapItem*)((curItemDspAdress - headerOffsets[coreId]) * 2 + (t_uint32)headerAddresses[coreId]); // To ARM address
+ count++;
+ }
+ }
+
}
+ if (count != entryNumber[coreId]) {
+ ERROR("CheckLoadMap: number of component differs: count=%d, expected %d (last item @ %p)\n", count, entryNumber[coreId],
+ curItem, 0, 0, 0);
+ dump--;
+ return CM_INVALID_COMPONENT_HANDLE;
+ }
return CM_OK;
}
+
+t_cm_error cm_DSPABI_CheckLoadMap(t_nmf_core_id coreId)
+{
+ t_cm_error error;
+ OSAL_LOCK_API();
+ error = cm_DSPABI_CheckLoadMap_nolock(coreId);
+ OSAL_UNLOCK_API();
+ return error;
+}
+#endif
diff --git a/drivers/staging/nmf-cm/cm/inc/cm_type.h b/drivers/staging/nmf-cm/cm/inc/cm_type.h
index b2f97090a3a..83a34ecd706 100644
--- a/drivers/staging/nmf-cm/cm/inc/cm_type.h
+++ b/drivers/staging/nmf-cm/cm/inc/cm_type.h
@@ -37,7 +37,7 @@ typedef t_nmf_error t_cm_error; //!<
/* tests/src/common/nte/src/nte.c */
/*********************************************************************************/
#define CM_LAST_ERROR_ID ((t_cm_error)-128)
-#define CM_INTEGRATION_ERROR NMF_INTEGRATION_ERROR0 //!< \ref NMF_INTEGRATION_ERROR0
+#define CM_INTEGRATION_ERROR NMF_INTEGRATION_ERROR0 //!< \ref NMF_INTEGRATION_ERROR0
/* Communication */
#define CM_FLUSH_MESSAGE NMF_FLUSH_MESSAGE //!< Message send after call to CM_FlushChannel()
@@ -107,6 +107,7 @@ typedef t_nmf_error t_cm_error; //!<
#define CM_PWR_NOT_AVAILABLE ((t_cm_error)-16) //!< No modification of the state of the power input
/* Common errors */
+#define CM_INVALID_DATA ((t_cm_error)-4) //!< Invalid internal data encountered
#define CM_OUT_OF_LIMITS ((t_cm_error)-3) //!< User reach an internal nmf limits of limits.h file
#define CM_INVALID_PARAMETER NMF_INVALID_PARAMETER //!< \ref NMF_INVALID_PARAMETER
#define CM_NOT_YET_IMPLEMENTED ((t_cm_error)-1) //!< CM API not yet implemented