FAILED: patch "[PATCH] drm/nouveau: unsubscribe the channel-kill event before the" failed to apply to 6.1-stable tree
Subsystems (4)
[email protected]
maintainerThe patch below does not apply to the 6.1-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.1.y
git checkout FETCH_HEAD
git cherry-pick -x 511585987d27d8cb668acebd399fc4deda23404c
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026090931-aqueduct-chafe-a114@gregkh' --subject-prefix 'PATCH 6.1.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 511585987d27d8cb668acebd399fc4deda23404c Mon Sep 17 00:00:00 2001
From: Marek Czernohous <[email protected]>
Date: Thu, 13 Aug 2026 01:13:27 +0200
Subject: [PATCH] drm/nouveau: unsubscribe the channel-kill event before the
fence context
nouveau_channel_del() tears the fence context down first and only drops the channel-kill subscription later, in the middle of the nvif object teardown:
if (chan->fence) nouveau_fence(chan->cli->drm)->context_del(chan); ... nvif_object_dtor(&chan->vram); nvif_event_dtor(&chan->kill);
The subscribed handler is nouveau_channel_killed(), which calls nouveau_channel_kill() and from there nouveau_fence_context_kill() on chan->fence. A kill event delivered in that window takes fctx->lock and walks fctx->pending on a fence context that context_del() has already freed.
Nothing reaches this below Fermi today, because the subscription is gated on FERMI_CHANNEL_GPFIFO and nothing kills a channel there. On Fermi and newer the window is real but narrow, since a kill has to land exactly while the channel is being destroyed. That is reason enough on its own, which is why this carries a Fixes: tag. The last patch in this series subscribes Tesla channels as well; nothing kills those today, so it does not widen the exposure now, but it is the groundwork for a recovery path that would, and the ordering is better fixed before that lands than alongside it.
Drop the subscription before anything it depends on is torn down.
drivers/gpu/drm/nouveau/nouveau_chan.c +8 -1
@@ -90,6 +90,14 @@ nouveau_channel_del(struct nouveau_channel **pchan) {struct nouveau_channel *chan = *pchan;if (chan) { +/* +* Drop the kill-event subscription first. Its handler +* dereferences chan->fence, which the fence context teardown +* below frees, so leaving it armed across the teardown leaves +* a window for a use-after-free. +*/ +nvif_event_dtor (&chan->kill); +if (chan->fence)nouveau_fence (chan->cli->drm)->context_del (chan);
@@ -100,7 +108,6 @@ nouveau_channel_del(struct nouveau_channel **pchan)nvif_object_dtor (&chan->nvsw);nvif_object_dtor (&chan->gart);nvif_object_dtor (&chan->vram); -nvif_event_dtor (&chan->kill);nvif_object_dtor (&chan->user);nvif_mem_dtor (&chan->mem_userd);nouveau_vma_del (&chan->sema.vma);
Sasha Levin
maintainerPATCH 1/2 drm/nouveau: get vmm via nouveau_cli_vmm()
From: Danilo Krummrich <[email protected]>
[ Upstream commit 7b05a7c0c9ca6e7e2d27181504920987226477e5 ]
Provide a getter function for the client's current vmm context. Since we'll add a new (u)vmm context for UMD bindings in subsequent commits, this will keep the code clean.
Stable-dep-of: 511585987d27 ("drm/nouveau: unsubscribe the channel-kill event before the fence context")
--- drivers/gpu/drm/nouveau/nouveau_bo.c | 2 +- drivers/gpu/drm/nouveau/nouveau_chan.c | 2 +- drivers/gpu/drm/nouveau/nouveau_drv.h | 9 +++++++++ drivers/gpu/drm/nouveau/nouveau_gem.c | 6 +++--- 4 files changed, 14 insertions(+), 5 deletions(-)
drivers/gpu/drm/nouveau/nouveau_bo.c +1 -1
@@ -206,7 +206,7 @@ nouveau_bo_alloc(struct nouveau_cli *cli, u64 *size, int *align, u32 domain,struct nouveau_drm *drm = cli->drm;struct nouveau_bo *nvbo;struct nvif_mmu *mmu = &cli->mmu; -struct nvif_vmm *vmm = cli->svm.cli ? &cli->svm.vmm : &cli->vmm.vmm; +struct nvif_vmm *vmm = &nouveau_cli_vmm (cli)->vmm;int i, pi =-1 ;if (!*size) {
drivers/gpu/drm/nouveau/nouveau_chan.c +1 -1
@@ -150,7 +150,7 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device, chan->device = device; chan->drm = drm; - chan->vmm = cli->svm.cli ? &cli->svm : &cli->vmm; + chan->vmm =nouveau_cli_vmm (cli);atomic_set (&chan->killed,0 );/* allocate memory for dma push buffer */
drivers/gpu/drm/nouveau/nouveau_drv.h +9 -0
@@ -118,6 +118,15 @@ struct nouveau_cli_work {struct dma_fence_cb cb; }; +static inline struct nouveau_vmm * +nouveau_cli_vmm (struct nouveau_cli *cli) +{ +if (cli->svm.cli) +return &cli->svm; + +return &cli->vmm; +} +void nouveau_cli_work_queue (struct nouveau_cli *,struct dma_fence *,struct nouveau_cli_work *);
drivers/gpu/drm/nouveau/nouveau_gem.c +3 -3
@@ -100,7 +100,7 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv)struct nouveau_bo *nvbo =nouveau_gem_object (gem);struct nouveau_drm *drm =nouveau_bdev (nvbo->bo.bdev);struct device *dev = drm->dev->dev; -struct nouveau_vmm *vmm = cli->svm.cli ? &cli->svm : &cli->vmm; +struct nouveau_vmm *vmm =nouveau_cli_vmm (cli);struct nouveau_vma *vma;int ret;
@@ -177,7 +177,7 @@ nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv)struct nouveau_bo *nvbo =nouveau_gem_object (gem);struct nouveau_drm *drm =nouveau_bdev (nvbo->bo.bdev);struct device *dev = drm->dev->dev; -struct nouveau_vmm *vmm = cli->svm.cli ? &cli->svm : & cli->vmm; +struct nouveau_vmm *vmm =nouveau_cli_vmm (cli);struct nouveau_vma *vma;int ret;
@@ -266,7 +266,7 @@ nouveau_gem_info(struct drm_file *file_priv, struct drm_gem_object *gem, {struct nouveau_cli *cli =nouveau_cli (file_priv);struct nouveau_bo *nvbo =nouveau_gem_object (gem); -struct nouveau_vmm *vmm = cli->svm.cli ? &cli->svm : &cli->vmm; +struct nouveau_vmm *vmm =nouveau_cli_vmm (cli);struct nouveau_vma *vma;if (is_power_of_2 (nvbo->valid_domains))
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/2 drm/nouveau: unsubscribe the channel-kill event before the fence context
From: Marek Czernohous <[email protected]>
[ Upstream commit 511585987d27d8cb668acebd399fc4deda23404c ]
nouveau_channel_del() tears the fence context down first and only drops the channel-kill subscription later, in the middle of the nvif object teardown:
if (chan->fence) nouveau_fence(chan->cli->drm)->context_del(chan); ... nvif_object_dtor(&chan->vram); nvif_event_dtor(&chan->kill);
The subscribed handler is nouveau_channel_killed(), which calls nouveau_channel_kill() and from there nouveau_fence_context_kill() on chan->fence. A kill event delivered in that window takes fctx->lock and walks fctx->pending on a fence context that context_del() has already freed.
Nothing reaches this below Fermi today, because the subscription is gated on FERMI_CHANNEL_GPFIFO and nothing kills a channel there. On Fermi and newer the window is real but narrow, since a kill has to land exactly while the channel is being destroyed. That is reason enough on its own, which is why this carries a Fixes: tag. The last patch in this series subscribes Tesla channels as well; nothing kills those today, so it does not widen the exposure now, but it is the groundwork for a recovery path that would, and the ordering is better fixed before that lands than alongside it.
Drop the subscription before anything it depends on is torn down.
--- drivers/gpu/drm/nouveau/nouveau_chan.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
drivers/gpu/drm/nouveau/nouveau_chan.c +8 -1
@@ -87,6 +87,14 @@ nouveau_channel_del(struct nouveau_channel **pchan)if (chan) {struct nouveau_cli *cli = (void *)chan->user.client; +/* +* Drop the kill-event subscription first. Its handler +* dereferences chan->fence, which the fence context teardown +* below frees, so leaving it armed across the teardown leaves +* a window for a use-after-free. +*/ +nvif_notify_dtor (&chan->kill); +if (chan->fence)nouveau_fence (chan->drm)->context_del (chan);
@@ -96,7 +104,6 @@ nouveau_channel_del(struct nouveau_channel **pchan)nvif_object_dtor (&chan->nvsw);nvif_object_dtor (&chan->gart);nvif_object_dtor (&chan->vram); -nvif_notify_dtor (&chan->kill);nvif_object_dtor (&chan->user);nvif_object_dtor (&chan->push.ctxdma);nouveau_vma_del (&chan->push.vma);
Signature · 1 line
2.53.0