fix(hftest): define stacks for all secondary cores
The hftest common libraries was reusing the same stack section
for all secondary cores.
This means some tests would fail unexpectidly.
Adding a function to common.c and service_common.c, which have
the same purpose in the target they are used in, to retrieve
the buffers for the secondary core stacks defined globally.
Signed-off-by: J-Alves <joao.alves@arm.com>
Signed-off-by: K-Meakin <karl.meakin@arm.com>
Change-Id: If93aed330a88c3b52e5771d09911296f2c6214ed
diff --git a/test/hftest/common.c b/test/hftest/common.c
index 1f85694..7aeda22 100644
--- a/test/hftest/common.c
+++ b/test/hftest/common.c
@@ -27,6 +27,8 @@
static struct hftest_context global_context;
+static alignas(PAGE_SIZE) uint8_t secondary_ec_stack[MAX_CPUS][PAGE_SIZE];
+
struct hftest_context *hftest_get_context(void)
{
return &global_context;
@@ -295,6 +297,12 @@
return index;
}
+uint8_t *hftest_get_secondary_ec_stack(size_t id)
+{
+ assert(id < MAX_CPUS);
+ return secondary_ec_stack[id];
+}
+
/**
* Get the ID of the CPU with the given index.
*/
diff --git a/test/hftest/power_mgmt.c b/test/hftest/power_mgmt.c
index 7b8c041..787a7fe 100644
--- a/test/hftest/power_mgmt.c
+++ b/test/hftest/power_mgmt.c
@@ -22,12 +22,6 @@
struct spinlock lock;
};
-/*
- * Stack for secondary execution contexts.
- * Used in tests for MP partitions where multicore functionality is tested.
- */
-alignas(PAGE_SIZE) uint8_t secondary_ec_stack[MAX_CPUS - 1][PAGE_SIZE];
-
static noreturn void cpu_entry(uintptr_t arg)
{
/*
@@ -56,18 +50,18 @@
arch_cpu_stop();
}
-bool hftest_cpu_start(cpu_id_t id, cpu_entry_point *entry, uintptr_t arg)
+bool hftest_cpu_start(cpu_id_t id, const uint8_t *secondary_ec_stack,
+ cpu_entry_point *entry, uintptr_t arg)
{
struct cpu_start_state s;
struct arch_cpu_start_state s_arch;
- size_t stack_size = sizeof(secondary_ec_stack[0]);
/*
* Config for arch_cpu_start() which will start a new CPU and
* immediately jump to cpu_entry(). This function must guarantee that
* the state struct is not be freed until cpu_entry() is called.
*/
- s_arch.initial_sp = (uintptr_t)secondary_ec_stack + stack_size;
+ s_arch.initial_sp = (uintptr_t)secondary_ec_stack;
s_arch.entry = cpu_entry;
s_arch.arg = (uintptr_t)&s;
diff --git a/test/hftest/service_common.c b/test/hftest/service_common.c
index b277b38..f0ab701 100644
--- a/test/hftest/service_common.c
+++ b/test/hftest/service_common.c
@@ -29,6 +29,14 @@
static struct hftest_context global_context;
+static alignas(PAGE_SIZE) uint8_t secondary_ec_stack[MAX_CPUS][PAGE_SIZE];
+
+uint8_t *hftest_get_secondary_ec_stack(size_t id)
+{
+ assert(id < MAX_CPUS);
+ return secondary_ec_stack[id];
+}
+
struct hftest_context *hftest_get_context(void)
{
return &global_context;
diff --git a/test/inc/test/hftest.h b/test/inc/test/hftest.h
index a7f23a6..fe2a074 100644
--- a/test/inc/test/hftest.h
+++ b/test/inc/test/hftest.h
@@ -183,10 +183,13 @@
* with the provided argument. It is a wrapper around the generic cpu_start()
* and takes care of MMU initialization.
*/
-bool hftest_cpu_start(cpu_id_t id, void (*entry)(uintptr_t arg), uintptr_t arg);
+bool hftest_cpu_start(cpu_id_t id, const uint8_t *secondary_ec_stack,
+ void (*entry)(uintptr_t arg), uintptr_t arg);
cpu_id_t hftest_get_cpu_id(size_t index);
+uint8_t *hftest_get_secondary_ec_stack(size_t id);
+
/*
* The type of CPU entry points: a function that takes one `uintptr_t` argument
* and returns `void`.
diff --git a/test/vmapi/ffa_secure_partitions/dir_msg.c b/test/vmapi/ffa_secure_partitions/dir_msg.c
index 68a90d7..d5d1ea5 100644
--- a/test/vmapi/ffa_secure_partitions/dir_msg.c
+++ b/test/vmapi/ffa_secure_partitions/dir_msg.c
@@ -160,9 +160,10 @@
id = hftest_get_cpu_id(i);
HFTEST_LOG("Booting CPU %zu - %lx", i, id);
- EXPECT_EQ(hftest_cpu_start(id, migrate_busy_up_sp,
- (uintptr_t)&args),
- true);
+ EXPECT_EQ(
+ hftest_cpu_start(id, hftest_get_secondary_ec_stack(i),
+ migrate_busy_up_sp, (uintptr_t)&args),
+ true);
HFTEST_LOG("Done with CPU %zu", i);
}
diff --git a/test/vmapi/ffa_secure_partitions/notifications.c b/test/vmapi/ffa_secure_partitions/notifications.c
index b50e30e..94e4a81 100644
--- a/test/vmapi/ffa_secure_partitions/notifications.c
+++ b/test/vmapi/ffa_secure_partitions/notifications.c
@@ -205,8 +205,9 @@
args.vcpu_id = i;
- EXPECT_EQ(hftest_cpu_start(hftest_get_cpu_id(i), cpu_entry,
- (uintptr_t)&args),
+ EXPECT_EQ(hftest_cpu_start(hftest_get_cpu_id(i),
+ hftest_get_secondary_ec_stack(i),
+ cpu_entry, (uintptr_t)&args),
true);
/* Wait for CPU to release the lock. */
diff --git a/test/vmapi/ffa_secure_partitions/power_mgt.c b/test/vmapi/ffa_secure_partitions/power_mgt.c
index e1feafb..29d7e8e 100644
--- a/test/vmapi/ffa_secure_partitions/power_mgt.c
+++ b/test/vmapi/ffa_secure_partitions/power_mgt.c
@@ -148,8 +148,9 @@
*/
args.vcpu_id = (ffa_vcpu_index_t)i;
- EXPECT_EQ(hftest_cpu_start(hftest_get_cpu_id(i), entry,
- (uintptr_t)&args),
+ EXPECT_EQ(hftest_cpu_start(hftest_get_cpu_id(i),
+ hftest_get_secondary_ec_stack(i),
+ entry, (uintptr_t)&args),
true);
/* Wait for CPU to release the lock. */
diff --git a/test/vmapi/ffa_secure_partitions/secure_interrupts.c b/test/vmapi/ffa_secure_partitions/secure_interrupts.c
index da0e171..0f5e3ce 100644
--- a/test/vmapi/ffa_secure_partitions/secure_interrupts.c
+++ b/test/vmapi/ffa_secure_partitions/secure_interrupts.c
@@ -549,8 +549,9 @@
args.vcpu_id = i;
HFTEST_LOG("Booting CPU %u - %lx", i, cpu_id);
- EXPECT_EQ(hftest_cpu_start(cpu_id, cpu_entry_sp_sleep_loop,
- (uintptr_t)&args),
+ EXPECT_EQ(hftest_cpu_start(
+ cpu_id, hftest_get_secondary_ec_stack(i),
+ cpu_entry_sp_sleep_loop, (uintptr_t)&args),
true);
/* Wait for CPU to release the lock. */
diff --git a/test/vmapi/primary_only/faults.c b/test/vmapi/primary_only/faults.c
index 0618674..215aac8 100644
--- a/test/vmapi/primary_only/faults.c
+++ b/test/vmapi/primary_only/faults.c
@@ -70,7 +70,8 @@
* MAX_CPUS - index internally. Since legacy VMs do not follow this
* convention, index 7 is passed into `hftest_cpu_get_id`.
*/
- EXPECT_EQ(hftest_cpu_start(hftest_get_cpu_id(7), rx_reader,
+ EXPECT_EQ(hftest_cpu_start(hftest_get_cpu_id(7),
+ hftest_get_secondary_ec_stack(0), rx_reader,
(uintptr_t)&s),
true);
diff --git a/test/vmapi/primary_only/primary_only.c b/test/vmapi/primary_only/primary_only.c
index 385f312..629f173 100644
--- a/test/vmapi/primary_only/primary_only.c
+++ b/test/vmapi/primary_only/primary_only.c
@@ -91,8 +91,9 @@
* MAX_CPUS - index internally. Since legacy VMs do not follow this
* convention, index 7 is passed into `hftest_cpu_get_id`.
*/
- EXPECT_EQ(hftest_cpu_start(hftest_get_cpu_id(7), vm_cpu_entry,
- (uintptr_t)&lock),
+ EXPECT_EQ(hftest_cpu_start(hftest_get_cpu_id(7),
+ hftest_get_secondary_ec_stack(0),
+ vm_cpu_entry, (uintptr_t)&lock),
true);
/* Wait for CPU to release the lock. */
@@ -139,6 +140,7 @@
sl_lock(&lock);
dlog("Starting second CPU.\n");
EXPECT_EQ(hftest_cpu_start(hftest_get_cpu_id(secondary_cpu_index),
+ hftest_get_secondary_ec_stack(0),
vm_cpu_entry_stop, (uintptr_t)&lock),
true);
@@ -154,6 +156,7 @@
dlog("Starting second CPU again.\n");
EXPECT_EQ(hftest_cpu_start(hftest_get_cpu_id(secondary_cpu_index),
+ hftest_get_secondary_ec_stack(0),
vm_cpu_entry_stop, (uintptr_t)&lock),
true);
diff --git a/test/vmapi/primary_with_secondaries/dir_msg.c b/test/vmapi/primary_with_secondaries/dir_msg.c
index 5096595..2a632d3 100644
--- a/test/vmapi/primary_with_secondaries/dir_msg.c
+++ b/test/vmapi/primary_with_secondaries/dir_msg.c
@@ -1068,6 +1068,7 @@
HFTEST_LOG("Starting secondary core...");
ASSERT_TRUE(hftest_cpu_start(hftest_get_cpu_id(vcpu_id),
+ hftest_get_secondary_ec_stack(vcpu_id),
cpu_entry_echo_mp, (uintptr_t)&args));
/* Wait for secondary core to return before finishing the test. */
@@ -1102,6 +1103,7 @@
HFTEST_LOG("Starting secondary core...");
ASSERT_TRUE(hftest_cpu_start(hftest_get_cpu_id(vcpu_id),
+ hftest_get_secondary_ec_stack(vcpu_id - 1),
cpu_entry_echo_mp, (uintptr_t)&args));
/* Wait for secondary core to return before finishing the test. */
diff --git a/test/vmapi/primary_with_secondaries/run_race.c b/test/vmapi/primary_with_secondaries/run_race.c
index 2a6705a..ff4d984 100644
--- a/test/vmapi/primary_with_secondaries/run_race.c
+++ b/test/vmapi/primary_with_secondaries/run_race.c
@@ -111,8 +111,9 @@
* MAX_CPUS - index internally. Since legacy VMs do not follow this
* convention, index 7 is passed into `hftest_cpu_get_id`.
*/
- ASSERT_TRUE(hftest_cpu_start(hftest_get_cpu_id(7), vm_cpu_entry,
- (uintptr_t)&state));
+ ASSERT_TRUE(hftest_cpu_start(hftest_get_cpu_id(7),
+ hftest_get_secondary_ec_stack(0),
+ vm_cpu_entry, (uintptr_t)&state));
/* Run on a loop until the secondary VM is done. */
EXPECT_TRUE(run_loop(&mb));
diff --git a/test/vmapi/primary_with_secondaries/services/smp.c b/test/vmapi/primary_with_secondaries/services/smp.c
index e0530f4..3e64204 100644
--- a/test/vmapi/primary_with_secondaries/services/smp.c
+++ b/test/vmapi/primary_with_secondaries/services/smp.c
@@ -56,7 +56,8 @@
/* Start second vCPU. */
dlog("Secondary starting second vCPU.\n");
- ASSERT_TRUE(hftest_cpu_start(1, vm_cpu_entry, ARG_VALUE));
+ ASSERT_TRUE(hftest_cpu_start(1, hftest_get_secondary_ec_stack(0),
+ vm_cpu_entry, ARG_VALUE));
dlog("Secondary started second vCPU.\n");
/* Check that vCPU statuses are as expected. */