diff options
Diffstat (limited to 'drivers/char/drm/radeon_state.c')
-rw-r--r-- | drivers/char/drm/radeon_state.c | 105 |
1 files changed, 47 insertions, 58 deletions
diff --git a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c index 7bc27516d425..c5b8f774a599 100644 --- a/drivers/char/drm/radeon_state.c +++ b/drivers/char/drm/radeon_state.c | |||
@@ -45,22 +45,53 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t * | |||
45 | u32 off = *offset; | 45 | u32 off = *offset; |
46 | struct drm_radeon_driver_file_fields *radeon_priv; | 46 | struct drm_radeon_driver_file_fields *radeon_priv; |
47 | 47 | ||
48 | if (off >= dev_priv->fb_location && | 48 | /* Hrm ... the story of the offset ... So this function converts |
49 | off < (dev_priv->gart_vm_start + dev_priv->gart_size)) | 49 | * the various ideas of what userland clients might have for an |
50 | return 0; | 50 | * offset in the card address space into an offset into the card |
51 | 51 | * address space :) So with a sane client, it should just keep | |
52 | radeon_priv = filp_priv->driver_priv; | 52 | * the value intact and just do some boundary checking. However, |
53 | off += radeon_priv->radeon_fb_delta; | 53 | * not all clients are sane. Some older clients pass us 0 based |
54 | * offsets relative to the start of the framebuffer and some may | ||
55 | * assume the AGP aperture it appended to the framebuffer, so we | ||
56 | * try to detect those cases and fix them up. | ||
57 | * | ||
58 | * Note: It might be a good idea here to make sure the offset lands | ||
59 | * in some "allowed" area to protect things like the PCIE GART... | ||
60 | */ | ||
54 | 61 | ||
55 | DRM_DEBUG("offset fixed up to 0x%x\n", off); | 62 | /* First, the best case, the offset already lands in either the |
63 | * framebuffer or the GART mapped space | ||
64 | */ | ||
65 | if ((off >= dev_priv->fb_location && | ||
66 | off < (dev_priv->fb_location + dev_priv->fb_size)) || | ||
67 | (off >= dev_priv->gart_vm_start && | ||
68 | off < (dev_priv->gart_vm_start + dev_priv->gart_size))) | ||
69 | return 0; | ||
56 | 70 | ||
57 | if (off < dev_priv->fb_location || | 71 | /* Ok, that didn't happen... now check if we have a zero based |
58 | off >= (dev_priv->gart_vm_start + dev_priv->gart_size)) | 72 | * offset that fits in the framebuffer + gart space, apply the |
59 | return DRM_ERR(EINVAL); | 73 | * magic offset we get from SETPARAM or calculated from fb_location |
74 | */ | ||
75 | if (off < (dev_priv->fb_size + dev_priv->gart_size)) { | ||
76 | radeon_priv = filp_priv->driver_priv; | ||
77 | off += radeon_priv->radeon_fb_delta; | ||
78 | } | ||
60 | 79 | ||
61 | *offset = off; | 80 | /* Finally, assume we aimed at a GART offset if beyond the fb */ |
81 | if (off > (dev_priv->fb_location + dev_priv->fb_size)) | ||
82 | off = off - (dev_priv->fb_location + dev_priv->fb_size) + | ||
83 | dev_priv->gart_vm_start; | ||
62 | 84 | ||
63 | return 0; | 85 | /* Now recheck and fail if out of bounds */ |
86 | if ((off >= dev_priv->fb_location && | ||
87 | off < (dev_priv->fb_location + dev_priv->fb_size)) || | ||
88 | (off >= dev_priv->gart_vm_start && | ||
89 | off < (dev_priv->gart_vm_start + dev_priv->gart_size))) { | ||
90 | DRM_DEBUG("offset fixed up to 0x%x\n", off); | ||
91 | *offset = off; | ||
92 | return 0; | ||
93 | } | ||
94 | return DRM_ERR(EINVAL); | ||
64 | } | 95 | } |
65 | 96 | ||
66 | static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * | 97 | static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * |
@@ -1939,11 +1970,6 @@ static int radeon_surface_alloc(DRM_IOCTL_ARGS) | |||
1939 | drm_radeon_private_t *dev_priv = dev->dev_private; | 1970 | drm_radeon_private_t *dev_priv = dev->dev_private; |
1940 | drm_radeon_surface_alloc_t alloc; | 1971 | drm_radeon_surface_alloc_t alloc; |
1941 | 1972 | ||
1942 | if (!dev_priv) { | ||
1943 | DRM_ERROR("%s called with no initialization\n", __FUNCTION__); | ||
1944 | return DRM_ERR(EINVAL); | ||
1945 | } | ||
1946 | |||
1947 | DRM_COPY_FROM_USER_IOCTL(alloc, | 1973 | DRM_COPY_FROM_USER_IOCTL(alloc, |
1948 | (drm_radeon_surface_alloc_t __user *) data, | 1974 | (drm_radeon_surface_alloc_t __user *) data, |
1949 | sizeof(alloc)); | 1975 | sizeof(alloc)); |
@@ -1960,12 +1986,7 @@ static int radeon_surface_free(DRM_IOCTL_ARGS) | |||
1960 | drm_radeon_private_t *dev_priv = dev->dev_private; | 1986 | drm_radeon_private_t *dev_priv = dev->dev_private; |
1961 | drm_radeon_surface_free_t memfree; | 1987 | drm_radeon_surface_free_t memfree; |
1962 | 1988 | ||
1963 | if (!dev_priv) { | 1989 | DRM_COPY_FROM_USER_IOCTL(memfree, (drm_radeon_surface_free_t __user *) data, |
1964 | DRM_ERROR("%s called with no initialization\n", __FUNCTION__); | ||
1965 | return DRM_ERR(EINVAL); | ||
1966 | } | ||
1967 | |||
1968 | DRM_COPY_FROM_USER_IOCTL(memfree, (drm_radeon_mem_free_t __user *) data, | ||
1969 | sizeof(memfree)); | 1990 | sizeof(memfree)); |
1970 | 1991 | ||
1971 | if (free_surface(filp, dev_priv, memfree.address)) | 1992 | if (free_surface(filp, dev_priv, memfree.address)) |
@@ -2100,11 +2121,6 @@ static int radeon_cp_vertex(DRM_IOCTL_ARGS) | |||
2100 | 2121 | ||
2101 | LOCK_TEST_WITH_RETURN(dev, filp); | 2122 | LOCK_TEST_WITH_RETURN(dev, filp); |
2102 | 2123 | ||
2103 | if (!dev_priv) { | ||
2104 | DRM_ERROR("%s called with no initialization\n", __FUNCTION__); | ||
2105 | return DRM_ERR(EINVAL); | ||
2106 | } | ||
2107 | |||
2108 | DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); | 2124 | DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); |
2109 | 2125 | ||
2110 | DRM_COPY_FROM_USER_IOCTL(vertex, (drm_radeon_vertex_t __user *) data, | 2126 | DRM_COPY_FROM_USER_IOCTL(vertex, (drm_radeon_vertex_t __user *) data, |
@@ -2189,11 +2205,6 @@ static int radeon_cp_indices(DRM_IOCTL_ARGS) | |||
2189 | 2205 | ||
2190 | LOCK_TEST_WITH_RETURN(dev, filp); | 2206 | LOCK_TEST_WITH_RETURN(dev, filp); |
2191 | 2207 | ||
2192 | if (!dev_priv) { | ||
2193 | DRM_ERROR("%s called with no initialization\n", __FUNCTION__); | ||
2194 | return DRM_ERR(EINVAL); | ||
2195 | } | ||
2196 | |||
2197 | DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); | 2208 | DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); |
2198 | 2209 | ||
2199 | DRM_COPY_FROM_USER_IOCTL(elts, (drm_radeon_indices_t __user *) data, | 2210 | DRM_COPY_FROM_USER_IOCTL(elts, (drm_radeon_indices_t __user *) data, |
@@ -2340,11 +2351,6 @@ static int radeon_cp_indirect(DRM_IOCTL_ARGS) | |||
2340 | 2351 | ||
2341 | LOCK_TEST_WITH_RETURN(dev, filp); | 2352 | LOCK_TEST_WITH_RETURN(dev, filp); |
2342 | 2353 | ||
2343 | if (!dev_priv) { | ||
2344 | DRM_ERROR("%s called with no initialization\n", __FUNCTION__); | ||
2345 | return DRM_ERR(EINVAL); | ||
2346 | } | ||
2347 | |||
2348 | DRM_COPY_FROM_USER_IOCTL(indirect, | 2354 | DRM_COPY_FROM_USER_IOCTL(indirect, |
2349 | (drm_radeon_indirect_t __user *) data, | 2355 | (drm_radeon_indirect_t __user *) data, |
2350 | sizeof(indirect)); | 2356 | sizeof(indirect)); |
@@ -2417,11 +2423,6 @@ static int radeon_cp_vertex2(DRM_IOCTL_ARGS) | |||
2417 | 2423 | ||
2418 | LOCK_TEST_WITH_RETURN(dev, filp); | 2424 | LOCK_TEST_WITH_RETURN(dev, filp); |
2419 | 2425 | ||
2420 | if (!dev_priv) { | ||
2421 | DRM_ERROR("%s called with no initialization\n", __FUNCTION__); | ||
2422 | return DRM_ERR(EINVAL); | ||
2423 | } | ||
2424 | |||
2425 | DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); | 2426 | DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); |
2426 | 2427 | ||
2427 | DRM_COPY_FROM_USER_IOCTL(vertex, (drm_radeon_vertex2_t __user *) data, | 2428 | DRM_COPY_FROM_USER_IOCTL(vertex, (drm_radeon_vertex2_t __user *) data, |
@@ -2738,11 +2739,6 @@ static int radeon_cp_cmdbuf(DRM_IOCTL_ARGS) | |||
2738 | 2739 | ||
2739 | LOCK_TEST_WITH_RETURN(dev, filp); | 2740 | LOCK_TEST_WITH_RETURN(dev, filp); |
2740 | 2741 | ||
2741 | if (!dev_priv) { | ||
2742 | DRM_ERROR("%s called with no initialization\n", __FUNCTION__); | ||
2743 | return DRM_ERR(EINVAL); | ||
2744 | } | ||
2745 | |||
2746 | DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); | 2742 | DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); |
2747 | 2743 | ||
2748 | DRM_COPY_FROM_USER_IOCTL(cmdbuf, | 2744 | DRM_COPY_FROM_USER_IOCTL(cmdbuf, |
@@ -2897,11 +2893,6 @@ static int radeon_cp_getparam(DRM_IOCTL_ARGS) | |||
2897 | drm_radeon_getparam_t param; | 2893 | drm_radeon_getparam_t param; |
2898 | int value; | 2894 | int value; |
2899 | 2895 | ||
2900 | if (!dev_priv) { | ||
2901 | DRM_ERROR("%s called with no initialization\n", __FUNCTION__); | ||
2902 | return DRM_ERR(EINVAL); | ||
2903 | } | ||
2904 | |||
2905 | DRM_COPY_FROM_USER_IOCTL(param, (drm_radeon_getparam_t __user *) data, | 2896 | DRM_COPY_FROM_USER_IOCTL(param, (drm_radeon_getparam_t __user *) data, |
2906 | sizeof(param)); | 2897 | sizeof(param)); |
2907 | 2898 | ||
@@ -2981,11 +2972,6 @@ static int radeon_cp_setparam(DRM_IOCTL_ARGS) | |||
2981 | drm_radeon_setparam_t sp; | 2972 | drm_radeon_setparam_t sp; |
2982 | struct drm_radeon_driver_file_fields *radeon_priv; | 2973 | struct drm_radeon_driver_file_fields *radeon_priv; |
2983 | 2974 | ||
2984 | if (!dev_priv) { | ||
2985 | DRM_ERROR("%s called with no initialization\n", __FUNCTION__); | ||
2986 | return DRM_ERR(EINVAL); | ||
2987 | } | ||
2988 | |||
2989 | DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); | 2975 | DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); |
2990 | 2976 | ||
2991 | DRM_COPY_FROM_USER_IOCTL(sp, (drm_radeon_setparam_t __user *) data, | 2977 | DRM_COPY_FROM_USER_IOCTL(sp, (drm_radeon_setparam_t __user *) data, |
@@ -3012,6 +2998,9 @@ static int radeon_cp_setparam(DRM_IOCTL_ARGS) | |||
3012 | case RADEON_SETPARAM_PCIGART_LOCATION: | 2998 | case RADEON_SETPARAM_PCIGART_LOCATION: |
3013 | dev_priv->pcigart_offset = sp.value; | 2999 | dev_priv->pcigart_offset = sp.value; |
3014 | break; | 3000 | break; |
3001 | case RADEON_SETPARAM_NEW_MEMMAP: | ||
3002 | dev_priv->new_memmap = sp.value; | ||
3003 | break; | ||
3015 | default: | 3004 | default: |
3016 | DRM_DEBUG("Invalid parameter %d\n", sp.param); | 3005 | DRM_DEBUG("Invalid parameter %d\n", sp.param); |
3017 | return DRM_ERR(EINVAL); | 3006 | return DRM_ERR(EINVAL); |