SPCI: Add tests for N constituents per memory region

Extend the test suite to exercise the functionality of sharing multiple
constituents per memory region.

Bug: 132420445
Change-Id: I583f412d80dc4e72410e44d6d48716965d3fd2f4
diff --git a/test/vmapi/primary_with_secondaries/memory_sharing.c b/test/vmapi/primary_with_secondaries/memory_sharing.c
index f1a3f10..daf5227 100644
--- a/test/vmapi/primary_with_secondaries/memory_sharing.c
+++ b/test/vmapi/primary_with_secondaries/memory_sharing.c
@@ -25,7 +25,7 @@
 #include "primary_with_secondary.h"
 #include "util.h"
 
-alignas(PAGE_SIZE) static uint8_t page[PAGE_SIZE];
+alignas(PAGE_SIZE) static uint8_t pages[4 * PAGE_SIZE];
 
 /**
  * Helper function to test sending memory in the different configurations.
@@ -187,15 +187,15 @@
 {
 	struct spci_value run_res;
 	struct mailbox_buffers mb = set_up_mailbox();
-	uint8_t *ptr = page;
+	uint8_t *ptr = pages;
 	uint32_t msg_size;
 	struct spci_memory_region_constituent constituents[] = {
-		{.address = (uint64_t)page, .page_count = 1},
+		{.address = (uint64_t)pages, .page_count = 1},
 	};
 
 	SERVICE_SELECT(SERVICE_VM1, "memory_increment", mb.send);
 
-	memset_s(ptr, sizeof(page), 'a', PAGE_SIZE);
+	memset_s(ptr, sizeof(pages), 'a', PAGE_SIZE);
 
 	msg_size = spci_memory_init(
 		mb.send, SPCI_MEMORY_SHARE, SERVICE_VM1, constituents,
@@ -212,7 +212,7 @@
 	EXPECT_EQ(run_res.func, SPCI_YIELD_32);
 
 	for (int i = 0; i < PAGE_SIZE; ++i) {
-		page[i] = i;
+		pages[i] = i;
 	}
 
 	run_res = spci_run(SERVICE_VM1, 0);
@@ -221,7 +221,7 @@
 	for (int i = 0; i < PAGE_SIZE; ++i) {
 		uint8_t value = i + 1;
 
-		EXPECT_EQ(page[i], value);
+		EXPECT_EQ(pages[i], value);
 	}
 }
 
@@ -232,16 +232,16 @@
 {
 	struct spci_value run_res;
 	struct mailbox_buffers mb = set_up_mailbox();
-	uint8_t *ptr = page;
+	uint8_t *ptr = pages;
 	uint32_t msg_size;
 	struct spci_memory_region_constituent constituents[] = {
-		{.address = (uint64_t)page, .page_count = 1},
+		{.address = (uint64_t)pages, .page_count = 1},
 	};
 
 	SERVICE_SELECT(SERVICE_VM1, "spci_memory_lend_relinquish", mb.send);
 
 	/* Dirty the memory before sharing it. */
-	memset_s(ptr, sizeof(page), 'b', PAGE_SIZE);
+	memset_s(ptr, sizeof(pages), 'b', PAGE_SIZE);
 
 	msg_size = spci_memory_share_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
@@ -292,16 +292,17 @@
 {
 	struct spci_value run_res;
 	struct mailbox_buffers mb = set_up_mailbox();
-	uint8_t *ptr = page;
+	uint8_t *ptr = pages;
 	uint32_t msg_size;
 
 	SERVICE_SELECT(SERVICE_VM1, "spci_memory_lend_relinquish", mb.send);
 
 	/* Initialise the memory before giving it. */
-	memset_s(ptr, sizeof(page), 'b', PAGE_SIZE);
+	memset_s(ptr, sizeof(pages), 'b', PAGE_SIZE);
 
 	struct spci_memory_region_constituent constituents[] = {
-		{.address = (uint64_t)page, .page_count = 1},
+		{.address = (uint64_t)pages, .page_count = 1},
+		{.address = (uint64_t)pages + PAGE_SIZE, .page_count = 2},
 	};
 
 	msg_size = spci_memory_lend_init(
@@ -335,16 +336,16 @@
 {
 	struct spci_value run_res;
 	struct mailbox_buffers mb = set_up_mailbox();
-	uint8_t *ptr = page;
+	uint8_t *ptr = pages;
 	uint32_t msg_size;
 	struct spci_memory_region_constituent constituents[] = {
-		{.address = (uint64_t)page, .page_count = 1},
+		{.address = (uint64_t)pages, .page_count = 1},
 	};
 
 	SERVICE_SELECT(SERVICE_VM1, "spci_memory_return", mb.send);
 
 	/* Dirty the memory before giving it. */
-	memset_s(ptr, sizeof(page), 'b', PAGE_SIZE);
+	memset_s(ptr, sizeof(pages), 'b', PAGE_SIZE);
 
 	msg_size = spci_memory_donate_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
@@ -374,16 +375,16 @@
 {
 	struct spci_value run_res;
 	struct mailbox_buffers mb = set_up_mailbox();
-	uint8_t *ptr = page;
+	uint8_t *ptr = pages;
 	uint32_t msg_size;
 	struct spci_memory_region_constituent constituents[] = {
-		{.address = (uint64_t)page, .page_count = 1},
+		{.address = (uint64_t)pages, .page_count = 1},
 	};
 
 	SERVICE_SELECT(SERVICE_VM1, "spci_memory_lend_relinquish", mb.send);
 
 	/* Dirty the memory before lending it. */
-	memset_s(ptr, sizeof(page), 'c', PAGE_SIZE);
+	memset_s(ptr, sizeof(pages), 'c', PAGE_SIZE);
 
 	msg_size = spci_memory_lend_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
@@ -415,7 +416,7 @@
 	struct mailbox_buffers mb = set_up_mailbox();
 	uint32_t msg_size;
 	struct spci_memory_region_constituent constituents[] = {
-		{.address = (uint64_t)page, .page_count = 1},
+		{.address = (uint64_t)pages, .page_count = 1},
 	};
 
 	SERVICE_SELECT(SERVICE_VM1, "spci_memory_lend_relinquish", mb.send);
@@ -459,7 +460,7 @@
 	struct mailbox_buffers mb = set_up_mailbox();
 	uint32_t msg_size;
 	struct spci_memory_region_constituent constituents[] = {
-		{.address = (uint64_t)page, .page_count = 1},
+		{.address = (uint64_t)pages, .page_count = 1},
 	};
 
 	SERVICE_SELECT(SERVICE_VM1, "spci_memory_lend_relinquish", mb.send);
@@ -565,18 +566,27 @@
 {
 	struct spci_value run_res;
 	struct mailbox_buffers mb = set_up_mailbox();
-	uint8_t *ptr = page;
+	uint8_t *ptr = pages;
 	uint32_t msg_size;
 
 	SERVICE_SELECT(SERVICE_VM1, "spci_donate_check_upper_bound", mb.send);
+	SERVICE_SELECT(SERVICE_VM2, "spci_donate_check_upper_bound", mb.send);
 
 	/* Initialise the memory before giving it. */
-	memset_s(ptr, sizeof(page), 'b', 1 * PAGE_SIZE);
+	memset_s(ptr, sizeof(pages), 'b', 4 * PAGE_SIZE);
 
+	/* Specify non-contiguous memory regions. */
 	struct spci_memory_region_constituent constituents[] = {
-		{.address = (uint64_t)page, .page_count = 1},
+		{.address = (uint64_t)pages, .page_count = 1},
+		{.address = (uint64_t)pages + PAGE_SIZE * 2, .page_count = 1},
 	};
 
+	/*
+	 * Specify that we want to test the first constituent of the donated
+	 * memory region. This is utilised by the test service.
+	 */
+	pages[0] = 0;
+
 	msg_size = spci_memory_donate_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
 		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
@@ -586,9 +596,33 @@
 			  .func,
 		  SPCI_SUCCESS_32);
 
-	/* Observe the service faulting when accessing the memory. */
+	/* Observe the service faulting when accessing out of bounds. */
 	run_res = spci_run(SERVICE_VM1, 0);
 	EXPECT_SPCI_ERROR(run_res, SPCI_ABORTED);
+
+	/* Use different memory regions for verifying the second constituent. */
+	constituents[0].address = (uint64_t)pages + PAGE_SIZE * 1;
+	constituents[1].address = (uint64_t)pages + PAGE_SIZE * 3;
+
+	/*
+	 * Specify that we now want to test the second constituent of the
+	 * donated memory region.
+	 */
+	pages[PAGE_SIZE] = 1;
+
+	/* Use the secondary VM for this test as the first is now aborted. */
+	msg_size = spci_memory_donate_init(
+		mb.send, SERVICE_VM2, constituents, 2, 0, SPCI_MEMORY_RW_X,
+		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
+		SPCI_MEMORY_OUTER_SHAREABLE);
+	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM2, msg_size,
+				SPCI_MSG_SEND_LEGACY_MEMORY)
+			  .func,
+		  SPCI_SUCCESS_32);
+
+	/* Observe the service faulting when accessing out of bounds. */
+	run_res = spci_run(SERVICE_VM2, 0);
+	EXPECT_SPCI_ERROR(run_res, SPCI_ABORTED);
 }
 
 /**
@@ -598,18 +632,27 @@
 {
 	struct spci_value run_res;
 	struct mailbox_buffers mb = set_up_mailbox();
-	uint8_t *ptr = page;
+	uint8_t *ptr = pages;
 	uint32_t msg_size;
 
 	SERVICE_SELECT(SERVICE_VM1, "spci_donate_check_lower_bound", mb.send);
+	SERVICE_SELECT(SERVICE_VM2, "spci_donate_check_lower_bound", mb.send);
 
-	/* Initialise the memory before giving it. */
-	memset_s(ptr, sizeof(page), 'b', 1 * PAGE_SIZE);
+	/* Initialise the memory before donating it. */
+	memset_s(ptr, sizeof(pages), 'b', 4 * PAGE_SIZE);
 
+	/* Specify non-contiguous memory regions. */
 	struct spci_memory_region_constituent constituents[] = {
-		{.address = (uint64_t)page, .page_count = 1},
+		{.address = (uint64_t)pages, .page_count = 1},
+		{.address = (uint64_t)pages + PAGE_SIZE * 2, .page_count = 1},
 	};
 
+	/*
+	 * Specify that we want to test the first constituent of the donated
+	 * memory region. This is utilised by the test service.
+	 */
+	pages[0] = 0;
+
 	msg_size = spci_memory_donate_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
 		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
@@ -619,9 +662,33 @@
 			  .func,
 		  SPCI_SUCCESS_32);
 
-	/* Observe the service faulting when accessing the memory. */
+	/* Observe the service faulting when accessing out of bounds. */
 	run_res = spci_run(SERVICE_VM1, 0);
 	EXPECT_SPCI_ERROR(run_res, SPCI_ABORTED);
+
+	/* Use different memory regions for verifying the second constituent. */
+	constituents[0].address = (uint64_t)pages + PAGE_SIZE * 1;
+	constituents[1].address = (uint64_t)pages + PAGE_SIZE * 3;
+
+	/*
+	 * Specify that we now want to test the second constituent of the
+	 * donated memory region.
+	 */
+	pages[PAGE_SIZE] = 1;
+
+	/* Use the secondary VM for this test as the first is now aborted. */
+	msg_size = spci_memory_donate_init(
+		mb.send, SERVICE_VM2, constituents, 2, 0, SPCI_MEMORY_RW_X,
+		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
+		SPCI_MEMORY_OUTER_SHAREABLE);
+	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM2, msg_size,
+				SPCI_MSG_SEND_LEGACY_MEMORY)
+			  .func,
+		  SPCI_SUCCESS_32);
+
+	/* Observe the service faulting when accessing out of bounds. */
+	run_res = spci_run(SERVICE_VM2, 0);
+	EXPECT_SPCI_ERROR(run_res, SPCI_ABORTED);
 }
 
 /**
@@ -632,17 +699,17 @@
 {
 	struct spci_value run_res;
 	struct mailbox_buffers mb = set_up_mailbox();
-	uint8_t *ptr = page;
+	uint8_t *ptr = pages;
 	uint32_t msg_size;
 
 	SERVICE_SELECT(SERVICE_VM1, "spci_memory_return", mb.send);
 	SERVICE_SELECT(SERVICE_VM2, "spci_memory_return", mb.send);
 
 	/* Initialise the memory before giving it. */
-	memset_s(ptr, sizeof(page), 'b', 1 * PAGE_SIZE);
+	memset_s(ptr, sizeof(pages), 'b', 1 * PAGE_SIZE);
 
 	struct spci_memory_region_constituent constituents[] = {
-		{.address = (uint64_t)page, .page_count = 1},
+		{.address = (uint64_t)pages, .page_count = 1},
 	};
 
 	msg_size = spci_memory_donate_init(
@@ -682,17 +749,17 @@
 {
 	struct spci_value run_res;
 	struct mailbox_buffers mb = set_up_mailbox();
-	uint8_t *ptr = page;
+	uint8_t *ptr = pages;
 	uint32_t msg_size;
 
 	SERVICE_SELECT(SERVICE_VM1, "spci_donate_secondary_and_fault", mb.send);
 	SERVICE_SELECT(SERVICE_VM2, "spci_memory_receive", mb.send);
 
 	/* Initialise the memory before giving it. */
-	memset_s(ptr, sizeof(page), 'b', 1 * PAGE_SIZE);
+	memset_s(ptr, sizeof(pages), 'b', 1 * PAGE_SIZE);
 
 	struct spci_memory_region_constituent constituents[] = {
-		{.address = (uint64_t)page, .page_count = 1},
+		{.address = (uint64_t)pages, .page_count = 1},
 	};
 
 	/* Set up VM2 to wait for message. */
@@ -733,17 +800,17 @@
 {
 	struct spci_value run_res;
 	struct mailbox_buffers mb = set_up_mailbox();
-	uint8_t *ptr = page;
+	uint8_t *ptr = pages;
 	uint32_t msg_size;
 
 	SERVICE_SELECT(SERVICE_VM1, "spci_donate_twice", mb.send);
 	SERVICE_SELECT(SERVICE_VM2, "spci_memory_receive", mb.send);
 
 	/* Initialise the memory before giving it. */
-	memset_s(ptr, sizeof(page), 'b', 1 * PAGE_SIZE);
+	memset_s(ptr, sizeof(pages), 'b', 1 * PAGE_SIZE);
 
 	struct spci_memory_region_constituent constituents[] = {
-		{.address = (uint64_t)page, .page_count = 1},
+		{.address = (uint64_t)pages, .page_count = 1},
 	};
 
 	/* Donate memory to VM1. */
@@ -789,13 +856,13 @@
 TEST(memory_sharing, donate_to_self)
 {
 	struct mailbox_buffers mb = set_up_mailbox();
-	uint8_t *ptr = page;
+	uint8_t *ptr = pages;
 	uint32_t msg_size;
 
 	/* Initialise the memory before giving it. */
-	memset_s(ptr, sizeof(page), 'b', PAGE_SIZE);
+	memset_s(ptr, sizeof(pages), 'b', PAGE_SIZE);
 	struct spci_memory_region_constituent constituents[] = {
-		{.address = (uint64_t)page, .page_count = 1},
+		{.address = (uint64_t)pages, .page_count = 1},
 	};
 
 	msg_size = spci_memory_donate_init(
@@ -815,13 +882,13 @@
 TEST(memory_sharing, lend_to_self)
 {
 	struct mailbox_buffers mb = set_up_mailbox();
-	uint8_t *ptr = page;
+	uint8_t *ptr = pages;
 	uint32_t msg_size;
 
 	/* Initialise the memory before giving it. */
-	memset_s(ptr, sizeof(page), 'b', PAGE_SIZE);
+	memset_s(ptr, sizeof(pages), 'b', PAGE_SIZE);
 	struct spci_memory_region_constituent constituents[] = {
-		{.address = (uint64_t)page, .page_count = 1},
+		{.address = (uint64_t)pages, .page_count = 1},
 	};
 
 	msg_size = spci_memory_lend_init(
@@ -840,13 +907,13 @@
 TEST(memory_sharing, share_to_self)
 {
 	struct mailbox_buffers mb = set_up_mailbox();
-	uint8_t *ptr = page;
+	uint8_t *ptr = pages;
 	uint32_t msg_size;
 
 	/* Initialise the memory before giving it. */
-	memset_s(ptr, sizeof(page), 'b', PAGE_SIZE);
+	memset_s(ptr, sizeof(pages), 'b', PAGE_SIZE);
 	struct spci_memory_region_constituent constituents[] = {
-		{.address = (uint64_t)page, .page_count = 1},
+		{.address = (uint64_t)pages, .page_count = 1},
 	};
 
 	msg_size = spci_memory_share_init(
@@ -866,16 +933,16 @@
 {
 	struct spci_value run_res;
 	struct mailbox_buffers mb = set_up_mailbox();
-	uint8_t *ptr = page;
+	uint8_t *ptr = pages;
 	uint32_t msg_size;
 
 	SERVICE_SELECT(SERVICE_VM1, "spci_donate_invalid_source", mb.send);
 	SERVICE_SELECT(SERVICE_VM2, "spci_memory_receive", mb.send);
 
 	/* Initialise the memory before giving it. */
-	memset_s(ptr, sizeof(page), 'b', PAGE_SIZE);
+	memset_s(ptr, sizeof(pages), 'b', PAGE_SIZE);
 	struct spci_memory_region_constituent constituents[] = {
-		{.address = (uint64_t)page, .page_count = 1},
+		{.address = (uint64_t)pages, .page_count = 1},
 	};
 
 	/* Try invalid configurations. */
@@ -932,28 +999,42 @@
 
 	SERVICE_SELECT(SERVICE_VM1, "spci_memory_return", mb.send);
 
-	for (int i = 1; i < PAGE_SIZE; i++) {
-		struct spci_memory_region_constituent constituents[] = {
-			{.address = (uint64_t)page + i, .page_count = 1},
-		};
-		uint32_t msg_size = spci_memory_donate_init(
-			mb.send, SERVICE_VM1, constituents,
-			ARRAY_SIZE(constituents), 0, SPCI_MEMORY_RW_X,
-			SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
-			SPCI_MEMORY_OUTER_SHAREABLE);
-		EXPECT_SPCI_ERROR(
-			spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				      SPCI_MSG_SEND_LEGACY_MEMORY),
-			SPCI_INVALID_PARAMETERS);
-		msg_size = spci_memory_lend_init(
-			mb.send, SERVICE_VM1, constituents,
-			ARRAY_SIZE(constituents), 0, SPCI_MEMORY_RW_X,
-			SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
-			SPCI_MEMORY_OUTER_SHAREABLE);
-		EXPECT_SPCI_ERROR(
-			spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
-				      SPCI_MSG_SEND_LEGACY_MEMORY),
-			SPCI_INVALID_PARAMETERS);
+	/* Check for unaligned pages for either constituent. */
+	for (int i = 0; i < PAGE_SIZE; i++) {
+		for (int j = 0; i < PAGE_SIZE; i++) {
+			/* Skip the case they're both aligned. */
+			if (i == 0 && j == 0) {
+				continue;
+			}
+			struct spci_memory_region_constituent constituents[] = {
+				{.address = (uint64_t)pages + i,
+				 .page_count = 1},
+				{.address = (uint64_t)pages + PAGE_SIZE + j,
+				 .page_count = 1},
+			};
+			uint32_t msg_size = spci_memory_donate_init(
+				mb.send, SERVICE_VM1, constituents,
+				ARRAY_SIZE(constituents), 0, SPCI_MEMORY_RW_X,
+				SPCI_MEMORY_NORMAL_MEM,
+				SPCI_MEMORY_CACHE_WRITE_BACK,
+				SPCI_MEMORY_OUTER_SHAREABLE);
+			EXPECT_SPCI_ERROR(
+				spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1,
+					      msg_size,
+					      SPCI_MSG_SEND_LEGACY_MEMORY),
+				SPCI_INVALID_PARAMETERS);
+			msg_size = spci_memory_lend_init(
+				mb.send, SERVICE_VM1, constituents,
+				ARRAY_SIZE(constituents), 0, SPCI_MEMORY_RW_X,
+				SPCI_MEMORY_NORMAL_MEM,
+				SPCI_MEMORY_CACHE_WRITE_BACK,
+				SPCI_MEMORY_OUTER_SHAREABLE);
+			EXPECT_SPCI_ERROR(
+				spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1,
+					      msg_size,
+					      SPCI_MSG_SEND_LEGACY_MEMORY),
+				SPCI_INVALID_PARAMETERS);
+		}
 	}
 }
 
@@ -964,15 +1045,15 @@
 {
 	struct spci_value run_res;
 	struct mailbox_buffers mb = set_up_mailbox();
-	uint8_t *ptr = page;
+	uint8_t *ptr = pages;
 	uint32_t msg_size;
 
 	SERVICE_SELECT(SERVICE_VM1, "spci_lend_invalid_source", mb.send);
 
 	/* Initialise the memory before giving it. */
-	memset_s(ptr, sizeof(page), 'b', PAGE_SIZE);
+	memset_s(ptr, sizeof(pages), 'b', PAGE_SIZE);
 	struct spci_memory_region_constituent constituents[] = {
-		{.address = (uint64_t)page, .page_count = 1},
+		{.address = (uint64_t)pages, .page_count = 1},
 	};
 
 	/* Check cannot swap VM IDs. */
@@ -1011,16 +1092,16 @@
 {
 	struct spci_value run_res;
 	struct mailbox_buffers mb = set_up_mailbox();
-	uint8_t *ptr = page;
+	uint8_t *ptr = pages;
 	uint32_t msg_size;
 
 	SERVICE_SELECT(SERVICE_VM1, "spci_memory_lend_relinquish_RW", mb.send);
 
 	/* Initialise the memory before giving it. */
-	memset_s(ptr, sizeof(page), 'b', PAGE_SIZE);
+	memset_s(ptr, sizeof(pages), 'b', PAGE_SIZE);
 
 	struct spci_memory_region_constituent constituents[] = {
-		{.address = (uint64_t)page, .page_count = 1},
+		{.address = (uint64_t)pages, .page_count = 1},
 	};
 
 	msg_size = spci_memory_lend_init(
@@ -1042,7 +1123,7 @@
 	EXPECT_EQ(run_res.func, SPCI_MSG_SEND_32);
 
 	/* Re-initialise the memory before giving it. */
-	memset_s(ptr, sizeof(page), 'b', PAGE_SIZE);
+	memset_s(ptr, sizeof(pages), 'b', PAGE_SIZE);
 
 	msg_size = spci_memory_lend_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
@@ -1071,16 +1152,16 @@
 {
 	struct spci_value run_res;
 	struct mailbox_buffers mb = set_up_mailbox();
-	uint8_t *ptr = page;
+	uint8_t *ptr = pages;
 	uint32_t msg_size;
 
 	SERVICE_SELECT(SERVICE_VM1, "spci_memory_lend_relinquish_RW", mb.send);
 
 	/* Initialise the memory before giving it. */
-	memset_s(ptr, sizeof(page), 'b', PAGE_SIZE);
+	memset_s(ptr, sizeof(pages), 'b', PAGE_SIZE);
 
 	struct spci_memory_region_constituent constituents[] = {
-		{.address = (uint64_t)page, .page_count = 1},
+		{.address = (uint64_t)pages, .page_count = 1},
 	};
 
 	msg_size = spci_memory_share_init(
@@ -1108,7 +1189,7 @@
 	EXPECT_EQ(run_res.func, SPCI_MSG_SEND_32);
 
 	/* Re-initialise the memory before giving it. */
-	memset_s(ptr, sizeof(page), 'b', PAGE_SIZE);
+	memset_s(ptr, sizeof(pages), 'b', PAGE_SIZE);
 
 	msg_size = spci_memory_share_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
@@ -1143,16 +1224,16 @@
 {
 	struct spci_value run_res;
 	struct mailbox_buffers mb = set_up_mailbox();
-	uint8_t *ptr = page;
+	uint8_t *ptr = pages;
 	uint32_t msg_size;
 
 	SERVICE_SELECT(SERVICE_VM1, "spci_memory_lend_relinquish_RW", mb.send);
 
 	/* Initialise the memory before giving it. */
-	memset_s(ptr, sizeof(page), 'b', PAGE_SIZE);
+	memset_s(ptr, sizeof(pages), 'b', PAGE_SIZE);
 
 	struct spci_memory_region_constituent constituents[] = {
-		{.address = (uint64_t)page, .page_count = 1},
+		{.address = (uint64_t)pages, .page_count = 1},
 	};
 
 	msg_size = spci_memory_share_init(
@@ -1179,7 +1260,7 @@
 	EXPECT_EQ(run_res.func, SPCI_MSG_SEND_32);
 
 	/* Re-initialise the memory before giving it. */
-	memset_s(ptr, sizeof(page), 'b', PAGE_SIZE);
+	memset_s(ptr, sizeof(pages), 'b', PAGE_SIZE);
 
 	msg_size = spci_memory_share_init(
 		mb.send, SERVICE_VM1, constituents, ARRAY_SIZE(constituents), 0,
@@ -1213,20 +1294,20 @@
 {
 	struct spci_value run_res;
 	struct mailbox_buffers mb = set_up_mailbox();
-	uint8_t *ptr = page;
+	uint8_t *ptr = pages;
 	uint32_t msg_size;
 
 	SERVICE_SELECT(SERVICE_VM1, "spci_memory_lend_relinquish_X", mb.send);
 
 	/* Initialise the memory before giving it. */
-	memset_s(ptr, sizeof(page), 0, PAGE_SIZE);
+	memset_s(ptr, sizeof(pages), 0, PAGE_SIZE);
 
-	uint64_t *ptr2 = (uint64_t *)page;
+	uint64_t *ptr2 = (uint64_t *)pages;
 	/* Set memory to contain the RET instruction to attempt to execute. */
 	*ptr2 = 0xD65F03C0;
 
 	struct spci_memory_region_constituent constituents[] = {
-		{.address = (uint64_t)page, .page_count = 1},
+		{.address = (uint64_t)pages, .page_count = 1},
 	};
 
 	msg_size = spci_memory_lend_init(
@@ -1263,20 +1344,20 @@
 {
 	struct spci_value run_res;
 	struct mailbox_buffers mb = set_up_mailbox();
-	uint8_t *ptr = page;
+	uint8_t *ptr = pages;
 	uint32_t msg_size;
 
 	SERVICE_SELECT(SERVICE_VM1, "spci_memory_lend_relinquish_X", mb.send);
 
 	/* Initialise the memory before giving it. */
-	memset_s(ptr, sizeof(page), 0, PAGE_SIZE);
+	memset_s(ptr, sizeof(pages), 0, PAGE_SIZE);
 
-	uint64_t *ptr2 = (uint64_t *)page;
+	uint64_t *ptr2 = (uint64_t *)pages;
 	/* Set memory to contain the RET instruction to attempt to execute. */
 	*ptr2 = 0xD65F03C0;
 
 	struct spci_memory_region_constituent constituents[] = {
-		{.address = (uint64_t)page, .page_count = 1},
+		{.address = (uint64_t)pages, .page_count = 1},
 	};
 
 	msg_size = spci_memory_lend_init(
@@ -1313,17 +1394,17 @@
 {
 	struct spci_value run_res;
 	struct mailbox_buffers mb = set_up_mailbox();
-	uint8_t *ptr = page;
+	uint8_t *ptr = pages;
 	uint32_t msg_size;
 
 	SERVICE_SELECT(SERVICE_VM1, "spci_memory_lend_relinquish_RW", mb.send);
 	SERVICE_SELECT(SERVICE_VM2, "spci_memory_lend_relinquish_RW", mb.send);
 
 	/* Initialise the memory before giving it. */
-	memset_s(ptr, sizeof(page) * 2, 'b', PAGE_SIZE * 2);
+	memset_s(ptr, sizeof(pages) * 2, 'b', PAGE_SIZE * 2);
 
 	struct spci_memory_region_constituent constituents[] = {
-		{.address = (uint64_t)page, .page_count = 2},
+		{.address = (uint64_t)pages, .page_count = 2},
 	};
 
 	msg_size = spci_memory_lend_init(
@@ -1343,7 +1424,7 @@
 	/* Ensure we can't donate any sub section of memory to another VM. */
 	constituents[0].page_count = 1;
 	for (int i = 1; i < PAGE_SIZE * 2; i++) {
-		constituents[0].address = (uint64_t)page + PAGE_SIZE;
+		constituents[0].address = (uint64_t)pages + PAGE_SIZE;
 		msg_size = spci_memory_donate_init(
 			mb.send, SERVICE_VM2, constituents,
 			ARRAY_SIZE(constituents), 0, SPCI_MEMORY_RW_X,
@@ -1373,17 +1454,18 @@
 {
 	struct spci_value run_res;
 	struct mailbox_buffers mb = set_up_mailbox();
-	uint8_t *ptr = page;
+	uint8_t *ptr = pages;
 	uint32_t msg_size;
 
 	SERVICE_SELECT(SERVICE_VM1, "spci_memory_lend_relinquish_RW", mb.send);
 	SERVICE_SELECT(SERVICE_VM2, "spci_memory_lend_relinquish_RW", mb.send);
 
 	/* Initialise the memory before giving it. */
-	memset_s(ptr, sizeof(page) * 2, 'b', PAGE_SIZE * 2);
+	memset_s(ptr, sizeof(pages), 'b', PAGE_SIZE * 4);
 
 	struct spci_memory_region_constituent constituents[] = {
-		{.address = (uint64_t)page, .page_count = 2},
+		{.address = (uint64_t)pages, .page_count = 2},
+		{.address = (uint64_t)pages + PAGE_SIZE * 2, .page_count = 2},
 	};
 
 	msg_size = spci_memory_share_init(
@@ -1407,7 +1489,7 @@
 	/* Ensure we can't donate any sub section of memory to another VM. */
 	constituents[0].page_count = 1;
 	for (int i = 1; i < PAGE_SIZE * 2; i++) {
-		constituents[0].address = (uint64_t)page + PAGE_SIZE;
+		constituents[0].address = (uint64_t)pages + PAGE_SIZE;
 		msg_size = spci_memory_donate_init(
 			mb.send, SERVICE_VM2, constituents,
 			ARRAY_SIZE(constituents), 0, SPCI_MEMORY_RW_X,
@@ -1437,17 +1519,18 @@
 {
 	struct spci_value run_res;
 	struct mailbox_buffers mb = set_up_mailbox();
-	uint8_t *ptr = page;
+	uint8_t *ptr = pages;
 	uint32_t msg_size;
 
 	SERVICE_SELECT(SERVICE_VM1, "spci_memory_lend_twice", mb.send);
 	SERVICE_SELECT(SERVICE_VM2, "spci_memory_lend_twice", mb.send);
 
 	/* Initialise the memory before giving it. */
-	memset_s(ptr, sizeof(page) * 2, 'b', PAGE_SIZE * 2);
+	memset_s(ptr, sizeof(pages), 'b', PAGE_SIZE * 4);
 
 	struct spci_memory_region_constituent constituents[] = {
-		{.address = (uint64_t)page, .page_count = 2},
+		{.address = (uint64_t)pages, .page_count = 2},
+		{.address = (uint64_t)pages + PAGE_SIZE * 3, .page_count = 1},
 	};
 
 	msg_size = spci_memory_lend_init(
@@ -1477,10 +1560,22 @@
 	check_cannot_relinquish_memory(mb, constituents,
 				       ARRAY_SIZE(constituents));
 
+	/* Now attempt to share only a portion of the same area of memory. */
+	struct spci_memory_region_constituent constituents_subsection[] = {
+		{.address = (uint64_t)pages + PAGE_SIZE * 3, .page_count = 1},
+	};
+	check_cannot_lend_memory(mb, constituents_subsection,
+				 ARRAY_SIZE(constituents_subsection), -1);
+	check_cannot_donate_memory(mb, constituents_subsection,
+				   ARRAY_SIZE(constituents_subsection),
+				   SERVICE_VM1);
+	check_cannot_relinquish_memory(mb, constituents_subsection,
+				       ARRAY_SIZE(constituents_subsection));
+
 	/* Attempt to lend again with different permissions. */
 	constituents[0].page_count = 1;
 	for (int i = 0; i < 2; i++) {
-		constituents[0].address = (uint64_t)page + i * PAGE_SIZE;
+		constituents[0].address = (uint64_t)pages + i * PAGE_SIZE;
 		msg_size = spci_memory_lend_init(
 			mb.send, SERVICE_VM1, constituents,
 			ARRAY_SIZE(constituents), 0, SPCI_MEMORY_RO_X,
@@ -1500,17 +1595,17 @@
 {
 	struct spci_value run_res;
 	struct mailbox_buffers mb = set_up_mailbox();
-	uint8_t *ptr = page;
+	uint8_t *ptr = pages;
 	uint32_t msg_size;
 
 	SERVICE_SELECT(SERVICE_VM1, "spci_memory_lend_twice", mb.send);
 	SERVICE_SELECT(SERVICE_VM2, "spci_memory_lend_twice", mb.send);
 
 	/* Initialise the memory before giving it. */
-	memset_s(ptr, sizeof(page) * 2, 'b', PAGE_SIZE * 2);
+	memset_s(ptr, sizeof(pages) * 2, 'b', PAGE_SIZE * 2);
 
 	struct spci_memory_region_constituent constituents[] = {
-		{.address = (uint64_t)page, .page_count = 2},
+		{.address = (uint64_t)pages, .page_count = 2},
 	};
 
 	msg_size = spci_memory_share_init(
@@ -1545,7 +1640,7 @@
 	/* Attempt to share again with different permissions. */
 	constituents[0].page_count = 1;
 	for (int i = 0; i < 2; i++) {
-		constituents[0].address = (uint64_t)page + i * PAGE_SIZE;
+		constituents[0].address = (uint64_t)pages + i * PAGE_SIZE;
 		msg_size = spci_memory_share_init(
 			mb.send, SERVICE_VM1, constituents,
 			ARRAY_SIZE(constituents), 0, SPCI_MEMORY_RO_X,
@@ -1564,17 +1659,17 @@
 TEST(memory_sharing, share_clear)
 {
 	struct mailbox_buffers mb = set_up_mailbox();
-	uint8_t *ptr = page;
+	uint8_t *ptr = pages;
 	uint32_t msg_size;
 	size_t i;
 
 	SERVICE_SELECT(SERVICE_VM1, "spci_memory_return", mb.send);
 
 	/* Initialise the memory before giving it. */
-	memset_s(ptr, sizeof(page) * 2, 'b', PAGE_SIZE * 2);
+	memset_s(ptr, sizeof(pages) * 2, 'b', PAGE_SIZE * 2);
 
 	struct spci_memory_region_constituent constituents[] = {
-		{.address = (uint64_t)page, .page_count = 2},
+		{.address = (uint64_t)pages, .page_count = 2},
 	};
 
 	msg_size = spci_memory_init(
@@ -1592,3 +1687,135 @@
 		ASSERT_EQ(ptr[i], 0);
 	};
 }
+
+/**
+ * SPCI: Verify past the upper bound of the lent region cannot be accessed.
+ */
+TEST(memory_sharing, spci_lend_check_upper_bounds)
+{
+	struct spci_value run_res;
+	struct mailbox_buffers mb = set_up_mailbox();
+	uint8_t *ptr = pages;
+	uint32_t msg_size;
+
+	SERVICE_SELECT(SERVICE_VM1, "spci_lend_check_upper_bound", mb.send);
+	SERVICE_SELECT(SERVICE_VM2, "spci_lend_check_upper_bound", mb.send);
+
+	/* Initialise the memory before lending it. */
+	memset_s(ptr, sizeof(pages), 'b', 4 * PAGE_SIZE);
+
+	/* Specify non-contiguous memory regions. */
+	struct spci_memory_region_constituent constituents[] = {
+		{.address = (uint64_t)pages, .page_count = 1},
+		{.address = (uint64_t)pages + PAGE_SIZE * 2, .page_count = 1},
+	};
+
+	/*
+	 * Specify that we want to test the first constituent of the donated
+	 * memory region. This is utilised by the test service.
+	 */
+	pages[0] = 0;
+
+	msg_size = spci_memory_lend_init(
+		mb.send, SERVICE_VM1, constituents, 2, 0, SPCI_MEMORY_RW_X,
+		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
+		SPCI_MEMORY_OUTER_SHAREABLE);
+	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
+				SPCI_MSG_SEND_LEGACY_MEMORY)
+			  .func,
+		  SPCI_SUCCESS_32);
+
+	/* Observe the service faulting when accessing out of bounds. */
+	run_res = spci_run(SERVICE_VM1, 0);
+	EXPECT_SPCI_ERROR(run_res, SPCI_ABORTED);
+
+	/* Use different memory regions for verifying the second constituent. */
+	constituents[0].address = (uint64_t)pages + PAGE_SIZE * 1;
+	constituents[1].address = (uint64_t)pages + PAGE_SIZE * 3;
+
+	/*
+	 * Specify that we now want to test the second constituent of the
+	 * lent memory region.
+	 */
+	pages[PAGE_SIZE] = 1;
+
+	/* Use the secondary VM for this test as the first is now aborted. */
+	msg_size = spci_memory_lend_init(
+		mb.send, SERVICE_VM2, constituents, 2, 0, SPCI_MEMORY_RW_X,
+		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
+		SPCI_MEMORY_OUTER_SHAREABLE);
+	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM2, msg_size,
+				SPCI_MSG_SEND_LEGACY_MEMORY)
+			  .func,
+		  SPCI_SUCCESS_32);
+
+	/* Observe the service faulting when accessing out of bounds. */
+	run_res = spci_run(SERVICE_VM2, 0);
+	EXPECT_SPCI_ERROR(run_res, SPCI_ABORTED);
+}
+
+/**
+ * SPCI: Verify past the lower bound of the lent region cannot be accessed.
+ */
+TEST(memory_sharing, spci_lend_check_lower_bounds)
+{
+	struct spci_value run_res;
+	struct mailbox_buffers mb = set_up_mailbox();
+	uint8_t *ptr = pages;
+	uint32_t msg_size;
+
+	SERVICE_SELECT(SERVICE_VM1, "spci_lend_check_lower_bound", mb.send);
+	SERVICE_SELECT(SERVICE_VM2, "spci_lend_check_lower_bound", mb.send);
+
+	/* Initialise the memory before lending it. */
+	memset_s(ptr, sizeof(pages), 'b', 4 * PAGE_SIZE);
+
+	/* Specify non-contiguous memory regions. */
+	struct spci_memory_region_constituent constituents[] = {
+		{.address = (uint64_t)pages, .page_count = 1},
+		{.address = (uint64_t)pages + PAGE_SIZE * 2, .page_count = 1},
+	};
+
+	/*
+	 * Specify that we want to test the first constituent of the lent
+	 * memory region. This is utilised by the test service.
+	 */
+	pages[0] = 0;
+
+	msg_size = spci_memory_lend_init(
+		mb.send, SERVICE_VM1, constituents, 2, 0, SPCI_MEMORY_RW_X,
+		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
+		SPCI_MEMORY_OUTER_SHAREABLE);
+	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM1, msg_size,
+				SPCI_MSG_SEND_LEGACY_MEMORY)
+			  .func,
+		  SPCI_SUCCESS_32);
+
+	/* Observe the service faulting when accessing out of bounds. */
+	run_res = spci_run(SERVICE_VM1, 0);
+	EXPECT_SPCI_ERROR(run_res, SPCI_ABORTED);
+
+	/* Use different memory regions for verifying the second constituent. */
+	constituents[0].address = (uint64_t)pages + PAGE_SIZE * 1;
+	constituents[1].address = (uint64_t)pages + PAGE_SIZE * 3;
+
+	/*
+	 * Specify that we now want to test the second constituent of the
+	 * lent memory region.
+	 */
+	pages[PAGE_SIZE] = 1;
+
+	/* Use the secondary VM for this test as the first is now aborted. */
+	msg_size = spci_memory_lend_init(
+		mb.send, SERVICE_VM2, constituents, 2, 0, SPCI_MEMORY_RW_X,
+		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
+		SPCI_MEMORY_OUTER_SHAREABLE);
+	EXPECT_EQ(spci_msg_send(HF_PRIMARY_VM_ID, SERVICE_VM2, msg_size,
+				SPCI_MSG_SEND_LEGACY_MEMORY)
+			  .func,
+		  SPCI_SUCCESS_32);
+
+	/* Observe the service faulting when accessing out of bounds. */
+	run_res = spci_run(SERVICE_VM2, 0);
+	EXPECT_SPCI_ERROR(run_res, SPCI_ABORTED);
+}
diff --git a/test/vmapi/primary_with_secondaries/services/memory.c b/test/vmapi/primary_with_secondaries/services/memory.c
index 97307c1..9015e8e 100644
--- a/test/vmapi/primary_with_secondaries/services/memory.c
+++ b/test/vmapi/primary_with_secondaries/services/memory.c
@@ -45,7 +45,7 @@
 		ptr = (uint8_t *)constituents[0].address;
 
 		/* Check the memory was cleared. */
-		for (int i = 0; i < PAGE_SIZE; ++i) {
+		for (i = 0; i < PAGE_SIZE; ++i) {
 			ASSERT_EQ(ptr[i], 0);
 		}
 
@@ -71,6 +71,7 @@
 		struct spci_value ret = spci_msg_wait();
 		uint8_t *ptr;
 		uint32_t msg_size;
+		size_t i;
 
 		EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
 		EXPECT_EQ(spci_msg_send_attributes(ret),
@@ -86,7 +87,7 @@
 		ptr = (uint8_t *)constituents[0].address;
 
 		/* Check that one has access to the shared region. */
-		for (int i = 0; i < PAGE_SIZE; ++i) {
+		for (i = 0; i < PAGE_SIZE; ++i) {
 			ptr[i]++;
 		}
 
@@ -158,6 +159,7 @@
 		struct spci_value ret = spci_msg_wait();
 		uint8_t *ptr;
 		uint32_t msg_size;
+		size_t i;
 		void *recv_buf = SERVICE_RECV_BUFFER();
 		void *send_buf = SERVICE_SEND_BUFFER();
 		struct spci_memory_region *memory_region;
@@ -173,7 +175,7 @@
 		ptr = (uint8_t *)constituents[0].address;
 
 		/* Check that one has access to the shared region. */
-		for (int i = 0; i < PAGE_SIZE; ++i) {
+		for (i = 0; i < PAGE_SIZE; ++i) {
 			ptr[i]++;
 		}
 
@@ -202,6 +204,7 @@
 {
 	struct spci_value ret = spci_msg_wait();
 	uint8_t *ptr;
+	uint8_t index;
 	void *recv_buf = SERVICE_RECV_BUFFER();
 	struct spci_memory_region *memory_region;
 	struct spci_memory_region_constituent *constituents;
@@ -210,7 +213,10 @@
 	EXPECT_EQ(spci_msg_send_attributes(ret), SPCI_MSG_SEND_LEGACY_MEMORY);
 	memory_region = spci_get_memory_region(recv_buf);
 	constituents = spci_memory_region_get_constituents(memory_region);
-	ptr = (uint8_t *)constituents[0].address;
+
+	/* Choose which constituent we want to test. */
+	index = *(uint8_t *)constituents[0].address;
+	ptr = (uint8_t *)constituents[index].address;
 
 	spci_rx_release();
 
@@ -222,16 +228,19 @@
 {
 	struct spci_value ret = spci_msg_wait();
 	uint8_t *ptr;
+	uint8_t index;
 	void *recv_buf = SERVICE_RECV_BUFFER();
-	struct spci_memory_region *memory_region;
-	struct spci_memory_region_constituent *constituents;
+	struct spci_memory_region *memory_region =
+		spci_get_memory_region(recv_buf);
+	struct spci_memory_region_constituent *constituents =
+		spci_memory_region_get_constituents(memory_region);
 
 	EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
 	EXPECT_EQ(spci_msg_send_attributes(ret), SPCI_MSG_SEND_LEGACY_MEMORY);
-	memory_region = spci_get_memory_region(recv_buf);
-	constituents = spci_memory_region_get_constituents(memory_region);
-	ptr = (uint8_t *)constituents[0].address;
 
+	/* Choose which constituent we want to test. */
+	index = *(uint8_t *)constituents[0].address;
+	ptr = (uint8_t *)constituents[index].address;
 	spci_rx_release();
 
 	/* Check that one cannot access out of bounds before donated region. */
@@ -397,7 +406,11 @@
 	for (;;) {
 		struct spci_value ret = spci_msg_wait();
 		uint8_t *ptr;
+		uint8_t *ptr2;
+		uint32_t count;
+		uint32_t count2;
 		uint32_t msg_size;
+		size_t i;
 
 		void *recv_buf = SERVICE_RECV_BUFFER();
 		void *send_buf = SERVICE_SEND_BUFFER();
@@ -410,11 +423,17 @@
 		EXPECT_EQ(spci_msg_send_attributes(ret),
 			  SPCI_MSG_SEND_LEGACY_MEMORY);
 		ptr = (uint8_t *)constituents[0].address;
+		count = constituents[0].page_count;
+		ptr2 = (uint8_t *)constituents[1].address;
+		count2 = constituents[1].page_count;
 
 		/* Check that one has access to the shared region. */
-		for (int i = 0; i < PAGE_SIZE; ++i) {
+		for (i = 0; i < PAGE_SIZE * count; ++i) {
 			ptr[i]++;
 		}
+		for (i = 0; i < PAGE_SIZE * count2; ++i) {
+			ptr2[i]++;
+		}
 
 		/* Give the memory back and notify the sender. */
 		msg_size = spci_memory_relinquish_init(
@@ -445,6 +464,7 @@
 		struct spci_value ret = spci_msg_wait();
 		uint8_t *ptr;
 		uint32_t msg_size;
+		size_t i;
 
 		void *recv_buf = SERVICE_RECV_BUFFER();
 		void *send_buf = SERVICE_SEND_BUFFER();
@@ -460,7 +480,7 @@
 		ptr = (uint8_t *)constituents[0].address;
 
 		/* Check that one has access to the shared region. */
-		for (int i = 0; i < PAGE_SIZE; ++i) {
+		for (i = 0; i < PAGE_SIZE; ++i) {
 			ptr[i]++;
 		}
 		/* Give the memory back and notify the sender. */
@@ -592,6 +612,7 @@
 		struct spci_value ret = spci_msg_wait();
 		uint8_t *ptr;
 		uint32_t msg_size;
+		size_t i;
 
 		void *recv_buf = SERVICE_RECV_BUFFER();
 		void *send_buf = SERVICE_SEND_BUFFER();
@@ -610,7 +631,7 @@
 		ptr = (uint8_t *)constituent_copy.address;
 
 		/* Check that we have read access. */
-		for (int i = 0; i < PAGE_SIZE; ++i) {
+		for (i = 0; i < PAGE_SIZE; ++i) {
 			EXPECT_EQ(ptr[i], 'b');
 		}
 
@@ -618,7 +639,7 @@
 		spci_yield();
 
 		/* Attempt to modify the memory. */
-		for (int i = 0; i < PAGE_SIZE; ++i) {
+		for (i = 0; i < PAGE_SIZE; ++i) {
 			ptr[i]++;
 		}
 
@@ -633,36 +654,13 @@
 }
 
 /**
- * Attempt to modify below the lower bound for the lent memory.
- */
-TEST_SERVICE(spci_lend_check_lower_bound)
-{
-	struct spci_value ret = spci_msg_wait();
-	uint8_t *ptr;
-
-	void *recv_buf = SERVICE_RECV_BUFFER();
-	struct spci_memory_region *memory_region =
-		spci_get_memory_region(recv_buf);
-	struct spci_memory_region_constituent *constituents =
-		spci_memory_region_get_constituents(memory_region);
-
-	EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
-	EXPECT_EQ(spci_msg_send_attributes(ret), SPCI_MSG_SEND_LEGACY_MEMORY);
-
-	ptr = (uint8_t *)constituents[0].address;
-	spci_rx_release();
-
-	/* Check that one cannot access before donated region. */
-	ptr[-1]++;
-}
-
-/**
  * Attempt to modify above the upper bound for the lent memory.
  */
 TEST_SERVICE(spci_lend_check_upper_bound)
 {
 	struct spci_value ret = spci_msg_wait();
 	uint8_t *ptr;
+	uint8_t index;
 
 	void *recv_buf = SERVICE_RECV_BUFFER();
 	struct spci_memory_region *memory_region =
@@ -673,11 +671,41 @@
 	EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
 	EXPECT_EQ(spci_msg_send_attributes(ret), SPCI_MSG_SEND_LEGACY_MEMORY);
 
-	ptr = (uint8_t *)constituents[0].address;
+	/* Choose which constituent we want to test. */
+	index = *(uint8_t *)constituents[0].address;
+	ptr = (uint8_t *)constituents[index].address;
 	spci_rx_release();
 
-	/* Check that one cannot access after donated region. */
-	ptr[PAGE_SIZE]++;
+	/* Check that one cannot access after lent region. */
+	ASSERT_EQ(ptr[PAGE_SIZE], 0);
+}
+
+/**
+ * Attempt to modify below the lower bound for the lent memory.
+ */
+TEST_SERVICE(spci_lend_check_lower_bound)
+{
+	struct spci_value ret = spci_msg_wait();
+	uint8_t *ptr;
+	uint8_t index;
+
+	void *recv_buf = SERVICE_RECV_BUFFER();
+	struct spci_memory_region *memory_region =
+		spci_get_memory_region(recv_buf);
+	struct spci_memory_region_constituent *constituents =
+		spci_memory_region_get_constituents(memory_region);
+
+	EXPECT_EQ(ret.func, SPCI_MSG_SEND_32);
+	EXPECT_EQ(spci_msg_send_attributes(ret), SPCI_MSG_SEND_LEGACY_MEMORY);
+
+	/* Choose which constituent we want to test. */
+	index = *(uint8_t *)constituents[0].address;
+	ptr = (uint8_t *)constituents[index].address;
+	spci_rx_release();
+
+	/* Check that one cannot access after lent region. */
+	ptr[-1]++;
+	spci_yield();
 }
 
 TEST_SERVICE(spci_memory_lend_twice)
@@ -685,6 +713,7 @@
 	struct spci_value ret = spci_msg_wait();
 	uint8_t *ptr;
 	uint32_t msg_size;
+	size_t i;
 
 	void *recv_buf = SERVICE_RECV_BUFFER();
 	void *send_buf = SERVICE_SEND_BUFFER();
@@ -702,16 +731,16 @@
 	ptr = (uint8_t *)constituent_copy.address;
 
 	/* Check that we have read access. */
-	for (int i = 0; i < PAGE_SIZE; ++i) {
+	for (i = 0; i < PAGE_SIZE; ++i) {
 		EXPECT_EQ(ptr[i], 'b');
 	}
 
 	/* Attempt to modify the memory. */
-	for (int i = 0; i < PAGE_SIZE; ++i) {
+	for (i = 0; i < PAGE_SIZE; ++i) {
 		ptr[i]++;
 	}
 
-	for (int i = 1; i < PAGE_SIZE * 2; i++) {
+	for (i = 1; i < PAGE_SIZE * 2; i++) {
 		constituent_copy.address = (uint64_t)ptr + i;
 
 		/* Fail to lend or share the memory back to the primary. */