Index: linux-core/drm_bufs.c =================================================================== RCS file: /home/eich/cvs/drm/linux-core/drm_bufs.c,v retrieving revision 1.1.1.2 diff -u -r1.1.1.2 drm_bufs.c --- linux-core/drm_bufs.c 12 Apr 2005 17:48:19 -0000 1.1.1.2 +++ linux-core/drm_bufs.c 17 May 2005 13:22:54 -0000 @@ -44,7 +44,7 @@ drm_map_list_t *r_list = NULL; hash = (unsigned int)(((lhandle >> 32) - + ((lhandle >> 16) /* & 0xffff0000 */) + + ((lhandle >> 16) & 0xffff0000) + lhandle) & PAGE_MASK); while (1) { if (hash == 0) hash = (1 << 16); @@ -128,10 +128,11 @@ if (map->type == _DRM_REGISTERS) map->handle = drm_ioremap(map->offset, map->size, dev); + + down(&dev->struct_sem); if (map->offset) map->pub_handle = HandleID((unsigned long) map->offset,dev); - down(&dev->struct_sem); list_add(&list->head, &dev->maplist->head); up(&dev->struct_sem); @@ -323,14 +324,14 @@ list->map = map; down(&dev->struct_sem); + map->pub_handle = (map->type == _DRM_SHM + ? HandleID((unsigned long)map->handle,dev) + : HandleID(map->offset,dev)); list_add(&list->head, &dev->maplist->head); up(&dev->struct_sem); + found_it: - - map->pub_handle = - tmp_map.handle = (map->type == _DRM_SHM - ? HandleID((unsigned long)map->handle,dev) - : HandleID(map->offset,dev)); + tmp_map.handle = map->pub_handle; if ( copy_to_user( argp, &tmp_map, sizeof(tmp_map) ) ) return -EFAULT; Index: linux-core/drm_context.c =================================================================== RCS file: /home/eich/cvs/drm/linux-core/drm_context.c,v retrieving revision 1.1.1.2 retrieving revision 1.1.1.3 diff -u -r1.1.1.2 -r1.1.1.3 --- linux-core/drm_context.c 12 Apr 2005 17:48:19 -0000 1.1.1.2 +++ linux-core/drm_context.c 12 Apr 2005 17:59:34 -0000 1.1.1.3 @@ -372,7 +372,7 @@ memset(&ctx, 0, sizeof(ctx)); for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) { ctx.handle = i; - if (copy_to_user(&res.contexts[i], &i, sizeof(i))) + if (copy_to_user(&res.contexts[i], &ctx, sizeof(ctx))) return -EFAULT; } } Index: linux-core/drm_ioctl32.c =================================================================== RCS file: /home/eich/cvs/drm/linux-core/drm_ioctl32.c,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 drm_ioctl32.c --- linux-core/drm_ioctl32.c 12 Apr 2005 17:48:19 -0000 1.1.1.1 +++ linux-core/drm_ioctl32.c 17 May 2005 13:22:54 -0000 @@ -41,6 +41,8 @@ #ifdef __x86_64__ +#define NEW_IOCTL32 + #include #include "drm.h" #define IOCTL32_PRIVATE @@ -66,10 +68,8 @@ #define DRM_IOCTL_MAP_BUFS_32 DRM_IOWR(0x19, drm32_buf_map_t) #define DRM_IOCTL_FREE_BUFS_32 DRM_IOW( 0x1a, drm32_buf_free_t) #define DRM_IOCTL_RM_MAP_32 DRM_IOW( 0x1b, drm32_map_t) -#if 0 #define DRM_IOCTL_SET_SAREA_CTX_32 DRM_IOW( 0x1c, drm32_ctx_priv_map_t) #define DRM_IOCTL_GET_SAREA_CTX_32 DRM_IOWR(0x1d, drm32_ctx_priv_map_t) -#endif #define DRM_IOCTL_RES_CTX_32 DRM_IOWR(0x26, drm32_ctx_res_t) #define DRM_IOCTL_DMA_32 DRM_IOWR(0x29, drm32_dma_t) #define DRM_IOCTL_AGP_ENABLE_32 DRM_IOW( 0x32, drm32_agp_mode_t) @@ -108,12 +108,10 @@ /*?*/ unsigned int iocs; /* Ioctl count */ } drm32_client_t; -#if 0 typedef struct drm32_ctx_priv_map { unsigned int ctx_id; /* Context requesting private mapping */ /*?*/ u32 handle; /* Handle of map */ } drm32_ctx_priv_map_t; -#endif typedef struct drm32_buf_desc { /* OK */ int count; /* Number of buffers of this size */ @@ -247,22 +245,23 @@ drm_version_32_64(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - drm32_version_t *arg32 = (drm32_version_t *) arg; - drm_version_t arg64; - mm_segment_t old_fs; + DECLARE_ARG32(drm32_version_t); + DECLARE_ARG64(drm_version_t); int err = 0; - u64 dummy; + DUMMY_ARG; + DUMMY_ARG_P; + OLD_FS; DEBUG("drm_version_32_64"); GET_USER(version_major); GET_USER(version_minor); GET_USER(version_patchlevel); GET_USER(name_len); - GET_USER_P(name); + GET_USER_P(name,VERIFY_WRITE,ARG64(name_len)); GET_USER(date_len); - GET_USER_P(date); + GET_USER_P(date,VERIFY_WRITE,ARG64(date_len)); GET_USER(desc_len); - GET_USER_P(desc); + GET_USER_P(desc,VERIFY_WRITE,ARG64(desc_len)); if (err) return -EFAULT; @@ -287,15 +286,16 @@ drm_unique_wr_32_64(unsigned int fd, unsigned cmd, unsigned long arg, struct file *file) { - drm32_unique_t *arg32 = (drm32_unique_t *) arg; - drm_unique_t arg64; - mm_segment_t old_fs; + DECLARE_ARG32(drm32_unique_t); + DECLARE_ARG64(drm_unique_t); int err = 0; - u64 dummy; + DUMMY_ARG; + DUMMY_ARG_P; + OLD_FS; DEBUG("drm_unique_wr_32_64"); GET_USER(unique_len); - GET_USER_P(unique); + GET_USER_P(unique,VERIFY_WRITE,ARG64(unique_len)); if (err) return -EFAULT; @@ -312,15 +312,16 @@ drm_unique_w_32_64(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - drm32_unique_t *arg32 = (drm32_unique_t *) arg; - drm_unique_t arg64; - mm_segment_t old_fs; + DECLARE_ARG32(drm32_unique_t); + DECLARE_ARG64(drm_unique_t); int err = 0; - u64 dummy; + DUMMY_ARG; + DUMMY_ARG_P; + OLD_FS; DEBUG("drm_unique_w_32_64"); GET_USER(unique_len); - GET_USER_P(unique); + GET_USER_P(unique,VERIFY_WRITE,ARG64(unique_len)); if (err) return -EFAULT; @@ -333,11 +334,11 @@ drm_addmap_rw_32_64(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - drm32_map_t *arg32 = (drm32_map_t *) arg; - drm_map_t arg64; - mm_segment_t old_fs; + DECLARE_ARG32(drm32_map_t); + DECLARE_ARG64(drm_map_t); int err = 0; -// u64 dummy; + DUMMY_ARG; + OLD_FS; DEBUG("drm_addmap_rw_32_64"); GET_USER(offset); @@ -363,11 +364,11 @@ drm_getmap_rw_32_64(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - drm32_map_t *arg32 = (drm32_map_t *) arg; - drm_map_t arg64; - mm_segment_t old_fs; + DECLARE_ARG32(drm32_map_t); + DECLARE_ARG64(drm_map_t); + DUMMY_ARG; int err = 0; -// u64 dummy; + OLD_FS; DEBUG("drm_getmap_rw_32_64"); GET_USER(offset); @@ -395,18 +396,18 @@ drm_map_w_32_64(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - drm32_map_t *arg32 = (drm32_map_t *) arg; - drm_map_t arg64; - mm_segment_t old_fs; + DECLARE_ARG32(drm32_map_t); + DECLARE_ARG64(drm_map_t); int err = 0; -// u64 dummy; + DUMMY_ARG; + OLD_FS; DEBUG("drm_map_w_32_64"); GET_USER(offset); GET_USER(size); GET_USER(type); GET_USER(flags); -// GET_USER_P(handle); +// GET_USER(handle); GET_USER(mtrr); if (err) return -EFAULT; @@ -420,10 +421,11 @@ drm_client_32_64(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - drm32_client_t *arg32 = (drm32_client_t *) arg; - drm_client_t arg64; - mm_segment_t old_fs; + DECLARE_ARG32(drm32_client_t); + DECLARE_ARG64(drm_client_t); int err = 0; + DUMMY_ARG; + OLD_FS; DEBUG("drm_client_32_64"); GET_USER(idx); @@ -457,18 +459,21 @@ drm_stats_32_64(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - drm32_stats_t *arg32 = (drm32_stats_t *) arg; - drm_stats_t arg64; - mm_segment_t old_fs; + DECLARE_ARG32(drm32_stats_t); + DECLARE_ARG64(drm_stats_t); int err = 0; - int i; + int i, count; + DUMMY_ARG; + OLD_FS; DEBUG("drm_stats_32_64"); SYS_IOCTL; if (err) return err; PUT_USER(count); - for (i = 0; i < arg64.count; i ++) { + GET_ARG64(count,count); + + for (i = 0; i < count; i ++) { PUT_USER(data[i].value); PUT_USER(data[i].type); } @@ -477,20 +482,19 @@ return err ? -EFAULT : 0; } -#if 0 static int drm_ctx_priv_map_wr_32_64(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - drm32_ctx_priv_map_t *arg32 = (drm32_ctx_priv_map_t *) arg; - drm_ctx_priv_map_t arg64; - mm_segment_t old_fs; + DECLARE_ARG32(drm32_ctx_priv_map_t); + DECLARE_ARG64(drm_ctx_priv_map_t); int err = 0; - u64 dummy; + DUMMY_ARG; + OLD_FS; DEBUG("drm_ctx_priv_map_wr_32_64"); GET_USER(ctx_id); -// GET_USER_P(handle); +// GET_USER(handle); if (err) return -EFAULT; @@ -498,7 +502,7 @@ if (err) return err; // PUT_USER(ctx_id); - PUT_USER_P(handle); + PUT_USER(handle); DEBUG("done"); return err ? -EFAULT : 0; @@ -508,15 +512,15 @@ drm_ctx_priv_map_w_32_64(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - drm32_ctx_priv_map_t *arg32 = (drm32_ctx_priv_map_t *) arg; - drm_ctx_priv_map_t arg64; - mm_segment_t old_fs; + DECLARE_ARG32(drm32_ctx_priv_map_t); + DECLARE_ARG64(drm_ctx_priv_map_t); int err = 0; - u64 dummy; + DUMMY_ARG; + OLD_FS; DEBUG("drm_ctx_priv_map_w_32_64"); GET_USER(ctx_id); - GET_USER_P(handle); + GET_USER(handle); if (err) return -EFAULT; @@ -525,21 +529,21 @@ DEBUG("done"); return err; } -#endif static int drm_ctx_res_32_64(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - drm32_ctx_res_t *arg32 = (drm32_ctx_res_t *) arg; - drm_ctx_res_t arg64; - mm_segment_t old_fs; + DECLARE_ARG32(drm32_ctx_res_t); + DECLARE_ARG64(drm_ctx_res_t); int err = 0; - u64 dummy; + DUMMY_ARG; + DUMMY_ARG_P; + OLD_FS; DEBUG("drm_ctx_res_32_64"); GET_USER(count); - GET_USER_P(contexts); + GET_USER_P(contexts,VERIFY_WRITE, ARG64(count)*sizeof(drm_ctx_t)); if (err) return -EFAULT; @@ -558,22 +562,25 @@ drm_dma_32_64(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - drm32_dma_t *arg32 = (drm32_dma_t *) arg; - drm_dma_t arg64; - mm_segment_t old_fs; + DECLARE_ARG32(drm32_dma_t); + DECLARE_ARG64(drm_dma_t); int err = 0; - u64 dummy; + DUMMY_ARG; + DUMMY_ARG_P; + OLD_FS; DEBUG("drm_dma_32_64"); GET_USER(context); GET_USER(send_count); - GET_USER_P(send_indices); - GET_USER_P(send_sizes); + GET_USER_P(send_indices, VERIFY_READ, ARG64(send_count) * sizeof(int)); + GET_USER_P(send_sizes, VERIFY_READ, ARG64(send_count) * sizeof(int)); GET_USER(flags); GET_USER(request_count); GET_USER(request_size); - GET_USER_P(request_indices); - GET_USER_P(request_sizes); + GET_USER_P(request_indices, VERIFY_WRITE, + ARG64(request_count) * sizeof(int)); + GET_USER_P(request_sizes, VERIFY_WRITE, + ARG64(request_count) * sizeof(int)); GET_USER(granted_count); if (err) return -EFAULT; @@ -600,10 +607,11 @@ drm_buf_desc_wr_32_64(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - drm32_buf_desc_t *arg32 = (drm32_buf_desc_t *) arg; - drm_buf_desc_t arg64; - mm_segment_t old_fs; + DECLARE_ARG32(drm32_buf_desc_t); + DECLARE_ARG64(drm_buf_desc_t); int err = 0; + DUMMY_ARG; + OLD_FS; DEBUG("drm_buf_desc_wr_32_64"); GET_USER(count); @@ -633,10 +641,11 @@ drm_buf_desc_w_32_64(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - drm32_buf_desc_t *arg32 = (drm32_buf_desc_t *) arg; - drm_buf_desc_t arg64; - mm_segment_t old_fs; + DECLARE_ARG32(drm32_buf_desc_t); + DECLARE_ARG64(drm_buf_desc_t); int err = 0; + DUMMY_ARG; + OLD_FS; DEBUG("drm_buf_desc_w_32_64"); GET_USER(count); @@ -658,28 +667,31 @@ drm_buf_info_32_64(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - drm32_buf_info_t *arg32 = (drm32_buf_info_t *) arg; - drm_buf_info_t arg64; - mm_segment_t old_fs; - int err = 0; - drm32_buf_desc_t *list32 = (drm32_buf_desc_t*)(u64)arg32->list; - drm_buf_desc_t *list64; - int i; - + DECLARE_ARG32(drm32_buf_info_t); + DECLARE_ARG64_NOALLOC(drm_buf_info_t); + drm32_buf_desc_t __user *list32; + drm_buf_desc_t __IOCTL32_USER *list64; + u64 tmp; + int i, num, count; + int err = 0; + DUMMY_ARG; + OLD_FS; + DEBUG("drm_buf_info_32_64"); - list64 = K_ALLOC(arg32->count * sizeof (drm_buf_desc_t)); + + if (get_user(num,&ARG32(count)) || num < 0) return -EFAULT; + + err |= get_user(tmp,&ARG32(list)); + if (err) return -EFAULT; + list32 = (drm32_buf_desc_t __user *)tmp; + + if (num < DRM_MAX_ORDER + 1) num = DRM_MAX_ORDER + 1; + + K_ALLOC(list64, num * sizeof (drm_buf_desc_t)); if (!list64) return -EFAULT; GET_USER(count); - arg64.list = list64; - - for (i = 0 ; i < arg32->count; i ++) { - err |= get_user(list64[i].count,&list32[i].count); - err |= get_user(list64[i].size,&list32[i].size); - err |= get_user(list64[i].high_mark,&list32[i].low_mark); - err |= get_user(list64[i].flags,&list32[i].flags); - err |= get_user(list64[i].agp_start,&list32[i].agp_start); - } + PUT_ARG64(list,list64); if (err) { K_FREE(list64); @@ -692,14 +704,16 @@ return err; } - - for (i = 0 ; i < arg32->count; i ++) { - err |= put_user(list64[i].count,&list32[i].count); - err |= put_user(list64[i].size,&list32[i].size); - err |= put_user(list64[i].low_mark,&list32[i].low_mark); - err |= put_user(list64[i].high_mark,&list32[i].high_mark); - err |= put_user(list64[i].flags,&list32[i].flags); -// err |= put_user(list64[i].agp_start,&list32[i].agp_start); + GET_ARG64(count,count); + if (num > count) { + for (i = 0 ; i < count; i ++) { + PUT_USER_ARG(list64[i].count,list32[i].count); + PUT_USER_ARG(list64[i].size,list32[i].size); + PUT_USER_ARG(list64[i].low_mark,list32[i].low_mark); + PUT_USER_ARG(list64[i].high_mark,list32[i].high_mark); + PUT_USER_ARG(list64[i].flags,list32[i].flags); +// PUT_USER_ARG(list64[i].agp_start,list32[i].agp_start); + } } PUT_USER(count); @@ -714,52 +728,52 @@ drm_buf_map_32_64(unsigned int fd, unsigned cmd, unsigned long arg, struct file *file) { - drm32_buf_map_t *arg32 = (drm32_buf_map_t *) arg; - drm_buf_map_t arg64; - mm_segment_t old_fs; - int err = 0; - drm32_buf_pub_t *list32 = (drm32_buf_pub_t*)(unsigned long)arg32->list; - drm_buf_pub_t *list64; - int count, i; - u64 dummy; + DECLARE_ARG32(drm32_buf_map_t); + DECLARE_ARG64_NOALLOC(drm_buf_map_t); + int err = 0; + drm32_buf_pub_t __user *list32; + drm_buf_pub_t __IOCTL32_USER *list64; + int i, count, tmp_count; + u64 tmp; + DUMMY_ARG; + DUMMY_ARG_P; + OLD_FS; DEBUG("drm_buf_map_32_64"); - list64 = K_ALLOC(arg32->count * sizeof (drm_buf_pub_t)); + + if (get_user(count,& ARG32(count)) || count < 0) return -EFAULT; + + if (get_user(tmp,&ARG32(list))) return -EFAULT; + list32 = (drm32_buf_pub_t __user *) tmp; + + K_ALLOC(list64, count * sizeof (drm_buf_pub_t)); if (!list64) return -EFAULT; - + PUT_ARG64(list,list64); + GET_USER(count); - GET_USER_P(virtual); - arg64.list = list64; -#if 0 - for (i = 0 ; i < arg32->count; i ++) { - err |= get_user(list64[i].idx,&list32[i].idx); - err |= get_user(list64[i].total,&list32[i].total); - err |= get_user(list64[i].used,&list32[i].used); - err |= get_user(dummy,&list32[i].address); - list64[i].address = (void *)dummy; - } -#endif + if (err) { K_FREE(list64); return -EFAULT; } - + SYS_IOCTL; if (err) { K_FREE(list64); return err; } - count = arg32->count < arg64.count ? arg32->count : arg64.count; PUT_USER(count); PUT_USER_P(virtual); + GET_ARG64(tmp_count,count); + if (count > tmp_count) count = tmp_count; + for (i = 0 ; i < count; i ++) { - err |= put_user(list64[i].idx,&list32[i].idx); - err |= put_user(list64[i].total,&list32[i].total); - err |= put_user(list64[i].used,&list32[i].used); - dummy = (u64)list64[i].address; - err |= put_user((u32)dummy,&list32[i].address); + PUT_USER_ARG(list64[i].idx,list32[i].idx); + PUT_USER_ARG(list64[i].total,list32[i].total); + PUT_USER_ARG(list64[i].used,list32[i].used); + PUT_USER_ARG_P(list64[i].address,list32[i].address); } K_FREE(list64); @@ -770,18 +784,17 @@ drm_buf_free_w_32_64(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - drm32_buf_free_t *arg32 = (drm32_buf_free_t *) arg; - drm_buf_free_t arg64; - mm_segment_t old_fs; + DECLARE_ARG32(drm32_buf_free_t); + DECLARE_ARG64(drm_buf_free_t); int err = 0; - int i; - int *list32 = (int *)(unsigned long)arg32->list; + DUMMY_ARG; + DUMMY_ARG_P; + OLD_FS; DEBUG("drm_buf_free_w_32_64"); + printk(KERN_WARNING "drm_buf_free_w_32_64"); GET_USER(count); - for (i = 0; i < arg32->count; i++) - err |= get_user(arg64.list[i],&list32[i]); - + GET_USER_P(list, VERIFY_READ, ARG64(count) * sizeof(int)); if (err) return -EFAULT; @@ -795,10 +808,11 @@ drm_agp_info_32_64(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - drm32_agp_info_t *arg32 = (drm32_agp_info_t *) arg; - drm_agp_info_t arg64; - mm_segment_t old_fs; + DECLARE_ARG32(drm32_agp_info_t); + DECLARE_ARG64(drm_agp_info_t); + DUMMY_ARG; int err = 0; + OLD_FS; DEBUG("drm_agp_info_32_64"); @@ -826,10 +840,11 @@ drm_agp_buffer_w_32_64(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - drm32_agp_buffer_t *arg32 = (drm32_agp_buffer_t *) arg; - drm_agp_buffer_t arg64; - mm_segment_t old_fs; + DECLARE_ARG32(drm32_agp_buffer_t); + DECLARE_ARG64(drm_agp_buffer_t); int err = 0; + DUMMY_ARG; + OLD_FS; DEBUG("drm_agp_buffer_w_32_64"); GET_USER(handle); @@ -844,10 +859,11 @@ drm_agp_buffer_32_64(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - drm32_agp_buffer_t *arg32 = (drm32_agp_buffer_t *) arg; - drm_agp_buffer_t arg64; - mm_segment_t old_fs; + DECLARE_ARG32(drm32_agp_buffer_t); + DECLARE_ARG64(drm_agp_buffer_t); int err = 0; + DUMMY_ARG; + OLD_FS; DEBUG("drm_agp_buffer_32_64"); GET_USER(size); @@ -875,10 +891,11 @@ drm_agp_mode_w_32_64(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - drm32_agp_mode_t *arg32 = (drm32_agp_mode_t *) arg; - drm_agp_mode_t arg64; - mm_segment_t old_fs; + DECLARE_ARG32(drm32_agp_mode_t); + DECLARE_ARG64(drm_agp_mode_t); int err = 0; + DUMMY_ARG; + OLD_FS; DEBUG("drm_agp_mode_w_32_64"); GET_USER(mode); @@ -894,10 +911,11 @@ drm_agp_binding_w_32_64(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - drm32_agp_binding_t *arg32 = (drm32_agp_binding_t *) arg; - drm_agp_binding_t arg64; - mm_segment_t old_fs; + DECLARE_ARG32(drm32_agp_binding_t); + DECLARE_ARG64(drm_agp_binding_t); int err = 0; + DUMMY_ARG; + OLD_FS; DEBUG("drm_agp_binding_w_32_64"); GET_USER(handle); @@ -914,10 +932,11 @@ drm32_scatter_gather_w_32_64(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - drm32_scatter_gather_t *arg32 = (drm32_scatter_gather_t *) arg; - drm_scatter_gather_t arg64; - mm_segment_t old_fs; + DECLARE_ARG32(drm32_scatter_gather_t); + DECLARE_ARG64(drm_scatter_gather_t); int err = 0; + DUMMY_ARG; + OLD_FS; DEBUG("drm_agp_scatter_gather_w_32_64"); @@ -935,27 +954,28 @@ drm32_wait_vblank_rw_32_64(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - drm32_wait_vblank_t *arg32 = (drm32_wait_vblank_t *) arg; - drm_wait_vblank_t arg64; - mm_segment_t old_fs; + DECLARE_ARG32(drm32_wait_vblank_t); + DECLARE_ARG64(drm_wait_vblank_t); int err = 0; + DUMMY_ARG; + OLD_FS; DEBUG("drm_agp_scatter_gather_rw_32_64"); - err |= get_user(arg64.request.type,&arg32->request.type); - err |= get_user(arg64.request.sequence,&arg32->request.sequence); - err |= get_user(arg64.request.signal,&arg32->request.signal); + GET_USER(request.type); + GET_USER(request.sequence); + GET_USER(request.signal); if (err) return -EFAULT; SYS_IOCTL; - err |= put_user(arg64.reply.type,&arg32->reply.type); - err |= put_user(arg64.reply.sequence,&arg32->reply.sequence); + PUT_USER(reply.type); + PUT_USER(reply.sequence); ASSERT32(reply.tval_sec); - err |= put_user(arg64.reply.tval_sec,&arg32->reply.tval_sec); + PUT_USER(reply.tval_sec); ASSERT32(reply.tval_usec); - err |= put_user(arg64.reply.tval_usec,&arg32->reply.tval_usec); + PUT_USER(reply.tval_usec); return err ? -EFAULT : 0; } @@ -985,10 +1005,8 @@ REG_IOCTL32(DRM_IOCTL_MAP_BUFS_32,drm_buf_map_32_64); REG_IOCTL32(DRM_IOCTL_FREE_BUFS_32,drm_buf_free_w_32_64); REG_IOCTL32(DRM_IOCTL_RM_MAP_32,drm_map_w_32_64); -#if 0 REG_IOCTL32(DRM_IOCTL_SET_SAREA_CTX_32,drm_ctx_priv_map_w_32_64); REG_IOCTL32(DRM_IOCTL_GET_SAREA_CTX_32,drm_ctx_priv_map_wr_32_64); -#endif REG_IOCTL32(DRM_IOCTL_RES_CTX_32,drm_ctx_res_32_64) REG_IOCTL32(DRM_IOCTL_DMA_32,drm_dma_32_64); REG_IOCTL32(DRM_IOCTL_AGP_ENABLE_32,drm_agp_mode_w_32_64); @@ -1007,8 +1025,10 @@ REG_IOCTL32(DRM_IOCTL_BLOCK,drm32_default_handler); REG_IOCTL32(DRM_IOCTL_UNBLOCK,drm32_default_handler); REG_IOCTL32(DRM_IOCTL_CONTROL,drm32_default_handler); +#if 0 REG_IOCTL32(DRM_IOCTL_SET_SAREA_CTX,drm32_default_handler); REG_IOCTL32(DRM_IOCTL_GET_SAREA_CTX,drm32_default_handler); +#endif REG_IOCTL32(DRM_IOCTL_ADD_CTX,drm32_default_handler); REG_IOCTL32(DRM_IOCTL_RM_CTX,drm32_default_handler); REG_IOCTL32(DRM_IOCTL_MOD_CTX,drm32_default_handler); @@ -1037,10 +1057,8 @@ UNREG_IOCTL32(DRM_IOCTL_VERSION_32); UNREG_IOCTL32(DRM_IOCTL_GET_UNIQUE_32); UNREG_IOCTL32(DRM_IOCTL_GET_CLIENT_32); -#if 0 UNREG_IOCTL32(DRM_IOCTL_SET_SAREA_CTX_32); UNREG_IOCTL32(DRM_IOCTL_GET_SAREA_CTX_32); -#endif UNREG_IOCTL32(DRM_IOCTL_RES_CTX_32); UNREG_IOCTL32(DRM_IOCTL_DMA_32); @@ -1072,8 +1090,10 @@ UNREG_IOCTL32(DRM_IOCTL_BLOCK); UNREG_IOCTL32(DRM_IOCTL_UNBLOCK); UNREG_IOCTL32(DRM_IOCTL_CONTROL); +#if 0 UNREG_IOCTL32(DRM_IOCTL_SET_SAREA_CTX); UNREG_IOCTL32(DRM_IOCTL_GET_SAREA_CTX); +#endif UNREG_IOCTL32(DRM_IOCTL_ADD_CTX); UNREG_IOCTL32(DRM_IOCTL_RM_CTX); UNREG_IOCTL32(DRM_IOCTL_MOD_CTX); Index: linux-core/drm_ioctl32.h =================================================================== RCS file: /home/eich/cvs/drm/linux-core/drm_ioctl32.h,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 drm_ioctl32.h --- linux-core/drm_ioctl32.h 12 Apr 2005 17:48:19 -0000 1.1.1.1 +++ linux-core/drm_ioctl32.h 17 May 2005 13:22:54 -0000 @@ -23,42 +23,152 @@ *ings in this Software without prior written authorization from Egbert Eich. * */ +/* #undef NEW_IOCTL32 */ #ifndef _DRM_IOCTL32_H # define _DRM_IOCTL32_H # ifdef IOCTL32_PRIVATE -#define DEBUG(x) /**/ /* printk(KERN_DEBUG"%s\n",x) */ -#define SYS_IOCTL_FUNC sys_ioctl +# define DEBUG(x) printk(KERN_DEBUG"%s\n",x); +# define DEBUG_IOCTL32(nr) \ + printk(KERN_WARNING "Registering IOCTL32: %lx\n",nr); -# define GET_USER_ARGS(x32,x64,elem) err |= get_user(x64.elem,&x32->elem) -# define PUT_USER_ARGS(x32,x64,elem) err |= put_user(x64.elem,&x32->elem) -# define GET_USER(elem) GET_USER_ARGS(arg32,arg64,elem) -# define PUT_USER(elem) PUT_USER_ARGS(arg32,arg64,elem) -# define GET_USER_P_ARGS(x32,x64,elem) do { \ - err |= get_user(dummy,&x32->elem); \ - x64.elem = (void *) dummy; \ -} while (0); -# define PUT_USER_P_ARGS(x32,x64,elem) do { \ - dummy = (u64) x64.elem; \ - err |= put_user((u32)dummy,&x32->elem); \ -} while (0); - -# define GET_USER_P(elem) GET_USER_P_ARGS(arg32,arg64,elem) -# define PUT_USER_P(elem) PUT_USER_P_ARGS(arg32,arg64,elem) - -# define SYS_IOCTL do { \ - old_fs = get_fs(); \ - set_fs(KERNEL_DS); \ - DEBUG("SYS_IOCTL_FUNC called"); \ - err = SYS_IOCTL_FUNC(fd,cmd,(unsigned long)&arg64); \ - DEBUG("SYS_IOCTL_FUNC done"); \ - set_fs(old_fs); \ +# define SYS_IOCTL_FUNC sys_ioctl + +# ifndef NEW_IOCTL32 + +# define DECLARE_ARG32(x) x __user *arg32 = (x __user *) arg +# define DECLARE_ARG64(x) x __user arg64 +# define DECLARE_ARG64_NOALLOC(x) DECLARE_ARG64(x) +# define OLD_FS mm_segment_t old_fs; +# define DUMMY_ARG +# define DUMMY_ARG_P u64 dummy + +# define ARG32(arg) arg32->arg +# define ARG64(arg) arg64.arg + +# define GET_ARG64(target,arg) target = ARG64(arg) +# define PUT_ARG64(arg,val) val = ARG64(arg) + +# define GET_USER_ARG(x64,x32) err |= get_user(x64,&x32) +# define PUT_USER_ARG(x64,x32) err |= put_user(x64,&x32) + +# define GET_USER(elem) GET_USER_ARG(arg64.elem,arg32->elem) +# define PUT_USER(elem) PUT_USER_ARG(arg64.elem,arg32->elem) + +# define VERIFY_SIZE(x) do { x; } while (0); +# define VERIFY_SIZE_DECL(x) x + +# define GET_USER_ARG_P(x64,x32,acc,size) \ + if (size == 0 || access_ok(acc,(void __user *)&(x32), size)) { \ + err |= get_user(dummy,&(x32)); \ + x64 = (void *) dummy; \ + } else \ + err |= -EFAULT; + + +# define PUT_USER_ARG_P(x64,x32) do { \ + dummy = (u64) (x64); \ + err |= put_user((u32)dummy,&(x32)); \ + } while (0); + +# define GET_USER_P(elem,acc,size) \ + GET_USER_ARG_P(arg64.elem,arg32->elem,acc,size) +# define PUT_USER_P(elem) PUT_USER_ARG_P(arg64.elem,arg32->elem) + +# define SYS_IOCTL do { \ + old_fs = get_fs(); \ + set_fs(KERNEL_DS); \ + DEBUG("SYS_IOCTL_FUNC called"); \ + err = SYS_IOCTL_FUNC(fd,cmd,(unsigned long)&arg64); \ + DEBUG("SYS_IOCTL_FUNC done"); \ + set_fs(old_fs); \ + } while (0); + +# define K_ALLOC(addr, x) addr = kmalloc(x,GFP_KERNEL) +# define K_FREE(x) kfree(x) +# define __IOCTL32_USER + +# define ASSERT32(x) do { \ + if (ARG64(x) & 0xFFFFFFFF00000000) \ + printk(KERN_WARNING "ioctl32: var " #x " is > 32bit in ioctl(0x%x)\n",cmd); \ + } while (0) + +# else /* NEW_IOCTL32 */ + +# include + +# define DECLARE_ARG32(x) x __user *arg32 = (x __user *) arg +# define DECLARE_ARG64(x) x __user *arg64 = compat_alloc_user_space(sizeof(*arg64)) +# define DECLARE_ARG64_NOALLOC(x) x __user *arg64 + +# define OLD_FS + +# define DUMMY_ARG u32 dummy +# define DUMMY_ARG_P compat_uptr_t dummy_p; + +# define ARG32(arg) arg32->arg +# define ARG64(arg) arg64->arg + +# define GET_ARG64(target, arg) err |= get_user(target,&ARG64(arg)) +# define PUT_ARG64(arg,val) (err |= put_user(tmp,&ARG64(arg))) + +# define GET_USER_ARG(x64,x32) do { \ + err |= get_user(dummy,&x32); \ + err |= put_user(dummy,&x64); \ + } while (0); + +# define PUT_USER_ARG(x64,x32) do { \ + err |= get_user(dummy,&x64); \ + err |= put_user(dummy,&x32); \ + } while (0); + +# define GET_USER(elem) GET_USER_ARG(arg64->elem,arg32->elem) +# define PUT_USER(elem) PUT_USER_ARG(arg64->elem,arg32->elem) + +# define VERIFY_SIZE(x) +# define VERIFY_SIZE_DECL(x) + +# define GET_USER_ARG_P(x64,x32,acc,size) do { \ + err |= get_user(dummy_p,&x32); \ + err |= put_user(compat_ptr(dummy_p),&x64); \ + } while (0); + +# define PUT_USER_ARG_P(x64,x32) do { \ + void __user *dummy_p; \ + err |= get_user(dummy_p,&(x64)); \ + err |= put_user((unsigned int)((unsigned long)dummy_p),&(x32)); \ + } while (0); + +# define GET_USER_P(elem,acc,size) \ + GET_USER_ARG_P(arg64->elem,arg32->elem,acc,size) +# define PUT_USER_P(elem) PUT_USER_ARG_P(arg64->elem,arg32->elem) + +# define SYS_IOCTL do { \ + DEBUG("SYS_IOCTL_FUNC called"); \ + err = SYS_IOCTL_FUNC(fd,cmd,(unsigned long)arg64); \ } while (0); -#define DEBUG_IOCTL32(nr) \ - printk(KERN_WARNING "Registering IOCTL32: %lx\n",nr); +# define K_ALLOC(addr,x) do { \ + arg64 = compat_alloc_user_space(sizeof(*arg64)+x); \ + addr = (void __user *)(arg64 + 1); \ + } while(0); + +# define K_FREE(x) + +# define __IOCTL32_USER __user + +# define ASSERT32(x) do { \ + u64 tmp = 0; \ + get_user(tmp,&ARG64(x)); \ + if (tmp & 0xFFFFFFFF00000000) \ + printk(KERN_WARNING "ioctl32: var " #x " is > 32bit in ioctl(0x%x)\n",cmd); \ + } while (0) + + +# endif /* NEW_IOCTL32 */ + # define REG_IOCTL32(nr,c_func) \ err = register_ioctl32_conversion(nr,c_func); \ @@ -67,13 +177,6 @@ # define UNREG_IOCTL32(nr) \ unregister_ioctl32_conversion(nr); -# define K_ALLOC(x) kmalloc(x,GFP_KERNEL) -# define K_FREE(x) kfree(x) - -# define ASSERT32(x) do { \ - if (arg64.x & 0xFFFFFFFF00000000) \ - printk(KERN_WARNING "ioctl32: var " #x " is > 32bit in ioctl(0x%x)\n",cmd); \ - } while (0) extern int drm32_default_handler(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file); @@ -82,5 +185,8 @@ extern int drm32_register(void); extern void drm32_unregister(void); +extern int radeon_register_ioctl32(void); +extern int r128_register_ioctl32(void); +extern int mga_register_ioctl32(void); #endif Index: linux-core/mga_ioctl32.c =================================================================== RCS file: /home/eich/cvs/drm/linux-core/mga_ioctl32.c,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 mga_ioctl32.c --- linux-core/mga_ioctl32.c 12 Apr 2005 17:48:19 -0000 1.1.1.1 +++ linux-core/mga_ioctl32.c 17 May 2005 13:22:54 -0000 @@ -44,6 +44,7 @@ #include "drm.h" #include "mga_drm.h" #define IOCTL32_PRIVATE +#define NEW_IOCTL32 #include "drm_ioctl32.h" @@ -82,11 +83,12 @@ mga_init_w_32_64(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - drm32_mga_init_t *arg32 = (drm32_mga_init_t *) arg; - drm_mga_init_t arg64; - mm_segment_t old_fs; + DECLARE_ARG32(drm32_mga_init_t); + DECLARE_ARG64(drm_mga_init_t); + DUMMY_ARG; int err = 0; int i; + OLD_FS; DEBUG("mga_init_w_32_64"); GET_USER(func); @@ -125,15 +127,16 @@ mga_getparam_wr_32_64(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - drm32_mga_getparam_t *arg32 = (drm32_mga_getparam_t *) arg; - drm_mga_getparam_t arg64; - mm_segment_t old_fs; + DECLARE_ARG32(drm32_mga_getparam_t); + DECLARE_ARG64(drm_mga_getparam_t); + DUMMY_ARG; int err = 0; - u64 dummy; + DUMMY_ARG_P; + OLD_FS; DEBUG("mga_getparam_wr_32_64"); GET_USER(param); - GET_USER_P(value); + GET_USER_P(value, VERIFY_WRITE, sizeof(int)); if (err) return -EFAULT; Index: linux-core/r128_ioctl32.c =================================================================== RCS file: /home/eich/cvs/drm/linux-core/r128_ioctl32.c,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 r128_ioctl32.c --- linux-core/r128_ioctl32.c 12 Apr 2005 17:48:19 -0000 1.1.1.1 +++ linux-core/r128_ioctl32.c 17 May 2005 13:22:54 -0000 @@ -44,6 +44,7 @@ #include "drm.h" #include "r128_drm.h" #define IOCTL32_PRIVATE +#define NEW_IOCTL32 #include "drm_ioctl32.h" #define DRM_IOCTL_R128_INIT32 DRM_IOW( 0x40, drm32_r128_init_t) @@ -97,10 +98,11 @@ drm_128_init_32_64(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - drm32_r128_init_t *arg32 = (drm32_r128_init_t *) arg; - drm_r128_init_t arg64; - mm_segment_t old_fs; + DECLARE_ARG32(drm32_r128_init_t); + DECLARE_ARG64(drm_r128_init_t); int err = 0; + DUMMY_ARG; + OLD_FS; DEBUG("r128_init_32_64"); @@ -137,20 +139,33 @@ drm_128_depth_32_64(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - drm32_r128_depth_t *arg32 = (drm32_r128_depth_t *) arg; - drm_r128_depth_t arg64; - mm_segment_t old_fs; + DECLARE_ARG32(drm32_r128_depth_t); + DECLARE_ARG64(drm_r128_depth_t); int err = 0; - u64 dummy; + DUMMY_ARG; + DUMMY_ARG_P; + VERIFY_SIZE_DECL(int buffer_size = 0); + VERIFY_SIZE_DECL(int mask_size = 0); + OLD_FS; DEBUG("r128_depth_32_64"); GET_USER(func); GET_USER(n); - GET_USER_P(x); - GET_USER_P(y); - GET_USER_P(buffer); - GET_USER_P(mask); + GET_USER_P(x, VERIFY_READ, ARG64(n) * sizeof(*arg64.x)); + GET_USER_P(y, VERIFY_READ, ARG64(n) * sizeof(*arg64.y)); + VERIFY_SIZE( + switch (ARG64(func)) { + case R128_WRITE_SPAN: + case R128_WRITE_PIXELS: + buffer_size = ARG64(n) * sizeof(u32); + mask_size = ARG64(n) * sizeof(u8); + default: + break; + } + ); + GET_USER_P(buffer,VERIFY_READ,buffer_size); + GET_USER_P(mask,VERIFY_READ,mask_size); if (err) return -EFAULT; @@ -162,15 +177,15 @@ drm_128_stipple_32_64(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - drm32_r128_stipple_t *arg32 = (drm32_r128_stipple_t *) arg; - drm_r128_stipple_t arg64; - mm_segment_t old_fs; + DECLARE_ARG32(drm32_r128_stipple_t); + DECLARE_ARG64(drm_r128_stipple_t); int err = 0; - u64 dummy; + DUMMY_ARG_P; + OLD_FS; DEBUG("r128_stipple_32_64"); - GET_USER_P(mask); + GET_USER_P(mask, VERIFY_READ, 32 * sizeof(u32)); if (err) return -EFAULT; @@ -182,15 +197,16 @@ drm_128_getparam_32_64(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - drm32_r128_getparam_t *arg32 = (drm32_r128_getparam_t *) arg; - drm_r128_getparam_t arg64; - mm_segment_t old_fs; + DECLARE_ARG32(drm32_r128_getparam_t); + DECLARE_ARG64(drm_r128_getparam_t); int err = 0; - u64 dummy; + DUMMY_ARG; + DUMMY_ARG_P; + OLD_FS; DEBUG("r128_getparam_wr_32_64"); GET_USER(param); - GET_USER_P(value); + GET_USER_P(value, VERIFY_WRITE, sizeof(int)); if (err) return -EFAULT; Index: linux-core/radeon_ioctl32.c =================================================================== RCS file: /home/eich/cvs/drm/linux-core/radeon_ioctl32.c,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 radeon_ioctl32.c --- linux-core/radeon_ioctl32.c 12 Apr 2005 17:48:19 -0000 1.1.1.1 +++ linux-core/radeon_ioctl32.c 17 May 2005 13:22:54 -0000 @@ -42,8 +42,11 @@ #include #include "drm.h" +#include "drmP.h" #include "radeon_drm.h" +#include "radeon_drv.h" #define IOCTL32_PRIVATE +#define NEW_IOCTL32 #include "drm_ioctl32.h" @@ -154,19 +157,28 @@ drm_clear_w_32_64(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - drm32_radeon_clear_t *arg32 = (drm32_radeon_clear_t *) arg; - drm_radeon_clear_t arg64; - mm_segment_t old_fs; + DECLARE_ARG32(drm32_radeon_clear_t); + DECLARE_ARG64(drm_radeon_clear_t); int err = 0; - u64 dummy; - + int num; + drm_file_t *priv = file->private_data; + drm_device_t *dev = priv->head->dev; + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + DUMMY_ARG; + DUMMY_ARG_P; + OLD_FS; + + num = (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS + ? RADEON_NR_SAREA_CLIPRECTS : sarea_priv->nbox); + DEBUG("drm_clear_w_32_64"); GET_USER(flags); GET_USER(clear_color); GET_USER(clear_depth); GET_USER(color_mask); GET_USER(depth_mask); - GET_USER_P(depth_boxes); + GET_USER_P(depth_boxes, VERIFY_READ, num * sizeof(*arg64.depth_boxes)); if (err) return -EFAULT; @@ -178,14 +190,14 @@ drm_stipple_w_32_64(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - drm32_radeon_stipple_t *arg32 = (drm32_radeon_stipple_t *) arg; - drm_radeon_stipple_t arg64; - mm_segment_t old_fs; + DECLARE_ARG32(drm32_radeon_stipple_t); + DECLARE_ARG64(drm_radeon_stipple_t); int err = 0; - u64 dummy; + DUMMY_ARG_P; + OLD_FS; DEBUG("drm_stipple_w_32_64"); - GET_USER_P(mask); + GET_USER_P(mask, VERIFY_READ, 32 * sizeof(u32)); if (err) return -EFAULT; @@ -197,13 +209,21 @@ drm_texture_32_64(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - drm32_radeon_texture_t *arg32 = (drm32_radeon_texture_t *) arg; - drm_radeon_texture_t arg64; - drm32_radeon_tex_image_t *image32; - drm_radeon_tex_image_t image64; - mm_segment_t old_fs; - int err = 0, err_tmp = 0; - u64 dummy; + DECLARE_ARG32(drm32_radeon_texture_t); + DECLARE_ARG64_NOALLOC(drm_radeon_texture_t); + drm_radeon_tex_image_t __IOCTL32_USER *image64; + drm32_radeon_tex_image_t __user *image32; + u64 tmp; + int err = 0 /* , err_tmp = 0 */; + DUMMY_ARG; + DUMMY_ARG_P; + OLD_FS; + + err |= get_user(tmp,&ARG32(image)); + return -EFAULT; + image32 = (drm32_radeon_tex_image_t __user *)tmp; + + K_ALLOC(image64,sizeof(drm_radeon_tex_image_t)); DEBUG("drm_texture_32_64"); GET_USER(offset); @@ -211,54 +231,82 @@ GET_USER(format); GET_USER(width); GET_USER(height); - image32 = (drm32_radeon_tex_image_t *)(unsigned long)(arg32->image); - arg64.image = &image64; - err |= get_user(image64.x,&image32->x); - err |= get_user(image64.y,&image32->y); - err |= get_user(image64.width,&image32->width); - err |= get_user(image64.height,&image32->height); - err |= get_user(dummy,&image32->data); - image64.data = (void *)dummy; - - if (err) return -EFAULT; - - SYS_IOCTL; - err_tmp = err; - err = 0; + PUT_ARG64(image,image64); + GET_USER_ARG(image64->x,image32->x); + GET_USER_ARG(image64->y,image32->y); + GET_USER_ARG(image64->width,image32->width); + GET_USER_ARG(image64->height,image32->height); + VERIFY_SIZE( + { + int n; + switch (ARG64(format)) { + case RADEON_TXFORMAT_ARGB8888: + case RADEON_TXFORMAT_RGBA8888: + n = 4; + break; + case RADEON_TXFORMAT_I8: + case RADEON_TXFORMAT_RGB332: + n = 1; + break; + default: + n = 1; + } + GET_USER_ARG_P(image64->data,image32->data, VERIFY_READ, + image64->width * image32->height * n); + } + ); - PUT_USER(offset); - PUT_USER(pitch); - PUT_USER(format); - PUT_USER(width); - PUT_USER(height); - err |= put_user(image64.x,&image32->x); - err |= put_user(image64.y,&image32->y); - err |= put_user(image64.width,&image32->width); - err |= put_user(image64.height,&image32->height); - dummy = (u64)image64.data; + if (err) { + K_FREE(image64); + return -EFAULT; + } + + SYS_IOCTL; +// err_tmp = err; +// err = 0; - err |= put_user((u32)dummy,&image32->data); - return err ? -EFAULT : err_tmp; +// PUT_USER(offset); +// PUT_USER(pitch); +// PUT_USER(format); +// PUT_USER(width); +// PUT_USER(height); +// PUT_USER_ARG(image64->x,image32->x); +// PUT_USER_ARG(image64->y,image32->y); +// PUT_USER_ARG(image64->width,image32->width); +// PUT_USER_ARG(image64->height,image32->height); +// PUT_USER_ARG_P(image64->data,image32->data); + K_FREE(image64); +// return err ? -EFAULT : err_tmp; + return err; } static int drm_vertex2_32_64(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - drm32_radeon_vertex2_t *arg32 = (drm32_radeon_vertex2_t *) arg; - drm_radeon_vertex2_t arg64; - mm_segment_t old_fs; - u64 dummy; + DECLARE_ARG32(drm32_radeon_vertex2_t); + DECLARE_ARG64(drm_radeon_vertex2_t); int err = 0; - + DUMMY_ARG; + DUMMY_ARG_P; + VERIFY_SIZE_DECL(int i); + VERIFY_SIZE_DECL(int max_state = 0); + OLD_FS; + DEBUG("drm_vertex2_32_64"); GET_USER(idx); GET_USER(discard); - GET_USER(nr_states); - GET_USER_P(state); GET_USER(nr_prims); - GET_USER_P(prim); + GET_USER_P(prim, VERIFY_READ, ARG64(nr_prims) * sizeof(*ARG64(prim))); + GET_USER(nr_states); + VERIFY_SIZE( + for (i = 0; i < ARG64(nr_prims); i++) { + if (max_state < ARG64(prim[i].stateidx)) + max_state = ARG64(prim[i].stateidx); + } + ); + GET_USER_P(state, VERIFY_READ, max_state * sizeof(*arg64.state)); if (err) return -EFAULT; @@ -272,10 +320,11 @@ drm_radeon_init_w_32_64(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - drm32_radeon_init_t *arg32 = (drm32_radeon_init_t *) arg; - drm_radeon_init_t arg64; - mm_segment_t old_fs; + DECLARE_ARG32(drm32_radeon_init_t); + DECLARE_ARG64(drm_radeon_init_t); int err = 0; + DUMMY_ARG; + OLD_FS; DEBUG("radeon_init_w_32_64"); @@ -311,18 +360,19 @@ drm_radeon_cmd_buffer_32_64(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - drm32_radeon_cmd_buffer_t *arg32 = (drm32_radeon_cmd_buffer_t *) arg; - drm_radeon_cmd_buffer_t arg64; - mm_segment_t old_fs; + DECLARE_ARG32(drm32_radeon_cmd_buffer_t); + DECLARE_ARG64(drm_radeon_cmd_buffer_t); int err = 0; - u64 dummy; + DUMMY_ARG; + DUMMY_ARG_P; + OLD_FS; DEBUG("radeon_cmd_buffer_32_64"); GET_USER(bufsz); - GET_USER_P(buf); + GET_USER_P(buf,VERIFY_READ, ARG64(bufsz) * sizeof(*ARG64(buf))); GET_USER(nbox); - GET_USER_P(boxes); + GET_USER_P(boxes, VERIFY_READ, ARG64(nbox) * sizeof(*ARG64(boxes))); if (err) return -EFAULT; @@ -334,18 +384,19 @@ drm_radeon_mem_alloc_32_64(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - drm32_radeon_mem_alloc_t *arg32 = (drm32_radeon_mem_alloc_t *) arg; - drm_radeon_mem_alloc_t arg64; - mm_segment_t old_fs; + DECLARE_ARG32(drm32_radeon_mem_alloc_t); + DECLARE_ARG64(drm_radeon_mem_alloc_t); int err = 0; - u64 dummy; + DUMMY_ARG; + DUMMY_ARG_P; + OLD_FS; DEBUG("radeon_alloc_32_64"); GET_USER(region); GET_USER(alignment); GET_USER(size); - GET_USER_P(region_offset); + GET_USER_P(region_offset, VERIFY_WRITE, sizeof(int)); if (err) return -EFAULT; @@ -357,15 +408,15 @@ drm_radeon_irq_emit_32_64(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - drm32_radeon_irq_emit_t *arg32 = (drm32_radeon_irq_emit_t *) arg; - drm_radeon_irq_emit_t arg64; - mm_segment_t old_fs; + DECLARE_ARG32(drm32_radeon_irq_emit_t); + DECLARE_ARG64(drm_radeon_irq_emit_t); int err = 0; - u64 dummy; + DUMMY_ARG_P; + OLD_FS; DEBUG("radeon_irq_emit_32_64"); - GET_USER_P(irq_seq); + GET_USER_P(irq_seq, VERIFY_WRITE, sizeof(int)); if (err) return -EFAULT; @@ -377,16 +428,17 @@ drm_radeon_getparam_32_64(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - drm32_radeon_getparam_t *arg32 = (drm32_radeon_getparam_t *) arg; - drm_radeon_getparam_t arg64; - mm_segment_t old_fs; + DECLARE_ARG32(drm32_radeon_getparam_t); + DECLARE_ARG64(drm_radeon_getparam_t); + DUMMY_ARG; int err = 0; - u64 dummy; + DUMMY_ARG_P; + OLD_FS; DEBUG("radeon_getpram_32_64"); GET_USER(param); - GET_USER_P(value); + GET_USER_P(value, VERIFY_WRITE, sizeof(int)); if (err) return -EFAULT; @@ -398,10 +450,11 @@ drm_radeon_setparam_32_64(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - drm32_radeon_setparam_t *arg32 = (drm32_radeon_setparam_t *) arg; - drm_radeon_setparam_t arg64; - mm_segment_t old_fs; + DECLARE_ARG32(drm32_radeon_setparam_t); + DECLARE_ARG64(drm_radeon_setparam_t); int err = 0; + DUMMY_ARG; + OLD_FS; DEBUG("radeon_setparam_32_64"); Index: shared-core/r128_drm.h =================================================================== RCS file: /home/eich/cvs/drm/shared-core/r128_drm.h,v retrieving revision 1.1.1.1 retrieving revision 1.1.1.2 diff -u -r1.1.1.1 -r1.1.1.2 --- shared-core/r128_drm.h 12 Apr 2005 17:46:46 -0000 1.1.1.1 +++ shared-core/r128_drm.h 12 Apr 2005 17:59:34 -0000 1.1.1.2 @@ -213,7 +213,7 @@ #define DRM_IOCTL_R128_INDIRECT DRM_IOWR(DRM_COMMAND_BASE + DRM_R128_INDIRECT, drm_r128_indirect_t) #define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( DRM_COMMAND_BASE + DRM_R128_FULLSCREEN, drm_r128_fullscreen_t) #define DRM_IOCTL_R128_CLEAR2 DRM_IOW( DRM_COMMAND_BASE + DRM_R128_CLEAR2, drm_r128_clear2_t) -#define DRM_IOCTL_R128_GETPARAM DRM_IOW( DRM_COMMAND_BASE + DRM_R128_GETPARAM, drm_r128_getparam_t) +#define DRM_IOCTL_R128_GETPARAM DRM_IOWR( DRM_COMMAND_BASE + DRM_R128_GETPARAM, drm_r128_getparam_t) #define DRM_IOCTL_R128_FLIP DRM_IO( DRM_COMMAND_BASE + DRM_R128_FLIP) typedef struct drm_r128_init {