[PATCH v4 09/22] efi_loader: make MM transport selection runtime-safe

Harsimran Singh Tungal <[email protected]>
Newsgroups gmane.comp.boot-loaders.u-boot
Message-ID <[email protected]>
Track when ExitBootServices() has been called and make the MM transport
selection helper callable from EFI runtime code.

At runtime, select the FF-A transport only when FF-A runtime mode is
enabled. Otherwise keep using the OP-TEE MM communication path so builds
without CONFIG_ARM_FFA_RT_MODE do not lose their existing runtime
backend.

Reviewed-by: Simon Glass <[email protected]>
Reviewed-by: Abdellatif El Khlifi <[email protected]>
Signed-off-by: Harsimran Singh Tungal <[email protected]>
---
 lib/efi_loader/efi_variable_tee.c | 44 +++++++++++++++++++++++--------
 1 file changed, 33 insertions(+), 11 deletions(-)

diff --git a/lib/efi_loader/efi_variable_tee.c b/lib/efi_loader/efi_variable_tee.c
index 8a75da414f7..72055b36bba 100644
--- a/lib/efi_loader/efi_variable_tee.c
+++ b/lib/efi_loader/efi_variable_tee.c
@@ -56,12 +56,28 @@ extern struct efi_var_file __efi_runtime_data *efi_var_buf;
 static efi_uintn_t max_buffer_size;	/* comm + var + func + data */
 static efi_uintn_t max_payload_size;	/* func + data */
 static const u16 __efi_runtime_rodata pk[] = u"PK";
+static bool __efi_runtime_data ebs_called;
 
 struct mm_connection {
 	struct udevice *tee;
 	u32 session;
 };
 
+/**
+ * efi_at_runtime() - Indicate whether the system is in the UEFI runtime phase
+ *
+ * This helper returns whether the firmware has transitioned into the
+ * UEFI runtime phase, meaning that ExitBootServices() has been invoked.
+ *
+ * Return:
+ *   true  - The system is operating in UEFI runtime mode.
+ *   false - The system is still in the boot services phase.
+ */
+static bool __efi_runtime efi_at_runtime(void)
+{
+	return ebs_called;
+}
+
 /**
  * get_connection() - Retrieve OP-TEE session for a specific UUID.
  *
@@ -399,27 +415,30 @@ static efi_status_t ffa_mm_communicate(void *comm_buf, ulong comm_buf_size)
 /**
  * get_mm_comms() - detect the available MM transport
  *
- * Make sure the FF-A bus is probed successfully
- * which means FF-A communication with secure world works and ready
- * for use.
+ * Make sure the FF-A bus is probed successfully during the boot phase,
+ * which means FF-A communication with secure world works and is ready for
+ * use. During the runtime phase, use FF-A only when FF-A runtime mode is
+ * enabled; otherwise keep using OP-TEE comms.
  *
- * If FF-A bus is not ready, use OPTEE comms.
+ * If FF-A bus is not ready at boot, use OP-TEE comms.
  *
- * Return:
- *
- * MM_COMMS_FFA or MM_COMMS_OPTEE
+ * Return: MM_COMMS_FFA or MM_COMMS_OPTEE
  */
-static enum mm_comms_select get_mm_comms(void)
+static enum mm_comms_select __efi_runtime get_mm_comms(void)
 {
 	struct udevice *dev;
 	int ret;
 
-	ret = uclass_first_device_err(UCLASS_FFA, &dev);
-	if (ret) {
-		log_debug("EFI: Cannot find FF-A bus device, trying Optee comms\n");
+	if (efi_at_runtime()) {
+		if (IS_ENABLED(CONFIG_ARM_FFA_RT_MODE))
+			return MM_COMMS_FFA;
 		return MM_COMMS_OPTEE;
 	}
 
+	ret = uclass_first_device_err(UCLASS_FFA, &dev);
+	if (ret)
+		return MM_COMMS_OPTEE;
+
 	return MM_COMMS_FFA;
 }
 #endif
@@ -1018,6 +1037,9 @@ void efi_variables_boot_exit_notify(void)
 			efi_get_next_variable_name_runtime;
 	efi_runtime_services.set_variable = efi_set_variable_runtime;
 	efi_update_table_header_crc32(&efi_runtime_services.hdr);
+
+	/* Record that ExitBootServices() has been called */
+	ebs_called = true;
 }
 
 /**
-- 
2.34.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.