Kaynağa Gözat

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 <[email protected]>
Vijay Kumar Tumati 2 yıl önce
ebeveyn
işleme
16be1306ef

+ 12 - 12
drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c

@@ -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,
-	bool protect, int32_t offset)
+	bool protect, int32_t offset, bool is_shutdown)
 {
 	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) {
 			CAM_ERR(CAM_CSIPHY,
 				"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;
 	}
 
-	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);
-
-		csiphy_dev->csiphy_info[offset].secure_info_updated = false;
+		if (!protect)
+			csiphy_dev->csiphy_info[offset].secure_info_updated = false;
 	}
 
 	return rc;
@@ -1436,7 +1436,7 @@ void cam_csiphy_shutdown(struct csiphy_device *csiphy_dev)
 
 			if (param->secure_mode)
 				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;
 
@@ -2216,7 +2216,7 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
 		if (--csiphy_dev->start_dev_count) {
 			if (param->secure_mode)
 				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->csiphy_cpas_cp_reg_mask = 0;
@@ -2253,7 +2253,7 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
 
 		if (param->secure_mode)
 			cam_csiphy_program_secure_mode(csiphy_dev, CAM_SECURE_MODE_NON_SECURE,
-				offset);
+				offset, false);
 
 		param->secure_mode = CAM_SECURE_MODE_NON_SECURE;
 		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)
 			cam_csiphy_program_secure_mode(
 				csiphy_dev,
-				CAM_SECURE_MODE_NON_SECURE, offset);
+				CAM_SECURE_MODE_NON_SECURE, offset, false);
 
 		csiphy_dev->csiphy_info[offset].secure_mode =
 			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,
-					CAM_SECURE_MODE_SECURE, offset);
+					CAM_SECURE_MODE_SECURE, offset, false);
 				if (rc) {
 					csiphy_dev->csiphy_info[offset]
 						.secure_mode =
@@ -2574,7 +2574,7 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
 
 			rc = cam_csiphy_program_secure_mode(
 				csiphy_dev,
-				CAM_SECURE_MODE_SECURE, offset);
+				CAM_SECURE_MODE_SECURE, offset, false);
 			if (rc) {
 				csiphy_dev->csiphy_info[offset].secure_mode =
 					CAM_SECURE_MODE_NON_SECURE;

+ 45 - 32
drivers/cam_utils/cam_compat.c

@@ -327,7 +327,7 @@ bool cam_is_mink_api_available(void)
 }
 #if KERNEL_VERSION(6, 0, 0) <= LINUX_VERSION_CODE
 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;
 	struct Object client_env, sc_object;
@@ -339,41 +339,54 @@ int cam_csiphy_notify_secure_mode(struct csiphy_device *csiphy_dev,
 		return -EINVAL;
 	}
 
-	rc = get_client_env_object(&client_env);
-	if (rc) {
-		CAM_ERR(CAM_CSIPHY, "Failed getting mink env object, rc: %d", rc);
-		return rc;
-	}
+	if (!is_shutdown) {
+		rc = get_client_env_object(&client_env);
+		if (rc) {
+			CAM_ERR(CAM_CSIPHY, "Failed getting mink env object, rc: %d", rc);
+			return rc;
+		}
 
-	rc = IClientEnv_open(client_env, CTrustedCameraDriver_UID, &sc_object);
-	if (rc) {
-		CAM_ERR(CAM_CSIPHY, "Failed getting mink sc_object, rc: %d", rc);
-		return rc;
-	}
+		rc = IClientEnv_open(client_env, CTrustedCameraDriver_UID, &sc_object);
+		if (rc) {
+			CAM_ERR(CAM_CSIPHY, "Failed getting mink sc_object, rc: %d", rc);
+			return rc;
+		}
 
-	secure_info = &csiphy_dev->csiphy_info[offset].secure_info;
-	params.csid_hw_idx_mask = secure_info->csid_hw_idx_mask;
-	params.cdm_hw_idx_mask = secure_info->cdm_hw_idx_mask;
-	params.vc_mask = secure_info->vc_mask;
-	params.phy_lane_sel_mask =
-		csiphy_dev->csiphy_info[offset].csiphy_phy_lane_sel_mask;
-	params.protect = protect ? 1 : 0;
+		secure_info = &csiphy_dev->csiphy_info[offset].secure_info;
+		params.csid_hw_idx_mask = secure_info->csid_hw_idx_mask;
+		params.cdm_hw_idx_mask = secure_info->cdm_hw_idx_mask;
+		params.vc_mask = secure_info->vc_mask;
+		params.phy_lane_sel_mask =
+			csiphy_dev->csiphy_info[offset].csiphy_phy_lane_sel_mask;
+		params.protect = protect ? 1 : 0;
+
+		rc = ITrustedCameraDriver_dynamicProtectSensor(sc_object, &params);
+		if (rc) {
+			CAM_ERR(CAM_CSIPHY, "Mink secure call failed, rc: %d", rc);
+			return rc;
+		}
 
-	rc = ITrustedCameraDriver_dynamicProtectSensor(sc_object, &params);
-	if (rc) {
-		CAM_ERR(CAM_CSIPHY, "Mink secure call failed, rc: %d", rc);
-		return rc;
-	}
+		rc = Object_release(sc_object);
+		if (rc) {
+			CAM_ERR(CAM_CSIPHY, "Failed releasing secure camera object, rc: %d", rc);
+			return rc;
+		}
 
-	rc = Object_release(sc_object);
-	if (rc) {
-		CAM_ERR(CAM_CSIPHY, "Failed releasing secure camera object, rc: %d", rc);
-		return rc;
-	}
-	rc = Object_release(client_env);
-	if (rc) {
-		CAM_ERR(CAM_CSIPHY, "Failed releasing mink env object, rc: %d", rc);
-		return rc;
+		rc = Object_release(client_env);
+		if (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;

+ 1 - 1
drivers/cam_utils/cam_compat.h

@@ -66,7 +66,7 @@ int cam_ife_notify_safe_lut_scm(bool safe_trigger);
 int camera_component_match_add_drivers(struct device *master_dev,
 	struct component_match **match_list);
 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);
 void cam_free_clear(const void *);
 void cam_check_iommu_faults(struct iommu_domain *domain,