SDOCM00116544 Cache management for ARM speculative execution
authorRamsey Harris <ramsey@ti.com>
Wed, 20 May 2015 15:08:24 +0000 (08:08 -0700)
committerRobert Tivy <rtivy@ti.com>
Wed, 20 May 2015 23:40:05 +0000 (16:40 -0700)
The ARM Cortex-A15 processor performs speculative execution on
the instruction stream. This might pull unwanted data into the
cache. The ListMP module expects shared data to be absent from
the cache. However, when running on ARM, we cannot count on the
data to be absent from the cache. A cache invalidate operation
is required.

packages/ti/sdo/ipc/GateMP.c
packages/ti/sdo/ipc/ListMP.c
packages/ti/sdo/ipc/transports/TransportShm.c

index a3d90b3176280a0b38aaffe48d89e38f6183c0a0..ba60477bef570b2582359c1738039a0beedb8c49 100644 (file)
@@ -1367,7 +1367,7 @@ Void ti_sdo_ipc_GateMP_Instance_finalize(
 
     ti_sdo_ipc_GateMP_Handle *remoteHandles;
     UInt8 *inUseArray;
-    UInt numResources;
+    UInt size;
 
     /* Cannot call when numOpen is non-zero. */
     Assert_isTrue(obj->numOpens == 0, ti_sdo_ipc_GateMP_A_invalidDelete);
@@ -1406,7 +1406,7 @@ Void ti_sdo_ipc_GateMP_Instance_finalize(
 
             inUseArray = GateMP_module->remoteSystemInUse;
             remoteHandles = GateMP_module->remoteSystemGates;
-            numResources = GateMP_module->numRemoteSystem;
+            size = GateMP_module->numRemoteSystem * sizeof(UInt8);
             break;
 
         case GateMP_RemoteProtect_CUSTOM1:
@@ -1419,7 +1419,7 @@ Void ti_sdo_ipc_GateMP_Instance_finalize(
 
             inUseArray = GateMP_module->remoteCustom1InUse;
             remoteHandles = GateMP_module->remoteCustom1Gates;
-            numResources = GateMP_module->numRemoteCustom1;
+            size = GateMP_module->numRemoteCustom1 * sizeof(UInt8);
             break;
 
         case GateMP_RemoteProtect_CUSTOM2:
@@ -1432,7 +1432,7 @@ Void ti_sdo_ipc_GateMP_Instance_finalize(
 
             inUseArray = GateMP_module->remoteCustom2InUse;
             remoteHandles = GateMP_module->remoteCustom2Gates;
-            numResources = GateMP_module->numRemoteCustom2;
+            size = GateMP_module->numRemoteCustom2 * sizeof(UInt8);
             break;
         case GateMP_RemoteProtect_NONE:
             /*
@@ -1464,13 +1464,16 @@ Void ti_sdo_ipc_GateMP_Instance_finalize(
             systemKey = Hwi_disable();
         }
 
+#ifdef xdc_target__isaCompatible_v7A
+        /* ARM speculative execution might have pulled array into cache */
+        if (obj->cacheEnabled) {
+            Cache_inv(inUseArray, size, Cache_Type_ALL, TRUE);
+        }
+#endif
         /* update the GateMP resource tracker */
         inUseArray[obj->resourceId] = UNUSED;
         if (obj->cacheEnabled) {
-            Cache_wbInv(inUseArray,
-                        numResources * sizeof(UInt8),
-                        Cache_Type_ALL,
-                        TRUE);
+            Cache_wbInv(inUseArray, size, Cache_Type_ALL, TRUE);
         }
 
         if (GateMP_module->defaultGate != NULL) {
index 80bbafa820755fae69e01653715c82037d720090..4e89cf8e40cfea6d1010ecc758152815804521ec 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2014 Texas Instruments Incorporated - http://www.ti.com
+ * Copyright (c) 2012-2015 Texas Instruments Incorporated - http://www.ti.com
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -257,6 +257,7 @@ SizeT ListMP_sharedMemReq(const ListMP_Params *params)
 Bool ListMP_empty(ListMP_Handle handle)
 {
     ti_sdo_ipc_ListMP_Object *obj = (ti_sdo_ipc_ListMP_Object *)handle;
+    ti_sdo_ipc_ListMP_Attrs *attrs = obj->attrs;
     Bool flag = FALSE;
     IArg key;
     SharedRegion_SRPtr sharedHead;
@@ -264,25 +265,30 @@ Bool ListMP_empty(ListMP_Handle handle)
     /* prevent another thread or processor from modifying the ListMP */
     key = GateMP_enter((GateMP_Handle)obj->gate);
 
+#ifdef xdc_target__isaCompatible_v7A
+    /* ARM speculative execution might have pulled attrs into cache */
+    if (obj->cacheEnabled) {
+        Cache_inv(attrs, sizeof(ti_sdo_ipc_ListMP_Attrs), Cache_Type_ALL, TRUE);
+    }
+#endif
 
     if (ti_sdo_ipc_SharedRegion_translate == FALSE) {
         /* get the SRPtr for the head */
-        sharedHead = (SharedRegion_SRPtr)&(obj->attrs->head);
+        sharedHead = (SharedRegion_SRPtr)&(attrs->head);
     }
     else {
         /* get the SRPtr for the head */
-        sharedHead = SharedRegion_getSRPtr(&(obj->attrs->head), obj->regionId);
+        sharedHead = SharedRegion_getSRPtr(&(attrs->head), obj->regionId);
     }
 
     /* if 'next' is ourself, then the ListMP must be empty */
-    if (obj->attrs->head.next == sharedHead) {
+    if (attrs->head.next == sharedHead) {
         flag = TRUE;
     }
 
     if (obj->cacheEnabled) {
         /* invalidate the head to make sure we are not getting stale data */
-        Cache_inv(&(obj->attrs->head), sizeof(ListMP_Elem), Cache_Type_ALL,
-                  TRUE);
+        Cache_inv(&(attrs->head), sizeof(ListMP_Elem), Cache_Type_ALL, TRUE);
     }
 
     /* leave the gate */
@@ -307,6 +313,7 @@ GateMP_Handle ListMP_getGate(ListMP_Handle handle)
 Ptr ListMP_getHead(ListMP_Handle handle)
 {
     ti_sdo_ipc_ListMP_Object *obj = (ti_sdo_ipc_ListMP_Object *)handle;
+    ti_sdo_ipc_ListMP_Attrs *attrs = obj->attrs;
     ListMP_Elem *elem;
     ListMP_Elem *localHeadNext;
     ListMP_Elem *localNext;
@@ -316,18 +323,25 @@ Ptr ListMP_getHead(ListMP_Handle handle)
     /* prevent another thread or processor from modifying the ListMP */
     key = GateMP_enter((GateMP_Handle)obj->gate);
 
+#ifdef xdc_target__isaCompatible_v7A
+    /* ARM speculative execution might have pulled attrs into cache */
+    if (obj->cacheEnabled) {
+        Cache_inv(attrs, sizeof(ti_sdo_ipc_ListMP_Attrs), Cache_Type_ALL, TRUE);
+    }
+#endif
+
     if (ti_sdo_ipc_SharedRegion_translate == FALSE) {
-        localHeadNext = (ListMP_Elem *)obj->attrs->head.next;
+        localHeadNext = (ListMP_Elem *)attrs->head.next;
     }
     else {
-        localHeadNext = SharedRegion_getPtr(obj->attrs->head.next);
+        localHeadNext = SharedRegion_getPtr(attrs->head.next);
     }
 
     /* Assert that pointer is not NULL */
     Assert_isTrue(localHeadNext != NULL, ti_sdo_ipc_Ipc_A_nullPointer);
 
     /* See if the ListMP was empty */
-    if (localHeadNext == (ListMP_Elem *)(&(obj->attrs->head))) {
+    if (localHeadNext == (ListMP_Elem *)(&(attrs->head))) {
         /* Empty, return NULL */
         elem = NULL;
     }
@@ -356,7 +370,7 @@ Ptr ListMP_getHead(ListMP_Handle handle)
         }
 
         /* Fix the head of the list next pointer */
-        obj->attrs->head.next = elem->next;
+        attrs->head.next = elem->next;
 
         /* Fix the prev pointer of the new first elem on the list */
         localNext->prev = localHeadNext->prev;
@@ -366,8 +380,7 @@ Ptr ListMP_getHead(ListMP_Handle handle)
     }
 
     if (obj->cacheEnabled) {
-        Cache_wbInv(&(obj->attrs->head), sizeof(ListMP_Elem),
-                    Cache_Type_ALL, TRUE);
+        Cache_wbInv(&(attrs->head), sizeof(ListMP_Elem), Cache_Type_ALL, TRUE);
     }
 
     GateMP_leave((GateMP_Handle)obj->gate, key);
@@ -381,6 +394,7 @@ Ptr ListMP_getHead(ListMP_Handle handle)
 Ptr ListMP_getTail(ListMP_Handle handle)
 {
     ti_sdo_ipc_ListMP_Object *obj = (ti_sdo_ipc_ListMP_Object *)handle;
+    ti_sdo_ipc_ListMP_Attrs *attrs = obj->attrs;
     ListMP_Elem *elem;
     ListMP_Elem *localHeadPrev;
     ListMP_Elem *localPrev;
@@ -390,18 +404,25 @@ Ptr ListMP_getTail(ListMP_Handle handle)
     /* prevent another thread or processor from modifying the ListMP */
     key = GateMP_enter((GateMP_Handle)obj->gate);
 
+#ifdef xdc_target__isaCompatible_v7A
+    /* ARM speculative execution might have pulled attrs into cache */
+    if (obj->cacheEnabled) {
+        Cache_inv(attrs, sizeof(ti_sdo_ipc_ListMP_Attrs), Cache_Type_ALL, TRUE);
+    }
+#endif
+
     if (ti_sdo_ipc_SharedRegion_translate == FALSE) {
-        localHeadPrev = (ListMP_Elem *)obj->attrs->head.prev;
+        localHeadPrev = (ListMP_Elem *)attrs->head.prev;
     }
     else {
-        localHeadPrev = SharedRegion_getPtr(obj->attrs->head.prev);
+        localHeadPrev = SharedRegion_getPtr(attrs->head.prev);
     }
 
     /* Assert that pointer is not NULL */
     Assert_isTrue(localHeadPrev != NULL, ti_sdo_ipc_Ipc_A_nullPointer);
 
     /* See if the ListMP was empty */
-    if (localHeadPrev == (ListMP_Elem *)(&(obj->attrs->head))) {
+    if (localHeadPrev == (ListMP_Elem *)(&(attrs->head))) {
         /* Empty, return NULL */
         elem = NULL;
     }
@@ -430,7 +451,7 @@ Ptr ListMP_getTail(ListMP_Handle handle)
         }
 
         /* Fix the head of the list prev pointer */
-        obj->attrs->head.prev = elem->prev;
+        attrs->head.prev = elem->prev;
 
         /* Fix the next pointer of the new last elem on the list */
         localPrev->next = localHeadPrev->next;
@@ -440,8 +461,7 @@ Ptr ListMP_getTail(ListMP_Handle handle)
     }
 
     if (obj->cacheEnabled) {
-        Cache_wbInv(&(obj->attrs->head), sizeof(ListMP_Elem),
-                    Cache_Type_ALL, TRUE);
+        Cache_wbInv(&(attrs->head), sizeof(ListMP_Elem), Cache_Type_ALL, TRUE);
     }
 
     GateMP_leave((GateMP_Handle)obj->gate, key);
@@ -469,7 +489,6 @@ Int ListMP_insert(ListMP_Handle handle, ListMP_Elem *newElem,
     if (ti_sdo_ipc_SharedRegion_translate == FALSE) {
         sharedNewElem = (SharedRegion_SRPtr)newElem;
         sharedCurElem = (SharedRegion_SRPtr)curElem;
-        localPrevElem = (ListMP_Elem *)(curElem->prev);
     }
     else {
         /* get SRPtr for newElem */
@@ -537,7 +556,6 @@ Ptr ListMP_next(ListMP_Handle handle, ListMP_Elem *elem)
         /* Keep track of whether an extra Cache_inv is needed */
         elemIsCached = obj->cacheEnabled;
         elem = (ListMP_Elem *)&(obj->attrs->head);
-
     }
     else {
         elemIsCached = SharedRegion_isCacheEnabled(SharedRegion_getId(elem));
@@ -554,7 +572,7 @@ Ptr ListMP_next(ListMP_Handle handle, ListMP_Elem *elem)
     }
 
     if (elemIsCached) {
-        /* Invalidate because elem pulled into cache && elem != head. */
+        /* invalidate because elem pulled into cache */
         Cache_inv(elem, sizeof(ListMP_Elem), Cache_Type_ALL, TRUE);
     }
 
@@ -590,7 +608,7 @@ Ptr ListMP_prev(ListMP_Handle handle, ListMP_Elem *elem)
     }
 
     if (elemIsCached) {
-        /* Invalidate because elem pulled into cache && elem != head. */
+        /* invalidate because elem pulled into cache */
         Cache_inv(elem, sizeof(ListMP_Elem), Cache_Type_ALL, TRUE);
     }
 
@@ -603,6 +621,7 @@ Ptr ListMP_prev(ListMP_Handle handle, ListMP_Elem *elem)
 Int ListMP_putHead(ListMP_Handle handle, ListMP_Elem *elem)
 {
     ti_sdo_ipc_ListMP_Object *obj = (ti_sdo_ipc_ListMP_Object *)handle;
+    ti_sdo_ipc_ListMP_Attrs *attrs = obj->attrs;
     UInt key;
     UInt16 id;
     ListMP_Elem *localNextElem;
@@ -613,16 +632,23 @@ Int ListMP_putHead(ListMP_Handle handle, ListMP_Elem *elem)
     /* prevent another thread or processor from modifying the ListMP */
     key = GateMP_enter((GateMP_Handle)obj->gate);
 
+#ifdef xdc_target__isaCompatible_v7A
+    /* ARM speculative execution might have pulled attrs into cache */
+    if (obj->cacheEnabled) {
+        Cache_inv(attrs, sizeof(ti_sdo_ipc_ListMP_Attrs), Cache_Type_ALL, TRUE);
+    }
+#endif
+
     id = SharedRegion_getId(elem);
     if (ti_sdo_ipc_SharedRegion_translate == FALSE) {
         sharedElem = (SharedRegion_SRPtr)elem;
-        sharedHead = (SharedRegion_SRPtr)&(obj->attrs->head);
-        localNextElem = (ListMP_Elem *)obj->attrs->head.next;
+        sharedHead = (SharedRegion_SRPtr)&(attrs->head);
+        localNextElem = (ListMP_Elem *)attrs->head.next;
     }
     else {
         sharedElem = SharedRegion_getSRPtr(elem, id);
-        sharedHead = SharedRegion_getSRPtr(&(obj->attrs->head), obj->regionId);
-        localNextElem = SharedRegion_getPtr(obj->attrs->head.next);
+        sharedHead = SharedRegion_getSRPtr(&(attrs->head), obj->regionId);
+        localNextElem = SharedRegion_getPtr(attrs->head.next);
     }
 
     /* Assert that pointer is not NULL */
@@ -635,19 +661,18 @@ Int ListMP_putHead(ListMP_Handle handle, ListMP_Elem *elem)
     }
 
     /* add the new elem into the list */
-    elem->next = obj->attrs->head.next;
+    elem->next = attrs->head.next;
     elem->prev = sharedHead;
     localNextElem->prev = sharedElem;
-    obj->attrs->head.next = sharedElem;
+    attrs->head.next = sharedElem;
 
     if (localNextElemIsCached) {
         /* Write-back because localNextElem->prev changed */
         Cache_wbInv(localNextElem, sizeof(ListMP_Elem), Cache_Type_ALL, TRUE);
     }
     if (obj->cacheEnabled) {
-        /* Write-back because obj->attrs->head.next changed */
-        Cache_wbInv(&(obj->attrs->head), sizeof(ListMP_Elem), Cache_Type_ALL,
-                    TRUE);
+        /* Write-back because attrs->head.next changed */
+        Cache_wbInv(&(attrs->head), sizeof(ListMP_Elem), Cache_Type_ALL, TRUE);
     }
     if (SharedRegion_isCacheEnabled(id)) {
         /* Write-back because elem->next & elem->prev changed */
@@ -665,6 +690,7 @@ Int ListMP_putHead(ListMP_Handle handle, ListMP_Elem *elem)
 Int ListMP_putTail(ListMP_Handle handle, ListMP_Elem *elem)
 {
     ti_sdo_ipc_ListMP_Object *obj = (ti_sdo_ipc_ListMP_Object *)handle;
+    ti_sdo_ipc_ListMP_Attrs *attrs = obj->attrs;
     UInt key;
     UInt16  id;
     ListMP_Elem *localPrevElem;
@@ -675,16 +701,23 @@ Int ListMP_putTail(ListMP_Handle handle, ListMP_Elem *elem)
     /* prevent another thread or processor from modifying the ListMP */
     key = GateMP_enter((GateMP_Handle)obj->gate);
 
+#ifdef xdc_target__isaCompatible_v7A
+    /* ARM speculative execution might have pulled attrs into cache */
+    if (obj->cacheEnabled) {
+        Cache_inv(attrs, sizeof(ti_sdo_ipc_ListMP_Attrs), Cache_Type_ALL, TRUE);
+    }
+#endif
+
     id = SharedRegion_getId(elem);
     if (ti_sdo_ipc_SharedRegion_translate == FALSE) {
         sharedElem = (SharedRegion_SRPtr)elem;
-        sharedHead = (SharedRegion_SRPtr)&(obj->attrs->head);
-        localPrevElem = (ListMP_Elem *)obj->attrs->head.prev;
+        sharedHead = (SharedRegion_SRPtr)&(attrs->head);
+        localPrevElem = (ListMP_Elem *)attrs->head.prev;
     }
     else {
         sharedElem = SharedRegion_getSRPtr(elem, id);
-        sharedHead = SharedRegion_getSRPtr(&(obj->attrs->head), obj->regionId);
-        localPrevElem = SharedRegion_getPtr(obj->attrs->head.prev);
+        sharedHead = SharedRegion_getSRPtr(&(attrs->head), obj->regionId);
+        localPrevElem = SharedRegion_getPtr(attrs->head.prev);
     }
 
     /* Assert that pointer is not NULL */
@@ -698,18 +731,17 @@ Int ListMP_putTail(ListMP_Handle handle, ListMP_Elem *elem)
 
     /* add the new elem into the list */
     elem->next = sharedHead;
-    elem->prev = obj->attrs->head.prev;
+    elem->prev = attrs->head.prev;
     localPrevElem->next = sharedElem;
-    obj->attrs->head.prev = sharedElem;
+    attrs->head.prev = sharedElem;
 
     if (localPrevElemIsCached) {
         /* Write-back because localPrevElem->next changed */
         Cache_wbInv(localPrevElem, sizeof(ListMP_Elem), Cache_Type_ALL, TRUE);
     }
     if (obj->cacheEnabled) {
-        /* Write-back because obj->attrs->head.prev changed */
-        Cache_wbInv(&(obj->attrs->head), sizeof(ListMP_Elem), Cache_Type_ALL,
-                TRUE);
+        /* Write-back because attrs->head.prev changed */
+        Cache_wbInv(&(attrs->head), sizeof(ListMP_Elem), Cache_Type_ALL, TRUE);
     }
     if (SharedRegion_isCacheEnabled(id)) {
         /* Write-back because elem->next & elem->prev changed */
@@ -798,6 +830,13 @@ Int ti_sdo_ipc_ListMP_Instance_init(ti_sdo_ipc_ListMP_Object *obj,
         obj->cacheEnabled = SharedRegion_isCacheEnabled(obj->regionId);
         obj->cacheLineSize = SharedRegion_getCacheLineSize(obj->regionId);
 
+#ifdef xdc_target__isaCompatible_v7A
+    /* ARM speculative execution might have pulled attrs into cache */
+    if (obj->cacheEnabled) {
+        Cache_inv(obj->attrs, sizeof(ti_sdo_ipc_ListMP_Attrs), Cache_Type_ALL,
+                TRUE);
+    }
+#endif
         /* get the local address of the SRPtr */
         localAddr = SharedRegion_getPtr(obj->attrs->gateMPAddr);
 
index b53b1b977b2e8814be27804bc4f2c7091ca6815d..75d3ad41dc5c4b63d6284ef10cc01eede1871f46 100644 (file)
@@ -104,13 +104,6 @@ Void TransportShm_swiFxn(UArg arg)
         /* put the message to the destination queue */
         MessageQ_put(queueId, msg);
 
-#if defined(gnu_targets_STD_) && defined (xdc_target__isaCompatible_v7A)
-        __asm__ __volatile__ (
-            "dmb"
-            ::: "memory"
-        );
-#endif
-
         /* check to see if there are more messages */
         msg = (MessageQ_Msg)ListMP_getHead((ListMP_Handle)obj->localList);
     }