The AMDGPU_GEM_OP_GET_MAPPING_INFO branch of amdgpu_gem_op_ioctl()
holds three cleanup-tracked resources before calling kvcalloc():
the drm_gem_object reference from drm_gem_object_lookup(), the
drm_exec lock on the looked-up GEM via drm_exec_lock_obj(), and
the drm_exec lock on the per-process VM root page directory via
amdgpu_vm_lock_pd(). All three are released by the out_exec
label that every other error path in this function jumps to.
The kvcalloc() failure path returns -ENOMEM directly, skipping
out_exec and leaking all three.
The leaked per-process VM root PD dma_resv lock is the
load-bearing leak: any subsequent operation on the same VM
(further GEM ops, command-submission, eviction, TTM shrinker
callbacks) blocks on the held lock. DRM_IOCTL_AMDGPU_GEM_OP is
DRM_AUTH | DRM_RENDER_ALLOW, so this is an unprivileged-local
denial of service against the caller's GPU context, reachable
by any process with /dev/dri/renderD* access.
Route the failure through out_exec so drm_exec_fini() and
drm_gem_object_put() run.
Reproduced on stock 7.0.0-10, Ryzen 7 5700U / Radeon Vega
(Lucienne): the failing ioctl returns -ENOMEM and a second
GET_MAPPING_INFO on the same fd then blocks in
drm_exec_lock_obj() on the leaked dma_resv. SIGKILL on the
caller does not reap the task; the fd-release path during
process exit goes through amdgpu_gem_object_close() ->
drm_exec_prepare_obj() on the same lock, leaving the task in D
state until the box is rebooted. The patched kernel was not
rebuilt and re-tested on this hardware; the fix is mechanical.
Tested on a single Lucienne / Vega box only.
Ziyi Guo posted an independent INT_MAX-bound check for
args->num_entries in the same branch [1]; the two patches are
complementary and can land in either order.
Fixes: 4d82724f7f2b ("drm/amdgpu: Add mapping info option for GEM_OP ioctl")
Cc: stable(a)vger.kernel.org
Link: https://lore.kernel.org/all/20260208000255.4073363-1-n7l8m4@u.northwestern.… # [1]
Signed-off-by: Michael Bommarito <michael.bommarito(a)gmail.com>
Assisted-by: Claude:claude-opus-4-7
---
drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
index 9ef80bca4102..8224fb499fdf 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
@@ -1091,8 +1091,10 @@ int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data,
* be retried.
*/
vm_entries = kvcalloc(args->num_entries, sizeof(*vm_entries), GFP_KERNEL);
- if (!vm_entries)
- return -ENOMEM;
+ if (!vm_entries) {
+ r = -ENOMEM;
+ goto out_exec;
+ }
amdgpu_vm_bo_va_for_each_valid_mapping(bo_va, mapping) {
if (num_mappings < args->num_entries) {
--
2.53.0
This patchset enhances the LINFlexD UART driver and its device tree bindings to
support DMA transfers, configurable clock inputs, dynamic baudrate changes, and
termios features. It also includes a series of fixes and improvements to ensure
reliable operation across various modes and configurations.
The changes added can be summarized as follows:
1. Fixes with respect to FIFO handling, locking, interrupt related registers and
INITM mode transition.
2. Removal of the earlycon workaround, as proper FIFO handling and INITM
transitions now ensure stable behavior.
3. Support for configurable stop bits and dynamic baudrate changes based on
clock inputs and termios settings.
4. Optional DMA support for RX and TX paths, preventing character loss during
high-throughput operations like copy-paste. Cyclic DMA is used for RX to avoid
gaps between transactions.
Larisa Grigore (8):
serial: linflexuart: Clean SLEEP bit in LINCR1 after suspend
serial: linflexuart: Check FIFO full before writing
serial: linflexuart: Correctly clear UARTSR in buffer mode
serial: linflexuart: Update RXEN/TXEN outside INITM mode
serial: linflexuart: Ensure FIFO is empty when entering INITM
serial: linflexuart: Revert earlycon workaround
serial: linflexuart: Add support for configurable stop bits
serial: linflexuart: Add DMA support
Radu Pirea (5):
serial: linflexuart: Fix locking in set_termios
dt-bindings: serial: fsl-linflexuart: add clock input properties
dt-bindings: serial: fsl-linflexuart: add dma properties
serial: linflexuart: Add support for changing baudrate
serial: linflexuart: Avoid stopping DMA during receive operations
.../bindings/serial/fsl,s32-linflexuart.yaml | 31 +
drivers/tty/serial/fsl_linflexuart.c | 972 +++++++++++++++---
2 files changed, 846 insertions(+), 157 deletions(-)
--
2.47.0
From: Vineeth Pillai <vineeth(a)bitbyteword.org>
Replace trace_foo() with the new trace_call__foo() at sites already
guarded by trace_foo_enabled(), avoiding a redundant
static_branch_unlikely() re-evaluation inside the tracepoint.
trace_call__foo() calls the tracepoint callbacks directly without
utilizing the static branch again.
Original v2 series:
https://lore.kernel.org/linux-trace-kernel/20260323160052.17528-1-vineeth@b…
Parts of the original v2 series have already been merged in mainline.
This patch is being reposted as a follow-up cleanup for the remaining
unmerged pieces.
Suggested-by: Steven Rostedt <rostedt(a)goodmis.org>
Suggested-by: Peter Zijlstra <peterz(a)infradead.org>
Signed-off-by: Vineeth Pillai (Google) <vineeth(a)bitbyteword.org>
Assisted-by: Claude:claude-sonnet-4-6
---
drivers/dma-buf/dma-fence.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c
index a2aa82f4eedd..a41cdd9c9343 100644
--- a/drivers/dma-buf/dma-fence.c
+++ b/drivers/dma-buf/dma-fence.c
@@ -553,7 +553,7 @@ dma_fence_wait_timeout(struct dma_fence *fence, bool intr, signed long timeout)
}
if (trace_dma_fence_wait_end_enabled()) {
rcu_read_lock();
- trace_dma_fence_wait_end(fence);
+ trace_call__dma_fence_wait_end(fence);
rcu_read_unlock();
}
return ret;
--
2.54.0
virtio_gpu_cursor_plane_update() allocates a virtio_gpu_object_array,
locks its dma_resv, and queues a fenced transfer to the host. The
lock acquisition can fail in two ways:
- dma_resv_lock_interruptible() returns -EINTR when a signal is
delivered while waiting for the reservation lock.
- dma_resv_reserve_fences() returns -ENOMEM if it fails to allocate
a fence slot; in this case lock_resv unlocks before returning.
The return value was ignored, so the cursor path could proceed with
the resv lock not held. The queue path then walks the object array
and calls dma_resv_add_fence(), which requires the lock; with lockdep
enabled this trips dma_resv_assert_held():
WARNING: drivers/dma-buf/dma-resv.c:296 at dma_resv_add_fence+0x71e/0x840
Call Trace:
virtio_gpu_array_add_fence
virtio_gpu_queue_ctrl_sgs
virtio_gpu_queue_fenced_ctrl_buffer
virtio_gpu_cursor_plane_update
drm_atomic_helper_commit_planes
drm_atomic_helper_commit_tail
commit_tail
drm_atomic_helper_commit
drm_atomic_commit
drm_atomic_helper_update_plane
__setplane_atomic
drm_mode_cursor_universal
drm_mode_cursor_common
drm_mode_cursor_ioctl
drm_ioctl
__x64_sys_ioctl
Beyond the WARN, mutating the dma_resv fence list without the lock
races with concurrent readers/writers and can corrupt the list.
The DRM atomic helpers do not allow .atomic_update to fail: by the
time it runs, the commit has been signed off to userspace and there
is no clean rollback path. Move the fallible work -- objs allocation,
dma_resv locking, and fence slot reservation -- into
virtio_gpu_plane_prepare_fb, which is the designated callback for
resource acquisition and may return errors that the framework
handles by rolling back the commit. Stash the prepared object array
on virtio_gpu_plane_state so the update step can consume it.
Make virtio_gpu_plane_cleanup_fb release the objs if the commit was
rolled back before update ran (i.e., objs not consumed). The queue
path already unlocks the resv after attaching the fence (vq.c:411)
and frees the array via put_free_delayed after host completion
(vq.c:271), so the update step only needs to clear vgplane_st->objs
to transfer ownership.
Simplify virtio_gpu_cursor_plane_update to a no-fail queue submission
that hands the prepared, locked objs to the queue path.
The bug was reported by syzbot, triggered via fault injection
(fail_nth) on the DRM_IOCTL_MODE_CURSOR path, which forces the
-ENOMEM branch in dma_resv_reserve_fences().
Reported-by: syzbot+72bd3dd3a5d5f39a0271(a)syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=72bd3dd3a5d5f39a0271
Fixes: 5cfd31c5b3a3 ("drm/virtio: fix virtio_gpu_cursor_plane_update().")
Cc: stable(a)vger.kernel.org
Link: https://lore.kernel.org/all/20260510053025.100224-1-kartikey406@gmail.com/T/ [v1]
Signed-off-by: Deepanshu Kartikey <kartikey406(a)gmail.com>
---
v2: Move resv lock acquisition from .atomic_update (which must not
fail) to .prepare_fb (which may), per maintainer review of v1.
The previous approach of silently skipping the cursor update on
lock failure violated the atomic-commit contract with userspace.
---
drivers/gpu/drm/virtio/virtgpu_drv.h | 1 +
drivers/gpu/drm/virtio/virtgpu_plane.c | 38 ++++++++++++++++++++------
2 files changed, 30 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h
index f17660a71a3e..e51f959dce46 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -198,6 +198,7 @@ struct virtio_gpu_framebuffer {
struct virtio_gpu_plane_state {
struct drm_plane_state base;
struct virtio_gpu_fence *fence;
+ struct virtio_gpu_object_array *objs;
};
#define to_virtio_gpu_plane_state(x) \
container_of(x, struct virtio_gpu_plane_state, base)
diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c
index a126d1b25f46..b0511ace89e6 100644
--- a/drivers/gpu/drm/virtio/virtgpu_plane.c
+++ b/drivers/gpu/drm/virtio/virtgpu_plane.c
@@ -381,6 +381,23 @@ static int virtio_gpu_plane_prepare_fb(struct drm_plane *plane,
goto err_fence;
}
+ if (plane->type == DRM_PLANE_TYPE_CURSOR && bo->dumb) {
+ struct virtio_gpu_object_array *objs;
+
+ objs = virtio_gpu_array_alloc(1);
+ if (!objs) {
+ ret = -ENOMEM;
+ goto err_fence;
+ }
+ virtio_gpu_array_add_obj(objs, vgfb->base.obj[0]);
+ ret = virtio_gpu_array_lock_resv(objs);
+ if (ret) {
+ virtio_gpu_array_put_free(objs);
+ goto err_fence;
+ }
+ vgplane_st->objs = objs;
+ }
+
return 0;
err_fence:
@@ -417,6 +434,12 @@ static void virtio_gpu_plane_cleanup_fb(struct drm_plane *plane,
vgplane_st->fence = NULL;
}
+ if (vgplane_st->objs) {
+ virtio_gpu_array_unlock_resv(vgplane_st->objs);
+ virtio_gpu_array_put_free(vgplane_st->objs);
+ vgplane_st->objs = NULL;
+ }
+
obj = state->fb->obj[0];
if (drm_gem_is_imported(obj))
virtio_gpu_cleanup_imported_obj(obj);
@@ -452,21 +475,18 @@ static void virtio_gpu_cursor_plane_update(struct drm_plane *plane,
}
if (bo && bo->dumb && (plane->state->fb != old_state->fb)) {
- /* new cursor -- update & wait */
- struct virtio_gpu_object_array *objs;
-
- objs = virtio_gpu_array_alloc(1);
- if (!objs)
- return;
- virtio_gpu_array_add_obj(objs, vgfb->base.obj[0]);
- virtio_gpu_array_lock_resv(objs);
+ /* objs and fence were prepared in virtio_gpu_plane_prepare_fb;
+ * the resv is already locked. The queue path takes ownership
+ * of objs and unlocks the resv after attaching the fence.
+ */
virtio_gpu_cmd_transfer_to_host_2d
(vgdev, 0,
plane->state->crtc_w,
plane->state->crtc_h,
- 0, 0, objs, vgplane_st->fence);
+ 0, 0, vgplane_st->objs, vgplane_st->fence);
virtio_gpu_notify(vgdev);
dma_fence_wait(&vgplane_st->fence->f, true);
+ vgplane_st->objs = NULL;
}
if (plane->state->fb != old_state->fb) {
--
2.43.0
On 5/7/26 10:50, Ming Lei wrote:
...
>>> BTW, inspired by this approach, I adds similar feature to ublk via UBLK_IO_F_SHMEM_ZC
>>> which can maintain long-term vfio dma mapping over registered user-place aligned buffer.
>>
>> Interesting, just too a glance, and it looks like what David Wei
>> was thinking to add to fuse, but IIUC he gave up exactly because the
>> client will need to cooperate and that could be troublesome.
>
> Here the cooperation is minimized, maybe one shmem/hugetlb path, or memfd,
> and it is one optimization and opt-in, and fallback to normal path
> if application doesn't cooperate.
My point is that with widely enough adopted interface the user will be
able to opportunistically use it without knowledge about the file, i.e.
not knowing whether it's ublk or something else. But as you mentioned
below, it'd be cooperative interface in either case.
>> Should we try to push everything under the same interface instead of
>> keeping a ublk specific one? Again to the point that it requires
>
> If generic interface can be figured out, it shouldn't be a big deal for
> ublk to switch to it, and the usage is simple actually.
Sure, you'd just need to maintain both as there is a mismatch between
interfaces.
> So far, ublk supports both FS and nvme block device.
>
> And cooperation can't be avoided for this usage no matter if generic or
> driver specific implementation is taken, for both fuse & ublk.
--
Pavel Begunkov
On 7/5/26 17:16, Alexey Kardashevskiy wrote:
> On 6/5/26 23:16, Jason Gunthorpe wrote:
>> On Wed, May 06, 2026 at 12:35:42PM +1000, Alexey Kardashevskiy wrote:
>>> Hi!
>>>
>>> Let's reignite this topic.
>>>
>>> I've been using these patches + QEMU side hacks for 6+ months. And it's been fine until I got a device where MSIX BAR is in a middle of another BAR marked as TEE in the TDISP interface report. And no trusted MSIX yet.
>>>
>>> Every time QEMU mmaps a BAR - I request a dmabuf fd from VFIO in QEMU. Since mapping of an entire MSIX BAR is allowed by default, VFIORegion::nr_mmaps==1 and it is an entire BAR.
>>>
>>> Problem: KVM memslot mismatches the dmabuf fd size
>>
>> Huh? kvm does not care about dmabuf at all? Are you running other
>> patches to hook kvm and dmabuf?
>
> yup, 06/12 of this patchset.
>
>> Putting a slice in a dmabuf is a well understood need for MSI, so I
>> expect whatever kvm dmabuf interface that gets merged to accomodate
>> this?
>
> good to know.
>
>>> Solution2: modify logic in VFIO dmabuf to allow multiple KVM memory
>>> slots per dmabuf. Now it is kvm_memory_slot::dmabuf_attach with no
>>> offset into the dmabuf and one kvm_vfio_dmabuf per dma_buf.
>>
>> Yes, when kvm learns to take in a dmabuf it needs to take in a slice,
>> not the whole buf. Or you need to create multiple dmabufs with the
>> necessary slices from the VFIO. The upstream vfio dmabuf creation
>> allows creating it with a slice.
>
> true but either way dmabuf slicing will be directed by QEMU's msix-table emulation MR and this slicing needs to match the TDISP report so I'll have to teach QEMU these reports, right?
Or TDISP devices are going to align MSIX BARs to 4K, and QEMU will do the same and it should "just work", and if it does not - the host won't crash. Can this work? Thanks,
> I am worried if I miss something obvious, again. Thanks,
>
>
> ps. I like nntp.lore.kernel.org very much for ability to dig out old stuff and then just reply to it :)
>
>>
>> Jason
>
--
Alexey
virtio_gpu_cursor_plane_update() calls virtio_gpu_array_lock_resv()
but ignores its return value. The function can fail in two ways:
- dma_resv_lock_interruptible() returns -ERESTARTSYS when a signal
is delivered while waiting for the reservation lock.
- dma_resv_reserve_fences() returns -ENOMEM if it fails to allocate
a fence slot; in this case lock_resv unlocks before returning.
In both cases the resv lock is not held on return. The cursor path
proceeds to queue a fenced transfer command. The queue path then
walks the object array and calls dma_resv_add_fence() on the cursor
BO's reservation. dma_resv_add_fence() requires the resv lock to be
held; with lockdep enabled the missing lock trips
dma_resv_assert_held():
WARNING: drivers/dma-buf/dma-resv.c:296 at dma_resv_add_fence+0x71e/0x840
Call Trace:
virtio_gpu_array_add_fence+0xcd/0x140
virtio_gpu_queue_ctrl_sgs
virtio_gpu_queue_fenced_ctrl_buffer+0x578/0xfb0
virtio_gpu_cursor_plane_update+0x411/0xbc0
drm_atomic_helper_commit_planes+0x497/0xf10
...
drm_mode_cursor_ioctl+0xd4/0x110
drm_ioctl+0x5e6/0xc60
__x64_sys_ioctl+0x18e/0x210
Beyond the WARN, mutating the dma_resv fence list without the lock
races with concurrent readers/writers and can corrupt the list.
Check the return value of virtio_gpu_array_lock_resv(). On failure,
drop the references taken by virtio_gpu_array_add_obj() with
virtio_gpu_array_put_free() (which does not unlock, matching the
not-locked state) and return without queueing the command. A
skipped cursor frame is harmless; the WARN and the underlying race
are not.
The bug was reported by syzbot, triggered via fault injection
(fail_nth) on the DRM_IOCTL_MODE_CURSOR path, which forces the
-ENOMEM branch in dma_resv_reserve_fences().
Reported-by: syzbot+72bd3dd3a5d5f39a0271(a)syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=72bd3dd3a5d5f39a0271
Fixes: 5cfd31c5b3a3 ("drm/virtio: fix virtio_gpu_cursor_plane_update().")
Cc: stable(a)vger.kernel.org
Signed-off-by: Deepanshu Kartikey <kartikey406(a)gmail.com>
---
drivers/gpu/drm/virtio/virtgpu_plane.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c
index a126d1b25f46..ca379b08b9ec 100644
--- a/drivers/gpu/drm/virtio/virtgpu_plane.c
+++ b/drivers/gpu/drm/virtio/virtgpu_plane.c
@@ -459,7 +459,10 @@ static void virtio_gpu_cursor_plane_update(struct drm_plane *plane,
if (!objs)
return;
virtio_gpu_array_add_obj(objs, vgfb->base.obj[0]);
- virtio_gpu_array_lock_resv(objs);
+ if (virtio_gpu_array_lock_resv(objs)) {
+ virtio_gpu_array_put_free(objs);
+ return;
+ }
virtio_gpu_cmd_transfer_to_host_2d
(vgdev, 0,
plane->state->crtc_w,
--
2.43.0
On Sat, May 09, 2026 at 01:31:56PM +0800, Xu Yilun wrote:
> > Would you be open to an in-between? The exporter and importer both
> > have information that should not leak into each other's drivers.
> >
> > What if the dmabuf mapping type core code was the only thing that had
> > access to *BOTH*? The exporter provides the address data, the importer
> > provides the iommu_domain. The core code, and only the core code, has
> > both and does the required operation?
>
> I think that may not work for KVM. On IOMMU side, IOMMUFD acts as the
> address space (iova) manager and dma_api/IOMMU driver acts as the
> actual page table mapper. But for KVM, it is both. KVM doesn't allow
> another component to provide an unknown address space (GPA space) and
> say "map it", so doesn't expose to other components about "KVM domain".
>
> Even if we expose "KVM domain", KVM still acts as the importer and the
> mapper, is it wierd to say we trust KVM-the-mapper, but don't trust
> KVM-the-as-manager?
>
> Is it also wierd that we trust IOMMU-the-mapper, but don't trust
> IOMMUFD-the-as-manager? There are more IOMMU drivers than IOMMUFD...
Yeah, it doesn't work well for kvm, and yes it is really weird and
worse that phys in every way..
Jason
On Thu, May 07, 2026 at 05:16:56PM +1000, Alexey Kardashevskiy wrote:
> true but either way dmabuf slicing will be directed by QEMU's
> msix-table emulation MR and this slicing needs to match the TDISP
> report so I'll have to teach QEMU these reports, right? I am worried
> if I miss something obvious, again. Thanks,
I don't think so.. It just needs to slice it into the MSI page
blindly. When the VM goes to validate the TDISP report against the
mappings it will fail to accept the device if there is a mismatch.
The only thing qemu could do is fail sooner, but I don't know that is
worth the complexity as we do expect all devices to have their MSI
range unprotected.
Jason