Merge "fix(SME): add a missing ISB"
diff --git a/include/lib/extensions/sve.h b/include/lib/extensions/sve.h
index 45481d7..07bd663 100644
--- a/include/lib/extensions/sve.h
+++ b/include/lib/extensions/sve.h
@@ -17,6 +17,8 @@
 #define SVE_VECTOR_LEN_BYTES		256
 #define SVE_NUM_VECTORS			32
 
+#ifndef __ASSEMBLY__
+
 typedef uint8_t sve_vector_t[SVE_VECTOR_LEN_BYTES];
 
 #ifdef __aarch64__
@@ -37,5 +39,5 @@
 }
 
 #endif /* __aarch64__ */
-
+#endif /* __ASSEMBLY__ */
 #endif /* SVE_H */
diff --git a/spm/cactus/cactus_interrupt.c b/spm/cactus/cactus_interrupt.c
index 16785db..b8eb058 100644
--- a/spm/cactus/cactus_interrupt.c
+++ b/spm/cactus/cactus_interrupt.c
@@ -88,7 +88,7 @@
 			 cactus_get_cmd(ffa_ret) != CACTUS_RESUME_AFTER_MANAGED_EXIT;
 
 		if (waiting_resume_after_managed_exit) {
-			ERROR("Expected a direct message request from endpoint"
+			VERBOSE("Expected a direct message request from endpoint"
 			      " %x with command CACTUS_RESUME_AFTER_MANAGED_EXIT\n",
 			       g_dir_req_source_id);
 			ffa_ret = cactus_error_resp(g_ffa_id,
diff --git a/tftf/tests/runtime_services/secure_service/spm_common.c b/tftf/tests/runtime_services/secure_service/spm_common.c
index ae00ff5..3cd8350 100644
--- a/tftf/tests/runtime_services/secure_service/spm_common.c
+++ b/tftf/tests/runtime_services/secure_service/spm_common.c
@@ -88,7 +88,7 @@
 
 	if (cactus_get_response(ret) != expected_resp ||
 	    (uint32_t)ret.arg4 != arg) {
-		ERROR("Expected response %x and %x; "
+		VERBOSE("Expected response %x and %x; "
 		      "Obtained %x and %x\n",
 		      expected_resp, arg, cactus_get_response(ret),
 		      (int32_t)ret.arg4);
diff --git a/tftf/tests/runtime_services/secure_service/sve_operations_cactus.S b/tftf/tests/runtime_services/secure_service/sve_operations_cactus.S
new file mode 100644
index 0000000..f538b2c
--- /dev/null
+++ b/tftf/tests/runtime_services/secure_service/sve_operations_cactus.S
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+
+#ifdef __aarch64__
+#if __GNUC__ > 8 || (__GNUC__ == 8 && __GNUC_MINOR__ > 0)
+
+#define SVE_ARRAYSIZE 1024
+
+/*
+ * Based on example code from the Arm Compiler Scalable Vector Extension User
+ * Guide[1].
+ * [1] https://developer.arm.com/docs/100891/latest/getting-started-with-the-sve-compiler/compiling-c-and-c-code-for-sve-enabled-targets
+ */
+
+	.arch armv8.2-a+crc+fp16+sve
+	.global	sve_subtract_interleaved_smc
+func sve_subtract_interleaved_smc
+	mov	x4, SVE_ARRAYSIZE
+	mov	x5, x4
+	mov	x3, 0
+	whilelo	p0.s, xzr, x4
+.loop:
+	ld1w	z0.s, p0/z, [x1, x3, lsl 2]
+	ld1w	z1.s, p0/z, [x2, x3, lsl 2]
+	sub	z0.s, z0.s, z1.s
+	st1w	z0.s, p0, [x0, x3, lsl 2]
+	incw	x3
+
+	stp x0, x1, [sp, #-48]!
+	stp x2, x3, [sp, #16]
+	stp x4, x5, [sp, #32]
+
+	/*
+	 * Forge a FF-A direct request with a command for cactus to fill SIMD
+	 * vectors in the secure world.
+	 */
+	mov w0, #0x6f                   /* FFA_MSG_SEND_DIRECT_REQ_SMC32 */
+	movk w0, #0x8400, lsl #16
+	mov     x1, #0x8001             /* src: nwd, dest: SP1 */
+	mov     x2, xzr
+	mov     x3, #0x4d44
+	movk    w3, #0x5349, lsl #16    /* CACTUS_REQ_SIMD_FILL_CMD */
+	smc     #0
+	and     w1, w0, #0xffff
+	cmp     w1, #0x70               /* FFA_MSG_SEND_DIRECT_RESP_SMC32 (low 16bits) */
+	bne     .			/* Test hangs if direct response not received */
+	cmp	w3, #0x0		/* Check CACTUS_SUCCESS (0x0) returned */
+	bne	.
+	ldp     x4, x5, [sp, #32]
+	ldp     x2, x3, [sp, #16]
+	ldp     x0, x1, [sp], #48
+
+	whilelo	p0.s, x3, x5
+	bne	.loop
+	ret
+endfunc sve_subtract_interleaved_smc
+
+#endif /* __GNUC__ > 8 || (__GNUC__ == 8 && __GNUC_MINOR__ > 0) */
+#endif /* __aarch64__ */
diff --git a/tftf/tests/runtime_services/secure_service/test_spm_cpu_features.c b/tftf/tests/runtime_services/secure_service/test_spm_cpu_features.c
index 2927fc2..a230d56 100644
--- a/tftf/tests/runtime_services/secure_service/test_spm_cpu_features.c
+++ b/tftf/tests/runtime_services/secure_service/test_spm_cpu_features.c
@@ -7,14 +7,18 @@
 #include <cactus_test_cmds.h>
 #include <ffa_endpoints.h>
 #include <ffa_helpers.h>
-#include <lib/extensions/sve.h>
 #include <test_helpers.h>
 
 #define SENDER HYP_ID
 #define RECEIVER SP_ID(1)
+#define SVE_TEST_ITERATIONS	100
+#define SVE_ARRAYSIZE		1024
 
 static const struct ffa_uuid expected_sp_uuids[] = { {PRIMARY_UUID} };
 
+extern void sve_subtract_interleaved_smc(int *difference, const int *sve_op_1,
+				       const int *sve_op_2);
+
 static test_result_t fp_vector_compare(uint8_t *a, uint8_t *b,
 	size_t vector_size, uint8_t vectors_num)
 {
@@ -27,6 +31,8 @@
 #ifdef __aarch64__
 static sve_vector_t sve_vectors_input[SVE_NUM_VECTORS] __aligned(16);
 static sve_vector_t sve_vectors_output[SVE_NUM_VECTORS] __aligned(16);
+static int sve_op_1[SVE_ARRAYSIZE];
+static int sve_op_2[SVE_ARRAYSIZE];
 #endif
 
 /*
@@ -38,9 +44,9 @@
 test_result_t test_simd_vectors_preserved(void)
 {
 	/**********************************************************************
-	 * Verify that FFA is there and that it has the correct version.
+	 * Verify that FF-A is there and that it has the correct version.
 	 **********************************************************************/
-	CHECK_SPMC_TESTING_SETUP(1, 0, expected_sp_uuids);
+	CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
 
 	simd_vector_t simd_vectors_send[SIMD_NUM_VECTORS],
 		      simd_vectors_receive[SIMD_NUM_VECTORS];
@@ -84,9 +90,9 @@
 	SKIP_TEST_IF_SVE_NOT_SUPPORTED();
 
 	/**********************************************************************
-	 * Verify that FFA is there and that it has the correct version.
+	 * Verify that FF-A is there and that it has the correct version.
 	 **********************************************************************/
-	CHECK_SPMC_TESTING_SETUP(1, 0, expected_sp_uuids);
+	CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
 
 	/*
 	 * Clear SVE vectors buffers used to compare the SVE state before calling
@@ -137,3 +143,48 @@
 	return TEST_RESULT_SKIPPED;
 #endif /* __aarch64__ */
 }
+
+/*
+ * Tests that SVE vector operations in normal world are not affected by context
+ * switches between normal world and the secure world.
+ */
+test_result_t test_sve_vectors_operations(void)
+{
+#ifdef __aarch64__
+	unsigned int val;
+
+	SKIP_TEST_IF_SVE_NOT_SUPPORTED();
+
+	/**********************************************************************
+	 * Verify that FF-A is there and that it has the correct version.
+	 **********************************************************************/
+	CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
+
+	val = 2 * SVE_TEST_ITERATIONS;
+
+	for (unsigned int i = 0; i < SVE_ARRAYSIZE; i++) {
+		sve_op_1[i] = val;
+		sve_op_2[i] = 1;
+	}
+
+	/* Set ZCR_EL2.LEN to implemented VL (constrained by EL3). */
+	write_zcr_el2(0xf);
+	isb();
+
+	for (unsigned int i = 0; i < SVE_TEST_ITERATIONS; i++) {
+		/* Perform SVE operations with intermittent calls to Swd. */
+		sve_subtract_interleaved_smc(sve_op_1, sve_op_1, sve_op_2);
+	}
+
+	/* Check result of SVE operations. */
+	for (unsigned int i = 0; i < SVE_ARRAYSIZE; i++) {
+		if (sve_op_1[i] != (val - SVE_TEST_ITERATIONS)) {
+			return TEST_RESULT_FAIL;
+		}
+	}
+
+	return TEST_RESULT_SUCCESS;
+#else
+	return TEST_RESULT_SKIPPED;
+#endif /* __aarch64__ */
+}
diff --git a/tftf/tests/tests-spm.mk b/tftf/tests/tests-spm.mk
index 702c10c..5d71aec 100644
--- a/tftf/tests/tests-spm.mk
+++ b/tftf/tests/tests-spm.mk
@@ -3,7 +3,6 @@
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
-
 TESTS_SOURCES	+=							\
 	$(addprefix tftf/tests/runtime_services/secure_service/,	\
 		${ARCH}/ffa_arch_helpers.S				\
@@ -18,6 +17,7 @@
 		test_spm_cpu_features.c					\
 		test_spm_smmu.c						\
 		test_ffa_exceptions.c					\
+		sve_operations_cactus.S					\
 	)
 
 TESTS_SOURCES	+=							\
diff --git a/tftf/tests/tests-spm.xml b/tftf/tests/tests-spm.xml
index aa722c2..68d6357 100644
--- a/tftf/tests/tests-spm.xml
+++ b/tftf/tests/tests-spm.xml
@@ -104,6 +104,8 @@
                function="test_simd_vectors_preserved" />
      <testcase name="Check that SVE registers context is preserved"
                function="test_sve_vectors_preserved" />
+     <testcase name="Check that SVE operations in NWd are unaffected by SWd"
+               function="test_sve_vectors_operations" />
   </testsuite>
 
    <testsuite name="FF-A Interrupt"