I forgot to add this in the first patch, you will GPF without it. The
attachment includes it.
@@ -72,7 +80,7 @@ static int drm_setup(drm_device_t * dev)
INIT_LIST_HEAD(&dev->ctxlist->head);
dev->vmalist = NULL;
- dev->sigdata.lock = dev->lock.hw_lock = NULL;
+ dev->sigdata.lock = NULL;
init_waitqueue_head(&dev->lock.lock_queue);
dev->queue_count = 0;
dev->queue_reserved = 0;
--
Jon Smirl
[EMAIL PROTECTED]
diff --git a/linux-core/drmP.h b/linux-core/drmP.h
--- a/linux-core/drmP.h
+++ b/linux-core/drmP.h
@@ -280,7 +280,7 @@ typedef int drm_ioctl_compat_t(struct fi
typedef struct drm_ioctl_desc {
drm_ioctl_t *func;
int auth_needed;
- int root_only;
+ int master;
} drm_ioctl_desc_t;
typedef struct drm_devstate {
@@ -375,6 +375,7 @@ typedef struct drm_buf_entry {
/** File private data */
typedef struct drm_file {
int authenticated;
+ int master;
int minor;
pid_t pid;
uid_t uid;
diff --git a/linux-core/drm_bufs.c b/linux-core/drm_bufs.c
--- a/linux-core/drm_bufs.c
+++ b/linux-core/drm_bufs.c
@@ -56,7 +56,8 @@ static drm_local_map_t *drm_find_matchin
list_for_each(list, &dev->maplist->head) {
drm_map_list_t *entry = list_entry(list, drm_map_list_t, head);
if (entry->map && map->type == entry->map->type &&
- entry->map->offset == map->offset) {
+ ((entry->map->offset == map->offset) ||
+ (map->type == _DRM_SHM))) {
return entry->map;
}
}
@@ -163,6 +164,19 @@ int drm_addmap(drm_device_t * dev, unsig
map->handle = drm_ioremap(map->offset, map->size, dev);
break;
case _DRM_SHM:
+ found_map = drm_find_matching_map(dev, map);
+ if (found_map != NULL) {
+ if (found_map->size != map->size) {
+ DRM_DEBUG("Matching maps of type %d with "
+ "mismatched sizes, (%ld vs %ld)\n",
+ map->type, map->size, found_map->size);
+ found_map->size = map->size;
+ }
+
+ drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+ *map_ptr = found_map;
+ return 0;
+ }
map->handle = vmalloc_32(map->size);
DRM_DEBUG("%lu %d %p\n",
map->size, drm_order(map->size), map->handle);
@@ -181,15 +195,34 @@ int drm_addmap(drm_device_t * dev, unsig
dev->sigdata.lock = dev->lock.hw_lock = map->handle; /* Pointer to lock */
}
break;
- case _DRM_AGP:
- if (drm_core_has_AGP(dev)) {
+ case _DRM_AGP: {
+ drm_agp_mem_t *entry;
+ int valid = 0;
+
+ if (!drm_core_has_AGP(dev)) {
+ drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+ return -EINVAL;
+ }
#ifdef __alpha__
- map->offset += dev->hose->mem_space->start;
+ map->offset += dev->hose->mem_space->start;
#endif
- map->offset += dev->agp->base;
- map->mtrr = dev->agp->agp_mtrr; /* for getmap */
+ map->offset += dev->agp->base;
+ map->mtrr = dev->agp->agp_mtrr; /* for getmap */
+
+ for (entry = dev->agp->memory; entry; entry = entry->next) {
+ if ((map->offset >= entry->bound) &&
+ (map->offset + map->offset <= entry->bound + entry->pages * PAGE_SIZE)) {
+ valid = 1;
+ break;
+ }
+ }
+ if (!valid) {
+ drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+ return -EPERM;
}
+ DRM_DEBUG("AGP offset = 0x%08lx, size = 0x%08lx\n", map->offset, map->size);
break;
+ }
case _DRM_SCATTER_GATHER:
if (!dev->sg) {
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
@@ -258,6 +291,9 @@ int drm_addmap_ioctl(struct inode *inode
return -EFAULT;
}
+ if (!(capable(CAP_SYS_ADMIN) || map.type == _DRM_AGP))
+ return -EPERM;
+
err = drm_addmap( dev, map.offset, map.size, map.type, map.flags,
& map_ptr );
diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c
--- a/linux-core/drm_drv.c
+++ b/linux-core/drm_drv.c
@@ -545,13 +545,14 @@ int drm_ioctl(struct inode *inode, struc
if (!func) {
DRM_DEBUG("no function\n");
retcode = -EINVAL;
- } else if ((ioctl->root_only && !capable(CAP_SYS_ADMIN)) ||
- (ioctl->auth_needed && !priv->authenticated)) {
+ } else if (((ioctl->master && !priv->master) ||
+ (ioctl->auth_needed && !priv->authenticated)) &&
+ (!capable(CAP_SYS_ADMIN))) {
retcode = -EACCES;
} else {
retcode = func(inode, filp, cmd, arg);
}
- err_i1:
+err_i1:
atomic_dec(&dev->ioctl_count);
if (retcode)
DRM_DEBUG("ret = %x\n", retcode);
diff --git a/linux-core/drm_fops.c b/linux-core/drm_fops.c
--- a/linux-core/drm_fops.c
+++ b/linux-core/drm_fops.c
@@ -34,18 +34,26 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "drmP.h"
#include <linux/poll.h>
+#include "drmP.h"
+#include "drm_sarea.h"
+
static int drm_open_helper(struct inode *inode, struct file *filp, drm_device_t * dev);
static int drm_setup(drm_device_t * dev)
{
+ drm_local_map_t *map;
int i;
if (dev->driver->presetup)
dev->driver->presetup(dev);
+ /* prebuild the SAREA */
+ i = drm_addmap(dev, 0, SAREA_MAX, _DRM_SHM, _DRM_CONTAINS_LOCK, &map);
+ if (i != 0)
+ return i;
+
atomic_set(&dev->ioctl_count, 0);
atomic_set(&dev->vma_count, 0);
dev->buf_use = 0;
@@ -72,7 +80,7 @@ static int drm_setup(drm_device_t * dev)
INIT_LIST_HEAD(&dev->ctxlist->head);
dev->vmalist = NULL;
- dev->sigdata.lock = dev->lock.hw_lock = NULL;
+ dev->sigdata.lock = NULL;
init_waitqueue_head(&dev->lock.lock_queue);
dev->queue_count = 0;
dev->queue_reserved = 0;
@@ -244,6 +252,7 @@ static int drm_open_helper(struct inode
priv->minor = minor;
priv->head = drm_heads[minor];
priv->ioctl_count = 0;
+ /* for compatibility root is always authenticated */
priv->authenticated = capable(CAP_SYS_ADMIN);
priv->lock_count = 0;
@@ -259,6 +268,9 @@ static int drm_open_helper(struct inode
priv->prev = NULL;
dev->file_first = priv;
dev->file_last = priv;
+ /* first opener automatically becomes master and authenticated */
+ priv->master = 1;
+ priv->authenticated = 1;
} else {
priv->next = NULL;
priv->prev = dev->file_last;
diff --git a/shared-core/drm.h b/shared-core/drm.h
--- a/shared-core/drm.h
+++ b/shared-core/drm.h
@@ -62,6 +62,12 @@
#define __user
#endif
+#ifdef __GNUC__
+# define DEPRECATED __attribute__ ((deprecated))
+#else
+# define DEPRECATED
+#endif
+
#if defined(__linux__)
#if defined(__KERNEL__)
#include <linux/config.h>
diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c
--- a/shared-core/radeon_cp.c
+++ b/shared-core/radeon_cp.c
@@ -1245,7 +1245,7 @@ static void radeon_set_pciegart(drm_rade
u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL);
if (on) {
- DRM_DEBUG("programming pcie %08X %08lX %08X\n", dev_priv->gart_vm_start, dev_priv->bus_pci_gart,dev_priv->gart_size);
+ DRM_DEBUG("programming pcie %08X %08X %08X\n", dev_priv->gart_vm_start, dev_priv->bus_pci_gart,dev_priv->gart_size);
RADEON_WRITE_PCIE(RADEON_PCIE_TX_DISCARD_RD_ADDR_LO, dev_priv->gart_vm_start);
RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_BASE, dev_priv->bus_pci_gart);
RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_START_LO, dev_priv->gart_vm_start);
@@ -1398,8 +1398,6 @@ static int radeon_do_init_cp(drm_device_
DRM_GETSAREA();
- dev_priv->fb_offset = init->fb_offset;
- dev_priv->mmio_offset = init->mmio_offset;
dev_priv->ring_offset = init->ring_offset;
dev_priv->ring_rptr_offset = init->ring_rptr_offset;
dev_priv->buffers_offset = init->buffers_offset;
@@ -1411,12 +1409,6 @@ static int radeon_do_init_cp(drm_device_
return DRM_ERR(EINVAL);
}
- dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset);
- if (!dev_priv->mmio) {
- DRM_ERROR("could not find mmio region!\n");
- radeon_do_cleanup_cp(dev);
- return DRM_ERR(EINVAL);
- }
dev_priv->cp_ring = drm_core_findmap(dev, init->ring_offset);
if (!dev_priv->cp_ring) {
DRM_ERROR("could not find cp ring region!\n");
diff --git a/shared-core/radeon_drm.h b/shared-core/radeon_drm.h
--- a/shared-core/radeon_drm.h
+++ b/shared-core/radeon_drm.h
@@ -492,7 +492,7 @@ typedef struct drm_radeon_init {
RADEON_INIT_R300_CP = 0x04
} func;
unsigned long sarea_priv_offset;
- int is_pci; /* not used, driver asks hardware */
+ int is_pci DEPRECATED; /* deprecated, driver asks hardware */
int cp_mode;
int gart_size;
int ring_size;
@@ -504,8 +504,8 @@ typedef struct drm_radeon_init {
unsigned int depth_bpp;
unsigned int depth_offset, depth_pitch;
- unsigned long fb_offset;
- unsigned long mmio_offset;
+ unsigned long fb_offset DEPRECATED; /* deprecated, driver asks hardware */
+ unsigned long mmio_offset DEPRECATED; /* deprecated, driver asks hardware */
unsigned long ring_offset;
unsigned long ring_rptr_offset;
unsigned long buffers_offset;
diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h
--- a/shared-core/radeon_drv.h
+++ b/shared-core/radeon_drv.h
@@ -242,8 +242,6 @@ typedef struct drm_radeon_private {
drm_radeon_depth_clear_t depth_clear;
- unsigned long fb_offset;
- unsigned long mmio_offset;
unsigned long ring_offset;
unsigned long ring_rptr_offset;
unsigned long buffers_offset;
diff --git a/shared-core/radeon_state.c b/shared-core/radeon_state.c
--- a/shared-core/radeon_state.c
+++ b/shared-core/radeon_state.c
@@ -2917,7 +2917,7 @@ static int radeon_cp_getparam(DRM_IOCTL_
value = dev_priv->gart_vm_start;
break;
case RADEON_PARAM_REGISTER_HANDLE:
- value = dev_priv->mmio_offset;
+ value = dev_priv->mmio->offset;
break;
case RADEON_PARAM_STATUS_HANDLE:
value = dev_priv->ring_rptr_offset;