Commit 50a1d632 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] i830 DRM missing put_user

From: Arjan van de Ven <arjanv@redhat.com>

The patch below adds a few missing put_user()'s to the i810/i830 drm
modules.  Users reported oopses with 4g/4g split in action, and sparse
annotations indeed found the offender in the function in question.  I've
kept the sparse __user annotations since those are generally useful anyway.
 I can't test it myself but a few people reported that the oopses went away
so far.
parent 1079b187
......@@ -844,11 +844,13 @@ static void i810_dma_dispatch_vertex(drm_device_t *dev,
if (buf_priv->currently_mapped == I810_BUF_MAPPED) {
unsigned int prim = (sarea_priv->vertex_prim & PR_MASK);
*(u32 *)buf_priv->virtual = (GFX_OP_PRIMITIVE | prim |
((used/4)-2));
put_user((GFX_OP_PRIMITIVE | prim |
((used/4)-2)),
(u32 *)buf_priv->virtual);
if (used & 4) {
*(u32 *)((u32)buf_priv->virtual + used) = 0;
put_user(0,
(u32 *)((u32)buf_priv->virtual + used));
used += 4;
}
......
......@@ -39,6 +39,7 @@
#include <linux/interrupt.h> /* For task queue support */
#include <linux/pagemap.h> /* For FASTCALL on unlock_page() */
#include <linux/delay.h>
#include <asm/uaccess.h>
#define I830_BUF_FREE 2
#define I830_BUF_CLIENT 1
......@@ -160,7 +161,7 @@ static int i830_map_buffer(drm_buf_t *buf, struct file *filp)
old_fops = filp->f_op;
filp->f_op = &i830_buffer_fops;
dev_priv->mmap_buffer = buf;
buf_priv->virtual = (void *)do_mmap(filp, 0, buf->total,
buf_priv->virtual = (void __user *)do_mmap(filp, 0, buf->total,
PROT_READ|PROT_WRITE,
MAP_SHARED,
buf->bus_address);
......@@ -462,7 +463,7 @@ static int i830_dma_initialize(drm_device_t *dev,
}
int i830_dma_init(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
unsigned int cmd, unsigned long __user arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
......@@ -470,7 +471,7 @@ int i830_dma_init(struct inode *inode, struct file *filp,
drm_i830_init_t init;
int retcode = 0;
if (copy_from_user(&init, (drm_i830_init_t *)arg, sizeof(init)))
if (copy_from_user(&init, (void * __user) arg, sizeof(init)))
return -EFAULT;
switch(init.func) {
......@@ -1164,19 +1165,19 @@ static void i830_dma_dispatch_vertex(drm_device_t *dev,
DRM_DEBUG( "start + used - 4 : %ld\n", start + used - 4);
if (buf_priv->currently_mapped == I830_BUF_MAPPED) {
u32 *vp = buf_priv->virtual;
u32 *vp = buf_priv->virtual;
vp[0] = (GFX_OP_PRIMITIVE |
put_user( (GFX_OP_PRIMITIVE |
sarea_priv->vertex_prim |
((used/4)-2));
((used/4)-2)), &vp[0]);
if (dev_priv->use_mi_batchbuffer_start) {
vp[used/4] = MI_BATCH_BUFFER_END;
put_user(MI_BATCH_BUFFER_END, &vp[used/4]);
used += 4;
}
if (used & 4) {
vp[used/4] = 0;
put_user(0, &vp[used/4]);
used += 4;
}
......@@ -1314,7 +1315,7 @@ void i830_reclaim_buffers( struct file *filp )
}
int i830_flush_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
unsigned int cmd, unsigned long __user arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
......@@ -1329,7 +1330,7 @@ int i830_flush_ioctl(struct inode *inode, struct file *filp,
}
int i830_dma_vertex(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
unsigned int cmd, unsigned long __user arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
......@@ -1340,7 +1341,7 @@ int i830_dma_vertex(struct inode *inode, struct file *filp,
dev_priv->sarea_priv;
drm_i830_vertex_t vertex;
if (copy_from_user(&vertex, (drm_i830_vertex_t *)arg, sizeof(vertex)))
if (copy_from_user(&vertex, (drm_i830_vertex_t __user *)arg, sizeof(vertex)))
return -EFAULT;
if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
......@@ -1364,13 +1365,13 @@ int i830_dma_vertex(struct inode *inode, struct file *filp,
}
int i830_clear_bufs(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
unsigned int cmd, unsigned long __user arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_i830_clear_t clear;
if (copy_from_user(&clear, (drm_i830_clear_t *)arg, sizeof(clear)))
if (copy_from_user(&clear, (drm_i830_clear_t __user *)arg, sizeof(clear)))
return -EFAULT;
if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
......@@ -1391,7 +1392,7 @@ int i830_clear_bufs(struct inode *inode, struct file *filp,
}
int i830_swap_bufs(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
unsigned int cmd, unsigned long __user arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
......@@ -1434,7 +1435,7 @@ int i830_do_cleanup_pageflip( drm_device_t *dev )
}
int i830_flip_bufs(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
unsigned int cmd, unsigned long __user arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
......@@ -1455,7 +1456,7 @@ int i830_flip_bufs(struct inode *inode, struct file *filp,
}
int i830_getage(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
unsigned long __user arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
......@@ -1469,7 +1470,7 @@ int i830_getage(struct inode *inode, struct file *filp, unsigned int cmd,
}
int i830_getbuf(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
unsigned long __user arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
......@@ -1481,7 +1482,7 @@ int i830_getbuf(struct inode *inode, struct file *filp, unsigned int cmd,
dev_priv->sarea_priv;
DRM_DEBUG("getbuf\n");
if (copy_from_user(&d, (drm_i830_dma_t *)arg, sizeof(d)))
if (copy_from_user(&d, (drm_i830_dma_t __user *)arg, sizeof(d)))
return -EFAULT;
if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
......@@ -1496,7 +1497,7 @@ int i830_getbuf(struct inode *inode, struct file *filp, unsigned int cmd,
DRM_DEBUG("i830_dma: %d returning %d, granted = %d\n",
current->pid, retcode, d.granted);
if (copy_to_user((drm_dma_t *)arg, &d, sizeof(d)))
if (copy_to_user((drm_dma_t __user *)arg, &d, sizeof(d)))
return -EFAULT;
sarea_priv->last_dispatch = (int) hw_status[5];
......@@ -1506,7 +1507,7 @@ int i830_getbuf(struct inode *inode, struct file *filp, unsigned int cmd,
int i830_copybuf(struct inode *inode,
struct file *filp,
unsigned int cmd,
unsigned long arg)
unsigned long __user arg)
{
/* Never copy - 2.4.x doesn't need it */
return 0;
......@@ -1521,7 +1522,7 @@ int i830_docopy(struct inode *inode, struct file *filp, unsigned int cmd,
int i830_getparam( struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg )
unsigned long __user arg )
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
......@@ -1534,7 +1535,7 @@ int i830_getparam( struct inode *inode, struct file *filp, unsigned int cmd,
return -EINVAL;
}
if (copy_from_user(&param, (drm_i830_getparam_t *)arg, sizeof(param) ))
if (copy_from_user(&param, (drm_i830_getparam_t __user *)arg, sizeof(param) ))
return -EFAULT;
switch( param.param ) {
......@@ -1555,7 +1556,7 @@ int i830_getparam( struct inode *inode, struct file *filp, unsigned int cmd,
int i830_setparam( struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg )
unsigned long __user arg )
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
......@@ -1567,7 +1568,7 @@ int i830_setparam( struct inode *inode, struct file *filp, unsigned int cmd,
return -EINVAL;
}
if (copy_from_user(&param, (drm_i830_setparam_t *)arg, sizeof(param) ))
if (copy_from_user(&param, (drm_i830_setparam_t __user *)arg, sizeof(param) ))
return -EFAULT;
switch( param.param ) {
......
......@@ -290,11 +290,11 @@ typedef struct _drm_i830_vertex {
typedef struct _drm_i830_copy_t {
int idx; /* buffer index */
int used; /* nr bytes in use */
void *address; /* Address to copy from */
void __user *address; /* Address to copy from */
} drm_i830_copy_t;
typedef struct drm_i830_dma {
void *virtual;
void __user *virtual;
int request_idx;
int request_size;
int granted;
......@@ -304,7 +304,7 @@ typedef struct drm_i830_dma {
/* 1.3: Userspace can request & wait on irq's:
*/
typedef struct drm_i830_irq_emit {
int *irq_seq;
int __user *irq_seq;
} drm_i830_irq_emit_t;
typedef struct drm_i830_irq_wait {
......@@ -318,7 +318,7 @@ typedef struct drm_i830_irq_wait {
typedef struct drm_i830_getparam {
int param;
int *value;
int __user *value;
} drm_i830_getparam_t;
......
......@@ -36,7 +36,7 @@ typedef struct drm_i830_buf_priv {
u32 *in_use;
int my_use_idx;
int currently_mapped;
void *virtual;
void __user *virtual;
void *kernel_virtual;
} drm_i830_buf_priv_t;
......
......@@ -121,7 +121,7 @@ int i830_wait_irq(drm_device_t *dev, int irq_nr)
/* Needs the lock as it touches the ring.
*/
int i830_irq_emit( struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg )
unsigned long __user arg )
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment