Interface: Ensure veneer function result return in dispatch

The tfm_ns_interface_dispatch() function returns TFM_ERROR_GENERIC
when mutex operations fails.
However, this error code could be interrepted by the caller as
another status code or even valid return.

For example the psa_connect() of NS interface, it treats the value
of TFM_ERROR_GENERIC a valid handle.
And the psa_call() could treat TFM_ERROR_GENERIC as another status
code of the RoT service.
In both cases, the TFM_ERROR_GENERIC is translated incorrectly.

The tfm_ns_interface_dispatch() should only return status code from
the veneer function being called. Other unrecoverable errors should
be considered as fatal error and should not return.

Change-Id: Id4082a46cd866acaba85aa63d10cfe46d09b3044
Signed-off-by: Kevin Peng <kevin.peng@arm.com>
diff --git a/interface/include/tfm_ns_interface.h b/interface/include/tfm_ns_interface.h
index 21857be..1dd0692 100644
--- a/interface/include/tfm_ns_interface.h
+++ b/interface/include/tfm_ns_interface.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2017-2021, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -31,6 +31,10 @@
  * \param[in] arg3 Argument 3
  *
  * \return Returns the same return value of the requested veneer function
+ *
+ * \note This API must ensure the return value is from the veneer function.
+ *       Other unrecoverable errors must be considered as fatal error and should
+ *       not return.
  */
 int32_t tfm_ns_interface_dispatch(veneer_fn fn,
                                   uint32_t arg0, uint32_t arg1,
diff --git a/interface/src/tfm_ns_interface.c b/interface/src/tfm_ns_interface.c
index 7b01695..2f745c2 100644
--- a/interface/src/tfm_ns_interface.c
+++ b/interface/src/tfm_ns_interface.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2017-2021, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -25,16 +25,12 @@
     int32_t result;
 
     /* TFM request protected by NS lock */
-    if (os_wrapper_mutex_acquire(ns_lock_handle, OS_WRAPPER_WAIT_FOREVER)
-            != OS_WRAPPER_SUCCESS) {
-        return (int32_t)TFM_ERROR_GENERIC;
-    }
+    while (os_wrapper_mutex_acquire(ns_lock_handle, OS_WRAPPER_WAIT_FOREVER)
+            != OS_WRAPPER_SUCCESS);
 
     result = fn(arg0, arg1, arg2, arg3);
 
-    if (os_wrapper_mutex_release(ns_lock_handle) != OS_WRAPPER_SUCCESS) {
-        return (int32_t)TFM_ERROR_GENERIC;
-    }
+    while (os_wrapper_mutex_release(ns_lock_handle) != OS_WRAPPER_SUCCESS);
 
     return result;
 }