Fix gem ioctls to be 32/64-bit clean.
authorKeith Packard <keithp@keithp.com>
Fri, 2 May 2008 03:31:16 +0000 (20:31 -0700)
committerKeith Packard <keithp@keithp.com>
Fri, 2 May 2008 03:31:16 +0000 (20:31 -0700)
mixed 32/64 bit systems need 'special' help for ioctl where the user-space
and kernel-space datatypes differ. Fixing the datatypes to be the same size,
and align the same way for both 32 and 64-bit ppc and x86 environments will
elimiante the need to have magic 32/64-bit ioctl translation code.

linux-core/drm_gem.c
linux-core/i915_gem.c
shared-core/drm.h
shared-core/i915_drm.h

index d39585e..41976bc 100644 (file)
@@ -233,7 +233,7 @@ drm_gem_pread_ioctl(struct drm_device *dev, void *data,
 
        offset = args->offset;
 
-       read = obj->filp->f_op->read(obj->filp, (char __user *)args->data,
+       read = obj->filp->f_op->read(obj->filp, (char __user *)(uintptr_t)args->data_ptr,
                                     args->size, &offset);
        if (read != args->size) {
                drm_gem_object_unreference(dev, obj);
@@ -270,7 +270,7 @@ drm_gem_mmap_ioctl(struct drm_device *dev, void *data,
        offset = args->offset;
 
        down_write(&current->mm->mmap_sem);
-       args->addr = (void *)do_mmap(obj->filp, 0, args->size,
+       args->addr_ptr = (uint64_t) do_mmap(obj->filp, 0, args->size,
                                    PROT_READ | PROT_WRITE, MAP_SHARED,
                                    args->offset);
        up_write(&current->mm->mmap_sem);
@@ -300,7 +300,7 @@ drm_gem_pwrite_ioctl(struct drm_device *dev, void *data,
 
        offset = args->offset;
 
-       written = obj->filp->f_op->write(obj->filp, (char __user *)args->data,
+       written = obj->filp->f_op->write(obj->filp, (char __user *)args->data_ptr,
                                         args->size, &offset);
        if (written != args->size) {
                drm_gem_object_unreference(dev, obj);
index 29b2d89..335f061 100644 (file)
@@ -167,6 +167,7 @@ i915_gem_reloc_and_validate_object(struct drm_device *dev,
                                   struct drm_gem_object *obj)
 {
        struct drm_i915_gem_relocation_entry reloc;
+       struct drm_i915_gem_relocation_entry __user *relocs;
        struct drm_i915_gem_object *obj_priv = obj->driver_private;
        int i;
 
@@ -177,6 +178,7 @@ i915_gem_reloc_and_validate_object(struct drm_device *dev,
                        return -ENOMEM;
        }
 
+       relocs = (struct drm_i915_gem_relocation_entry __user *) (uintptr_t) entry->relocs_ptr;
        /* Apply the relocations, using the GTT aperture to avoid cache
         * flushing requirements.
         */
@@ -187,7 +189,7 @@ i915_gem_reloc_and_validate_object(struct drm_device *dev,
                uint32_t reloc_val, *reloc_entry;
                int ret;
 
-               ret = copy_from_user(&reloc, entry->relocs + i, sizeof(reloc));
+               ret = copy_from_user(&reloc, relocs + i, sizeof(reloc));
                if (ret != 0)
                        return ret;
 
@@ -229,7 +231,7 @@ i915_gem_reloc_and_validate_object(struct drm_device *dev,
                reloc_val = target_obj_priv->gtt_offset + reloc.delta;
 
                DRM_DEBUG("Applied relocation: %p@0x%08x = 0x%08x\n",
-                         obj, reloc.offset, reloc_val);
+                         obj, (unsigned int) reloc.offset, reloc_val);
                *reloc_entry = reloc_val;
 
                iounmap(reloc_page);
@@ -299,8 +301,8 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
                goto err;
        }
        ret = copy_from_user(validate_list,
-                            (struct drm_i915_relocation_entry __user*)
-                            args->buffers,
+                            (struct drm_i915_relocation_entry __user*)(uintptr_t)
+                            args->buffers_ptr,
                             sizeof(*validate_list) * args->buffer_count);
        if (ret != 0)
                goto err;
@@ -329,8 +331,8 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
                validate_list[i].buffer_offset = obj_priv->gtt_offset;
        }
        ret = copy_to_user(validate_list,
-                            (struct drm_i915_relocation_entry __user*)
-                            args->buffers,
+                            (struct drm_i915_relocation_entry __user*)(uintptr_t)
+                            args->buffers_ptr,
                             sizeof(*validate_list) * args->buffer_count);
 
        /* Clean up and return */
index 1f49cbb..90c23fa 100644 (file)
@@ -967,25 +967,28 @@ struct drm_gem_alloc {
         *
         * The (page-aligned) allocated size for the object will be returned.
         */
-       uint32_t size;
+       uint64_t size;
        /**
         * Returned handle for the object.
         *
         * Object handles are nonzero.
         */
        uint32_t handle;
+       uint32_t pad;
 };
 
 struct drm_gem_unreference {
        /** Handle of the object to be unreferenced. */
        uint32_t handle;
+       uint32_t pad;
 };
 
 struct drm_gem_link {
        /** Handle for the object being given a name. */
        uint32_t handle;
+       uint32_t pad;
        /** Requested file name to export the object under. */
-       char *name;
+       uint64_t name_ptr;      /* char *, but pointers are not 32/64 compatible */
        /** Requested file mode to export the object under. */
        mode_t mode;
 };
@@ -993,38 +996,41 @@ struct drm_gem_link {
 struct drm_gem_pread {
        /** Handle for the object being read. */
        uint32_t handle;
+       uint32_t pad;
        /** Offset into the object to read from */
-       off_t offset;
+       uint64_t offset;
        /** Length of data to read */
-       size_t size;
+       uint64_t size;
        /** Pointer to write the data into. */
-       void *data;
+       uint64_t data_ptr;      /* void *, but pointers are not 32/64 compatible */
 };
 
 struct drm_gem_pwrite {
        /** Handle for the object being written to. */
        uint32_t handle;
+       uint32_t pad;
        /** Offset into the object to write to */
-       off_t offset;
+       uint64_t offset;
        /** Length of data to write */
-       size_t size;
+       uint64_t size;
        /** Pointer to read the data from. */
-       void *data;
+       uint64_t data_ptr;      /* void *, but pointers are not 32/64 compatible */
 };
 
 struct drm_gem_mmap {
        /** Handle for the object being mapped. */
        uint32_t handle;
+       uint32_t pad;
        /** Offset in the object to map. */
-       off_t offset;
+       uint64_t offset;
        /**
         * Length of data to map.
         *
         * The value will be page-aligned.
         */
-       size_t size;
+       uint64_t size;
        /** Returned pointer the data was mapped at */
-       void *addr;
+       uint64_t addr_ptr;      /* void *, but pointers are not 32/64 compatible */
 };
 
 /**
index 4d113e4..91461c4 100644 (file)
@@ -407,12 +407,12 @@ struct drm_i915_gem_init {
         * Beginning offset in the GTT to be managed by the DRM memory
         * manager.
         */
-       off_t gtt_start;
+       uint64_t gtt_start;
        /**
         * Ending offset in the GTT to be managed by the DRM memory
         * manager.
         */
-       off_t gtt_end;
+       uint64_t gtt_end;
 };
 
 struct drm_i915_gem_relocation_entry {
@@ -425,15 +425,15 @@ struct drm_i915_gem_relocation_entry {
         */
        uint32_t target_handle;
 
-       /** Offset in the buffer the relocation entry will be written into */
-       uint32_t offset;
-
        /**
         * Value to be added to the offset of the target buffer to make up
         * the relocation entry.
         */
        uint32_t delta;
 
+       /** Offset in the buffer the relocation entry will be written into */
+       uint64_t offset;
+
        /**
         * Offset value of the target buffer that the relocation entry was last
         * written as.
@@ -442,7 +442,7 @@ struct drm_i915_gem_relocation_entry {
         * and writing the relocation.  This value is written back out by
         * the execbuffer ioctl when the relocation is written.
         */
-       uint32_t presumed_offset;
+       uint64_t presumed_offset;
 };
 
 struct drm_i915_gem_validate_entry {
@@ -457,8 +457,9 @@ struct drm_i915_gem_validate_entry {
         */
        uint32_t buffer_offset;
        /** List of relocations to be performed on this buffer */
-       struct drm_i915_gem_relocation_entry *relocs;
+       uint64_t relocs_ptr;    /* struct drm_i915_gem_relocation_entry *relocs */
        uint32_t relocation_count;
+       uint32_t pad;
 };
 
 struct drm_i915_gem_execbuffer {
@@ -470,7 +471,7 @@ struct drm_i915_gem_execbuffer {
         * a buffer is performing refer to buffers that have already appeared
         * in the validate list.
         */
-       struct drm_i915_gem_validate_entry *buffers;
+       uint64_t buffers_ptr;   /* struct drm_i915_gem_validate_entry *buffers */
        uint32_t buffer_count;
 
        /** Offset in the batchbuffer to start execution from. */
@@ -480,12 +481,13 @@ struct drm_i915_gem_execbuffer {
        uint32_t DR1;
        uint32_t DR4;
        uint32_t num_cliprects;
-       struct drm_clip_rect *cliprects;
+       uint64_t cliprects_ptr; /* struct drm_clip_rect *cliprects */
 };
 
 struct drm_i915_gem_pin {
        /** Handle of the buffer to be pinned. */
        uint32_t handle;
+       uint32_t pad;
 
        /** Returned GTT offset of the buffer. */
        uint64_t offset;
@@ -494,6 +496,7 @@ struct drm_i915_gem_pin {
 struct drm_i915_gem_unpin {
        /** Handle of the buffer to be unpinned. */
        uint32_t handle;
+       uint32_t pad;
 };