Re: [PATCH] drm/nouveau/gsp: only handle GSP interrupts routed to the host

From: David Airlie

Date: Sat Oct 24 2026 - 03:07:32 EST


On Fri, Oct 23, 2026 at 7:38 PM Joe Finzel via B4 Relay
<devnull+joe.sudmix.de@xxxxxxxxxx> wrote:
>
> From: Joe Finzel <joe@xxxxxxxxx>
>
> The GSP's interrupt handler takes every pending interrupt the RISC-V
> IRQMASK enables as its own, without looking at IRQDEST, which says
> whether an interrupt goes to the host or to the GSP itself. One that
> belongs to GSP-RM, pending when the host's handler runs for the message
> queue, is reported as unknown, cleared and masked off with IRQMCLR,
> taking it away from the firmware:
>
> nouveau 0000:01:00.0: gsp: intr 00040000
>
> NVIDIA's driver reads the interrupts routed to the host as
> IRQSTAT & IRQMASK & IRQDEST (kflcnRiscvReadIntrStatus_TU102() and
> _GA102()). Do the same, with IRQDEST from NVIDIA's register headers
> next to IRQMASK on each falcon.
>
> Seen once in a few boots on an RTX 3070 Ti (GA104, GSP-RM 570.144),
> before the login prompt. There IRQMASK reads 0x01049042 and IRQDEST
> 0x01000040: 0x00040000 is enabled but routed to the GSP.
>
> Fixes: 830531e94712 ("drm/nouveau/gsp/r535: add interrupt handling")
> Cc: stable@xxxxxxxxxxxxxxx
> Signed-off-by: Joe Finzel <joe@xxxxxxxxx>

This seems very reasonable.


Reviewed-by: Dave Airlie <airlied@xxxxxxxxxx>

> ---
> drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h | 1 +
> drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga100.c | 1 +
> drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c | 1 +
> drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c | 4 +++-
> drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c | 1 +
> 5 files changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h
> index 341f133dc38..eb8adaf07fe 100644
> --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h
> +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h
> @@ -63,6 +63,7 @@ struct nvkm_falcon_func {
> int (*select)(struct nvkm_falcon *);
> u32 addr2;
> u32 riscv_irqmask;
> + u32 riscv_irqdest;
> bool reset_pmc;
> int (*reset_eng)(struct nvkm_falcon *);
> int (*reset_prep)(struct nvkm_falcon *);
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga100.c
> index d5126fe39d2..10e2813a016 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga100.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga100.c
> @@ -27,6 +27,7 @@ ga100_gsp_flcn = {
> .enable = gm200_flcn_enable,
> .addr2 = 0x1000,
> .riscv_irqmask = 0x2b4,
> + .riscv_irqdest = 0x2b8,
> .reset_eng = gp102_flcn_reset_eng,
> .reset_wait_mem_scrubbing = gm200_flcn_reset_wait_mem_scrubbing,
> .bind_inst = gm200_flcn_bind_inst,
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c
> index b6b3eb6f4c0..96fa26fa612 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/ga102.c
> @@ -140,6 +140,7 @@ ga102_gsp_flcn = {
> .select = ga102_flcn_select,
> .addr2 = 0x1000,
> .riscv_irqmask = 0x528,
> + .riscv_irqdest = 0x52c,
> .reset_eng = gp102_flcn_reset_eng,
> .reset_prep = ga102_flcn_reset_prep,
> .reset_wait_mem_scrubbing = ga102_flcn_reset_wait_mem_scrubbing,
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c
> index 94925f1590e..463e463db24 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c
> @@ -64,7 +64,9 @@ r535_gsp_intr(struct nvkm_inth *inth)
> u32 intr = nvkm_falcon_rd32(&gsp->falcon, 0x0008);
> u32 inte = nvkm_falcon_rd32(&gsp->falcon, gsp->falcon.func->addr2 +
> gsp->falcon.func->riscv_irqmask);
> - u32 stat = intr & inte;
> + u32 dest = nvkm_falcon_rd32(&gsp->falcon, gsp->falcon.func->addr2 +
> + gsp->falcon.func->riscv_irqdest);
> + u32 stat = intr & inte & dest;
>
> if (!stat) {
> nvkm_debug(subdev, "inte %08x %08x\n", intr, inte);
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c
> index 11a37963bd4..823532758af 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c
> @@ -420,6 +420,7 @@ tu102_gsp_flcn = {
> .enable = gm200_flcn_enable,
> .addr2 = 0x1000,
> .riscv_irqmask = 0x2b4,
> + .riscv_irqdest = 0x2b8,
> .reset_eng = gp102_flcn_reset_eng,
> .reset_wait_mem_scrubbing = gm200_flcn_reset_wait_mem_scrubbing,
> .bind_inst = gm200_flcn_bind_inst,
>
> ---
> base-commit: fb26cf4f1df40a462ea65552a3fbcc8cfafab523
> change-id: 20261023-nouveau-gsp-irqdest-a0819d1eda96
>
> Best regards,
> --
> Joe Finzel <joe@xxxxxxxxx>
>
>