From 7d07b3ae8ddad407913c5301877e694430a3263f Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Thu, 23 Nov 2023 08:24:31 +0000
Subject: [PATCH] add build kerneldeb
---
kernel/drivers/video/rockchip/rga3/rga_iommu.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 48 insertions(+), 1 deletions(-)
diff --git a/kernel/drivers/video/rockchip/rga3/rga_iommu.c b/kernel/drivers/video/rockchip/rga3/rga_iommu.c
index 3b7a4ef..6ef9cbc 100644
--- a/kernel/drivers/video/rockchip/rga3/rga_iommu.c
+++ b/kernel/drivers/video/rockchip/rga3/rga_iommu.c
@@ -5,7 +5,7 @@
* Author: Huang Lee <Putin.li@rock-chips.com>
*/
-#define pr_fmt(fmt) "rga2_mmu: " fmt
+#define pr_fmt(fmt) "rga_iommu: " fmt
#include "rga_iommu.h"
#include "rga_dma_buf.h"
@@ -170,6 +170,12 @@
* size * channel_num * address_size
*/
order = get_order(size * 3 * sizeof(*mmu_base->buf_virtual));
+ if (order >= MAX_ORDER) {
+ pr_err("Can not alloc pages with order[%d] for mmu_page_table, max_order = %d\n",
+ order, MAX_ORDER);
+ goto err_free_mmu_base;
+ }
+
mmu_base->buf_virtual = (uint32_t *) __get_free_pages(GFP_KERNEL | GFP_DMA32, order);
if (mmu_base->buf_virtual == NULL) {
pr_err("Can not alloc pages for mmu_page_table\n");
@@ -178,6 +184,12 @@
mmu_base->buf_order = order;
order = get_order(size * sizeof(*mmu_base->pages));
+ if (order >= MAX_ORDER) {
+ pr_err("Can not alloc pages with order[%d] for mmu_base->pages, max_order = %d\n",
+ order, MAX_ORDER);
+ goto err_free_buf_virtual;
+ }
+
mmu_base->pages = (struct page **)__get_free_pages(GFP_KERNEL | GFP_DMA32, order);
if (mmu_base->pages == NULL) {
pr_err("Can not alloc pages for mmu_base->pages\n");
@@ -219,6 +231,38 @@
kfree(base);
*mmu_base = NULL;
+}
+
+static int rga_iommu_intr_fault_handler(struct iommu_domain *iommu, struct device *iommu_dev,
+ unsigned long iova, int status, void *arg)
+{
+ struct rga_scheduler_t *scheduler = (struct rga_scheduler_t *)arg;
+ struct rga_job *job = scheduler->running_job;
+
+ if (job == NULL)
+ return 0;
+
+ pr_err("IOMMU intr fault, IOVA[0x%lx], STATUS[0x%x]\n", iova, status);
+ if (scheduler->ops->irq)
+ scheduler->ops->irq(scheduler);
+
+ /* iommu interrupts on rga2 do not affect rga2 itself. */
+ if (!test_bit(RGA_JOB_STATE_INTR_ERR, &job->state)) {
+ set_bit(RGA_JOB_STATE_INTR_ERR, &job->state);
+ scheduler->ops->soft_reset(scheduler);
+ }
+
+ if (status & RGA_IOMMU_IRQ_PAGE_FAULT) {
+ pr_err("RGA IOMMU: page fault! Please check the memory size.\n");
+ job->ret = -EACCES;
+ } else if (status & RGA_IOMMU_IRQ_BUS_ERROR) {
+ pr_err("RGA IOMMU: bus error! Please check if the memory is invalid or has been freed.\n");
+ job->ret = -EACCES;
+ } else {
+ pr_err("RGA IOMMU: Wrong IOMMU interrupt signal!\n");
+ }
+
+ return 0;
}
int rga_iommu_detach(struct rga_iommu_info *info)
@@ -306,6 +350,9 @@
if (main_iommu == NULL) {
main_iommu = scheduler->iommu_info;
main_iommu_index = i;
+ iommu_set_fault_handler(main_iommu->domain,
+ rga_iommu_intr_fault_handler,
+ (void *)scheduler);
} else {
scheduler->iommu_info->domain = main_iommu->domain;
scheduler->iommu_info->default_dev = main_iommu->default_dev;
--
Gitblit v1.6.2