Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b746c4f5 authored by Ravikishore Pampana's avatar Ravikishore Pampana
Browse files

msm: camera: core: Send event on smmu page fault



Currently when page fault happen, iommu driver callers camera
handler with CB details and iova address which caused the page
fault. With iommu iova address cam smmu driver finds the
closest mapping address for that cb and call the
corresponding driver to find the which port caused page fault.
This has limitation has page fault address always not mapped.
New approach is get the page fault ids from iommu driver.
Based on the Pid and Mid values, get the HW id and port ids,
go through all context which has this hw id and port id and log
the data. Once context id is identified, log the acquire data and
last consumed client address details. Dump the hw register data
in the given buffer. Send the smmu page fault event through
v4l2 queue to user.

CRs-Fixed: 2750690
Change-Id: I87c809b3229992c7c95655a4f3c6c70ebc035ae8
Signed-off-by: default avatarRavikishore Pampana <rpampana@codeaurora.org>
parent 3da4eff7
Loading
Loading
Loading
Loading
+5 −7
Original line number Diff line number Diff line
@@ -1224,16 +1224,14 @@ static void cam_hw_cdm_work(struct work_struct *work)

}

static void cam_hw_cdm_iommu_fault_handler(struct iommu_domain *domain,
	struct device *dev, unsigned long iova, int flags, void *token,
	uint32_t buf_info)
static void cam_hw_cdm_iommu_fault_handler(struct cam_smmu_pf_info *pf_info)
{
	struct cam_hw_info *cdm_hw = NULL;
	struct cam_cdm *core = NULL;
	int i;

	if (token) {
		cdm_hw = (struct cam_hw_info *)token;
	if (pf_info->token) {
		cdm_hw = (struct cam_hw_info *)pf_info->token;
		core = (struct cam_cdm *)cdm_hw->core_info;
		set_bit(CAM_CDM_ERROR_HW_STATUS, &core->cdm_status);
		mutex_lock(&cdm_hw->hw_mutex);
@@ -1254,9 +1252,9 @@ static void cam_hw_cdm_iommu_fault_handler(struct iommu_domain *domain,
			mutex_unlock(&core->bl_fifo[i].fifo_lock);
		mutex_unlock(&cdm_hw->hw_mutex);
		CAM_ERR_RATE_LIMIT(CAM_CDM, "Page fault iova addr %pK\n",
			(void *)iova);
			(void *)pf_info->iova);
		cam_cdm_notify_clients(cdm_hw, CAM_CDM_CB_STATUS_PAGEFAULT,
			(void *)iova);
			(void *)pf_info->iova);
		clear_bit(CAM_CDM_ERROR_HW_STATUS, &core->cdm_status);
	} else {
		CAM_ERR(CAM_CDM, "Invalid token");
+3 −3
Original line number Diff line number Diff line
@@ -287,8 +287,8 @@ int cam_context_handle_crm_dump_req(struct cam_context *ctx,
	return rc;
}

int cam_context_dump_pf_info(struct cam_context *ctx, unsigned long iova,
	uint32_t buf_info)
int cam_context_dump_pf_info(struct cam_context *ctx,
	struct cam_smmu_pf_info *pf_info)
{
	int rc = 0;

@@ -301,7 +301,7 @@ int cam_context_dump_pf_info(struct cam_context *ctx, unsigned long iova,
		(ctx->state < CAM_CTX_STATE_MAX)) {
		if (ctx->state_machine[ctx->state].pagefault_ops) {
			rc = ctx->state_machine[ctx->state].pagefault_ops(
				ctx, iova, buf_info);
				ctx, pf_info);
		} else {
			CAM_WARN(CAM_CORE, "No dump ctx in dev %d, state %d",
				ctx->dev_hdl, ctx->state);
+4 −4
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
#include <linux/kref.h>
#include "cam_req_mgr_interface.h"
#include "cam_hw_mgr_intf.h"
#include "cam_smmu_api.h"

/* Forward declarations */
struct cam_context;
@@ -360,12 +361,11 @@ int cam_context_handle_crm_dump_req(struct cam_context *ctx,
 * @brief:        Handle dump active request request command
 *
 * @ctx:          Object pointer for cam_context
 * @iova:         Page fault address
 * @buf_info:     Information about closest memory handle
 * @pf_info:      Smmu page fault info
 *
 */
int cam_context_dump_pf_info(struct cam_context *ctx, unsigned long iova,
	uint32_t buf_info);
int cam_context_dump_pf_info(struct cam_context *ctx,
	struct cam_smmu_pf_info *pf_info);

/**
 * cam_context_handle_acquire_dev()
+9 −4
Original line number Diff line number Diff line
@@ -994,8 +994,8 @@ int32_t cam_context_stop_dev_to_hw(struct cam_context *ctx)
}

int32_t cam_context_dump_pf_info_to_hw(struct cam_context *ctx,
	struct cam_packet *packet, unsigned long iova, uint32_t buf_info,
	bool *mem_found)
	struct cam_packet *packet, bool *mem_found, bool *ctx_found,
	uint32_t  *resource_type, struct cam_smmu_pf_info *pf_info)
{
	int rc = 0;
	struct cam_hw_cmd_args cmd_args;
@@ -1017,9 +1017,14 @@ int32_t cam_context_dump_pf_info_to_hw(struct cam_context *ctx,
		cmd_args.ctxt_to_hw_map = ctx->ctxt_to_hw_map;
		cmd_args.cmd_type = CAM_HW_MGR_CMD_DUMP_PF_INFO;
		cmd_args.u.pf_args.pf_data.packet = packet;
		cmd_args.u.pf_args.iova = iova;
		cmd_args.u.pf_args.buf_info = buf_info;
		cmd_args.u.pf_args.iova = pf_info->iova;
		cmd_args.u.pf_args.buf_info = pf_info->buf_info;
		cmd_args.u.pf_args.mem_found = mem_found;
		cmd_args.u.pf_args.ctx_found = ctx_found;
		cmd_args.u.pf_args.resource_type = resource_type;
		cmd_args.u.pf_args.bid = pf_info->bid;
		cmd_args.u.pf_args.pid = pf_info->pid;
		cmd_args.u.pf_args.mid = pf_info->mid;
		ctx->hw_mgr_intf->hw_cmd(ctx->hw_mgr_intf->hw_mgr_priv,
			&cmd_args);
	}
+4 −2
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
#define _CAM_CONTEXT_UTILS_H_

#include <linux/types.h>
#include "cam_smmu_api.h"

int cam_context_buf_done_from_hw(struct cam_context *ctx,
	void *done_event_data, uint32_t evt_id);
@@ -27,8 +28,9 @@ int32_t cam_context_flush_ctx_to_hw(struct cam_context *ctx);
int32_t cam_context_flush_req_to_hw(struct cam_context *ctx,
	struct cam_flush_dev_cmd *cmd);
int32_t cam_context_dump_pf_info_to_hw(struct cam_context *ctx,
	struct cam_packet *packet, unsigned long iova, uint32_t buf_info,
	bool *mem_found);
	struct cam_packet *packet, bool *mem_found, bool *ctx_found,
	uint32_t  *resource_type,
	struct cam_smmu_pf_info *pf_info);
int32_t cam_context_dump_hw_acq_info(struct cam_context *ctx);
int32_t cam_context_dump_dev_to_hw(struct cam_context *ctx,
	struct cam_dump_req_cmd *cmd);
Loading