Call drm_gem_prime_handle_to_fd() and drm_gem_prime_fd_to_handle() by default if no PRIME import/export helpers have been set. Both functions are the default for almost all drivers. DRM drivers implement struct drm_driver.gem_prime_import_sg_table to import dma-buf objects from other drivers. Having the function drm_gem_prime_fd_to_handle() functions set by default allows each driver to import dma-buf objects to itself, even without support for other drivers. For drm_gem_prime_handle_to_fd() it is similar: using it by default allows each driver to export to itself, even without support for other drivers. This functionality enables userspace to share per-driver buffers across process boundaries via PRIME (e.g., wlroots requires this functionality). The patch generalizes a pattern that has previously been implemented by GEM VRAM helpers [1] to work with any driver. For example, gma500 can now run the wlroots-based sway compositor. Signed-off-by: Thomas Zimmermann <tzimmermann@xxxxxxx> Link: https://lore.kernel.org/dri-devel/20230302143502.500661-1-contact@xxxxxxxxxxx/ --- drivers/gpu/drm/drm_ioctl.c | 4 ++-- drivers/gpu/drm/drm_prime.c | 29 ++++++++++++++++++++--------- include/drm/drm_drv.h | 6 ++++++ 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 7c9d66ee917de..faa7018bda0a3 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -245,8 +245,8 @@ static int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_ req->value = 1; return 0; case DRM_CAP_PRIME: - req->value |= dev->driver->prime_fd_to_handle ? DRM_PRIME_CAP_IMPORT : 0; - req->value |= dev->driver->prime_handle_to_fd ? DRM_PRIME_CAP_EXPORT : 0; + req->value |= DRM_PRIME_CAP_IMPORT; + req->value |= DRM_PRIME_CAP_EXPORT; return 0; case DRM_CAP_SYNCOBJ: req->value = drm_core_check_feature(dev, DRIVER_SYNCOBJ); diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index d29dafce9bb0a..36cecfc7c947b 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -372,11 +372,16 @@ int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void *data, { struct drm_prime_handle *args = data; - if (!dev->driver->prime_fd_to_handle) - return -ENOSYS; + /* + * TODO: Convert remaining drivers to drm_gem_prime_fd_to_handle() + * and remove this callback. + */ + if (dev->driver->prime_fd_to_handle) { + return dev->driver->prime_fd_to_handle(dev, file_priv, args->fd, + &args->handle); + } - return dev->driver->prime_fd_to_handle(dev, file_priv, - args->fd, &args->handle); + return drm_gem_prime_fd_to_handle(dev, file_priv, args->fd, &args->handle); } static struct dma_buf *export_and_register_object(struct drm_device *dev, @@ -518,15 +523,21 @@ int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data, { struct drm_prime_handle *args = data; - if (!dev->driver->prime_handle_to_fd) - return -ENOSYS; - /* check flags are valid */ if (args->flags & ~(DRM_CLOEXEC | DRM_RDWR)) return -EINVAL; - return dev->driver->prime_handle_to_fd(dev, file_priv, - args->handle, args->flags, &args->fd); + /* + * TODO: Convert remaining drivers to drm_gem_prime_handle_to_fd() + * and remove this callback. + */ + if (dev->driver->prime_handle_to_fd) { + return dev->driver->prime_handle_to_fd(dev, file_priv, + args->handle, args->flags, + &args->fd); + } + return drm_gem_prime_handle_to_fd(dev, file_priv, args->handle, + args->flags, &args->fd); } /** diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index 89e2706cac561..10af1899236a0 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -309,6 +309,9 @@ struct drm_driver { * * For an in-depth discussion see :ref:`PRIME buffer sharing * documentation <prime_buffer_sharing>`. + * + * TODO: Convert remaining drivers to drm_gem_prime_handle_to_fd() + * and remove this callback. */ int (*prime_handle_to_fd)(struct drm_device *dev, struct drm_file *file_priv, uint32_t handle, uint32_t flags, int *prime_fd); @@ -320,6 +323,9 @@ struct drm_driver { * * For an in-depth discussion see :ref:`PRIME buffer sharing * documentation <prime_buffer_sharing>`. + * + * TODO: Convert remaining drivers to drm_gem_prime_fd_to_handle() + * and remove this callback. */ int (*prime_fd_to_handle)(struct drm_device *dev, struct drm_file *file_priv, int prime_fd, uint32_t *handle); -- 2.41.0