Module Name: src Committed By: riastradh Date: Tue Feb 21 11:40:13 UTC 2023
Modified Files: src/sys/external/bsd/drm2/linux: linux_dma_buf.c Log Message: drm: Teach dmabuf to handle lseek. Needed by libdrm_amdgpu. Based on patch from Jeff Frasca -- thanks! XXX pullup-10 To generate a diff of this commit: cvs rdiff -u -r1.15 -r1.16 src/sys/external/bsd/drm2/linux/linux_dma_buf.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/external/bsd/drm2/linux/linux_dma_buf.c diff -u src/sys/external/bsd/drm2/linux/linux_dma_buf.c:1.15 src/sys/external/bsd/drm2/linux/linux_dma_buf.c:1.16 --- src/sys/external/bsd/drm2/linux/linux_dma_buf.c:1.15 Sat Apr 9 23:44:44 2022 +++ src/sys/external/bsd/drm2/linux/linux_dma_buf.c Tue Feb 21 11:40:13 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: linux_dma_buf.c,v 1.15 2022/04/09 23:44:44 riastradh Exp $ */ +/* $NetBSD: linux_dma_buf.c,v 1.16 2023/02/21 11:40:13 riastradh Exp $ */ /*- * Copyright (c) 2018 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: linux_dma_buf.c,v 1.15 2022/04/09 23:44:44 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: linux_dma_buf.c,v 1.16 2023/02/21 11:40:13 riastradh Exp $"); #include <sys/types.h> #include <sys/atomic.h> @@ -48,6 +48,8 @@ static int dmabuf_fop_close(struct file static int dmabuf_fop_kqfilter(struct file *, struct knote *); static int dmabuf_fop_mmap(struct file *, off_t *, size_t, int, int *, int *, struct uvm_object **, int *); +static int dmabuf_fop_seek(struct file *fp, off_t delta, int whence, + off_t *newoffp, int flags); static const struct fileops dmabuf_fileops = { .fo_name = "dmabuf", @@ -61,6 +63,7 @@ static const struct fileops dmabuf_fileo .fo_kqfilter = dmabuf_fop_kqfilter, .fo_restart = fnullop_restart, .fo_mmap = dmabuf_fop_mmap, + .fo_seek = dmabuf_fop_seek, }; struct dma_buf * @@ -288,3 +291,54 @@ dmabuf_fop_mmap(struct file *file, off_t return dmabuf->ops->mmap(dmabuf, offp, size, prot, flagsp, advicep, uobjp, maxprotp); } + +/* + * We don't actually do anything with the file offset; this is just how + * libdrm_amdgpu expects to find the size of the DMA buf. (Why it + * doesn't use fstat is unclear, but it doesn't really matter.) + */ +static int +dmabuf_fop_seek(struct file *fp, off_t delta, int whence, off_t *newoffp, + int flags) +{ + const off_t OFF_MAX = __type_max(off_t); + struct dma_buf *dmabuf = fp->f_data; + off_t base, newoff; + int error; + + mutex_enter(&fp->f_lock); + + switch (whence) { + case SEEK_CUR: + base = fp->f_offset; + break; + case SEEK_END: + base = dmabuf->size; + break; + case SEEK_SET: + base = 0; + break; + default: + error = EINVAL; + goto out; + } + + /* Check for arithmetic overflow and reject negative offsets. */ + if (base < 0 || delta > OFF_MAX - base || base + delta < 0) { + error = EINVAL; + goto out; + } + + /* Compute the new offset. */ + newoff = base + delta; + + /* Success! */ + if (newoffp) + *newoffp = newoff; + if (flags & FOF_UPDATE_OFFSET) + fp->f_offset = newoff; + error = 0; + +out: mutex_exit(&fp->f_lock); + return error; +}