Don't use more memory groups than declared

The number of usable memory groups is limited by the constant limit
MEMORY_GROUP_MANAGER_NR_GROUPS but also by the number of groups actually
declared.  Check both limits during allocation.

Bug: 201677538
Signed-off-by: Sean Callanan <spyffe@google.com>
Change-Id: Id23264452a8472e7589ffce3c6bc87cf0552ca32
diff --git a/mali_pixel/memory_group_manager.c b/mali_pixel/memory_group_manager.c
index d057148..5c98a5d 100644
--- a/mali_pixel/memory_group_manager.c
+++ b/mali_pixel/memory_group_manager.c
@@ -94,6 +94,7 @@
  * struct mgm_groups - Structure for groups of memory group manager
  *
  * @groups: To keep track of the number of allocated pages of all groups
+ * @ngroups: Number of groups actually used
  * @dev: device attached
  * @pt_handle: Link to SLC partition data
  * @kobj: &sruct kobject used for linking to pixel_stats_sysfs node
@@ -104,6 +105,7 @@
  */
 struct mgm_groups {
 	struct mgm_group groups[MEMORY_GROUP_MANAGER_NR_GROUPS];
+	size_t ngroups;
 	struct device *dev;
 	struct pt_handle *pt_handle;
 	struct kobject kobj;
@@ -397,6 +399,10 @@
 	if (INVALID_GROUP_ID(group_id))
 		return NULL;
 
+	if (WARN_ON_ONCE((group_id != MGM_RESERVED_GROUP_ID) &&
+			 (GROUP_ID_TO_PT_IDX(group_id) >= data->ngroups)))
+		return NULL;
+
 	/* We don't expect to be allocting pages into the group used for
 	 * external or imported memory
 	 */
@@ -596,6 +602,14 @@
 {
 	int i, ret;
 
+	const int ngroups = of_property_count_strings(mgm_data->dev->of_node, "pt_id");
+	if (WARN_ON(ngroups < 0) ||
+	    WARN_ON(ngroups > MEMORY_GROUP_MANAGER_NR_GROUPS)) {
+		mgm_data->ngroups = 0;
+	} else {
+		mgm_data->ngroups = ngroups;
+	}
+
 	for (i = 0; i < MEMORY_GROUP_MANAGER_NR_GROUPS; i++) {
 		atomic_set(&mgm_data->groups[i].size, 0);
 		atomic_set(&mgm_data->groups[i].lp_size, 0);