diff options
| author | Sam Day <me@samcday.com> | 2026-01-08 08:30:21 +1000 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2026-01-14 15:58:22 +0100 |
| commit | 0145e7acd29855dfba4a2f387d455b5d9a520f0e (patch) | |
| tree | f046815254f74fea8e8f3e34322ec2b19307a410 /drivers/usb/gadget/function | |
| parent | 8e4c1d06183c25022f6b0002a5cab84979ca6337 (diff) | |
usb: gadget: f_fs: fix DMA-BUF OUT queues
Currently, DMA_FROM_DEVICE is used when attaching DMABUFs to IN
endpoints and DMA_TO_DEVICE for OUT endpoints. This is inverted from
how it should be.
The result is IOMMU read-only mappings placed on OUT queues,
triggering arm-smmu write faults.
Put differently, OUT endpoints flow data from host -> gadget, meaning
the UDC peripheral needs to have write access to the buffer to fill it
with the incoming data.
This commit flips the directions and updates the implicit-sync helpers
so IN endpoints act as readers and OUT endpoints as writers.
Signed-off-by: Sam Day <me@samcday.com>
Tested-by: David Heidelberg <david@ixit.cz> # OnePlus 6T on sdm845-next-20251119
Link: https://patch.msgid.link/20260108-ffs-dmabuf-ioctl-fix-v1-2-e51633891a81@samcday.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/gadget/function')
| -rw-r--r-- | drivers/usb/gadget/function/f_fs.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index c479d0204afb..c1826aa2f0f8 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -1513,7 +1513,7 @@ static int ffs_dmabuf_attach(struct file *file, int fd) goto err_dmabuf_detach; } - dir = epfile->in ? DMA_FROM_DEVICE : DMA_TO_DEVICE; + dir = epfile->in ? DMA_TO_DEVICE : DMA_FROM_DEVICE; err = ffs_dma_resv_lock(dmabuf, nonblock); if (err) @@ -1643,7 +1643,7 @@ static int ffs_dmabuf_transfer(struct file *file, /* Make sure we don't have writers */ timeout = nonblock ? 0 : msecs_to_jiffies(DMABUF_ENQUEUE_TIMEOUT_MS); retl = dma_resv_wait_timeout(dmabuf->resv, - dma_resv_usage_rw(epfile->in), + dma_resv_usage_rw(!epfile->in), true, timeout); if (retl == 0) retl = -EBUSY; @@ -1688,7 +1688,7 @@ static int ffs_dmabuf_transfer(struct file *file, dma_fence_init(&fence->base, &ffs_dmabuf_fence_ops, &priv->lock, priv->context, seqno); - resv_dir = epfile->in ? DMA_RESV_USAGE_WRITE : DMA_RESV_USAGE_READ; + resv_dir = epfile->in ? DMA_RESV_USAGE_READ : DMA_RESV_USAGE_WRITE; dma_resv_add_fence(dmabuf->resv, &fence->base, resv_dir); dma_resv_unlock(dmabuf->resv); |
