treewide: Make exported DRM FDs read-write.
Some checks are pending
macOS-CI / macOS-CI (dri) (push) Waiting to run
macOS-CI / macOS-CI (xlib) (push) Waiting to run

Without this, somebody trying to map a buffer for write by the CPU would
fail.  This is not common to do in hardware driver environments, but it
shouldn't be disallowed, and there's no downside to allowing it.

I did skip virgl, because that's one where I don't know for sure if there
wouldn't be a downside to allowing RDWR (there are other virt exports
where RDWR is gated on a mappable flag).

This is a follow-up to !37088 to keep copy and paste from introducing the
same bug anywhere else.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37339>
This commit is contained in:
Emma Anholt 2025-09-12 10:01:08 -07:00 committed by Marge Bot
parent 8ef811b02a
commit 4531b8ace4
13 changed files with 18 additions and 18 deletions

View file

@ -376,7 +376,7 @@ agx_bo_make_shared(struct agx_device *dev, struct agx_bo *bo)
assert(bo->prime_fd == -1);
int ret =
drmPrimeHandleToFD(dev->fd, bo->handle, DRM_CLOEXEC, &bo->prime_fd);
drmPrimeHandleToFD(dev->fd, bo->handle, DRM_CLOEXEC | DRM_RDWR, &bo->prime_fd);
assert(ret == 0);
assert(bo->prime_fd >= 0);

View file

@ -2103,7 +2103,7 @@ device_alloc_for_wsi(struct v3dv_device *device,
int fd;
err =
drmPrimeHandleToFD(display_fd, create_dumb.handle, O_CLOEXEC, &fd);
drmPrimeHandleToFD(display_fd, create_dumb.handle, DRM_CLOEXEC | DRM_RDWR, &fd);
if (err < 0)
goto fail_export;
@ -2916,7 +2916,7 @@ v3dv_GetMemoryFdKHR(VkDevice _device,
int fd, ret;
ret = drmPrimeHandleToFD(device->pdevice->render_fd,
mem->bo->handle,
DRM_CLOEXEC, &fd);
DRM_CLOEXEC | DRM_RDWR, &fd);
if (ret)
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);

View file

@ -105,7 +105,7 @@ renderonly_create_kms_dumb_buffer_for_resource(struct pipe_resource *rsc,
out_handle->type = WINSYS_HANDLE_TYPE_FD;
out_handle->stride = create_dumb.pitch;
err = drmPrimeHandleToFD(ro->kms_fd, create_dumb.handle, O_CLOEXEC,
err = drmPrimeHandleToFD(ro->kms_fd, create_dumb.handle, DRM_CLOEXEC | DRM_RDWR,
(int *)&out_handle->handle);
if (err < 0) {
fprintf(stderr, "failed to export dumb buffer: %s\n", strerror(errno));

View file

@ -395,7 +395,7 @@ bool lima_bo_export(struct lima_bo *bo, struct winsys_handle *handle)
return true;
case WINSYS_HANDLE_TYPE_FD:
if (drmPrimeHandleToFD(screen->fd, bo->handle, DRM_CLOEXEC,
if (drmPrimeHandleToFD(screen->fd, bo->handle, DRM_CLOEXEC | DRM_RDWR,
(int*)&handle->handle))
return false;

View file

@ -428,7 +428,7 @@ v3d_bo_get_dmabuf(struct v3d_bo *bo)
{
int fd;
int ret = drmPrimeHandleToFD(bo->screen->fd, bo->handle,
O_CLOEXEC, &fd);
DRM_CLOEXEC | DRM_RDWR, &fd);
if (ret != 0) {
fprintf(stderr, "Failed to export gem bo %d to dmabuf\n",
bo->handle);

View file

@ -469,7 +469,7 @@ vc4_bo_get_dmabuf(struct vc4_bo *bo)
{
int fd;
int ret = drmPrimeHandleToFD(bo->screen->fd, bo->handle,
O_CLOEXEC, &fd);
DRM_CLOEXEC | DRM_RDWR, &fd);
if (ret != 0) {
fprintf(stderr, "Failed to export gem bo %d to dmabuf\n",
bo->handle);

View file

@ -852,7 +852,7 @@ nouveau_bo_set_prime(struct nouveau_bo *bo, int *prime_fd)
struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
int ret;
ret = drmPrimeHandleToFD(drm->fd, nvbo->base.handle, O_CLOEXEC, prime_fd);
ret = drmPrimeHandleToFD(drm->fd, nvbo->base.handle, DRM_CLOEXEC | DRM_RDWR, prime_fd);
if (ret)
return ret;

View file

@ -96,7 +96,7 @@ panfrost_create_kms_dumb_buffer_for_resource(struct pipe_resource *rsc,
out_handle->type = WINSYS_HANDLE_TYPE_FD;
out_handle->stride = create_dumb.pitch;
err = drmPrimeHandleToFD(ro->kms_fd, create_dumb.handle, O_CLOEXEC,
err = drmPrimeHandleToFD(ro->kms_fd, create_dumb.handle, DRM_CLOEXEC | DRM_RDWR,
(int *)&out_handle->handle);
if (err < 0) {
fprintf(stderr, "failed to export dumb buffer: %s\n", strerror(errno));

View file

@ -1327,7 +1327,7 @@ static bool radeon_winsys_bo_get_handle(struct radeon_winsys *rws,
} else if (whandle->type == WINSYS_HANDLE_TYPE_KMS) {
whandle->handle = bo->handle;
} else if (whandle->type == WINSYS_HANDLE_TYPE_FD) {
if (drmPrimeHandleToFD(ws->fd, bo->handle, DRM_CLOEXEC, (int*)&whandle->handle))
if (drmPrimeHandleToFD(ws->fd, bo->handle, DRM_CLOEXEC | DRM_RDWR, (int*)&whandle->handle))
return false;
}

View file

@ -326,7 +326,7 @@ vmw_drm_surface_get_handle(struct svga_winsys_screen *sws,
whandle->handle = vsrf->sid;
break;
case WINSYS_HANDLE_TYPE_FD:
ret = drmPrimeHandleToFD(vws->ioctl.drm_fd, vsrf->sid, DRM_CLOEXEC,
ret = drmPrimeHandleToFD(vws->ioctl.drm_fd, vsrf->sid, DRM_CLOEXEC | DRM_RDWR,
(int *)&whandle->handle);
if (ret) {
vmw_error("Failed to get file descriptor from prime.\n");

View file

@ -148,7 +148,7 @@ pvr_drm_display_buffer_create(struct pvr_drm_winsys *drm_ws,
if (result != VK_SUCCESS)
return result;
ret = drmPrimeHandleToFD(drm_ws->base.display_fd, handle, DRM_CLOEXEC, &fd);
ret = drmPrimeHandleToFD(drm_ws->base.display_fd, handle, DRM_CLOEXEC | DRM_RDWR, &fd);
pvr_winsys_helper_display_buffer_destroy(&drm_ws->base, handle);
if (ret)
return vk_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY);
@ -290,7 +290,7 @@ VkResult pvr_drm_winsys_buffer_get_fd(struct pvr_winsys_bo *bo,
ret = drmPrimeHandleToFD(drm_ws->base.render_fd,
drm_bo->handle,
DRM_CLOEXEC,
DRM_CLOEXEC | DRM_RDWR,
fd_out);
if (ret)
return vk_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY);

View file

@ -62,7 +62,7 @@ static VkResult pvr_srv_alloc_display_pmr(struct pvr_srv_winsys *srv_ws,
if (result != VK_SUCCESS)
return result;
ret = drmPrimeHandleToFD(srv_ws->base.display_fd, handle, O_CLOEXEC, &fd);
ret = drmPrimeHandleToFD(srv_ws->base.display_fd, handle, DRM_CLOEXEC | DRM_RDWR, &fd);
if (ret) {
result = vk_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY);
goto err_display_buffer_destroy;
@ -289,7 +289,7 @@ VkResult pvr_srv_winsys_buffer_get_fd(struct pvr_winsys_bo *bo,
return pvr_srv_physmem_export_dmabuf(ws->render_fd, srv_bo->pmr, fd_out);
/* For display buffers, export using saved buffer handle */
ret = drmPrimeHandleToFD(ws->display_fd, srv_bo->handle, O_CLOEXEC, fd_out);
ret = drmPrimeHandleToFD(ws->display_fd, srv_bo->handle, DRM_CLOEXEC | DRM_RDWR, fd_out);
if (ret)
return vk_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY);

View file

@ -511,7 +511,7 @@ panthor_kmod_bo_wait(struct pan_kmod_bo *bo, int64_t timeout_ns,
*/
int dmabuf_fd;
int ret =
drmPrimeHandleToFD(bo->dev->fd, bo->handle, DRM_CLOEXEC, &dmabuf_fd);
drmPrimeHandleToFD(bo->dev->fd, bo->handle, DRM_CLOEXEC | DRM_RDWR, &dmabuf_fd);
if (ret) {
mesa_loge("drmPrimeHandleToFD() failed (err=%d)", errno);
@ -592,7 +592,7 @@ panthor_kmod_bo_attach_sync_point(struct pan_kmod_bo *bo, uint32_t sync_handle,
}
ret =
drmPrimeHandleToFD(bo->dev->fd, bo->handle, DRM_CLOEXEC, &dmabuf_fd);
drmPrimeHandleToFD(bo->dev->fd, bo->handle, DRM_CLOEXEC | DRM_RDWR, &dmabuf_fd);
if (ret) {
mesa_loge("drmPrimeHandleToFD() failed (err=%d)", errno);
close(isync.fd);
@ -654,7 +654,7 @@ panthor_kmod_bo_get_sync_point(struct pan_kmod_bo *bo, uint32_t *sync_handle,
*/
int dmabuf_fd;
int ret =
drmPrimeHandleToFD(bo->dev->fd, bo->handle, DRM_CLOEXEC, &dmabuf_fd);
drmPrimeHandleToFD(bo->dev->fd, bo->handle, DRM_CLOEXEC | DRM_RDWR, &dmabuf_fd);
if (ret) {
mesa_loge("drmPrimeHandleToFD() failed (err=%d)\n", errno);
return -1;