Forráskód Böngészése

Merge a7f959ccdbf7e268f52af6673434304164d59ec5 on remote branch

Change-Id: Iddf8054257035000f250e01bbfd5f80e4d1c7f9b
Linux Build Service Account 1 éve
szülő
commit
e8c4960c3f

+ 3 - 1
BUILD.bazel

@@ -73,6 +73,8 @@ ddk_headers(
     includes = [".", "smmu-proxy"],
 )
 
-load("pineapple.bzl", "define_pineapple")
+load(":build/pineapple.bzl", "define_pineapple")
+load(":build/blair.bzl", "define_blair")
 
 define_pineapple()
+define_blair()

+ 21 - 0
build/blair.bzl

@@ -0,0 +1,21 @@
+load(":securemsm_kernel.bzl", "define_consolidate_gki_modules")
+
+def define_blair():
+    define_consolidate_gki_modules(
+        target = "blair",
+        modules = [
+            "smcinvoke_dlkm",
+            "tz_log_dlkm",
+            "hdcp_qseecom_dlkm",
+            "qce50_dlkm",
+            "qcedev-mod_dlkm",
+            "qrng_dlkm",
+            "qcrypto-msm_dlkm",
+            "smmu_proxy_dlkm",
+            "qseecom_dlkm"
+        ],
+        extra_options = [
+            "CONFIG_QCOM_SMCINVOKE",
+            "CONFIG_QSEECOM",
+        ],
+    )

+ 0 - 0
pineapple.bzl → build/pineapple.bzl


+ 0 - 2
crypto-qti/qce50.c

@@ -3014,8 +3014,6 @@ static int _qce_sps_transfer(struct qce_device *pce_dev, int req_info)
 		pr_err("sps_xfr() fail (producer pipe=0x%lx) rc = %d\n",
 			(uintptr_t)pce_dev->ce_bam_info.producer[op].pipe, rc);
 ret:
-	if (rc)
-		_qce_dump_descr_fifos(pce_dev, req_info);
 	return rc;
 }
 

+ 82 - 31
include/linux/ITrustedCameraDriver.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
 /*
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include "smcinvoke_object.h"
@@ -21,59 +21,110 @@
  */
 
 typedef struct {
-  uint32_t version;
-  uint32_t protect;
-  uint32_t csid_hw_idx_mask;
-  uint32_t cdm_hw_idx_mask;
-  uint64_t vc_mask;
-  uint64_t phy_lane_sel_mask;
-  uint64_t reserved;
+	uint32_t version;
+	uint32_t protect;
+	uint32_t csid_hw_idx_mask;
+	uint32_t cdm_hw_idx_mask;
+	uint64_t vc_mask;
+	uint64_t phy_lane_sel_mask;
+	uint64_t reserved;
 } ITCDriverSensorInfo;
 
+#define ITrustedCameraDriver_ERROR_NOT_ALLOWED 10
+
 #define ITrustedCameraDriver_OP_dynamicProtectSensor 0
 #define ITrustedCameraDriver_OP_getVersion 1
+#define ITrustedCameraDriver_OP_dynamicConfigureFDPort 3
 
 static inline int32_t
 ITrustedCameraDriver_release(struct Object self)
 {
-  return Object_invoke(self, Object_OP_release, 0, 0);
+	return Object_invoke(self, Object_OP_release, 0, 0);
 }
 
 static inline int32_t
 ITrustedCameraDriver_retain(struct Object self)
 {
-  return Object_invoke(self, Object_OP_retain, 0, 0);
+	return Object_invoke(self, Object_OP_retain, 0, 0);
 }
 
+/*
+ * Description: This method allows protecting a camera sensor based on the sensor
+ *              information provided.
+ *
+ * In:          this - ITrustedCameraDriver object
+ * In:          phy_info_ptr - Camera HW settings required for securing the usecase
+ * Out:         void
+ * Return:      Object_OK on success
+ *              secure camera error codes from seccam_def on failure
+ */
+
 static inline int32_t
-ITrustedCameraDriver_dynamicProtectSensor(struct Object self, const ITCDriverSensorInfo *phy_info_ptr)
+ITrustedCameraDriver_dynamicProtectSensor(struct Object self,
+		const ITCDriverSensorInfo *phy_info_ptr)
 {
-  union ObjectArg a[1]={{{0,0}}};
-  a[0].bi = (struct ObjectBufIn) { phy_info_ptr, sizeof(ITCDriverSensorInfo) };
+	union ObjectArg a[1] = {{{0, 0}}};
+
+	a[0].bi = (struct ObjectBufIn) { phy_info_ptr, sizeof(ITCDriverSensorInfo) };
 
-  return Object_invoke(self, ITrustedCameraDriver_OP_dynamicProtectSensor, a, ObjectCounts_pack(1, 0, 0, 0));
+	return Object_invoke(self, ITrustedCameraDriver_OP_dynamicProtectSensor, a,
+			ObjectCounts_pack(1, 0, 0, 0));
 }
 
+/*
+ * Description: Get the current version info
+ *
+ * In:         this - ITrustedCameraDriver object
+ * Out:        arch_ver_ptr - the pointer of arch version number.
+ * Out:        max_ver_ptr -  the pointer of the second part of the version number
+ * Out:        min_ver_ptr -  the pointer of the third part of the version number
+ * Return:     Object_OK on success
+ */
+
 static inline int32_t
-ITrustedCameraDriver_getVersion(struct Object self, uint32_t *arch_ver_ptr, uint32_t *max_ver_ptr, uint32_t *min_ver_ptr)
+ITrustedCameraDriver_getVersion(struct Object self, uint32_t *arch_ver_ptr,
+		uint32_t *max_ver_ptr, uint32_t *min_ver_ptr)
 {
-  union ObjectArg a[1]={{{0,0}}};
-  int32_t result;
-  struct {
-    uint32_t m_arch_ver;
-    uint32_t m_max_ver;
-    uint32_t m_min_ver;
-  } o = {0};
-  a[0].b = (struct ObjectBuf) { &o, 12 };
-
-  result = Object_invoke(self, ITrustedCameraDriver_OP_getVersion, a, ObjectCounts_pack(0, 1, 0, 0));
-
-  *arch_ver_ptr = o.m_arch_ver;
-  *max_ver_ptr = o.m_max_ver;
-  *min_ver_ptr = o.m_min_ver;
-
-  return result;
+	union ObjectArg a[1] = {{{0, 0}}};
+	int32_t result;
+	struct {
+		uint32_t m_arch_ver;
+		uint32_t m_max_ver;
+		uint32_t m_min_ver;
+	} o = {0};
+
+	a[0].b = (struct ObjectBuf) { &o, 12 };
+
+	result = Object_invoke(self, ITrustedCameraDriver_OP_getVersion, a,
+			ObjectCounts_pack(0, 1, 0, 0));
+
+	*arch_ver_ptr = o.m_arch_ver;
+	*max_ver_ptr = o.m_max_ver;
+	*min_ver_ptr = o.m_min_ver;
+
+	return result;
 }
 
+/*
+ * Description: Dynamic configuration to allow secure/non-secure FD port
+ *              on all the CSIDs
+ *
+ * In:          this - ITrustedCameraDriver object
+ * In:          protect - to secure or non-secure the port
+ * Out:         void
+ * Return:      Object_OK on success
+ *              Object_ERROR on failure
+ *              ITrustedCameraDriver_ERROR_NOT_ALLOWED on request to
+ *              configure FD port even when disabled by OEM
+ */
+
+static inline int32_t
+ITrustedCameraDriver_dynamicConfigureFDPort(struct Object self, uint32_t protect)
+{
+	union ObjectArg a[1] = {{{0, 0}}};
 
+	a[0].b = (struct ObjectBuf) { &protect, sizeof(uint32_t) };
 
+	return Object_invoke(self, ITrustedCameraDriver_OP_dynamicConfigureFDPort, a,
+			ObjectCounts_pack(1, 0, 0, 0));
+}

+ 17 - 6
qseecom/qseecom.c

@@ -333,6 +333,7 @@ struct qseecom_control {
 	bool  whitelist_support;
 	bool  commonlib_loaded;
 	bool  commonlib64_loaded;
+	bool  commonlib_loaded_by_hostvm;
 	struct ce_hw_usage_info ce_info;
 
 	int qsee_bw_count;
@@ -2772,7 +2773,8 @@ static int qseecom_load_app(struct qseecom_dev_handle *data, void __user *argp)
 
 	/* Check and load cmnlib */
 	if (qseecom.qsee_version > QSEEE_VERSION_00) {
-		if (!qseecom.commonlib_loaded &&
+		if (!(qseecom.commonlib_loaded ||
+				qseecom.commonlib_loaded_by_hostvm) &&
 				load_img_req.app_arch == ELFCLASS32) {
 			ret = qseecom_load_commonlib_image(data, "cmnlib");
 			if (ret) {
@@ -2783,7 +2785,8 @@ static int qseecom_load_app(struct qseecom_dev_handle *data, void __user *argp)
 			pr_debug("cmnlib is loaded\n");
 		}
 
-		if (!qseecom.commonlib64_loaded &&
+		if (!(qseecom.commonlib64_loaded ||
+				qseecom.commonlib_loaded_by_hostvm) &&
 				load_img_req.app_arch == ELFCLASS64) {
 			ret = qseecom_load_commonlib_image(data, "cmnlib64");
 			if (ret) {
@@ -4748,7 +4751,9 @@ static int __qseecom_load_fw(struct qseecom_dev_handle *data, char *appname,
 
 	/* Check and load cmnlib */
 	if (qseecom.qsee_version > QSEEE_VERSION_00) {
-		if (!qseecom.commonlib_loaded && app_arch == ELFCLASS32) {
+		if (!(qseecom.commonlib_loaded ||
+				qseecom.commonlib_loaded_by_hostvm) &&
+				app_arch == ELFCLASS32) {
 			ret = qseecom_load_commonlib_image(data, "cmnlib");
 			if (ret) {
 				pr_err("failed to load cmnlib\n");
@@ -4758,7 +4763,9 @@ static int __qseecom_load_fw(struct qseecom_dev_handle *data, char *appname,
 			pr_debug("cmnlib is loaded\n");
 		}
 
-		if (!qseecom.commonlib64_loaded && app_arch == ELFCLASS64) {
+		if (!(qseecom.commonlib64_loaded ||
+				qseecom.commonlib_loaded_by_hostvm) &&
+				app_arch == ELFCLASS64) {
 			ret = qseecom_load_commonlib_image(data, "cmnlib64");
 			if (ret) {
 				pr_err("failed to load cmnlib64\n");
@@ -6511,7 +6518,7 @@ static int qseecom_create_key(struct qseecom_dev_handle *data,
 	struct qseecom_create_key_req create_key_req;
 	struct qseecom_key_generate_ireq generate_key_ireq;
 	struct qseecom_key_select_ireq set_key_ireq;
-	uint32_t entries = 0;
+	int32_t entries = 0;
 
 	ret = copy_from_user(&create_key_req, argp, sizeof(create_key_req));
 	if (ret) {
@@ -6656,7 +6663,7 @@ static int qseecom_wipe_key(struct qseecom_dev_handle *data,
 	struct qseecom_wipe_key_req wipe_key_req;
 	struct qseecom_key_delete_ireq delete_key_ireq;
 	struct qseecom_key_select_ireq clear_key_ireq;
-	uint32_t entries = 0;
+	int32_t entries = 0;
 
 	ret = copy_from_user(&wipe_key_req, argp, sizeof(wipe_key_req));
 	if (ret) {
@@ -9376,6 +9383,7 @@ static int qseecom_init_control(void)
 	qseecom.qseos_version = QSEOS_VERSION_14;
 	qseecom.commonlib_loaded = false;
 	qseecom.commonlib64_loaded = false;
+	qseecom.commonlib_loaded_by_hostvm = false;
 	qseecom.whitelist_support = qseecom_check_whitelist_feature();
 
 	return rc;
@@ -9397,6 +9405,9 @@ static int qseecom_parse_dt(struct platform_device *pdev)
 	qseecom.commonlib64_loaded =
 			of_property_read_bool((&pdev->dev)->of_node,
 			"qcom,commonlib64-loaded-by-uefi");
+	qseecom.commonlib_loaded_by_hostvm =
+			of_property_read_bool((&pdev->dev)->of_node,
+			"qcom,commonlib-loaded-by-hostvm");
 	qseecom.fde_key_size =
 			of_property_read_bool((&pdev->dev)->of_node,
 			"qcom,fde-key-size");

+ 19 - 10
securemsm_kernel_product_board.mk

@@ -1,27 +1,36 @@
 #Build ssg kernel driver
-ENABLE_SECUREMSM_DLKM := false
-ifeq ($(TARGET_KERNEL_DLKM_DISABLE), true)
-ifeq ($(TARGET_KERNEL_DLKM_SECURE_MSM_OVERRIDE), true)
-ENABLE_SECUREMSM_DLKM := true
-endif
-else
+
 ENABLE_SECUREMSM_DLKM := true
+ENABLE_SECUREMSM_QTEE_DLKM := true
+
+ifeq ($(TARGET_KERNEL_DLKM_DISABLE), true)
+  ifeq ($(TARGET_KERNEL_DLKM_SECURE_MSM_OVERRIDE), false)
+      ENABLE_SECUREMSM_DLKM := false
+  endif
+  ifeq ($(TARGET_KERNEL_DLKM_SECUREMSM_QTEE_OVERRIDE), false)
+      ENABLE_SECUREMSM_QTEE_DLKM := false
+  endif
 endif
 
 ifeq ($(ENABLE_SECUREMSM_DLKM), true)
-PRODUCT_PACKAGES += tz_log_dlkm.ko
 PRODUCT_PACKAGES += qcedev-mod_dlkm.ko
 PRODUCT_PACKAGES += qce50_dlkm.ko
 PRODUCT_PACKAGES += qcrypto-msm_dlkm.ko
 PRODUCT_PACKAGES += hdcp_qseecom_dlkm.ko
 PRODUCT_PACKAGES += qrng_dlkm.ko
-PRODUCT_PACKAGES += smcinvoke_dlkm.ko
-PRODUCT_PACKAGES += qseecom_dlkm.ko
 
 ifeq ($(TARGET_USES_SMMU_PROXY), true)
 PRODUCT_PACKAGES += smmu_proxy_dlkm.ko
 endif
-
 endif #ENABLE_SECUREMSM_DLKM
 
+ifeq ($(ENABLE_SECUREMSM_QTEE_DLKM), true)
+PRODUCT_PACKAGES += smcinvoke_dlkm.ko
+PRODUCT_PACKAGES += tz_log_dlkm.ko
+#Enable Qseecom if TARGET_ENABLE_QSEECOM or TARGET_BOARD_AUTO is set to true
+ifneq (, $(filter true, $(TARGET_ENABLE_QSEECOM) $(TARGET_BOARD_AUTO)))
+PRODUCT_PACKAGES += qseecom_dlkm.ko
+endif #TARGET_ENABLE_QSEECOM OR TARGET_BOARD_AUTO
+endif #ENABLE_SECUREMSM_QTEE_DLKM
+
 

+ 23 - 17
securemsm_kernel_vendor_board.mk

@@ -1,27 +1,37 @@
-ENABLE_SECUREMSM_DLKM := false
+ENABLE_SECUREMSM_DLKM := true
+ENABLE_SECUREMSM_QTEE_DLKM := true
 
 ifeq ($(TARGET_KERNEL_DLKM_DISABLE), true)
-ifeq ($(TARGET_KERNEL_DLKM_SECURE_MSM_OVERRIDE), true)
-ENABLE_SECUREMSM_DLKM := true
+  ifeq ($(TARGET_KERNEL_DLKM_SECURE_MSM_OVERRIDE), false)
+      ENABLE_SECUREMSM_DLKM := false
+  endif
+  ifeq ($(TARGET_KERNEL_DLKM_SECUREMSM_QTEE_OVERRIDE), false)
+      ENABLE_SECUREMSM_QTEE_DLKM := false
+  endif
 endif
-else
-ENABLE_SECUREMSM_DLKM := true
-endif
-
 
 ifeq ($(ENABLE_SECUREMSM_DLKM), true)
-BOARD_VENDOR_KERNEL_MODULES += $(KERNEL_MODULES_OUT)/tz_log_dlkm.ko \
-      $(KERNEL_MODULES_OUT)/qcedev-mod_dlkm.ko \
+BOARD_VENDOR_KERNEL_MODULES += $(KERNEL_MODULES_OUT)/qcedev-mod_dlkm.ko \
       $(KERNEL_MODULES_OUT)/qcrypto-msm_dlkm.ko \
       $(KERNEL_MODULES_OUT)/qce50_dlkm.ko \
       $(KERNEL_MODULES_OUT)/hdcp_qseecom_dlkm.ko \
       $(KERNEL_MODULES_OUT)/qrng_dlkm.ko \
 
+BOARD_VENDOR_RAMDISK_KERNEL_MODULES += $(KERNEL_MODULES_OUT)/hdcp_qseecom_dlkm.ko
+
+ifeq ($(TARGET_USES_SMMU_PROXY), true)
+BOARD_VENDOR_KERNEL_MODULES += $(KERNEL_MODULES_OUT)/smmu_proxy_dlkm.ko
+endif
+endif #ENABLE_SECUREMSM_DLKM
+
+ifeq ($(ENABLE_SECUREMSM_QTEE_DLKM), true)
+
+BOARD_VENDOR_KERNEL_MODULES += $(KERNEL_MODULES_OUT)/smcinvoke_dlkm.ko \
+			       $(KERNEL_MODULES_OUT)/tz_log_dlkm.ko \
+
 BOARD_VENDOR_RAMDISK_KERNEL_MODULES += $(KERNEL_MODULES_OUT)/tz_log_dlkm.ko \
-      $(KERNEL_MODULES_OUT)/hdcp_qseecom_dlkm.ko \
+                                       $(KERNEL_MODULES_OUT)/smcinvoke_dlkm.ko \
 
-BOARD_VENDOR_KERNEL_MODULES += $(KERNEL_MODULES_OUT)/smcinvoke_dlkm.ko
-BOARD_VENDOR_RAMDISK_KERNEL_MODULES += $(KERNEL_MODULES_OUT)/smcinvoke_dlkm.ko
 BOARD_VENDOR_RAMDISK_RECOVERY_KERNEL_MODULES_LOAD += $(KERNEL_MODULES_OUT)/smcinvoke_dlkm.ko
 
 
@@ -29,8 +39,4 @@ BOARD_VENDOR_KERNEL_MODULES += $(KERNEL_MODULES_OUT)/qseecom_dlkm.ko
 BOARD_VENDOR_RAMDISK_KERNEL_MODULES += $(KERNEL_MODULES_OUT)/qseecom_dlkm.ko
 BOARD_VENDOR_RAMDISK_RECOVERY_KERNEL_MODULES_LOAD += $(KERNEL_MODULES_OUT)/qseecom_dlkm.ko
 
-ifeq ($(TARGET_USES_SMMU_PROXY), true)
-BOARD_VENDOR_KERNEL_MODULES += $(KERNEL_MODULES_OUT)/smmu_proxy_dlkm.ko
-endif
-
-endif #ENABLE_SECUREMSM_DLKM
+endif #ENABLE_SECUREMSM_QTEE_DLKM

+ 1 - 109
smcinvoke/smcinvoke.c

@@ -213,7 +213,7 @@ static const struct file_operations g_smcinvoke_fops = {
 static dev_t smcinvoke_device_no;
 static struct cdev smcinvoke_cdev;
 static struct class *driver_class;
-static struct device *class_dev;
+struct device *class_dev;
 static struct platform_device *smcinvoke_pdev;
 
 /* We disable async memory object support by default,
@@ -2939,114 +2939,6 @@ int process_invoke_request_from_kernel_client(int fd,
 	return ret;
 }
 
-char *firmware_request_from_smcinvoke(const char *appname, size_t *fw_size, struct qtee_shm *shm)
-{
-
-	int rc = 0;
-	const struct firmware *fw_entry = NULL, *fw_entry00 = NULL, *fw_entrylast = NULL;
-	char fw_name[MAX_APP_NAME_SIZE] = "\0";
-	int num_images = 0, phi = 0;
-	unsigned char app_arch = 0;
-	u8 *img_data_ptr = NULL;
-	size_t bufferOffset = 0, phdr_table_offset = 0;
-	size_t *offset = NULL;
-	Elf32_Phdr phdr32;
-	Elf64_Phdr phdr64;
-	struct elf32_hdr *ehdr = NULL;
-	struct elf64_hdr *ehdr64 = NULL;
-
-
-	/* load b00*/
-	snprintf(fw_name, sizeof(fw_name), "%s.b00", appname);
-	rc = firmware_request_nowarn(&fw_entry00, fw_name, class_dev);
-	if (rc) {
-		pr_err("Load %s failed, ret:%d\n", fw_name, rc);
-		return NULL;
-	}
-
-	app_arch = *(unsigned char *)(fw_entry00->data + EI_CLASS);
-
-	/*Get the offsets for split images header*/
-	if (app_arch == ELFCLASS32) {
-
-		ehdr = (struct elf32_hdr *)fw_entry00->data;
-		num_images = ehdr->e_phnum;
-		offset = kcalloc(num_images, sizeof(size_t), GFP_KERNEL);
-		if (offset == NULL)
-			goto release_fw_entry00;
-		phdr_table_offset = (size_t) ehdr->e_phoff;
-		for (phi = 1; phi < num_images; ++phi) {
-			bufferOffset = phdr_table_offset + phi * sizeof(Elf32_Phdr);
-			phdr32 = *(Elf32_Phdr *)(fw_entry00->data + bufferOffset);
-			offset[phi] = (size_t)phdr32.p_offset;
-		}
-
-	} else if (app_arch == ELFCLASS64) {
-
-		ehdr64 = (struct elf64_hdr *)fw_entry00->data;
-		num_images = ehdr64->e_phnum;
-		offset = kcalloc(num_images, sizeof(size_t), GFP_KERNEL);
-		if (offset == NULL)
-			goto release_fw_entry00;
-		phdr_table_offset = (size_t) ehdr64->e_phoff;
-		for (phi = 1; phi < num_images; ++phi) {
-			bufferOffset = phdr_table_offset + phi * sizeof(Elf64_Phdr);
-			phdr64 = *(Elf64_Phdr *)(fw_entry00->data + bufferOffset);
-			offset[phi] = (size_t)phdr64.p_offset;
-		}
-
-	} else {
-
-		pr_err("QSEE %s app, arch %u is not supported\n", appname, app_arch);
-		goto release_fw_entry00;
-	}
-
-	/*Find the size of last split bin image*/
-	snprintf(fw_name, ARRAY_SIZE(fw_name), "%s.b%02d", appname, num_images-1);
-	rc = firmware_request_nowarn(&fw_entrylast, fw_name, class_dev);
-	if (rc) {
-		pr_err("Failed to locate blob %s\n", fw_name);
-		goto release_fw_entry00;
-	}
-
-	/*Total size of image will be the offset of last image + the size of last split image*/
-	*fw_size = fw_entrylast->size + offset[num_images-1];
-
-	/*Allocate memory for the buffer that will hold the split image*/
-	rc = qtee_shmbridge_allocate_shm((*fw_size), shm);
-	if (rc) {
-		pr_err("smbridge alloc failed for size: %zu\n", *fw_size);
-		goto release_fw_entrylast;
-	}
-	img_data_ptr = shm->vaddr;
-	/*
-	 * Copy contents of split bins to the buffer
-	 */
-	memcpy(img_data_ptr, fw_entry00->data, fw_entry00->size);
-	for (phi = 1; phi < num_images-1; phi++) {
-		snprintf(fw_name, ARRAY_SIZE(fw_name), "%s.b%02d", appname, phi);
-		rc = firmware_request_nowarn(&fw_entry, fw_name, class_dev);
-		if (rc) {
-			pr_err("Failed to locate blob %s\n", fw_name);
-			qtee_shmbridge_free_shm(shm);
-			img_data_ptr = NULL;
-			goto release_fw_entrylast;
-		}
-		memcpy(img_data_ptr + offset[phi], fw_entry->data, fw_entry->size);
-		release_firmware(fw_entry);
-		fw_entry = NULL;
-	}
-	memcpy(img_data_ptr + offset[phi], fw_entrylast->data, fw_entrylast->size);
-
-release_fw_entrylast:
-	release_firmware(fw_entrylast);
-release_fw_entry00:
-	release_firmware(fw_entry00);
-	kfree(offset);
-	return img_data_ptr;
-}
-EXPORT_SYMBOL(firmware_request_from_smcinvoke);
-
 static int smcinvoke_open(struct inode *nodp, struct file *filp)
 {
 	struct smcinvoke_file_data *tzcxt = NULL;

+ 116 - 4
smcinvoke/smcinvoke_kernel.c

@@ -27,7 +27,11 @@
 #endif
 #endif
 
+#define MAX_FW_APP_SIZE	256		//Application name size.
+#define FILE_EXT_SIZE	5		//File extension like .mbn etc
+
 const uint32_t CQSEEComCompatAppLoader_UID = 122;
+extern struct device *class_dev;
 
 struct qseecom_compat_context {
 	void *dev; /* in/out */
@@ -330,13 +334,13 @@ static int load_app(struct qseecom_compat_context *cxt, const char *app_name)
 	size_t fw_size = 0;
 	u8 *imgbuf_va = NULL;
 	int ret = 0;
-	char dist_name[MAX_APP_NAME_SIZE] = {0};
+	char dist_name[MAX_FW_APP_SIZE] = {0};
 	size_t dist_name_len = 0;
 	struct qtee_shm shm = {0};
 
-	if (strnlen(app_name, MAX_APP_NAME_SIZE) == MAX_APP_NAME_SIZE) {
+	if (strnlen(app_name, MAX_FW_APP_SIZE) == MAX_FW_APP_SIZE) {
 		pr_err("The app_name (%s) with length %zu is not valid\n",
-			app_name, strnlen(app_name, MAX_APP_NAME_SIZE));
+			app_name, strnlen(app_name, MAX_FW_APP_SIZE));
 		return -EINVAL;
 	}
 
@@ -356,7 +360,7 @@ static int load_app(struct qseecom_compat_context *cxt, const char *app_name)
 	ret = IQSEEComCompatAppLoader_loadFromBuffer(
 			cxt->app_loader, imgbuf_va, fw_size,
 			app_name, strlen(app_name),
-			dist_name, MAX_APP_NAME_SIZE, &dist_name_len,
+			dist_name, MAX_FW_APP_SIZE, &dist_name_len,
 			&cxt->app_controller);
 	if (ret) {
 		pr_err("loadFromBuffer failed for app %s, ret = %d\n",
@@ -525,3 +529,111 @@ EXPORT_SYMBOL(qseecom_send_command);
 #endif
 
 #endif
+
+char *firmware_request_from_smcinvoke(const char *appname, size_t *fw_size, struct qtee_shm *shm)
+{
+
+	int rc = 0;
+	const struct firmware *fw_entry = NULL, *fw_entry00 = NULL, *fw_entrylast = NULL;
+	char fw_name[MAX_FW_APP_SIZE + FILE_EXT_SIZE] = "\0";
+	int num_images = 0, phi = 0;
+	unsigned char app_arch = 0;
+	u8 *img_data_ptr = NULL;
+	size_t bufferOffset = 0, phdr_table_offset = 0;
+	size_t *offset = NULL;
+	Elf32_Phdr phdr32;
+	Elf64_Phdr phdr64;
+	struct elf32_hdr *ehdr = NULL;
+	struct elf64_hdr *ehdr64 = NULL;
+
+
+	/* load b00*/
+	snprintf(fw_name, sizeof(fw_name), "%s.b00", appname);
+	rc = firmware_request_nowarn(&fw_entry00, fw_name, class_dev);
+	if (rc) {
+		pr_err("Load %s failed, ret:%d\n", fw_name, rc);
+		return NULL;
+	}
+
+	app_arch = *(unsigned char *)(fw_entry00->data + EI_CLASS);
+
+	/*Get the offsets for split images header*/
+	if (app_arch == ELFCLASS32) {
+
+		ehdr = (struct elf32_hdr *)fw_entry00->data;
+		num_images = ehdr->e_phnum;
+		offset = kcalloc(num_images, sizeof(size_t), GFP_KERNEL);
+		if (offset == NULL)
+			goto release_fw_entry00;
+		phdr_table_offset = (size_t) ehdr->e_phoff;
+		for (phi = 1; phi < num_images; ++phi) {
+			bufferOffset = phdr_table_offset + phi * sizeof(Elf32_Phdr);
+			phdr32 = *(Elf32_Phdr *)(fw_entry00->data + bufferOffset);
+			offset[phi] = (size_t)phdr32.p_offset;
+		}
+
+	} else if (app_arch == ELFCLASS64) {
+
+		ehdr64 = (struct elf64_hdr *)fw_entry00->data;
+		num_images = ehdr64->e_phnum;
+		offset = kcalloc(num_images, sizeof(size_t), GFP_KERNEL);
+		if (offset == NULL)
+			goto release_fw_entry00;
+		phdr_table_offset = (size_t) ehdr64->e_phoff;
+		for (phi = 1; phi < num_images; ++phi) {
+			bufferOffset = phdr_table_offset + phi * sizeof(Elf64_Phdr);
+			phdr64 = *(Elf64_Phdr *)(fw_entry00->data + bufferOffset);
+			offset[phi] = (size_t)phdr64.p_offset;
+		}
+
+	} else {
+
+		pr_err("QSEE %s app, arch %u is not supported\n", appname, app_arch);
+		goto release_fw_entry00;
+	}
+
+	/*Find the size of last split bin image*/
+	snprintf(fw_name, ARRAY_SIZE(fw_name), "%s.b%02d", appname, num_images-1);
+	rc = firmware_request_nowarn(&fw_entrylast, fw_name, class_dev);
+	if (rc) {
+		pr_err("Failed to locate blob %s\n", fw_name);
+		goto release_fw_entry00;
+	}
+
+	/*Total size of image will be the offset of last image + the size of last split image*/
+	*fw_size = fw_entrylast->size + offset[num_images-1];
+
+	/*Allocate memory for the buffer that will hold the split image*/
+	rc = qtee_shmbridge_allocate_shm((*fw_size), shm);
+	if (rc) {
+		pr_err("smbridge alloc failed for size: %zu\n", *fw_size);
+		goto release_fw_entrylast;
+	}
+	img_data_ptr = shm->vaddr;
+	/*
+	 * Copy contents of split bins to the buffer
+	 */
+	memcpy(img_data_ptr, fw_entry00->data, fw_entry00->size);
+	for (phi = 1; phi < num_images-1; phi++) {
+		snprintf(fw_name, ARRAY_SIZE(fw_name), "%s.b%02d", appname, phi);
+		rc = firmware_request_nowarn(&fw_entry, fw_name, class_dev);
+		if (rc) {
+			pr_err("Failed to locate blob %s\n", fw_name);
+			qtee_shmbridge_free_shm(shm);
+			img_data_ptr = NULL;
+			goto release_fw_entrylast;
+		}
+		memcpy(img_data_ptr + offset[phi], fw_entry->data, fw_entry->size);
+		release_firmware(fw_entry);
+		fw_entry = NULL;
+	}
+	memcpy(img_data_ptr + offset[phi], fw_entrylast->data, fw_entrylast->size);
+
+release_fw_entrylast:
+	release_firmware(fw_entrylast);
+release_fw_entry00:
+	release_firmware(fw_entry00);
+	kfree(offset);
+	return img_data_ptr;
+}
+EXPORT_SYMBOL(firmware_request_from_smcinvoke);

+ 126 - 23
tz_log/tz_log.c

@@ -3,6 +3,9 @@
  * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
  * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
+
+#define pr_fmt(fmt) "%s:[%s][%d]: " fmt, KBUILD_MODNAME, __func__, __LINE__
+
 #include <linux/debugfs.h>
 #include <linux/errno.h>
 #include <linux/delay.h>
@@ -21,6 +24,10 @@
 #include <linux/qtee_shmbridge.h>
 #include <linux/proc_fs.h>
 #include <linux/version.h>
+#if IS_ENABLED(CONFIG_MSM_TMECOM_QMP)
+#include <linux/tmelog.h>
+#endif
+
 #include "misc/qseecomi.h"
 
 /* QSEE_LOG_BUF_SIZE = 32K */
@@ -29,6 +36,9 @@
 /* enlarged qsee log buf size is 128K by default */
 #define QSEE_LOG_BUF_SIZE_V2 0x20000
 
+/* Tme log buffer size 20K */
+#define TME_LOG_BUF_SIZE 0x5000
+
 /* TZ Diagnostic Area legacy version number */
 #define TZBSP_DIAG_MAJOR_VERSION_LEGACY	2
 
@@ -376,6 +386,11 @@ struct hypdbg_t {
 	uint8_t log_buf_p[];
 };
 
+struct tme_log_pos {
+	uint32_t offset;
+	size_t size;
+};
+
 /*
  * Enumeration order for VMID's
  */
@@ -390,6 +405,7 @@ enum tzdbg_stats_type {
 	TZDBG_HYP_GENERAL,
 	TZDBG_HYP_LOG,
 	TZDBG_RM_LOG,
+	TZDBG_TME_LOG,
 	TZDBG_STATS_MAX
 };
 
@@ -398,15 +414,18 @@ struct tzdbg_stat {
 	size_t display_offset;
 	char *name;
 	char *data;
+	bool avail;
 };
 
 struct tzdbg {
 	void __iomem *virt_iobase;
 	void __iomem *hyp_virt_iobase;
 	void __iomem *rmlog_virt_iobase;
+	void __iomem *tmelog_virt_iobase;
 	struct tzdbg_t *diag_buf;
 	struct hypdbg_t *hyp_diag_buf;
 	uint8_t *rm_diag_buf;
+	uint8_t *tme_buf;
 	char *disp_buf;
 	int debug_tz[TZDBG_STATS_MAX];
 	struct tzdbg_stat stat[TZDBG_STATS_MAX];
@@ -459,6 +478,7 @@ static struct tzdbg tzdbg = {
 	.stat[TZDBG_HYP_GENERAL].name = "hyp_general",
 	.stat[TZDBG_HYP_LOG].name = "hyp_log",
 	.stat[TZDBG_RM_LOG].name = "rm_log",
+	.stat[TZDBG_TME_LOG].name = "tme_log",
 };
 
 static struct tzdbg_log_t *g_qsee_log;
@@ -468,6 +488,7 @@ static uint32_t debug_rw_buf_size;
 static uint32_t display_buf_size;
 static uint32_t qseelog_buf_size;
 static phys_addr_t disp_buf_paddr;
+static uint32_t tmecrashdump_address_offset;
 
 static uint64_t qseelog_shmbridge_handle;
 static struct encrypted_log_info enc_qseelog_info;
@@ -1176,6 +1197,61 @@ static int _disp_hyp_general_stats(size_t count)
 	return len;
 }
 
+#if IS_ENABLED(CONFIG_MSM_TMECOM_QMP)
+static int _disp_tme_log_stats(size_t count)
+{
+	static struct tme_log_pos log_start = { 0 };
+	static bool wrap_around = { false };
+	uint32_t buf_size;
+	uint8_t *log_ptr = NULL;
+	uint32_t log_len = 0;
+	int ret = 0;
+
+	/* Return 0 to close the display file */
+	if ((log_start.size == 0x0) && wrap_around) {
+		wrap_around = false;
+		return 0;
+	}
+
+	/* Copy TME log data to tzdbg diag buffer for the first time */
+	if (!wrap_around) {
+		if (tmelog_process_request(tmecrashdump_address_offset,
+								   TME_LOG_BUF_SIZE, &buf_size)) {
+			pr_err("Read tme log failed, ret=%d, buf_size: %#x\n", ret, buf_size);
+			return 0;
+		}
+		log_start.offset = 0x0;
+		log_start.size = buf_size;
+	}
+
+	log_ptr = tzdbg.tmelog_virt_iobase;
+	log_len = log_start.size;
+	log_ptr += log_start.offset;
+
+	/* Check if we exceed the max length provided by user space */
+	log_len = min(min((uint32_t)count, log_len), display_buf_size);
+
+	log_start.size -= log_len;
+	log_start.offset += log_len;
+	pr_debug("log_len: %d, log_start.offset: %#x, log_start.size: %#x\n",
+			log_len, log_start.offset, log_start.size);
+
+	if (log_start.size)
+		wrap_around =  true;
+
+	/* Copy TME log data to display buffer */
+	memcpy_fromio(tzdbg.disp_buf, log_ptr, log_len);
+
+	tzdbg.stat[TZDBG_TME_LOG].data = tzdbg.disp_buf;
+	return log_len;
+}
+#else
+static int _disp_tme_log_stats(size_t count)
+{
+	return 0;
+}
+#endif
+
 static ssize_t tzdbg_fs_read_unencrypted(int tz_id, char __user *buf,
 	size_t count, loff_t *offp)
 {
@@ -1232,6 +1308,10 @@ static ssize_t tzdbg_fs_read_unencrypted(int tz_id, char __user *buf,
 		len = _disp_rm_log_stats(count);
 		*offp = 0;
 		break;
+	case TZDBG_TME_LOG:
+		len = _disp_tme_log_stats(count);
+		*offp = 0;
+		break;
 	default:
 		break;
 	}
@@ -1298,7 +1378,7 @@ static ssize_t tzdbg_fs_read(struct file *file, char __user *buf,
 
 	if (!tzdbg.is_encrypted_log_enabled ||
 	    (tz_id == TZDBG_HYP_GENERAL || tz_id == TZDBG_HYP_LOG)
-	    || tz_id == TZDBG_RM_LOG)
+	    || tz_id == TZDBG_RM_LOG || tz_id == TZDBG_TME_LOG)
 		return tzdbg_fs_read_unencrypted(tz_id, buf, count, offp);
 	else
 		return tzdbg_fs_read_encrypted(tz_id, buf, count, offp);
@@ -1327,6 +1407,31 @@ struct proc_ops tzdbg_fops = {
 	.proc_release = tzdbg_procfs_release,
 };
 
+static int tzdbg_init_tme_log(struct platform_device *pdev, void __iomem *virt_iobase)
+{
+	/*
+	 * Tme logs are dumped in tme log ddr region but that region is not
+	 * accessible to hlos. Instead, collect logs at tme crashdump ddr
+	 * region with tmecom interface and then display logs reading from
+	 * crashdump region.
+	 */
+	if (of_property_read_u32((&pdev->dev)->of_node, "tmecrashdump-address-offset",
+				&tmecrashdump_address_offset)) {
+		pr_err("Tme Crashdump address offset need to be defined!\n");
+		return -EINVAL;
+	}
+
+	tzdbg.tmelog_virt_iobase =
+		devm_ioremap(&pdev->dev, tmecrashdump_address_offset, TME_LOG_BUF_SIZE);
+	if (!tzdbg.tmelog_virt_iobase) {
+		pr_err("ERROR: Could not ioremap: start=%#x, len=%u\n",
+				tmecrashdump_address_offset, TME_LOG_BUF_SIZE);
+		return -ENXIO;
+	}
+
+	return 0;
+}
+
 /*
  * Allocates log buffer from ION, registers the buffer at TZ
  */
@@ -1468,20 +1573,6 @@ static void tzdbg_free_encrypted_log_buf(struct platform_device *pdev)
 			enc_qseelog_info.vaddr, enc_qseelog_info.paddr);
 }
 
-static bool is_hyp_dir(int tzdbg_stat_type)
-{
-	switch(tzdbg_stat_type)
-	{
-		case TZDBG_HYP_GENERAL:
-		case TZDBG_HYP_LOG:
-		case TZDBG_RM_LOG:
-			return true;
-		default:
-			return false;
-	}
-	return false;
-}
-
 static int  tzdbg_fs_init(struct platform_device *pdev)
 {
 	int rc = 0;
@@ -1497,14 +1588,9 @@ static int  tzdbg_fs_init(struct platform_device *pdev)
 
 	for (i = 0; i < TZDBG_STATS_MAX; i++) {
 		tzdbg.debug_tz[i] = i;
-		/*
-		 * If hypervisor is disabled, do not create
-		 * hyp_general, hyp_log and rm_log directories,
-		 * as accessing them would give segmentation fault
-		 */
-		if ((!tzdbg.is_hyplog_enabled) && (is_hyp_dir(i))) {
+		if (!tzdbg.stat[i].avail)
 			continue;
-		}
+
 		dent = proc_create_data(tzdbg.stat[i].name,
 				0444, dent_dir,
 				&tzdbg_fops, &tzdbg.debug_tz[i]);
@@ -1691,7 +1777,14 @@ static int tz_log_probe(struct platform_device *pdev)
 	void __iomem *virt_iobase;
 	phys_addr_t tzdiag_phy_iobase;
 	uint32_t *ptr = NULL;
-	int ret = 0;
+	int ret = 0, i;
+
+	/*
+	 * By default all nodes will be created.
+	 * Mark avail as false later selectively if there's need to skip proc node creation.
+	 */
+	for (i = 0; i < TZDBG_STATS_MAX; i++)
+		tzdbg.stat[i].avail = true;
 
 	ret = tzdbg_get_tz_version();
 	if (ret)
@@ -1744,6 +1837,9 @@ static int tz_log_probe(struct platform_device *pdev)
 				return -EINVAL;
 			}
 		} else {
+			tzdbg.stat[TZDBG_HYP_LOG].avail = false;
+			tzdbg.stat[TZDBG_HYP_GENERAL].avail = false;
+			tzdbg.stat[TZDBG_RM_LOG].avail = false;
 			dev_info(&pdev->dev, "Hyp log service not support\n");
 		}
 	} else {
@@ -1785,6 +1881,13 @@ static int tz_log_probe(struct platform_device *pdev)
 		}
 	}
 
+	/* Init for tme log */
+	ret = tzdbg_init_tme_log(pdev, virt_iobase);
+	if (ret < 0) {
+		tzdbg.stat[TZDBG_TME_LOG].avail = false;
+		pr_warn("Tme log initialization failed!\n");
+	}
+
 	/* register unencrypted qsee log buffer */
 	ret = tzdbg_register_qsee_log_buf(pdev);
 	if (ret)