Merge branch 'openbsd-fixes' into 'main'

OpenBSD fixes

See merge request mesa/libdrm!119
This commit is contained in:
Jonathan Gray 2025-06-13 06:52:58 +10:00
commit e609b05a3c
3 changed files with 37 additions and 69 deletions

View file

@ -75,7 +75,11 @@ static inline int sync_wait(int fd, int timeout)
}
return 0;
} else if (ret == 0) {
#ifndef ETIME
errno = ETIMEDOUT;
#else
errno = ETIME;
#endif
return -1;
}
} while (ret == -1 && (errno == EINTR || errno == EAGAIN));

View file

@ -100,6 +100,11 @@
#define DRM_MAJOR 226 /* Linux */
#endif
#ifdef __OpenBSD__
#define NO_MKNOD
#define X_PRIVSEP
#endif
#if defined(__OpenBSD__) || defined(__DragonFly__)
struct drm_pciinfo {
uint16_t domain;
@ -794,7 +799,7 @@ static int drmMatchBusID(const char *id1, const char *id2, int pci_domain_ok)
* If any other failure happened then it will output error message using
* drmMsg() call.
*/
#if !UDEV
#if !UDEV && !defined(NO_MKNOD)
static int chown_check_return(const char *path, uid_t owner, gid_t group)
{
int rv;
@ -823,6 +828,18 @@ static const char *drmGetDeviceName(int type)
return NULL;
}
#ifdef X_PRIVSEP
static int
_priv_open_device(const char *path)
{
drmMsg("_priv_open_device\n");
return open(path, O_RDWR);
}
drm_public int priv_open_device(const char *)
__attribute__((weak, alias ("_priv_open_device")));
#endif
/**
* Open the DRM device, creating it if necessary.
*
@ -844,7 +861,7 @@ static int drmOpenDevice(dev_t dev, int minor, int type)
int fd;
mode_t devmode = DRM_DEV_MODE, serv_mode;
gid_t serv_group;
#if !UDEV
#if !UDEV && !defined(NO_MKNOD)
int isroot = !geteuid();
uid_t user = DRM_DEV_UID;
gid_t group = DRM_DEV_GID;
@ -862,7 +879,7 @@ static int drmOpenDevice(dev_t dev, int minor, int type)
devmode &= ~(S_IXUSR|S_IXGRP|S_IXOTH);
}
#if !UDEV
#if !UDEV && !defined(NO_MKNOD)
if (stat(DRM_DIR_NAME, &st)) {
if (!isroot)
return DRM_ERR_NOT_ROOT;
@ -884,7 +901,7 @@ static int drmOpenDevice(dev_t dev, int minor, int type)
chown_check_return(buf, user, group);
chmod(buf, devmode);
}
#else
#elif UDEV
/* if we modprobed then wait for udev */
{
int udev_count = 0;
@ -909,13 +926,17 @@ wait_for_udev:
}
#endif
#ifndef X_PRIVSEP
fd = open(buf, O_RDWR | O_CLOEXEC);
#else
fd = priv_open_device(buf);
#endif
drmMsg("drmOpenDevice: open result is %d, (%s)\n",
fd, fd < 0 ? strerror(errno) : "OK");
if (fd >= 0)
return fd;
#if !UDEV
#if !UDEV && !defined(NO_MKNOD)
/* Check if the device node is not what we expect it to be, and recreate it
* and try again if so.
*/
@ -967,8 +988,13 @@ static int drmOpenMinor(int minor, int create, int type)
return -EINVAL;
sprintf(buf, dev_name, DRM_DIR_NAME, minor);
if ((fd = open(buf, O_RDWR | O_CLOEXEC)) >= 0)
return fd;
#ifndef X_PRIVSEP
fd = open(buf, O_RDWR | O_CLOEXEC);
#else
fd = priv_open_device(buf);
#endif
if (fd >= 0)
return fd;
return -errno;
}
@ -4577,60 +4603,6 @@ drm_device_has_rdev(drmDevicePtr device, dev_t find_rdev)
*/
drm_public int drmGetDeviceFromDevId(dev_t find_rdev, uint32_t flags, drmDevicePtr *device)
{
#ifdef __OpenBSD__
/*
* DRI device nodes on OpenBSD are not in their own directory, they reside
* in /dev along with a large number of statically generated /dev nodes.
* Avoid stat'ing all of /dev needlessly by implementing this custom path.
*/
drmDevicePtr d;
char node[PATH_MAX + 1];
const char *dev_name;
int node_type, subsystem_type;
int maj, min, n, ret;
const int max_node_length = ALIGN(drmGetMaxNodeName(), sizeof(void *));
struct stat sbuf;
if (device == NULL)
return -EINVAL;
maj = major(find_rdev);
min = minor(find_rdev);
if (!drmNodeIsDRM(maj, min))
return -EINVAL;
node_type = drmGetMinorType(maj, min);
if (node_type == -1)
return -ENODEV;
dev_name = drmGetDeviceName(node_type);
if (!dev_name)
return -EINVAL;
/* anything longer than this will be truncated in drmDeviceAlloc.
* Account for NULL byte
*/
n = snprintf(node, PATH_MAX, dev_name, DRM_DIR_NAME, min);
if (n == -1 || n >= PATH_MAX)
return -errno;
if (n + 1 > max_node_length)
return -EINVAL;
if (stat(node, &sbuf))
return -EINVAL;
subsystem_type = drmParseSubsystemType(maj, min);
if (subsystem_type != DRM_BUS_PCI)
return -ENODEV;
ret = drmProcessPciDevice(&d, node, node_type, maj, min, true, flags);
if (ret)
return ret;
*device = d;
return 0;
#else
drmDevicePtr local_devices[MAX_DRM_NODES];
drmDevicePtr d;
DIR *sysdir;
@ -4694,7 +4666,6 @@ drm_public int drmGetDeviceFromDevId(dev_t find_rdev, uint32_t flags, drmDeviceP
if (*device == NULL)
return -ENODEV;
return 0;
#endif
}
drm_public int drmGetNodeTypeFromDevId(dev_t devid)

View file

@ -76,18 +76,11 @@ extern "C" {
(S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)
#define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
#ifdef __OpenBSD__
#define DRM_DIR_NAME "/dev"
#define DRM_PRIMARY_MINOR_NAME "drm"
#define DRM_CONTROL_MINOR_NAME "drmC" /* deprecated */
#define DRM_RENDER_MINOR_NAME "drmR"
#else
#define DRM_DIR_NAME "/dev/dri"
#define DRM_PRIMARY_MINOR_NAME "card"
#define DRM_CONTROL_MINOR_NAME "controlD" /* deprecated */
#define DRM_RENDER_MINOR_NAME "renderD"
#define DRM_PROC_NAME "/proc/dri/" /* For backward Linux compatibility */
#endif
#define DRM_DEV_NAME "%s/" DRM_PRIMARY_MINOR_NAME "%d"
#define DRM_CONTROL_DEV_NAME "%s/" DRM_CONTROL_MINOR_NAME "%d" /* deprecated */