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

Commit 4f207329 authored by Arun Menon's avatar Arun Menon
Browse files

msm: vidc: Add smmu page fault handler support



Register for the smmu page fault handler and print
buffer address and size details for all active video
instances. Whenever there is a page fault from Venus,
the page fault handler would be called with the faulting
address and the driver will print all of above buffer details.
This will help us understand if the faulting address is
within mapped memory or not.

Change-Id: I3519f4bb87952f646d356447682c2d4541dbb705
Signed-off-by: default avatarArun Menon <avmenon@codeaurora.org>
parent 8ae65e26
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -2211,7 +2211,7 @@ static int msm_comm_init_core(struct msm_vidc_inst *inst)
		goto fail_core_init;
	}
	core->state = VIDC_CORE_INIT;

	core->smmu_fault_handled = false;
core_already_inited:
	change_inst_state(inst, MSM_VIDC_CORE_INIT);
	mutex_unlock(&core->lock);
+1 −0
Original line number Diff line number Diff line
@@ -257,6 +257,7 @@ struct msm_vidc_core {
	u32 enc_codec_supported;
	u32 dec_codec_supported;
	struct delayed_work fw_unload_work;
	bool smmu_fault_handled;
};

struct msm_vidc_inst {
+78 −5
Original line number Diff line number Diff line
@@ -829,14 +829,85 @@ remove_cb:
	return rc;
}

int msm_vidc_smmu_fault_handler(struct iommu_domain *domain,
		struct device *dev, unsigned long iova, int flags, void *token)
{
	struct msm_vidc_core *core = token;
	struct msm_vidc_inst *inst;
	struct buffer_info *temp;
	struct internal_buf *buf;
	int i = 0;

	if (!domain || !core) {
		dprintk(VIDC_ERR, "%s - invalid param %p %p\n",
			__func__, domain, core);
		return -EINVAL;
	}

	if (core->smmu_fault_handled)
		return -ENOSYS;

	dprintk(VIDC_ERR, "%s - faulting address: %lx\n", __func__, iova);

	mutex_lock(&core->lock);
	list_for_each_entry(inst, &core->instances, list) {
		dprintk(VIDC_ERR,
			"---Buffer details for inst: %p of type: %d---\n",
			inst, inst->session_type);
		mutex_lock(&inst->registeredbufs.lock);
		dprintk(VIDC_ERR, "registered buffer list:\n");
		list_for_each_entry(temp, &inst->registeredbufs.list, list)
			for (i = 0; i < temp->num_planes; i++)
				dprintk(VIDC_ERR,
					"type: %d plane: %d addr: %pa size: %d\n",
					temp->type, i, &temp->device_addr[i],
					temp->size[i]);

		mutex_unlock(&inst->registeredbufs.lock);

		mutex_lock(&inst->scratchbufs.lock);
		dprintk(VIDC_ERR, "scratch buffer list:\n");
		list_for_each_entry(buf, &inst->scratchbufs.list, list)
			dprintk(VIDC_ERR, "type: %d addr: %pa size: %lu\n",
				buf->buffer_type, &buf->handle->device_addr,
				buf->handle->size);
		mutex_unlock(&inst->scratchbufs.lock);

		mutex_lock(&inst->persistbufs.lock);
		dprintk(VIDC_ERR, "persist buffer list:\n");
		list_for_each_entry(buf, &inst->persistbufs.list, list)
			dprintk(VIDC_ERR, "type: %d addr: %pa size: %lu\n",
				buf->buffer_type, &buf->handle->device_addr,
				buf->handle->size);
		mutex_unlock(&inst->persistbufs.lock);

		mutex_lock(&inst->outputbufs.lock);
		dprintk(VIDC_ERR, "dpb buffer list:\n");
		list_for_each_entry(buf, &inst->outputbufs.list, list)
			dprintk(VIDC_ERR, "type: %d addr: %pa size: %lu\n",
				buf->buffer_type, &buf->handle->device_addr,
				buf->handle->size);
		mutex_unlock(&inst->outputbufs.lock);
	}
	core->smmu_fault_handled = true;
	mutex_unlock(&core->lock);
	/*
	 * Return -ENOSYS to elicit the default behaviour of smmu driver.
	 * If we return -ENOSYS, then smmu driver assumes page fault handler
	 * is not installed and prints a list of useful debug information like
	 * FAR, SID etc. This information is not printed if we return 0.
	 */
	return -ENOSYS;
}

static int msm_vidc_populate_context_bank(struct device *dev,
		struct msm_vidc_platform_resources *res)
		struct msm_vidc_core *core)
{
	int rc = 0;
	struct context_bank_info *cb = NULL;
	struct device_node *np = NULL;

	if (!dev || !res) {
	if (!dev || !core) {
		dprintk(VIDC_ERR, "%s - invalid inputs\n", __func__);
		return -EINVAL;
	}
@@ -849,7 +920,7 @@ static int msm_vidc_populate_context_bank(struct device *dev,
	}

	INIT_LIST_HEAD(&cb->list);
	list_add_tail(&cb->list, &res->context_banks);
	list_add_tail(&cb->list, &core->resources.context_banks);

	rc = of_property_read_string(np, "label", &cb->name);
	if (rc) {
@@ -890,6 +961,9 @@ static int msm_vidc_populate_context_bank(struct device *dev,
		goto err_setup_cb;
	}

	iommu_set_fault_handler(cb->mapping->domain,
		msm_vidc_smmu_fault_handler, (void *)core);

	return 0;

err_setup_cb:
@@ -936,8 +1010,7 @@ int read_context_bank_resources_from_dt(struct platform_device *pdev)
			}
		}
	} else {
		rc = msm_vidc_populate_context_bank(&pdev->dev,
					&core->resources);
		rc = msm_vidc_populate_context_bank(&pdev->dev, core);
		if (rc)
			dprintk(VIDC_ERR, "Failed to probe context bank\n");
		else