feat(planes): test SIMD access from plane N

Add tests to exercise access to SIMD functinality from Plane N.
The tests alternate execution of 'rdvl' instruction from Plane 0 and
Plane N in different sequences and combinations of TRAP_SIMD values.

Signed-off-by: Javier Almansa Sobrino <javier.almansasobrino@arm.com>
Change-Id: I55b9bf55b43b72419e8244f228c505a58c2a819c
diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h
index 72cd009..98bbab8 100644
--- a/include/lib/aarch64/arch.h
+++ b/include/lib/aarch64/arch.h
@@ -1093,6 +1093,7 @@
 #define EC_AARCH64_HVC			U(0x16)
 #define EC_AARCH64_SMC			U(0x17)
 #define EC_AARCH64_SYS			U(0x18)
+#define EC_AARCH64_SVE			U(0x19)
 #define EC_IABORT_LOWER_EL		U(0x20)
 #define EC_IABORT_CUR_EL		U(0x21)
 #define EC_PC_ALIGN			U(0x22)
diff --git a/include/runtime_services/host_realm_managment/host_realm_simd.h b/include/runtime_services/host_realm_managment/host_realm_simd.h
index 9680a96..49a8608 100644
--- a/include/runtime_services/host_realm_managment/host_realm_simd.h
+++ b/include/runtime_services/host_realm_managment/host_realm_simd.h
@@ -8,6 +8,9 @@
 
 #include <stdint.h>
 
+/* Number of attempts, for plane N, to cause a SIMD access */
+#define SIMD_TRAP_ATTEMPTS		(3UL)
+
 struct sve_cmd_rdvl {
 	uint64_t rdvl;
 };
diff --git a/include/runtime_services/host_realm_managment/host_shared_data.h b/include/runtime_services/host_realm_managment/host_shared_data.h
index 1f8d624..c084c51 100644
--- a/include/runtime_services/host_realm_managment/host_shared_data.h
+++ b/include/runtime_services/host_realm_managment/host_shared_data.h
@@ -72,6 +72,8 @@
 	REALM_SVE_FILL_REGS,
 	REALM_SVE_CMP_REGS,
 	REALM_SVE_UNDEF_ABORT,
+	REALM_SVE_PLANE_N_ACCESS,
+	REALM_SVE_TEST_PLANE_N,
 	REALM_PAUTH_SET_CMD,
 	REALM_PAUTH_CHECK_CMD,
 	REALM_PAUTH_FAULT,
diff --git a/realm/include/realm_helpers.h b/realm/include/realm_helpers.h
index c5af1be..90fde00 100644
--- a/realm/include/realm_helpers.h
+++ b/realm/include/realm_helpers.h
@@ -30,12 +30,11 @@
  * Function to enter Aux Plane from Primary Plane
  * arg1 == plane index
  * arg2 == permission index to be used by plane
- * arg3 == base entrypoint
- * arg4 == entry flags
- * aarg5 == run object, needs to be PAGE aligned
+ * arg3 == entry flags
+ * arg4 == run object, needs to be PAGE aligned
  */
 bool realm_plane_enter(u_register_t plane_index, u_register_t perm_index,
-		u_register_t base, u_register_t flags, rsi_plane_run *run);
+			u_register_t flags, rsi_plane_run *run);
 
 /* This function will call the Host to request IPA of the NS shared buffer */
 u_register_t realm_get_ns_buffer(void);
@@ -48,8 +47,13 @@
 
 /* Function for initializing planes, called at Boot */
 void realm_plane_init(void);
+
 bool plane_common_init(u_register_t plane_index, u_register_t perm_index,
 		u_register_t base, rsi_plane_run *run);
 
+/* Resume execution of plane N */
+bool realm_resume_plane_n(rsi_plane_run *run, u_register_t plane_index,
+			  u_register_t flags);
+
 #endif /* REALM_HELPERS_H */
 
diff --git a/realm/include/realm_rsi.h b/realm/include/realm_rsi.h
index 38793e9..2e984b0 100644
--- a/realm/include/realm_rsi.h
+++ b/realm/include/realm_rsi.h
@@ -556,6 +556,9 @@
 #define RSI_PLANE_ENTRY_FLAG_TRAP_WFI	U(1UL << 0)
 #define RSI_PLANE_ENTRY_FLAG_TRAP_WFE	U(1UL << 1)
 #define RSI_PLANE_ENTRY_FLAG_TRAP_HC	U(1UL << 2)
+#define RSI_PLANE_ENTRY_FLAG_TRAP_SIMD	U(1UL << 4)
+
+#define RSI_PLANE_ENTRY_FLAG_MASK	U(0x1F)
 
 /* Data structure used to pass values from P0 to the RMM on Plane entry */
 struct rsi_plane_entry {
diff --git a/realm/include/realm_tests.h b/realm/include/realm_tests.h
index 4ed3367..dedf1cf 100644
--- a/realm/include/realm_tests.h
+++ b/realm/include/realm_tests.h
@@ -23,6 +23,8 @@
 bool test_realm_sve_fill_regs(void);
 bool test_realm_sve_cmp_regs(void);
 bool test_realm_sve_undef_abort(void);
+bool test_realm_sve_plane_n_access(void);
+bool test_realm_sve_plane_n(void);
 bool test_realm_multiple_rec_psci_denied_cmd(void);
 bool test_realm_multiple_rec_multiple_cpu_cmd(void);
 bool test_realm_multiple_plane_multiple_rec_multiple_cpu_cmd(void);
diff --git a/realm/realm_multiple_rec.c b/realm/realm_multiple_rec.c
index 2b364c5..50964ae 100644
--- a/realm/realm_multiple_rec.c
+++ b/realm/realm_multiple_rec.c
@@ -56,7 +56,7 @@
 	/* Use Base adr, plane_index, perm_index programmed by P0 rec0 */
 	run[rec].enter.pc = base;
 	realm_printf("Entering plane %ld, ep=0x%lx rec=0x%lx\n", plane_index, base, rec);
-	realm_plane_enter(plane_index, perm_index, base, flags, &run[rec]);
+	realm_plane_enter(plane_index, perm_index, flags, &run[rec]);
 
 	if (run[rec].exit.gprs[0] == SMC_PSCI_CPU_OFF) {
 		realm_printf("Plane N did not request CPU OFF\n");
@@ -150,7 +150,7 @@
 
 		plane_common_init(plane_index, perm_index, base, &run[0U]);
 
-		ret1 = realm_plane_enter(plane_index, perm_index, base, flags, &run[0U]);
+		ret1 = realm_plane_enter(plane_index, perm_index, flags, &run[0U]);
 		while (ret1 && run->exit.gprs[0] == SMC_PSCI_CPU_ON_AARCH64) {
 			realm_printf("Plane N requested CPU on Rec=0x%lx\n", run[0].exit.gprs[1]);
 
@@ -160,7 +160,7 @@
 						CXT_ID_MAGIC + run[0].exit.gprs[1]);
 
 			/* re-enter plane N 1 to complete cpu on */
-			ret1 = realm_plane_enter(plane_index, perm_index, base, flags, &run[0U]);
+			ret1 = realm_plane_enter(plane_index, perm_index, flags, &run[0U]);
 			if (!ret1) {
 				realm_printf("PlaneN CPU on complete failed\n");
 				rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD);
diff --git a/realm/realm_payload_main.c b/realm/realm_payload_main.c
index c891746..8bded3f 100644
--- a/realm/realm_payload_main.c
+++ b/realm/realm_payload_main.c
@@ -60,7 +60,7 @@
 	}
 
 	realm_printf("Entering plane %ld, ep=0x%lx run=0x%lx\n", plane_index, base, &run);
-	return realm_plane_enter(plane_index, perm_index, base, flags, &run);
+	return realm_plane_enter(plane_index, perm_index, flags, &run);
 }
 
 static bool test_realm_enter_plane_n_reg_rw(void)
@@ -80,7 +80,7 @@
 		}
 
 		realm_printf("Entering plane %ld, ep=0x%lx run=0x%lx\n", plane_index, base, &run);
-		ret = realm_plane_enter(plane_index, perm_index, base, flags, &run);
+		ret = realm_plane_enter(plane_index, perm_index, flags, &run);
 		if (ret) {
 			/* get return value from plane1 */
 			reg1 = realm_shared_data_get_plane_n_val(plane_index,
@@ -132,7 +132,7 @@
 			}
 
 			/* enter plane n */
-			ret = realm_plane_enter(plane_index, perm_index, base, flags, &run);
+			ret = realm_plane_enter(plane_index, perm_index, flags, &run);
 			if (ret) {
 				/* read pauth register for plane1 */
 				ret = rsi_plane_sysreg_read(plane_index, SYSREG_ID_apibkeylo_el1,
@@ -324,7 +324,7 @@
 	}
 
 	realm_printf("Entering plane %ld, ep=0x%lx run=0x%lx\n", plane_index, base, &run);
-	ret1 = realm_plane_enter(plane_index, perm_index, base, flags, &run);
+	ret1 = realm_plane_enter(plane_index, perm_index, flags, &run);
 
 	realm_printf("Plane exit reason=0x%lx\n", run.exit.exit_reason);
 
@@ -659,6 +659,12 @@
 		case REALM_SVE_UNDEF_ABORT:
 			test_succeed = test_realm_sve_undef_abort();
 			break;
+		case REALM_SVE_PLANE_N_ACCESS:
+			test_succeed = test_realm_sve_plane_n_access();
+			break;
+		case REALM_SVE_TEST_PLANE_N:
+			test_succeed = test_realm_sve_plane_n();
+			break;
 		case REALM_SME_ID_REGISTERS:
 			test_succeed = test_realm_sme_read_id_registers();
 			break;
diff --git a/realm/realm_plane.c b/realm/realm_plane.c
index dba6cff..d0e4ec4 100644
--- a/realm/realm_plane.c
+++ b/realm/realm_plane.c
@@ -193,7 +193,6 @@
 
 bool realm_plane_enter(u_register_t plane_index,
 		u_register_t perm_index,
-		u_register_t base,
 		u_register_t flags,
 		rsi_plane_run *run)
 {
@@ -226,3 +225,19 @@
 	}
 }
 
+bool realm_resume_plane_n(rsi_plane_run *run, u_register_t plane_index,
+			  u_register_t flags)
+{
+	u_register_t perm_index = plane_index + 1U;
+
+	/* Restore PSTATE on the plane */
+	run->enter.pstate = run->exit.pstate;
+
+	restore_plane_context(run);
+
+	flags &= RSI_PLANE_ENTRY_FLAG_MASK;
+
+	realm_printf("Resuming plane %ld, ep=0x%lx, run=0x%lx, flags=0x%lx\n",
+		     plane_index, run->enter.pc, run, flags);
+	return realm_plane_enter(plane_index, perm_index, flags, run);
+}
diff --git a/realm/realm_simd.c b/realm/realm_simd.c
index 0ff1710..7972478 100644
--- a/realm/realm_simd.c
+++ b/realm/realm_simd.c
@@ -36,6 +36,8 @@
 static fpu_cs_regs_t rl_fpu_cs_regs_write;
 static fpu_cs_regs_t rl_fpu_cs_regs_read;
 
+static rsi_plane_run run __aligned(PAGE_SIZE);
+
 /* Returns the maximum supported VL. This test is called only by sve Realm */
 bool test_realm_sve_rdvl(void)
 {
@@ -231,3 +233,188 @@
 
 	return (realm_get_undef_abort_count() != 0U);
 }
+
+/*
+ * Helper function to try triggering a SVE exception by executing rdvl instruction.
+ */
+static u_register_t read_scaled_vector_length(void)
+{
+	u_register_t vl;
+
+	__asm__ volatile(
+		".arch_extension sve\n"
+		"rdvl %0, #1;"
+		".arch_extension nosve\n"
+		: "=r" (vl)
+	);
+
+	return vl;
+}
+
+/*
+ * Executes as many accesses to SVE registers as indicated by HOST_ARG1_INDEX.
+ *
+ * On plane exit, Plane 0 receives the following return values:
+ *	- HOST_ARG1_INDEX: Number of attempted accesses to SVE registers.
+ *	- HOST_ARG2_INDEX: Number of completed accesses to SVE registers.
+ */
+bool test_realm_sve_plane_n_access(void)
+{
+	uint64_t iterations = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
+	unsigned int n_access = 0U;
+
+	/* This should only be executed from Plane N */
+	assert(!realm_is_plane0());
+
+	realm_shared_data_set_my_realm_val(HOST_ARG1_INDEX, 0U);
+	realm_shared_data_set_my_realm_val(HOST_ARG2_INDEX, 0U);
+
+	for (; iterations > 0UL; iterations--) {
+		realm_shared_data_set_my_realm_val(HOST_ARG1_INDEX, ++n_access);
+		(void)read_scaled_vector_length();
+		realm_shared_data_set_my_realm_val(HOST_ARG2_INDEX, n_access);
+	}
+
+	return true;
+}
+
+static bool test_realm_enter_plane_n(u_register_t flags)
+{
+	u_register_t base, plane_index, perm_index;
+	bool ret1;
+
+	plane_index = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
+	base = realm_shared_data_get_my_host_val(HOST_ARG2_INDEX);
+	perm_index = plane_index + 1U;
+	flags &= RSI_PLANE_ENTRY_FLAG_MASK;
+
+	ret1 = plane_common_init(plane_index, perm_index, base, &run);
+	if (!ret1) {
+		return ret1;
+	}
+
+	realm_printf("Entering plane %ld, ep=0x%lx run=0x%lx\n", plane_index, base, &run);
+	return realm_plane_enter(plane_index, perm_index, flags, &run);
+}
+
+/*
+ * Test that combines accesses to SVE registers from Plane 0 and Plane N,
+ * using different sequences of entries to Plane N with and without TRAP_SIMD
+ * flag enabled.
+ *
+ * Expected arguments from Host:
+ *	- HOST_ARG1_INDEX: Plane index for Pn to run.
+ *	- HOST_ARG2_INDEX: Entry point for Pn.
+ *	- HOST_ARG3_INDEX: If 0, first SIMD access is performed from P0.
+ *			   Otherwise, first SIMD access is performed from Pn.
+ */
+bool test_realm_sve_plane_n(void)
+{
+	unsigned long attempted, success;
+	u_register_t plane_index = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
+
+	if (realm_shared_data_get_my_host_val(HOST_ARG3_INDEX) == 0UL) {
+		/* First SIMD access performed from P0 */
+		INFO("Executing first SIMD access from P0\n");
+		(void)read_scaled_vector_length();
+	} else {
+		INFO("Executing first SIMD access from PN\n");
+	}
+
+	/*
+	 * Enter Plane N with TRAP_SIMD disabled. Plane N will attempt
+	 * to executte SVE instrucctions SIMD_TRAP_ATTEMPTS times
+	 * and no plane exit should happen.
+	 */
+	if (!test_realm_enter_plane_n(0UL)) {
+		return false;
+	}
+
+	if ((run.exit.exit_reason != RSI_EXIT_SYNC) ||
+	    (EC_BITS(run.exit.esr) != EC_AARCH64_HVC)) {
+		ERROR("Invalid exit reason from PN: 0x%lx, EC: 0x%lx\n",
+			run.exit.exit_reason, EC_BITS(run.exit.esr));
+		return false;
+	}
+
+	attempted = realm_shared_data_get_plane_n_val(plane_index,
+						      REC_IDX(read_mpidr_el1()),
+						      HOST_ARG1_INDEX);
+	success = realm_shared_data_get_plane_n_val(plane_index,
+						    REC_IDX(read_mpidr_el1()),
+						    HOST_ARG2_INDEX);
+
+	if ((attempted < SIMD_TRAP_ATTEMPTS) || (success < SIMD_TRAP_ATTEMPTS)) {
+		ERROR("Attempted %u executions of rdvl instruction. %u succedded\n",
+		      attempted, success);
+		return false;
+	}
+
+	/* Try another access to the SVE registers from Plane 0 */
+	(void)read_scaled_vector_length();
+
+	/*
+	 * Restart PN again, this time with TRAP_SIMD enabled. That should
+	 * cause a plane exit when attempting SVE instructions.
+	 */
+	if (!test_realm_enter_plane_n(RSI_PLANE_ENTRY_FLAG_TRAP_SIMD)) {
+		return false;
+	}
+
+	if ((run.exit.exit_reason != RSI_EXIT_SYNC) ||
+	    (EC_BITS(run.exit.esr) != EC_AARCH64_SVE)) {
+		ERROR("Invalid exit reason from PN: 0x%lx, EC: 0x%lx\n",
+			run.exit.exit_reason, EC_BITS(run.exit.esr));
+		return false;
+	}
+
+	attempted = realm_shared_data_get_plane_n_val(plane_index,
+						      REC_IDX(read_mpidr_el1()),
+						      HOST_ARG1_INDEX);
+	success = realm_shared_data_get_plane_n_val(plane_index,
+						    REC_IDX(read_mpidr_el1()),
+						    HOST_ARG2_INDEX);
+
+	/*
+	 * Plane N should have exited after 1 attempt and the access should not
+	 * be completed yet.
+	 */
+	if ((attempted != 1U) || (success > 0U)) {
+		ERROR("Attempted %u executions of rdvl instruction. %u succedded\n",
+		      attempted, success);
+		return false;
+	}
+
+	/* Try another access to the SIMD registers from Plane 0 */
+	(void)read_scaled_vector_length();
+
+	/*
+	 * Resume Plane N with TRAP_SIMD disabled. No Plane exit should happen
+	 * due to SIMD access.
+	 */
+	if (!realm_resume_plane_n(&run, plane_index, 0U)) {
+		return false;
+	}
+
+	if ((run.exit.exit_reason != RSI_EXIT_SYNC) ||
+	    (EC_BITS(run.exit.esr) != EC_AARCH64_HVC)) {
+		ERROR("Invalid exit reason from PN: 0x%lx, EC: 0x%lx\n",
+			run.exit.exit_reason, EC_BITS(run.exit.esr));
+		return false;
+	}
+
+	attempted = realm_shared_data_get_plane_n_val(plane_index,
+						      REC_IDX(read_mpidr_el1()),
+						      HOST_ARG1_INDEX);
+	success = realm_shared_data_get_plane_n_val(plane_index,
+						    REC_IDX(read_mpidr_el1()),
+						    HOST_ARG2_INDEX);
+
+	if ((attempted < SIMD_TRAP_ATTEMPTS) || (success < SIMD_TRAP_ATTEMPTS)) {
+		ERROR("Attempted %u executions of rdvl instruction. %u succedded\n",
+		      attempted, success);
+		return false;
+	}
+
+	return true;
+}
diff --git a/tftf/tests/runtime_services/realm_payload/host_realm_payload_simd_tests.c b/tftf/tests/runtime_services/realm_payload/host_realm_payload_simd_tests.c
index 1c2f58e..7a087ff 100644
--- a/tftf/tests/runtime_services/realm_payload/host_realm_payload_simd_tests.c
+++ b/tftf/tests/runtime_services/realm_payload/host_realm_payload_simd_tests.c
@@ -99,7 +99,7 @@
 
 	sve_vq = EXTRACT(RMI_FEATURE_REGISTER_0_SVE_VL, rmi_feat_reg0);
 
-	rc = host_create_sve_realm_payload(&realm, true, sve_vq);
+	rc = host_create_sve_realm_payload(&realm, true, sve_vq, 1U, 0U);
 	if (rc != TEST_RESULT_SUCCESS) {
 		ERROR("Failed to create Realm with SVE\n");
 		return TEST_RESULT_FAIL;
@@ -157,7 +157,7 @@
 		return TEST_RESULT_SKIPPED;
 	}
 
-	rc = host_create_sve_realm_payload(&realm, true, (sve_vq + 1));
+	rc = host_create_sve_realm_payload(&realm, true, (sve_vq + 1), 1U, 0U);
 	if (rc == TEST_RESULT_SUCCESS) {
 		ERROR("Error: Realm created with invalid SVE VL %u\n", (sve_vq + 1));
 		host_destroy_realm(&realm);
@@ -183,7 +183,7 @@
 		sve_vq = EXTRACT(RMI_FEATURE_REGISTER_0_SVE_VL, rmi_feat_reg0);
 	}
 
-	rc = host_create_sve_realm_payload(&realm, sve_en, sve_vq);
+	rc = host_create_sve_realm_payload(&realm, sve_en, sve_vq, 1U, 0U);
 	if (rc != TEST_RESULT_SUCCESS) {
 		return rc;
 	}
@@ -264,7 +264,7 @@
 
 	sve_vq = EXTRACT(RMI_FEATURE_REGISTER_0_SVE_VL, rmi_feat_reg0);
 
-	rc = host_create_sve_realm_payload(&realm, true, sve_vq);
+	rc = host_create_sve_realm_payload(&realm, true, sve_vq, 1U, 0U);
 	if (rc != TEST_RESULT_SUCCESS) {
 		return rc;
 	}
@@ -319,7 +319,7 @@
 
 	vq = EXTRACT(RMI_FEATURE_REGISTER_0_SVE_VL, rmi_feat_reg0);
 
-	rc = host_create_sve_realm_payload(&realm, true, vq);
+	rc = host_create_sve_realm_payload(&realm, true, vq, 1U, 0U);
 	if (rc != TEST_RESULT_SUCCESS) {
 		return rc;
 	}
@@ -396,7 +396,7 @@
 	unsigned int i;
 	int val;
 
-	rc = host_create_sve_realm_payload(&realm, realm_sve_en, realm_sve_vq);
+	rc = host_create_sve_realm_payload(&realm, realm_sve_en, realm_sve_vq, 1U, 0U);
 	if (rc != TEST_RESULT_SUCCESS) {
 		return rc;
 	}
@@ -558,7 +558,7 @@
 	sve_config_vq(SVE_VQ_ARCH_MIN);
 
 	/* 3. Create Realm with max VQ (higher than NS SVE VQ) */
-	rc = host_create_sve_realm_payload(&realm, true, sve_vq);
+	rc = host_create_sve_realm_payload(&realm, true, sve_vq, 1U, 0U);
 	if (rc != TEST_RESULT_SUCCESS) {
 		return rc;
 	}
@@ -609,7 +609,7 @@
 	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
 	SKIP_TEST_IF_SVE_NOT_SUPPORTED();
 
-	rc = host_create_sve_realm_payload(&realm, false, 0);
+	rc = host_create_sve_realm_payload(&realm, false, 0, 1U, 0U);
 	if (rc != TEST_RESULT_SUCCESS) {
 		return rc;
 	}
@@ -644,7 +644,7 @@
 
 	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
 
-	rc = host_create_sve_realm_payload(&realm, false, 0);
+	rc = host_create_sve_realm_payload(&realm, false, 0, 1U, 0U);
 	if (rc != TEST_RESULT_SUCCESS) {
 		return rc;
 	}
@@ -687,7 +687,7 @@
 	SKIP_TEST_IF_SME_NOT_SUPPORTED();
 	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
 
-	rc = host_create_sve_realm_payload(&realm, false, 0);
+	rc = host_create_sve_realm_payload(&realm, false, 0, 1U, 0U);
 	if (rc != TEST_RESULT_SUCCESS) {
 		return rc;
 	}
@@ -736,7 +736,7 @@
 		sve_vq = 0;
 	}
 
-	rc = host_create_sve_realm_payload(&realm, sve_en, sve_vq);
+	rc = host_create_sve_realm_payload(&realm, sve_en, sve_vq, 1U, 0U);
 	if (rc != TEST_RESULT_SUCCESS) {
 		return rc;
 	}
@@ -814,3 +814,55 @@
 
 	return rc;
 }
+
+test_result_t host_realm_check_sve_in_planes(void)
+{
+	u_register_t rmi_feat_reg0;
+	uint8_t sve_vq;
+	test_result_t rc;
+
+	SKIP_TEST_IF_SME_NOT_SUPPORTED();
+	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
+
+	CHECK_SVE_SUPPORT_IN_HW_AND_IN_RMI(rmi_feat_reg0);
+
+	sve_vq = EXTRACT(RMI_FEATURE_REGISTER_0_SVE_VL, rmi_feat_reg0);
+
+	/*
+	 * This test will create a realm with two RECs.
+	 *	- REC 0 will execute REALM_SVE_TEST_PLANE_N_FIRST_P0
+	 *	- REC 1 will ececute REALM_SVE_TEST_PLANE_N_FIRST_PN
+	 */
+	rc = host_create_sve_realm_payload(&realm, true, sve_vq, 2U, 1U);
+	if (rc != TEST_RESULT_SUCCESS) {
+		return rc;
+	}
+
+	/* Setup the configuration for Plane 1 on both RECs */
+	for (unsigned int i = 0U; i < 2U; i++) {
+		host_shared_data_set_realm_cmd(&realm, REALM_SVE_PLANE_N_ACCESS, 1U, i);
+		host_shared_data_set_host_val(&realm, 1U, i, HOST_ARG1_INDEX,
+					      SIMD_TRAP_ATTEMPTS);
+		host_realm_set_aux_plane_args(&realm, 1U, i);
+
+		/* Rest of P0 parameters */
+		host_shared_data_set_host_val(&realm, PRIMARY_PLANE_ID, i,
+					      HOST_ARG3_INDEX, i);
+
+		/* Enter the REC */
+		rc = host_enter_realm_execute(&realm, REALM_SVE_TEST_PLANE_N,
+					      RMI_EXIT_HOST_CALL, i);
+
+		if (!rc) {
+			ERROR("Realm command REALM_SVE_TEST_PLANE_N failed\n");
+			rc = TEST_RESULT_FAIL;
+			break;
+		}
+	}
+
+	if (!host_destroy_realm(&realm)) {
+		return TEST_RESULT_FAIL;
+	}
+
+	return rc;
+}
diff --git a/tftf/tests/runtime_services/realm_payload/host_realm_simd_common.c b/tftf/tests/runtime_services/realm_payload/host_realm_simd_common.c
index 1ac65dd..2d271f7 100644
--- a/tftf/tests/runtime_services/realm_payload/host_realm_simd_common.c
+++ b/tftf/tests/runtime_services/realm_payload/host_realm_simd_common.c
@@ -22,17 +22,24 @@
 sve_z_regs_t ns_sve_z_regs_read;
 
 test_result_t host_create_sve_realm_payload(struct realm *realm, bool sve_en,
-					    uint8_t sve_vq)
+					    uint8_t sve_vq,
+					    unsigned int max_recs,
+					    unsigned int max_aux_planes)
 {
 	u_register_t feature_flag0 = 0UL;
+	u_register_t feature_flag1 = RMI_REALM_FLAGS1_RTT_TREE_PP;
 	long sl = RTT_MIN_LEVEL;
-	u_register_t rec_flag[1] = {RMI_RUNNABLE};
+	u_register_t rec_flag[MAX_REC_COUNT] = {RMI_NOT_RUNNABLE};
 
 	if (is_feat_52b_on_4k_2_supported() == true) {
 		feature_flag0 = RMI_FEATURE_REGISTER_0_LPA2;
 		sl = RTT_MIN_LEVEL_LPA2;
 	}
 
+	for (unsigned int i = 0U; i < max_recs; i++) {
+		rec_flag[i] = RMI_RUNNABLE;
+	}
+
 	if (sve_en) {
 		feature_flag0 |= RMI_FEATURE_REGISTER_0_SVE_EN |
 				INPLACE(RMI_FEATURE_REGISTER_0_SVE_VL, sve_vq);
@@ -41,7 +48,8 @@
 	/* Initialise Realm payload */
 	if (!host_create_activate_realm_payload(realm,
 				       (u_register_t)REALM_IMAGE_BASE,
-				       feature_flag0, 0UL, sl, rec_flag, 1U, 0U,
+				       feature_flag0, feature_flag1,
+				       sl, rec_flag, max_recs, max_aux_planes,
 				       get_test_mecid())) {
 		return TEST_RESULT_FAIL;
 	}
diff --git a/tftf/tests/runtime_services/realm_payload/host_realm_simd_common.h b/tftf/tests/runtime_services/realm_payload/host_realm_simd_common.h
index 6ab45c3..1de6c26 100644
--- a/tftf/tests/runtime_services/realm_payload/host_realm_simd_common.h
+++ b/tftf/tests/runtime_services/realm_payload/host_realm_simd_common.h
@@ -10,6 +10,7 @@
 #define NS_STREAMING_SVE	0x2U
 
 test_result_t host_create_sve_realm_payload(struct realm *realm, bool sve_en,
-					    uint8_t sve_vq);
+					    uint8_t sve_vq, unsigned int max_recs,
+					    unsigned int max_aux_planes);
 
 #endif
diff --git a/tftf/tests/runtime_services/realm_payload/host_realm_spm.c b/tftf/tests/runtime_services/realm_payload/host_realm_spm.c
index e81d82d..74c06d4 100644
--- a/tftf/tests/runtime_services/realm_payload/host_realm_spm.c
+++ b/tftf/tests/runtime_services/realm_payload/host_realm_spm.c
@@ -106,7 +106,7 @@
 
 	/* Create Realm with SVE enabled if RMI features supports it */
 	INFO("TFTF: create realm sve_en/sve_vq: %d/%d\n", sve_en, sve_vq);
-	rc = host_create_sve_realm_payload(realm, sve_en, sve_vq);
+	rc = host_create_sve_realm_payload(realm, sve_en, sve_vq, 1U, 0U);
 	if (rc != TEST_RESULT_SUCCESS) {
 		return rc;
 	}
diff --git a/tftf/tests/tests-realm-payload.xml b/tftf/tests/tests-realm-payload.xml
index df1e4c5..ee3f846 100644
--- a/tftf/tests/tests-realm-payload.xml
+++ b/tftf/tests/tests-realm-payload.xml
@@ -16,6 +16,8 @@
 	  function="host_test_realm_create_planes_register_rw" />
 	  <testcase name="Realm payload Planes multi rec multiple cpu"
 	  function="host_realm_multi_planes_multi_rec_multiple_cpu" />
+	  <testcase name="Access SVE registers from Plane N"
+	  function="host_realm_check_sve_in_planes" />
 	  <testcase name="Realm EL1 creation and execution test"
 	  function="host_test_realm_create_enter" />
 	  <testcase name="Realm RTT fold unfold test Unassigned Empty"