mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] drm/i915/irq: crtc guard inside interrupt handlers
@ 2026-09-25 11:55 Marcel Hamer
  2026-09-25 12:48 ` Jani Nikula
  0 siblings, 1 reply; 2+ messages in thread
From: Marcel Hamer @ 2026-09-25 11:55 UTC (permalink / raw)
  To: Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
	David Airlie, Simona Vetter, Ville Syrjälä,
	Vinod Govindapillai
  Cc: Marcel Hamer, stable, intel-gfx, intel-xe, dri-devel, linux-kernel

Interrupts are enabled before the crtc datastructures are initialized.
As intel_crtc_for_pipe() is called inside interrupt handlers and can
return a NULL value, this can in rare cases lead to the following NULL
pointer dereference and panic:

RIP: 0010:handle_plane_fault+0x19/0xc0 [i915]
Code: 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa 0f
1f 44 00 00 55 48 89 e5 41 55 41 54 49 89 fc 53 48 83 ec 18 <48> 8b 1f
65 4c 8b 2d 24 90 31 ef 4c 89 6d e0 41 89 f5 48 85 db 74
RSP:
0018:ffff92b180003e50 EFLAGS: 00010086
RAX: ffffffffc0911fc0 RBX: ffffffffc06e0b90 RCX: 0000000000000005
RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
RBP: ffff92b180003e80 R08: 0000000000000005 R09: 000000010517d5f6
R10: 0000008000000041 R11: 000000010517d5f6 R12: 0000000000000000
R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
FS:  00007f72f5b72780(0000) GS:ffff8bbdcbfe9000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000000000000 CR3: 0000000102f2c000 CR4: 00000000003506f0
Kernel panic - not syncing: Fatal exception in interrupt
Kernel Offset: 0x2c800000 from 0xffffffff81000000 (relocation range:
0xffffffff80000000-0xffffffffbfffffff)
Call Trace:
 <IRQ>
 intel_pipe_fault_irq_handler+0x42/0xc0 [i915]
 gen8_de_irq_handler+0x1ed/0xdf0 [i915]
 gen8_irq_handler+0xb5/0xd0 [i915]
 __handle_irq_event_percpu+0x6e/0x230
 handle_irq_event+0x3a/0x90
 handle_edge_irq+0xd1/0x1a0
 __common_interrupt+0x48/0xe0
 ? generic_smp_call_function_single_interrupt+0x17/0x20
 common_interrupt+0x84/0xa0

Fixes: f13011a79999 ("drm/i915: Pimp display fault reporting")
Fixes: 138d2bda4eaf ("drm/i915/display: pass display to intel_crtc_for_pipe()")
Cc: stable@vger.kernel.org # 6.18.x
Signed-off-by: Marcel Hamer <marcel@solidxs.se>
---
 drivers/gpu/drm/i915/display/intel_display_irq.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c
index a59b75830bd1..4ffc8789c9f3 100644
--- a/drivers/gpu/drm/i915/display/intel_display_irq.c
+++ b/drivers/gpu/drm/i915/display/intel_display_irq.c
@@ -131,6 +131,9 @@ static void intel_pipe_fault_irq_handler(struct intel_display *display,
 	struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe);
 	const struct pipe_fault_handler *handler;
 
+	if (!crtc)
+		return;
+
 	for (handler = handlers; handler && handler->fault; handler++) {
 		if ((fault_errors & handler->fault) == 0)
 			continue;
@@ -148,7 +151,8 @@ intel_handle_vblank(struct intel_display *display, enum pipe pipe)
 {
 	struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe);
 
-	drm_crtc_handle_vblank(&crtc->base);
+	if (crtc)
+		drm_crtc_handle_vblank(&crtc->base);
 }
 
 /**
@@ -425,9 +429,14 @@ static void display_pipe_crc_irq_handler(struct intel_display *display,
 					 u32 crc4)
 {
 	struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe);
-	struct intel_pipe_crc *pipe_crc = &crtc->pipe_crc;
+	struct intel_pipe_crc *pipe_crc;
 	u32 crcs[5] = { crc0, crc1, crc2, crc3, crc4 };
 
+	if (!crtc)
+		return;
+
+	pipe_crc = &crtc->pipe_crc;
+
 	trace_intel_pipe_crc(crtc, crcs);
 
 	spin_lock(&pipe_crc->lock);
@@ -465,6 +474,9 @@ static void flip_done_handler(struct intel_display *display,
 {
 	struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe);
 
+	if (!crtc)
+		return;
+
 	spin_lock(&display->drm->event_lock);
 
 	if (crtc->flip_done_event) {

base-commit: f49a343b305c0b6c19a3b50c0bbf10bcd0e2e8fd
-- 
2.47.3


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] drm/i915/irq: crtc guard inside interrupt handlers
  2026-09-25 11:55 [PATCH] drm/i915/irq: crtc guard inside interrupt handlers Marcel Hamer
@ 2026-09-25 12:48 ` Jani Nikula
  0 siblings, 0 replies; 2+ messages in thread
From: Jani Nikula @ 2026-09-25 12:48 UTC (permalink / raw)
  To: Marcel Hamer, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
	David Airlie, Simona Vetter, Ville Syrjälä,
	Vinod Govindapillai
  Cc: Marcel Hamer, stable, intel-gfx, intel-xe, dri-devel, linux-kernel

On Fri, 25 Sep 2026, Marcel Hamer <marcel@solidxs.se> wrote:
> Interrupts are enabled before the crtc datastructures are initialized.
> As intel_crtc_for_pipe() is called inside interrupt handlers and can
> return a NULL value, this can in rare cases lead to the following NULL
> pointer dereference and panic:
>
> RIP: 0010:handle_plane_fault+0x19/0xc0 [i915]
> Code: 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa 0f
> 1f 44 00 00 55 48 89 e5 41 55 41 54 49 89 fc 53 48 83 ec 18 <48> 8b 1f
> 65 4c 8b 2d 24 90 31 ef 4c 89 6d e0 41 89 f5 48 85 db 74
> RSP:
> 0018:ffff92b180003e50 EFLAGS: 00010086
> RAX: ffffffffc0911fc0 RBX: ffffffffc06e0b90 RCX: 0000000000000005
> RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
> RBP: ffff92b180003e80 R08: 0000000000000005 R09: 000000010517d5f6
> R10: 0000008000000041 R11: 000000010517d5f6 R12: 0000000000000000
> R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
> FS:  00007f72f5b72780(0000) GS:ffff8bbdcbfe9000(0000) knlGS:0000000000000000
> CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> CR2: 0000000000000000 CR3: 0000000102f2c000 CR4: 00000000003506f0
> Kernel panic - not syncing: Fatal exception in interrupt
> Kernel Offset: 0x2c800000 from 0xffffffff81000000 (relocation range:
> 0xffffffff80000000-0xffffffffbfffffff)
> Call Trace:
>  <IRQ>
>  intel_pipe_fault_irq_handler+0x42/0xc0 [i915]
>  gen8_de_irq_handler+0x1ed/0xdf0 [i915]
>  gen8_irq_handler+0xb5/0xd0 [i915]
>  __handle_irq_event_percpu+0x6e/0x230
>  handle_irq_event+0x3a/0x90
>  handle_edge_irq+0xd1/0x1a0
>  __common_interrupt+0x48/0xe0
>  ? generic_smp_call_function_single_interrupt+0x17/0x20
>  common_interrupt+0x84/0xa0
>
> Fixes: f13011a79999 ("drm/i915: Pimp display fault reporting")
> Fixes: 138d2bda4eaf ("drm/i915/display: pass display to intel_crtc_for_pipe()")
> Cc: stable@vger.kernel.org # 6.18.x
> Signed-off-by: Marcel Hamer <marcel@solidxs.se>

Please file a bug as described at [1], attaching full dmesg reproducing
the problem. I don't think we're seeing this in our CI, so would be good
to understand the root cause better.

BR,
Jani.


[1] https://drm.pages.freedesktop.org/intel-docs/how-to-file-i915-bugs.html


> ---
>  drivers/gpu/drm/i915/display/intel_display_irq.c | 16 ++++++++++++++--
>  1 file changed, 14 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c
> index a59b75830bd1..4ffc8789c9f3 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_irq.c
> +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c
> @@ -131,6 +131,9 @@ static void intel_pipe_fault_irq_handler(struct intel_display *display,
>  	struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe);
>  	const struct pipe_fault_handler *handler;
>  
> +	if (!crtc)
> +		return;
> +
>  	for (handler = handlers; handler && handler->fault; handler++) {
>  		if ((fault_errors & handler->fault) == 0)
>  			continue;
> @@ -148,7 +151,8 @@ intel_handle_vblank(struct intel_display *display, enum pipe pipe)
>  {
>  	struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe);
>  
> -	drm_crtc_handle_vblank(&crtc->base);
> +	if (crtc)
> +		drm_crtc_handle_vblank(&crtc->base);
>  }
>  
>  /**
> @@ -425,9 +429,14 @@ static void display_pipe_crc_irq_handler(struct intel_display *display,
>  					 u32 crc4)
>  {
>  	struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe);
> -	struct intel_pipe_crc *pipe_crc = &crtc->pipe_crc;
> +	struct intel_pipe_crc *pipe_crc;
>  	u32 crcs[5] = { crc0, crc1, crc2, crc3, crc4 };
>  
> +	if (!crtc)
> +		return;
> +
> +	pipe_crc = &crtc->pipe_crc;
> +
>  	trace_intel_pipe_crc(crtc, crcs);
>  
>  	spin_lock(&pipe_crc->lock);
> @@ -465,6 +474,9 @@ static void flip_done_handler(struct intel_display *display,
>  {
>  	struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe);
>  
> +	if (!crtc)
> +		return;
> +
>  	spin_lock(&display->drm->event_lock);
>  
>  	if (crtc->flip_done_event) {
>
> base-commit: f49a343b305c0b6c19a3b50c0bbf10bcd0e2e8fd

-- 
Jani Nikula, Intel

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-09-25 12:48 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-25 11:55 [PATCH] drm/i915/irq: crtc guard inside interrupt handlers Marcel Hamer
2026-09-25 12:48 ` Jani Nikula

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®