test(rme): check if non SVE realm gets undefined abort

This test checks whether a non SVE realm receives undefined abort upon
accessing SVE register state or instructions.

Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
Change-Id: I2785488b1344cc4d59dde75e38d9e0d6f856af61
diff --git a/include/runtime_services/host_realm_managment/host_shared_data.h b/include/runtime_services/host_realm_managment/host_shared_data.h
index 4cb3c0a..201e9f4 100644
--- a/include/runtime_services/host_realm_managment/host_shared_data.h
+++ b/include/runtime_services/host_realm_managment/host_shared_data.h
@@ -53,6 +53,7 @@
 	REALM_SVE_PROBE_VL,
 	REALM_SVE_OPS,
 	REALM_SVE_FILL_REGS,
+	REALM_SVE_UNDEF_ABORT,
 	REALM_PAUTH_SET_CMD,
 	REALM_PAUTH_CHECK_CMD,
 	REALM_PAUTH_FAULT
diff --git a/realm/include/realm_tests.h b/realm/include/realm_tests.h
index 4bd260c..b73cc3b 100644
--- a/realm/include/realm_tests.h
+++ b/realm/include/realm_tests.h
@@ -20,6 +20,7 @@
 bool test_realm_sve_probe_vl(void);
 bool test_realm_sve_ops(void);
 bool test_realm_sve_fill_regs(void);
+bool test_realm_sve_undef_abort(void);
 
 #endif /* REALM_TESTS_H */
 
diff --git a/realm/realm_payload_main.c b/realm/realm_payload_main.c
index b8c27bd..94ef25e 100644
--- a/realm/realm_payload_main.c
+++ b/realm/realm_payload_main.c
@@ -119,6 +119,9 @@
 		case REALM_SVE_FILL_REGS:
 			test_succeed = test_realm_sve_fill_regs();
 			break;
+		case REALM_SVE_UNDEF_ABORT:
+			test_succeed = test_realm_sve_undef_abort();
+			break;
 		default:
 			realm_printf("%s() invalid cmd %u\n", __func__, cmd);
 			break;
diff --git a/realm/realm_sve.c b/realm/realm_sve.c
index 0512789..b41e23d 100644
--- a/realm/realm_sve.c
+++ b/realm/realm_sve.c
@@ -9,6 +9,7 @@
 #include <assert.h>
 #include <debug.h>
 #include <stdlib.h>
+#include <sync.h>
 #include <lib/extensions/sve.h>
 
 #include <host_realm_sve.h>
@@ -22,6 +23,8 @@
 
 static sve_vector_t rl_sve_vectors_write[SVE_NUM_VECTORS] __aligned(16);
 
+static int volatile realm_got_undef_abort;
+
 /* Returns the maximum supported VL. This test is called only by sve Realm */
 bool test_realm_sve_rdvl(void)
 {
@@ -128,3 +131,34 @@
 
 	return true;
 }
+
+static bool realm_sync_exception_handler(void)
+{
+	uint64_t esr_el1 = read_esr_el1();
+
+	if (EC_BITS(esr_el1) == EC_UNKNOWN) {
+		realm_printf("Realm: received undefined abort. "
+			     "esr_el1: 0x%llx elr_el1: 0x%llx\n",
+			     esr_el1, read_elr_el1());
+		realm_got_undef_abort++;
+	}
+
+	return true;
+}
+
+/* Check if Realm gets undefined abort when it accesses SVE functionality */
+bool test_realm_sve_undef_abort(void)
+{
+	realm_got_undef_abort = 0UL;
+
+	/* install exception handler to catch undef abort */
+	register_custom_sync_exception_handler(&realm_sync_exception_handler);
+	(void)sve_rdvl_1();
+	unregister_custom_sync_exception_handler();
+
+	if (realm_got_undef_abort == 0UL) {
+		return false;
+	}
+
+	return true;
+}
diff --git a/tftf/tests/runtime_services/realm_payload/host_realm_payload_sve_tests.c b/tftf/tests/runtime_services/realm_payload/host_realm_payload_sve_tests.c
index 358c8bb..93dfbfd 100644
--- a/tftf/tests/runtime_services/realm_payload/host_realm_payload_sve_tests.c
+++ b/tftf/tests/runtime_services/realm_payload/host_realm_payload_sve_tests.c
@@ -540,3 +540,36 @@
 
 	return rc;
 }
+
+/*
+ * Create a non SVE Realm and try to access SVE, the Realm must receive
+ * undefined abort.
+ */
+test_result_t host_non_sve_realm_check_undef_abort(void)
+{
+	test_result_t rc;
+	bool realm_rc;
+
+	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
+	SKIP_TEST_IF_SVE_NOT_SUPPORTED();
+
+	rc = host_create_sve_realm_payload(false, 0);
+	if (rc != TEST_RESULT_SUCCESS) {
+		return rc;
+	}
+
+	realm_rc = host_enter_realm_execute(REALM_SVE_UNDEF_ABORT, NULL,
+					    RMI_EXIT_HOST_CALL, 0U);
+	if (!realm_rc) {
+		ERROR("Realm didn't receive undefined abort\n");
+		rc = TEST_RESULT_FAIL;
+	} else {
+		rc = TEST_RESULT_SUCCESS;
+	}
+
+	if (!host_destroy_realm()) {
+		return TEST_RESULT_FAIL;
+	}
+
+	return rc;
+}
diff --git a/tftf/tests/tests-realm-payload.xml b/tftf/tests/tests-realm-payload.xml
index 188ff29..77c17fb 100644
--- a/tftf/tests/tests-realm-payload.xml
+++ b/tftf/tests/tests-realm-payload.xml
@@ -53,6 +53,8 @@
 	  function="host_sve_realm_check_vectors_operations" />
 	  <testcase name="Check if RMM does not leak Realm SVE vector registers"
 	  function="host_sve_realm_check_vectors_leaked" />
+	  <testcase name="Check if Realm gets undefined abort if it access SVE"
+	  function="host_non_sve_realm_check_undef_abort" />
 	  <testcase name="Check if PAuth keys are preserved in RL/SE/NS"
 	  function="host_realm_enable_pauth" />
 	  <testcase name="Generate PAuth Fault by overwriting LR"