Commit c6f3eafd authored by Erico Nunes's avatar Erico Nunes Committed by Jinjiang Tu
Browse files

drm/lima: add mask irq callback to gp and pp

stable inclusion
from stable-v5.10.221
commit e12c363cf5fdd0decef467ee2c0069dcad267679
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IACV6I
CVE: CVE-2024-40976

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=e12c363cf5fdd0decef467ee2c0069dcad267679



--------------------------------

[ Upstream commit 49c13b4d2dd4a831225746e758893673f6ae961c ]

This is needed because we want to reset those devices in device-agnostic
code such as lima_sched.
In particular, masking irqs will be useful before a hard reset to
prevent race conditions.

Signed-off-by: default avatarErico Nunes <nunes.erico@gmail.com>
Signed-off-by: default avatarQiang Yu <yuq825@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240405152951.1531555-2-nunes.erico@gmail.com


Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Signed-off-by: default avatarJinjiang Tu <tujinjiang@huawei.com>
parent 1e94b0d2
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -43,6 +43,18 @@ void lima_bcast_suspend(struct lima_ip *ip)

}

int lima_bcast_mask_irq(struct lima_ip *ip)
{
	bcast_write(LIMA_BCAST_BROADCAST_MASK, 0);
	bcast_write(LIMA_BCAST_INTERRUPT_MASK, 0);
	return 0;
}

int lima_bcast_reset(struct lima_ip *ip)
{
	return lima_bcast_hw_init(ip);
}

int lima_bcast_init(struct lima_ip *ip)
{
	int i;
+3 −0
Original line number Diff line number Diff line
@@ -13,4 +13,7 @@ void lima_bcast_fini(struct lima_ip *ip);

void lima_bcast_enable(struct lima_device *dev, int num_pp);

int lima_bcast_mask_irq(struct lima_ip *ip);
int lima_bcast_reset(struct lima_ip *ip);

#endif
+8 −0
Original line number Diff line number Diff line
@@ -212,6 +212,13 @@ static void lima_gp_task_mmu_error(struct lima_sched_pipe *pipe)
	lima_sched_pipe_task_done(pipe);
}

static void lima_gp_task_mask_irq(struct lima_sched_pipe *pipe)
{
	struct lima_ip *ip = pipe->processor[0];

	gp_write(LIMA_GP_INT_MASK, 0);
}

static int lima_gp_task_recover(struct lima_sched_pipe *pipe)
{
	struct lima_ip *ip = pipe->processor[0];
@@ -344,6 +351,7 @@ int lima_gp_pipe_init(struct lima_device *dev)
	pipe->task_error = lima_gp_task_error;
	pipe->task_mmu_error = lima_gp_task_mmu_error;
	pipe->task_recover = lima_gp_task_recover;
	pipe->task_mask_irq = lima_gp_task_mask_irq;

	return 0;
}
+18 −0
Original line number Diff line number Diff line
@@ -408,6 +408,9 @@ static void lima_pp_task_error(struct lima_sched_pipe *pipe)

		lima_pp_hard_reset(ip);
	}

	if (pipe->bcast_processor)
		lima_bcast_reset(pipe->bcast_processor);
}

static void lima_pp_task_mmu_error(struct lima_sched_pipe *pipe)
@@ -416,6 +419,20 @@ static void lima_pp_task_mmu_error(struct lima_sched_pipe *pipe)
		lima_sched_pipe_task_done(pipe);
}

static void lima_pp_task_mask_irq(struct lima_sched_pipe *pipe)
{
	int i;

	for (i = 0; i < pipe->num_processor; i++) {
		struct lima_ip *ip = pipe->processor[i];

		pp_write(LIMA_PP_INT_MASK, 0);
	}

	if (pipe->bcast_processor)
		lima_bcast_mask_irq(pipe->bcast_processor);
}

static struct kmem_cache *lima_pp_task_slab;
static int lima_pp_task_slab_refcnt;

@@ -447,6 +464,7 @@ int lima_pp_pipe_init(struct lima_device *dev)
	pipe->task_fini = lima_pp_task_fini;
	pipe->task_error = lima_pp_task_error;
	pipe->task_mmu_error = lima_pp_task_mmu_error;
	pipe->task_mask_irq = lima_pp_task_mask_irq;

	return 0;
}
+1 −0
Original line number Diff line number Diff line
@@ -83,6 +83,7 @@ struct lima_sched_pipe {
	void (*task_error)(struct lima_sched_pipe *pipe);
	void (*task_mmu_error)(struct lima_sched_pipe *pipe);
	int (*task_recover)(struct lima_sched_pipe *pipe);
	void (*task_mask_irq)(struct lima_sched_pipe *pipe);

	struct work_struct recover_work;
};