dri-devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Lyude Paul" <lyude@redhat.com>
Cc: dri-devel@lists.freedesktop.org
Subject: Re: [PATCH 1/5] drm/nouveau/gsp/r535: Add support for INTERNAL_GCX_ENTRY_PREREQUISITE
Date: Fri, 11 Sep 2026 22:36:50 +0000	[thread overview]
Message-ID: <20260911223650.8F0F61F000FF@smtp.kernel.org> (raw)
In-Reply-To: <20260911222428.752641-2-lyude@redhat.com>

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] Negative error codes from `nvif_device_gcx_ready()` are treated as bitmasks, leading to unpredictable runtime suspend behavior.
- [High] Hardcoding `r535_gsp_gcx_ready(gsp)` bypasses the GSP function vtable and will cause a NULL pointer dereference on non-RM GSPs.
- [Medium] `nvkm_udevice_gcx_ready()` bypasses the ioctl unpack protocol and returns a positive bitmask directly as a return code.
- [Low] `GSP_GCX_ENTRY_GC6_READY` and `GSP_GCX_ENTRY_GCOFF_READY` are defined but never used.
--

commit 9f05a64653e46f7b990f534168f7024b8a4d408a
Author: Lyude Paul <lyude@redhat.com>

drm/nouveau/gsp/r535: Add support for INTERNAL_GCX_ENTRY_PREREQUISITE

OpenRM consults GSP to check if the GPU should be allowed to enter Gc6
and/or GcOff before runtime suspending. If not ready, runtime suspend is
delayed. This commit implements the NV2080_CTRL_CMD_INTERNAL_GCX_ENTRY_PREREQUISITE
query and adds readiness checks in nouveau_pmops_runtime_suspend().

> diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h
> --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h
> +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h
> @@ -10,6 +10,9 @@
>  #define GSP_PAGE_SHIFT 12
>  #define GSP_PAGE_SIZE  BIT(GSP_PAGE_SHIFT)
>  
> +#define GSP_GCX_ENTRY_GC6_READY		BIT(0)
> +#define GSP_GCX_ENTRY_GCOFF_READY	BIT(1)

[Severity: Low]
This isn't a bug, but these macros appear to be unused in this patch?
It looks like NV_DEVICE_GC6_READY and NV_DEVICE_GCOFF_READY are used
instead throughout the rest of the implementation.

[ ... ]

> diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
> --- a/drivers/gpu/drm/nouveau/nouveau_drm.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
> @@ -1157,6 +1157,7 @@ nouveau_pmops_runtime_suspend(struct device *dev)
>  {
>  	struct pci_dev *pdev = to_pci_dev(dev);
>  	struct nouveau_drm *drm = pci_get_drvdata(pdev);
> +	struct nvif_device *nvif = &drm->client.device;
>  	int ret;
>  
>  	if (!nouveau_pmops_runtime()) {
> @@ -1164,6 +1165,14 @@ nouveau_pmops_runtime_suspend(struct device *dev)
>  		return -EBUSY;
>  	}
>  
> +	// Check if the GPU itself is ready for runtime suspend, otherwise mark as busy and check
> +	// again in a bit.
> +	if (!(nvif_device_gcx_ready(nvif) & NV_DEVICE_GCOFF_READY)) {

[Severity: High]
Can this bitwise check misinterpret negative error codes?

Looking at nvif_device_gcx_ready(), it can return negative error codes
like -ENOSYS or other transport errors. Since negative numbers usually
have higher bits set in two's complement (e.g., -ENOSYS often has bit 1
set), the bitwise AND with NV_DEVICE_GCOFF_READY (which is BIT(1)) might
evaluate to non-zero.

This could cause the driver to mistakenly assume the GPU is ready and
proceed with runtime suspend when the query actually failed, leading to
unpredictable power transition behavior.

> +		NV_DEBUG(drm, "GPU isn't ready for suspend yet, delaying...\n");
> +		pm_runtime_mark_last_busy(dev);
> +		return -EBUSY;
> +	}

[ ... ]

> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c
> --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c
> @@ -189,6 +191,38 @@ nvkm_udevice_time(struct nvkm_udevice *udev, void *data, u32 size)
>  	return ret;
>  }
>  
> +static int
> +nvkm_udevice_gcx_ready(struct nvkm_udevice *udev, void *data, u32 size)
> +{
> +	struct nvkm_object *object = &udev->object;
> +	struct nvkm_device *device = udev->device;
> +	struct nvkm_gsp *gsp = device->gsp;
> +	union {
> +		struct nv_device_gcx_ready_v0 v0;
> +	} *args = data;
> +	int ret = -ENOSYS;
> +
> +	/* XXX: We don't know any way of performing this check outside of GSP, so just assume
> +	 * things are ready for non-GSP clients.
> +	 */
> +	if (!device->gsp)
> +		return NV_DEVICE_GC6_READY | NV_DEVICE_GCOFF_READY;

[Severity: Medium]
Does this early return break the NVIF mthd API contract?

The convention for mthd handlers is generally to unpack the arguments,
set the output fields in the args struct, and return 0 on success. Returning
a positive bitmask directly here bypasses the nvif_unpack sequence.

This positive value then bubbles up to the caller in nvif_device_gcx_ready(),
where it acts as a pseudo-error code and leaves the actual args.ready field
uninitialized.

> +
> +	nvif_ioctl(object, "device gcx ready size %d\n", size);
> +	if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
> +		nvif_ioctl(object, "device gcx ready vers %d\n", args->v0.version);
> +
> +		ret = r535_gsp_gcx_ready(gsp);

[Severity: High]
Could this lead to a NULL pointer dereference on architectures running
without full Resource Manager (RM) functionality?

When falling back to firmware like gv100_gsp_nofw (e.g., on Turing or
Ampere), device->gsp is non-NULL, so the early return above is bypassed.
However, the RM structures are not initialized.

When r535_gsp_gcx_ready() is called in this state, it eventually invokes
nvkm_gsp_rm_ctrl_rd() -> nvkm_gsp_rm_ctrl_get(), which attempts to
dereference object->client->gsp->rm->api. If gsp->rm is NULL, this will
crash.

Would checking for !nvkm_gsp_rm(device->gsp) rather than !device->gsp
safeguard against this?

> +		if (ret < 0)
> +			return ret;

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260911222428.752641-1-lyude@redhat.com?part=1

  reply	other threads:[~2026-09-11 22:36 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-11 21:49 [PATCH 0/5] drm/nouveau/gsp/r570: Follow OpenRM's runtime PM process more closely Lyude Paul
2026-09-11 21:49 ` [PATCH 1/5] drm/nouveau/gsp/r535: Add support for INTERNAL_GCX_ENTRY_PREREQUISITE Lyude Paul
2026-09-11 22:36   ` sashiko-bot [this message]
2026-09-11 21:49 ` [PATCH 2/5] drm/nouveau/gsp/r535: Add support for MEMSYS_GET_STATIC_CONFIG Lyude Paul
2026-09-11 22:34   ` sashiko-bot
2026-09-11 21:49 ` [PATCH 3/5] drm/nouveau/gsp/r570: Add comp mode workaround from issue #3172217 Lyude Paul
2026-09-11 22:37   ` sashiko-bot
2026-09-11 21:49 ` [PATCH 4/5] drm/nouveau/gsp/r570: Start saving comptag backing stores Lyude Paul
2026-09-11 22:43   ` sashiko-bot
2026-09-11 21:49 ` [PATCH 5/5] drm/nouveau/gsp/r570: Enable Gcoff in fbsr again Lyude Paul
2026-09-11 22:49   ` sashiko-bot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260911223650.8F0F61F000FF@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=lyude@redhat.com \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox