diff options
Diffstat (limited to 'tftf/tests/runtime_services/standard_service/psci/api_tests/mem_protect/test_mem_protect.c')
-rw-r--r-- | tftf/tests/runtime_services/standard_service/psci/api_tests/mem_protect/test_mem_protect.c | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/tftf/tests/runtime_services/standard_service/psci/api_tests/mem_protect/test_mem_protect.c b/tftf/tests/runtime_services/standard_service/psci/api_tests/mem_protect/test_mem_protect.c new file mode 100644 index 000000000..35c26e8ac --- /dev/null +++ b/tftf/tests/runtime_services/standard_service/psci/api_tests/mem_protect/test_mem_protect.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2018, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <debug.h> +#include <psci.h> +#include <stdlib.h> +#include <test_helpers.h> +#include <tftf_lib.h> +#include <xlat_tables_v2.h> + +#define SENTINEL 0x55 +#define MEM_PROT_ENABLED 1 +#define MEM_PROT_DISABLED 0 +/* + * Test to verify that mem_protect is executed in next boot after calling + * the PSCI mem_protect function + * + * Returns: + * TEST_RESULT_SUCCESS : when after rebooting mem_protect is activated + * and the sentinel is detected to have been reset. + * TEST_RESULT_FAIL : when some of the calls to mem_protect fails or + * sentinel is not cleared after resetting. + */ +static test_result_t test_mem_protect_helper(void *arg) +{ + int ret; + unsigned char value; + unsigned char *sentinel = arg; + + assert(sentinel != NULL); + + if (tftf_is_rebooted()) { + value = *sentinel; + if (value != 0 && value != SENTINEL) { + tftf_testcase_printf("Sentinel address modified out of mem_protect:%d\n", + value); + return TEST_RESULT_FAIL; + } + if (value == SENTINEL) { + tftf_testcase_printf("Sentinel address not cleared by mem_protect\n"); + return TEST_RESULT_FAIL; + } + return TEST_RESULT_SUCCESS; + } + + ret = psci_mem_protect(MEM_PROT_DISABLED); + if (ret != MEM_PROT_ENABLED && ret != MEM_PROT_DISABLED) { + INFO("Mem_protect failed %d\n", ret); + return TEST_RESULT_FAIL; + } + + /* mem_protect mechanism should be disabled at this point */ + ret = psci_mem_protect(MEM_PROT_ENABLED); + if (ret != MEM_PROT_DISABLED) { + tftf_testcase_printf("Mem_protect failed %d\n", ret); + return TEST_RESULT_FAIL; + } + + /* mem_protect mechanism should be enabled at this point */ + ret = psci_mem_protect(MEM_PROT_ENABLED); + if (ret != MEM_PROT_ENABLED) { + tftf_testcase_printf("Mem_protect failed %d\n", ret); + return TEST_RESULT_FAIL; + } + + *sentinel = SENTINEL; + + /* Notify that we are rebooting now. */ + tftf_notify_reboot(); + + psci_system_reset(); + /* + * psci_reset shouldn't return + */ + return TEST_RESULT_FAIL; +} + +test_result_t test_mem_protect(void) +{ + map_args_unmap_t args; + unsigned char *sentinel; + int ret; + + ret = tftf_get_psci_feature_info(SMC_PSCI_MEM_PROTECT); + if (ret == PSCI_E_NOT_SUPPORTED) { + tftf_testcase_printf("Mem_protect is not supported %d\n", ret); + return TEST_RESULT_SKIPPED; + } + + sentinel = psci_mem_prot_get_sentinel(); + if (sentinel == NULL) { + tftf_testcase_printf("Could not find a suitable address for the sentinel.\n"); + return TEST_RESULT_SKIPPED; + } + + args.addr = (uintptr_t) sentinel & ~PAGE_SIZE_MASK; + args.size = PAGE_SIZE; + args.attr = MT_RW_DATA; + args.arg = sentinel; + + return map_test_unmap(&args, test_mem_protect_helper); +} |