Added policy permission to exclude resource ranges from UNSPECIFIED base allocation...
authorJustin Sobota <jsobota@ti.com>
Wed, 1 Jul 2015 21:31:52 +0000 (17:31 -0400)
committerJustin Sobota <jsobota@ti.com>
Wed, 1 Jul 2015 21:31:52 +0000 (17:31 -0400)
include/rm_policyloc.h
include/rm_treeloc.h
src/rm.c
src/rm_allocator.c
src/rm_policy.c
test/dts_files/server-policy.c
test/dts_files/server-policy.dtb
test/dts_files/server-policy.dts
test/src/rm_test.c

index 5b27dd4ad199b0602865231e36e057ce6459016f..e1c209b09896b4cdc6bad3829e3de283ee062411 100644 (file)
@@ -101,13 +101,19 @@ typedef enum {
     /* Validate usage permissions for a resource */
     Rm_policyCheck_USE,
     /* Validate shared Linux permissions for a resource */
-    Rm_policyCheck_SHARED_LINUX
+    Rm_policyCheck_SHARED_LINUX,
+    /* Validate shared UNSPECIFIED allocation exclusion for a resource */
+    Rm_policyCheck_UNSPEC_EXCLUSION
 } Rm_PolicyCheckType;
 
 /* Permissions validation configuration structure */
 typedef struct {
     /* The type of validation to perform */
     Rm_PolicyCheckType      type;
+    /* Negative check:
+     * RM_FALSE (0) - Check if passes policy
+     * RM_TRUE  (1) - Check if fails policy */
+    uint32_t                neg;
     /* Resource's policy tree used to validate permissions */
     Rm_PolicyTree          *polTree;
     /* Valid instance node having its permissions checked for the resource */
@@ -122,9 +128,10 @@ Rm_PolicyValidInstNode *rmPolicyGetValidInstNode(Rm_Handle rmHandle,
                                                  const char *instName);
 Rm_PolicyValidInstNode *rmPolicyGetLinuxInstNode(Rm_Handle rmHandle);
 int32_t rmPolicyCheckPrivilege(Rm_PolicyCheckCfg *privilegeCfg);
-uint32_t rmPolicyGetResourceBase(Rm_PolicyTree *policyTree,
+int32_t rmPolicyGetResourceBase(Rm_PolicyTree *policyTree,
                                  Rm_PolicyValidInstNode *validInstNode,
-                                 Rm_PolicyCheckType policyCheckType);
+                                 Rm_PolicyCheckType policyCheckType,
+                                 int32_t *resBase);
 uint32_t rmPolicyGetAllocAlign(Rm_PolicyTree *policyTree);
 uint32_t rmPolicyGetCdAllocSize(Rm_PolicyTree *policyTree);
 Rm_PolicyValidInstTree *rmPolicyVInstTreeInit(Rm_Handle rmHandle,
index 488db60cc54657bec257fe779a1874d14ad54e91..6f8def0fa2f14b6124d2c4ed7387b39c58260e91 100644 (file)
@@ -158,37 +158,42 @@ typedef RB_HEAD(_Rm_AllocatorResourceTree, _Rm_ResourceNode) Rm_ResourceTree;
 
 /* Maximum number of bits used to represent all permissions.  Must be
  * changed as new permissions are added */
-#define RM_POLICY_PERM_MAX_BITS            4
+#define RM_POLICY_PERM_MAX_BITS                5
 
 /* Initialization permission characters */
-#define RM_POLICY_PERM_INIT_LOWER         'i'
-#define RM_POLICY_PERM_INIT_UPPER         'I'
+#define RM_POLICY_PERM_INIT_LOWER             'i'
+#define RM_POLICY_PERM_INIT_UPPER             'I'
 /* Initialization permission bit shift */
-#define RM_POLICY_PERM_INIT_SHIFT          0
+#define RM_POLICY_PERM_INIT_SHIFT              0
 /* Usage permission characters */
-#define RM_POLICY_PERM_USE_LOWER          'u'
-#define RM_POLICY_PERM_USE_UPPER          'U'
+#define RM_POLICY_PERM_USE_LOWER              'u'
+#define RM_POLICY_PERM_USE_UPPER              'U'
 /* Usage permission bit shift */
-#define RM_POLICY_PERM_USE_SHIFT           1
+#define RM_POLICY_PERM_USE_SHIFT               1
 /* Exclusive permission characters */
-#define RM_POLICY_PERM_EXCLUSIVE_LOWER    'x'
-#define RM_POLICY_PERM_EXCLUSIVE_UPPER    'X'
+#define RM_POLICY_PERM_EXCLUSIVE_LOWER        'x'
+#define RM_POLICY_PERM_EXCLUSIVE_UPPER        'X'
 /* Exclusive permission bit shift */
-#define RM_POLICY_PERM_EXCLUSIVE_SHIFT     2
+#define RM_POLICY_PERM_EXCLUSIVE_SHIFT         2
 /* Shared Linux permission characters */
-#define RM_POLICY_PERM_SHARED_LINUX_LOWER 's'
-#define RM_POLICY_PERM_SHARED_LINUX_UPPER 'S'
+#define RM_POLICY_PERM_SHARED_LINUX_LOWER     's'
+#define RM_POLICY_PERM_SHARED_LINUX_UPPER     'S'
 /* Shared Linux permission bit shift */
-#define RM_POLICY_PERM_SHARED_LINUX_SHIFT  3
+#define RM_POLICY_PERM_SHARED_LINUX_SHIFT      3
+/* UNSPECIFIED allocation exclusion permission characters */
+#define RM_POLICY_PERM_UNSPEC_EXCLUSION_LOWER 'e'
+#define RM_POLICY_PERM_UNSPEC_EXCLUSION_UPPER 'E'
+/* UNSPECIFIED allocation exclusion permission bit shift */
+#define RM_POLICY_PERM_UNSPEC_EXCLUSION_SHIFT  4
 
 /* Permissions subgroup start character */
-#define RM_POLICY_PERM_SUBGROUP_START     '('
+#define RM_POLICY_PERM_SUBGROUP_START         '('
 /* Permissions subgroup end character */
-#define RM_POLICY_PERM_SUBGROUP_END       ')'
+#define RM_POLICY_PERM_SUBGROUP_END           ')'
 /* Permissions subgroup terminator */
-#define RM_POLICY_PERM_TERMINATOR         '&'
+#define RM_POLICY_PERM_TERMINATOR             '&'
 /* Permissions assignment character */
-#define RM_POLICY_PERM_ASSIGNMENT         '='
+#define RM_POLICY_PERM_ASSIGNMENT             '='
 
 /* Policy permission bit storage type */
 typedef uint32_t Rm_PolicyPermBits;
index c539fe42ecb5cc6462826c353c7cd967abe9819d..b6ba7aaf5eb4134942c384d677ef825ea63b030d 100644 (file)
--- a/src/rm.c
+++ b/src/rm.c
@@ -460,6 +460,7 @@ static void staticAllocationHandler(Rm_Handle rmHandle,
             } else {
                 privCheckCfg.type = Rm_policyCheck_USE;
             }
+            privCheckCfg.neg            = RM_FALSE;
             privCheckCfg.validInstNode  = rmPolicyGetValidInstNode(rmHandle,
                                                               rmInst->instName);
             privCheckCfg.polTree        = allocNode->policyRoot;
index 9ffc1feab7a847d68653d157479e48e1f6e528e8..83ffa3dda2238c1c22bfbba5891de2900a52b969 100644 (file)
@@ -465,13 +465,16 @@ static int32_t allocatorPreAllocate(Rm_Handle rmHandle,
         matchingNode = RB_MIN(_Rm_AllocatorResourceTree, allocator->resourceRoot);
         opInfo->resourceInfo->base = matchingNode->base;
     } else {
-        opInfo->resourceInfo->base = rmPolicyGetResourceBase(allocator->policyRoot,
-                                                             opInfo->serviceInstNode,
-                                                             policyCheckType);
-    }
+        int32_t tmpBase;
 
-    if (retVal != RM_OK) {
-        return (retVal);
+        retVal = rmPolicyGetResourceBase(allocator->policyRoot,
+                                         opInfo->serviceInstNode,
+                                         policyCheckType, &tmpBase);
+        if (retVal == RM_OK) {
+            opInfo->resourceInfo->base = tmpBase;
+        } else {
+            return(retVal);
+        }
     }
 
     if (opInfo->resourceInfo->alignment == RM_RESOURCE_ALIGNMENT_UNSPECIFIED) {
@@ -504,40 +507,18 @@ static int32_t allocatorPreAllocate(Rm_Handle rmHandle,
                 (findEnd <= matchingEnd)) {
                 /* Attempt to preallocate from node only if not owned by anyone
                  * and sits within a matching node. */
-                policyCheckCfg.type = policyCheckType;
-                policyCheckCfg.validInstNode = opInfo->serviceInstNode;
-                policyCheckCfg.resourceBase = findNode.base;
+                policyCheckCfg.type           = policyCheckType;
+                policyCheckCfg.neg            = RM_FALSE;
+                policyCheckCfg.validInstNode  = opInfo->serviceInstNode;
+                policyCheckCfg.resourceBase   = findNode.base;
                 policyCheckCfg.resourceLength = findNode.length;
                 nodePassesPolicy = rmPolicyCheckPrivilege(&policyCheckCfg);
 
-                if (nodePassesPolicy && (matchingNode->allocationCount > 0)) {
-                    if (allocatorResNodeIsOwnedBy(rmHandle, matchingNode,
-                                          rmPolicyGetLinuxInstNode(rmHandle))) {
-                        /* Check if instance requesting resource has privileges
-                         * to share a resource already reserved by Linux */
-                        policyCheckCfg.type = Rm_policyCheck_SHARED_LINUX;
-                        nodePassesPolicy = rmPolicyCheckPrivilege(&policyCheckCfg);
-                    }
-
-                    if (nodePassesPolicy) {
-                        /* Check exclusive privileges of instance requesting
-                         * resource.  Requesting instance with exclusive
-                         * privileges can't reserve resource if already owned*/
-                        policyCheckCfg.type = Rm_policyCheck_EXCLUSIVE;
-                        nodePassesPolicy = !rmPolicyCheckPrivilege(&policyCheckCfg);
-                    }
-                }
-
-                if (nodePassesPolicy && (matchingNode->allocationCount == 1)) {
-                    /* Check exclusive privileges of instance that currently
-                     * owns resource */
-                    policyCheckCfg.type = Rm_policyCheck_EXCLUSIVE;
-                    policyCheckCfg.validInstNode = matchingNode->ownerList->instNameNode;
-                    nodePassesPolicy = !rmPolicyCheckPrivilege(&policyCheckCfg);
-                }
-
-                if (retVal != RM_OK) {
-                    break;
+                if (nodePassesPolicy) {
+                    /* Is range excluded from UNSPECIFIED allocations? */
+                    policyCheckCfg.type = Rm_policyCheck_UNSPEC_EXCLUSION;
+                    policyCheckCfg.neg  = RM_TRUE;
+                    nodePassesPolicy = rmPolicyCheckPrivilege(&policyCheckCfg);
                 }
 
                 if (nodePassesPolicy) {
@@ -646,6 +627,7 @@ static int32_t allocatorAllocate(Rm_Handle rmHandle,
                 allocPassesPolicy = RM_TRUE;
             } else {
                 checkCfg.type           = policyCheckType;
+                checkCfg.neg            = RM_FALSE;
                 checkCfg.polTree        = allocator->policyRoot;
                 checkCfg.validInstNode  = opInfo->serviceInstNode;
                 checkCfg.resourceBase   = findNode.base;
@@ -669,6 +651,7 @@ static int32_t allocatorAllocate(Rm_Handle rmHandle,
                              * privileges to share a resource already reserved
                              * by Linux */
                             checkCfg.type = Rm_policyCheck_SHARED_LINUX;
+                            checkCfg.neg = RM_FALSE;
                             checkCfg.validInstNode = opInfo->serviceInstNode;
                             allocPassesPolicy = rmPolicyCheckPrivilege(&checkCfg);
                             if (!allocPassesPolicy) {
@@ -681,8 +664,9 @@ static int32_t allocatorAllocate(Rm_Handle rmHandle,
                              * exclusive privileges can't reserve resource if
                              * already owned*/
                             checkCfg.type = Rm_policyCheck_EXCLUSIVE;
+                            checkCfg.neg = RM_TRUE;
                             checkCfg.validInstNode = opInfo->serviceInstNode;
-                            allocPassesPolicy = !rmPolicyCheckPrivilege(&checkCfg);
+                            allocPassesPolicy = rmPolicyCheckPrivilege(&checkCfg);
                             if (!allocPassesPolicy) {
                                 retVal = RM_SERVICE_DENIED_EXCLUSIVE_RES_ALLOCD;
                             }
@@ -693,8 +677,9 @@ static int32_t allocatorAllocate(Rm_Handle rmHandle,
                         /* Check exclusive privileges of instance that
                          * currently owns resource */
                         checkCfg.type = Rm_policyCheck_EXCLUSIVE;
+                        checkCfg.neg = RM_TRUE;
                         checkCfg.validInstNode = matchingNode->ownerList->instNameNode;
-                        allocPassesPolicy = !rmPolicyCheckPrivilege(&checkCfg);
+                        allocPassesPolicy = rmPolicyCheckPrivilege(&checkCfg);
                         if (!allocPassesPolicy) {
                             retVal = RM_SERVICE_DENIED_ALLOCD_TO_EXCLUSIVE_INST;
                         }
index 9b9e211d669948bc2ebe19e72de7c63569cab81e..2f0700581ab101c38addf3da4c6c3c31fc063e62 100644 (file)
@@ -238,6 +238,17 @@ static Rm_PolicyPermission *policyParseSubPermission(char *permStrStart,
                                            1);
                         newPerm = newPerm->nextPermission;
                     }
+                } else if ((*permStrPtr ==
+                            RM_POLICY_PERM_UNSPEC_EXCLUSION_LOWER) ||
+                         (*permStrPtr ==
+                          RM_POLICY_PERM_UNSPEC_EXCLUSION_UPPER)) {
+                    newPerm = startPerm;
+                    while (newPerm) {
+                        Rm_PolicyPermBits *pBits = &(newPerm->permissionBits);
+                        RM_policy_PERM_SET(pBits, 0, 0,
+                                      RM_POLICY_PERM_UNSPEC_EXCLUSION_SHIFT, 1);
+                        newPerm = newPerm->nextPermission;
+                    }
                 } else {
                     /* Invalid permission character.  This is a syntax error.
                      * Free the permission list and the temporary string
@@ -316,6 +327,17 @@ static Rm_PolicyPermission *policyParseSubPermission(char *permStrStart,
                                            1);
                         newPerm = newPerm->nextPermission;
                     }
+                } else if ((*permStrPtr ==
+                            RM_POLICY_PERM_UNSPEC_EXCLUSION_LOWER) ||
+                         (*permStrPtr ==
+                          RM_POLICY_PERM_UNSPEC_EXCLUSION_UPPER)) {
+                    newPerm = startPerm;
+                    while (newPerm) {
+                        Rm_PolicyPermBits *pBits = &(newPerm->permissionBits);
+                        RM_policy_PERM_SET(pBits, 0, 0,
+                                      RM_POLICY_PERM_UNSPEC_EXCLUSION_SHIFT, 1);
+                        newPerm = newPerm->nextPermission;
+                    }
                 } else {
                     /* Invalid permission character.  This is a syntax error.
                      * Free the permission list and the temporary string
@@ -636,7 +658,7 @@ Rm_PolicyValidInstNode *rmPolicyGetLinuxInstNode(Rm_Handle rmHandle)
  */
 int32_t rmPolicyCheckPrivilege(Rm_PolicyCheckCfg *privilegeCfg)
 {
-    uint32_t       permShift = RM_POLICY_PERM_INIT_SHIFT;
+    uint32_t       permShift;
     uint32_t       globPermIdx;
     uint32_t       globPermOffset;
     uint32_t       instPermIdx;
@@ -660,6 +682,9 @@ int32_t rmPolicyCheckPrivilege(Rm_PolicyCheckCfg *privilegeCfg)
         case Rm_policyCheck_SHARED_LINUX:
             permShift = RM_POLICY_PERM_SHARED_LINUX_SHIFT;
             break;
+        case Rm_policyCheck_UNSPEC_EXCLUSION:
+            permShift = RM_POLICY_PERM_UNSPEC_EXCLUSION_SHIFT;
+            break;
         default:
             return(isApproved);
     }
@@ -688,18 +713,28 @@ int32_t rmPolicyCheckPrivilege(Rm_PolicyCheckCfg *privilegeCfg)
     }
 
     /* Check permissions across all policy nodes which the request range
-     * spans */
+     * spans.  Assume approved until denial found */
+    isApproved = RM_TRUE;
     while (matchNode) {
-        /* Not approved if any matching node has permission denial */
-        if ((!RM_policy_PERM_GET(matchNode->perms, globPermIdx, globPermOffset,
-                               permShift)) &&
-            (!RM_policy_PERM_GET(matchNode->perms, instPermIdx, instPermOffset,
-                               permShift))) {
-            isApproved = RM_FALSE;
-            break;
+        if (privilegeCfg->neg) {
+            /* Not approved if any matching node is assigned an exclusion
+             * permission */
+            if ((RM_policy_PERM_GET(matchNode->perms, globPermIdx,
+                                    globPermOffset, permShift)) ||
+                (RM_policy_PERM_GET(matchNode->perms, instPermIdx,
+                                    instPermOffset, permShift))) {
+                isApproved = RM_FALSE;
+                break;
+            }
         } else {
-            /* Approve until find otherwise */
-            isApproved = RM_TRUE;
+            /* Not approved if any matching node does not have permission */
+            if ((!RM_policy_PERM_GET(matchNode->perms, globPermIdx,
+                                     globPermOffset, permShift)) &&
+                (!RM_policy_PERM_GET(matchNode->perms, instPermIdx,
+                                     instPermOffset, permShift))) {
+                isApproved = RM_FALSE;
+                break;
+            }
         }
 
         matchEnd = matchNode->base + matchNode->len - 1;
@@ -709,6 +744,10 @@ int32_t rmPolicyCheckPrivilege(Rm_PolicyCheckCfg *privilegeCfg)
         if (findEnd > matchEnd) {
             matchNode = RB_NEXT(_Rm_AllocatorPolicyTree, privilegeCfg->polTree,
                                 matchNode);
+            if (matchNode == NULL) {
+                /* Request range outspans actual resource range */
+                isApproved = RM_FALSE;
+            }
         } else {
             break;
         }
@@ -723,9 +762,10 @@ int32_t rmPolicyCheckPrivilege(Rm_PolicyCheckCfg *privilegeCfg)
  *              ranges assigned to the specified valid instance by the
  *              Policy DTB.
  */
-uint32_t rmPolicyGetResourceBase(Rm_PolicyTree *policyTree,
+int32_t rmPolicyGetResourceBase(Rm_PolicyTree *policyTree,
                                  Rm_PolicyValidInstNode *validInstNode,
-                                 Rm_PolicyCheckType checkType)
+                                 Rm_PolicyCheckType checkType,
+                                 int32_t *resBase)
 {
     uint32_t       permShift = RM_POLICY_PERM_INIT_SHIFT;
     uint32_t       globPermIdx;
@@ -733,12 +773,15 @@ uint32_t rmPolicyGetResourceBase(Rm_PolicyTree *policyTree,
     uint32_t       instPermIdx;
     uint32_t       instPermOffset;
     Rm_PolicyNode *polNode;
-    int32_t        resBase = RM_RESOURCE_BASE_UNSPECIFIED;
+
+    *resBase = RM_RESOURCE_BASE_UNSPECIFIED;
 
     if (checkType == Rm_policyCheck_INIT) {
         permShift = RM_POLICY_PERM_INIT_SHIFT;
     } else if (checkType == Rm_policyCheck_USE) {
         permShift = RM_POLICY_PERM_USE_SHIFT;
+    } else {
+        return(RM_ERROR_INVALID_SERVICE_TYPE);
     }
 
     /* Calculate the word indices and offsets for the global permissions and
@@ -753,12 +796,16 @@ uint32_t rmPolicyGetResourceBase(Rm_PolicyTree *policyTree,
                                permShift) ||
             RM_policy_PERM_GET(polNode->perms, instPermIdx, instPermOffset,
                                permShift)) {
-            resBase = polNode->base;
+            *resBase = polNode->base;
             break;
         }
     }
 
-    return(resBase);
+    if (*resBase == RM_RESOURCE_BASE_UNSPECIFIED) {
+        return(RM_SERVICE_DENIED_RES_ALLOC_REQS_NOT_MET);
+    }
+
+    return(RM_OK);
 }
 
 /* FUNCTION PURPOSE: Returns resource's allocation alignment
index 304c4352de3f5e35c418944c3e710cda1a8476c1..a51cd227e6ce355cfb038bd4537221afd1c98ba8 100644 (file)
@@ -7,8 +7,8 @@ const char rmGlobalPolicy[] = {
 0xed,
 0x00,
 0x00,
-0x0a,
-0xfc,
+0x0b,
+0x0c,
 0x00,
 0x00,
 0x00,
@@ -16,7 +16,7 @@ const char rmGlobalPolicy[] = {
 0x00,
 0x00,
 0x0a,
-0xb8,
+0xc8,
 0x00,
 0x00,
 0x00,
@@ -40,7 +40,7 @@ const char rmGlobalPolicy[] = {
 0x00,
 0x00,
 0x0a,
-0x80,
+0x90,
 0x00,
 0x00,
 0x00,
@@ -1008,7 +1008,7 @@ const char rmGlobalPolicy[] = {
 0x00,
 0x00,
 0x00,
-0x12,
+0x24,
 0x00,
 0x00,
 0x00,
@@ -1020,10 +1020,10 @@ const char rmGlobalPolicy[] = {
 0x00,
 0x00,
 0x00,
-0x08,
+0x04,
 0x69,
 0x75,
-0x78,
+0x65,
 0x20,
 0x3d,
 0x20,
@@ -1033,6 +1033,22 @@ const char rmGlobalPolicy[] = {
 0x00,
 0x00,
 0x00,
+0x03,
+0x64,
+0x00,
+0x00,
+0x00,
+0x04,
+0x69,
+0x75,
+0x20,
+0x20,
+0x3d,
+0x20,
+0x28,
+0x2a,
+0x29,
+0x00,
 0x00,
 0x00,
 0x00,
@@ -2817,4 +2833,116 @@ const char rmGlobalPolicy[] = {
 0x00,
 0x00,
 0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
 };
index 1e4c4d26daed0608914578447f6638b3bb250fe6..a218bf1a65f7f0b53078c0a989f1d542cc8e94a6 100644 (file)
Binary files a/test/dts_files/server-policy.dtb and b/test/dts_files/server-policy.dtb differ
index e6faf97997cd1b482db669ca62b18fed1e3910ed..c8172f6856b6457d007c00d62ddf35114afca8e1 100644 (file)
@@ -14,7 +14,7 @@
     /* Format for assigning resources to specific RM instances */
     qmss {
         pdsps {
-               assignments = <0 2>, "iux = (*)";
+            assignments = <0 2>, "iux = (*)";
         };
         memory-regions {
             /* Mem-region 12 reserved by Linux kernel */
             assignments = <692 4>, "iux = (*)";
         };
         bcp-queue {
-            assignments = <864 8>, "iux = (*)";
+            /* First four BCP queues are excluded from being allocated to an
+             * UNSPECIFIED base value request */
+            assignments = <864 4>, "iue = (*)",
+                          <868 4>, "iu  = (*)";
         };
         high-prio-queue {
             assignments = <704 32>, "iux = (*)";
index 75b7aedffc664efff9ef8f3c0a931c593e10e766..2ab5fff2f2068940bdfca2b9e54be1e57c2220a3 100644 (file)
@@ -367,6 +367,7 @@ char                resourceNameAifRxCh[RM_NAME_MAX_CHARS]    = "aif-rx-ch";
 char                resourceNameInfraQ[RM_NAME_MAX_CHARS]     = "infra-queue";
 char                resourceNameLowPrioQ[RM_NAME_MAX_CHARS]   = "low-prio-queue";
 char                resourceNamePassQ[RM_NAME_MAX_CHARS]      = "pass-queue";
+char                resourceNameBcpQ[RM_NAME_MAX_CHARS]       = "bcp-queue";
 
 /* Test RM NameServer name */
 char                nameServerNameFavQ[RM_NAME_MAX_CHARS]     = "My_Favorite_Queue";
@@ -1023,33 +1024,51 @@ void rmClientTsk(UArg arg0, UArg arg1)
 
 
     /* BEGIN testing allocations with UNSPECIFIED base and alignment values */
-    setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_USE, resourceNameAccumCh, 
-                 RM_RESOURCE_BASE_UNSPECIFIED, 5, 4, NULL, RM_TEST_TRUE, &responseInfo);        
+    setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_USE, resourceNameAccumCh,
+                 RM_RESOURCE_BASE_UNSPECIFIED, 5, 4, NULL, RM_TEST_TRUE, &responseInfo);
     rmCdServiceHandle->Rm_serviceHandler(rmCdServiceHandle->rmHandle, &requestInfo, &responseInfo);
-    waitForResponse(&responseInfo); 
-    POSITIVE_PASS_CHECK("---------- Use Allocation w/ UNSPECIFIED Base -----------", 
+    waitForResponse(&responseInfo);
+    POSITIVE_PASS_CHECK("---------- Use Allocation w/ UNSPECIFIED Base -----------",
                         coreNum, rmCdName, resourceNameAccumCh,
-                        RM_RESOURCE_BASE_UNSPECIFIED, requestInfo.resourceLength, 
-                        requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);    
+                        responseInfo.resourceBase, responseInfo.resourceLength,
+                        requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
 
-    setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_USE, resourceNameAccumCh, 
-                 RM_RESOURCE_BASE_UNSPECIFIED, 2, 1, NULL, RM_TEST_TRUE, &responseInfo);      
-    rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo); 
-    waitForResponse(&responseInfo); 
-    POSITIVE_PASS_CHECK("---------- Use Allocation w/ UNSPECIFIED Base -----------", 
+    setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_USE, resourceNameAccumCh,
+                 RM_RESOURCE_BASE_UNSPECIFIED, 2, 1, NULL, RM_TEST_TRUE, &responseInfo);
+    rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+    waitForResponse(&responseInfo);
+    POSITIVE_PASS_CHECK("---------- Use Allocation w/ UNSPECIFIED Base -----------",
                         coreNum, rmClientName, resourceNameAccumCh,
-                        RM_RESOURCE_BASE_UNSPECIFIED, requestInfo.resourceLength, 
-                        requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);     
+                        responseInfo.resourceBase, responseInfo.resourceLength,
+                        requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
 
-    setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_USE, resourceNameAccumCh, 
-                 RM_RESOURCE_BASE_UNSPECIFIED, 2, RM_RESOURCE_ALIGNMENT_UNSPECIFIED, NULL, RM_TEST_TRUE, &responseInfo);     
+    setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_USE, resourceNameAccumCh,
+                 RM_RESOURCE_BASE_UNSPECIFIED, 2, RM_RESOURCE_ALIGNMENT_UNSPECIFIED, NULL, RM_TEST_TRUE, &responseInfo);
     rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
-    waitForResponse(&responseInfo); 
-    POSITIVE_PASS_CHECK("---- Use Allocation w/ UNSPECIFIED Base & Alignment -----", 
+    waitForResponse(&responseInfo);
+    POSITIVE_PASS_CHECK("---- Use Allocation w/ UNSPECIFIED Base & Alignment -----",
                         coreNum, rmClientName, resourceNameAccumCh,
-                        RM_RESOURCE_BASE_UNSPECIFIED, requestInfo.resourceLength, 
-                        RM_RESOURCE_ALIGNMENT_UNSPECIFIED, responseInfo.serviceState, RM_SERVICE_APPROVED);     
-    /* END testing allocations with UNSPECIFIED base and alignment values */    
+                        responseInfo.resourceBase, responseInfo.resourceLength,
+                        RM_RESOURCE_ALIGNMENT_UNSPECIFIED, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+    setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_USE, resourceNameBcpQ,
+                 RM_RESOURCE_BASE_UNSPECIFIED, 5, 1, NULL, RM_TEST_TRUE, &responseInfo);
+    rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+    waitForResponse(&responseInfo); 
+    NEGATIVE_PASS_CHECK("--- UNSPECIFIED Allocation Exclusion (Negative Test) ----",
+                        coreNum, rmClientName, resourceNameBcpQ,
+                        RM_RESOURCE_BASE_UNSPECIFIED, requestInfo.resourceLength,
+                        requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+    setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_USE, resourceNameBcpQ,
+                 RM_RESOURCE_BASE_UNSPECIFIED, 2, 1, NULL, RM_TEST_TRUE, &responseInfo);
+    rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+    waitForResponse(&responseInfo); 
+    POSITIVE_PASS_CHECK("------------ UNSPECIFIED Allocation Exclusion -----------",
+                        coreNum, rmClientName, resourceNameBcpQ,
+                        responseInfo.resourceBase, responseInfo.resourceLength,
+                        requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+    /* END testing allocations with UNSPECIFIED base and alignment values */
 
     /* Allocate infrastructure queue shared between Linux kernel and Client */
     setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_INIT, resourceNameInfraQ,