Merge changes I5961f953,I9ab3d94f
* changes:
feat(realm_payload): use random start REC
feat(realm_payload): increase maximum number of RECs
diff --git a/include/runtime_services/host_realm_managment/realm_def.h b/include/runtime_services/host_realm_managment/realm_def.h
index 992ed9a..5258b87 100644
--- a/include/runtime_services/host_realm_managment/realm_def.h
+++ b/include/runtime_services/host_realm_managment/realm_def.h
@@ -17,7 +17,7 @@
#define DATA_PATTERN_2 0x11223344U
#define REALM_SUCCESS 0U
#define REALM_ERROR 1U
-#define MAX_REC_COUNT 8U
+#define MAX_REC_COUNT 17U
#define MAX_REALM_COUNT U(2)
/* Only support 4KB at the moment */
diff --git a/tftf/tests/runtime_services/realm_payload/host_realm_payload_multiple_rec_tests.c b/tftf/tests/runtime_services/realm_payload/host_realm_payload_multiple_rec_tests.c
index 0047d30..e3ee23b 100644
--- a/tftf/tests/runtime_services/realm_payload/host_realm_payload_multiple_rec_tests.c
+++ b/tftf/tests/runtime_services/realm_payload/host_realm_payload_multiple_rec_tests.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -30,10 +30,10 @@
test_result_t host_realm_multi_rec_single_cpu(void)
{
bool ret1, ret2;
- u_register_t rec_flag[] = {RMI_RUNNABLE, RMI_RUNNABLE, RMI_RUNNABLE,
- RMI_RUNNABLE, RMI_RUNNABLE, RMI_RUNNABLE, RMI_RUNNABLE, RMI_RUNNABLE};
+ u_register_t rec_flag[MAX_REC_COUNT];
u_register_t feature_flag = 0U;
long sl = RTT_MIN_LEVEL;
+ unsigned int rec_num;
SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
@@ -42,18 +42,30 @@
sl = RTT_MIN_LEVEL_LPA2;
}
+ for (unsigned int i = 0U; i < MAX_REC_COUNT; i++) {
+ rec_flag[i] = RMI_RUNNABLE;
+ }
+
if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
feature_flag, sl, rec_flag, MAX_REC_COUNT)) {
return TEST_RESULT_FAIL;
}
+ /* Start random Rec */
+ rec_num = (unsigned int)rand() % MAX_REC_COUNT;
+
for (unsigned int i = 0; i < MAX_REC_COUNT; i++) {
- host_shared_data_set_host_val(&realm, i, HOST_ARG1_INDEX, 10U);
+ host_shared_data_set_host_val(&realm, rec_num, HOST_ARG1_INDEX, 10U);
ret1 = host_enter_realm_execute(&realm, REALM_SLEEP_CMD,
- RMI_EXIT_HOST_CALL, i);
+ RMI_EXIT_HOST_CALL, rec_num);
if (!ret1) {
break;
}
+
+ /* Increment Rec number */
+ if (++rec_num == MAX_REC_COUNT) {
+ rec_num = 0U;
+ }
}
ret2 = host_destroy_realm(&realm);
@@ -224,23 +236,26 @@
test_result_t host_realm_multi_rec_exit_irq(void)
{
bool ret1, ret2;
- unsigned int rec_count = MAX_REC_COUNT;
u_register_t other_mpidr, my_mpidr, ret;
- int cpu_node;
+ unsigned int cpu_node, rec_count;
u_register_t feature_flag = 0U;
long sl = RTT_MIN_LEVEL;
- u_register_t rec_flag[] = {RMI_RUNNABLE, RMI_RUNNABLE, RMI_RUNNABLE,
- RMI_RUNNABLE, RMI_RUNNABLE, RMI_RUNNABLE, RMI_RUNNABLE,
- RMI_RUNNABLE};
+ u_register_t rec_flag[MAX_REC_COUNT];
SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
- SKIP_TEST_IF_LESS_THAN_N_CPUS(rec_count);
+
+ rec_count = tftf_get_total_cpus_count();
+ assert(rec_count <= MAX_REC_COUNT);
if (is_feat_52b_on_4k_2_supported() == true) {
feature_flag = RMI_FEATURE_REGISTER_0_LPA2;
sl = RTT_MIN_LEVEL_LPA2;
}
+ for (unsigned int i = 0U; i < rec_count; i++) {
+ rec_flag[i] = RMI_RUNNABLE;
+ }
+
if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
feature_flag, sl, rec_flag, rec_count)) {
return TEST_RESULT_FAIL;
@@ -261,7 +276,7 @@
}
}
- INFO("Wait for all CPU to come up\n");
+ INFO("Wait for all CPUs to come up\n");
while (is_secondary_cpu_on != (rec_count - 1U)) {
waitms(100U);
}
@@ -269,7 +284,7 @@
destroy_realm:
tftf_irq_enable(IRQ_NS_SGI_7, GIC_HIGHEST_NS_PRIORITY);
for (unsigned int i = 1U; i < rec_count; i++) {
- INFO("Raising NS IRQ for rec %d\n", i);
+ INFO("Raising NS IRQ for rec %u\n", i);
host_rec_send_sgi(&realm, IRQ_NS_SGI_7, i);
}
tftf_irq_disable(IRQ_NS_SGI_7);
@@ -313,7 +328,7 @@
* Each of the secondary then enters Realm with a different REC
* and executes the test REALM_MULTIPLE_REC_MULTIPLE_CPU_CMD in Realm payload.
* It is expected that the REC will exit with PSCI_CPU_OFF as the exit reason.
- * REC00 checks if all other CPUs are off, via PSCI_AFFINITY_INFO.
+ * REC0 checks if all other CPUs are off, via PSCI_AFFINITY_INFO.
* Host completes the PSCI requests.
*/
test_result_t host_realm_multi_rec_multiple_cpu(void)
@@ -324,32 +339,36 @@
u_register_t rec_num;
u_register_t other_mpidr, my_mpidr;
struct rmi_rec_run *run;
- unsigned int host_call_result, i = 0U;
- u_register_t rec_flag[] = {RMI_RUNNABLE, RMI_NOT_RUNNABLE, RMI_NOT_RUNNABLE,
- RMI_NOT_RUNNABLE, RMI_NOT_RUNNABLE, RMI_NOT_RUNNABLE, RMI_NOT_RUNNABLE,
- RMI_NOT_RUNNABLE};
+ unsigned int host_call_result, i;
+ u_register_t rec_flag[MAX_REC_COUNT] = {RMI_RUNNABLE};
u_register_t exit_reason;
- int cpu_node;
+ unsigned int cpu_node, rec_count;
u_register_t feature_flag = 0U;
long sl = RTT_MIN_LEVEL;
SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
- SKIP_TEST_IF_LESS_THAN_N_CPUS(MAX_REC_COUNT);
+
+ rec_count = tftf_get_total_cpus_count();
+ assert(rec_count <= MAX_REC_COUNT);
if (is_feat_52b_on_4k_2_supported() == true) {
feature_flag = RMI_FEATURE_REGISTER_0_LPA2;
sl = RTT_MIN_LEVEL_LPA2;
}
+ for (i = 1U; i < rec_count; i++) {
+ rec_flag[i] = RMI_NOT_RUNNABLE;
+ }
+
if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
- feature_flag, sl, rec_flag, MAX_REC_COUNT)) {
+ feature_flag, sl, rec_flag, rec_count)) {
return TEST_RESULT_FAIL;
}
is_secondary_cpu_on = 0U;
init_spinlock(&secondary_cpu_lock);
my_mpidr = read_mpidr_el1() & MPID_MASK;
- host_shared_data_set_host_val(&realm, 0U, HOST_ARG1_INDEX, MAX_REC_COUNT);
+ host_shared_data_set_host_val(&realm, 0U, HOST_ARG1_INDEX, rec_count);
ret1 = host_enter_realm_execute(&realm, REALM_MULTIPLE_REC_MULTIPLE_CPU_CMD,
RMI_EXIT_PSCI, 0U);
if (!ret1) {
@@ -386,9 +405,11 @@
goto destroy_realm;
}
+ i = 0U;
+
/* Turn on all CPUs */
for_each_cpu(cpu_node) {
- if (i == (MAX_REC_COUNT - 1U)) {
+ if (i == (rec_count - 1U)) {
break;
}
other_mpidr = tftf_get_mpidr_from_node(cpu_node);
@@ -416,7 +437,7 @@
break;
}
rec_num = host_realm_find_rec_by_mpidr(run->exit.gprs[1], &realm);
- if (rec_num >= MAX_REC_COUNT) {
+ if (rec_num >= rec_count) {
ERROR("Invalid mpidr requested\n");
goto destroy_realm;
}
@@ -463,9 +484,7 @@
struct realm realm2;
u_register_t feature_flag = 0U;
long sl = RTT_MIN_LEVEL;
- u_register_t rec_flag[] = {RMI_RUNNABLE, RMI_NOT_RUNNABLE, RMI_NOT_RUNNABLE,
- RMI_NOT_RUNNABLE, RMI_NOT_RUNNABLE, RMI_NOT_RUNNABLE, RMI_NOT_RUNNABLE,
- RMI_NOT_RUNNABLE};
+ u_register_t rec_flag[MAX_REC_COUNT] = {RMI_RUNNABLE};
u_register_t exit_reason;
SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
@@ -475,6 +494,10 @@
sl = RTT_MIN_LEVEL_LPA2;
}
+ for (unsigned int i = 1U; i < MAX_REC_COUNT; i++) {
+ rec_flag[i] = RMI_NOT_RUNNABLE;
+ }
+
if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
feature_flag, sl, rec_flag, MAX_REC_COUNT)) {
return TEST_RESULT_FAIL;
@@ -596,21 +619,27 @@
{
u_register_t feature_flag = 0U;
u_register_t rmm_feat_reg0;
- u_register_t rec_flag[8U] = {RMI_RUNNABLE, RMI_RUNNABLE, RMI_RUNNABLE, RMI_RUNNABLE,
- RMI_RUNNABLE, RMI_RUNNABLE, RMI_RUNNABLE, RMI_RUNNABLE};
- bool ret1 = 0U, ret2;
- unsigned int num_cnts, i = 0U;
+ u_register_t rec_flag[MAX_REC_COUNT];
+ bool ret1 = false, ret2;
+ unsigned int num_cnts, rec_count, i;
u_register_t other_mpidr, my_mpidr, ret;
int cpu_node;
long sl = RTT_MIN_LEVEL;
SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
+ rec_count = tftf_get_total_cpus_count();
+ assert(rec_count <= MAX_REC_COUNT);
+
if (is_feat_52b_on_4k_2_supported() == true) {
feature_flag = RMI_FEATURE_REGISTER_0_LPA2;
sl = RTT_MIN_LEVEL_LPA2;
}
+ for (i = 0U; i < rec_count; i++) {
+ rec_flag[i] = RMI_RUNNABLE;
+ }
+
/* Get Max PMU counter implemented through RMI_FEATURES */
if (host_rmi_features(0UL, &rmm_feat_reg0) != REALM_SUCCESS) {
ERROR("%s() failed\n", "host_rmi_features");
@@ -673,7 +702,7 @@
/* Prepare realm0, create recs for realm0 later */
if (!host_prepare_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
- feature_flag, sl, rec_flag, MAX_REC_COUNT)) {
+ feature_flag, sl, rec_flag, rec_count)) {
goto test_exit;
return TEST_RESULT_FAIL;
}
@@ -687,7 +716,7 @@
}
if (!host_create_activate_realm_payload(&realm1, (u_register_t)REALM_IMAGE_BASE,
- feature_flag, sl, rec_flag, MAX_REC_COUNT)) {
+ feature_flag, sl, rec_flag, rec_count)) {
goto test_exit2;
}
@@ -710,7 +739,7 @@
INFO("MAX PMU Counter=%u\n", num_cnts);
/* Pass num of PMU counters programmed to realm */
- for (unsigned int j = 0U; j < MAX_REC_COUNT; j++) {
+ for (unsigned int j = 0U; j < rec_count; j++) {
host_shared_data_set_host_val(&realm, j, HOST_ARG1_INDEX, num_cnts);
host_shared_data_set_host_val(&realm1, j, HOST_ARG1_INDEX, num_cnts - 1U);
}
@@ -742,9 +771,11 @@
goto test_exit2;
}
+ i = 0U;
+
/* Turn on all CPUs */
for_each_cpu(cpu_node) {
- if (i == (MAX_REC_COUNT - 1U)) {
+ if (i == (rec_count - 1U)) {
break;
}
other_mpidr = tftf_get_mpidr_from_node(cpu_node);
@@ -762,7 +793,7 @@
}
/* Wait for all CPU to power up */
- while (is_secondary_cpu_on != MAX_REC_COUNT - 1U) {
+ while (is_secondary_cpu_on != (rec_count - 1U)) {
waitms(100);
}
diff --git a/tftf/tests/runtime_services/realm_payload/host_realm_payload_tests.c b/tftf/tests/runtime_services/realm_payload/host_realm_payload_tests.c
index 278e72e..e22a9f1 100644
--- a/tftf/tests/runtime_services/realm_payload/host_realm_payload_tests.c
+++ b/tftf/tests/runtime_services/realm_payload/host_realm_payload_tests.c
@@ -25,18 +25,20 @@
extern const char *rmi_exit[];
+static struct realm realm[MAX_REALM_COUNT];
+
#if ENABLE_PAUTH
static uint128_t pauth_keys_before[NUM_KEYS];
static uint128_t pauth_keys_after[NUM_KEYS];
#endif
/*
- * @Test_Aim@ Test realm payload creation, execution and destruction iteratively
+ * @Test_Aim@ Test realm payload creation, execution and destruction iteratively
*/
test_result_t host_test_realm_create_enter(void)
{
bool ret1, ret2;
- u_register_t rec_flag[1] = {RMI_RUNNABLE};
+ u_register_t rec_flag[MAX_REC_COUNT];
struct realm realm;
u_register_t feature_flag = 0UL;
long sl = RTT_MIN_LEVEL;
@@ -48,14 +50,22 @@
sl = RTT_MIN_LEVEL_LPA2;
}
+ for (unsigned int i = 0U; i < MAX_REC_COUNT; i++) {
+ rec_flag[i] = RMI_RUNNABLE;
+ }
+
for (unsigned int i = 0U; i < 5U; i++) {
+ /* Run random Rec */
+ unsigned int run_num = (unsigned int)rand() % MAX_REC_COUNT;
+
if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
- feature_flag, sl, rec_flag, 1U)) {
+ feature_flag, sl, rec_flag, MAX_REC_COUNT)) {
return TEST_RESULT_FAIL;
}
- host_shared_data_set_host_val(&realm, 0U, HOST_ARG1_INDEX, SLEEP_TIME_MS);
- ret1 = host_enter_realm_execute(&realm, REALM_SLEEP_CMD, RMI_EXIT_HOST_CALL, 0U);
+ host_shared_data_set_host_val(&realm, run_num, HOST_ARG1_INDEX, SLEEP_TIME_MS);
+ ret1 = host_enter_realm_execute(&realm, REALM_SLEEP_CMD, RMI_EXIT_HOST_CALL,
+ run_num);
ret2 = host_destroy_realm(&realm);
if (!ret1 || !ret2) {
@@ -113,8 +123,7 @@
return TEST_RESULT_SKIPPED;
#else
bool ret1, ret2;
- u_register_t rec_flag[MAX_REC_COUNT] = {RMI_RUNNABLE, RMI_RUNNABLE, RMI_RUNNABLE,
- RMI_RUNNABLE, RMI_RUNNABLE, RMI_RUNNABLE, RMI_RUNNABLE, RMI_RUNNABLE,};
+ u_register_t rec_flag[MAX_REC_COUNT];
struct realm realm;
u_register_t feature_flag = 0U;
long sl = RTT_MIN_LEVEL;
@@ -126,6 +135,10 @@
sl = RTT_MIN_LEVEL_LPA2;
}
+ for (unsigned int i = 0U; i < MAX_REC_COUNT; i++) {
+ rec_flag[i] = RMI_RUNNABLE;
+ }
+
pauth_test_lib_fill_regs_and_template(pauth_keys_before);
if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
feature_flag, sl, rec_flag, MAX_REC_COUNT)) {
@@ -368,19 +381,19 @@
}
/*
- * Test aim to create, enter and destroy 2 realms
- * Host created 2 realms with 1 rec each
- * Host enters both rec sequentially
- * Verifies both realm returned success
- * Destroys both realms
+ * Test aim to create, enter and destroy MAX_REALM_COUNT realms
+ * Host created MAX_REALM_COUNT realms with MAX_REC_COUNT rec each
+ * Host enters all recs sequentially, starting from the random rec
+ * Verifies all realms returned success
+ * Destroys all realms
*/
test_result_t host_test_multiple_realm_create_enter(void)
{
- bool ret1, ret2, ret3;
- u_register_t rec_flag[1] = {RMI_RUNNABLE};
- struct realm realm1, realm2;
+ bool ret;
+ u_register_t rec_flag[MAX_REC_COUNT];
u_register_t feature_flag = 0U;
long sl = RTT_MIN_LEVEL;
+ unsigned int run_rec[MAX_REALM_COUNT], num;
SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
@@ -389,40 +402,47 @@
sl = RTT_MIN_LEVEL_LPA2;
}
- if (!host_create_activate_realm_payload(&realm1, (u_register_t)REALM_IMAGE_BASE,
- feature_flag, sl, rec_flag, 1U)) {
- return TEST_RESULT_FAIL;
+ for (unsigned int i = 0U; i < MAX_REC_COUNT; i++) {
+ rec_flag[i] = RMI_RUNNABLE;
}
+ for (num = 0U; num < MAX_REALM_COUNT; num++) {
+ /* Generate random REC start number */
+ run_rec[num] = (unsigned int)rand() % MAX_REC_COUNT;
- if (!host_create_activate_realm_payload(&realm2, (u_register_t)REALM_IMAGE_BASE,
- feature_flag, sl, rec_flag, 1U)) {
- ret2 = host_destroy_realm(&realm1);
- return TEST_RESULT_FAIL;
+ ret = host_create_activate_realm_payload(&realm[num],
+ (u_register_t)REALM_IMAGE_BASE,
+ feature_flag, sl, rec_flag, MAX_REC_COUNT);
+ if (!ret) {
+ goto destroy_realms;
+ }
}
- host_shared_data_set_host_val(&realm1, 0U, HOST_ARG1_INDEX, SLEEP_TIME_MS);
- ret1 = host_enter_realm_execute(&realm1, REALM_SLEEP_CMD, RMI_EXIT_HOST_CALL, 0U);
- if (!ret1) {
- goto destroy_realms;
+ for (unsigned int j = 0U; j < MAX_REC_COUNT; j++) {
+ for (unsigned int i = 0U; i < MAX_REALM_COUNT; i++) {
+ host_shared_data_set_host_val(&realm[i], run_rec[i], HOST_ARG1_INDEX,
+ SLEEP_TIME_MS);
+ ret = host_enter_realm_execute(&realm[i], REALM_SLEEP_CMD,
+ RMI_EXIT_HOST_CALL, run_rec[i]);
+ if (!ret) {
+ goto destroy_realms;
+ }
+
+ /* Increment REC number */
+ if (++run_rec[i] == MAX_REC_COUNT) {
+ run_rec[i] = 0U;
+ }
+ }
}
- host_shared_data_set_host_val(&realm2, 0U, HOST_ARG1_INDEX, SLEEP_TIME_MS);
- ret1 = host_enter_realm_execute(&realm2, REALM_SLEEP_CMD, RMI_EXIT_HOST_CALL, 0U);
destroy_realms:
- ret2 = host_destroy_realm(&realm1);
- ret3 = host_destroy_realm(&realm2);
-
- if (!ret3 || !ret2) {
- ERROR("destroy failed\n");
- return TEST_RESULT_FAIL;
+ for (unsigned int i = 0U; i < num; i++) {
+ if (!host_destroy_realm(&realm[i])) {
+ ERROR("Realm #%u destroy failed\n", i);
+ ret = false;
+ }
}
-
- if (!ret1) {
- return TEST_RESULT_FAIL;
- }
-
- return TEST_RESULT_SUCCESS;
+ return (ret ? TEST_RESULT_SUCCESS : TEST_RESULT_FAIL);
}
/*
@@ -1233,8 +1253,7 @@
struct realm realm;
u_register_t feature_flag = 0UL;
long sl = RTT_MIN_LEVEL;
- u_register_t rec_flag[] = {RMI_RUNNABLE, RMI_RUNNABLE, RMI_RUNNABLE,
- RMI_RUNNABLE, RMI_RUNNABLE, RMI_RUNNABLE, RMI_RUNNABLE, RMI_RUNNABLE}, dit;
+ u_register_t rec_flag[MAX_REC_COUNT], dit;
SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
@@ -1243,6 +1262,10 @@
sl = RTT_MIN_LEVEL_LPA2;
}
+ for (unsigned int i = 0U; i < MAX_REC_COUNT; i++) {
+ rec_flag[i] = RMI_RUNNABLE;
+ }
+
if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
feature_flag, sl, rec_flag, MAX_REC_COUNT)) {
return TEST_RESULT_FAIL;