From 30efad5113944681c1abd6452e10355c105e9c39 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 1 May 2008 20:31:16 -0700 Subject: Fix gem ioctls to be 32/64-bit clean. 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 | 6 +++--- linux-core/i915_gem.c | 14 ++++++++------ shared-core/drm.h | 28 +++++++++++++++++----------- shared-core/i915_drm.h | 21 ++++++++++++--------- 4 files changed, 40 insertions(+), 29 deletions(-) diff --git a/linux-core/drm_gem.c b/linux-core/drm_gem.c index d39585e9..41976bc7 100644 --- a/linux-core/drm_gem.c +++ b/linux-core/drm_gem.c @@ -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(¤t->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(¤t->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); diff --git a/linux-core/i915_gem.c b/linux-core/i915_gem.c index 29b2d894..335f0618 100644 --- a/linux-core/i915_gem.c +++ b/linux-core/i915_gem.c @@ -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 */ diff --git a/shared-core/drm.h b/shared-core/drm.h index 1f49cbb0..90c23fa7 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -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 */ }; /** diff --git a/shared-core/i915_drm.h b/shared-core/i915_drm.h index 4d113e4c..91461c41 100644 --- a/shared-core/i915_drm.h +++ b/shared-core/i915_drm.h @@ -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; }; -- cgit v1.2.3