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 <quic_vtumati@quicinc.com>
This commit is contained in:
Vijay Kumar Tumati
2023-01-06 13:51:39 -08:00
committed by Camera Software Integration
parent 8c38f564e3
commit 6dc4887fd9
8 changed files with 139 additions and 10 deletions

View File

@@ -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))\

View File

@@ -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)

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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_ */

View File

@@ -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)

View File

@@ -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_ */