refactor: allocate vcpu structures from heap

On SoCs with large number of physical cores, hafnium memory footprint
gets very large, since the vm and vcpu structures are allocated
statically based on build time constants (MAX_VMS, MAX_CPUS). This patch
changes the code so that vcpu structures are allocated from the heap and
based on vcpu count in the manifest, as opposed to statically. This
gives huge savings since a lot of SPs need only be UP SPs, and combined
with previous changes where the first boot SP need not be an MP SP, thus
removing any mandates of presence of MP SPs in the system, provides
large reduction in memory footprint of the hafnium SPMC image.

Change-Id: I8c161d3bc164715e9218626e6839c7a213b8e8da
Signed-off-by: Raghu Krishnamurthy <raghu.ncstate@gmail.com>
diff --git a/src/vm.c b/src/vm.c
index 514c74c..896b0ef 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -54,6 +54,9 @@
 {
 	uint32_t i;
 	struct vm *vm;
+	size_t vcpu_ppool_entries = (align_up(sizeof(struct vcpu) * vcpu_count,
+					      MM_PPOOL_ENTRY_SIZE) /
+				     MM_PPOOL_ENTRY_SIZE);
 
 	if (id == HF_OTHER_WORLD_ID) {
 		CHECK(el0_partition == false);
@@ -74,6 +77,10 @@
 
 	vm->id = id;
 	vm->vcpu_count = vcpu_count;
+
+	vm->vcpus = (struct vcpu *)mpool_alloc_contiguous(
+		ppool, vcpu_ppool_entries, 1);
+	CHECK(vm->vcpus != NULL);
 	vm->mailbox.state = MAILBOX_STATE_EMPTY;
 	atomic_init(&vm->aborting, false);
 	vm->el0_partition = el0_partition;
@@ -460,7 +467,7 @@
 	to_check = vm_get_notifications(vm_locked, from_vm);
 
 	/* Check if there are pending per vcpu notifications */
-	for (uint32_t i = 0U; i < MAX_CPUS; i++) {
+	for (uint32_t i = 0U; i < vm_locked.vm->vcpu_count; i++) {
 		if ((to_check->per_vcpu[i].pending & notifications) != 0U) {
 			return true;
 		}
@@ -488,7 +495,7 @@
 bool vm_are_per_vcpu_notifications_pending(struct vm_locked vm_locked,
 					   ffa_vcpu_index_t vcpu_id)
 {
-	CHECK(vcpu_id < MAX_CPUS);
+	CHECK(vcpu_id < vm_locked.vm->vcpu_count);
 
 	return vm_get_notifications(vm_locked, true)
 			       ->per_vcpu[vcpu_id]
@@ -700,7 +707,7 @@
 	struct notifications_state *state;
 
 	CHECK(vm_locked.vm != NULL);
-	CHECK(vcpu_id < MAX_CPUS);
+	CHECK(vcpu_id < vm_locked.vm->vcpu_count);
 
 	to_set = vm_get_notifications(vm_locked, is_from_vm);
 
@@ -764,7 +771,7 @@
 
 	assert(vm_locked.vm != NULL);
 	to_get = vm_get_notifications(vm_locked, is_from_vm);
-	assert(vcpu_id < MAX_CPUS);
+	assert(vcpu_id < vm_locked.vm->vcpu_count);
 
 	to_ret = vm_notifications_state_get_pending(&to_get->global);
 	to_ret |=