From 8f30e90fc104c2b9e044d279fe953a308c44353f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 19 Mar 2026 18:31:32 +0100 Subject: [PATCH] winsys/amdgpu: Prefer render node FD for ac_drm_device_initialize If the FD passed in isn't from a render node, try to determine the corresponding render node and open it. If that succeeds, pass the render node FD to ac_drm_device_initialize. The existing code already detects when ac_drm_device_get_fd doesn't return the FD passed in, and handles that case correctly. This avoids issues with unauthenticated FDs from card nodes. Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/7289 v2: * Always close render_fd after calling ac_drm_device_initialize for it. (Pierre-Eric Pelloux-Prayer) * Formatting tweaks for logging when ac_drm_device_initialize fails for render_fd. v3: (Pierre-Eric Pelloux-Prayer) * Log render_device path when ac_drm_device_initialize fails for render_fd. * Fix render_device string leak. Part-of: --- src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c | 31 ++++++++++++++++--- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c b/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c index ada39e7f278..223c86473fa 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c @@ -397,7 +397,7 @@ amdgpu_winsys_create(int fd, const struct pipe_screen_config *config, { struct amdgpu_screen_winsys *sws; struct amdgpu_winsys *aws; - ac_drm_device *dev; + ac_drm_device *dev = NULL; uint32_t drm_major, drm_minor; int r; @@ -415,10 +415,31 @@ amdgpu_winsys_create(int fd, const struct pipe_screen_config *config, /* Initialize the amdgpu device. This should always return the same pointer * for the same fd. */ - r = ac_drm_device_initialize(fd, is_virtio, &drm_major, &drm_minor, &dev); - if (r) { - mesa_loge("amdgpu: amd%s_device_initialize failed.\n", is_virtio ? "vgpu" : "gpu"); - goto fail; + if (drmGetNodeTypeFromFd(fd) != DRM_NODE_RENDER) { + char *render_device = drmGetRenderDeviceNameFromFd(fd); + + if (render_device) { + int render_fd = open(render_device, O_RDWR | O_CLOEXEC); + + if (render_fd >= 0) { + r = ac_drm_device_initialize(render_fd, is_virtio, &drm_major, &drm_minor, &dev); + close(render_fd); + if (r) { + mesa_logd("amdgpu: amd%s_device_initialize failed for %s\n", + is_virtio ? "vgpu" : "gpu", render_device); + } + } + + free(render_device); + } + } + + if (!dev) { + r = ac_drm_device_initialize(fd, is_virtio, &drm_major, &drm_minor, &dev); + if (r) { + mesa_loge("amdgpu: amd%s_device_initialize failed.\n", is_virtio ? "vgpu" : "gpu"); + goto fail; + } } /* Lookup a winsys if we have already created one for this device. */