summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/pci/drm/drmP.h18
-rw-r--r--sys/dev/pci/drm/drm_bufs.c13
-rw-r--r--sys/dev/pci/drm/drm_drv.c37
-rw-r--r--sys/dev/pci/drm/drm_fops.c32
-rw-r--r--sys/dev/pci/drm/drm_vm.c8
-rw-r--r--sys/sys/conf.h4
6 files changed, 75 insertions, 37 deletions
diff --git a/sys/dev/pci/drm/drmP.h b/sys/dev/pci/drm/drmP.h
index ae3842c596a..6248fedfaec 100644
--- a/sys/dev/pci/drm/drmP.h
+++ b/sys/dev/pci/drm/drmP.h
@@ -322,11 +322,18 @@ enum {
#elif defined(__NetBSD__)
#define drm_get_device_from_kdev(_kdev) device_lookup(&drm_cd, minor(_kdev))
#elif defined(__OpenBSD__)
+/* D_CLONE only supports one device, this will be fixed eventually */
+#define drm_get_device_from_kdev(_kdev) \
+ drm_units[0]
+
+#if 0 /* D_CLONE only supports on device for now */
#define drm_get_device_from_kdev(_kdev) \
(minor(kdev) < DRM_MAXUNITS) ? \
drm_units[minor(kdev)] : NULL
#endif
+#endif /* __FreeBSD__ / __NetBSD__ / __OpenBSD__ */
+
#ifdef __FreeBSD__
#define PAGE_ALIGN(addr) round_page(addr)
#if __FreeBSD_version >= 700000
@@ -968,10 +975,13 @@ dev_type_mmap(drm_mmap);
extern drm_local_map_t *drm_getsarea(drm_device_t *dev);
/* File operations helpers (drm_fops.c) */
-int drm_open_helper(DRM_CDEV kdev, int flags, int fmt,
- DRM_STRUCTPROC *p, drm_device_t *dev);
-extern drm_file_t *drm_find_file_by_proc(drm_device_t *dev,
- DRM_STRUCTPROC *p);
+int drm_open_helper(DRM_CDEV, int, int,
+ DRM_STRUCTPROC *, drm_device_t *);
+#ifdef __OpenBSD__
+drm_file_t *drm_find_file_by_minor(drm_device_t *, int);
+#else
+drm_file_t *drm_find_file_by_proc(drm_device_t *, DRM_STRUCTPROC *);
+#endif
/* Memory management support (drm_memory.c) */
void drm_mem_init(void);
diff --git a/sys/dev/pci/drm/drm_bufs.c b/sys/dev/pci/drm/drm_bufs.c
index e98da50ceb6..0102327beee 100644
--- a/sys/dev/pci/drm/drm_bufs.c
+++ b/sys/dev/pci/drm/drm_bufs.c
@@ -348,9 +348,6 @@ drm_addmap_ioctl(drm_device_t *dev, void *data, struct drm_file *file_priv)
if (!(dev->flags & (FREAD|FWRITE)))
return EACCES; /* Require read/write */
- if (!DRM_SUSER(DRM_CURPROC) && request->type != _DRM_AGP)
- return EACCES;
-
DRM_LOCK();
err = drm_addmap(dev, request->offset, request->size, request->type,
request->flags, &map);
@@ -944,11 +941,6 @@ drm_addbufs_sg(drm_device_t *dev, drm_buf_desc_t *request)
DRM_SPINLOCK(&dev->dma_lock);
- if (!DRM_SUSER(DRM_CURPROC)) {
- DRM_SPINUNLOCK(&dev->dma_lock);
- return EACCES;
- }
-
if (request->count < 0 || request->count > 4096) {
DRM_SPINUNLOCK(&dev->dma_lock);
return EINVAL;
@@ -985,11 +977,6 @@ drm_addbufs_pci(drm_device_t *dev, drm_buf_desc_t *request)
DRM_SPINLOCK(&dev->dma_lock);
- if (!DRM_SUSER(DRM_CURPROC)) {
- DRM_SPINUNLOCK(&dev->dma_lock);
- return EACCES;
- }
-
if (request->count < 0 || request->count > 4096) {
DRM_SPINUNLOCK(&dev->dma_lock);
return EINVAL;
diff --git a/sys/dev/pci/drm/drm_drv.c b/sys/dev/pci/drm/drm_drv.c
index bb0dcc82b7c..4ea99a8b63b 100644
--- a/sys/dev/pci/drm/drm_drv.c
+++ b/sys/dev/pci/drm/drm_drv.c
@@ -580,15 +580,16 @@ error:
void
drm_unload(drm_device_t *dev)
{
+#ifdef __FreeBSD__
int i;
- DRM_DEBUG( "\n" );
-#ifdef __FreeBSD__
drm_sysctl_cleanup(dev);
destroy_dev(dev->devnode);
#endif
+ DRM_DEBUG( "\n" );
+
drm_ctxbitmap_cleanup(dev);
#if !defined(DRM_NO_MTRR) && !defined(DRM_NO_AGP)
@@ -618,21 +619,6 @@ drm_unload(drm_device_t *dev)
dev->pcirid[i], dev->pcir[i]);
dev->pcir[i] = NULL;
}
-#elif defined(__NetBSD__) || defined(__OpenBSD__)
- for (i = 0; i < DRM_MAX_PCI_RESOURCE; i++) {
- if (dev->pcir[i] == NULL)
- continue;
- if (dev->pcir[i]->mapped)
- {
- bus_space_unmap(dev->pa.pa_memt,
- dev->pcir[i]->bsh,
- dev->pcir[i]->size);
- dev->pcir[i]->mapped = 0;
- }
- free(dev->pcir[i], M_DRM);
- dev->pcir[i] = NULL;
- }
-#endif
if ( dev->agp ) {
free(dev->agp, M_DRM);
@@ -721,7 +707,11 @@ drm_close(DRM_CDEV kdev, int flags, int fmt, DRM_STRUCTPROC *p)
DRM_LOCK();
+#ifdef __OpenBSD__
+ file_priv = drm_find_file_by_minor(dev, minor(kdev));
+#else
file_priv = drm_find_file_by_proc(dev, p);
+#endif
if (!file_priv) {
DRM_UNLOCK();
DRM_ERROR("can't find authenticator\n");
@@ -843,7 +833,11 @@ drm_ioctl(DRM_CDEV kdev, u_long cmd, caddr_t data, int flags,
return ENODEV;
DRM_LOCK();
+#ifdef __OpenBSD__
+ file_priv = drm_find_file_by_minor(dev, minor(kdev));
+#else
file_priv = drm_find_file_by_proc(dev, p);
+#endif
DRM_UNLOCK();
if (file_priv == NULL) {
DRM_ERROR("can't find authenticator\n");
@@ -926,9 +920,18 @@ drm_ioctl(DRM_CDEV kdev, u_long cmd, caddr_t data, int flags,
return EINVAL;
}
+#ifdef __OpenBSD__
+ /*
+ * master must be root, and all ioctls that are ROOT_ONLY are
+ * also DRM_MASTER.
+ */
+ if (((ioctl->flags & DRM_AUTH) && !file_priv->authenticated) ||
+ ((ioctl->flags & DRM_MASTER) && !file_priv->master))
+#else
if (((ioctl->flags & DRM_ROOT_ONLY) && !DRM_SUSER(p)) ||
((ioctl->flags & DRM_AUTH) && !file_priv->authenticated) ||
((ioctl->flags & DRM_MASTER) && !file_priv->master))
+#endif
return EACCES;
if (is_driver_ioctl) {
diff --git a/sys/dev/pci/drm/drm_fops.c b/sys/dev/pci/drm/drm_fops.c
index 0c982f88959..6c7334eb727 100644
--- a/sys/dev/pci/drm/drm_fops.c
+++ b/sys/dev/pci/drm/drm_fops.c
@@ -36,6 +36,23 @@
#include "drmP.h"
+#ifdef __OpenBSD__
+
+drm_file_t *
+drm_find_file_by_minor(struct drm_device *dev, int minor)
+{
+ drm_file_t *priv;
+
+ DRM_SPINLOCK_ASSERT(&dev->dev_lock);
+
+ TAILQ_FOREACH(priv, &dev->files, link)
+ if (priv->minor == minor)
+ return (priv);
+ return (NULL);
+}
+
+#else
+
drm_file_t *
drm_find_file_by_proc(drm_device_t *dev, DRM_STRUCTPROC *p)
{
@@ -51,6 +68,7 @@ drm_find_file_by_proc(drm_device_t *dev, DRM_STRUCTPROC *p)
return priv;
return NULL;
}
+#endif
/* drm_open_helper is called whenever a process opens /dev/drm. */
int
@@ -68,7 +86,11 @@ drm_open_helper(DRM_CDEV kdev, int flags, int fmt, DRM_STRUCTPROC *p,
DRM_DEBUG("pid = %d, minor = %d\n", DRM_CURRENTPID, m);
DRM_LOCK();
+#ifdef __OpenBSD__
+ priv = drm_find_file_by_minor(dev, m);
+#else
priv = drm_find_file_by_proc(dev, p);
+#endif
if (priv) {
priv->refs++;
} else {
@@ -97,7 +119,15 @@ drm_open_helper(DRM_CDEV kdev, int flags, int fmt, DRM_STRUCTPROC *p,
}
}
- /* first opener automatically becomes master */
+ /* first opener automatically becomes master if root */
+#ifdef __OpenBSD__
+ if (TAILQ_EMPTY(&dev->files) && !DRM_SUSER(p)) {
+ free(priv, M_DRM);
+ DRM_UNLOCK();
+ return (EPERM);
+ }
+#endif
+
priv->master = TAILQ_EMPTY(&dev->files);
TAILQ_INSERT_TAIL(&dev->files, priv, link);
diff --git a/sys/dev/pci/drm/drm_vm.c b/sys/dev/pci/drm/drm_vm.c
index 550f7b9a14f..09a4879a647 100644
--- a/sys/dev/pci/drm/drm_vm.c
+++ b/sys/dev/pci/drm/drm_vm.c
@@ -51,7 +51,11 @@ drm_mmap(dev_t kdev, off_t offset, int prot)
#endif
DRM_LOCK();
+#ifdef __OpenBSD__
+ priv = drm_find_file_by_minor(dev, minor(kdev));
+#else
priv = drm_find_file_by_proc(dev, DRM_CURPROC);
+#endif
DRM_UNLOCK();
if (priv == NULL) {
DRM_ERROR("can't find authenticator\n");
@@ -104,7 +108,11 @@ drm_mmap(dev_t kdev, off_t offset, int prot)
DRM_DEBUG("can't find map\n");
return -1;
}
+#ifdef __OpenBSD__
+ if (((map->flags&_DRM_RESTRICTED) && priv->master == 0)) {
+#else
if (((map->flags&_DRM_RESTRICTED) && !DRM_SUSER(DRM_CURPROC))) {
+#endif
DRM_UNLOCK();
DRM_DEBUG("restricted map\n");
return -1;
diff --git a/sys/sys/conf.h b/sys/sys/conf.h
index d9bc4c07941..469a0cfa51f 100644
--- a/sys/sys/conf.h
+++ b/sys/sys/conf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: conf.h,v 1.88 2008/05/24 19:37:34 mglocker Exp $ */
+/* $OpenBSD: conf.h,v 1.89 2008/06/03 17:21:22 oga Exp $ */
/* $NetBSD: conf.h,v 1.33 1996/05/03 20:03:32 christos Exp $ */
/*-
@@ -516,7 +516,7 @@ void randomattach(void);
dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \
(dev_type_write((*))) enodev, dev_init(c,n,ioctl), \
(dev_type_stop((*))) enodev, 0, dev_init(c,n,poll), \
- dev_init(c,n,mmap), D_TTY }
+ dev_init(c,n,mmap), 0, D_CLONE }
#endif