summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSandrine Bailleux <sandrine.bailleux@arm.com>2018-01-16 10:08:52 +0100
committerSandrine Bailleux <sandrine.bailleux@arm.com>2018-01-30 11:18:07 +0100
commit5e9630d0060d87ec2fb2bb163f9c0a3086b9999e (patch)
tree132317d5e10dad3c3600860b452a58dc6519629a
parentf29f2b468d53a97aa0906dc04ac75bd28420aa4a (diff)
SPM: Test that NS interrupt do not interrupt secure services
This patch introduces a new test in TFTF that checks that a non-secure interrupt (in this case, a non-secure timer interrupt) cannot interrupt a fast secure service request handled in a secure partition (in this case, Cactus). Change-Id: Iaf9d1a5afde9e1211a37eb60a23f25515bf48990 Signed-off-by: Sandrine Bailleux <sandrine.bailleux@arm.com>
-rw-r--r--cactus/cactus.mk1
-rw-r--r--tests/runtime_services/secure_service/test_secure_service_interrupts.c121
-rw-r--r--tests/tests-common.xml1
-rw-r--r--tests/tests.mk1
4 files changed, 124 insertions, 0 deletions
diff --git a/cactus/cactus.mk b/cactus/cactus.mk
index 0f1a4bc..4c18e92 100644
--- a/cactus/cactus.mk
+++ b/cactus/cactus.mk
@@ -20,6 +20,7 @@ CACTUS_SOURCES := cactus/aarch64/cactus_entrypoint.S \
lib/${ARCH}/cache_helpers.S \
lib/${ARCH}/misc_helpers.S \
lib/stdlib/assert.c \
+ lib/stdlib/mem.c \
lib/stdlib/putchar.c \
lib/stdlib/printf.c \
lib/stdlib/rand.c \
diff --git a/tests/runtime_services/secure_service/test_secure_service_interrupts.c b/tests/runtime_services/secure_service/test_secure_service_interrupts.c
new file mode 100644
index 0000000..549ca48
--- /dev/null
+++ b/tests/runtime_services/secure_service/test_secure_service_interrupts.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <debug.h>
+#include <mm_svc.h>
+#include <secure_partition.h>
+#include <smc.h>
+#include <spm_svc.h>
+#include <string.h>
+#include <test_helpers.h>
+#include <timer.h>
+#include <tftf_lib.h>
+
+
+static volatile int timer_irq_received;
+
+/*
+ * ISR for the timer interrupt.
+ * Just update a global variable to prove it has been called.
+ */
+static int timer_handler(void *data)
+{
+ assert(timer_irq_received == 0);
+ timer_irq_received = 1;
+ INFO("Timer interrupt handled\n");
+ return 0;
+}
+
+
+/*
+ * @Test_Aim@ Test that non-secure interrupts do not interrupt secure service
+ * requests.
+ *
+ * 1. Register a handler for the non-secure timer interrupt.
+ *
+ * 2. Program the non-secure timer to fire in 3 seconds.
+ *
+ * 3. Make a long-running (> 3 sec) fast secure service request.
+ * This is achieved by requesting the timer sleep service in Cactus
+ * with a 5 second sleep delay.
+ *
+ * 4. While servicing the timer sleep request, the non-secure timer should
+ * fire but not interrupt Cactus.
+ *
+ * 5. Once back in TFTF, check the response from Cactus, which shows whether the
+ * secure service indeed ran to completion.
+ *
+ * 6. Also check whether the pending non-secure timer interrupt successfully got
+ * handled in TFTF.
+ */
+test_result_t test_secure_partition_interrupt_by_ns(void)
+{
+ int rc;
+ secure_partition_request_info_t *sps_request;
+ test_result_t result = TEST_RESULT_FAIL;
+
+ SKIP_TEST_IF_MM_VERSION_LESS_THAN(1, 0);
+
+ timer_irq_received = 0;
+ tftf_timer_register_handler(timer_handler);
+
+ NOTICE("Programming the timer...\n");
+ rc = tftf_program_timer(3000);
+ if (rc < 0) {
+ tftf_testcase_printf("Failed to program timer (%d)\n", rc);
+ goto exit_test;
+ }
+
+ INFO("Sending MM_COMMUNICATE_AARCH64 to Cactus\n");
+
+ uint8_t timer_delay = 5;
+ sps_request = create_sps_request(SPS_TIMER_SLEEP,
+ &timer_delay, sizeof(timer_delay));
+ smc_args mm_communicate_smc = {
+ MM_COMMUNICATE_AARCH64,
+ 0, /* cookie, MBZ */
+ (uintptr_t) sps_request,
+ 0
+ };
+
+ smc_ret_values smc_ret = tftf_smc(&mm_communicate_smc);
+
+ INFO("Returned from Cactus, MM_COMMUNICATE_AARCH64 handling complete\n");
+
+ /*
+ * If MM_COMMUNICATE gets interrupted, SPM will return SPM_QUEUED, which
+ * is normally not a valid return value for MM_COMMUNICATE.
+ */
+ if ((uint32_t) smc_ret.ret0 != SPM_SUCCESS) {
+ tftf_testcase_printf("Cactus returned: 0x%x\n",
+ (uint32_t) smc_ret.ret0);
+ goto exit_test;
+ }
+
+ uint32_t cactus_response;
+ memcpy(&cactus_response, sps_request->data, sizeof(cactus_response));
+ if (cactus_response != CACTUS_FAST_REQUEST_SUCCESS) {
+ tftf_testcase_printf("Error code from the timer secure service: 0x%x\n",
+ cactus_response);
+ goto exit_test;
+ }
+
+ /*
+ * If the timer interrupt is still pending, make sure it is taken right
+ * now.
+ */
+ isb();
+
+ if (timer_irq_received == 1)
+ result = TEST_RESULT_SUCCESS;
+
+exit_test:
+ tftf_cancel_timer();
+ tftf_timer_unregister_handler();
+ return result;
+}
diff --git a/tests/tests-common.xml b/tests/tests-common.xml
index 170a89e..da428ac 100644
--- a/tests/tests-common.xml
+++ b/tests/tests-common.xml
@@ -31,6 +31,7 @@
</testsuite>
<testsuite name="SPM" description="SPM test framework">
+ <testcase name="SPM NS interrupts test" function="test_secure_partition_interrupt_by_ns" />
<testcase name="SPM secondary CPUs sequential test" function="test_secure_partition_secondary_cores_seq" />
<testcase name="SPM secondary CPUs simultaneous test" function="test_secure_partition_secondary_cores_sim" />
</testsuite>
diff --git a/tests/tests.mk b/tests/tests.mk
index a20bdfd..cc9ae66 100644
--- a/tests/tests.mk
+++ b/tests/tests.mk
@@ -11,6 +11,7 @@ TESTS_SOURCES := tests/framework_validation_tests/test_timer_framework.c \
tests/framework_validation_tests/test_validation_sgi.c \
tests/performance_tests/smc_latencies.c \
tests/runtime_services/secure_service/test_secure_service_handle.c \
+ tests/runtime_services/secure_service/test_secure_service_interrupts.c \
tests/runtime_services/secure_service/secure_service_helpers.c \
tests/runtime_services/sip_service/test_exec_state_switch.c \
tests/runtime_services/sip_service/test_exec_state_switch_asm.S \