Multiple persistent object manipulation

xtest 6014 is introduced. It highlights an issue when persistent
objects are manipulated in a loop.
cf. https://github.com/OP-TEE/optee_os/issues/798

Signed-off-by: Pascal Brand <pascal.brand@st.com>
Reviewed-by: Joakim Bech <joakim.bech@linaro.org>
Tested-by: Joakim Bech <joakim.bech@linaro.org> (QEMU)
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
diff --git a/host/xtest/xtest_6000.c b/host/xtest/xtest_6000.c
index dacadff..0358a2b 100644
--- a/host/xtest/xtest_6000.c
+++ b/host/xtest/xtest_6000.c
@@ -1275,6 +1275,25 @@
 	TEEC_CloseSession(&sess);
 }
 
+static void xtest_tee_test_6014(ADBG_Case_t *c)
+{
+	TEEC_Session sess;
+	uint32_t orig;
+	TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
+
+	if (!ADBG_EXPECT_TEEC_SUCCESS(c,
+		xtest_teec_open_session(&sess, &storage_ta_uuid, NULL, &orig)))
+		return;
+
+	op.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE,
+					 TEEC_NONE, TEEC_NONE);
+
+	ADBG_EXPECT_TEEC_SUCCESS(c,
+		TEEC_InvokeCommand(&sess, TA_STORAGE_CMD_LOOP, &op, &orig));
+
+	TEEC_CloseSession(&sess);
+}
+
 ADBG_CASE_DEFINE(
 	XTEST_TEE_6001, xtest_tee_test_6001,
 	/* Title */
@@ -1432,3 +1451,15 @@
     /* How to implement */
     "Description of how to implement ..."
 );
+
+ADBG_CASE_DEFINE(
+    XTEST_TEE_6014, xtest_tee_test_6014,
+    /* Title */
+    "Loop on Persistent objects",
+    /* Short description */
+    "Short description ...",
+    /* Requirement IDs */
+    "TEE-??",
+    /* How to implement */
+    "Description of how to implement ..."
+);
diff --git a/host/xtest/xtest_main.c b/host/xtest/xtest_main.c
index e1f8d3b..88e5734 100644
--- a/host/xtest/xtest_main.c
+++ b/host/xtest/xtest_main.c
@@ -66,6 +66,7 @@
 #endif
 ADBG_SUITE_ENTRY(XTEST_TEE_6012, NULL)
 ADBG_SUITE_ENTRY(XTEST_TEE_6013, NULL)
+ADBG_SUITE_ENTRY(XTEST_TEE_6014, NULL)
 ADBG_SUITE_ENTRY(XTEST_TEE_7001, NULL)
 /* FVP    ADBG_SUITE_ENTRY(XTEST_TEE_7002, NULL) */
 ADBG_SUITE_ENTRY(XTEST_TEE_7003, NULL)
diff --git a/host/xtest/xtest_test.h b/host/xtest/xtest_test.h
index 8f2ac7f..f815335 100644
--- a/host/xtest/xtest_test.h
+++ b/host/xtest/xtest_test.h
@@ -61,6 +61,7 @@
 #endif
 ADBG_CASE_DECLARE(XTEST_TEE_6012);
 ADBG_CASE_DECLARE(XTEST_TEE_6013);
+ADBG_CASE_DECLARE(XTEST_TEE_6014);
 ADBG_CASE_DECLARE(XTEST_TEE_7001);
 ADBG_CASE_DECLARE(XTEST_TEE_7002);
 ADBG_CASE_DECLARE(XTEST_TEE_7003);
diff --git a/ta/storage/include/storage.h b/ta/storage/include/storage.h
index a736197..d5609d2 100644
--- a/ta/storage/include/storage.h
+++ b/ta/storage/include/storage.h
@@ -48,5 +48,6 @@
 TEE_Result ta_storage_cmd_next_enum(uint32_t param_types, TEE_Param params[4]);
 TEE_Result ta_storage_cmd_key_in_persistent(uint32_t param_types,
 					    TEE_Param params[4]);
+TEE_Result ta_storage_cmd_loop(uint32_t param_types, TEE_Param params[4]);
 
 #endif /*STORAGE_H */
diff --git a/ta/storage/include/ta_storage.h b/ta/storage/include/ta_storage.h
index ecaf541..abc6119 100644
--- a/ta/storage/include/ta_storage.h
+++ b/ta/storage/include/ta_storage.h
@@ -31,21 +31,22 @@
 #define TA_STORAGE_UUID { 0xb689f2a7, 0x8adf, 0x477a, \
 	{ 0x9f, 0x99, 0x32, 0xe9, 0x0c, 0x0a, 0xd0, 0xa2 } }
 
-#define TA_STORAGE_CMD_OPEN           0
-#define TA_STORAGE_CMD_CLOSE          1
-#define TA_STORAGE_CMD_READ           2
-#define TA_STORAGE_CMD_WRITE          3
-#define TA_STORAGE_CMD_CREATE         4
-#define TA_STORAGE_CMD_SEEK           5
-#define TA_STORAGE_CMD_UNLINK         6
-#define TA_STORAGE_CMD_RENAME         7
-#define TA_STORAGE_CMD_TRUNC          8
-#define TA_STORAGE_CMD_ALLOC_ENUM     9
-#define TA_STORAGE_CMD_FREE_ENUM      10
-#define TA_STORAGE_CMD_RESET_ENUM     11
-#define TA_STORAGE_CMD_START_ENUM     12
-#define TA_STORAGE_CMD_NEXT_ENUM      13
-#define TA_STORAGE_CMD_CREATE_OVERWRITE	14
-#define TA_STORAGE_CMD_KEY_IN_PERSISTENT 15
+#define TA_STORAGE_CMD_OPEN			0
+#define TA_STORAGE_CMD_CLOSE			1
+#define TA_STORAGE_CMD_READ			2
+#define TA_STORAGE_CMD_WRITE			3
+#define TA_STORAGE_CMD_CREATE			4
+#define TA_STORAGE_CMD_SEEK			5
+#define TA_STORAGE_CMD_UNLINK			6
+#define TA_STORAGE_CMD_RENAME			7
+#define TA_STORAGE_CMD_TRUNC			8
+#define TA_STORAGE_CMD_ALLOC_ENUM		9
+#define TA_STORAGE_CMD_FREE_ENUM		10
+#define TA_STORAGE_CMD_RESET_ENUM		11
+#define TA_STORAGE_CMD_START_ENUM		12
+#define TA_STORAGE_CMD_NEXT_ENUM		13
+#define TA_STORAGE_CMD_CREATE_OVERWRITE		14
+#define TA_STORAGE_CMD_KEY_IN_PERSISTENT	15
+#define TA_STORAGE_CMD_LOOP			16
 
 #endif /*TA_SKELETON_H */
diff --git a/ta/storage/storage.c b/ta/storage/storage.c
index 2be171e..db13466 100644
--- a/ta/storage/storage.c
+++ b/ta/storage/storage.c
@@ -388,3 +388,38 @@
 	return result;
 }
 
+TEE_Result ta_storage_cmd_loop(uint32_t param_types, TEE_Param params[4])
+{
+	TEE_ObjectHandle object = TEE_HANDLE_NULL;
+	TEE_Result res;
+	int object_id = 0;
+	uint32_t flags =  TEE_DATA_FLAG_OVERWRITE |
+			  TEE_DATA_FLAG_ACCESS_WRITE_META;
+	int i = 0;
+
+	(void)param_types;
+	(void)params;
+
+	for (i = 0; i < 20; i++) {
+		DMSG("\n\nLOOP : %d", i);
+		object = TEE_HANDLE_NULL;
+		object_id = i;
+		res = TEE_CreatePersistentObject(TEE_STORAGE_PRIVATE,
+						 &object_id, sizeof(int), flags,
+						 TEE_HANDLE_NULL, NULL, 0,
+						 &object);
+
+		if (res != TEE_SUCCESS) {
+			EMSG("FAIL");
+			return res;
+		}
+
+		res = TEE_CloseAndDeletePersistentObject1(object);
+		if (res != TEE_SUCCESS) {
+			EMSG("FAIL");
+			return res;
+		}
+	}
+
+	return TEE_SUCCESS;
+}
diff --git a/ta/storage/ta_entry.c b/ta/storage/ta_entry.c
index d2efd18..d3bfd0f 100644
--- a/ta/storage/ta_entry.c
+++ b/ta/storage/ta_entry.c
@@ -118,6 +118,9 @@
 	case TA_STORAGE_CMD_KEY_IN_PERSISTENT:
 		return ta_storage_cmd_key_in_persistent(nParamTypes, pParams);
 
+	case TA_STORAGE_CMD_LOOP:
+		return ta_storage_cmd_loop(nParamTypes, pParams);
+
 	default:
 		return TEE_ERROR_BAD_PARAMETERS;
 	}