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: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40519>
This commit is contained in:
Michel Dänzer 2026-03-19 18:31:32 +01:00 committed by Marge Bot
parent 218be90084
commit 8f30e90fc1

View file

@ -397,7 +397,7 @@ amdgpu_winsys_create(int fd, const struct pipe_screen_config *config,
{ {
struct amdgpu_screen_winsys *sws; struct amdgpu_screen_winsys *sws;
struct amdgpu_winsys *aws; struct amdgpu_winsys *aws;
ac_drm_device *dev; ac_drm_device *dev = NULL;
uint32_t drm_major, drm_minor; uint32_t drm_major, drm_minor;
int r; int r;
@ -415,11 +415,32 @@ amdgpu_winsys_create(int fd, const struct pipe_screen_config *config,
/* Initialize the amdgpu device. This should always return the same pointer /* Initialize the amdgpu device. This should always return the same pointer
* for the same fd. */ * for the same fd. */
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); r = ac_drm_device_initialize(fd, is_virtio, &drm_major, &drm_minor, &dev);
if (r) { if (r) {
mesa_loge("amdgpu: amd%s_device_initialize failed.\n", is_virtio ? "vgpu" : "gpu"); mesa_loge("amdgpu: amd%s_device_initialize failed.\n", is_virtio ? "vgpu" : "gpu");
goto fail; goto fail;
} }
}
/* Lookup a winsys if we have already created one for this device. */ /* Lookup a winsys if we have already created one for this device. */
aws = util_hash_table_get(dev_tab, (void *)ac_drm_device_get_cookie(dev)); aws = util_hash_table_get(dev_tab, (void *)ac_drm_device_get_cookie(dev));