regression: add tests for panic events handling

Adds a new set of tests for checking the proper releasing of
the memory resources in case of a panic event. The tests are
covering use cases when connections to the panicked context are
established whether to non-secure sessions (CA) or
other secure sessions (TA).

Also are tested several scenarios which involve all supporter
instance types:
- Multiple Instance TAs
- Single Instance TAs
- Single Instance Keep Alive TAs

Signed-off-by: Ovidiu Mihalachi <ovidiu_mihalachi@mentor.com>
Acked-by: Jens Wiklander <jens.wiklander@linaro.org>
Acked-by: Jerome Forissier <jerome.forissier@linaro.org>
Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
diff --git a/Android.mk b/Android.mk
index 1005ded..6d846cc 100644
--- a/Android.mk
+++ b/Android.mk
@@ -89,6 +89,8 @@
 		$(LOCAL_PATH)/ta/os_test/include \
 		$(LOCAL_PATH)/ta/rpc_test/include \
 		$(LOCAL_PATH)/ta/sims/include \
+		$(LOCAL_PATH)/ta/miss/include \
+		$(LOCAL_PATH)/ta/sims_keepalive/include \
 		$(LOCAL_PATH)/ta/include \
 		$(LOCAL_PATH)/ta/storage_benchmark/include \
 		$(LOCAL_PATH)/ta/sha_perf/include \
diff --git a/host/xtest/Makefile b/host/xtest/Makefile
index e930d9c..8564ddd 100644
--- a/host/xtest/Makefile
+++ b/host/xtest/Makefile
@@ -105,6 +105,8 @@
 CFLAGS += -I../../ta/os_test/include
 CFLAGS += -I../../ta/rpc_test/include
 CFLAGS += -I../../ta/sims/include
+CFLAGS += -I../../ta/miss/include
+CFLAGS += -I../../ta/sims_keepalive/include
 CFLAGS += -I../../ta/storage_benchmark/include
 CFLAGS += -I../../ta/concurrent/include
 CFLAGS += -I../../ta/concurrent_large/include
diff --git a/host/xtest/regression_1000.c b/host/xtest/regression_1000.c
index 86f69c3..f390b8c 100644
--- a/host/xtest/regression_1000.c
+++ b/host/xtest/regression_1000.c
@@ -31,6 +31,8 @@
 #include <ta_create_fail_test.h>
 #include <ta_rpc_test.h>
 #include <ta_sims_test.h>
+#include <ta_miss_test.h>
+#include <ta_sims_keepalive_test.h>
 #include <ta_concurrent.h>
 #include <sdp_basic.h>
 #ifdef CFG_SECSTOR_TA_MGMT_PTA
@@ -1469,3 +1471,247 @@
 }
 ADBG_CASE_DEFINE(regression, 1020, xtest_tee_test_1020,
 		"Test lockdep algorithm");
+
+static TEEC_Result open_sec_session(TEEC_Session *session,
+				    const TEEC_UUID *uuid)
+{
+	TEEC_Result res = TEEC_ERROR_GENERIC;
+	TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
+	uint32_t ret_orig = 0;
+
+	op.params[0].tmpref.buffer = (void *)uuid;
+	op.params[0].tmpref.size = sizeof(*uuid);
+	op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
+					 TEEC_NONE, TEEC_NONE, TEEC_NONE);
+
+	res = TEEC_InvokeCommand(session, TA_SIMS_OPEN_TA_SESSION,
+				 &op, &ret_orig);
+	if (res != TEEC_SUCCESS)
+		return TEEC_ERROR_GENERIC;
+
+	return res;
+}
+
+static TEEC_Result sims_get_counter(TEEC_Session *session,
+				    uint32_t *counter)
+{
+	TEEC_Result res = TEEC_ERROR_GENERIC;
+	TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
+	uint32_t ret_orig = 0;
+
+	op.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT,
+					 TEEC_NONE, TEEC_NONE, TEEC_NONE);
+
+	res = TEEC_InvokeCommand(session, TA_SIMS_CMD_GET_COUNTER,
+				 &op, &ret_orig);
+	if (res == TEEC_SUCCESS)
+		*counter = op.params[0].value.a;
+
+	return res;
+}
+
+static TEEC_Result trigger_panic(TEEC_Session *session,
+				 const TEEC_UUID *uuid)
+{
+	TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
+	uint32_t ret_orig = 0;
+
+	if (!uuid) {
+		op.params[0].tmpref.buffer = NULL;
+		op.params[0].tmpref.size = 0;
+	} else {
+		op.params[0].tmpref.buffer = (void *)uuid;
+		op.params[0].tmpref.size = sizeof(*uuid);
+	}
+	op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
+					 TEEC_NONE, TEEC_NONE, TEEC_NONE);
+
+	return TEEC_InvokeCommand(session, TA_SIMS_CMD_PANIC,
+				  &op, &ret_orig);
+}
+
+static void test_panic_ca_to_ta(ADBG_Case_t *c, const TEEC_UUID *uuid,
+				bool multi_instance)
+{
+	TEEC_Result exp_res = TEEC_ERROR_GENERIC;
+	uint32_t counter = 0;
+	uint32_t ret_orig = 0;
+	uint32_t exp_counter = 0;
+	TEEC_Session cs[3] = { };
+
+	if (!ADBG_EXPECT_TEEC_SUCCESS(c,
+			xtest_teec_open_session(&cs[0], uuid, NULL,
+						&ret_orig)))
+		return;
+
+	if (!ADBG_EXPECT_TEEC_SUCCESS(c,
+			xtest_teec_open_session(&cs[1], uuid, NULL,
+						&ret_orig)))
+		goto bail0;
+
+	if (!ADBG_EXPECT_TEEC_SUCCESS(c, sims_get_counter(&cs[0], &counter)))
+		goto bail1;
+
+	if (!ADBG_EXPECT(c, 0, counter))
+		goto bail1;
+
+	if (!ADBG_EXPECT_TEEC_SUCCESS(c, sims_get_counter(&cs[1], &counter)))
+		goto bail1;
+
+	exp_counter = multi_instance ? 0 : 1;
+	if (ADBG_EXPECT(c, exp_counter, counter))
+		goto bail1;
+
+	if (!ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_TARGET_DEAD,
+				     trigger_panic(&cs[1], NULL)))
+		goto bail1;
+
+	exp_res = multi_instance ? TEEC_SUCCESS : TEEC_ERROR_TARGET_DEAD;
+	if (!ADBG_EXPECT_TEEC_RESULT(c, exp_res,
+				     sims_get_counter(&cs[0], &counter)))
+		goto bail1;
+
+	if (!ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_TARGET_DEAD,
+				     sims_get_counter(&cs[1], &counter)))
+		goto bail1;
+
+	/* Attempt to open a session on panicked context */
+	if (!ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_TARGET_DEAD,
+			xtest_teec_open_session(&cs[1], uuid, NULL,
+						&ret_orig)))
+		goto bail1;
+
+	/* Sanity check of still valid TA context */
+	if (!ADBG_EXPECT_TEEC_SUCCESS(c,
+			xtest_teec_open_session(&cs[2], uuid, NULL,
+						&ret_orig)))
+		goto bail1;
+
+	/* Sanity check of still valid TA context */
+	if (multi_instance) {
+		if (!ADBG_EXPECT_TEEC_SUCCESS(c,
+				sims_get_counter(&cs[0], &counter)))
+			goto bail2;
+
+		if (!ADBG_EXPECT(c, 0, counter))
+			goto bail2;
+	}
+
+	if (!ADBG_EXPECT_TEEC_SUCCESS(c, sims_get_counter(&cs[2], &counter)))
+		goto bail2;
+
+	if (!ADBG_EXPECT(c, 0, counter))
+		goto bail2;
+
+bail2:
+	TEEC_CloseSession(&cs[2]);
+bail1:
+	TEEC_CloseSession(&cs[1]);
+bail0:
+	TEEC_CloseSession(&cs[0]);
+}
+
+static void test_panic_ta_to_ta(ADBG_Case_t *c, const TEEC_UUID *uuid1,
+				const TEEC_UUID *uuid2)
+{
+	uint32_t ret_orig = 0;
+	uint32_t counter = 0;
+	TEEC_Session cs[3] = { };
+
+	/* Test pre-conditions */
+	/* 2.1 - CA opens a session toward TA1 */
+	if (!ADBG_EXPECT_TEEC_SUCCESS(c,
+			xtest_teec_open_session(&cs[0], uuid1, NULL,
+						&ret_orig)))
+		return;
+
+	/* 2.2 - CA opens a session toward TA2 */
+	if (!ADBG_EXPECT_TEEC_SUCCESS(c,
+			xtest_teec_open_session(&cs[1], uuid2, NULL,
+						&ret_orig)))
+		goto bail0;
+
+	/* 2.3 - TA1 opens a session toward TA2 */
+	if (!ADBG_EXPECT_TEEC_SUCCESS(c, open_sec_session(&cs[0], uuid2)))
+		goto bail1;
+
+	/* 2.4 - CA invokes TA2 which panics */
+	if (!ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_TARGET_DEAD,
+				     trigger_panic(&cs[1], NULL)))
+		goto bail1;
+
+	/* Expected results */
+	/* 2.5 - Expect CA->TA1 session is still alive */
+	if (!ADBG_EXPECT_TEEC_SUCCESS(c, sims_get_counter(&cs[0], &counter)))
+		goto bail1;
+
+	/* 2.6 - Expect CA->TA2 session is properly released */
+	if (!ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_TARGET_DEAD,
+				     sims_get_counter(&cs[1], &counter)))
+		goto bail1;
+
+bail1:
+	TEEC_CloseSession(&cs[1]);
+bail0:
+	TEEC_CloseSession(&cs[0]);
+
+	memset(cs, 0, sizeof(cs));
+
+	/* Test pre-conditions */
+	/* 2.1 - CA opens a session toward TA1 */
+	if (!ADBG_EXPECT_TEEC_SUCCESS(c,
+			xtest_teec_open_session(&cs[0], uuid1, NULL,
+						&ret_orig)))
+		return;
+
+	/* 2.2 - CA opens a session toward TA2 */
+	if (!ADBG_EXPECT_TEEC_SUCCESS(c,
+			xtest_teec_open_session(&cs[1], uuid2, NULL,
+						&ret_orig)))
+		goto bail2;
+
+	/* 2.3 - TA1 opens a session toward TA2 */
+	if (!ADBG_EXPECT_TEEC_SUCCESS(c, open_sec_session(&cs[0], uuid2)))
+		goto bail3;
+
+	/* 2.4 - CA invokes TA1 which invokes TA2 which panics */
+	if (!ADBG_EXPECT_TEEC_SUCCESS(c, trigger_panic(&cs[0], uuid2)))
+		goto bail3;
+
+	/* Expected results */
+	/* 2.5 - Expect CA->TA1 session is still alive */
+	if (!ADBG_EXPECT_TEEC_SUCCESS(c, sims_get_counter(&cs[0], &counter)))
+		goto bail3;
+
+	/* 2.6 - Expect CA->TA2 session is properly released */
+	if (!ADBG_EXPECT_TEEC_RESULT(c, TEEC_ERROR_TARGET_DEAD,
+				     sims_get_counter(&cs[1], &counter)))
+		goto bail3;
+
+bail3:
+	TEEC_CloseSession(&cs[1]);
+bail2:
+	TEEC_CloseSession(&cs[0]);
+}
+
+static void xtest_tee_test_1021(ADBG_Case_t *c)
+{
+	Do_ADBG_BeginSubCase(c, "Multiple Instances Single Session");
+	test_panic_ca_to_ta(c, &miss_test_ta_uuid, true);
+	Do_ADBG_EndSubCase(c, "Multiple Instances Single Session");
+
+	Do_ADBG_BeginSubCase(c, "Single Instance Multi Sessions");
+	test_panic_ca_to_ta(c, &sims_test_ta_uuid, false);
+	Do_ADBG_EndSubCase(c, "Single Instance Multi Sessions");
+
+	Do_ADBG_BeginSubCase(c, "Single Instance Multi Sessions Keep Alive");
+	test_panic_ca_to_ta(c, &sims_keepalive_test_ta_uuid, false);
+	Do_ADBG_EndSubCase(c, "Single Instance Multi Sessions Keep Alive");
+
+	Do_ADBG_BeginSubCase(c, "Multi Sessions TA to TA");
+	test_panic_ta_to_ta(c, &sims_test_ta_uuid,
+			    &sims_keepalive_test_ta_uuid);
+	Do_ADBG_EndSubCase(c, "Multi Sessions TA to TA");
+}
+ADBG_CASE_DEFINE(regression, 1021, xtest_tee_test_1021,
+		 "Test panic context release");
diff --git a/host/xtest/xtest_test.c b/host/xtest/xtest_test.c
index 95f2ac8..a106ed0 100644
--- a/host/xtest/xtest_test.c
+++ b/host/xtest/xtest_test.c
@@ -19,6 +19,8 @@
 #include <ta_os_test.h>
 #include <ta_rpc_test.h>
 #include <ta_sims_test.h>
+#include <ta_miss_test.h>
+#include <ta_sims_keepalive_test.h>
 #include <ta_storage.h>
 #include <ta_concurrent.h>
 #include <ta_concurrent_large.h>
@@ -94,6 +96,8 @@
 const TEEC_UUID pta_invoke_tests_ta_uuid = PTA_INVOKE_TESTS_UUID;
 const TEEC_UUID rpc_test_ta_uuid = TA_RPC_TEST_UUID;
 const TEEC_UUID sims_test_ta_uuid = TA_SIMS_TEST_UUID;
+const TEEC_UUID miss_test_ta_uuid = TA_MISS_TEST_UUID;
+const TEEC_UUID sims_keepalive_test_ta_uuid = TA_SIMS_KEEP_ALIVE_TEST_UUID;
 const TEEC_UUID storage_ta_uuid = TA_STORAGE_UUID;
 const TEEC_UUID storage2_ta_uuid = TA_STORAGE2_UUID;
 const TEEC_UUID enc_fs_key_manager_test_ta_uuid = ENC_FS_KEY_MANAGER_TEST_UUID;
diff --git a/host/xtest/xtest_test.h b/host/xtest/xtest_test.h
index def35d9..df82bf3 100644
--- a/host/xtest/xtest_test.h
+++ b/host/xtest/xtest_test.h
@@ -103,6 +103,8 @@
 extern const TEEC_UUID create_fail_test_ta_uuid;
 extern const TEEC_UUID rpc_test_ta_uuid;
 extern const TEEC_UUID sims_test_ta_uuid;
+extern const TEEC_UUID miss_test_ta_uuid;
+extern const TEEC_UUID sims_keepalive_test_ta_uuid;
 extern const TEEC_UUID gp_tta_testing_client_api_uuid;
 extern const TEEC_UUID gp_tta_answer_success_to_open_session_invoke_uuid;
 extern const TEEC_UUID gp_tta_answer_error_to_invoke_uuid;
diff --git a/ta/CMakeLists.txt b/ta/CMakeLists.txt
index 795237e..7adcbe0 100644
--- a/ta/CMakeLists.txt
+++ b/ta/CMakeLists.txt
@@ -15,6 +15,8 @@
 	INTERFACE sdp_basic/include
 	INTERFACE sha_perf/include
 	INTERFACE sims/include
+	INTERFACE miss/include
+	INTERFACE sims_keepalive/include
 	INTERFACE socket/include
 	INTERFACE storage_benchmark/include
 )
diff --git a/ta/Makefile b/ta/Makefile
index 620169c..22d386f 100644
--- a/ta/Makefile
+++ b/ta/Makefile
@@ -24,6 +24,8 @@
 	   os_test \
 	   rpc_test \
 	   sims \
+	   miss \
+	   sims_keepalive \
 	   storage \
 	   storage2 \
 	   concurrent \
diff --git a/ta/miss/Android.mk b/ta/miss/Android.mk
new file mode 100644
index 0000000..fbfcf88
--- /dev/null
+++ b/ta/miss/Android.mk
@@ -0,0 +1,4 @@
+LOCAL_PATH := $(call my-dir)
+
+local_module := 528938ce-fc59-11e8-8eb2-f2801f1b9fd1
+include $(BUILD_OPTEE_MK)
diff --git a/ta/miss/Makefile b/ta/miss/Makefile
new file mode 100644
index 0000000..34fb718
--- /dev/null
+++ b/ta/miss/Makefile
@@ -0,0 +1,2 @@
+BINARY = 528938ce-fc59-11e8-8eb2-f2801f1b9fd1
+include ../ta_common.mk
diff --git a/ta/miss/include/ta_miss_test.h b/ta/miss/include/ta_miss_test.h
new file mode 100644
index 0000000..07d1a3d
--- /dev/null
+++ b/ta/miss/include/ta_miss_test.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2019, Mentor Graphics Corporation
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#ifndef TA_MISS_TEST_H
+#define TA_MISS_TEST_H
+
+/* This UUID is generated with uuidgen */
+#define TA_MISS_TEST_UUID { 0x528938ce, 0xfc59, 0x11e8, \
+	{ 0x8e, 0xb2, 0xf2, 0x80, 0x1f, 0x1b, 0x9f, 0xd1 } }
+
+#endif /* TA_MISS_TEST_H */
diff --git a/ta/miss/include/user_ta_header_defines.h b/ta/miss/include/user_ta_header_defines.h
new file mode 100644
index 0000000..73d0522
--- /dev/null
+++ b/ta/miss/include/user_ta_header_defines.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2019, Mentor Graphics Corporation
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#ifndef USER_TA_HEADER_DEFINES_H
+#define USER_TA_HEADER_DEFINES_H
+
+#include <ta_miss_test.h>
+
+#define TA_NAME		"MISS"
+#define TA_UUID		TA_MISS_TEST_UUID
+
+#define TA_FLAGS		(0UL)
+#define TA_STACK_SIZE		(32 * 1024)
+#define TA_DATA_SIZE		(32 * 1024)
+
+#endif /* USER_TA_HEADER_DEFINES_H */
diff --git a/ta/miss/sub.mk b/ta/miss/sub.mk
new file mode 100644
index 0000000..695892f
--- /dev/null
+++ b/ta/miss/sub.mk
@@ -0,0 +1,6 @@
+global-incdirs-y += include
+global-incdirs-y += ../sims/include
+global-incdirs-y += ../sims_keepalive/include
+
+srcs-y += ta_entry.c
+srcs-y += ta_miss.c
diff --git a/ta/miss/ta_entry.c b/ta/miss/ta_entry.c
new file mode 100644
index 0000000..304d952
--- /dev/null
+++ b/ta/miss/ta_entry.c
@@ -0,0 +1 @@
+#include "../sims/ta_entry.c"
diff --git a/ta/miss/ta_miss.c b/ta/miss/ta_miss.c
new file mode 100644
index 0000000..5006c64
--- /dev/null
+++ b/ta/miss/ta_miss.c
@@ -0,0 +1 @@
+#include "../sims/ta_sims.c"
diff --git a/ta/sims/sub.mk b/ta/sims/sub.mk
index b48e957..bbdeb62 100644
--- a/ta/sims/sub.mk
+++ b/ta/sims/sub.mk
@@ -1,3 +1,4 @@
 global-incdirs-y += include
+global-incdirs-y += ../sims_keepalive/include
 srcs-y += ta_entry.c
 srcs-y += ta_sims.c
diff --git a/ta/sims_keepalive/Android.mk b/ta/sims_keepalive/Android.mk
new file mode 100644
index 0000000..9ca1077
--- /dev/null
+++ b/ta/sims_keepalive/Android.mk
@@ -0,0 +1,4 @@
+LOCAL_PATH := $(call my-dir)
+
+local_module := a4c04d50-f180-11e8-8eb2-f2801f1b9fd1.ta
+include $(BUILD_OPTEE_MK)
diff --git a/ta/sims_keepalive/Makefile b/ta/sims_keepalive/Makefile
new file mode 100644
index 0000000..171f80d
--- /dev/null
+++ b/ta/sims_keepalive/Makefile
@@ -0,0 +1,2 @@
+BINARY = a4c04d50-f180-11e8-8eb2-f2801f1b9fd1
+include ../ta_common.mk
diff --git a/ta/sims_keepalive/include/ta_sims_keepalive_test.h b/ta/sims_keepalive/include/ta_sims_keepalive_test.h
new file mode 100644
index 0000000..01a829b
--- /dev/null
+++ b/ta/sims_keepalive/include/ta_sims_keepalive_test.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2019, Mentor Graphics Corporation
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#ifndef TA_SIMS_KEEP_ALIVE_TEST_H
+#define TA_SIMS_KEEP_ALIVE_TEST_H
+
+/* This UUID is generated with uuidgen */
+#define TA_SIMS_KEEP_ALIVE_TEST_UUID { 0xa4c04d50, 0xf180, 0x11e8, \
+	{ 0x8e, 0xb2, 0xf2, 0x80, 0x1f, 0x1b, 0x9f, 0xd1 } }
+
+#endif /* TA_SIMS_KEEP_ALIVE_TEST_H */
diff --git a/ta/sims_keepalive/include/user_ta_header_defines.h b/ta/sims_keepalive/include/user_ta_header_defines.h
new file mode 100644
index 0000000..e414a30
--- /dev/null
+++ b/ta/sims_keepalive/include/user_ta_header_defines.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2019, Mentor Graphics Corporation
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#ifndef USER_TA_HEADER_DEFINES_H
+#define USER_TA_HEADER_DEFINES_H
+
+#include <ta_sims_keepalive_test.h>
+
+#define TA_NAME		"SIMS_KEEPALIVE"
+#define TA_UUID		TA_SIMS_KEEP_ALIVE_TEST_UUID
+
+#define TA_FLAGS		(TA_FLAG_SINGLE_INSTANCE | \
+				TA_FLAG_MULTI_SESSION | \
+				TA_FLAG_INSTANCE_KEEP_ALIVE)
+#define TA_STACK_SIZE		(4 * 1024)
+#define TA_DATA_SIZE		(64 * 1024)
+
+#endif /* USER_TA_HEADER_DEFINES_H */
diff --git a/ta/sims_keepalive/sub.mk b/ta/sims_keepalive/sub.mk
new file mode 100644
index 0000000..acbd063
--- /dev/null
+++ b/ta/sims_keepalive/sub.mk
@@ -0,0 +1,6 @@
+global-incdirs-y += include
+global-incdirs-y += ../sims/include
+global-incdirs-y += ../sims_keepalive/include
+
+srcs-y += ta_entry.c
+srcs-y += ta_sims_keepalive.c
diff --git a/ta/sims_keepalive/ta_entry.c b/ta/sims_keepalive/ta_entry.c
new file mode 100644
index 0000000..304d952
--- /dev/null
+++ b/ta/sims_keepalive/ta_entry.c
@@ -0,0 +1 @@
+#include "../sims/ta_entry.c"
diff --git a/ta/sims_keepalive/ta_sims_keepalive.c b/ta/sims_keepalive/ta_sims_keepalive.c
new file mode 100644
index 0000000..5006c64
--- /dev/null
+++ b/ta/sims_keepalive/ta_sims_keepalive.c
@@ -0,0 +1 @@
+#include "../sims/ta_sims.c"