Merge "fix(fuzzing): resolve script issue"
diff --git a/docs/getting_started/requirements.rst b/docs/getting_started/requirements.rst
index eba75a2..40edbc9 100644
--- a/docs/getting_started/requirements.rst
+++ b/docs/getting_started/requirements.rst
@@ -25,7 +25,7 @@
======================== =====================
Name Version
======================== =====================
-Mbed TLS 3.6.3
+Mbed TLS 3.6.4
Transfer List Library 0.0.1
Event Log Library 0.0.1
======================== =====================
diff --git a/ext/mbedtls b/ext/mbedtls
index 22098d4..c765c83 160000
--- a/ext/mbedtls
+++ b/ext/mbedtls
@@ -1 +1 @@
-Subproject commit 22098d41c6620ce07cf8a0134d37302355e1e5ef
+Subproject commit c765c831e5c2a0971410692f92f7a81d6ec65ec2
diff --git a/include/configs/tftf_mbedtls_config.h b/include/configs/tftf_mbedtls_config.h
index 9ad0b71..66ec744 100644
--- a/include/configs/tftf_mbedtls_config.h
+++ b/include/configs/tftf_mbedtls_config.h
@@ -21,8 +21,8 @@
/* For snprintf function declaration */
#include <stdio.h>
-/* This file is compatible with release 3.6.3 */
-#define MBEDTLS_CONFIG_VERSION 0x03060300
+/* This file is compatible with release 3.6.4 */
+#define MBEDTLS_CONFIG_VERSION 0x03060400
/* Configuration file to build mbed TLS with the required features for TFTF */
#define MBEDTLS_PLATFORM_MEMORY
diff --git a/include/runtime_services/psci.h b/include/runtime_services/psci.h
index 0e56bdc..e76156b 100644
--- a/include/runtime_services/psci.h
+++ b/include/runtime_services/psci.h
@@ -110,6 +110,13 @@
#endif /* __ASSEMBLY__ */
/*******************************************************************************
+ * PSCI target CPU defines
+ ******************************************************************************/
+
+#define PSCI_TARGET_CPU_MASK ULL(0x000000FF00FFFFFF)
+#define psci_target_cpu_from_mpid(mpidr) ((mpidr) & PSCI_TARGET_CPU_MASK)
+
+/*******************************************************************************
* PSCI Migrate specific defines
******************************************************************************/
#define PSCI_TOS_UP_MIG_CAP 0
diff --git a/lib/psci/psci.c b/lib/psci/psci.c
index 42e53b9..720d319 100644
--- a/lib/psci/psci.c
+++ b/lib/psci/psci.c
@@ -60,7 +60,7 @@
{
smc_args args = {
SMC_PSCI_CPU_ON,
- target_cpu,
+ psci_target_cpu_from_mpid(target_cpu),
entry_point_address,
context_id
};
@@ -97,7 +97,7 @@
{
smc_args args = {
SMC_PSCI_STAT_RESIDENCY,
- target_cpu,
+ psci_target_cpu_from_mpid(target_cpu),
power_state,
};
smc_ret_values ret_vals;
@@ -111,7 +111,7 @@
{
smc_args args = {
SMC_PSCI_STAT_COUNT,
- target_cpu,
+ psci_target_cpu_from_mpid(target_cpu),
power_state,
};
smc_ret_values ret_vals;
@@ -127,7 +127,7 @@
smc_args args = {
SMC_PSCI_AFFINITY_INFO,
- target_affinity,
+ psci_target_cpu_from_mpid(target_affinity),
lowest_affinity_level
};
@@ -139,7 +139,7 @@
{
smc_args args = {
SMC_PSCI_CPU_HW_STATE,
- target_cpu,
+ psci_target_cpu_from_mpid(target_cpu),
power_level
};
smc_ret_values ret;
diff --git a/spm/common/sp_tests/sp_test_ffa.c b/spm/common/sp_tests/sp_test_ffa.c
index 951e44b..25e47ae 100644
--- a/spm/common/sp_tests/sp_test_ffa.c
+++ b/spm/common/sp_tests/sp_test_ffa.c
@@ -94,6 +94,8 @@
FFA_VERSION_1_1},
{"FFA_YIELD_32", FFA_MSG_YIELD, FFA_SUCCESS_SMC32,
FFA_VERSION_1_0},
+ {"FFA_ABORT_32", FFA_ABORT_32, FFA_SUCCESS_SMC32},
+ {"FFA_ABORT_64", FFA_ABORT_64, FFA_SUCCESS_SMC32},
};
INFO("Test FFA_FEATURES.\n");
diff --git a/tftf/tests/neg_scenario_tests/neg_scenario_test_infra.c b/tftf/tests/neg_scenario_tests/neg_scenario_test_infra.c
new file mode 100644
index 0000000..e45a0b0
--- /dev/null
+++ b/tftf/tests/neg_scenario_tests/neg_scenario_test_infra.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2025, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "neg_scenario_test_infra.h"
+
+/*
+ Temporary variables to speed up the authentication parameters search. These
+ variables are assigned once during the integrity check and used any time an
+ authentication parameter is requested, so we do not have to parse the image
+ again
+ */
+
+
+int get_pubKey_from_cert(void *cert, size_t cert_len, void **returnPtr) {
+
+ int ret;
+ size_t len;
+ unsigned char *p, *end, *crt_end, *pk_end;
+ mbedtls_asn1_buf pk;
+
+ /*
+ * The unique ASN.1 DER encoding of [0] EXPLICIT INTEGER { v3(2} }.
+ */
+ const char v3[] = {
+ /* The outer CONTEXT SPECIFIC 0 tag */
+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC | 0,
+ /* The number bytes used to encode the inner INTEGER */
+ 3,
+ /* The tag of the inner INTEGER */
+ MBEDTLS_ASN1_INTEGER,
+ /* The number of bytes needed to represent 2 */
+ 1,
+ /* The actual value 2 */
+ 2,
+ };
+
+ p = (unsigned char *)cert;
+ len = cert_len;
+ crt_end = p + len;
+ end = crt_end;
+
+ /*
+ * Certificate ::= SEQUENCE {
+ * tbsCertificate TBSCertificate,
+ * signatureAlgorithm AlgorithmIdentifier,
+ * signatureValue BIT STRING }
+ */
+ ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
+ MBEDTLS_ASN1_SEQUENCE);
+ if ((ret != 0) || ((p + len) != end))
+ return -1;
+
+ /*
+ * TBSCertificate ::= SEQUENCE {
+ */
+ ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
+ MBEDTLS_ASN1_SEQUENCE);
+ if (ret != 0)
+ return -1;
+
+ end = p + len;
+
+ /*
+ * Version ::= [0] EXPLICIT INTEGER { v1(0), v2(1), v3(2) }
+ * -- only v3 accepted
+ */
+ if (((end - p) <= (ptrdiff_t)sizeof(v3)) ||
+ (memcmp(p, v3, sizeof(v3)) != 0)) {
+ return -1;
+ }
+ p += sizeof(v3);
+
+ /*
+ * CertificateSerialNumber ::= INTEGER
+ */
+ ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_INTEGER);
+ if (ret != 0)
+ return -1;
+
+ p += len;
+
+ /*
+ * signature AlgorithmIdentifier
+ */
+
+ ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
+ MBEDTLS_ASN1_SEQUENCE);
+ if (ret != 0)
+ return -1;
+
+ p += len;
+
+ /*
+ * issuer Name
+ */
+ ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
+ MBEDTLS_ASN1_SEQUENCE);
+ if (ret != 0)
+ return -1;
+
+ p += len;
+
+ /*
+ * Validity ::= SEQUENCE {
+ * notBefore Time,
+ * notAfter Time }
+ *
+ */
+ ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
+ MBEDTLS_ASN1_SEQUENCE);
+ if (ret != 0)
+ return -1;
+
+ p += len;
+
+ /*
+ * subject Name
+ */
+ ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
+ MBEDTLS_ASN1_SEQUENCE);
+ if (ret != 0)
+ return -1;
+
+ p += len;
+
+ /*
+ * SubjectPublicKeyInfo
+ */
+ pk.p = p;
+ ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
+ MBEDTLS_ASN1_SEQUENCE);
+ if (ret != 0)
+ return -1;
+
+ pk_end = p + len;
+ pk.len = pk_end - pk.p;
+
+ *returnPtr = p;
+
+ return 0;
+}
diff --git a/tftf/tests/neg_scenario_tests/neg_scenario_test_infra.h b/tftf/tests/neg_scenario_tests/neg_scenario_test_infra.h
new file mode 100644
index 0000000..428f86b
--- /dev/null
+++ b/tftf/tests/neg_scenario_tests/neg_scenario_test_infra.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2025, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+#include <mbedtls/oid.h>
+#include <mbedtls/platform.h>
+#include <firmware_image_package.h>
+
+/*
+ cert:
+ cert_len:
+ returnPtr: ptr to pubKey in cert
+
+ return 0 upon success, -1 on fail
+*/
+int get_pubKey_from_cert(void *cert, size_t cert_len, void **returnPtr);
diff --git a/tftf/tests/neg_scenario_tests/test_invalid_rotpk.c b/tftf/tests/neg_scenario_tests/test_invalid_rotpk.c
new file mode 100644
index 0000000..9f465a0
--- /dev/null
+++ b/tftf/tests/neg_scenario_tests/test_invalid_rotpk.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2025, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <uuid.h>
+#include <io_storage.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <psci.h>
+#include <smccc.h>
+#include <status.h>
+#include <tftf_lib.h>
+#include <uuid_utils.h>
+#include "neg_scenario_test_infra.h"
+
+#define CRYPTO_SUPPORT 1
+
+static fip_toc_entry_t *
+find_fiptoc_entry_t(const int fip_base, const uuid_t *uuid)
+{
+ fip_toc_entry_t *current_file =
+ (fip_toc_entry_t *) (fip_base + sizeof(fip_toc_header_t));
+
+ while (!is_uuid_null(&(current_file->uuid))) {
+ if (uuid_equal(&(current_file->uuid), uuid)){
+ return current_file;
+ }
+
+ current_file += 1;
+ };
+
+ return NULL;
+}
+
+test_result_t test_invalid_rotpk(void)
+{
+ smc_args args = { SMC_PSCI_SYSTEM_RESET };
+ smc_ret_values ret = (smc_ret_values){0};
+ const uuid_t trusted_cert = UUID_TRUSTED_KEY_CERT;
+
+ uintptr_t handle;
+ fip_toc_entry_t * cert;
+ size_t exp_len, len;
+ int address, rc;
+ void * paramOut = NULL;
+
+ if(tftf_is_rebooted() ){
+ /* ROTPK is tampered with and upon reboot tfa should not reach this point */
+ return TEST_RESULT_FAIL;
+ }
+
+ /* Locate Trusted Key certificate memory address by using UUID */
+ cert = find_fiptoc_entry_t(PLAT_ARM_FIP_BASE, &trusted_cert);
+ if (cert == NULL){
+ return TEST_RESULT_FAIL;
+ }
+
+ address = (uintptr_t)cert->offset_address;
+ exp_len = cert->size;
+ if (exp_len == 0U){
+ return TEST_RESULT_FAIL;
+ }
+
+ /* Runtime-sized buffer on stack */
+ uint8_t cert_buffer[exp_len];
+
+ /* Open NVM and Read certicate */
+ plat_get_nvm_handle(&handle);
+ if(handle < 0) {
+ return TEST_RESULT_FAIL;
+ }
+
+ rc = io_seek(handle, IO_SEEK_SET, address);
+ if (rc < 0){
+ return TEST_RESULT_FAIL;
+ }
+
+ rc = io_read(handle, (uintptr_t) &cert_buffer, exp_len, &len);
+ if (rc < 0 || len != exp_len){
+ return TEST_RESULT_FAIL;
+ }
+
+ /* Parse certifacte to retrieve public key */
+ rc = get_pubKey_from_cert(&cert_buffer, len, ¶mOut);
+ if ( rc != 0){
+ return TEST_RESULT_FAIL;
+ }
+
+ /*
+ * Corrupt part of the certificate in storage.
+ * Simple overwrite: just clobber the first 32 bytes so parsing/verification fails.
+ */
+ {
+ uint8_t junk[32] = {0};
+
+ rc = io_seek(handle, IO_SEEK_SET, address);
+ if (rc < 0){
+ return TEST_RESULT_FAIL;
+ }
+
+ rc = io_write(handle, (uintptr_t)junk, sizeof(junk), &len);
+ if (rc < 0 || len != sizeof(junk)){
+ return TEST_RESULT_FAIL;
+ }
+ }
+
+ /* Reboot */
+ tftf_notify_reboot();
+ ret = tftf_smc(&args);
+
+ /* The PSCI SYSTEM_RESET call is not supposed to return */
+ tftf_testcase_printf("System didn't reboot properly (%d)\n",
+ (unsigned int)ret.ret0);
+
+ /* If this point is reached, reboot failed to trigger*/
+ return TEST_RESULT_FAIL;
+}
diff --git a/tftf/tests/runtime_services/el3/query_ven_el3_svc.c b/tftf/tests/runtime_services/el3/query_ven_el3_svc.c
index 0b3b6e3..50d918a 100644
--- a/tftf/tests/runtime_services/el3/query_ven_el3_svc.c
+++ b/tftf/tests/runtime_services/el3/query_ven_el3_svc.c
@@ -47,6 +47,10 @@
ven_el3_svc_args.fid = VEN_EL3_SVC_UID;
ret = tftf_smc(&ven_el3_svc_args);
+ /* These functions are optional, skip test when not supported. */
+ if (ret.ret0 == SMC_UNKNOWN)
+ return TEST_RESULT_SKIPPED;
+
make_uuid_from_4words(&ven_el3_svc_uuid,
ret.ret0, ret.ret1, ret.ret2, ret.ret3);
if (!uuid_equal(&ven_el3_svc_uuid, &armtf_ven_el3_svc_uuid)) {
diff --git a/tftf/tests/runtime_services/generic/generic_smc.c b/tftf/tests/runtime_services/generic/generic_smc.c
index 6d057a6..1d15dcf 100644
--- a/tftf/tests/runtime_services/generic/generic_smc.c
+++ b/tftf/tests/runtime_services/generic/generic_smc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2025, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -17,10 +17,6 @@
/* An invalid SMC function number. */
#define INVALID_FN 0x666
-/* PSCI version returned by TF-A. */
-static const uint32_t psci_version = PSCI_VERSION(PSCI_MAJOR_VER,
- PSCI_MINOR_VER);
-
/* UUID of the standard service in TF-A. */
static const smc_ret_values std_svc_uuid = {
0x108d905b, 0x47e8f863, 0xfbc02dae, 0xe2f64156
@@ -46,6 +42,26 @@
} while (0)
/*
+ * Check that the values it returns match the expected ones. If not, write an
+ * error message in the test report.
+ */
+static bool smc_check_eq_common(const smc_ret_values *ret,
+ const smc_ret_values *expect)
+{
+ if (memcmp(ret, expect, sizeof(smc_ret_values)) == 0)
+ return true;
+
+ tftf_testcase_printf(
+ "Got {0x%lx,0x%lx,0x%lx,0x%lx,0x%lx,0x%lx,0x%lx,0x%lx}, \
+ expected {0x%lx,0x%lx,0x%lx,0x%lx,0x%lx,0x%lx,0x%lx,0x%lx}.\n",
+ ret->ret0, ret->ret1, ret->ret2, ret->ret3,
+ ret->ret4, ret->ret5, ret->ret6, ret->ret7,
+ expect->ret0, expect->ret1, expect->ret2, expect->ret3,
+ expect->ret4, expect->ret5, expect->ret6, expect->ret7);
+ return false;
+}
+
+/*
* Send an SMC with the specified arguments.
* Check that the values it returns match the expected ones. If not, write an
* error message in the test report.
@@ -54,18 +70,27 @@
{
smc_ret_values ret = tftf_smc(args);
- if (memcmp(&ret, expect, sizeof(smc_ret_values)) == 0) {
- return true;
- } else {
- tftf_testcase_printf(
- "Got {0x%lx,0x%lx,0x%lx,0x%lx,0x%lx,0x%lx,0x%lx,0x%lx}, \
- expected {0x%lx,0x%lx,0x%lx,0x%lx,0x%lx,0x%lx,0x%lx,0x%lx}.\n",
- ret.ret0, ret.ret1, ret.ret2, ret.ret3,
- ret.ret4, ret.ret5, ret.ret6, ret.ret7,
- expect->ret0, expect->ret1, expect->ret2, expect->ret3,
- expect->ret4, expect->ret5, expect->ret6, expect->ret7);
- return false;
- }
+ return smc_check_eq_common(&ret, expect);
+}
+
+/*
+ * Send an optional SMC with the specified arguments. Treat it as skipped if the
+ * firmware does not support the call and skip further checks.
+ * Otherwise, check that the values it returns match the expected ones. If not,
+ * return a test fail result.
+ */
+static test_result_t smc_check_eq_optional(const smc_args *args, const smc_ret_values *expect)
+{
+ smc_ret_values ret = tftf_smc(args);
+
+ if (ret.ret0 == SMC_UNKNOWN)
+ return TEST_RESULT_SKIPPED;
+
+ if (smc_check_eq_common(&ret, expect))
+ return TEST_RESULT_SUCCESS;
+ else
+ return TEST_RESULT_FAIL;
+
}
/*
@@ -153,9 +178,14 @@
/* Exercise SMC32 calling convention with fast SMC calls. */
test_result_t smc32_fast(void)
{
+ test_result_t result;
+
/* Valid Fast SMC32 using all 4 return values. */
const smc_args args1 = { .fid = SMC_STD_SVC_UID };
- FAIL_IF(!smc_check_eq(&args1, &std_svc_uuid));
+ result = smc_check_eq_optional(&args1, &std_svc_uuid);
+ if (result != TEST_RESULT_SUCCESS) {
+ return result;
+ }
/* Invalid Fast SMC32. */
const smc_args args2 = {
@@ -171,10 +201,15 @@
const smc_args args3
= { SMC_PSCI_VERSION, 0x44444444, 0x55555555, 0x66666666,
0x77777777, 0x88888888, 0x99999999, 0xaaaaaaaa };
- const smc_ret_values ret3
- = { psci_version, 0x44444444, 0x55555555, 0x66666666,
+ smc_ret_values ret3
+ = { 0x00000000, 0x44444444, 0x55555555, 0x66666666,
0x77777777, 0x88888888, 0x99999999, 0xaaaaaaaa };
- FAIL_IF(!smc_check_eq(&args3, &ret3));
+
+ const bool check[8] = { false, true, true, true, true, true, true, true };
+ const bool allow_zeros[8] = { false, true, true, true,
+ true, true, true, true };
+
+ FAIL_IF(!smc_check_match(&args3, &ret3, check, allow_zeros));
return TEST_RESULT_SUCCESS;
}
@@ -182,9 +217,14 @@
/* Exercise SMC64 calling convention with yielding SMC calls. */
test_result_t smc64_yielding(void)
{
+ test_result_t result;
+
/* Valid Fast SMC32 using all 4 return values. */
const smc_args args1 = { .fid = SMC_STD_SVC_UID };
- FAIL_IF(!smc_check_eq(&args1, &std_svc_uuid));
+ result = smc_check_eq_optional(&args1, &std_svc_uuid);
+ if (result != TEST_RESULT_SUCCESS) {
+ return result;
+ }
/* Invalid function number, SMC64 Yielding. */
const smc_args args2 = {
@@ -239,9 +279,14 @@
#ifndef __aarch64__
static test_result_t smc64_fast_caller32(void)
{
+ test_result_t result;
+
/* Valid Fast SMC32 using all 4 return values. */
smc_args args1 = { .fid = SMC_STD_SVC_UID };
- FAIL_IF(!smc_check_eq(&args1, &std_svc_uuid));
+ result = smc_check_eq_optional(&args1, &std_svc_uuid);
+ if (result != TEST_RESULT_SUCCESS) {
+ return result;
+ }
/* Invalid SMC function number, Fast SMC64. */
const smc_args args2 = {
@@ -270,9 +315,14 @@
#else
static test_result_t smc64_fast_caller64(void)
{
+ test_result_t result;
+
/* Valid Fast SMC32 using all 4 return values. */
smc_args args1 = { .fid = SMC_STD_SVC_UID };
- FAIL_IF(!smc_check_eq(&args1, &std_svc_uuid));
+ result = smc_check_eq_optional(&args1, &std_svc_uuid);
+ if (result != TEST_RESULT_SUCCESS) {
+ return result;
+ }
/* Invalid function number, Fast SMC64. */
const smc_args args2 = {
@@ -310,9 +360,14 @@
/* Exercise SMC32 calling convention with yielding SMC calls. */
test_result_t smc32_yielding(void)
{
+ test_result_t result;
+
/* Valid Fast SMC32 using all 4 return values. */
const smc_args args1 = { .fid = SMC_STD_SVC_UID };
- FAIL_IF(!smc_check_eq(&args1, &std_svc_uuid));
+ result = smc_check_eq_optional(&args1, &std_svc_uuid);
+ if (result != TEST_RESULT_SUCCESS) {
+ return result;
+ }
/* Invalid function number, SMC32 Yielding. */
const smc_args args2 = {
diff --git a/tftf/tests/runtime_services/secure_service/spm_common.c b/tftf/tests/runtime_services/secure_service/spm_common.c
index 92a6644..baf556b 100644
--- a/tftf/tests/runtime_services/secure_service/spm_common.c
+++ b/tftf/tests/runtime_services/secure_service/spm_common.c
@@ -200,8 +200,6 @@
FFA_SUCCESS_SMC32},
{"FFA_NOTIFICATION_INFO_GET_64", FFA_NOTIFICATION_INFO_GET_SMC64,
FFA_SUCCESS_SMC32},
- {"FFA_ABORT_32", FFA_ABORT_32, FFA_ERROR},
- {"FFA_ABORT_64", FFA_ABORT_64, FFA_ERROR},
{"Check non-existent command", 0xFFFF, FFA_ERROR},
};
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_notifications.c b/tftf/tests/runtime_services/secure_service/test_ffa_notifications.c
index fe04751..9a63d85 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_notifications.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_notifications.c
@@ -17,23 +17,6 @@
#include <spm_test_helpers.h>
#include <test_helpers.h>
-/**
- * Defining variables to test the per-vCPU notifications.
- * The conceived test follows the same logic, despite the sender receiver type
- * of endpoint (VM or secure partition).
- * Using global variables because these need to be accessed in the cpu on handler
- * function 'request_notification_get_per_vcpu_on_handler'.
- * In each specific test function, change 'per_vcpu_receiver' and
- * 'per_vcpu_sender' have the logic work for:
- * - NWd to SP;
- * - SP to NWd;
- * - SP to SP.
- */
-static ffa_id_t per_vcpu_receiver;
-static ffa_id_t per_vcpu_sender;
-uint32_t per_vcpu_flags_get;
-static event_t per_vcpu_finished[PLATFORM_CORE_COUNT];
-
static const struct ffa_uuid expected_sp_uuids[] = {
{PRIMARY_UUID}, {SECONDARY_UUID}, {TERTIARY_UUID}
};
@@ -958,338 +941,6 @@
}
/**
- * CPU_ON handler for testing per-vCPU notifications to SPs (either from VMs
- * or from SPs). It requests the SP to retrieve its pending notifications
- * within its current Execution Context. The SP shall obtain all per-vCPU
- * targeted to the running vCPU.
- */
-static test_result_t request_notification_get_per_vcpu_on_handler(void)
-{
- unsigned int core_pos = get_current_core_id();
- test_result_t result = TEST_RESULT_FAIL;
-
- uint64_t exp_from_vm = 0;
- uint64_t exp_from_sp = 0;
-
- if (IS_SP_ID(per_vcpu_sender)) {
- exp_from_sp = FFA_NOTIFICATION(core_pos);
- } else {
- exp_from_vm = FFA_NOTIFICATION(core_pos);
- }
-
- VERBOSE("Request get per-vCPU notification to %x, core: %u.\n",
- per_vcpu_receiver, core_pos);
-
- /*
- * Request to get notifications sent to the respective vCPU.
- * Check also if NPI was handled by the receiver. It should have been
- * pended at notifications set, in the respective vCPU.
- */
- if (!notification_get_and_validate(
- per_vcpu_receiver, exp_from_sp, exp_from_vm, core_pos,
- per_vcpu_flags_get, true)) {
- goto out;
- }
-
- result = TEST_RESULT_SUCCESS;
-
-out:
- INFO("Request get per-vCPU notification to %x, core: %u.\n",
- per_vcpu_receiver, core_pos);
- /* Tell the lead CPU that the calling CPU has completed the test. */
- tftf_send_event(&per_vcpu_finished[core_pos]);
-
- return result;
-}
-
-static test_result_t base_npi_enable_per_cpu(bool enable)
-{
- test_result_t result = TEST_RESULT_FAIL;
- uint32_t core_pos = get_current_core_id();
-
- VERBOSE("Request SP %x to enable NPI in core %u\n",
- per_vcpu_receiver, core_pos);
-
- result = TEST_RESULT_SUCCESS;
-
- /* Tell the lead CPU that the calling CPU has completed the test. */
- tftf_send_event(&per_vcpu_finished[core_pos]);
-
- return result;
-}
-
-static test_result_t npi_enable_per_vcpu_on_handler(void)
-{
- return base_npi_enable_per_cpu(true);
-}
-
-static test_result_t npi_disable_per_vcpu_on_handler(void)
-{
- return base_npi_enable_per_cpu(false);
-}
-/**
- * Base function to test signaling of per-vCPU notifications.
- * Test whole flow between two FF-A endpoints: binding, getting notification
- * info, and getting pending notifications.
- * Each vCPU will receive a notification whose ID is the same as the core
- * position.
- */
-static test_result_t base_test_per_vcpu_notifications(ffa_id_t sender,
- ffa_id_t receiver)
-{
- /*
- * Manually set variables to validate what should be the return of to
- * FFA_NOTIFICATION_INFO_GET.
- */
- uint16_t exp_ids[FFA_NOTIFICATIONS_INFO_GET_MAX_IDS] = {
- receiver, 0, 1, 2,
- receiver, 3, 4, 5,
- receiver, 6, 7, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- };
- uint32_t exp_lists_count = 3;
- uint32_t exp_lists_sizes[FFA_NOTIFICATIONS_INFO_GET_MAX_IDS] = {
- 3, 3, 2, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- };
-
- const bool exp_more_notif_pending = false;
- test_result_t result = TEST_RESULT_SUCCESS;
- uint64_t notifications_to_unbind = 0;
-
- CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
-
- per_vcpu_flags_get = IS_SP_ID(sender)
- ? FFA_NOTIFICATIONS_FLAG_BITMAP_SP
- : FFA_NOTIFICATIONS_FLAG_BITMAP_VM;
-
- /* Setting global variables to be accessed by the cpu_on handler. */
- per_vcpu_receiver = receiver;
- per_vcpu_sender = sender;
-
- INFO("Execute npi_enable_per_vcpu_on_handler\n");
- /* Boot all cores and enable the NPI in all of them. */
- if (spm_run_multi_core_test(
- (uintptr_t)npi_enable_per_vcpu_on_handler,
- per_vcpu_finished) != TEST_RESULT_SUCCESS) {
- return TEST_RESULT_FAIL;
- }
-
- /*
- * Prepare notifications bitmap to request Cactus to bind them as
- * per-vCPU.
- */
- for (unsigned int i = 0; i < PLATFORM_CORE_COUNT; i++) {
- notifications_to_unbind |= FFA_NOTIFICATION(i);
-
- uint32_t flags = FFA_NOTIFICATIONS_FLAG_PER_VCPU |
- FFA_NOTIFICATIONS_FLAGS_VCPU_ID((uint16_t)i);
-
- flags |= (IS_SP_ID(sender))
- ? FFA_NOTIFICATIONS_FLAG_DELAY_SRI
- : 0;
-
- if (!notification_bind_and_set(sender,
- receiver,
- FFA_NOTIFICATION(i),
- flags)) {
- return TEST_RESULT_FAIL;
- }
- }
-
- /* Call FFA_NOTIFICATION_INFO_GET and validate return. */
- if (!notifications_info_get(exp_ids, exp_lists_count, exp_lists_sizes,
- FFA_NOTIFICATIONS_INFO_GET_MAX_IDS,
- exp_more_notif_pending)) {
- ERROR("Info Get Failed....\n");
- result = TEST_RESULT_FAIL;
- goto out;
- }
-
- /*
- * Request SP to get notifications in core 0, as this is not iterated
- * at the CPU ON handler.
- * Set `check_npi_handled` to true, as the receiver is supposed to be
- * preempted by the NPI.
- */
- if (!notification_get_and_validate(
- receiver, IS_SP_ID(sender) ? FFA_NOTIFICATION(0) : 0,
- !IS_SP_ID(sender) ? FFA_NOTIFICATION(0) : 0, 0,
- per_vcpu_flags_get, true)) {
- result = TEST_RESULT_FAIL;
- }
-
- INFO("Execute request_notification_get_per_vcpu_on_handler\n");
- /*
- * Bring up all the cores, and request the receiver to get notifications
- * in each one of them.
- */
- if (spm_run_multi_core_test(
- (uintptr_t)request_notification_get_per_vcpu_on_handler,
- per_vcpu_finished) != TEST_RESULT_SUCCESS) {
- result = TEST_RESULT_FAIL;
- }
-
-out:
- INFO("UNbind message on CPU:%lx\n", read_mpidr_el1());
- /* As a clean-up, unbind notifications. */
- if (!request_notification_unbind(receiver, receiver,
- sender,
- notifications_to_unbind,
- CACTUS_SUCCESS, 0)) {
- result = TEST_RESULT_FAIL;
- }
-
- INFO("Execute npi_disable_per_vcpu_on_handler\n");
- /* Boot all cores and DISABLE the NPI in all of them. */
- if (spm_run_multi_core_test(
- (uintptr_t)npi_disable_per_vcpu_on_handler,
- per_vcpu_finished) != TEST_RESULT_SUCCESS) {
- return TEST_RESULT_FAIL;
- }
-
- return result;
-}
-
-/**
- * Test to validate a VM can signal a per-vCPU notification to an SP.
- */
-test_result_t test_ffa_notifications_vm_signals_sp_per_vcpu(void)
-{
- return base_test_per_vcpu_notifications(0, SP_ID(1));
-}
-
-/**
- * Test to validate an SP can signal a per-vCPU notification to an SP.
- */
-test_result_t test_ffa_notifications_sp_signals_sp_per_vcpu(void)
-{
- return base_test_per_vcpu_notifications(SP_ID(1), SP_ID(2));
-}
-
-static test_result_t notification_get_per_vcpu_on_handler(void)
-{
- unsigned int core_pos = get_current_core_id();
- test_result_t result = TEST_RESULT_SUCCESS;
-
- VERBOSE("Getting per-vCPU notifications from %x, core: %u.\n",
- per_vcpu_receiver, core_pos);
-
- if (!notification_get_and_validate(per_vcpu_receiver,
- FFA_NOTIFICATION(core_pos), 0,
- core_pos,
- FFA_NOTIFICATIONS_FLAG_BITMAP_SP,
- false)) {
- result = TEST_RESULT_FAIL;
- }
-
- /* Tell the lead CPU that the calling CPU has completed the test. */
- tftf_send_event(&per_vcpu_finished[core_pos]);
-
- return result;
-}
-
-/**
- * Test whole flow from binding, to getting notifications' info, and getting
- * pending notifications, namely signaling of notifications from SP to a VM.
- * Each vCPU will receive a notification whose ID is the same as the core
- * position.
- */
-test_result_t test_ffa_notifications_sp_signals_vm_per_vcpu(void)
-{
- /* Making a VM the receiver, and an SP the sender */
- per_vcpu_receiver = VM_ID(1);
- per_vcpu_sender = SP_ID(2);
-
- /**
- * Manually set variables to validate what should be the return of to
- * FFA_NOTIFICATION_INFO_GET.
- */
- uint16_t exp_ids[FFA_NOTIFICATIONS_INFO_GET_MAX_IDS] = {
- per_vcpu_receiver, 0, 1, 2,
- per_vcpu_receiver, 3, 4, 5,
- per_vcpu_receiver, 6, 7, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- };
- uint32_t exp_lists_count = 3;
- uint32_t exp_lists_sizes[FFA_NOTIFICATIONS_INFO_GET_MAX_IDS] = {
- 3, 3, 2, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- };
-
- const bool exp_more_notif_pending = false;
- test_result_t result = TEST_RESULT_SUCCESS;
- uint64_t notifications_to_unbind = 0;
- struct ffa_value ret;
-
- CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
-
- /* Create bitmap for receiver. */
- if (!notifications_bitmap_create(per_vcpu_receiver,
- PLATFORM_CORE_COUNT)) {
- return TEST_RESULT_FAIL;
- }
-
- /* Bind notifications, and request Cactus SP to set them. */
- for (uint32_t i = 0U; i < PLATFORM_CORE_COUNT; i++) {
- notifications_to_unbind |= FFA_NOTIFICATION(i);
-
- uint32_t flags = FFA_NOTIFICATIONS_FLAG_DELAY_SRI |
- FFA_NOTIFICATIONS_FLAG_PER_VCPU |
- FFA_NOTIFICATIONS_FLAGS_VCPU_ID((uint16_t)i);
-
- if (!notification_bind_and_set(per_vcpu_sender,
- per_vcpu_receiver,
- FFA_NOTIFICATION(i),
- flags)) {
- return TEST_RESULT_FAIL;
- };
- }
-
- /* Call FFA_NOTIFICATION_INFO_GET and validate return. */
- if (!notifications_info_get(exp_ids, exp_lists_count, exp_lists_sizes,
- FFA_NOTIFICATIONS_INFO_GET_MAX_IDS,
- exp_more_notif_pending)) {
- ERROR("Info Get Failed....\n");
- return TEST_RESULT_FAIL;
- }
-
- /*
- * Get notifications in core 0, as it is not iterated at the CPU ON
- * handler.
- */
- if (!notification_get_and_validate(per_vcpu_receiver,
- FFA_NOTIFICATION(0), 0, 0,
- FFA_NOTIFICATIONS_FLAG_BITMAP_SP,
- false)) {
- result = TEST_RESULT_FAIL;
- }
-
- /* Bring up all the cores, and get notifications in each one of them. */
- if (spm_run_multi_core_test(
- (uintptr_t)notification_get_per_vcpu_on_handler,
- per_vcpu_finished) != TEST_RESULT_SUCCESS) {
- ERROR("Failed to get per-vCPU notifications\n");
- result = TEST_RESULT_FAIL;
- }
-
- /* As a clean-up, unbind notifications. */
- ret = ffa_notification_unbind(per_vcpu_sender, per_vcpu_receiver,
- notifications_to_unbind);
- if (is_ffa_call_error(ret)) {
- result = TEST_RESULT_FAIL;
- }
-
- if (!notifications_bitmap_destroy(per_vcpu_receiver)) {
- result = TEST_RESULT_FAIL;
- }
-
- return result;
-}
-
-/**
* Test to validate behavior in SWd if the SRI is not delayed. If the
* notification setter handled a managed exit it is indicative the SRI was
* sent immediately.
@@ -1476,91 +1127,3 @@
return result;
}
-
-test_result_t notifications_set_per_vcpu_on_handler(void)
-{
- unsigned int core_pos = get_current_core_id();
- test_result_t result = TEST_RESULT_FAIL;
-
- if (!notification_set(per_vcpu_receiver, per_vcpu_sender,
- FFA_NOTIFICATIONS_FLAG_DELAY_SRI |
- FFA_NOTIFICATIONS_FLAG_PER_VCPU |
- FFA_NOTIFICATIONS_FLAGS_VCPU_ID(0),
- FFA_NOTIFICATION(core_pos))) {
- goto out;
- }
-
- result = TEST_RESULT_SUCCESS;
-
-out:
- /* Tell the lead CPU that the calling CPU has completed the test. */
- tftf_send_event(&per_vcpu_finished[core_pos]);
-
- return result;
-}
-
-test_result_t test_ffa_notifications_mp_sp_signals_up_sp(void)
-{
- ffa_notification_bitmap_t to_bind = 0;
-
- /* prepare info get variables. */
-
- CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
-
- /* Setting per-vCPU sender and receiver IDs. */
- per_vcpu_sender = SP_ID(2); /* MP SP */
- per_vcpu_receiver = SP_ID(3); /* UP SP */
-
- schedule_receiver_interrupt_init();
-
- /* Prepare notifications bitmap to have one bit platform core. */
- for (uint32_t i = 0; i < PLATFORM_CORE_COUNT; i++) {
- to_bind |= FFA_NOTIFICATION(i);
- }
-
- /* Request receiver to bind a set of notifications to the sender. */
- if (!request_notification_bind(per_vcpu_receiver, per_vcpu_receiver,
- per_vcpu_sender, to_bind,
- FFA_NOTIFICATIONS_FLAG_PER_VCPU,
- CACTUS_SUCCESS, 0)) {
- return TEST_RESULT_FAIL;
- }
-
- /*
- * Boot up system, and then request sender to signal notification from
- * every core into into receiver's only vCPU. Delayed SRI.
- */
- if (!notification_set(per_vcpu_receiver, per_vcpu_sender,
- FFA_NOTIFICATIONS_FLAG_DELAY_SRI |
- FFA_NOTIFICATIONS_FLAG_PER_VCPU |
- FFA_NOTIFICATIONS_FLAGS_VCPU_ID(0),
- FFA_NOTIFICATION(0))) {
- return TEST_RESULT_FAIL;
- }
-
- if (spm_run_multi_core_test(
- (uintptr_t)notifications_set_per_vcpu_on_handler,
- per_vcpu_finished) != TEST_RESULT_SUCCESS) {
- return TEST_RESULT_FAIL;
- }
-
- if (!check_schedule_receiver_interrupt_handled()) {
- return TEST_RESULT_FAIL;
- }
-
- if (!notification_get_and_validate(per_vcpu_receiver, to_bind, 0, 0,
- FFA_NOTIFICATIONS_FLAG_BITMAP_SP, true)) {
- return TEST_RESULT_FAIL;
- }
-
- /* Request unbind. */
- if (!request_notification_unbind(per_vcpu_receiver, per_vcpu_receiver,
- per_vcpu_sender, to_bind,
- CACTUS_SUCCESS, 0)) {
- return TEST_RESULT_FAIL;
- }
-
- schedule_receiver_interrupt_deinit();
-
- return TEST_RESULT_SUCCESS;
-}
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_setup_and_discovery.c b/tftf/tests/runtime_services/secure_service/test_ffa_setup_and_discovery.c
index 1586fe6..2640fb6 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_setup_and_discovery.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_setup_and_discovery.c
@@ -97,6 +97,8 @@
{"FFA_FEATURE_NPI", FFA_FEATURE_NPI, FFA_ERROR, 0,
FFA_VERSION_1_1},
{"FFA_YIELD_32", FFA_MSG_YIELD, FFA_ERROR},
+ {"FFA_ABORT_32", FFA_ABORT_32, FFA_ERROR},
+ {"FFA_ABORT_64", FFA_ABORT_64, FFA_ERROR},
};
size_t test_target_size = get_ffa_feature_test_target(&func_ids_target);
diff --git a/tftf/tests/runtime_services/sip_service/test_debugfs.c b/tftf/tests/runtime_services/sip_service/test_debugfs.c
index 39a1bf9..dcc57b2 100644
--- a/tftf/tests/runtime_services/sip_service/test_debugfs.c
+++ b/tftf/tests/runtime_services/sip_service/test_debugfs.c
@@ -360,3 +360,51 @@
return TEST_RESULT_SUCCESS;
}
+
+/*
+ * @Test_Aim@ Verify that the I/O layer correctly handles out-of-bounds access.
+ *
+ * This test ensures robustness of seek/read APIs against invalid
+ * offsets and prevents potential memory or file corruption due to invalid
+ * access.
+ */
+test_result_t test_oob_access(void)
+{
+ int ret, fd;
+
+ /* Get debugfs interface version (if implemented)*/
+ ret = version();
+ if (ret != DEBUGFS_VERSION) {
+ /* Likely debugfs feature is not implemented */
+ return TEST_RESULT_SKIPPED;
+ }
+
+ /* Open BL2. */
+ fd = open("/fip/bl2.bin", O_READ);
+ if (fd < 0) {
+ tftf_testcase_printf("open failed fd=%d\n", fd);
+ return TEST_RESULT_FAIL;
+ }
+
+ /* Rewind to negative offset. */
+ ret = seek(fd, -1000, KSEEK_SET);
+
+ /* Reading with out-of-bounds cursor position should fail */
+ ret = read(fd, read_buffer, 128);
+ if (ret != 0) {
+ tftf_testcase_printf("Out-of-bounds read(%d)\n", __LINE__);
+ return TEST_RESULT_FAIL;
+ }
+
+ /* Reset cursor position to valid range. */
+ ret = seek(fd, 0, KSEEK_SET);
+
+ /* Read 128 bytes from start */
+ ret = read(fd, read_buffer, 128);
+ if (ret != 128) {
+ tftf_testcase_printf("read failed(%d) ret=%d\n", __LINE__, ret);
+ return TEST_RESULT_FAIL;
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
\ No newline at end of file
diff --git a/tftf/tests/runtime_services/standard_service/pmf/api_tests/runtime_instr/test_pmf_rt_instr.c b/tftf/tests/runtime_services/standard_service/pmf/api_tests/runtime_instr/test_pmf_rt_instr.c
index 43685e4..259ed1d 100644
--- a/tftf/tests/runtime_services/standard_service/pmf/api_tests/runtime_instr/test_pmf_rt_instr.c
+++ b/tftf/tests/runtime_services/standard_service/pmf/api_tests/runtime_instr/test_pmf_rt_instr.c
@@ -75,10 +75,11 @@
args.fid = PMF_SMC_GET_VERSION;
ret = tftf_smc(&args);
+ if (ret.ret0 == SMC_UNKNOWN)
+ return TEST_RESULT_SKIPPED;
+
if (ret.ret1 != PMF_SMC_VERSION)
- {
return TEST_RESULT_FAIL;
- }
return TEST_RESULT_SUCCESS;
}
diff --git a/tftf/tests/runtime_services/standard_service/psci/api_tests/migrate_info_type/test_migrate_info_type.c b/tftf/tests/runtime_services/standard_service/psci/api_tests/migrate_info_type/test_migrate_info_type.c
index 50462d7..a3141a5 100644
--- a/tftf/tests/runtime_services/standard_service/psci/api_tests/migrate_info_type/test_migrate_info_type.c
+++ b/tftf/tests/runtime_services/standard_service/psci/api_tests/migrate_info_type/test_migrate_info_type.c
@@ -89,7 +89,7 @@
* Pass a valid MPID so that the MIGRATE call doesn't fail because of
* invalid parameters
*/
- args.arg1 = read_mpidr_el1() & MPID_MASK;
+ args.arg1 = psci_target_cpu_from_mpid(read_mpidr_el1());
ret = tftf_smc(&args);
migrate_ret = (int32_t) ret.ret0;
diff --git a/tftf/tests/runtime_services/standard_service/query_std_svc.c b/tftf/tests/runtime_services/standard_service/query_std_svc.c
index c8ce6e9..6debe63 100644
--- a/tftf/tests/runtime_services/standard_service/query_std_svc.c
+++ b/tftf/tests/runtime_services/standard_service/query_std_svc.c
@@ -47,6 +47,10 @@
std_svc_args.fid = SMC_STD_SVC_UID;
ret = tftf_smc(&std_svc_args);
+ /* These functions are optional, skip test when not supported. */
+ if (ret.ret0 == SMC_UNKNOWN)
+ return TEST_RESULT_SKIPPED;
+
make_uuid_from_4words(&std_svc_uuid,
ret.ret0, ret.ret1, ret.ret2, ret.ret3);
if (!uuid_equal(&std_svc_uuid, &armtf_std_svc_uuid)) {
diff --git a/tftf/tests/tests-corrupt-rotpk.mk b/tftf/tests/tests-corrupt-rotpk.mk
new file mode 100644
index 0000000..bf25158
--- /dev/null
+++ b/tftf/tests/tests-corrupt-rotpk.mk
@@ -0,0 +1,14 @@
+#
+# Copyright (c) 2025, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+TESTS_SOURCES += $(addprefix tftf/tests/neg_scenario_tests/, \
+ test_invalid_rotpk.c \
+ neg_scenario_test_infra.c \
+)
+
+include lib/ext_mbedtls/mbedtls.mk
+
+
diff --git a/tftf/tests/tests-corrupt-rotpk.xml b/tftf/tests/tests-corrupt-rotpk.xml
new file mode 100644
index 0000000..354752b
--- /dev/null
+++ b/tftf/tests/tests-corrupt-rotpk.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ Copyright (c) 2025, Arm Limited. All rights reserved.
+
+ SPDX-License-Identifier: BSD-3-Clause
+-->
+
+<testsuites>
+ <testsuite name="neg scenario test-rotpk" description="Stress test for when ROTPK in fip cert is corrupted" >
+ <testcase name="invalid rotpk" function="test_invalid_rotpk" />
+ </testsuite>
+
+</testsuites>
+
diff --git a/tftf/tests/tests-debugfs.xml b/tftf/tests/tests-debugfs.xml
index 4da3152..61342e8 100644
--- a/tftf/tests/tests-debugfs.xml
+++ b/tftf/tests/tests-debugfs.xml
@@ -12,6 +12,7 @@
-->
<testsuite name="DebugFS" description="Test ARM SiP DebugFS service">
<testcase name="Expose filesystem" function="test_debugfs" />
+ <testcase name="Out-of-bounds accesses" function="test_oob_access" />
</testsuite>
</testsuites>
diff --git a/tftf/tests/tests-spm.xml b/tftf/tests/tests-spm.xml
index 60470fe..9c674a9 100644
--- a/tftf/tests/tests-spm.xml
+++ b/tftf/tests/tests-spm.xml
@@ -229,16 +229,8 @@
function="test_ffa_notifications_sp_signals_sp_delayed_sri" />
<testcase name="Notifications unbind while pending"
function="test_ffa_notifications_unbind_pending" />
- <testcase name="Notifications MP SP signals UP SP per-vCPU"
- function="test_ffa_notifications_mp_sp_signals_up_sp" />
<testcase name="Notifications info get no data"
function="test_ffa_notifications_info_get_none" />
- <testcase name="Notifications VM signals SP per-vCPU"
- function="test_ffa_notifications_vm_signals_sp_per_vcpu" />
- <testcase name="Notifications SP signals SP per-vCPU"
- function="test_ffa_notifications_sp_signals_sp_per_vcpu" />
- <testcase name="Notifications SP signals VM per-vCPU"
- function="test_ffa_notifications_sp_signals_vm_per_vcpu" />
<testcase name="Notifications VM signals SP, with SRI flag set and fail"
function="test_ffa_notifications_vm_signals_sp_delay_sri_fail" />
</testsuite>