]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-rtos/rm-lld.git/blobdiff - src/rm_policy.c
Resolved SDOCM00101586. Added test cases to cover resolved issued
[keystone-rtos/rm-lld.git] / src / rm_policy.c
index 9432c3dea0c90f053064b0b9661b7ad2c06df2b0..ca62fce38bf6085ac11137203b88d0a5e29f4040 100644 (file)
@@ -46,7 +46,9 @@
 #include <ti/drv/rm/rm.h>
 
 /* RM internal API includes */
+#include <ti/drv/rm/include/rm_internal.h>
 #include <ti/drv/rm/include/rm_loc.h>
+#include <ti/drv/rm/include/rm_allocatorloc.h>
 #include <ti/drv/rm/include/rm_policyloc.h>
 #include <ti/drv/rm/include/rm_dtb_utilloc.h>
 
  *********************** Policy Globals *******************************
  **********************************************************************/
 
+/* Character used in Policies to specify all RM instances receive
+ * the defined permissions for a resource node */
 const char Rm_policyAllInstances[] = "*";
 
 /**********************************************************************
  ******************** Local Policy Functions **************************
  **********************************************************************/
 
-static int32_t policyCheckInstances(Rm_PolicyValidInstTree *validInstTree, 
-                                    Rm_PolicyPermission *permissionsList)
+/* FUNCTION PURPOSE: Returns a pointer to the valid instance tree
+ ***********************************************************************
+ * DESCRIPTION: Returns a pointer to the instance's valid instance
+ *              tree based on the instance type
+ */
+static Rm_PolicyValidInstTree *policyGetValidInstTree(Rm_Handle rmHandle)
+{
+    Rm_Inst                *rmInst = (Rm_Inst *)rmHandle;
+    Rm_PolicyValidInstTree *tree = NULL;
+
+    if ((rmInst->instType == Rm_instType_SERVER) ||
+        (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+        tree = rmInst->u.server.globalValidInstTree;
+    }
+    else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+        tree = rmInst->u.cd.cdValidInstTree;
+    }
+    else if (rmInst->instType == Rm_instType_CLIENT) {
+        tree = rmInst->u.client.staticValidInstTree;
+    }
+    return(tree);
+}
+
+/* FUNCTION PURPOSE: Validates the instance names in a permissions string
+ ***********************************************************************
+ * DESCRIPTION: Returns RM_OK if all the instance names in a permissions
+ *              string match instance names defined in the valid instance
+ *              list.  RM_ERROR_PERM_STR_INST_NOT_VALID is returned if
+ *              there are any mismatches
+ */
+static int32_t policyCheckInstances(Rm_Handle rmHandle, Rm_PolicyPermission *permissionsList)
 {
     while (permissionsList) {
-        if (strcmp(permissionsList->instName, Rm_policyAllInstances) &&
-            (!rmPolicyGetValidInstNode(validInstTree, permissionsList->instName))) {
-            return(RM_INIT_ERROR_POLICY_UNKNOWN_INSTANCE);
+        if (strncmp(permissionsList->instName, Rm_policyAllInstances, RM_NAME_MAX_CHARS) &&
+            (!rmPolicyGetValidInstNode(rmHandle, permissionsList->instName))) {
+            return(RM_ERROR_PERM_STR_INST_NOT_VALID);
         }
         permissionsList = permissionsList->nextPermission;
     }
-    return(RM_INIT_OK);
+    return(RM_OK);
 }
 
+/* FUNCTION PURPOSE: Parses a permissions subgroup
+ ***********************************************************************
+ * DESCRIPTION: Returns a linked list of policy permissions defining
+ *              which RM instance referenced in the permissions subgroup
+ *              get which permissions.  Returns NULL if any syntax
+ *              errors are encountered during the parsing.  The error
+ *              is returned via the result pointer parameter.
+ */
 static Rm_PolicyPermission *policyParseSubPermission(char *permStrStart, char *permStrEnd, 
                                                      int32_t *result)
 {
@@ -95,10 +136,10 @@ static Rm_PolicyPermission *policyParseSubPermission(char *permStrStart, char *p
     uint32_t             permStrLen = (uint32_t)(permStrEnd - permStrStart + 1);
     char                 instNameTemp[RM_NAME_MAX_CHARS];
     uint32_t             instNameIndex;
-    bool                 foundInstName;
-    bool                 instNameComplete;
-    bool                 assignmentLeft;
-    bool                 assignmentRight;
+    int                  foundInstName;
+    int                  instNameComplete;
+    int                  assignmentLeft;
+    int                  assignmentRight;
 
     /* Create a local copy of the sub-permission string */
     permStrPtr = Rm_osalMalloc(permStrLen);
@@ -122,17 +163,16 @@ static Rm_PolicyPermission *policyParseSubPermission(char *permStrStart, char *p
          * c) Subgroup start and end are out of order
          * d) There is more than one instance subgroup specified in the string.  There
          *    should only be one subgroup per sub-permission string */
-        Rm_osalFree((void *)permStrStart, permStrLen);
-        *result = RM_INIT_ERROR_POLICY_SYNTAX_ERROR_MORE_THAN_ONE_INSTANCE_GROUP;
-        return(NULL);
+        *result = RM_ERROR_PERM_STR_TOO_MANY_INST_GROUPS;
+        goto parseError;
     }
 
     /* Create a permission entry for each instance specified in the instance group.
      * Instances names are separated by one or more spaces. */
     permStrPtr = subgroupStart + 1;
     instNameIndex = 0;
-    foundInstName = FALSE;
-    instNameComplete = FALSE;
+    foundInstName = RM_FALSE;
+    instNameComplete = RM_FALSE;
     while (permStrPtr <= subgroupEnd) {
         if ((isspace(*permStrPtr) || (*permStrPtr == RM_POLICY_PERM_SUBGROUP_END))
             && foundInstName) {
@@ -140,13 +180,13 @@ static Rm_PolicyPermission *policyParseSubPermission(char *permStrStart, char *p
              * terminates the instance name.  All other space characters are
              * ignored. */
             instNameTemp[instNameIndex] = '\0';
-            instNameComplete = TRUE; 
+            instNameComplete = RM_TRUE; 
         }
         else {
             if (!foundInstName) {
                 /* First non-whitespace character encountered is the start of an
                  * instance name */
-                foundInstName = TRUE;
+                foundInstName = RM_TRUE;
             }
 
             /* Copy the character into the temporary instance name string */
@@ -165,24 +205,18 @@ static Rm_PolicyPermission *policyParseSubPermission(char *permStrStart, char *p
                 startPerm = newPerm;
             }
             else {
-                prevPerm->nextPermission = (void *) newPerm;
+                prevPerm->nextPermission = newPerm;
             }
             prevPerm = newPerm;
 
-            instNameComplete = FALSE;
+            instNameComplete = RM_FALSE;
             instNameIndex = 0;
-            foundInstName = FALSE;
+            foundInstName = RM_FALSE;
         }
         else if (instNameIndex == RM_NAME_MAX_CHARS) {
             /* Instance name is longer than max length */
-            while (startPerm) {
-                nextPerm = startPerm->nextPermission;
-                Rm_osalFree((void *)startPerm, sizeof(Rm_PolicyPermission));
-                startPerm = nextPerm;
-            } 
-            Rm_osalFree((void *)permStrStart, sizeof(permStrLen));
-            *result = RM_INIT_ERROR_POLICY_SYNTAX_ERROR_INSTANCE_NAME_IN_ASSIGNMENT_TOO_LONG;
-            return(NULL);
+            *result = RM_ERROR_INST_NAME_IN_ASSIGNMENT_TOO_LONG;
+            goto parseError;
         }
 
         permStrPtr++;
@@ -192,7 +226,7 @@ static Rm_PolicyPermission *policyParseSubPermission(char *permStrStart, char *p
 
     /* Look on left of instance group for permission assignments. */
     permStrPtr = subgroupStart - 1;
-    assignmentLeft = FALSE;
+    assignmentLeft = RM_FALSE;
     while (permStrPtr >= permStrStart)
     {
         if (*permStrPtr == RM_POLICY_PERM_ASSIGNMENT) {
@@ -200,17 +234,11 @@ static Rm_PolicyPermission *policyParseSubPermission(char *permStrStart, char *p
                 /* Assignment character has been found more than once.  This is a
                  * syntax error.  Free the permission list and the temporary string
                  * and return. */
-                while (startPerm) {
-                    nextPerm = startPerm->nextPermission;
-                    Rm_osalFree((void *)startPerm, sizeof(Rm_PolicyPermission));
-                    startPerm = nextPerm;
-                } 
-                Rm_osalFree((void *)permStrStart, sizeof(permStrLen));
-                *result = RM_INIT_ERROR_POLICY_SYNTAX_ERROR_MORE_THAN_ONE_ASSIGNMENT_CHAR;
-                return(NULL);
+                *result = RM_ERROR_PERM_STR_TOO_MANY_ASSIGN_CHARS;
+                goto parseError;
             }
             else {
-                assignmentLeft = TRUE;
+                assignmentLeft = RM_TRUE;
             }
         }
         else if (!isspace(*permStrPtr)) {
@@ -251,28 +279,16 @@ static Rm_PolicyPermission *policyParseSubPermission(char *permStrStart, char *p
                     /* Invalid permission character.  This is a
                      * syntax error.  Free the permission list and the temporary string
                      * and return. */
-                    while (startPerm) {
-                        nextPerm = startPerm->nextPermission;
-                        Rm_osalFree((void *)startPerm, sizeof(Rm_PolicyPermission));
-                        startPerm = nextPerm;
-                    }  
-                    Rm_osalFree((void *)permStrStart, sizeof(permStrLen));
-                    *result = RM_INIT_ERROR_POLICY_SYNTAX_ERROR_INVALID_PERM_CHAR;
-                    return(NULL);
+                    *result = RM_ERROR_PERM_STR_INVALID_CHAR;
+                    goto parseError;
                 }
             }
             else {
                 /* Character found without the assignment character being found.  This is a
                  * syntax error.  Free the permission list and the temporary string
                  * and return. */
-                while (startPerm) {
-                    nextPerm = startPerm->nextPermission;
-                    Rm_osalFree((void *)startPerm, sizeof(Rm_PolicyPermission));
-                    startPerm = nextPerm;
-                }  
-                Rm_osalFree((void *)permStrStart, sizeof(permStrLen));
-                *result = RM_INIT_ERROR_POLICY_SYNTAX_ERROR_PERM_CHAR_WITHOUT_ASSIGN_CHAR;
-                return(NULL);
+                *result = RM_ERROR_PERM_CHAR_WITHOUT_ASSIGN_CHAR;
+                goto parseError;
             }
         }
         permStrPtr--;
@@ -280,18 +296,12 @@ static Rm_PolicyPermission *policyParseSubPermission(char *permStrStart, char *p
 
     /* Look on right of instance group for permission assignments. */
     permStrPtr = subgroupEnd + 1;
-    assignmentRight = FALSE;
+    assignmentRight = RM_FALSE;
     while (permStrPtr < permStrEnd) {
         if (assignmentLeft && (!isspace(*permStrPtr))) {
             /* There should be nothing but spaces on right if assignment was already found on left */
-            while (startPerm) {
-                nextPerm = startPerm->nextPermission;
-                Rm_osalFree((void *)startPerm, sizeof(Rm_PolicyPermission));
-                startPerm = nextPerm;
-            } 
-            Rm_osalFree((void *)permStrStart, sizeof(permStrLen));
-            *result = RM_INIT_ERROR_POLICY_SYNTAX_ERROR_INVALID_CHAR_ON_RIGHT_WITH_ASSINMENT_ON_LEFT;
-            return(NULL);              
+            *result = RM_ERROR_INVALID_PERMS_CHAR_ON_RIGHT;
+            goto parseError;             
         }
         
         if (*permStrPtr == RM_POLICY_PERM_ASSIGNMENT) {
@@ -299,17 +309,11 @@ static Rm_PolicyPermission *policyParseSubPermission(char *permStrStart, char *p
                 /* Assignment character has been found more than once.  This is a
                  * syntax error.  Free the permission list and the temporary string
                  * and return. */
-                while (startPerm) {
-                    nextPerm = startPerm->nextPermission;
-                    Rm_osalFree((void *)startPerm, sizeof(Rm_PolicyPermission));
-                    startPerm = nextPerm;
-                } 
-                Rm_osalFree((void *)permStrStart, sizeof(permStrLen));
-                *result = RM_INIT_ERROR_POLICY_SYNTAX_ERROR_MORE_THAN_ONE_ASSIGNMENT_CHAR;
-                return(NULL);                
+                *result = RM_ERROR_PERM_STR_TOO_MANY_ASSIGN_CHARS;
+                goto parseError;               
             }
             else {
-                assignmentRight = TRUE;
+                assignmentRight = RM_TRUE;
             }
         }
         else if (!isspace(*permStrPtr)) {
@@ -350,37 +354,41 @@ static Rm_PolicyPermission *policyParseSubPermission(char *permStrStart, char *p
                     /* Invalid permission character.  This is a
                      * syntax error.  Free the permission list and the temporary string
                      * and return. */
-                    while (startPerm) {
-                        nextPerm = startPerm->nextPermission;
-                        Rm_osalFree((void *)startPerm, sizeof(Rm_PolicyPermission));
-                        startPerm = nextPerm;
-                    }    
-                    Rm_osalFree((void *)permStrStart, sizeof(permStrLen));
-                    *result = RM_INIT_ERROR_POLICY_SYNTAX_ERROR_INVALID_PERM_CHAR;
-                    return(NULL);                    
+                    *result = RM_ERROR_PERM_STR_INVALID_CHAR;
+                    goto parseError;                   
                 }
             }
             else {
                 /* Character found without the assignment character being found.  This is a
                  * syntax error.  Free the permission list and the temporary string
                  * and return. */
-                while (startPerm) {
-                    nextPerm = startPerm->nextPermission;
-                    Rm_osalFree((void *)startPerm, sizeof(Rm_PolicyPermission));
-                    startPerm = nextPerm;
-                }    
-                Rm_osalFree((void *)permStrStart, sizeof(permStrLen));
-                *result = RM_INIT_ERROR_POLICY_SYNTAX_ERROR_MORE_THAN_ONE_ASSIGNMENT_CHAR;
-                return(NULL);                
+                *result = RM_ERROR_PERM_STR_TOO_MANY_ASSIGN_CHARS;
+                goto parseError;
             }
         }
         permStrPtr++;
     }
 
     Rm_osalFree((void *)permStrStart, sizeof(permStrLen));
+    *result = RM_OK;
     return (startPerm);
+
+parseError:
+    while (startPerm) {
+        nextPerm = startPerm->nextPermission;
+        Rm_osalFree((void *)startPerm, sizeof(Rm_PolicyPermission));
+        startPerm = nextPerm;
+    }    
+    Rm_osalFree((void *)permStrStart, sizeof(permStrLen));
+    return(NULL);     
 }
 
+/* FUNCTION PURPOSE: Frees a linked list of assignment permissions
+ ***********************************************************************
+ * DESCRIPTION: Frees the memory associated with a linked list of
+ *              assignment permissions extracted from a permissions
+ *              assignment subgroup in a policy DTB.
+ */
 static void policyFreeAssignmentPermissions(Rm_PolicyPermission *permissionList)
 {
     Rm_PolicyPermission *nextPerm;
@@ -392,6 +400,13 @@ static void policyFreeAssignmentPermissions(Rm_PolicyPermission *permissionList)
     }
 }
 
+/* FUNCTION PURPOSE: Extracts permissions from a Policy "assignment"
+ ***********************************************************************
+ * DESCRIPTION: Returns a linked list of permissions for a resource node
+ *              containing an "assignment" property in the Policy DTB.
+ *              Each node in the linked list will contain a valid instance
+ *              name along with the permissions assigned to the instance
+ */
 static Rm_PolicyPermission *policyGetAssignmentPermissions(Rm_PolicyAssignment *assignment, 
                                                            int32_t *result)
 {
@@ -402,6 +417,8 @@ static Rm_PolicyPermission *policyGetAssignmentPermissions(Rm_PolicyAssignment *
     char                *permStrEnd;
     uint32_t             permStrLen = strlen(assignment->permissionsList) + 1;
     uint32_t             i = 0;
+
+    *result = RM_OK;
     
     while(i < permStrLen) {
         /* Find the first sub-permission specification and parse it.  A sub-permission
@@ -414,7 +431,7 @@ static Rm_PolicyPermission *policyGetAssignmentPermissions(Rm_PolicyAssignment *
 
         newPerm = policyParseSubPermission(permStrStart, permStrEnd, result);
 
-        if (*result != RM_SERVICE_PROCESSING) {
+        if (*result != RM_OK) {
             /* Delete the permission list that's been created thus far, return
              * the error and NULL for the permission list */
             policyFreeAssignmentPermissions(startPerm);
@@ -443,7 +460,14 @@ static Rm_PolicyPermission *policyGetAssignmentPermissions(Rm_PolicyAssignment *
     return(startPerm);
 }
 
-static int32_t policyValidateAssignmentPermissions(Rm_PolicyValidInstTree *root,
+/* FUNCTION PURPOSE: Validates a policy "assignment" string list
+ ***********************************************************************
+ * DESCRIPTION: Returns RM_OK if the specified Policy DTB "assignment"
+ *              property specification parses okay and all the RM
+ *              instances in the assignment match RM instances in the
+ *              valid instances list
+ */
+static int32_t policyValidateAssignmentPermissions(Rm_Handle rmHandle,
                                                    Rm_PolicyAssignment *assignmentList)
 {
     Rm_PolicyAssignment *assignment = assignmentList;
@@ -453,11 +477,11 @@ static int32_t policyValidateAssignmentPermissions(Rm_PolicyValidInstTree *root,
     while (assignment) {
         /* Make sure assignment's permissions parse okay */
         permissionList = policyGetAssignmentPermissions(assignment, &result);
-        if (result != RM_INIT_OK) {
+        if (result != RM_OK) {
             return(result);
         }                        
         
-        if (result = policyCheckInstances(root, permissionList) != RM_INIT_OK) {
+        if (result = policyCheckInstances(rmHandle, permissionList) != RM_OK) {
             policyFreeAssignmentPermissions(permissionList);
             return(result);
         }
@@ -466,43 +490,91 @@ static int32_t policyValidateAssignmentPermissions(Rm_PolicyValidInstTree *root,
         assignment = assignment->nextAssignment;
     }
 
-    return (RM_INIT_OK);
+    return (RM_OK);
 }
 
 /**********************************************************************
  ************************ Internal Policy APIs ************************
  **********************************************************************/
 
-Rm_PolicyValidInstNode *rmPolicyGetValidInstNode(Rm_PolicyValidInstTree *validInstTree, char *instName)
+/* FUNCTION PURPOSE: Returns a pointer to the instance policy
+ ***********************************************************************
+ * DESCRIPTION: Returns a pointer to the instance's policy based on
+ *              the instance type
+ */
+void *rmPolicyGetPolicy(Rm_Handle rmHandle)
 {
+    Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
+    void    *policy = NULL;
+
+    if ((rmInst->instType == Rm_instType_SERVER) ||
+        (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+        policy = rmInst->u.server.globalPolicy;
+    }
+    else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+        policy = rmInst->u.cd.cdPolicy;
+    }
+    else if (rmInst->instType == Rm_instType_CLIENT) {
+        policy = rmInst->u.client.staticPolicy;
+    }
+    return(policy);
+}
+
+/* FUNCTION PURPOSE: Get a valid instace node from the valid inst tree
+ ***********************************************************************
+ * DESCRIPTION: Returns a valid instance node from the valid instance
+ *              tree that matches the specified instName
+ */
+Rm_PolicyValidInstNode *rmPolicyGetValidInstNode(Rm_Handle rmHandle, char *instName)
+{
+    Rm_Inst                *rmInst = (Rm_Inst *)rmHandle;
+    Rm_PolicyValidInstTree *treeRoot = policyGetValidInstTree(rmHandle);
     Rm_PolicyValidInstNode  findNode;
 
+    if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+        rmPolicyValidInstTreeInv(treeRoot);
+    }
+
     memset((void *)&findNode, 0, sizeof(Rm_PolicyValidInstNode));
     strncpy(findNode.name, instName, RM_NAME_MAX_CHARS);
     
-    return (RB_FIND(_Rm_PolicyValidInstTree, validInstTree, &findNode));
+    return (RB_FIND(_Rm_PolicyValidInstTree, treeRoot, &findNode));
 }
 
-Rm_PolicyValidInstNode *rmPolicyGetLinuxInstNode(Rm_PolicyValidInstTree *validInstTree)
+/* FUNCTION PURPOSE: Gets the Linux Valid instance node
+ ***********************************************************************
+ * DESCRIPTION: Returns a pointer to the valid instance node in the
+ *              valid instance tree that matches the instance name
+ *              reserved for resource assigned to the Linux kernel.
+ */
+Rm_PolicyValidInstNode *rmPolicyGetLinuxInstNode(Rm_Handle rmHandle)
 {
     char linuxName[] = RM_ALLOCATED_TO_LINUX;
 
-    return (rmPolicyGetValidInstNode(validInstTree, linuxName));
+    return (rmPolicyGetValidInstNode(rmHandle, linuxName));
 }
 
-bool rmPolicyCheckPrivilege(Rm_PolicyCheckCfg *privilegeCfg, int32_t *result)
+/* FUNCTION PURPOSE: Validates resource permissions against a Policy DTB
+ ***********************************************************************
+ * DESCRIPTION: Returns TRUE if the instance name has the specified
+ *              permissions for the specified resource in the Policy
+ *              DTB.  Otherwise, returns FALSE.
+ */
+int rmPolicyCheckPrivilege(Rm_PolicyCheckCfg *privilegeCfg, int32_t *result)
 {
     int32_t              propertyOffset;
     const char          *propertyName;
-       int32_t              propertyLen;
-       const void          *propertyData;
+    int32_t              propertyLen;
+    const void          *propertyData;
     Rm_PolicyAssignment *assignment = NULL;
     Rm_PolicyAssignment *assignmentStart = NULL;
     Rm_PolicyPermission *permission = NULL;
     Rm_PolicyPermission *permissionStart = NULL;
     uint32_t             assignmentEnd;
     uint32_t             resourceEnd = privilegeCfg->resourceBase + privilegeCfg->resourceLength - 1;
-    bool                 foundInstance;
+    int                  foundInstance;
+
+    *result = RM_OK;
 
     /* Get the resource's assignments */
     propertyOffset = fdt_first_property_offset(privilegeCfg->policyDtb, privilegeCfg->resourceOffset);
@@ -520,7 +592,7 @@ bool rmPolicyCheckPrivilege(Rm_PolicyCheckCfg *privilegeCfg, int32_t *result)
     if (assignment) {
         while (assignment) {
             assignmentEnd = assignment->resourceBase + assignment->resourceLength - 1;
-            foundInstance = FALSE;
+            foundInstance = RM_FALSE;
             if (((privilegeCfg->resourceBase >= assignment->resourceBase) &&
                  (privilegeCfg->resourceBase <= assignmentEnd)) ||
                 ((privilegeCfg->resourceBase < assignment->resourceBase) &&
@@ -530,32 +602,39 @@ bool rmPolicyCheckPrivilege(Rm_PolicyCheckCfg *privilegeCfg, int32_t *result)
                  
                 permission = permissionStart = policyGetAssignmentPermissions(assignment, result);
                 while (permission) {
-                    if ((strcmp(permission->instName, privilegeCfg->validInstNode->name) == 0) ||
-                        (strcmp(permission->instName, Rm_policyAllInstances) == 0)) {
-                        foundInstance = TRUE;
+                    if ((strncmp(permission->instName, privilegeCfg->validInstNode->name, RM_NAME_MAX_CHARS) == 0) ||
+                        (strncmp(permission->instName, Rm_policyAllInstances, RM_NAME_MAX_CHARS) == 0)) {
+                        foundInstance = RM_TRUE;
                         
                         /* Check instance's permissions */
                         if (privilegeCfg->type == Rm_policyCheck_INIT) {
                             if (!RM_policy_GET_PERM(permission->permissionBits, RM_POLICY_PERM_INIT_SHIFT)) {
                                 policyFreeAssignmentPermissions(permissionStart);
                                 rmDtbUtilPolicyFreeAssignments(assignmentStart);
-                                return(FALSE);
+                                return(RM_FALSE);
                             }
                         }
                         else if (privilegeCfg->type == Rm_policyCheck_USE) {
                             if (!RM_policy_GET_PERM(permission->permissionBits, RM_POLICY_PERM_USE_SHIFT)) {
                                 policyFreeAssignmentPermissions(permissionStart);
                                 rmDtbUtilPolicyFreeAssignments(assignmentStart);
-                                return(FALSE);
+                                return(RM_FALSE);
                             }   
                         }
                         else if (privilegeCfg->type == Rm_policyCheck_EXCLUSIVE) {
                             if (!RM_policy_GET_PERM(permission->permissionBits, RM_POLICY_PERM_EXCLUSIVE_SHIFT)) {
                                 policyFreeAssignmentPermissions(permissionStart);
                                 rmDtbUtilPolicyFreeAssignments(assignmentStart);
-                                return(FALSE);
+                                return(RM_FALSE);
                             }   
                         }
+                        else if (privilegeCfg->type == Rm_policyCheck_SHARED_LINUX) {
+                            if (!RM_policy_GET_PERM(permission->permissionBits, RM_POLICY_PERM_SHARED_LINUX_SHIFT)) {
+                                policyFreeAssignmentPermissions(permissionStart);
+                                rmDtbUtilPolicyFreeAssignments(assignmentStart);
+                                return(RM_FALSE);
+                            }   
+                        }                        
                         break;
                     }
                     permission = permission->nextPermission;
@@ -564,7 +643,7 @@ bool rmPolicyCheckPrivilege(Rm_PolicyCheckCfg *privilegeCfg, int32_t *result)
                 policyFreeAssignmentPermissions(permissionStart);
                 if (!foundInstance) {
                     rmDtbUtilPolicyFreeAssignments(assignmentStart);
-                    return(FALSE);
+                    return(RM_FALSE);
                 }
             }
             assignment = assignment->nextAssignment;
@@ -572,26 +651,34 @@ bool rmPolicyCheckPrivilege(Rm_PolicyCheckCfg *privilegeCfg, int32_t *result)
         rmDtbUtilPolicyFreeAssignments(assignmentStart);
     }
     else {
-        return(FALSE);
+        return(RM_FALSE);
     }
     
-    return(TRUE);
+    return(RM_TRUE);
 }
 
+/* FUNCTION PURPOSE: Returns resource base value according to the Policy
+ ***********************************************************************
+ * DESCRIPTION: Returns a resource base value based on the resource
+ *              ranges assigned to the specified valid instance by the
+ *              Policy DTB.
+ */
 uint32_t rmPolicyGetResourceBase(void *policyDtb, Rm_PolicyValidInstNode *validInstNode, 
-                                 int32_t resourceOffset, uint32_t allocType, 
+                                 int32_t resourceOffset, Rm_PolicyCheckType policyCheckType, 
                                  int32_t *result)
 
 {
     int32_t              propertyOffset;
     const char          *propertyName;
-       int32_t              propertyLen;
-       const void          *propertyData;
+    int32_t              propertyLen;
+    const void          *propertyData;
     Rm_PolicyAssignment *assignment = NULL;
     Rm_PolicyAssignment *assignmentStart = NULL;
     Rm_PolicyPermission *permission = NULL;
     Rm_PolicyPermission *permissionStart = NULL;
-    uint32_t             resourceBase = 0;
+    int32_t              resourceBase = RM_RESOURCE_BASE_UNSPECIFIED;
+
+    *result = RM_OK;
 
     propertyOffset = fdt_first_property_offset(policyDtb, resourceOffset);
     if (propertyOffset > RM_DTB_UTIL_STARTING_NODE_OFFSET) {
@@ -605,51 +692,54 @@ uint32_t rmPolicyGetResourceBase(void *policyDtb, Rm_PolicyValidInstNode *validI
         }
     }
 
-    /* Search policy permissions for a valid resource base */
-    if (assignment) {
-        while (assignment) {
-            permission = permissionStart = policyGetAssignmentPermissions(assignment, result);
-            while (permission) {
-                if ((strcmp(permission->instName, validInstNode->name) == 0) ||
-                    (strcmp(permission->instName, Rm_policyAllInstances) == 0)) {
-                    /* Check instance's permissions */
-                    if (RM_policy_GET_PERM(allocType, RM_POLICY_PERM_INIT_SHIFT) &&
-                        RM_policy_GET_PERM(permission->permissionBits, RM_POLICY_PERM_INIT_SHIFT)) {
-                        resourceBase = assignment->resourceBase;
-                        break;
-                    }
-                    else if (RM_policy_GET_PERM(allocType, RM_POLICY_PERM_USE_SHIFT) &&
-                             RM_policy_GET_PERM(permission->permissionBits, RM_POLICY_PERM_USE_SHIFT)) {
-                        resourceBase = assignment->resourceBase;
-                        break;
-                    }
+    /* Search policy permissions for valid resource base */
+    while (assignment) {
+        permission = permissionStart = policyGetAssignmentPermissions(assignment, result);
+        while (permission) {
+            if ((strncmp(permission->instName, validInstNode->name, RM_NAME_MAX_CHARS) == 0) ||
+                (strncmp(permission->instName, Rm_policyAllInstances, RM_NAME_MAX_CHARS) == 0)) {
+                /* Check instance's permissions */
+                if ((policyCheckType == Rm_policyCheck_INIT) &&
+                    RM_policy_GET_PERM(permission->permissionBits, RM_POLICY_PERM_INIT_SHIFT)) {
+                    resourceBase = assignment->resourceBase;
+                    break;
+                }
+                else if ((policyCheckType == Rm_policyCheck_USE) &&
+                         RM_policy_GET_PERM(permission->permissionBits, RM_POLICY_PERM_USE_SHIFT)) {
+                    resourceBase = assignment->resourceBase;
+                    break;
                 }
-                permission = permission->nextPermission;
             }
-            policyFreeAssignmentPermissions(permissionStart);
+            permission = permission->nextPermission;
+        }
+        policyFreeAssignmentPermissions(permissionStart);
 
-            if (resourceBase) {
-                break;
-            }
-            else {
-                assignment = assignment->nextAssignment;
-            }
+        if (resourceBase != RM_RESOURCE_BASE_UNSPECIFIED) {
+            break;
+        }
+        else {
+            assignment = assignment->nextAssignment;
         }
-        rmDtbUtilPolicyFreeAssignments(assignmentStart);
     }
-    else {
-        *result = RM_SERVICE_DENIED_NO_RANGE_ASSIGNMENTS_FOR_POLICY;
+
+    if (assignmentStart) {
+        rmDtbUtilPolicyFreeAssignments(assignmentStart);
     }
     
     return(resourceBase);
 }
 
+/* FUNCTION PURPOSE: Returns resource alignment value according to the Policy
+ ***********************************************************************
+ * DESCRIPTION: Parses the policy DTB to find and return a resource's 
+ *              alignment.
+ */
 uint32_t rmPolicyGetResourceAlignment(void *policyDtb, int32_t resourceOffset)
 {
     int32_t            propertyOffset;
     const char        *propertyName;
-       int32_t            propertyLen;
-       const void        *propertyData;
+    int32_t            propertyLen;
+    const void        *propertyData;
     Rm_ResourceValue  *alignmentList;
     uint32_t           resourceAlignment = 0;
 
@@ -668,35 +758,88 @@ uint32_t rmPolicyGetResourceAlignment(void *policyDtb, int32_t resourceOffset)
     return(resourceAlignment);
 }
 
+/* FUNCTION PURPOSE: Returns resource CD allocation size according to the Policy
+ ***********************************************************************
+ * DESCRIPTION: Parses the policy DTB to find and return a resource's 
+ *              allocation size.
+ */
+uint32_t rmPolicyGetResourceCdAllocSize(void *policyDtb, int32_t resourceOffset)
+{
+    int32_t            propertyOffset;
+    const char        *propertyName;
+    int32_t            propertyLen;
+    const void        *propertyData;
+    Rm_ResourceValue  *allocSizeList;
+    uint32_t           resourceAllocSize = 0;
+
+    propertyOffset = fdt_first_property_offset(policyDtb, resourceOffset);
+    if (propertyOffset > RM_DTB_UTIL_STARTING_NODE_OFFSET) {
+        while (propertyOffset > RM_DTB_UTIL_STARTING_NODE_OFFSET) {
+            propertyData = fdt_getprop_by_offset(policyDtb, propertyOffset, &propertyName, &propertyLen);
+            if (rmDtbUtilPolicyGetPropertyType(propertyName) == Rm_policyPropType_CD_ALLOCATION_SIZE) {
+                allocSizeList = rmDtbUtilPolicyExtractCdAllocationSizes(propertyData, propertyLen);
+                resourceAllocSize = allocSizeList->value;                
+                rmDtbUtilPolicyFreeCdAllocationSizes(allocSizeList);
+            }
+            propertyOffset = fdt_next_property_offset(policyDtb, propertyOffset);
+        }
+    }
+    return(resourceAllocSize);
+}
+
+
+/* FUNCTION PURPOSE: Get a resource's offset into a Policy
+ ***********************************************************************
+ * DESCRIPTION: Returns the location of the specified resource node
+ *              within the specified Policy in the form of an offset
+ *              into the DTB.  The resourceName and the Policy
+ *              node name must match.
+ */
 int32_t rmPolicyGetResourceOffset(void *policyDtb, char *resourceName)
 {
     int32_t     nodeOffset;
     int32_t     depth;
     const char *nodeName;
 
-    depth = RM_DTB_UTIL_STARTING_DEPTH;
-    nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;       
-
-    /* Find node offset for provided resource name */
-    while ((nodeOffset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) && 
-           (depth >= RM_DTB_UTIL_STARTING_DEPTH)) {
-        nodeOffset = fdt_next_node(policyDtb, nodeOffset, &depth);
-        nodeName = fdt_get_name(policyDtb, nodeOffset, NULL);
+    if (policyDtb) {
+        depth = RM_DTB_UTIL_STARTING_DEPTH;
+        nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;       
 
-        if (strcmp(nodeName, resourceName) == 0)
-        {
-            break;
+        /* Find node offset for provided resource name */
+        while (nodeOffset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) {
+            nodeOffset = fdt_next_node(policyDtb, nodeOffset, &depth);
+            if (depth < RM_DTB_UTIL_STARTING_DEPTH) {
+                /* Resource name not found */
+                nodeOffset = RM_SERVICE_DENIED_RES_DOES_NOT_EXIST;
+                break;
+            } 
+            else {
+                nodeName = fdt_get_name(policyDtb, nodeOffset, NULL);
+                if (strncmp(nodeName, resourceName, RM_NAME_MAX_CHARS) == 0) {
+                    break;
+                }
+            }
         }
     }
+    else {
+        nodeOffset = RM_ERROR_INSTANCE_HAS_NO_POLICY;
+    }
     return(nodeOffset);
 }
 
-int32_t rmPolicyValidatePolicyResourceNames(void *policyDtb, void *allocatorList)
+/* FUNCTION PURPOSE: Validates a Policy's resource node names
+ ***********************************************************************
+ * DESCRIPTION: Returns RM_OK if all of a Policy's resource node names
+ *              match a node name specified in the "valid-instances"
+ *              list specified at the top of the Policy.  Otherwise,
+ *              returns error
+ */
+int32_t rmPolicyValidatePolicyResourceNames(Rm_Handle rmHandle)
 {
-    Rm_Allocator *allocator = (Rm_Allocator *)allocatorList;
-    int32_t       nodeOffset;
-    int32_t       depth;
-    const char   *nodeName;
+    void       *policyDtb = rmPolicyGetPolicy(rmHandle);
+    int32_t     nodeOffset;
+    int32_t     depth;
+    const char *nodeName;
 
     depth = RM_DTB_UTIL_STARTING_DEPTH;
     nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;       
@@ -704,29 +847,41 @@ int32_t rmPolicyValidatePolicyResourceNames(void *policyDtb, void *allocatorList
     /* Parse DTB, verifying each resource's assignment permissions.
      * Permissions must have correct syntax and contain valid instance names
      * according validInstList */
-    while ((nodeOffset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) && 
-           (depth >= RM_DTB_UTIL_STARTING_DEPTH)) {
+    while (nodeOffset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) {
         nodeOffset = fdt_next_node(policyDtb, nodeOffset, &depth);
+        if (depth < RM_DTB_UTIL_STARTING_DEPTH) {
+            break;
+        }
         nodeName = fdt_get_name(policyDtb, nodeOffset, NULL);
         if (fdt_first_property_offset(policyDtb, nodeOffset) > RM_DTB_UTIL_STARTING_NODE_OFFSET) {
-            if (rmAllocatorFind(allocator, (char *)nodeName) == NULL) {
+            if (rmAllocatorFind(rmHandle, nodeName) == NULL) {
                 /* No allocator tied to resource name */
-                return(RM_INIT_ERROR_POLICY_UNKNOWN_RESOURCE);
+                return(RM_ERROR_UNKNOWN_RESOURCE_IN_POLICY);
             }        
         }
     }
-    return(RM_INIT_OK);
+    return(RM_OK);
 }
 
-/* TODO: ADD ABILITY TO RETURN THE SYNTAX ERROR LOCATION */
-int32_t rmPolicyValidatePolicy(void *policyDtb, Rm_PolicyValidInstTree *validInstTree)
+/* FUNCTION PURPOSE: Validates a Policy DTB
+ ***********************************************************************
+ * DESCRIPTION: Returns RM_OK if the input Policy satisfies the
+ *              following conditions:
+ *              a) All "assignment" permission string parse okay
+ *              b) All RM instance names specified in the permission
+ *                 strings match an instance name in the valid instance
+ *                 list
+ *              c) All resource node names match a resource allocator
+ */
+int32_t rmPolicyValidatePolicy(Rm_Handle rmHandle)
 {
+    void                *policyDtb = rmPolicyGetPolicy(rmHandle);
     int32_t              nodeOffset;
     int32_t              propertyOffset;
     int32_t              depth;
     const char          *propertyName;
-       int32_t              propertyLen;
-       const void          *propertyData;
+    int32_t              propertyLen;
+    const void          *propertyData;
     Rm_PolicyPropType    propertyType;
     Rm_PolicyAssignment *assignmentList;
     int32_t              result;
@@ -737,9 +892,11 @@ int32_t rmPolicyValidatePolicy(void *policyDtb, Rm_PolicyValidInstTree *validIns
     /* Parse DTB, verifying each resource's assignment permissions.
      * Permissions must have correct syntax and contain valid instance names
      * according validInstList */
-    while ((nodeOffset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) && 
-           (depth >= RM_DTB_UTIL_STARTING_DEPTH)) {
+    while (nodeOffset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) {
         nodeOffset = fdt_next_node(policyDtb, nodeOffset, &depth);
+        if (depth < RM_DTB_UTIL_STARTING_DEPTH) {
+            break;
+        }
         propertyOffset = fdt_first_property_offset(policyDtb, nodeOffset);                
         while (propertyOffset > RM_DTB_UTIL_STARTING_NODE_OFFSET) {
             propertyData = fdt_getprop_by_offset(policyDtb, propertyOffset, &propertyName, &propertyLen);
@@ -747,28 +904,39 @@ int32_t rmPolicyValidatePolicy(void *policyDtb, Rm_PolicyValidInstTree *validIns
             if (propertyType == Rm_policyPropType_ASSIGNMENTS) {
                 assignmentList = rmDtbUtilPolicyExtractAssignments(propertyData, propertyLen);
                 
-                if ((result = policyValidateAssignmentPermissions(validInstTree, assignmentList)) != RM_INIT_OK) {
+                if ((result = policyValidateAssignmentPermissions(rmHandle, assignmentList)) != RM_OK) {
                     rmDtbUtilPolicyFreeAssignments(assignmentList);
                     return(result);
                 }
                 rmDtbUtilPolicyFreeAssignments(assignmentList);
             }
             else if (propertyType == Rm_policyPropType_UNKNOWN) {
-                return(RM_INIT_ERROR_POLICY_UNKNOWN_RESOURCE_PROPERTY);
+                return(RM_ERROR_UNKNOWN_POLICY_RESOURCE_PROPERTY);
             }
             propertyOffset = fdt_next_property_offset(policyDtb, propertyOffset);
         }
     }
-    return(RM_INIT_OK);
+    return(RM_OK);
 }
 
-Rm_PolicyValidInstTree *rmPolicyCreateValidInstTree(void *policyDtb, int32_t *result)
+/* FUNCTION PURPOSE: Creates the valid instance tree for a RM instance
+ ***********************************************************************
+ * DESCRIPTION: Creates the valid instance tree for a RM instance 
+ *              that has been provided a global or static policy
+ *              The valid instance tree is created from the
+ *              "valid-instances" property at the top of the Policy.
+ *              The root entry of the valid instance tree is returned.
+ */
+Rm_PolicyValidInstTree *rmPolicyCreateValidInstTree(Rm_Handle rmHandle, int addLinux, int32_t *result)
 {
+    Rm_Inst                *rmInst = (Rm_Inst *)rmHandle;
+    void                   *policyDtb = rmPolicyGetPolicy(rmHandle);
     int32_t                 validInstOffset;
     const char             *validInstName = NULL;
-       int32_t                 validInstLen;
-       const void             *validInstData = NULL;
+    int32_t                 validInstLen;
+    const void             *validInstData = NULL;
     Rm_PolicyPropType       propertyType;
+    Rm_PolicyValidInst     *vInstListStart = NULL;
     Rm_PolicyValidInst     *validInstList = NULL;
     Rm_PolicyValidInstTree *rootEntry = NULL;
     Rm_PolicyValidInstNode *newNode = NULL;  
@@ -782,13 +950,13 @@ Rm_PolicyValidInstTree *rmPolicyCreateValidInstTree(void *policyDtb, int32_t *re
         return (NULL);
     } 
     else if (validInstOffset == -FDT_ERR_NOTFOUND) {
-        *result = RM_INIT_ERROR_POLICY_NO_VALID_INSTANCES_DEFINED;
+        *result = RM_ERROR_NO_VALID_INST_IN_POLICY;
         return (NULL);
     }
     validInstData = fdt_getprop_by_offset(policyDtb, validInstOffset, &validInstName, &validInstLen);
     propertyType = rmDtbUtilPolicyGetPropertyType(validInstName);
     if (propertyType != Rm_policyPropType_VALID_INSTANCES) {
-        *result = RM_INIT_ERROR_POLICY_NO_VALID_INSTANCES_DEFINED;
+        *result = RM_ERROR_NO_VALID_INST_IN_POLICY;
         return (NULL);
     }
 
@@ -800,29 +968,71 @@ Rm_PolicyValidInstTree *rmPolicyCreateValidInstTree(void *policyDtb, int32_t *re
     rootEntry = Rm_osalMalloc(sizeof(Rm_PolicyValidInstTree));
     RB_INIT(rootEntry);
 
+    vInstListStart = validInstList;
     while (validInstList) {
         newNode = rmPolicyValidInstNodeNew(validInstList->instName);
         RB_INSERT(_Rm_PolicyValidInstTree, rootEntry, newNode);
         
         validInstList = validInstList->nextValidInst;
     }
+    rmDtbUtilPolicyFreeValidInstances(vInstListStart);
 
     /* Add the Linux kernel node */
-    newNode = rmPolicyValidInstNodeNew(linuxName);
-    RB_INSERT(_Rm_PolicyValidInstTree, rootEntry, newNode);    
+    if (addLinux) {
+        newNode = rmPolicyValidInstNodeNew(linuxName);
+        RB_INSERT(_Rm_PolicyValidInstTree, rootEntry, newNode);    
+    }
+
+    if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+        /* Writeback the valid instance tree */
+        rmPolicyValidInstTreeWb(rootEntry);
+    }
 
-    *result = RM_INIT_OK;
+    *result = RM_OK;
     return (rootEntry);
 }
 
-void rmPolicyFreeValidInstTree(Rm_PolicyValidInstTree *validInstTree)
+/* FUNCTION PURPOSE: Deletes a valid instance tree
+ ***********************************************************************
+ * DESCRIPTION: Frees all memory associated with a Policy valid
+ *              instance tree.
+ */
+void rmPolicyFreeValidInstTree(Rm_Handle rmHandle)
 {
+    Rm_Inst                *rmInst = (Rm_Inst *)rmHandle;
+    Rm_PolicyValidInstTree *treeRoot = policyGetValidInstTree(rmHandle);
     Rm_PolicyValidInstNode *node;
-    
-    RB_FOREACH(node, _Rm_PolicyValidInstTree, validInstTree) {               
-        RB_REMOVE(_Rm_PolicyValidInstTree, validInstTree, node);
-        rmPolicyValidInstNodeFree(node);
-    }        
-    Rm_osalFree((void *)validInstTree, sizeof(Rm_PolicyValidInstTree));
+    Rm_PolicyValidInstNode *nextNode;
+
+    if (treeRoot) {
+        if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+            rmPolicyValidInstTreeInv(treeRoot);
+        }
+
+        for (node = RB_MIN(_Rm_PolicyValidInstTree, treeRoot); node != NULL; node = nextNode) {
+            nextNode = RB_NEXT(_Rm_PolicyValidInstTree, treeRoot, node);
+            RB_REMOVE(_Rm_PolicyValidInstTree, treeRoot, node);
+            rmPolicyValidInstNodeFree(node);
+        }
+
+        /* Don't need to writeback tree node changes since valid instance will be made
+         * NULL in instance */
+         
+        if (RB_MIN(_Rm_PolicyValidInstTree, treeRoot) == NULL) {
+            /* No more valid instance nodes in tree */
+            Rm_osalFree((void *)treeRoot, sizeof(Rm_PolicyValidInstTree));
+        }
+
+        if ((rmInst->instType == Rm_instType_SERVER) ||
+            (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+            rmInst->u.server.globalValidInstTree = NULL;
+        }
+        else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+            rmInst->u.cd.cdValidInstTree = NULL;
+        }
+        else if (rmInst->instType == Rm_instType_CLIENT) {
+            rmInst->u.client.staticValidInstTree = NULL;
+        }
+    }
 }