DF-4439 / probe_drm.c
/* * DF-4439 probe: is the DRM atomic ioctl surface present on this guest? * * The finding (missing backport of Linux 4e076c73e4f6: drm_atomic_state holds * no drm_device reference while nonblocking commits outlive the ioctl on * system_unbound_wq) can only be exercised where a DRM driver is attached. * This probe documents availability: it looks for the DRM device nodes, * opens one if present, queries DRM_IOCTL_VERSION and * DRM_IOCTL_MODE_GETRESOURCES (atomic-capable stack), and reports what it * found. On the audit guest (QEMU std VGA, no i915/amdgpu/radeon) there is * no DRM device, so the race cannot be driven here. * * Build: cc -O -o probe_drm probe_drm.c */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> #include <sys/ioctl.h> #include <sys/types.h> /* Minimal local copies of the drm uapi pieces (avoid include-path issues) */ struct drm_version_ { int version_major, version_minor, version_patchlevel; size_t name_len; char *name; size_t date_len; char *date; size_t desc_len; char *desc; }; #define DRM_IOCTL_VERSION_ _IOWR(0x00, 0x02, struct drm_version_) #define DRM_IOCTL_BASE 'd' #define DRM_IOCTL_MODE_GETRESOURCES_ _IOWR(DRM_IOCTL_BASE, 0xA0, int[8]) int main(void) { static const char *candidates[] = { "/dev/drm0", "/dev/drm1", "/dev/dri/card0", "/dev/dri/card1", "/dev/dri/renderD128", NULL }; int i, fd = -1; for (i = 0; candidates[i]; i++) { fd = open(candidates[i], O_RDWR); if (fd >= 0) { printf("opened %s\n", candidates[i]); break; } printf("%s: %s\n", candidates[i], strerror(errno)); } if (fd < 0) { printf("RESULT: no DRM device node available on this system\n"); printf("RESULT: DF-4439 race (nonblocking atomic commit vs driver\n"); printf("RESULT: unload) is NOT exercisable on this guest\n"); return 1; } struct drm_version_ v; char name[64] = {0}; memset(&v, 0, sizeof(v)); v.name = name; v.name_len = sizeof(name); if (ioctl(fd, DRM_IOCTL_VERSION_, &v) == 0) printf("DRM version: %d.%d driver=%s\n", v.version_major, v.version_minor, name); else printf("DRM_IOCTL_VERSION: %s\n", strerror(errno)); int res[8] = {0}; if (ioctl(fd, DRM_IOCTL_MODE_GETRESOURCES_, res) == 0) printf("KMS present: crtcs=%d connectors=%d fb=%d\n", res[0], res[2], res[4]); else printf("DRM_IOCTL_MODE_GETRESOURCES: %s\n", strerror(errno)); printf("RESULT: DRM present; DF-4439 race harness would run here\n"); close(fd); return 0; } |