Skip to content

[26.04_linux-nvidia] fix CMDQV teardown on unbind, probe failure, and shutdown/kexec - #689

Closed
NathanChenNVIDIA wants to merge 3 commits into
NVIDIA:26.04_linux-nvidiafrom
NathanChenNVIDIA:cmdqvfixes_26.04_linux-nvidia
Closed

NathanChenNVIDIA wants to merge 3 commits into
NVIDIA:26.04_linux-nvidiafrom
NathanChenNVIDIA:cmdqvfixes_26.04_linux-nvidia

Conversation

@NathanChenNVIDIA

@NathanChenNVIDIA NathanChenNVIDIA commented Nov 5, 2026 •

Copy link
Copy Markdown
Collaborator

Description

This PR backports three upstream fixes for tegra241-cmdqv teardown. They move SMMU teardown to devm, stop VINTF deinit from issuing a CMD_SYNC on a freed command queue during probe-failure unwind and vIOMMU destroy, and quiesce the VINTFs on shutdown and kexec.

Commits

  • 7d8c870b84bb iommu/arm-smmu-v3: Manage teardown with devm (upstream 2bd22a0d4050)
  • 3f303b85dd4d iommu/tegra241-cmdqv: Fix CMD_SYNC use-after-free on teardown (upstream 9ff145a25c5c)
  • a19853cb9e2f iommu/arm-smmu-v3: Disable the impl before disabling the SMMU on shutdown (upstream ab0dbf411ace)

Testing

Tested with the equivalent backport on the 26.04_linux-nvidia-bos tree on a Vera system with CMDQV enabled.

  • Boot and DMA: the SMMUs and CMDQVs probe cleanly. NVMe fio wrote and verified 32 GiB, and NIC transfers arrived intact, in both passthrough and translated (iommu.passthrough=0) modes.
  • Host reboot and kexec: kexec plus 3 reboots, including a shutdown with translated domains active. No oops, CMD_SYNC timeouts or CMDQV errors on serial, and a clean probe every time.
  • vIOMMU destroy: QEMU with iommufd, arm-smmuv3,accel=on,cmdqv=on and GPU passthrough. After both a clean poweroff and a kill -9, the host showed no errors and the VM restarted cleanly.
  • Guest reboot and kexec: the same kernel running in the vCMDQ VM survived 3 guest reboots and a guest kexec into translated mode. The guest console showed no CMD_SYNC timeouts or CMDQV errors, and the guest's CMDQV and VCMDQs probed cleanly every time.
  • Probe-failure unwind: forcing the VCMDQ enable to fail with a debug patch (not included) gives probe ... failed with error -110 and no oops.

LP: https://bugs.launchpad.net/ubuntu/+source/linux-nvidia/+bug/2173553

Shameer Kolothum and others added 3 commits November 5, 2026 17:32
arm_smmu_device_remove() manually frees the IOPF queue, destroys the
vmid_map and disables the device, while the IRQs and queues are devm
managed. devm unwinds only after remove() returns, so the cleanup runs
in the wrong order. The IOPF queue is freed before the event-queue IRQ
whose handler uses it.

Manage all of it with devm so the unwind order is correct. Free the IOPF
queue and vmid_map via devm actions, and disable the device from one
registered after arm_smmu_device_reset().

This is also a prerequisite for fixing a Tegra241 CMDQV CMD_SYNC
use-after-free in the subsequent patch.

Cc: stable@vger.kernel.org
Suggested-by: Jason Gunthorpe <jgg@ziepe.ca>
Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Will Deacon <will@kernel.org>
(cherry picked from commit 2bd22a0)
Signed-off-by: Nathan Chen <nathanc@nvidia.com>
arm_smmu_impl_remove() is registered as a devres action in
arm_smmu_impl_probe(), before arm_smmu_init_queues() allocates
smmu->cmdq.q.base. On a devres unwind, whether a failed probe or an
unbind, the queue is freed first and arm_smmu_impl_remove() then runs
tegra241_cmdqv_remove_vintf(), whose VINTF deinit issues a CMD_SYNC on
the freed memory.

Observed during testing with a QEMU hack that makes the VCMDQ fail to
enable, so the impl reset fails and probe aborts into the devres unwind:

 platform NVDA200C:00: tegra241_cmdqv: VINTF0: VCMDQ0/LVCMDQ0: failed to enable, STATUS=0x00000000
 platform NVDA200C:00: tegra241_cmdqv: VINTF0: VCMDQ0/LVCMDQ0: GERRORN=0x0, GERROR=0x4, CONS=0x0
 platform NVDA200C:00: tegra241_cmdqv: VINTF0: VCMDQ0/LVCMDQ0: uncleared error detected, resetting
 arm-smmu-v3 arm-smmu-v3.0.auto: failed to reset impl
 arm-smmu-v3 arm-smmu-v3.0.auto: probe with driver arm-smmu-v3 failed with error -110
 Unable to handle kernel paging request at virtual address ffff8000891e0098
 ...
 Internal error: Oops: 0000000096000047 [NVIDIA#1] SMP
 ...
 Call trace:
  arm_smmu_cmdq_issue_cmdlist+0x320/0x6fc (P)
  tegra241_vcmdq_hw_deinit+0x98/0x168
  tegra241_vintf_hw_deinit+0x5c/0x1b0
  tegra241_cmdqv_remove_vintf+0x34/0xec
  tegra241_cmdqv_remove+0x40/0x9c
  arm_smmu_impl_remove+0x20/0x30
  devm_action_release+0x14/0x20
  devres_release_all+0xa8/0x110
  device_unbind_cleanup+0x18/0x84
  really_probe+0x1f0/0x29c

Drop the VINTF deinit from tegra241_cmdqv_remove_vintf() so the unwind no
longer touches the freed queue. Quiesce the VINTFs earlier instead. Add a
device_disable() impl op and run it from arm_smmu_disable_action() while
the CMDQ is still up. That handles a live unbind. A failed reset is already
handled because tegra241_vintf_hw_init() deinits the VINTF on its own error
path. tegra241_cmdqv_remove_vintf() is also used by the iommufd viommu
destroy path, so quiesce there too.

Fixes: 4dc0d12 ("iommu/tegra241-cmdqv: Add user-space use support")
Cc: stable@vger.kernel.org
Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Will Deacon <will@kernel.org>
(cherry picked from commit 9ff145a)
Signed-off-by: Nathan Chen <nathanc@nvidia.com>
…down

arm_smmu_device_shutdown() only calls arm_smmu_device_disable(), and never
the impl_ops->device_disable() hook. On tegra241-cmdqv, that hook quiesces
every VINTF through tegra241_vintf_hw_deinit(), which issues a CMD_SYNC on
the shared CMDQ while it is still enabled.

arm_smmu_disable_action() already runs this hook before disabling the SMMU,
to cover an unbind or a probe failure, and no devres release ever follows a
reboot or a kexec to run it again. Have arm_smmu_device_shutdown() call it
directly, instead of reimplementing part of what it already does.

Fixes: 9ff145a ("iommu/tegra241-cmdqv: Fix CMD_SYNC use-after-free on teardown")
Cc: stable@vger.kernel.org
Reviewed-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Assisted-by: LLM
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Will Deacon <will@kernel.org>
(cherry picked from commit ab0dbf4)
Signed-off-by: Nathan Chen <nathanc@nvidia.com>
@nirmoy nirmoy added the help wanted Extra attention is needed label Nov 5, 2026
@nirmoy

nirmoy commented Nov 5, 2026 •

Copy link
Copy Markdown
Collaborator

BaseOS Kernel Review

Caution

⚠️ Review incomplete

Boro could not review 3 commits.

Findings: unavailable because the review failed
Review failures: 3

🔍 Review artifacts

📦 Build checks — 🟢 4/4 passed

Install the PR kernel with APT

Published for reviewed head 796dc12983d7: resolute/arm64. Requires the NVIDIA network.

curl -fsS https://baseos-reviewer-66d7b9.gitlab-master-pages.nvidia.com/install.sh | bash -s -- install pr-689

Manual setup · signing fingerprint DF52E10C47F28AC221DA19ED6D25A5DFC6686DFC

Manual commands for Ubuntu 26.04 Resolute / arm64 (Grace), on the NVIDIA network:

(
set -euo pipefail
work=$(mktemp -d)
trap 'rm -rf -- "$work"' EXIT
curl -qfsS --proto '=https' -o "$work/archive-keyring.gpg" https://baseos-reviewer-66d7b9.gitlab-master-pages.nvidia.com/archive-keyring.gpg
curl -qfsS --proto '=https' -o "$work/baseos-internal-tools.crt" https://baseos-reviewer-66d7b9.gitlab-master-pages.nvidia.com/baseos-internal-tools.crt
sudo install -d -m 0755 /etc/apt/keyrings
sudo install -m 0644 "$work/archive-keyring.gpg" /usr/share/keyrings/baseos-pr-kernels.gpg
sudo install -m 0644 "$work/baseos-internal-tools.crt" /etc/apt/keyrings/baseos-pr-https.crt
printf '%s\n' \
  'Acquire::https::baseos-internal-tools.nvidia.com::CaInfo "/etc/apt/keyrings/baseos-pr-https.crt";' \
  'Acquire::https::baseos-internal-tools.nvidia.com::Verify-Peer "true";' \
  'Acquire::https::baseos-internal-tools.nvidia.com::Verify-Host "true";' | \
  sudo tee /etc/apt/apt.conf.d/90baseos-pr-kernels >/dev/null
printf '%s\n' 'deb [arch=arm64 signed-by=/usr/share/keyrings/baseos-pr-kernels.gpg] https://baseos-internal-tools.nvidia.com:4001/reviews/apt/NVIDIA/NV-Kernels/689/resolute/arm64 resolute main' | \
  sudo tee /etc/apt/sources.list.d/nv-kernels-pr689.list >/dev/null
sudo apt update --error-on=any
sudo apt install --no-remove nv-kernels-pr-689
)

The repository remains configured. Later apt update and apt install nv-kernels-pr-689 pick up newly published builds; APT verifies signed metadata with the shown Signed-By key.

Note

Build reports and debs are retained for 10 days after the PR closes.

  • 🔴 PR Illustrated: failed — Published explanation could not be verified.
Review metadata
  • Reviewed head: 796dc12983d7
  • Overall status: incomplete
  • Build checks: 4/4 passed

This comment is maintained by BaseOS Reviewer and updated when the GitHub watcher publishes a newer review.

@github-actions

github-actions Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

PR Validation Report

Patchscan ✅ No Missing Fixes

All cherry-picked commits checked — no missing upstream fixes found.

PR Lint ⚠️ Warnings

Details
Checking 3 commits...

Cherry-pick digest:
┌──────────────┬──────────────────────────────────────────────────────────────────┬────────────┬─────────┬───────────────────────────┐
│ Local        │ Referenced upstream / Patch subject                              │ Patch-ID   │ Subject │ SoB chain                 │
├──────────────┼──────────────────────────────────────────────────────────────────┼────────────┼─────────┼───────────────────────────┤
│ 796dc12983d7 │ ab0dbf411ace iommu/arm-smmu-v3: Disable the impl before disablin │ match      │ match   │ preserved + nathanc added │
├──────────────┼──────────────────────────────────────────────────────────────────┼────────────┼─────────┼───────────────────────────┤
│ 17135e9f4f10 │ 9ff145a25c5c iommu/tegra241-cmdqv: Fix CMD_SYNC use-after-free o │ match      │ match   │ preserved + nathanc added │
├──────────────┼──────────────────────────────────────────────────────────────────┼────────────┼─────────┼───────────────────────────┤
│ 74f6822797ac │ 2bd22a0d4050 iommu/arm-smmu-v3: Manage teardown with devm        │ context    │ match   │ preserved + nathanc added │
└──────────────┴──────────────────────────────────────────────────────────────────┴────────────┴─────────┴───────────────────────────┘

Lint results:
W: 796dc12983d7 ("iommu/arm-smmu-v3: Disable the impl before disabli"): subject 73 chars (>72)

@jamieNguyenNVIDIA

Copy link
Copy Markdown
Collaborator

Codex found a potential non-blocking race in the new shutdown path: tegra241_cmdqv_hw_disable() reads a VINTF slot without synchronization, while a concurrent iommufd destroy could clear and free that VINTF. That said, this seems like a narrow corner case during reboot or kexec.

Acked-by: Jamie Nguyen <jamien@nvidia.com>

@clsotog

clsotog commented Nov 5, 2026

Copy link
Copy Markdown
Collaborator

I saw the same as Jamie. Will ack too.
Acked-by: Carol L Soto <csoto@nvidia.com>

@nvmochs

nvmochs commented Nov 6, 2026

Copy link
Copy Markdown
Collaborator

LGTM!

Acked-by: Matthew R. Ochs <mochs@nvidia.com>

@jamieNguyenNVIDIA

Copy link
Copy Markdown
Collaborator

Applied to Canonical resolute/main-next as:

  • c24ade8c2ba57e6f1cfcadec938d646596211e0a iommu/arm-smmu-v3: Manage teardown with devm
  • 03246453b5570eeb3c4c68329e6fd51a6981cb25 iommu/tegra241-cmdqv: Fix CMD_SYNC use-after-free on teardown
  • 554e90ed4ba7f6139853052c6dcdd9c1c163674a iommu/arm-smmu-v3: Disable the impl before disabling the SMMU on shutdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants