Merge "test: exercise secure espi interrupt handling"
diff --git a/include/runtime_services/cactus_test_cmds.h b/include/runtime_services/cactus_test_cmds.h
index 6398138..5f3d0d2 100644
--- a/include/runtime_services/cactus_test_cmds.h
+++ b/include/runtime_services/cactus_test_cmds.h
@@ -201,15 +201,10 @@
 static inline struct ffa_value cactus_mem_send_cmd(
 	ffa_id_t source, ffa_id_t dest, uint32_t mem_func,
 	ffa_memory_handle_t handle, ffa_memory_region_flags_t retrieve_flags,
-	bool non_secure, uint16_t word_to_write)
+	uint16_t word_to_write)
 {
-	/*
-	 * `non_secure` and `word_to_write` are packed in the same register.
-	 * Packed in a 32-bit value to support AArch32 platforms (eg Juno).
-	 */
-	uint32_t val3 = ((uint32_t)non_secure << 16) | word_to_write;
 	return cactus_send_cmd(source, dest, CACTUS_MEM_SEND_CMD, mem_func,
-			       handle, retrieve_flags, val3);
+			       handle, retrieve_flags, word_to_write);
 }
 
 static inline ffa_memory_handle_t cactus_mem_send_get_handle(
@@ -229,11 +224,6 @@
 	return (uint16_t)ret.arg7;
 }
 
-static inline bool cactus_mem_send_get_non_secure(struct ffa_value ret)
-{
-	return (bool)(ret.arg7 >> 16);
-}
-
 /**
  * Command to request a memory management operation. The 'mem_func' argument
  * identifies the operation that is to be performend, and 'receiver' is the id
diff --git a/include/runtime_services/ffa_helpers.h b/include/runtime_services/ffa_helpers.h
index a7cdcb5..149969e 100644
--- a/include/runtime_services/ffa_helpers.h
+++ b/include/runtime_services/ffa_helpers.h
@@ -403,6 +403,17 @@
 typedef uint8_t ffa_memory_access_permissions_t;
 
 /**
+ * FF-A v1.1 REL0 Table 10.18 memory region attributes descriptor NS Bit 6.
+ * Per section 10.10.4.1, NS bit is reserved for FFA_MEM_DONATE/LEND/SHARE
+ * and FFA_MEM_RETRIEVE_REQUEST.
+ */
+enum ffa_memory_security {
+	FFA_MEMORY_SECURITY_UNSPECIFIED = 0,
+	FFA_MEMORY_SECURITY_SECURE = 0,
+	FFA_MEMORY_SECURITY_NON_SECURE,
+};
+
+/**
  * This corresponds to table 10.18 of the FF-A v1.1 EAC0 specification, "Memory
  * region attributes descriptor".
  */
@@ -417,6 +428,9 @@
 #define FFA_MEMORY_TYPE_OFFSET (0x4U)
 #define FFA_MEMORY_TYPE_MASK ((0x3U) << FFA_MEMORY_TYPE_OFFSET)
 
+#define FFA_MEMORY_SECURITY_OFFSET (0x6U)
+#define FFA_MEMORY_SECURITY_MASK ((0x1U) << FFA_MEMORY_SECURITY_OFFSET)
+
 #define FFA_MEMORY_CACHEABILITY_OFFSET (0x2U)
 #define FFA_MEMORY_CACHEABILITY_MASK ((0x3U) << FFA_MEMORY_CACHEABILITY_OFFSET)
 
@@ -452,6 +466,11 @@
 ATTR_FUNCTION_GET(memory_type, ffa_memory_attributes_t, FFA_MEMORY_TYPE_OFFSET,
 		  FFA_MEMORY_TYPE_MASK)
 
+ATTR_FUNCTION_SET(memory_security, ffa_memory_attributes_t,
+		  FFA_MEMORY_SECURITY_OFFSET, FFA_MEMORY_SECURITY_MASK)
+ATTR_FUNCTION_GET(memory_security, ffa_memory_attributes_t,
+		  FFA_MEMORY_SECURITY_OFFSET, FFA_MEMORY_SECURITY_MASK)
+
 ATTR_FUNCTION_SET(memory_cacheability, ffa_memory_attributes_t,
 		  FFA_MEMORY_CACHEABILITY_OFFSET, FFA_MEMORY_CACHEABILITY_MASK)
 ATTR_FUNCTION_GET(memory_cacheability, ffa_memory_attributes_t,
diff --git a/lib/aarch64/misc_helpers.S b/lib/aarch64/misc_helpers.S
index b677721..2a2d633 100644
--- a/lib/aarch64/misc_helpers.S
+++ b/lib/aarch64/misc_helpers.S
@@ -197,9 +197,12 @@
 	 * Size of Elf64_Rela structure is 24 bytes.
 	 */
 1:
+	/* Skip R_AARCH64_NONE entry with code 0 */
+	ldr	x3, [x1, #8]
+	cbz	x3, 2f
+
 	/* Assert that the relocation type is R_AARCH64_RELATIVE */
 #if ENABLE_ASSERTIONS
-	ldr	x3, [x1, #8]
 	cmp	x3, #0x403
 	ASM_ASSERT(eq)
 #endif
diff --git a/spm/cactus/cactus_tests/cactus_test_memory_sharing.c b/spm/cactus/cactus_tests/cactus_test_memory_sharing.c
index d9467b4..15ab0f1 100644
--- a/spm/cactus/cactus_tests/cactus_test_memory_sharing.c
+++ b/spm/cactus/cactus_tests/cactus_test_memory_sharing.c
@@ -80,7 +80,6 @@
 	ffa_memory_region_flags_t retrv_flags =
 					 cactus_mem_send_get_retrv_flags(*args);
 	uint32_t words_to_write = cactus_mem_send_words_to_write(*args);
-	bool non_secure = cactus_mem_send_get_non_secure(*args);
 
 	expect(memory_retrieve(mb, &m, handle, source, vm_id,
 			       retrv_flags, mem_func), true);
@@ -101,7 +100,8 @@
 
 	mem_attrs = MT_RW_DATA | MT_EXECUTE_NEVER;
 
-	if (non_secure) {
+	if (ffa_get_memory_security_attr(m->attributes) ==
+	    FFA_MEMORY_SECURITY_NON_SECURE) {
 		mem_attrs |= MT_NS;
 	}
 
@@ -237,7 +237,7 @@
 	}
 
 	ffa_ret = cactus_mem_send_cmd(vm_id, receiver, mem_func, handle,
-				      0, non_secure, 10);
+				      0, 10);
 
 	if (!is_ffa_direct_response(ffa_ret)) {
 		return cactus_error_resp(vm_id, source, CACTUS_ERROR_FFA_CALL);
diff --git a/tftf/tests/misc_tests/test_invalid_access.c b/tftf/tests/misc_tests/test_invalid_access.c
index 5c173c5..343a553 100644
--- a/tftf/tests/misc_tests/test_invalid_access.c
+++ b/tftf/tests/misc_tests/test_invalid_access.c
@@ -271,13 +271,13 @@
 /**
  * @Test_Aim@ Check a root region cannot be accessed from a secure partition.
  *
- * This change adds TFTF and cactus test to permit checking a root region
- * cannot be accessed from secure world.
  * A hardcoded address marked Root in the GPT is shared to a secure
- * partition. The SP retrieves the region from the SPM, maps it and
- * attempts a read access to the region. It is expected to trigger a GPF
- * data abort on the PE caught by a custom exception handler.
- *
+ * partition. The operation fails given the memory shared needs to be
+ * preconfigured in the memory ranges described in the SPMC manifest. The ranges
+ * related with S/NS memory that the SP can access shall never contain
+ * realm/root memory as this incurs into a configuration error.
+ * This test validates the SP can't get access to root memory via FF-A memory
+ * sharing interfaces.
  */
 test_result_t rt_memory_cannot_be_accessed_in_s(void)
 {
@@ -297,8 +297,6 @@
 		return TEST_RESULT_SKIPPED;
 	}
 
-	SKIP_TEST_IF_FFA_VERSION_LESS_THAN(1,1);
-
 	CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
 
 	GET_TFTF_MAILBOX(mb);
@@ -309,32 +307,10 @@
 					FFA_MEM_SHARE_SMC32, &ret);
 
 	if (handle == FFA_MEMORY_HANDLE_INVALID) {
-		return TEST_RESULT_FAIL;
+		return TEST_RESULT_SUCCESS;
 	}
 
-	VERBOSE("TFTF - Handle: %llx Address: %p\n",
-		handle, constituents[0].address);
-
-	/* Retrieve the shared page and attempt accessing it. */
-	ret = cactus_mem_send_cmd(SENDER, RECEIVER, FFA_MEM_SHARE_SMC32,
-				  handle, 0, true, 1);
-
-	if (is_ffa_call_error(ffa_mem_reclaim(handle, 0))) {
-		ERROR("Memory reclaim failed!\n");
-		return TEST_RESULT_FAIL;
-	}
-
-	/*
-	 * Expect success response with value 1 hinting an exception
-	 * triggered while the SP accessed the region.
-	 */
-	if (!(cactus_get_response(ret) == CACTUS_SUCCESS &&
-	      cactus_error_code(ret) == 1)) {
-		ERROR("Exceptions test failed!\n");
-		return TEST_RESULT_FAIL;
-	}
-
-	return TEST_RESULT_SUCCESS;
+	return TEST_RESULT_FAIL;
 }
 
 test_result_t s_memory_cannot_be_accessed_in_rl(void)
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_exceptions.c b/tftf/tests/runtime_services/secure_service/test_ffa_exceptions.c
index 6fd77d2..5cb6dd4 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_exceptions.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_exceptions.c
@@ -82,7 +82,7 @@
 
 	/* Retrieve the shared page and attempt accessing it. */
 	ret = cactus_mem_send_cmd(SENDER, RECEIVER, FFA_MEM_SHARE_SMC32,
-				  handle, 0, true, 1);
+				  handle, 0, 1);
 
 	/* Undelegate the shared page. */
 	retmm = host_rmi_granule_undelegate((u_register_t)&share_page);
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_memory_sharing.c b/tftf/tests/runtime_services/secure_service/test_ffa_memory_sharing.c
index 83c94c1..d42492b 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_memory_sharing.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_memory_sharing.c
@@ -26,6 +26,7 @@
 /* Memory section to be used for memory share operations */
 static __aligned(PAGE_SIZE) uint8_t share_page[PAGE_SIZE];
 static __aligned(PAGE_SIZE) uint8_t consecutive_donate_page[PAGE_SIZE];
+static __aligned(PAGE_SIZE) uint8_t four_share_pages[PAGE_SIZE * 4];
 
 static bool check_written_words(uint32_t *ptr, uint32_t word, uint32_t wcount)
 {
@@ -161,7 +162,7 @@
 	ptr = (uint32_t *)constituents[0].address;
 
 	ret = cactus_mem_send_cmd(SENDER, borrower, mem_func, handle, 0,
-				  true, nr_words_to_write);
+				  nr_words_to_write);
 
 	if (!is_ffa_direct_response(ret)) {
 		return TEST_RESULT_FAIL;
@@ -172,16 +173,22 @@
 		return TEST_RESULT_FAIL;
 	}
 
-	/* Check that borrower used the memory as expected for this test. */
-	if (!check_written_words(ptr, mem_func, nr_words_to_write)) {
-		ERROR("Words written to shared memory, not as expected.\n");
-		return TEST_RESULT_FAIL;
-	}
+	if (mem_func != FFA_MEM_DONATE_SMC32) {
 
-	if (mem_func != FFA_MEM_DONATE_SMC32 &&
-	    is_ffa_call_error(ffa_mem_reclaim(handle, 0))) {
+		/* Reclaim memory entirely before checking its state. */
+		if (is_ffa_call_error(ffa_mem_reclaim(handle, 0))) {
 			tftf_testcase_printf("Couldn't reclaim memory\n");
 			return TEST_RESULT_FAIL;
+		}
+
+		/*
+		 * Check that borrower used the memory as expected for this
+		 * test.
+		 */
+		if (!check_written_words(ptr, mem_func, nr_words_to_write)) {
+			ERROR("Fail because of state of memory.\n");
+			return TEST_RESULT_FAIL;
+		}
 	}
 
 	return TEST_RESULT_SUCCESS;
@@ -380,7 +387,10 @@
 test_result_t test_mem_share_to_sp_clear_memory(void)
 {
 	struct ffa_memory_region_constituent constituents[] = {
-						{(void *)share_page, 1, 1}};
+		{(void *)four_share_pages, 4, 0},
+		{(void *)share_page, 1, 0}
+	};
+
 	const uint32_t constituents_count = sizeof(constituents) /
 			sizeof(struct ffa_memory_region_constituent);
 	struct mailbox_buffers mb;
@@ -421,8 +431,7 @@
 	VERBOSE("Memory has been shared!\n");
 
 	ret = cactus_mem_send_cmd(SENDER, RECEIVER, FFA_MEM_LEND_SMC32, handle,
-				  FFA_MEMORY_REGION_FLAG_CLEAR, true,
-				  nr_words_to_write);
+				  FFA_MEMORY_REGION_FLAG_CLEAR, nr_words_to_write);
 
 	if (!is_ffa_direct_response(ret)) {
 		return TEST_RESULT_FAIL;
diff --git a/tftf/tests/tests-invalid-access.mk b/tftf/tests/tests-invalid-access.mk
index 3b05349..346ba9d 100644
--- a/tftf/tests/tests-invalid-access.mk
+++ b/tftf/tests/tests-invalid-access.mk
@@ -25,4 +25,5 @@
 		ffa_helpers.c						\
 		spm_common.c						\
 		test_ffa_setup_and_discovery.c				\
+		spm_test_helpers.c					\
 )
diff --git a/tftf/tests/tests-invalid-access.xml b/tftf/tests/tests-invalid-access.xml
index 0cd8234..33b85c5 100644
--- a/tftf/tests/tests-invalid-access.xml
+++ b/tftf/tests/tests-invalid-access.xml
@@ -22,5 +22,7 @@
                 function="s_memory_cannot_be_accessed_in_rl" />
       <testcase name="Access Root memory from Realm world"
                 function="rt_memory_cannot_be_accessed_in_rl" />
+      <testcase name="Share memory to an SP from a Root region"
+                function="rt_memory_cannot_be_accessed_in_s" />
   </testsuite>
 </testsuites>