On Fri, Oct 23, 2026 at 7:38 PM Joe Finzel via B4 Relay
<[email protected]> wrote:
>
> From: Joe Finzel <[email protected]>
>
> 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: [email protected]
> Signed-off-by: Joe Finzel <[email protected]>

This seems very reasonable.


Reviewed-by: Dave Airlie <[email protected]>

> ---
>  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 <[email protected]>
>
>

Reply via email to