fix: replace platform get core pos usage
It is incorrect for secure partitions to use the platform_get_core_pos
macro. MPIDR_EL1 read from S-EL1 is the impdef virtual MPIDR value set
by the SPMC on behalf of SP. The MPIDR value does not hold physical CPU
affinity values, but the linear vCPU index for the currently running
vCPU. Add an SPM helper to retrieve the vCPU index information and
update call sites to use this helper.
Signed-off-by: Olivier Deprez <olivier.deprez@arm.com>
Change-Id: Ic9927acc5b64d25331cb61a83d9acbdc83173e2b
diff --git a/spm/cactus/cactus_tests/cactus_message_loop.c b/spm/cactus/cactus_tests/cactus_message_loop.c
index e56e51e..c0abf2b 100644
--- a/spm/cactus/cactus_tests/cactus_message_loop.c
+++ b/spm/cactus/cactus_tests/cactus_message_loop.c
@@ -11,6 +11,7 @@
#include <ffa_helpers.h>
#include <events.h>
#include <platform.h>
+#include <spm_helpers.h>
/**
* Counter of the number of handled requests, for each CPU. The number of
@@ -43,9 +44,8 @@
{
uint64_t in_cmd;
- /* Get which core it is running from. */
- unsigned int core_pos = platform_get_core_pos(
- read_mpidr_el1() & MPID_MASK);
+ /* Get vCPU index for currently running vCPU. */
+ unsigned int core_pos = spm_get_my_core_pos();
if (cmd_args == NULL || ret == NULL) {
ERROR("Invalid arguments passed to %s!\n", __func__);
diff --git a/spm/cactus/cactus_tests/cactus_test_interrupts.c b/spm/cactus/cactus_tests/cactus_test_interrupts.c
index 4250445..2e0249c 100644
--- a/spm/cactus/cactus_tests/cactus_test_interrupts.c
+++ b/spm/cactus/cactus_tests/cactus_test_interrupts.c
@@ -86,8 +86,9 @@
/* Received FFA_INTERRUPT in blocked state. */
VERBOSE("Processing FFA_INTERRUPT while"
" blocked on direct response\n");
- unsigned int my_core_pos =
- platform_get_core_pos(read_mpidr_el1());
+
+ /* Get vCPU index for currently running vCPU. */
+ unsigned int my_core_pos = spm_get_my_core_pos();
ffa_ret = ffa_run(fwd_dest, my_core_pos);
} else {
diff --git a/spm/cactus/cactus_tests/cactus_test_notifications.c b/spm/cactus/cactus_tests/cactus_test_notifications.c
index d8b88ed..6d7b41b 100644
--- a/spm/cactus/cactus_tests/cactus_test_notifications.c
+++ b/spm/cactus/cactus_tests/cactus_test_notifications.c
@@ -9,6 +9,7 @@
#include "sp_tests.h"
#include <ffa_helpers.h>
+#include <spm_helpers.h>
#include <debug.h>
/* Booleans to keep track of which CPUs handled NPI. */
@@ -33,9 +34,8 @@
void notification_pending_interrupt_handler(void)
{
- /* Get which core it is running from. */
- unsigned int core_pos = platform_get_core_pos(
- read_mpidr_el1() & MPID_MASK);
+ /* Get vCPU index for currently running vCPU. */
+ unsigned int core_pos = spm_get_my_core_pos();
VERBOSE("NPI handled in core %u\n", core_pos);
diff --git a/spm/cactus/cactus_tests/cactus_test_simd.c b/spm/cactus/cactus_tests/cactus_test_simd.c
index a1366d3..bcf1c38 100644
--- a/spm/cactus/cactus_tests/cactus_test_simd.c
+++ b/spm/cactus/cactus_tests/cactus_test_simd.c
@@ -7,6 +7,7 @@
#include "cactus_message_loop.h"
#include "cactus_test_cmds.h"
#include <fpu.h>
+#include <spm_helpers.h>
#include "spm_common.h"
/*
@@ -21,7 +22,8 @@
*/
CACTUS_CMD_HANDLER(req_simd_fill, CACTUS_REQ_SIMD_FILL_CMD)
{
- core_pos = platform_get_core_pos(read_mpidr_el1());
+ /* Get vCPU index for currently running vCPU. */
+ core_pos = spm_get_my_core_pos();
fpu_state_write_rand(&sp_fpu_state_write);
return cactus_response(ffa_dir_msg_dest(*args),
ffa_dir_msg_source(*args),
@@ -36,7 +38,8 @@
{
bool test_succeed = false;
- unsigned int core_pos1 = platform_get_core_pos(read_mpidr_el1());
+ /* Get vCPU index for currently running vCPU. */
+ unsigned int core_pos1 = spm_get_my_core_pos();
if (core_pos1 == core_pos) {
fpu_state_read(&sp_fpu_state_read);
if (fpu_state_compare(&sp_fpu_state_write,
diff --git a/spm/common/spm_helpers.c b/spm/common/spm_helpers.c
index 1cb5f4d..b2a4709 100644
--- a/spm/common/spm_helpers.c
+++ b/spm/common/spm_helpers.c
@@ -56,3 +56,16 @@
return (int64_t)ret.ret0;
}
+
+/**
+ * Return vCPU index for the currently running vCPU.
+ * Virtual MPIDR holds the linear vCPU index information in lower bits.
+ * Keep only first 24 bits (mapping to Aff0/Aff1/Aff2).
+ * Omit Aff3, bit [31], U[30], MT[24].
+ */
+unsigned int spm_get_my_core_pos(void)
+{
+ uint64_t mpidr = read_mpidr_el1();
+
+ return (unsigned int)(mpidr & 0xffffff);
+}
diff --git a/spm/common/spm_helpers.h b/spm/common/spm_helpers.h
index 1d3ddc2..59cdaf1 100644
--- a/spm/common/spm_helpers.h
+++ b/spm/common/spm_helpers.h
@@ -23,4 +23,6 @@
int64_t spm_interrupt_enable(uint32_t int_id, bool enable, enum interrupt_pin pin);
int64_t spm_interrupt_deactivate(uint32_t vint_id);
+unsigned int spm_get_my_core_pos(void);
+
#endif /* SPMC_H */