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"