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;

Reply via email to