summaryrefslogtreecommitdiff
path: root/spm
diff options
context:
space:
mode:
authorOlivier Deprez <olivier.deprez@arm.com>2021-04-22 14:39:54 +0200
committerOlivier Deprez <olivier.deprez@arm.com>2022-03-01 18:51:43 +0100
commit20b9b1784f209811a05db71f8503980c97f4634a (patch)
tree8c5da473df4f3cab66eeb9c12ed7c45f62a7d635 /spm
parent572ee4fde07faf8c208ebfd1bcaf745a93db003d (diff)
test(cactus): prevent realm region access from swd
This change adds TFTF and cactus tests to check a realm region cannot be accessed from secure world. A non-secure buffer is delegated to realm PAS and shared to a secure partition through FF-A memory sharing operations. The SP retrieves the region from the SPM, maps it and attempts a write access. The PE is expected to trigger a GPF data abort caught by a custom exception handler. Exception is trapped at S-EL1 within the secure partition because Hafnium configures HCR_EL2.GPF=0 (and SCR_EL3.GPF=0). Signed-off-by: Olivier Deprez <olivier.deprez@arm.com> Change-Id: I8f855f394d0490b3584e60ceba4f3d2a20197495
Diffstat (limited to 'spm')
-rw-r--r--spm/cactus/aarch64/cactus_exceptions.S27
-rw-r--r--spm/cactus/cactus.mk1
-rw-r--r--spm/cactus/cactus_main.c7
-rw-r--r--spm/cactus/cactus_tests/cactus_test_memory_sharing.c32
4 files changed, 48 insertions, 19 deletions
diff --git a/spm/cactus/aarch64/cactus_exceptions.S b/spm/cactus/aarch64/cactus_exceptions.S
index 6aec16d..9b024f8 100644
--- a/spm/cactus/aarch64/cactus_exceptions.S
+++ b/spm/cactus/aarch64/cactus_exceptions.S
@@ -31,14 +31,16 @@ unhandled_exception serr_sp0
/*
* Current EL with SPx : 0x200 - 0x400.
*/
-unhandled_exception sync_spx
+vector_entry sync_spx
+ b sync_exception_vector_entry
+end_vector_entry sync_spx
vector_entry irq_spx
- b irq_vector_entry
+ b interrupt_vector_entry
end_vector_entry irq_spx
vector_entry fiq_spx
- b fiq_vector_entry
+ b interrupt_vector_entry
end_vector_entry fiq_spx
unhandled_exception serr_spx
@@ -98,23 +100,30 @@ unhandled_exception serr_a32
ldp x0, x1, [sp, #0x0]
.endm
-func irq_vector_entry
+func sync_exception_vector_entry
sub sp, sp, #0x100
save_gp_regs
- bl cactus_interrupt_handler
- restore_gp_regs
+ mov x19, sp
+ bl tftf_sync_exception_handler
+ cbnz x0, 0f
+ mov x0, x19
+ /* Save original stack pointer value on the stack */
+ add x1, x0, #0x100
+ str x1, [x0, #0xf8]
+ b print_exception
+0: restore_gp_regs
add sp, sp, #0x100
eret
-endfunc irq_vector_entry
+endfunc sync_exception_vector_entry
-func fiq_vector_entry
+func interrupt_vector_entry
sub sp, sp, #0x100
save_gp_regs
bl cactus_interrupt_handler
restore_gp_regs
add sp, sp, #0x100
eret
-endfunc fiq_vector_entry
+endfunc interrupt_vector_entry
func crash_dump
/* Save general-purpose registers on the stack. */
diff --git a/spm/cactus/cactus.mk b/spm/cactus/cactus.mk
index 4109579..8970b29 100644
--- a/spm/cactus/cactus.mk
+++ b/spm/cactus/cactus.mk
@@ -68,6 +68,7 @@ CACTUS_SOURCES += drivers/arm/pl011/${ARCH}/pl011_console.S \
lib/smc/${ARCH}/asm_smc.S \
lib/smc/${ARCH}/smc.c \
lib/smc/${ARCH}/hvc.c \
+ lib/exceptions/${ARCH}/sync.c \
lib/locks/${ARCH}/spinlock.S \
lib/utils/mp_printf.c \
${XLAT_TABLES_LIB_SRCS}
diff --git a/spm/cactus/cactus_main.c b/spm/cactus/cactus_main.c
index c80abd9..58186d1 100644
--- a/spm/cactus/cactus_main.c
+++ b/spm/cactus/cactus_main.c
@@ -181,13 +181,6 @@ static void register_secondary_entrypoint(void)
tftf_smc(&args);
}
-int tftf_irq_handler_dispatcher(void)
-{
- ERROR("%s\n", __func__);
-
- return 0;
-}
-
void __dead2 cactus_main(bool primary_cold_boot)
{
assert(IS_IN_EL1() != 0);
diff --git a/spm/cactus/cactus_tests/cactus_test_memory_sharing.c b/spm/cactus/cactus_tests/cactus_test_memory_sharing.c
index 69d62dd..051208e 100644
--- a/spm/cactus/cactus_tests/cactus_test_memory_sharing.c
+++ b/spm/cactus/cactus_tests/cactus_test_memory_sharing.c
@@ -14,6 +14,27 @@
#include <sp_helpers.h>
#include <xlat_tables_defs.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <sync.h>
+
+static volatile uint32_t data_abort_gpf_triggered;
+
+static bool data_abort_gpf_handler(void)
+{
+ uint64_t esr_el1 = read_esr_el1();
+
+ VERBOSE("%s count %u esr_el1 %llx elr_el1 %llx\n",
+ __func__, data_abort_gpf_triggered, esr_el1,
+ read_elr_el1());
+
+ /* Expect a data abort because of a GPF. */
+ if ((EC_BITS(esr_el1) == EC_DABORT_CUR_EL) &&
+ ((ISS_BITS(esr_el1) & ISS_DFSC_MASK) == DFSC_GPF_DABORT)) {
+ data_abort_gpf_triggered++;
+ return true;
+ }
+
+ return false;
+}
/**
* Each Cactus SP has a memory region dedicated to memory sharing tests
@@ -51,7 +72,7 @@ CACTUS_CMD_HANDLER(mem_send_cmd, CACTUS_MEM_SEND_CMD)
cactus_mem_send_get_retrv_flags(*args);
uint32_t words_to_write = cactus_mem_send_words_to_write(*args);
- expect(memory_retrieve(mb, &m, handle, source, vm_id, mem_func,
+ expect(memory_retrieve(mb, &m, handle, source, vm_id,
retrv_flags), true);
composite = ffa_memory_region_get_composite(m, 0);
@@ -104,12 +125,17 @@ CACTUS_CMD_HANDLER(mem_send_cmd, CACTUS_MEM_SEND_CMD)
}
}
+ data_abort_gpf_triggered = 0;
+ register_custom_sync_exception_handler(data_abort_gpf_handler);
+
/* Write mem_func to retrieved memory region for validation purposes. */
VERBOSE("Writing: %x\n", mem_func);
for (unsigned int i = 0U; i < words_to_write; i++) {
ptr[i] = mem_func;
}
+ unregister_custom_sync_exception_handler();
+
/*
* A FFA_MEM_DONATE changes the ownership of the page, as such no
* relinquish is needed.
@@ -120,7 +146,7 @@ CACTUS_CMD_HANDLER(mem_send_cmd, CACTUS_MEM_SEND_CMD)
composite->constituents[0].page_count * PAGE_SIZE);
if (ret != 0) {
- ERROR("Failed first mmap_add_dynamic_region!\n");
+ ERROR("Failed to unmap received memory region(%d)!\n", ret);
return cactus_error_resp(vm_id, source,
CACTUS_ERROR_TEST);
}
@@ -139,7 +165,7 @@ CACTUS_CMD_HANDLER(mem_send_cmd, CACTUS_MEM_SEND_CMD)
}
return cactus_success_resp(vm_id,
- source, 0);
+ source, data_abort_gpf_triggered);
}
CACTUS_CMD_HANDLER(req_mem_send_cmd, CACTUS_REQ_MEM_SEND_CMD)