summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 78dd12e)
raw | patch | inline | side by side (parent: 78dd12e)
author | Justin Sobota <jsobota@ti.com> | |
Mon, 21 Jan 2013 00:18:20 +0000 (19:18 -0500) | ||
committer | Justin Sobota <jsobota@ti.com> | |
Mon, 21 Jan 2013 00:18:20 +0000 (19:18 -0500) |
index 223377076142030a681dfe7583131a653f68176b..b2ca53856b6682193bd699af69d7a526777184f5 100644 (file)
Binary files a/device/tci6614-server-policy.dtb and b/device/tci6614-server-policy.dtb differ
Binary files a/device/tci6614-server-policy.dtb and b/device/tci6614-server-policy.dtb differ
index 773af792b40422b5c2b1ec3f1ecbf9b053b74f00..6ad3b8989e1e717d5892522eeffab47ace67c136 100644 (file)
/* RM will deny any resource requests for resources not defined in the policy. */
/* Format for assigning resources to specific RM instances */
-
qmss {
- gp-queue {
- assignments = <2000 1000>, "iu=(RM_Server RM_Client_Delegate RM_Client)",
- <3000 1>, "iux=(RM_Server) & iu=(RM_Client_Delegate RM_Client)";
+ pdsps {
+ assignments = <0 2>, "iux = (*)";
+ };
+ memory-regions {
+ /* Mem-region 12 reserved by Linux kernel */
+ assignments = <0 12>, "(RM_Server RM_Client_Delegate RM_Client) = iux",
+ <12 1>, "(*)", /* No permissions for all instances */
+ <13 7>, "(*) = iux ";
+ };
+ link-ram {
+ assignments = <0x00000000 0xFFFFFFFF>, "iux = (*)";
};
accumulator-ch {
- assignments = <0 48>, "iux=(*)";
- alloc-alignments = <4>;
- };
- };
+ assignments = <0 48>, "iux = (*)";
+ };
+ qos-cluster {
+ assignments = <0 8>, "iux = (*)";
+ };
+ qos-queue {
+ assignments = <0 64>, "iux = (*)";
+ };
+
+ /* Queue definitions based on csl_qm_queue.h */
+ low-prio-queue {
+ assignments = <0 512>, "iux = (*)";
+ };
+ aif-queue {
+ assignments = <512 128>, "iux = (*)";
+ };
+ pass-queue {
+ assignments = <640 9>, "iux = (*)";
+ };
+ intc-queue {
+ assignments = <662 10>, "iux = (*)";
+ };
+ srio-queue {
+ assignments = <672 16>, "iux = (*)";
+ };
+ fftc-a-queue {
+ assignments = <688 4>, "iux = (*)";
+ };
+ fftc-b-queue {
+ assignments = <692 4>, "iux = (*)";
+ };
+ bcp-queue {
+ assignments = <864 8>, "iux = (*)";
+ };
+ high-prio-queue {
+ assignments = <704 32>, "iux = (*)";
+ };
+ starvation-queue {
+ assignments = <736 64>, "iux = (*)";
+ };
+ infra-queue {
+ assignments = <800 32>, "iux = (*)";
+ };
+ traffic-shaping-queue {
+ assignments = <832 32>, "iux = (*)";
+ };
+ gp-queue {
+ assignments = <896 1104>, "xiu = (*)",
+ <2000 1000>, "iu=(RM_Server RM_Client_Delegate RM_Client)",
+ <3000 5192>, "iux=(RM_Server) & iu=(RM_Client_Delegate RM_Client)";
+ };
+ }; /* qmss */
+ /* CPPI channel and flow ID ranges based on tci6614 cppi_device.c */
cppi {
+ srio-rx-ch {
+ assignments = <0 16>, "iux = (*)";
+ };
+ srio-tx-ch {
+ assignments = <0 16>, "iux = (*)";
+ };
+ srio-rx-flow-id {
+ assignments = <0 20>, "iux = (*)";
+ };
+
+ aif-rx-ch {
+ assignments = <0 50>, "iux = (*)",
+ <50 79>, "iu = (*)";
+ alloc-alignments = <20>;
+ };
+ aif-tx-ch {
+ assignments = <0 129>, "iux = (*)";
+ };
+ aif-rx-flow-id {
+ assignments = <0 129>, "iux = (*)";
+ };
+
+ fftc-a-rx-ch {
+ assignments = <0 4>, "iux = (*)";
+ };
+ fftc-a-tx-ch {
+ assignments = <0 4>, "iux = (*)";
+ };
+ fftc-a-rx-flow-id {
+ assignments = <0 8>, "iux = (*)";
+ };
+
+ fftc-b-rx-ch {
+ assignments = <0 4>, "iux = (*)";
+ };
+ fftc-b-tx-ch {
+ assignments = <0 4>, "iux = (*)";
+ };
+ fftc-b-rx-flow-id {
+ assignments = <0 8>, "iux = (*)";
+ };
+
+ pass-rx-ch {
+ assignments = <0 23>, "iux = (*)";
+ };
+ pass-tx-ch {
+ assignments = <0 9>, "iux = (*)";
+ };
pass-rx-flow-id {
- assignments = <0 20>, "iux=(*)";
- };
- };
+ assignments = <0 32>, "iux = (*)";
+ };
+
+ qmss-rx-ch {
+ assignments = <0 32>, "iux = (*)";
+ };
+ qmss-tx-ch {
+ assignments = <0 32>, "iux = (*)";
+ };
+ qmss-rx-flow-id {
+ assignments = <0 64>, "iux = (*)";
+ };
+
+ bcp-rx-ch {
+ assignments = <0 8>, "iux = (*)";
+ };
+ bcp-tx-ch {
+ assignments = <0 8>, "iux = (*)";
+ };
+ bcp-rx-flow-id {
+ assignments = <0 64>, "iux = (*)";
+ };
+ }; /* cppi */
+
+ pa-lut {
+ assignments = <0 5>, "iux = (*)";
+ };
+
};
diff --git a/include/rm_loc.h b/include/rm_loc.h
index 843a1d94c9e4b4edfcae22e3f2b00bdfc2e5e795..5806800691c46278ab838e97c519974c3e896f6e 100644 (file)
--- a/include/rm_loc.h
+++ b/include/rm_loc.h
typedef struct {
void *serviceSrcInstNode;
Rm_AllocatorOp operation;
+ uint32_t allocType;
Rm_ResourceInfo *resourceInfo;
} Rm_AllocatorOpInfo;
diff --git a/include/rm_policyloc.h b/include/rm_policyloc.h
index 44edff05c701aa70ccb5ca9163b340ca9f0cc320..a81e97675ccd6e9c3f5ee4e9f2ef82bfcad430b5 100644 (file)
--- a/include/rm_policyloc.h
+++ b/include/rm_policyloc.h
int32_t alignmentLen;
} Rm_PolicyNodeProperties;
-void Rm_policyIncrementValidInstAllocationCount(void *validInstNameNode);
-void Rm_policyDecrementValidInstAllocationCount(void *validInstNameNode);
-void *Rm_policyGetValidInstNode(void *validInstTree, char *instName);
-char *Rm_policyGetValidInstNodeName(void *validInstNode);
-void *Rm_policyGetLinuxInstNode(void *validInstTree);
-int32_t Rm_policyValidatePolicy(Rm_Inst *rmInst, void *policyDtb);
-void *Rm_policyCreateValidInstTree(void *policyDtb, int32_t *result);
+typedef enum {
+ Rm_policyCheck_EXCLUSIVE = 0,
+ Rm_policyCheck_INIT,
+ Rm_policyCheck_USE
+} Rm_PolicyCheckType;
+
+typedef struct {
+ Rm_PolicyCheckType type;
+ void *policyDtb;
+ void *validInstNode;
+ int32_t resourcePolicy;
+ uint32_t resourceBase;
+ uint32_t resourceLength;
+} Rm_PolicyCheckCfg;
+
+void Rm_policyIncrementValidInstAllocationCount(void *validInstNameNode);
+void Rm_policyDecrementValidInstAllocationCount(void *validInstNameNode);
+void *Rm_policyGetValidInstNode(void *validInstTree, char *instName);
+char *Rm_policyGetValidInstNodeName(void *validInstNode);
+bool Rm_policyCheckPrivilege(Rm_PolicyCheckCfg *privilegeCfg, int32_t *result);
+uint32_t Rm_policyGetResourceBase(void *policyDtb, void *validInstNode,
+ int32_t resourcePolicy, uint32_t allocType,
+ int32_t *result);
+uint32_t Rm_policyGetResourceAlignment(void *policyDtb, int32_t resourcePolicy);
+int32_t Rm_policyGetResourcePolicy(void *policyDtb, char *resourceName);
+void *Rm_policyGetLinuxInstNode(void *validInstTree);
+int32_t Rm_policyValidatePolicyResourceNames(Rm_Inst *rmInst, void *policyDtb);
+int32_t Rm_policyValidatePolicy(Rm_Inst *rmInst, void *policyDtb);
+void *Rm_policyCreateValidInstTree(void *policyDtb, int32_t *result);
/**********************************************************************
******************* Red-Black Tree BBST Defines **********************
diff --git a/rm_services.h b/rm_services.h
index abdf555128db250c50bd72aa4d3e0406596196cf..2013a662e0898fec77a65a354702334d99214214 100644 (file)
--- a/rm_services.h
+++ b/rm_services.h
#define RM_SERVICE_DENIED_POLICY_DENIAL_NO_RANGES_SPECIFIED (RM_SERVICE_DENIED_BEGIN+16)
/** The instance name of the service requesting instance is not in the policy valid instance list */
#define RM_SERVICE_DENIED_ORIGINATING_INSTANCE_NAME_NOT_VALID (RM_SERVICE_DENIED_BEGIN+17)
+/** The policy does not specify any assignment ranges for the resource in the service request */
+#define RM_SERVICE_DENIED_NO_RANGE_ASSIGNMENTS_FOR_POLICY (RM_SERVICE_DENIED_BEGIN+18)
+/** The resource couldn't be allocated because the requesting instance was not given the init/use
+ * permissions in the policy */
+#define RM_SERVICE_DENIED_INIT_USE_PERMISSION_DENIED (RM_SERVICE_DENIED_BEGIN+19)
+/** The resource couldn't be allocated because the requesting instance has exclusive privileges in the
+ * policy but the resource was already allocated */
+#define RM_SERVICE_DENIED_REQUESTER_HAS_EXCLUSIVE_PRIV_BUT_RESOURCE_ALLOCATED (RM_SERVICE_DENIED_BEGIN+20)
+/** The resource couldn't be allocated because it was already allocated to an instance with exclusive
+ * privileges for the resource */
+#define RM_SERVICE_DENIED_RESOURCE_ALLOCATED_TO_INSTANCE_WITH_EXCLUSIVE_PRIV (RM_SERVICE_DENIED_BEGIN+21)
/** End of resource denied reasons */
-#define RM_SERVICE_DENIED_END (RM_SERVICE_DENIED_BEGIN+17)
+#define RM_SERVICE_DENIED_END (RM_SERVICE_DENIED_BEGIN+21)
/** RM Service Request Error Code Base */
#define RM_SERVICE_ERROR_BASE (-64)
diff --git a/src/rm.c b/src/rm.c
index 7851b655797e677e38d03ae43ed82281eafab051..c108bf6c58d4a978b52367f0802715634bd2fe63 100644 (file)
--- a/src/rm.c
+++ b/src/rm.c
\r
bool Rm_compareResourceNodeAllocations(Rm_ResourceNode *nodeOne, Rm_ResourceNode *nodeTwo)\r
{\r
+ Rm_AllocatedTo *nodeOneAllocs = nodeOne->allocatedTo;\r
+ Rm_AllocatedTo *nodeTwoAllocs = nodeTwo->allocatedTo;\r
+ bool matchedInst;\r
+\r
if (nodeOne->allocationCount == nodeTwo->allocationCount) {\r
- \r
+ while (nodeOneAllocs) {\r
+ matchedInst = FALSE;\r
+ while (nodeTwoAllocs) {\r
+ if (nodeOneAllocs->instNameNode == nodeTwoAllocs->instNameNode) {\r
+ matchedInst = TRUE;\r
+ break;\r
+ }\r
+ nodeTwoAllocs = nodeTwoAllocs->nextAllocatedTo;\r
+ }\r
+\r
+ if (matchedInst) {\r
+ nodeTwoAllocs = nodeTwo->allocatedTo;\r
+ nodeOneAllocs = nodeOneAllocs->nextAllocatedTo;\r
+ }\r
+ else {\r
+ return(FALSE);\r
+ } \r
+ }\r
}\r
- return(FALSE);\r
+ else {\r
+ return(FALSE);\r
+ } \r
+ \r
+ return(TRUE);\r
}\r
\r
void Rm_deleteAllocatedTo(Rm_ResourceNode *node, void *serviceInstNode)\r
Rm_osalFree((void *)allocatedTo, sizeof(Rm_AllocatedTo));\r
}\r
\r
+void Rm_copyAllocatedTo(Rm_ResourceNode *dstNode, Rm_ResourceNode *srcNode)\r
+{\r
+ Rm_AllocatedTo *srcAllocs = srcNode->allocatedTo;\r
+ Rm_AllocatedTo *newDstAlloc;\r
+ Rm_AllocatedTo *prevDstAlloc;\r
+\r
+ dstNode->allocationCount = srcNode->allocationCount;\r
+\r
+ while (srcAllocs) {\r
+ newDstAlloc = Rm_osalMalloc(sizeof(Rm_AllocatedTo));\r
+ newDstAlloc->instNameNode = srcAllocs->instNameNode;\r
+ newDstAlloc->nextAllocatedTo = NULL;\r
+\r
+ if (dstNode->allocatedTo == NULL) {\r
+ dstNode->allocatedTo = newDstAlloc;\r
+ }\r
+ else {\r
+ prevDstAlloc->nextAllocatedTo = newDstAlloc;\r
+ }\r
+ prevDstAlloc = newDstAlloc;\r
+ srcAllocs = srcAllocs->nextAllocatedTo;\r
+ }\r
+}\r
+\r
+void Rm_clearAllocatedTo(Rm_ResourceNode *node)\r
+{\r
+ Rm_AllocatedTo *allocatedTo = node->allocatedTo;\r
+ Rm_AllocatedTo *nextAllocatedTo;\r
+\r
+ while (allocatedTo) {\r
+ nextAllocatedTo = allocatedTo->nextAllocatedTo;\r
+ node->allocationCount--;\r
+ Rm_osalFree((void *)allocatedTo, sizeof(Rm_AllocatedTo));\r
+ allocatedTo = nextAllocatedTo;\r
+ }\r
+}\r
+\r
int32_t Rm_createTreeAllocator(Rm_Inst *rmInst, const char *resourceName, Rm_ResourceRange *range)\r
{\r
Rm_Allocator *allocator = NULL;\r
@@ -458,33 +520,81 @@ int32_t Rm_createTreeAllocator(Rm_Inst *rmInst, const char *resourceName, Rm_Res
* policy does not agree another resource(s) must be preallocated and tested against the \r
* policy. Policy will provide initialize the preallocate with the base that it allows\r
* for the rm instance for the specified resource. */\r
-int32_t Rm_treePreAllocate(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo)\r
+int32_t Rm_treePreAllocate(Rm_Inst *rmInst, Rm_Allocator *allocator, int32_t resourcePolicy,\r
+ Rm_AllocatorOpInfo *opInfo)\r
{\r
- Rm_ResourceNode findNode;\r
- Rm_ResourceNode *matchingNode = NULL;\r
- uint32_t matchingEnd;\r
- uint32_t rangeIndex;\r
- bool resourceFound = FALSE;\r
- int32_t retVal = RM_SERVICE_PROCESSING;\r
-\r
- memset((void *)&findNode, 0, sizeof(Rm_ResourceNode));\r
- if (opInfo->resourceInfo->base) {\r
- findNode.base = opInfo->resourceInfo->base;\r
+ Rm_ResourceNode findNode;\r
+ Rm_ResourceNode *matchingNode = NULL;\r
+ uint32_t matchingEnd;\r
+ uint32_t rangeIndex;\r
+ bool resourceFound = FALSE;\r
+ Rm_PolicyCheckType policyCheckType;\r
+ Rm_PolicyCheckCfg policyCheckCfg;\r
+ bool nodePassesPolicy;\r
+ int32_t retVal = RM_SERVICE_PROCESSING; \r
+\r
+ opInfo->resourceInfo->base = Rm_policyGetResourceBase(rmInst->policy, opInfo->serviceSrcInstNode, \r
+ resourcePolicy, opInfo->allocType, \r
+ &retVal);\r
+ if (retVal != RM_SERVICE_PROCESSING) {\r
+ return (retVal);\r
}\r
- else {\r
- /* Use first resource value in tree */\r
- matchingNode = RB_MIN(_Rm_ResourceTree, allocator->allocatorRootEntry);\r
- findNode.base = matchingNode->base;\r
+\r
+ if (opInfo->resourceInfo->alignment == RM_RESOURCE_ALIGNMENT_UNSPECIFIED) { \r
+ /* Get alignment from policy */\r
+ opInfo->resourceInfo->alignment = Rm_policyGetResourceAlignment(rmInst->policy, resourcePolicy);\r
}\r
- /* Length always provided */\r
+ \r
+ if (opInfo->resourceInfo->alignment == 0) {\r
+ opInfo->resourceInfo->alignment = 1;\r
+ } \r
+\r
+ memset((void *)&findNode, 0, sizeof(Rm_ResourceNode));\r
+ findNode.base = opInfo->resourceInfo->base;\r
findNode.length = opInfo->resourceInfo->length;\r
\r
+ /* Configure policy checking structure */\r
+ memset((void *)&policyCheckCfg, 0, sizeof(Rm_PolicyCheckCfg));\r
+ if (RM_POLICY_GET_PERM(opInfo->allocType, RM_POLICY_PERM_INIT_SHIFT)) {\r
+ policyCheckType = Rm_policyCheck_INIT;\r
+ }\r
+ else if (RM_POLICY_GET_PERM(opInfo->allocType, RM_POLICY_PERM_USE_SHIFT)) {\r
+ policyCheckType = Rm_policyCheck_USE;\r
+ }\r
+ policyCheckCfg.policyDtb = rmInst->policy;\r
+ policyCheckCfg.resourcePolicy = resourcePolicy;\r
+ \r
do {\r
matchingNode = RB_FIND(_Rm_ResourceTree, allocator->allocatorRootEntry, &findNode);\r
\r
- if (matchingNode != NULL) {\r
- if (matchingNode->allocationCount == 0)\r
- {\r
+ if (matchingNode) {\r
+ nodePassesPolicy = FALSE;\r
+ policyCheckCfg.type = policyCheckType;\r
+ policyCheckCfg.validInstNode = opInfo->serviceSrcInstNode;\r
+ policyCheckCfg.resourceBase = findNode.base;\r
+ policyCheckCfg.resourceLength = findNode.length;\r
+ nodePassesPolicy = Rm_policyCheckPrivilege(&policyCheckCfg, &retVal); \r
+ \r
+ if (nodePassesPolicy && (matchingNode->allocationCount > 0)) {\r
+ /* Check exclusive privileges of instance requesting resource. Requesting\r
+ * instance with exclusive privileges can't reserve resource if already owned*/\r
+ policyCheckCfg.type = Rm_policyCheck_EXCLUSIVE;\r
+ policyCheckCfg.validInstNode = opInfo->serviceSrcInstNode;\r
+ nodePassesPolicy = !Rm_policyCheckPrivilege(&policyCheckCfg, &retVal);\r
+ }\r
+ \r
+ if (nodePassesPolicy && (matchingNode->allocationCount == 1)) {\r
+ /* Check exclusive privileges of instance that currently owns resource */\r
+ policyCheckCfg.type = Rm_policyCheck_EXCLUSIVE;\r
+ policyCheckCfg.validInstNode = matchingNode->allocatedTo->instNameNode;\r
+ nodePassesPolicy = !Rm_policyCheckPrivilege(&policyCheckCfg, &retVal);\r
+ }\r
+\r
+ if (retVal != RM_SERVICE_PROCESSING) {\r
+ break;\r
+ }\r
+\r
+ if (nodePassesPolicy) {\r
matchingEnd = matchingNode->base + matchingNode->length - 1;\r
/* Initialize indexer to be first resource value that alignment */\r
rangeIndex = findNode.base;\r
* allocate requirements */\r
opInfo->resourceInfo->base = rangeIndex;\r
resourceFound = TRUE;\r
- }\r
+ } \r
}\r
\r
if (!resourceFound) {\r
@@ -515,49 +625,148 @@ int32_t Rm_treePreAllocate(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo)
return(retVal); \r
}\r
\r
-int32_t Rm_treeAllocate(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo)\r
+int32_t Rm_treeAllocate(Rm_Inst *rmInst, Rm_Allocator *allocator, int32_t resourcePolicy,\r
+ Rm_AllocatorOpInfo *opInfo)\r
{\r
- Rm_ResourceNode findNode;\r
- Rm_ResourceNode *matchingNode = NULL;\r
- Rm_ResourceNode *leftNode = NULL;\r
- Rm_ResourceNode *rightNode = NULL; \r
- uint32_t findEnd;\r
- uint32_t matchingEnd;\r
- int32_t retVal;\r
+ Rm_ResourceNode findNode;\r
+ Rm_ResourceNode *matchingNode = NULL;\r
+ Rm_ResourceNode *leftNode = NULL;\r
+ Rm_ResourceNode *rightNode = NULL;\r
+ Rm_PolicyCheckType policyCheckType; \r
+ Rm_PolicyCheckCfg policyCheckCfg;\r
+ bool allocPassesPolicy;\r
+ bool combineLeft = FALSE;\r
+ bool combineRight = FALSE; \r
+ uint32_t findEnd;\r
+ uint32_t matchingEnd; \r
+ int32_t retVal = RM_SERVICE_PROCESSING;\r
\r
memset((void *)&findNode, 0, sizeof(Rm_ResourceNode));\r
findNode.base = opInfo->resourceInfo->base;\r
findNode.length = opInfo->resourceInfo->length;\r
matchingNode = RB_FIND(_Rm_ResourceTree, allocator->allocatorRootEntry, &findNode);\r
\r
+ /* Prepare privilege checks */\r
+ memset((void *)&policyCheckCfg, 0, sizeof(Rm_PolicyCheckCfg));\r
+ if (RM_POLICY_GET_PERM(opInfo->allocType, RM_POLICY_PERM_INIT_SHIFT)) {\r
+ policyCheckType = Rm_policyCheck_INIT;\r
+ }\r
+ else if (RM_POLICY_GET_PERM(opInfo->allocType, RM_POLICY_PERM_USE_SHIFT)) {\r
+ policyCheckType = Rm_policyCheck_USE;\r
+ }\r
+\r
if (matchingNode) {\r
findEnd = findNode.base + findNode.length - 1;\r
matchingEnd = matchingNode->base + matchingNode->length - 1;\r
\r
if ((findNode.base >= matchingNode->base) && (findEnd <= matchingEnd)) {\r
- if (matchingNode->allocationCount == 0) { \r
+ if (opInfo->serviceSrcInstNode == Rm_policyGetLinuxInstNode(rmInst->validInstances)) {\r
+ /* Bypass policy checks since Linux Kernel has full privileges */\r
+ allocPassesPolicy = TRUE;\r
+ }\r
+ else {\r
+ allocPassesPolicy = FALSE;\r
+ policyCheckCfg.policyDtb = rmInst->policy;\r
+ policyCheckCfg.resourcePolicy = resourcePolicy; \r
+ policyCheckCfg.type = policyCheckType;\r
+ policyCheckCfg.validInstNode = opInfo->serviceSrcInstNode;\r
+ policyCheckCfg.resourceBase = findNode.base;\r
+ policyCheckCfg.resourceLength = findNode.length;\r
+ allocPassesPolicy = Rm_policyCheckPrivilege(&policyCheckCfg, &retVal);\r
+ if (!allocPassesPolicy) {\r
+ retVal = RM_SERVICE_DENIED_INIT_USE_PERMISSION_DENIED;\r
+ }\r
+ \r
+ if (allocPassesPolicy && (matchingNode->allocationCount > 0)) {\r
+ /* Check exclusive privileges of instance requesting resource. Requesting\r
+ * instance with exclusive privileges can't reserve resource if already owned*/\r
+ policyCheckCfg.type = Rm_policyCheck_EXCLUSIVE;\r
+ policyCheckCfg.validInstNode = opInfo->serviceSrcInstNode;\r
+ allocPassesPolicy = !Rm_policyCheckPrivilege(&policyCheckCfg, &retVal);\r
+ if (!allocPassesPolicy) {\r
+ retVal = RM_SERVICE_DENIED_REQUESTER_HAS_EXCLUSIVE_PRIV_BUT_RESOURCE_ALLOCATED;\r
+ }\r
+ }\r
+ if (allocPassesPolicy && (matchingNode->allocationCount == 1)) {\r
+ /* Check exclusive privileges of instance that currently owns resource */\r
+ policyCheckCfg.type = Rm_policyCheck_EXCLUSIVE;\r
+ policyCheckCfg.validInstNode = matchingNode->allocatedTo->instNameNode;\r
+ allocPassesPolicy = !Rm_policyCheckPrivilege(&policyCheckCfg, &retVal);\r
+ if (!allocPassesPolicy) {\r
+ retVal = RM_SERVICE_DENIED_RESOURCE_ALLOCATED_TO_INSTANCE_WITH_EXCLUSIVE_PRIV;\r
+ } \r
+ } \r
+ }\r
+ \r
+ if (allocPassesPolicy) { \r
if ((findNode.base == matchingNode->base) && (findEnd == matchingEnd)) {\r
- /* findNode range matches the matchingNode range\r
+ /* findNode range matches matchingNode range\r
*\r
- * base0 base0+length0-1\r
- * |<---------------length0------------------->| => existing node\r
- * |<---------------length1------------------->| => requested resources\r
- * base1 base1+length1-1\r
+ * |<--left node-->||<--matched node-->||<--right node-->| => existing node\r
+ * |<--alloc request-->| => requested resources\r
*/ \r
+ leftNode = RB_PREV(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
+ rightNode = RB_NEXT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
+ RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
Rm_addAllocatedTo(matchingNode, opInfo->serviceSrcInstNode);\r
+\r
+ if (leftNode && Rm_compareResourceNodeAllocations(leftNode, matchingNode)) {\r
+ RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode);\r
+ combineLeft = TRUE;\r
+ }\r
+ if (rightNode && Rm_compareResourceNodeAllocations(rightNode, matchingNode)) {\r
+ RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode);\r
+ combineRight = TRUE;\r
+ }\r
+\r
+ if (combineLeft && combineRight) {\r
+ /* Combine all three nodes into matchingNode */\r
+ matchingNode->base = leftNode->base;\r
+ matchingNode->length = leftNode->length + matchingNode->length + rightNode->length;\r
+\r
+ Rm_clearAllocatedTo(leftNode);\r
+ Rm_freeResourceNode(leftNode);\r
+ Rm_clearAllocatedTo(rightNode);\r
+ Rm_freeResourceNode(rightNode); \r
+ }\r
+ else if (combineLeft) {\r
+ /* Combine left and matching nodes. Reinsert right. */\r
+ matchingNode->base = leftNode->base;\r
+ matchingNode->length += leftNode->length;\r
+\r
+ Rm_clearAllocatedTo(leftNode);\r
+ Rm_freeResourceNode(leftNode);\r
+ RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode); \r
+ }\r
+ else if (combineRight) {\r
+ /* Combine right and matching nodes. Reinsert left. */\r
+ matchingNode->length += rightNode->length;\r
+\r
+ Rm_clearAllocatedTo(rightNode);\r
+ Rm_freeResourceNode(rightNode);\r
+ RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode);\r
+ }\r
+ else {\r
+ /* No combine. */\r
+ RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode);\r
+ RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode);\r
+ }\r
+\r
+ /* Always reinsert matchingNode */ \r
+ RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode); \r
} \r
else if ((findNode.base > matchingNode->base) && (findEnd < matchingEnd)) {\r
/* findNode range is subset of matchingNode range and neither boundary is\r
* equivalent.\r
*\r
- * base0 base0+length0-1\r
- * |<---------------length0------------------->| => existing node\r
- * |<---------length1---------->| => requested resources\r
- * base1 base1+length1-1\r
+ * |<----------matched node---------->|\r
+ * |<---alloc request--->|\r
*/ \r
RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
leftNode = Rm_newResourceNode(matchingNode->base, findNode.base - matchingNode->base);\r
+ Rm_copyAllocatedTo(leftNode, matchingNode);\r
rightNode = Rm_newResourceNode(findNode.base + findNode.length, matchingEnd - findEnd);\r
+ Rm_copyAllocatedTo(rightNode, matchingNode);\r
\r
matchingNode->base = findNode.base; \r
matchingNode->length = findNode.length;\r
/* findNode base and matchingNode base are equivalent. May be combine\r
* possibilities to the left\r
*\r
- * base0 base0+length0-1\r
- * |<---------------length0------------------->| => existing node\r
- * |<---------length1---------->| => requested resources\r
- * base1 base1+length1-1\r
+ * |<---left node (alloc'd)--->||<----------matched node---------->|\r
+ * |<---findNode (alloc req)--->|\r
*/ \r
leftNode = RB_PREV(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
- RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode); \r
+ RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
+ /* Add allocating instance to allocatedTo list for compare with leftNode */\r
+ Rm_addAllocatedTo(matchingNode, opInfo->serviceSrcInstNode);\r
\r
- if (leftNode && (leftNode->allocationCount == 1) && \r
- (leftNode->allocatedTo->instNameNode == opInfo->serviceSrcInstNode)) {\r
- \r
+ if (leftNode && Rm_compareResourceNodeAllocations(leftNode, matchingNode)) {\r
RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode);\r
/* Combine leftNode and findNode */\r
leftNode->length += findNode.length;\r
}\r
else {\r
leftNode = Rm_newResourceNode(findNode.base, findNode.length);\r
- Rm_addAllocatedTo(leftNode, opInfo->serviceSrcInstNode);\r
+ Rm_copyAllocatedTo(leftNode, matchingNode);\r
}\r
\r
/* Account for leftNode in matchingNode */\r
/* findNode end and matchingNode end are equivalent. May be combine\r
* possibilities to the right\r
*\r
- * base0 base0+length0-1\r
- * |<---------------length0------------------->| => existing node\r
- * |<---------length1---------->| => requested resources\r
- * base1 base1+length1-1 \r
+ * |<----------matched node---------->||<---right node (alloc'd)--->|\r
+ * |<---findNode (alloc req)--->| \r
*/ \r
rightNode = RB_NEXT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
+ /* Add allocating instance to allocatedTo list for compare with rightNode */\r
+ Rm_addAllocatedTo(matchingNode, opInfo->serviceSrcInstNode);\r
\r
- if (rightNode && (rightNode->allocationCount == 1) && \r
- (rightNode->allocatedTo->instNameNode == opInfo->serviceSrcInstNode)) {\r
-\r
+ if (rightNode && Rm_compareResourceNodeAllocations(rightNode, matchingNode)) {\r
RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode);\r
-\r
/* Combine rightNode and findNode */\r
rightNode->base = findNode.base;\r
rightNode->length += findNode.length;\r
}\r
else {\r
rightNode = Rm_newResourceNode(findNode.base, findNode.length);\r
- Rm_addAllocatedTo(rightNode, opInfo->serviceSrcInstNode);\r
+ Rm_copyAllocatedTo(rightNode, matchingNode);\r
}\r
\r
/* Account for rightNode in matchingNode */\r
\r
RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode);\r
}\r
+ /* Remove allocating instance from leftover matchingNode */\r
+ Rm_deleteAllocatedTo(matchingNode, opInfo->serviceSrcInstNode);\r
RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
}\r
retVal = RM_SERVICE_APPROVED_AND_COMPLETED;\r
}\r
- else {\r
- retVal = RM_SERVICE_DENIED_RESOURCE_ALREADY_ALLOCATED;\r
- }\r
}\r
else {\r
retVal = RM_SERVICE_DENIED_RESOURCE_ALREADY_ALLOCATED;\r
return(retVal); \r
}\r
\r
-int32_t Rm_treeFree(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo)\r
+int32_t Rm_treeFree(Rm_Inst *rmInst, Rm_Allocator *allocator, int32_t resourcePolicy, Rm_AllocatorOpInfo *opInfo)\r
{\r
Rm_ResourceNode findNode;\r
Rm_ResourceNode *matchingNode = NULL;\r
leftNode = RB_PREV(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
rightNode = RB_NEXT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
+ Rm_deleteAllocatedTo(matchingNode, opInfo->serviceSrcInstNode);\r
\r
- if (leftNode && (leftNode->allocationCount == 0)) {\r
+ if (leftNode && Rm_compareResourceNodeAllocations(leftNode, matchingNode)) {\r
RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode);\r
combineLeft = TRUE;\r
}\r
- if (rightNode && (rightNode->allocationCount == 0)) {\r
+ if (rightNode && Rm_compareResourceNodeAllocations(rightNode, matchingNode)) {\r
RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode);\r
combineRight = TRUE;\r
}\r
matchingNode->base = leftNode->base;\r
matchingNode->length = leftNode->length + matchingNode->length + rightNode->length;\r
\r
+ Rm_clearAllocatedTo(leftNode);\r
Rm_freeResourceNode(leftNode);\r
+ Rm_clearAllocatedTo(rightNode);\r
Rm_freeResourceNode(rightNode); \r
}\r
else if (combineLeft) {\r
/* Combine left and matching nodes. Reinsert right. */\r
matchingNode->base = leftNode->base;\r
matchingNode->length += leftNode->length;\r
- \r
+\r
+ Rm_clearAllocatedTo(leftNode);\r
Rm_freeResourceNode(leftNode);\r
RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode); \r
}\r
else if (combineRight) {\r
/* Combine right and matching nodes. Reinsert left. */\r
matchingNode->length += rightNode->length;\r
- \r
+\r
+ Rm_clearAllocatedTo(rightNode);\r
Rm_freeResourceNode(rightNode);\r
RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode);\r
}\r
}\r
\r
/* Always reinsert matchingNode */\r
- Rm_deleteAllocatedTo(matchingNode, opInfo->serviceSrcInstNode);\r
RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode); \r
}\r
else if ((findNode.base > matchingNode->base) && (findEnd < matchingEnd)) {\r
*\r
* |<----------matched node---------->|\r
* |<---free request--->|\r
+ *\r
+ * Remove instance from AllocatedTo list then add it back in for side nodes for\r
+ * proper accounting of allocations in validInstance list\r
*/ \r
-\r
RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
+ Rm_deleteAllocatedTo(matchingNode, opInfo->serviceSrcInstNode);\r
\r
leftNode = Rm_newResourceNode(matchingNode->base, findNode.base - matchingNode->base);\r
+ Rm_copyAllocatedTo(leftNode, matchingNode);\r
Rm_addAllocatedTo(leftNode, opInfo->serviceSrcInstNode);\r
RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode);\r
\r
rightNode = Rm_newResourceNode(findNode.base + findNode.length, matchingEnd - findEnd);\r
+ Rm_copyAllocatedTo(rightNode, matchingNode);\r
Rm_addAllocatedTo(rightNode, opInfo->serviceSrcInstNode);\r
RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode);\r
\r
matchingNode->base = findNode.base; \r
matchingNode->length = findNode.length;\r
- Rm_deleteAllocatedTo(matchingNode, opInfo->serviceSrcInstNode);\r
RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
}\r
else { \r
\r
leftNode = RB_PREV(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
+ /* Remove freeing instance from allocatedTo list for compare with leftNode */\r
+ Rm_deleteAllocatedTo(matchingNode, opInfo->serviceSrcInstNode);\r
\r
- if (leftNode && (leftNode->allocationCount == 0)) {\r
+ if (leftNode && Rm_compareResourceNodeAllocations(leftNode, matchingNode)) {\r
RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode);\r
/* Combine leftNode and findNode */\r
leftNode->length += findNode.length;\r
}\r
else {\r
leftNode = Rm_newResourceNode(findNode.base, findNode.length);\r
+ Rm_copyAllocatedTo(leftNode, matchingNode);\r
}\r
\r
/* Remove leftNode range from matchingNode */\r
matchingNode->base = findNode.base + findNode.length;\r
matchingNode->length = matchingEnd - findEnd; \r
-\r
RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode);\r
}\r
else if (findEnd == matchingEnd) {\r
*/ \r
\r
rightNode = RB_NEXT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
- RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode); \r
+ RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode); \r
+ /* Remove freeing instance from allocatedTo list for compare with rightNode */\r
+ Rm_deleteAllocatedTo(matchingNode, opInfo->serviceSrcInstNode);\r
\r
- if (rightNode && (rightNode->allocationCount == 0)) {\r
+ if (rightNode && Rm_compareResourceNodeAllocations(rightNode, matchingNode)) {\r
RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode);\r
/* Combine rightNode and findNode */\r
rightNode->base = findNode.base;\r
}\r
else {\r
rightNode = Rm_newResourceNode(findNode.base, findNode.length);\r
+ Rm_copyAllocatedTo(rightNode, matchingNode);\r
}\r
\r
/* Remove rightNode range from matchingNode */\r
matchingNode->length -= findNode.length; \r
-\r
RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode);\r
}\r
\r
+ /* Add freeing instance back into matchingNode allocations */\r
+ Rm_addAllocatedTo(matchingNode, opInfo->serviceSrcInstNode);\r
RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
}\r
\r
int32_t Rm_allocatorOperation(Rm_Inst *rmInst, Rm_AllocatorOpInfo *opInfo)\r
{\r
Rm_Allocator *allocator = NULL;\r
+ int32_t resourcePolicy = NULL;\r
int32_t retVal;\r
void *key;\r
\r
/* Lock access to the RM instance's transaction queue */\r
key = Rm_osalMtCsEnter();\r
-\r
+ \r
+ resourcePolicy = Rm_policyGetResourcePolicy(rmInst->policy, opInfo->resourceInfo->name);\r
allocator = Rm_allocatorFind(rmInst, opInfo->resourceInfo->name);\r
- if (allocator) {\r
+ \r
+ if ((resourcePolicy > 0) && allocator) {\r
if (opInfo->operation == Rm_allocatorOp_PRE_ALLOCATE) {\r
- retVal = Rm_treePreAllocate(allocator, opInfo);\r
+ retVal = Rm_treePreAllocate(rmInst, allocator, resourcePolicy, opInfo);\r
} \r
else if (opInfo->operation == Rm_allocatorOp_ALLOCATE) {\r
- retVal = Rm_treeAllocate(allocator, opInfo);\r
+ retVal = Rm_treeAllocate(rmInst, allocator, resourcePolicy, opInfo);\r
}\r
else if (opInfo->operation == Rm_allocatorOp_FREE) {\r
- retVal = Rm_treeFree(allocator, opInfo);\r
+ retVal = Rm_treeFree(rmInst, allocator, resourcePolicy, opInfo);\r
} \r
}\r
else {\r
- /* Resource allocator could not be found */\r
+ /* Resource could not be found in policy and/or allocator */\r
retVal = RM_SERVICE_DENIED_RESOURCE_DOES_NOT_EXIST;\r
}\r
\r
return(retVal);\r
}\r
\r
-void Rm_allocationHandler (Rm_Inst *rmInst, Rm_Transaction *transaction, void *validInstNode)\r
+void Rm_allocationHandler (Rm_Inst *rmInst, Rm_Transaction *transaction, void *validInstNode,\r
+ uint32_t allocType)\r
{\r
Rm_AllocatorOpInfo opInfo;\r
int32_t retVal = transaction->state;\r
@@ -872,10 +1093,11 @@ void Rm_allocationHandler (Rm_Inst *rmInst, Rm_Transaction *transaction, void *v
else if (rmInst->instType == Rm_instType_SERVER) {\r
opInfo.resourceInfo = &transaction->resourceInfo;\r
opInfo.serviceSrcInstNode = validInstNode;\r
+ opInfo.allocType = allocType;\r
\r
if (strlen(transaction->resourceInfo.nsName) > 0) {\r
if (transaction->resourceInfo.base != 0) {\r
- /* Both a name and a value cannot be specified for the request */\r
+ /* Both NameServer name and static value cannot be specified for the request */\r
retVal = RM_SERVICE_ERROR_NAMESERVER_NAME_AND_RESOURCE_RANGE_BOTH_DEFINED;\r
}\r
else {\r
@@ -885,25 +1107,7 @@ void Rm_allocationHandler (Rm_Inst *rmInst, Rm_Transaction *transaction, void *v
\r
if (retVal == RM_SERVICE_PROCESSING) { \r
if (transaction->resourceInfo.base == RM_RESOURCE_BASE_UNSPECIFIED) {\r
- if ((transaction->resourceInfo.alignment == RM_RESOURCE_ALIGNMENT_UNSPECIFIED) ||\r
- (transaction->resourceInfo.alignment == 0)) { \r
- /* TEMP: Default resource alignment of 1 if the resource alignment is not\r
- * specified */\r
- opInfo.resourceInfo->alignment = 1;\r
- }\r
- \r
- /* TODO: set the resourceInfo->base value to be the base of the resource range\r
- * allowed for the RM instance */\r
- // opInfo.resourceInfo->base = policy_get_instance_base(...);\r
- opInfo.resourceInfo->base = 0;\r
- \r
- /* Execute the allocator pre-allocate operation to get the next available resources.\r
- * NORMALLY CHECKED AGAINST THE POLICY */\r
opInfo.operation = Rm_allocatorOp_PRE_ALLOCATE;\r
- \r
- /* If the pre-allocate operation succeeds the resourceInfo field pointed to\r
- * by opInfo will contain the next available resources that satisfy the\r
- * resource properties */\r
retVal = Rm_allocatorOperation(rmInst, &opInfo);\r
}\r
\r
\r
void Rm_transactionProcessor (Rm_Inst *rmInst, Rm_Transaction *transaction)\r
{\r
- void *validInstNode;\r
+ void *validInstNode;\r
+ uint32_t allocType = 0;\r
\r
/* Handle auto-forwarded transactions. These transactions include:\r
* - All request transactions received on Clients are forwarded to the Client Delegate\r
}\r
}\r
else {\r
- /* Try to complete the allocation/free request */\r
- if ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||\r
- (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE)) {\r
- Rm_allocationHandler(rmInst, transaction, validInstNode);\r
+ /* Complete allocation/free request */\r
+ if (transaction->type == Rm_service_RESOURCE_FREE) {\r
+ Rm_freeHandler(rmInst, transaction, validInstNode);\r
}\r
else {\r
- Rm_freeHandler(rmInst, transaction, validInstNode);\r
+ switch (transaction->type) {\r
+ case Rm_service_RESOURCE_ALLOCATE_INIT:\r
+ RM_POLICY_SET_PERM(allocType, RM_POLICY_PERM_INIT_SHIFT, 1);\r
+ break;\r
+ case Rm_service_RESOURCE_ALLOCATE_USE:\r
+ RM_POLICY_SET_PERM(allocType, RM_POLICY_PERM_USE_SHIFT, 1); \r
+ break;\r
+ }\r
+ Rm_allocationHandler(rmInst, transaction, validInstNode, allocType);\r
}\r
}\r
break;\r
{\r
Rm_Inst *rmInst = (Rm_Inst *) rmHandle;\r
Rm_Allocator *allocator = rmInst->allocators;\r
+ Rm_AllocatedTo *allocatedTo;\r
Rm_ResourceTree *treeRoot;\r
Rm_ResourceNode *treeNode;\r
\r
Rm_osalLog("NOT ALLOCATED\n");\r
}\r
else {\r
- Rm_osalLog("allocated to %s\n", \r
- Rm_policyGetValidInstNodeName(treeNode->allocatedTo->instNameNode));\r
+ allocatedTo = treeNode->allocatedTo;\r
+ Rm_osalLog("allocated to ");\r
+ while (allocatedTo) {\r
+ Rm_osalLog(" %s", Rm_policyGetValidInstNodeName(allocatedTo->instNameNode));\r
+ allocatedTo = allocatedTo->nextAllocatedTo;\r
+ }\r
+ Rm_osalLog("\n");\r
}\r
} \r
allocator = allocator->nextAllocator;\r
/* Create valid instance list from policy. Must be done prior to parsing\r
* GRL so that Linux resources can be reserved correctly */\r
rmInst->validInstances = Rm_policyCreateValidInstTree(policyDtb, result);\r
+ /* Validate policy assignment strings */\r
+ *result = Rm_policyValidatePolicy(rmInst, policyDtb);\r
+ rmInst->policy = policyDtb;\r
}\r
\r
/* RM Server specific actions */\r
}\r
\r
if ((rmInst->instType != Rm_instType_CLIENT) && initCfg->policy) {\r
- *result = Rm_policyValidatePolicy(rmInst, policyDtb);\r
+ *result = Rm_policyValidatePolicyResourceNames(rmInst, policyDtb);\r
} \r
\r
return ((Rm_Handle) rmInst);\r
diff --git a/src/rm_dtb_util.c b/src/rm_dtb_util.c
index e79c430a42f668d481c0141a4b0f031446afa414..d33ff91238ec9e455eb737fee6cd3d926e1440fd 100644 (file)
--- a/src/rm_dtb_util.c
+++ b/src/rm_dtb_util.c
Rm_NsAssignment *startAssignment = NULL;
Rm_NsAssignment *newAssignment = NULL;
Rm_NsAssignment *prevAssignment = NULL;
- int8_t i = 0;
+ int32_t i = 0;
uint16_t j;
/* NameServer assignments are stored in the DTB as a null-terminated character
@@ -509,7 +509,7 @@ Rm_PolicyAssignment *Rm_policyExtractAssignments(const void *dtbDataPtr, int32_t
Rm_PolicyAssignment *startAssignment = NULL;
Rm_PolicyAssignment *newAssignment = NULL;
Rm_PolicyAssignment *prevAssignment = NULL;
- int8_t i = 0;
+ int32_t i = 0;
uint16_t j;
/* Policy assignments are stored in the DTB as two 32-bit words containing a
@@ -615,7 +615,7 @@ Rm_PolicyValidInst *Rm_policyExtractValidInstances(const void *dtbDataPtr, int32
Rm_PolicyValidInst *startInst = NULL;
Rm_PolicyValidInst *newInst = NULL;
Rm_PolicyValidInst *prevInst = NULL;
- int8_t i = 0;
+ int32_t i = 0;
/* Valid RM instances are stored in the DTB as a list of null-terminated character
* strings. */
@}
*/
-
diff --git a/src/rm_policy.c b/src/rm_policy.c
index e870a5fab9eb9f57e52f5b61d81b582162b737e6..8e5c156f8332b01d41425a8f0f04a07b187ecd8b 100644 (file)
--- a/src/rm_policy.c
+++ b/src/rm_policy.c
@@ -319,6 +319,7 @@ Rm_PolicyPermission *Rm_policyParseSubPermission(char *permStrStart, char *permS
/* Look on right of instance group for permission assignments. */
permStrPtr = subgroupEnd + 1;
+ assignmentRight = FALSE;
while (permStrPtr < permStrEnd) {
if (assignmentLeft && (!isspace(*permStrPtr))) {
/* There should be nothing but spaces on right if assignment was already found on left */
@@ -415,7 +416,7 @@ Rm_PolicyPermission *Rm_policyParseSubPermission(char *permStrStart, char *permS
permStrPtr++;
}
- *result = RM_INIT_OK;
+ Rm_osalFree((void *)permStrStart, sizeof(permStrLen));
return (startPerm);
}
{
Rm_PolicyPermission *nextPerm;
- while (permissionList != NULL) {
+ while (permissionList) {
nextPerm = permissionList->nextPermission;
Rm_osalFree((void *)permissionList, sizeof(Rm_PolicyPermission));
permissionList = nextPerm;
@@ -452,7 +453,7 @@ Rm_PolicyPermission *Rm_policyGetAssignmentPermissions(Rm_PolicyAssignment *assi
newPerm = Rm_policyParseSubPermission(permStrStart, permStrEnd, result);
- if (*result != RM_INIT_OK) {
+ if (*result != RM_SERVICE_PROCESSING) {
/* Delete the permission list that's been created thus far, return
* the error and NULL for the permission list */
Rm_policyFreeAssignmentPermissions(startPerm);
@@ -460,7 +461,6 @@ Rm_PolicyPermission *Rm_policyGetAssignmentPermissions(Rm_PolicyAssignment *assi
}
if (prevPerm == NULL) {
- /* Save the first sub-permission in the list so it can be returned */
startPerm = newPerm;
}
else {
@@ -479,7 +479,6 @@ Rm_PolicyPermission *Rm_policyGetAssignmentPermissions(Rm_PolicyAssignment *assi
permStrStart = permStrEnd + 1;
}
- *result = RM_INIT_OK;
return(startPerm);
}
return (node->name);
}
+bool Rm_policyCheckPrivilege(Rm_PolicyCheckCfg *privilegeCfg, int32_t *result)
+{
+ Rm_ValidInstNode *instNode = (Rm_ValidInstNode *)privilegeCfg->validInstNode;
+ int32_t propertyOffset;
+ const char *propertyName;
+ 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;
+
+ /* Get the resource's assignments */
+ propertyOffset = fdt_first_property_offset(privilegeCfg->policyDtb, privilegeCfg->resourcePolicy);
+ if (propertyOffset > RM_DTB_UTIL_STARTING_NODE_OFFSET) {
+ while (propertyOffset > RM_DTB_UTIL_STARTING_NODE_OFFSET) {
+ propertyData = fdt_getprop_by_offset(privilegeCfg->policyDtb, propertyOffset, &propertyName, &propertyLen);
+ if (Rm_policyGetPropertyType(propertyName) == Rm_policyPropType_ASSIGNMENTS) {
+ assignment = assignmentStart = Rm_policyExtractAssignments(propertyData, propertyLen);
+ break;
+ }
+ propertyOffset = fdt_next_property_offset(privilegeCfg->policyDtb, propertyOffset);
+ }
+ }
+
+ if (assignment) {
+ while (assignment) {
+ assignmentEnd = assignment->resourceBase + assignment->resourceLength - 1;
+ foundInstance = FALSE;
+ if (((privilegeCfg->resourceBase >= assignment->resourceBase) &&
+ (privilegeCfg->resourceBase <= assignmentEnd)) ||
+ ((privilegeCfg->resourceBase < assignment->resourceBase) &&
+ (resourceEnd > assignmentEnd)) ||
+ ((resourceEnd >= assignment->resourceBase) &&
+ (resourceEnd <= assignmentEnd))) {
+
+ permission = permissionStart = Rm_policyGetAssignmentPermissions(assignment, result);
+ while (permission) {
+ if ((strcmp(permission->instName, instNode->name) == 0) ||
+ (strcmp(permission->instName, Rm_policyAllInstances) == 0)) {
+ foundInstance = TRUE;
+
+ /* Check instance's permissions */
+ if (privilegeCfg->type == Rm_policyCheck_INIT) {
+ if (!RM_POLICY_GET_PERM(permission->permissionBits, RM_POLICY_PERM_INIT_SHIFT)) {
+ Rm_policyFreeAssignmentPermissions(permissionStart);
+ Rm_policyFreeAssignments(assignmentStart);
+ return(FALSE);
+ }
+ }
+ else if (privilegeCfg->type == Rm_policyCheck_USE) {
+ if (!RM_POLICY_GET_PERM(permission->permissionBits, RM_POLICY_PERM_USE_SHIFT)) {
+ Rm_policyFreeAssignmentPermissions(permissionStart);
+ Rm_policyFreeAssignments(assignmentStart);
+ return(FALSE);
+ }
+ }
+ else if (privilegeCfg->type == Rm_policyCheck_EXCLUSIVE) {
+ if (!RM_POLICY_GET_PERM(permission->permissionBits, RM_POLICY_PERM_EXCLUSIVE_SHIFT)) {
+ Rm_policyFreeAssignmentPermissions(permissionStart);
+ Rm_policyFreeAssignments(assignmentStart);
+ return(FALSE);
+ }
+ }
+ break;
+ }
+ permission = permission->nextPermission;
+ }
+
+ Rm_policyFreeAssignmentPermissions(permissionStart);
+ if (!foundInstance) {
+ Rm_policyFreeAssignments(assignmentStart);
+ return(FALSE);
+ }
+ }
+ assignment = assignment->nextAssignment;
+ }
+ Rm_policyFreeAssignments(assignmentStart);
+ }
+ else {
+ return(FALSE);
+ }
+
+ return(TRUE);
+}
+
+uint32_t Rm_policyGetResourceBase(void *policyDtb, void *validInstNode,
+ int32_t resourcePolicy, uint32_t allocType,
+ int32_t *result)
+
+{
+ Rm_ValidInstNode *instNode = (Rm_ValidInstNode *)validInstNode;
+ int32_t propertyOffset;
+ const char *propertyName;
+ 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;
+
+ propertyOffset = fdt_first_property_offset(policyDtb, resourcePolicy);
+ 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 (Rm_policyGetPropertyType(propertyName) == Rm_policyPropType_ASSIGNMENTS) {
+ assignment = assignmentStart = Rm_policyExtractAssignments(propertyData, propertyLen);
+ break;
+ }
+ propertyOffset = fdt_next_property_offset(policyDtb, propertyOffset);
+ }
+ }
+
+ /* Search policy permissions for a valid resource base */
+ if (assignment) {
+ while (assignment) {
+ permission = permissionStart = Rm_policyGetAssignmentPermissions(assignment, result);
+ while (permission) {
+ if ((strcmp(permission->instName, instNode->name) == 0) ||
+ (strcmp(permission->instName, Rm_policyAllInstances) == 0)) {
+ /* Check instance's permissions */
+ if (RM_POLICY_GET_PERM(allocType, RM_POLICY_PERM_INIT_SHIFT)) {
+ if (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)) {
+ if (RM_POLICY_GET_PERM(permission->permissionBits, RM_POLICY_PERM_USE_SHIFT)) {
+ resourceBase = assignment->resourceBase;
+ break;
+ }
+ }
+ }
+ permission = permission->nextPermission;
+ }
+ Rm_policyFreeAssignmentPermissions(permissionStart);
+
+ if (resourceBase) {
+ break;
+ }
+ else {
+ assignment = assignment->nextAssignment;
+ }
+ }
+ Rm_policyFreeAssignments(assignmentStart);
+ }
+ else {
+ *result = RM_SERVICE_DENIED_NO_RANGE_ASSIGNMENTS_FOR_POLICY;
+ }
+
+ return(resourceBase);
+}
+
+uint32_t Rm_policyGetResourceAlignment(void *policyDtb, int32_t resourcePolicy)
+{
+ int32_t propertyOffset;
+ const char *propertyName;
+ int32_t propertyLen;
+ const void *propertyData;
+ Rm_ResourceValue *alignmentList;
+ uint32_t resourceAlignment = 0;
+
+ propertyOffset = fdt_first_property_offset(policyDtb, resourcePolicy);
+ 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 (Rm_policyGetPropertyType(propertyName) == Rm_policyPropType_ALLOCATION_ALIGNMENTS) {
+ alignmentList = Rm_policyExtractResourceAlignments(propertyData, propertyLen);
+ resourceAlignment = alignmentList->value;
+ Rm_policyFreeResourceAlignments(alignmentList);
+ }
+ propertyOffset = fdt_next_property_offset(policyDtb, propertyOffset);
+ }
+ }
+ return(resourceAlignment);
+}
+
+int32_t Rm_policyGetResourcePolicy(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 (strcmp(nodeName, resourceName) == 0)
+ {
+ break;
+ }
+ }
+ return(nodeOffset);
+}
+
void *Rm_policyGetLinuxInstNode(void * validInstTree)
{
char linuxName[] = RM_ALLOCATED_TO_LINUX;
return (Rm_policyGetValidInstNode(validInstTree, linuxName));
}
+int32_t Rm_policyValidatePolicyResourceNames(Rm_Inst *rmInst, void *policyDtb)
+{
+ int32_t nodeOffset;
+ int32_t depth;
+ const char *nodeName;
+
+ depth = RM_DTB_UTIL_STARTING_DEPTH;
+ nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;
+
+ /* 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)) {
+ nodeOffset = fdt_next_node(policyDtb, nodeOffset, &depth);
+ nodeName = fdt_get_name(policyDtb, nodeOffset, NULL);
+ if (fdt_first_property_offset(policyDtb, nodeOffset) > RM_DTB_UTIL_STARTING_NODE_OFFSET) {
+ if (Rm_allocatorFind(rmInst, (char *)nodeName) == NULL) {
+ /* No allocator tied to resource name */
+ return(RM_INIT_ERROR_POLICY_UNKNOWN_RESOURCE);
+ }
+ }
+ }
+ return(RM_INIT_OK);
+}
+
/* TODO: ADD ABILITY TO RETURN THE SYNTAX ERROR LOCATION */
int32_t Rm_policyValidatePolicy(Rm_Inst *rmInst, void *policyDtb)
{
int32_t nodeOffset;
int32_t propertyOffset;
int32_t depth;
- const char *nodeName;
const char *propertyName;
int32_t propertyLen;
const void *propertyData;
- Rm_PolicyPropType propertyType;
Rm_PolicyAssignment *assignmentList;
int32_t result;
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);
- propertyOffset = fdt_first_property_offset(policyDtb, nodeOffset);
- if (propertyOffset > RM_DTB_UTIL_STARTING_NODE_OFFSET) {
- if (Rm_allocatorFind(rmInst, (char *)nodeName) == NULL) {
- /* No allocator tied to resource name */
- return(RM_INIT_ERROR_POLICY_UNKNOWN_RESOURCE);
- }
+ propertyOffset = fdt_first_property_offset(policyDtb, nodeOffset);
+ while (propertyOffset > RM_DTB_UTIL_STARTING_NODE_OFFSET) {
+ propertyData = fdt_getprop_by_offset(policyDtb, propertyOffset, &propertyName, &propertyLen);
+ if (Rm_policyGetPropertyType(propertyName) == Rm_policyPropType_ASSIGNMENTS) {
+ assignmentList = Rm_policyExtractAssignments(propertyData, propertyLen);
- while (propertyOffset > RM_DTB_UTIL_STARTING_NODE_OFFSET) {
- propertyData = fdt_getprop_by_offset(policyDtb, propertyOffset, &propertyName, &propertyLen);
- propertyType = Rm_policyGetPropertyType(propertyName);
- if (propertyType == Rm_policyPropType_ASSIGNMENTS) {
- assignmentList = Rm_policyExtractAssignments(propertyData, propertyLen);
-
- if ((result = Rm_policyValidateAssignmentPermissions((Rm_ValidInstTree *) rmInst->validInstances,
- assignmentList)) != RM_INIT_OK) {
- Rm_policyFreeAssignments(assignmentList);
- return(result);
- }
+ if ((result = Rm_policyValidateAssignmentPermissions((Rm_ValidInstTree *) rmInst->validInstances,
+ assignmentList)) != RM_INIT_OK) {
Rm_policyFreeAssignments(assignmentList);
+ return(result);
}
- propertyOffset = fdt_next_property_offset(policyDtb, propertyOffset);
+ Rm_policyFreeAssignments(assignmentList);
}
+ propertyOffset = fdt_next_property_offset(policyDtb, propertyOffset);
}
}
return(RM_INIT_OK);
diff --git a/test/rm_test.c b/test/rm_test.c
index ea44165a062d28f986be12c73e0c3b27cddc6fcb..3d058478b993c756fe2be8ac9e83a082b8665fd1 100644 (file)
--- a/test/rm_test.c
+++ b/test/rm_test.c
char aifName[RM_RESOURCE_NAME_MAX_CHARS] = "aif-rx-ch";
char memRegionName[RM_RESOURCE_NAME_MAX_CHARS] = "memory-regions";
+
+
+ /* Issue the service request create a new NameServer object via the service port */
+ requestInfo.type = Rm_service_RESOURCE_ALLOCATE_USE;
+ requestInfo.resourceName = resourceName;
+ requestInfo.resourceBase = RM_RESOURCE_BASE_UNSPECIFIED;
+ requestInfo.resourceLength = 1;
+ requestInfo.resourceAlignment = 0;
+ requestInfo.callback.serviceCallback = testServiceCallback;
+
+ System_printf("Core %d: %s Allocating resource...\n", MultiProc_self(), rmServerName);
+ rmServerServicePort->rmService(rmServerServicePort->rmHandle, &requestInfo, &responseInfo);
+ if (blockForResponse(&responseInfo))
+ {
+ System_printf("Core %d: %s allocated resource: %s base: %d length: %d\n", MultiProc_self(),
+ rmServerName,
+ responseInfo.resourceName,
+ responseInfo.resourceBase,
+ responseInfo.resourceLength);
+ }
+
+ Rm_printResourceStatus(rmServerHandle);
+
+
+ /* Issue the service request create a new NameServer object via the service port */
+ requestInfo.type = Rm_service_RESOURCE_ALLOCATE_USE;
+ requestInfo.resourceName = resourceName;
+ requestInfo.resourceBase = RM_RESOURCE_BASE_UNSPECIFIED;
+ requestInfo.resourceLength = 1;
+ requestInfo.resourceAlignment = RM_RESOURCE_ALIGNMENT_UNSPECIFIED;
+ requestInfo.callback.serviceCallback = testServiceCallback;
+
+ System_printf("Core %d: %s Allocating resource...\n", MultiProc_self(), rmServerName);
+ rmServerServicePort->rmService(rmServerServicePort->rmHandle, &requestInfo, &responseInfo);
+ if (blockForResponse(&responseInfo))
+ {
+ System_printf("Core %d: %s allocated resource: %s base: %d length: %d\n", MultiProc_self(),
+ rmServerName,
+ responseInfo.resourceName,
+ responseInfo.resourceBase,
+ responseInfo.resourceLength);
+ }
+
+ Rm_printResourceStatus(rmServerHandle);
+
+ /* Issue the service request create a new NameServer object via the service port */
+ requestInfo.type = Rm_service_RESOURCE_ALLOCATE_USE;
+ requestInfo.resourceName = resourceName;
+ requestInfo.resourceBase = RM_RESOURCE_BASE_UNSPECIFIED;
+ requestInfo.resourceLength = 1;
+ requestInfo.resourceAlignment = 200;
+ requestInfo.callback.serviceCallback = testServiceCallback;
+
+ System_printf("Core %d: %s Allocating resource...\n", MultiProc_self(), rmServerName);
+ rmServerServicePort->rmService(rmServerServicePort->rmHandle, &requestInfo, &responseInfo);
+ if (blockForResponse(&responseInfo))
+ {
+ System_printf("Core %d: %s allocated resource: %s base: %d length: %d\n", MultiProc_self(),
+ rmServerName,
+ responseInfo.resourceName,
+ responseInfo.resourceBase,
+ responseInfo.resourceLength);
+ }
+
+ Rm_printResourceStatus(rmServerHandle);
+
+
/* Issue the service request create a new NameServer object via the service port */
requestInfo.type = Rm_service_RESOURCE_MAP_TO_NAME;
requestInfo.resourceName = resourceName;
Rm_printResourceStatus(rmServerHandle);
memset((void *) &requestInfo, 0, sizeof(Rm_ServiceReqInfo));
- requestInfo.type = Rm_service_RESOURCE_FREE;
+ requestInfo.type = Rm_service_RESOURCE_ALLOCATE_USE;
requestInfo.resourceName = aifName;
- requestInfo.resourceBase = 29;
+ requestInfo.resourceBase = 53;
requestInfo.resourceLength = 2;
requestInfo.callback.serviceCallback = testServiceCallback;
rmServerServicePort->rmService(rmServerServicePort->rmHandle, &requestInfo, &responseInfo);
if (blockForResponse(&responseInfo))
{
- System_printf("Core %d: %s freed resource: %s base: %d length: %d\n", MultiProc_self(),
+ System_printf("Core %d: %s allocate resource: %s base: %d length: %d\n", MultiProc_self(),
rmServerName,
requestInfo.resourceName,
requestInfo.resourceBase,
requestInfo.resourceLength);
}
memset((void *) &requestInfo, 0, sizeof(Rm_ServiceReqInfo));
- requestInfo.type = Rm_service_RESOURCE_FREE;
+ requestInfo.type = Rm_service_RESOURCE_ALLOCATE_USE;
requestInfo.resourceName = aifName;
- requestInfo.resourceBase = 46;
- requestInfo.resourceLength = 4;
+ requestInfo.resourceBase = 2;
+ requestInfo.resourceLength = 2;
requestInfo.callback.serviceCallback = testServiceCallback;
System_printf("Core %d: %s freeing resource...\n", MultiProc_self(), rmServerName);
rmServerServicePort->rmService(rmServerServicePort->rmHandle, &requestInfo, &responseInfo);
if (blockForResponse(&responseInfo))
{
- System_printf("Core %d: %s freed resource: %s base: %d length: %d\n", MultiProc_self(),
+ System_printf("Core %d: %s allocate resource: %s base: %d length: %d\n", MultiProc_self(),
rmServerName,
requestInfo.resourceName,
requestInfo.resourceBase,
requestInfo.resourceName = accumChName;
requestInfo.resourceBase = RM_RESOURCE_BASE_UNSPECIFIED;
requestInfo.resourceLength = 2;
- requestInfo.resourceAlignment = RM_RESOURCE_ALIGNMENT_UNSPECIFIED;
+ requestInfo.resourceAlignment = 1;
requestInfo.callback.serviceCallback = testServiceCallback;
System_printf("Core %d: %s Allocating resource...\n", MultiProc_self(), rmClientName);
requestInfo.resourceName = accumChName;
requestInfo.resourceBase = RM_RESOURCE_BASE_UNSPECIFIED;
requestInfo.resourceLength = 2;
- requestInfo.resourceAlignment = 20;
+ requestInfo.resourceAlignment = RM_RESOURCE_ALIGNMENT_UNSPECIFIED;
requestInfo.callback.serviceCallback = testServiceCallback;
System_printf("Core %d: %s Allocating resource...\n", MultiProc_self(), rmClientName);