msm: camera: csiphy: Handle process shutdown during secure camera

Use SCM 7 call during the process shutdown. This is to
workaround a race condition between the close of camera FD
and the invoke driver FD that leads to a device crash.
Additionally, keep the Domain ID clocks on only during
protect or unprotect operations.

CRs-Fixed: 3509086
Change-Id: Ic091aa737df10bb2b41190c2f850c31fd17af9b2
Signed-off-by: Vijay Kumar Tumati <quic_vtumati@quicinc.com>
This commit is contained in:
Vijay Kumar Tumati
2023-05-17 15:39:12 -07:00
committed by Camera Software Integration
parent ebaa2a7356
commit 16be1306ef
3 changed files with 58 additions and 45 deletions

View File

@@ -1234,11 +1234,11 @@ static int __cam_csiphy_prgm_bist_reg(struct csiphy_device *csiphy_dev, bool is_
} }
static int cam_csiphy_program_secure_mode(struct csiphy_device *csiphy_dev, static int cam_csiphy_program_secure_mode(struct csiphy_device *csiphy_dev,
bool protect, int32_t offset) bool protect, int32_t offset, bool is_shutdown)
{ {
int rc = 0; int rc = 0;
if (csiphy_dev->domain_id_security && protect) { if (csiphy_dev->domain_id_security) {
if (!csiphy_dev->csiphy_info[offset].secure_info_updated) { if (!csiphy_dev->csiphy_info[offset].secure_info_updated) {
CAM_ERR(CAM_CSIPHY, CAM_ERR(CAM_CSIPHY,
"PHY[%u] domain id info not updated, aborting secure call", "PHY[%u] domain id info not updated, aborting secure call",
@@ -1252,12 +1252,12 @@ static int cam_csiphy_program_secure_mode(struct csiphy_device *csiphy_dev,
return rc; return rc;
} }
rc = cam_csiphy_notify_secure_mode(csiphy_dev, protect, offset); rc = cam_csiphy_notify_secure_mode(csiphy_dev, protect, offset, is_shutdown);
if (csiphy_dev->domain_id_security && !protect) { if (csiphy_dev->domain_id_security) {
cam_cpas_enable_clks_for_domain_id(false); cam_cpas_enable_clks_for_domain_id(false);
if (!protect)
csiphy_dev->csiphy_info[offset].secure_info_updated = false; csiphy_dev->csiphy_info[offset].secure_info_updated = false;
} }
return rc; return rc;
@@ -1436,7 +1436,7 @@ void cam_csiphy_shutdown(struct csiphy_device *csiphy_dev)
if (param->secure_mode) if (param->secure_mode)
cam_csiphy_program_secure_mode(csiphy_dev, cam_csiphy_program_secure_mode(csiphy_dev,
CAM_SECURE_MODE_NON_SECURE, i); CAM_SECURE_MODE_NON_SECURE, i, true);
param->secure_mode = CAM_SECURE_MODE_NON_SECURE; param->secure_mode = CAM_SECURE_MODE_NON_SECURE;
@@ -2216,7 +2216,7 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
if (--csiphy_dev->start_dev_count) { if (--csiphy_dev->start_dev_count) {
if (param->secure_mode) if (param->secure_mode)
cam_csiphy_program_secure_mode(csiphy_dev, cam_csiphy_program_secure_mode(csiphy_dev,
CAM_SECURE_MODE_NON_SECURE, offset); CAM_SECURE_MODE_NON_SECURE, offset, false);
param->secure_mode = CAM_SECURE_MODE_NON_SECURE; param->secure_mode = CAM_SECURE_MODE_NON_SECURE;
param->csiphy_cpas_cp_reg_mask = 0; param->csiphy_cpas_cp_reg_mask = 0;
@@ -2253,7 +2253,7 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
if (param->secure_mode) if (param->secure_mode)
cam_csiphy_program_secure_mode(csiphy_dev, CAM_SECURE_MODE_NON_SECURE, cam_csiphy_program_secure_mode(csiphy_dev, CAM_SECURE_MODE_NON_SECURE,
offset); offset, false);
param->secure_mode = CAM_SECURE_MODE_NON_SECURE; param->secure_mode = CAM_SECURE_MODE_NON_SECURE;
param->csiphy_cpas_cp_reg_mask = 0x0; param->csiphy_cpas_cp_reg_mask = 0x0;
@@ -2323,7 +2323,7 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
if (csiphy_dev->csiphy_info[offset].secure_mode) if (csiphy_dev->csiphy_info[offset].secure_mode)
cam_csiphy_program_secure_mode( cam_csiphy_program_secure_mode(
csiphy_dev, csiphy_dev,
CAM_SECURE_MODE_NON_SECURE, offset); CAM_SECURE_MODE_NON_SECURE, offset, false);
csiphy_dev->csiphy_info[offset].secure_mode = csiphy_dev->csiphy_info[offset].secure_mode =
CAM_SECURE_MODE_NON_SECURE; CAM_SECURE_MODE_NON_SECURE;
@@ -2503,7 +2503,7 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
} }
rc = cam_csiphy_program_secure_mode(csiphy_dev, rc = cam_csiphy_program_secure_mode(csiphy_dev,
CAM_SECURE_MODE_SECURE, offset); CAM_SECURE_MODE_SECURE, offset, false);
if (rc) { if (rc) {
csiphy_dev->csiphy_info[offset] csiphy_dev->csiphy_info[offset]
.secure_mode = .secure_mode =
@@ -2574,7 +2574,7 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
rc = cam_csiphy_program_secure_mode( rc = cam_csiphy_program_secure_mode(
csiphy_dev, csiphy_dev,
CAM_SECURE_MODE_SECURE, offset); CAM_SECURE_MODE_SECURE, offset, false);
if (rc) { if (rc) {
csiphy_dev->csiphy_info[offset].secure_mode = csiphy_dev->csiphy_info[offset].secure_mode =
CAM_SECURE_MODE_NON_SECURE; CAM_SECURE_MODE_NON_SECURE;

View File

@@ -327,7 +327,7 @@ bool cam_is_mink_api_available(void)
} }
#if KERNEL_VERSION(6, 0, 0) <= LINUX_VERSION_CODE #if KERNEL_VERSION(6, 0, 0) <= LINUX_VERSION_CODE
int cam_csiphy_notify_secure_mode(struct csiphy_device *csiphy_dev, int cam_csiphy_notify_secure_mode(struct csiphy_device *csiphy_dev,
bool protect, int32_t offset) bool protect, int32_t offset, bool is_shutdown)
{ {
int rc = 0; int rc = 0;
struct Object client_env, sc_object; struct Object client_env, sc_object;
@@ -339,41 +339,54 @@ int cam_csiphy_notify_secure_mode(struct csiphy_device *csiphy_dev,
return -EINVAL; return -EINVAL;
} }
rc = get_client_env_object(&client_env); if (!is_shutdown) {
if (rc) { rc = get_client_env_object(&client_env);
CAM_ERR(CAM_CSIPHY, "Failed getting mink env object, rc: %d", rc); if (rc) {
return rc; CAM_ERR(CAM_CSIPHY, "Failed getting mink env object, rc: %d", rc);
} return rc;
}
rc = IClientEnv_open(client_env, CTrustedCameraDriver_UID, &sc_object); rc = IClientEnv_open(client_env, CTrustedCameraDriver_UID, &sc_object);
if (rc) { if (rc) {
CAM_ERR(CAM_CSIPHY, "Failed getting mink sc_object, rc: %d", rc); CAM_ERR(CAM_CSIPHY, "Failed getting mink sc_object, rc: %d", rc);
return rc; return rc;
} }
secure_info = &csiphy_dev->csiphy_info[offset].secure_info; secure_info = &csiphy_dev->csiphy_info[offset].secure_info;
params.csid_hw_idx_mask = secure_info->csid_hw_idx_mask; params.csid_hw_idx_mask = secure_info->csid_hw_idx_mask;
params.cdm_hw_idx_mask = secure_info->cdm_hw_idx_mask; params.cdm_hw_idx_mask = secure_info->cdm_hw_idx_mask;
params.vc_mask = secure_info->vc_mask; params.vc_mask = secure_info->vc_mask;
params.phy_lane_sel_mask = params.phy_lane_sel_mask =
csiphy_dev->csiphy_info[offset].csiphy_phy_lane_sel_mask; csiphy_dev->csiphy_info[offset].csiphy_phy_lane_sel_mask;
params.protect = protect ? 1 : 0; params.protect = protect ? 1 : 0;
rc = ITrustedCameraDriver_dynamicProtectSensor(sc_object, &params); rc = ITrustedCameraDriver_dynamicProtectSensor(sc_object, &params);
if (rc) { if (rc) {
CAM_ERR(CAM_CSIPHY, "Mink secure call failed, rc: %d", rc); CAM_ERR(CAM_CSIPHY, "Mink secure call failed, rc: %d", rc);
return rc; return rc;
} }
rc = Object_release(sc_object); rc = Object_release(sc_object);
if (rc) { if (rc) {
CAM_ERR(CAM_CSIPHY, "Failed releasing secure camera object, rc: %d", rc); CAM_ERR(CAM_CSIPHY, "Failed releasing secure camera object, rc: %d", rc);
return rc; return rc;
} }
rc = Object_release(client_env);
if (rc) { rc = Object_release(client_env);
CAM_ERR(CAM_CSIPHY, "Failed releasing mink env object, rc: %d", rc); if (rc) {
return rc; CAM_ERR(CAM_CSIPHY, "Failed releasing mink env object, rc: %d", rc);
return rc;
}
} else {
/* This is a temporary work around until the SMC Invoke driver is
* refactored to avoid the dependency on FDs, which was causing issues
* during process shutdown.
*/
rc = qcom_scm_camera_protect_phy_lanes(protect, 0);
if (rc) {
CAM_ERR(CAM_CSIPHY, "SCM call to hypervisor failed");
return rc;
}
} }
return 0; return 0;

View File

@@ -66,7 +66,7 @@ int cam_ife_notify_safe_lut_scm(bool safe_trigger);
int camera_component_match_add_drivers(struct device *master_dev, int camera_component_match_add_drivers(struct device *master_dev,
struct component_match **match_list); struct component_match **match_list);
int cam_csiphy_notify_secure_mode(struct csiphy_device *csiphy_dev, int cam_csiphy_notify_secure_mode(struct csiphy_device *csiphy_dev,
bool protect, int32_t offset); bool protect, int32_t offset, bool is_shutdown);
bool cam_is_mink_api_available(void); bool cam_is_mink_api_available(void);
void cam_free_clear(const void *); void cam_free_clear(const void *);
void cam_check_iommu_faults(struct iommu_domain *domain, void cam_check_iommu_faults(struct iommu_domain *domain,