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.
main
Keith Packard 2008-05-01 20:31:16 -07:00
parent abc896638f
commit 30efad5113
4 changed files with 40 additions and 29 deletions

View File

@ -233,7 +233,7 @@ drm_gem_pread_ioctl(struct drm_device *dev, void *data,
offset = args->offset; 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); args->size, &offset);
if (read != args->size) { if (read != args->size) {
drm_gem_object_unreference(dev, obj); drm_gem_object_unreference(dev, obj);
@ -270,7 +270,7 @@ drm_gem_mmap_ioctl(struct drm_device *dev, void *data,
offset = args->offset; offset = args->offset;
down_write(&current->mm->mmap_sem); 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, PROT_READ | PROT_WRITE, MAP_SHARED,
args->offset); args->offset);
up_write(&current->mm->mmap_sem); up_write(&current->mm->mmap_sem);
@ -300,7 +300,7 @@ drm_gem_pwrite_ioctl(struct drm_device *dev, void *data,
offset = args->offset; 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); args->size, &offset);
if (written != args->size) { if (written != args->size) {
drm_gem_object_unreference(dev, obj); drm_gem_object_unreference(dev, obj);

View File

@ -167,6 +167,7 @@ i915_gem_reloc_and_validate_object(struct drm_device *dev,
struct drm_gem_object *obj) struct drm_gem_object *obj)
{ {
struct drm_i915_gem_relocation_entry reloc; 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; struct drm_i915_gem_object *obj_priv = obj->driver_private;
int i; int i;
@ -177,6 +178,7 @@ i915_gem_reloc_and_validate_object(struct drm_device *dev,
return -ENOMEM; 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 /* Apply the relocations, using the GTT aperture to avoid cache
* flushing requirements. * flushing requirements.
*/ */
@ -187,7 +189,7 @@ i915_gem_reloc_and_validate_object(struct drm_device *dev,
uint32_t reloc_val, *reloc_entry; uint32_t reloc_val, *reloc_entry;
int ret; int ret;
ret = copy_from_user(&reloc, entry->relocs + i, sizeof(reloc)); ret = copy_from_user(&reloc, relocs + i, sizeof(reloc));
if (ret != 0) if (ret != 0)
return ret; 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; reloc_val = target_obj_priv->gtt_offset + reloc.delta;
DRM_DEBUG("Applied relocation: %p@0x%08x = 0x%08x\n", 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; *reloc_entry = reloc_val;
iounmap(reloc_page); iounmap(reloc_page);
@ -299,8 +301,8 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
goto err; goto err;
} }
ret = copy_from_user(validate_list, ret = copy_from_user(validate_list,
(struct drm_i915_relocation_entry __user*) (struct drm_i915_relocation_entry __user*)(uintptr_t)
args->buffers, args->buffers_ptr,
sizeof(*validate_list) * args->buffer_count); sizeof(*validate_list) * args->buffer_count);
if (ret != 0) if (ret != 0)
goto err; goto err;
@ -329,8 +331,8 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
validate_list[i].buffer_offset = obj_priv->gtt_offset; validate_list[i].buffer_offset = obj_priv->gtt_offset;
} }
ret = copy_to_user(validate_list, ret = copy_to_user(validate_list,
(struct drm_i915_relocation_entry __user*) (struct drm_i915_relocation_entry __user*)(uintptr_t)
args->buffers, args->buffers_ptr,
sizeof(*validate_list) * args->buffer_count); sizeof(*validate_list) * args->buffer_count);
/* Clean up and return */ /* Clean up and return */

View File

@ -967,25 +967,28 @@ struct drm_gem_alloc {
* *
* The (page-aligned) allocated size for the object will be returned. * The (page-aligned) allocated size for the object will be returned.
*/ */
uint32_t size; uint64_t size;
/** /**
* Returned handle for the object. * Returned handle for the object.
* *
* Object handles are nonzero. * Object handles are nonzero.
*/ */
uint32_t handle; uint32_t handle;
uint32_t pad;
}; };
struct drm_gem_unreference { struct drm_gem_unreference {
/** Handle of the object to be unreferenced. */ /** Handle of the object to be unreferenced. */
uint32_t handle; uint32_t handle;
uint32_t pad;
}; };
struct drm_gem_link { struct drm_gem_link {
/** Handle for the object being given a name. */ /** Handle for the object being given a name. */
uint32_t handle; uint32_t handle;
uint32_t pad;
/** Requested file name to export the object under. */ /** 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. */ /** Requested file mode to export the object under. */
mode_t mode; mode_t mode;
}; };
@ -993,38 +996,41 @@ struct drm_gem_link {
struct drm_gem_pread { struct drm_gem_pread {
/** Handle for the object being read. */ /** Handle for the object being read. */
uint32_t handle; uint32_t handle;
uint32_t pad;
/** Offset into the object to read from */ /** Offset into the object to read from */
off_t offset; uint64_t offset;
/** Length of data to read */ /** Length of data to read */
size_t size; uint64_t size;
/** Pointer to write the data into. */ /** Pointer to write the data into. */
void *data; uint64_t data_ptr; /* void *, but pointers are not 32/64 compatible */
}; };
struct drm_gem_pwrite { struct drm_gem_pwrite {
/** Handle for the object being written to. */ /** Handle for the object being written to. */
uint32_t handle; uint32_t handle;
uint32_t pad;
/** Offset into the object to write to */ /** Offset into the object to write to */
off_t offset; uint64_t offset;
/** Length of data to write */ /** Length of data to write */
size_t size; uint64_t size;
/** Pointer to read the data from. */ /** Pointer to read the data from. */
void *data; uint64_t data_ptr; /* void *, but pointers are not 32/64 compatible */
}; };
struct drm_gem_mmap { struct drm_gem_mmap {
/** Handle for the object being mapped. */ /** Handle for the object being mapped. */
uint32_t handle; uint32_t handle;
uint32_t pad;
/** Offset in the object to map. */ /** Offset in the object to map. */
off_t offset; uint64_t offset;
/** /**
* Length of data to map. * Length of data to map.
* *
* The value will be page-aligned. * The value will be page-aligned.
*/ */
size_t size; uint64_t size;
/** Returned pointer the data was mapped at */ /** Returned pointer the data was mapped at */
void *addr; uint64_t addr_ptr; /* void *, but pointers are not 32/64 compatible */
}; };
/** /**

View File

@ -407,12 +407,12 @@ struct drm_i915_gem_init {
* Beginning offset in the GTT to be managed by the DRM memory * Beginning offset in the GTT to be managed by the DRM memory
* manager. * manager.
*/ */
off_t gtt_start; uint64_t gtt_start;
/** /**
* Ending offset in the GTT to be managed by the DRM memory * Ending offset in the GTT to be managed by the DRM memory
* manager. * manager.
*/ */
off_t gtt_end; uint64_t gtt_end;
}; };
struct drm_i915_gem_relocation_entry { struct drm_i915_gem_relocation_entry {
@ -425,15 +425,15 @@ struct drm_i915_gem_relocation_entry {
*/ */
uint32_t target_handle; 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 * Value to be added to the offset of the target buffer to make up
* the relocation entry. * the relocation entry.
*/ */
uint32_t delta; 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 * Offset value of the target buffer that the relocation entry was last
* written as. * written as.
@ -442,7 +442,7 @@ struct drm_i915_gem_relocation_entry {
* and writing the relocation. This value is written back out by * and writing the relocation. This value is written back out by
* the execbuffer ioctl when the relocation is written. * the execbuffer ioctl when the relocation is written.
*/ */
uint32_t presumed_offset; uint64_t presumed_offset;
}; };
struct drm_i915_gem_validate_entry { struct drm_i915_gem_validate_entry {
@ -457,8 +457,9 @@ struct drm_i915_gem_validate_entry {
*/ */
uint32_t buffer_offset; uint32_t buffer_offset;
/** List of relocations to be performed on this buffer */ /** 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 relocation_count;
uint32_t pad;
}; };
struct drm_i915_gem_execbuffer { 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 * a buffer is performing refer to buffers that have already appeared
* in the validate list. * 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; uint32_t buffer_count;
/** Offset in the batchbuffer to start execution from. */ /** Offset in the batchbuffer to start execution from. */
@ -480,12 +481,13 @@ struct drm_i915_gem_execbuffer {
uint32_t DR1; uint32_t DR1;
uint32_t DR4; uint32_t DR4;
uint32_t num_cliprects; uint32_t num_cliprects;
struct drm_clip_rect *cliprects; uint64_t cliprects_ptr; /* struct drm_clip_rect *cliprects */
}; };
struct drm_i915_gem_pin { struct drm_i915_gem_pin {
/** Handle of the buffer to be pinned. */ /** Handle of the buffer to be pinned. */
uint32_t handle; uint32_t handle;
uint32_t pad;
/** Returned GTT offset of the buffer. */ /** Returned GTT offset of the buffer. */
uint64_t offset; uint64_t offset;
@ -494,6 +496,7 @@ struct drm_i915_gem_pin {
struct drm_i915_gem_unpin { struct drm_i915_gem_unpin {
/** Handle of the buffer to be unpinned. */ /** Handle of the buffer to be unpinned. */
uint32_t handle; uint32_t handle;
uint32_t pad;
}; };