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

msm: camera: smmu: Add support for Camera Security Framework 2.5

Query the CSF version in use from SMMU proxy driver and
use noncontiguous system heap in case of  CSF 2.5
instead of the contiguous secure display heap.
In addition, do not lend the buffer in CSF 2.5.

CRs-Fixed: 3424427
Change-Id: I3d5f2402034dd455c304d5726eb9aa8ee2080dcc
Signed-off-by: Vijay Kumar Tumati <[email protected]>
Vijay Kumar Tumati 2 éve
szülő
commit
6dc4887fd9

+ 3 - 0
Android.mk

@@ -22,6 +22,9 @@ SYNX_VENDOR_BOARDS := pineapple
 # List of board platforms for which SMCINVOKE_DLKM driver API should be enabled
 SMCINVOKE_DLKM_BOARDS := pineapple
 
+# List of board platforms for which SMMU_PROXY_DLKM driver API should be enabled
+SMMU_PROXY_DLKM_BOARDS := pineapple
+
 CAMERA_SRC_FILES := \
                     $(addprefix $(LOCAL_PATH)/, $(call all-named-files-under,*.h,drivers dt-bindings include))\
                     $(addprefix $(LOCAL_PATH)/, $(call all-named-files-under,*.mk,config))\

+ 16 - 2
dependency.mk

@@ -48,5 +48,19 @@ endif # End of check for board platform SMCINVOKE_DLKM_BOARDS
 
 endif # End of find smcinvoke_dlkm driver
 
-KBUILD_OPTIONS += KBUILD_EXTRA_SYMBOLS=$(CAM_MMRM_EXTRA_SYMBOLS) KBUILD_EXTRA_SYMBOLS+=$(CAM_SYNX_EXTRA_SYMBOLS) KBUILD_EXTRA_SYMBOLS+=$(SMCINVOKE_EXTRA_SYMBOLS)
-KBUILD_OPTIONS += KBUILD_EXTRA_CONFIGS=$(CAM_MMRM_EXTRA_CONFIGS) KBUILD_EXTRA_CONFIGS+=$(CAM_SYNX_EXTRA_CONFIGS) KBUILD_EXTRA_CONFIGS+=$(CAM_SMCINOKE_EXTRA_CONFIGS)
+# Check if this board's product.mk finds smmu_proxy_dlkm.ko driver
+ifeq ($(findstring smmu_proxy_dlkm.ko, $(BOARD_VENDOR_KERNEL_MODULES)), smmu_proxy_dlkm.ko)
+
+ifeq ($(call is-board-platform-in-list, $(SMMU_PROXY_DLKM_BOARDS)),true)
+SMMU_PROXY_EXTRA_SYMBOLS ?= $(realpath $(TOP))/$(call intermediates-dir-for,DLKM,smmu_proxy_dlkm.ko)/Module.symvers
+$(info camera-kernel: Found smmu proxy driver, adding symbol dependency! $(SMMU_PROXY_EXTRA_SYMBOLS))
+LOCAL_REQUIRED_MODULES  += smmu_proxy_dlkm.ko
+CAM_SMMU_PROXY_EXTRA_CONFIGS ?= $(realpath $(TOP))/vendor/qcom/opensource/securemsm-kernel/config/sec-kernel_defconfig_smmu_proxy.conf
+LOCAL_ADDITIONAL_DEPENDENCIES += $(call intermediates-dir-for,DLKM,smmu_proxy_dlkm.ko)/Module.symvers
+
+endif # End of check for board platform SMMU_PROXY_DLKM_BOARDS
+
+endif # End of find smmu_proxy_dlkm driver
+
+KBUILD_OPTIONS += KBUILD_EXTRA_SYMBOLS=$(CAM_MMRM_EXTRA_SYMBOLS) KBUILD_EXTRA_SYMBOLS+=$(CAM_SYNX_EXTRA_SYMBOLS) KBUILD_EXTRA_SYMBOLS+=$(SMCINVOKE_EXTRA_SYMBOLS) KBUILD_EXTRA_SYMBOLS+=$(SMMU_PROXY_EXTRA_SYMBOLS)
+KBUILD_OPTIONS += KBUILD_EXTRA_CONFIGS=$(CAM_MMRM_EXTRA_CONFIGS) KBUILD_EXTRA_CONFIGS+=$(CAM_SYNX_EXTRA_CONFIGS) KBUILD_EXTRA_CONFIGS+=$(CAM_SMCINOKE_EXTRA_CONFIGS) KBUILD_EXTRA_CONFIGS+=$(CAM_SMMU_PROXY_EXTRA_CONFIGS)

+ 13 - 6
drivers/cam_req_mgr/cam_mem_mgr.c

@@ -258,6 +258,8 @@ int cam_mem_mgr_init(void)
 	cam_common_register_mini_dump_cb(cam_mem_mgr_mini_dump_cb,
 		"cam_mem", NULL);
 
+	cam_smmu_get_csf_version(&tbl.csf_version);
+
 	return 0;
 put_heaps:
 #if IS_REACHABLE(CONFIG_DMABUF_HEAPS)
@@ -714,11 +716,15 @@ static int cam_mem_util_get_dma_buf(size_t len,
 	}
 
 	if (cam_flags & CAM_MEM_FLAG_PROTECTED_MODE) {
-		heap = tbl.secure_display_heap;
-
-		vmids[num_vmids] = VMID_CP_CAMERA;
-		perms[num_vmids] = PERM_READ | PERM_WRITE;
-		num_vmids++;
+		if (IS_CSF25(tbl.csf_version.arch_ver, tbl.csf_version.max_ver)) {
+			heap = tbl.system_heap;
+			len = cam_align_dma_buf_size(len);
+		} else {
+			heap = tbl.secure_display_heap;
+			vmids[num_vmids] = VMID_CP_CAMERA;
+			perms[num_vmids] = PERM_READ | PERM_WRITE;
+			num_vmids++;
+		}
 
 		if (cam_flags & CAM_MEM_FLAG_CDSP_OUTPUT) {
 			CAM_DBG(CAM_MEM, "Secure mode CDSP flags");
@@ -783,7 +789,8 @@ static int cam_mem_util_get_dma_buf(size_t len,
 
 	*i_ino = file_inode((*buf)->file)->i_ino;
 
-	if ((cam_flags & CAM_MEM_FLAG_PROTECTED_MODE) ||
+	if (((cam_flags & CAM_MEM_FLAG_PROTECTED_MODE) &&
+		!IS_CSF25(tbl.csf_version.arch_ver, tbl.csf_version.max_ver)) ||
 		(cam_flags & CAM_MEM_FLAG_EVA_NOPIXEL)) {
 		if (num_vmids >= CAM_MAX_VMIDS) {
 			CAM_ERR(CAM_MEM, "Insufficient array size for vmids %d", num_vmids);

+ 2 - 0
drivers/cam_req_mgr/cam_mem_mgr.h

@@ -89,6 +89,7 @@ struct cam_mem_buf_queue {
  * @force_cache_allocs: Force all internal buffer allocations with cache
  * @need_shared_buffer_padding: Whether padding is needed for shared buffer
  *                              allocations.
+ * @csf_version: Camera security framework version
  * @system_heap: Handle to system heap
  * @system_uncached_heap: Handle to system uncached heap
  * @camera_heap: Handle to camera heap
@@ -104,6 +105,7 @@ struct cam_mem_table {
 	size_t dbg_buf_idx;
 	bool force_cache_allocs;
 	bool need_shared_buffer_padding;
+	struct cam_csf_version csf_version;
 #if IS_REACHABLE(CONFIG_DMABUF_HEAPS)
 	struct dma_heap *system_heap;
 	struct dma_heap *system_uncached_heap;

+ 29 - 1
drivers/cam_smmu/cam_smmu_api.c

@@ -237,6 +237,7 @@ struct cam_iommu_cb_set {
 	bool force_cache_allocs;
 	bool need_shared_buffer_padding;
 	bool is_expanded_memory;
+	struct cam_csf_version csf_version;
 };
 
 static const struct of_device_id msm_cam_smmu_dt_match[] = {
@@ -327,6 +328,15 @@ struct cam_smmu_mini_dump_info {
 
 static struct cam_iommu_cb_set iommu_cb_set;
 
+/*
+ * This is expected to succeed as the SMMU bind would have
+ * failed if it could not fetch the CSF version from SMMU proxy
+ */
+void cam_smmu_get_csf_version(struct cam_csf_version *csf_ver)
+{
+	memcpy(csf_ver, &iommu_cb_set.csf_version, sizeof(*csf_ver));
+}
+
 static enum dma_data_direction cam_smmu_translate_dir(
 	enum cam_smmu_map_dir dir);
 
@@ -3465,6 +3475,11 @@ static int cam_smmu_map_stage2_buffer_and_add_to_list(int idx, int ion_fd,
 
 	attach->dma_map_attrs |= DMA_ATTR_SKIP_CPU_SYNC;
 
+	if (IS_CSF25(iommu_cb_set.csf_version.arch_ver,
+		iommu_cb_set.csf_version.max_ver))
+		attach->dma_map_attrs =
+			cam_update_dma_map_attributes(attach->dma_map_attrs);
+
 	table = dma_buf_map_attachment(attach, dma_dir);
 	if (IS_ERR_OR_NULL(table)) {
 		CAM_ERR(CAM_SMMU, "Error: dma buf map attachment failed");
@@ -3473,7 +3488,12 @@ static int cam_smmu_map_stage2_buffer_and_add_to_list(int idx, int ion_fd,
 	}
 
 	/* return addr and len to client */
-	*paddr_ptr = sg_phys(table->sgl);
+	if (IS_CSF25(iommu_cb_set.csf_version.arch_ver,
+		iommu_cb_set.csf_version.max_ver))
+		*paddr_ptr = sg_dma_address(table->sgl);
+	else
+		*paddr_ptr = sg_phys(table->sgl);
+
 	*len_ptr = (size_t)sg_dma_len(table->sgl);
 
 	/* fill up mapping_info */
@@ -5405,6 +5425,8 @@ const static struct component_ops cam_smmu_cb_qsmmu_component_ops = {
 static int cam_smmu_component_bind(struct device *dev,
 	struct device *master_dev, void *data)
 {
+	int rc;
+
 	INIT_WORK(&iommu_cb_set.smmu_work, cam_smmu_page_fault_work);
 	mutex_init(&iommu_cb_set.payload_list_lock);
 	INIT_LIST_HEAD(&iommu_cb_set.payload_list);
@@ -5420,6 +5442,12 @@ static int cam_smmu_component_bind(struct device *dev,
 	cam_common_register_mini_dump_cb(cam_smmu_mini_dump_cb,
 		"cam_smmu", NULL);
 
+	rc = cam_smmu_fetch_csf_version(&iommu_cb_set.csf_version);
+	if (rc) {
+		CAM_ERR(CAM_SMMU, "Failed to fetch CSF version: %d", rc);
+		return rc;
+	}
+
 	CAM_DBG(CAM_SMMU, "Main component bound successfully");
 	return 0;
 }

+ 22 - 1
drivers/cam_smmu/cam_smmu_api.h

@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
  * Copyright (c) 2014-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef _CAM_SMMU_API_H_
@@ -57,6 +57,22 @@ enum cam_smmu_subregion_id {
 	CAM_SMMU_SUBREGION_MAX,
 };
 
+/**
+ * @brief          : Represents camera security framework version
+ *
+ * @param arch_ver          : Captures the version of the high level secure
+ *                            camera architecture.
+ * @param max_ver           : Captures the version of the solution with in the
+ *                            high level architecture.
+ * @param min_ver           : Captures the version of the memory assignment
+ *                            mechanism with in the solution.
+ */
+struct cam_csf_version {
+	uint32_t              arch_ver;
+	uint32_t              max_ver;
+	uint32_t              min_ver;
+};
+
 /**
  * @brief          : cam_smmu_pf_info
  *
@@ -502,4 +518,9 @@ bool cam_smmu_is_expanded_memory(void);
  */
 int cam_smmu_is_cb_non_fatal_fault_en(int smmu_hdl, bool *non_fatal_en);
 
+/**
+ * @brief : API to get CSF version in use that's received from SMMU proxy driver
+ */
+void cam_smmu_get_csf_version(struct cam_csf_version *csf_ver);
+
 #endif /* _CAM_SMMU_API_H_ */

+ 41 - 0
drivers/cam_utils/cam_compat.c

@@ -111,6 +111,47 @@ int cam_cpas_drv_channel_switch_for_dev(const struct device *dev)
 }
 #endif
 
+int cam_smmu_fetch_csf_version(struct cam_csf_version *csf_version)
+{
+#if KERNEL_VERSION(6, 0, 0) <= LINUX_VERSION_CODE
+	struct csf_version csf_ver;
+	int rc;
+
+	/* Fetch CSF version from SMMU proxy driver */
+	rc = smmu_proxy_get_csf_version(&csf_ver);
+	if (rc) {
+		CAM_ERR(CAM_SMMU,
+			"Failed to get CSF version from SMMU proxy: %d", rc);
+		return rc;
+	}
+
+	csf_version->arch_ver = csf_ver.arch_ver;
+	csf_version->max_ver = csf_ver.max_ver;
+	csf_version->min_ver = csf_ver.min_ver;
+#else
+	/* This defaults to the legacy version */
+	csf_version->arch_ver = 2;
+	csf_version->max_ver = 0;
+	csf_version->min_ver = 0;
+#endif
+	return 0;
+}
+
+unsigned long cam_update_dma_map_attributes(unsigned long attrs)
+{
+#if KERNEL_VERSION(6, 0, 0) <= LINUX_VERSION_CODE
+	attrs |= DMA_ATTR_QTI_SMMU_PROXY_MAP;
+#endif
+	return attrs;
+}
+
+size_t cam_align_dma_buf_size(size_t len)
+{
+#if KERNEL_VERSION(6, 0, 0) <= LINUX_VERSION_CODE
+	len = ALIGN(len, SMMU_PROXY_MEM_ALIGNMENT);
+#endif
+	return len;
+}
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
 int cam_reserve_icp_fw(struct cam_fw_alloc_info *icp_fw, size_t fw_length)

+ 13 - 0
drivers/cam_utils/cam_compat.h

@@ -23,6 +23,11 @@
 #include "cam_cpastop_hw.h"
 #include "cam_smmu_api.h"
 
+#if KERNEL_VERSION(6, 0, 0) <= LINUX_VERSION_CODE
+#include <smmu-proxy/linux/qti-smmu-proxy.h>
+#include <linux/qcom-dma-mapping.h>
+#endif
+
 #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)
 #include <linux/ion.h>
 #include <linux/msm_ion.h>
@@ -46,6 +51,8 @@ MODULE_IMPORT_NS(DMA_BUF);
 #include <linux/CTrustedCameraDriver.h>
 #endif
 
+#define IS_CSF25(x, y) ((((x) == 2) && ((y) == 5)) ? 1 : 0)
+
 struct cam_fw_alloc_info {
 	struct device *fw_dev;
 	void          *fw_kva;
@@ -100,4 +107,10 @@ int cam_compat_util_get_irq(struct cam_hw_soc_info *soc_info);
 
 bool cam_secure_get_vfe_fd_port_config(void);
 
+int cam_smmu_fetch_csf_version(struct cam_csf_version *csf_version);
+
+unsigned long cam_update_dma_map_attributes(unsigned long attr);
+
+size_t cam_align_dma_buf_size(size_t len);
+
 #endif /* _CAM_COMPAT_H_ */