Lines 61-81
Link Here
|
61 |
return 0; |
61 |
return 0; |
62 |
} |
62 |
} |
63 |
|
63 |
|
64 |
static __inline__ int radeon_check_and_fixup_offset_user( drm_radeon_private_t *dev_priv, |
|
|
65 |
drm_file_t *filp_priv, |
66 |
u32 __user *offset ) { |
67 |
u32 off; |
68 |
|
69 |
DRM_GET_USER_UNCHECKED( off, offset ); |
70 |
|
71 |
if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, &off ) ) |
72 |
return DRM_ERR( EINVAL ); |
73 |
|
74 |
DRM_PUT_USER_UNCHECKED( offset, off ); |
75 |
|
76 |
return 0; |
77 |
} |
78 |
|
79 |
static __inline__ int radeon_check_and_fixup_packets( drm_radeon_private_t *dev_priv, |
64 |
static __inline__ int radeon_check_and_fixup_packets( drm_radeon_private_t *dev_priv, |
80 |
drm_file_t *filp_priv, |
65 |
drm_file_t *filp_priv, |
81 |
int id, |
66 |
int id, |
Lines 83-100
Link Here
|
83 |
switch ( id ) { |
68 |
switch ( id ) { |
84 |
|
69 |
|
85 |
case RADEON_EMIT_PP_MISC: |
70 |
case RADEON_EMIT_PP_MISC: |
86 |
if ( radeon_check_and_fixup_offset_user( dev_priv, filp_priv, |
71 |
if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, |
87 |
&data[( RADEON_RB3D_DEPTHOFFSET |
72 |
&data[( RADEON_RB3D_DEPTHOFFSET |
88 |
- RADEON_PP_MISC ) / 4] ) ) { |
73 |
- RADEON_PP_MISC ) / 4] ) ) { |
89 |
DRM_ERROR( "Invalid depth buffer offset\n" ); |
74 |
DRM_ERROR( "Invalid depth buffer offset\n" ); |
90 |
return DRM_ERR( EINVAL ); |
75 |
return DRM_ERR( EINVAL ); |
91 |
} |
76 |
} |
92 |
break; |
77 |
break; |
93 |
|
78 |
|
94 |
case RADEON_EMIT_PP_CNTL: |
79 |
case RADEON_EMIT_PP_CNTL: |
95 |
if ( radeon_check_and_fixup_offset_user( dev_priv, filp_priv, |
80 |
if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, |
96 |
&data[( RADEON_RB3D_COLOROFFSET |
81 |
&data[( RADEON_RB3D_COLOROFFSET |
97 |
- RADEON_PP_CNTL ) / 4] ) ) { |
82 |
- RADEON_PP_CNTL ) / 4] ) ) { |
98 |
DRM_ERROR( "Invalid colour buffer offset\n" ); |
83 |
DRM_ERROR( "Invalid colour buffer offset\n" ); |
99 |
return DRM_ERR( EINVAL ); |
84 |
return DRM_ERR( EINVAL ); |
100 |
} |
85 |
} |
Lines 106-113
Link Here
|
106 |
case R200_EMIT_PP_TXOFFSET_3: |
91 |
case R200_EMIT_PP_TXOFFSET_3: |
107 |
case R200_EMIT_PP_TXOFFSET_4: |
92 |
case R200_EMIT_PP_TXOFFSET_4: |
108 |
case R200_EMIT_PP_TXOFFSET_5: |
93 |
case R200_EMIT_PP_TXOFFSET_5: |
109 |
if ( radeon_check_and_fixup_offset_user( dev_priv, filp_priv, |
94 |
if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, |
110 |
&data[0] ) ) { |
95 |
&data[0] ) ) { |
111 |
DRM_ERROR( "Invalid R200 texture offset\n" ); |
96 |
DRM_ERROR( "Invalid R200 texture offset\n" ); |
112 |
return DRM_ERR( EINVAL ); |
97 |
return DRM_ERR( EINVAL ); |
113 |
} |
98 |
} |
Lines 116-124
Link Here
|
116 |
case RADEON_EMIT_PP_TXFILTER_0: |
101 |
case RADEON_EMIT_PP_TXFILTER_0: |
117 |
case RADEON_EMIT_PP_TXFILTER_1: |
102 |
case RADEON_EMIT_PP_TXFILTER_1: |
118 |
case RADEON_EMIT_PP_TXFILTER_2: |
103 |
case RADEON_EMIT_PP_TXFILTER_2: |
119 |
if ( radeon_check_and_fixup_offset_user( dev_priv, filp_priv, |
104 |
if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, |
120 |
&data[( RADEON_PP_TXOFFSET_0 |
105 |
&data[( RADEON_PP_TXOFFSET_0 |
121 |
- RADEON_PP_TXFILTER_0 ) / 4] ) ) { |
106 |
- RADEON_PP_TXFILTER_0 ) / 4] ) ) { |
122 |
DRM_ERROR( "Invalid R100 texture offset\n" ); |
107 |
DRM_ERROR( "Invalid R100 texture offset\n" ); |
123 |
return DRM_ERR( EINVAL ); |
108 |
return DRM_ERR( EINVAL ); |
124 |
} |
109 |
} |
Lines 132-140
Link Here
|
132 |
case R200_EMIT_PP_CUBIC_OFFSETS_5: { |
117 |
case R200_EMIT_PP_CUBIC_OFFSETS_5: { |
133 |
int i; |
118 |
int i; |
134 |
for ( i = 0; i < 5; i++ ) { |
119 |
for ( i = 0; i < 5; i++ ) { |
135 |
if ( radeon_check_and_fixup_offset_user( dev_priv, |
120 |
if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, |
136 |
filp_priv, |
121 |
&data[i] ) ) { |
137 |
&data[i] ) ) { |
|
|
138 |
DRM_ERROR( "Invalid R200 cubic texture offset\n" ); |
122 |
DRM_ERROR( "Invalid R200 cubic texture offset\n" ); |
139 |
return DRM_ERR( EINVAL ); |
123 |
return DRM_ERR( EINVAL ); |
140 |
} |
124 |
} |
Lines 217-233
Link Here
|
217 |
drm_file_t *filp_priv, |
201 |
drm_file_t *filp_priv, |
218 |
drm_radeon_cmd_buffer_t *cmdbuf, |
202 |
drm_radeon_cmd_buffer_t *cmdbuf, |
219 |
unsigned int *cmdsz ) { |
203 |
unsigned int *cmdsz ) { |
220 |
u32 tmp[4]; |
204 |
u32 *cmd = (u32 *) cmdbuf->buf; |
221 |
u32 __user *cmd = (u32 __user *)cmdbuf->buf; |
|
|
222 |
|
223 |
if ( DRM_COPY_FROM_USER_UNCHECKED( tmp, cmd, sizeof( tmp ) ) ) { |
224 |
DRM_ERROR( "Failed to copy data from user space\n" ); |
225 |
return DRM_ERR( EFAULT ); |
226 |
} |
227 |
|
205 |
|
228 |
*cmdsz = 2 + ( ( tmp[0] & RADEON_CP_PACKET_COUNT_MASK ) >> 16 ); |
206 |
*cmdsz = 2 + ( ( cmd[0] & RADEON_CP_PACKET_COUNT_MASK ) >> 16 ); |
229 |
|
207 |
|
230 |
if ( ( tmp[0] & 0xc0000000 ) != RADEON_CP_PACKET3 ) { |
208 |
if ( ( cmd[0] & 0xc0000000 ) != RADEON_CP_PACKET3 ) { |
231 |
DRM_ERROR( "Not a type 3 packet\n" ); |
209 |
DRM_ERROR( "Not a type 3 packet\n" ); |
232 |
return DRM_ERR( EINVAL ); |
210 |
return DRM_ERR( EINVAL ); |
233 |
} |
211 |
} |
Lines 238-269
Link Here
|
238 |
} |
216 |
} |
239 |
|
217 |
|
240 |
/* Check client state and fix it up if necessary */ |
218 |
/* Check client state and fix it up if necessary */ |
241 |
if ( tmp[0] & 0x8000 ) { /* MSB of opcode: next DWORD GUI_CNTL */ |
219 |
if ( cmd[0] & 0x8000 ) { /* MSB of opcode: next DWORD GUI_CNTL */ |
242 |
u32 offset; |
220 |
u32 offset; |
243 |
|
221 |
|
244 |
if ( tmp[1] & ( RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
222 |
if ( cmd[1] & ( RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
245 |
| RADEON_GMC_DST_PITCH_OFFSET_CNTL ) ) { |
223 |
| RADEON_GMC_DST_PITCH_OFFSET_CNTL ) ) { |
246 |
offset = tmp[2] << 10; |
224 |
offset = cmd[2] << 10; |
247 |
if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, &offset ) ) { |
225 |
if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, &offset ) ) { |
248 |
DRM_ERROR( "Invalid first packet offset\n" ); |
226 |
DRM_ERROR( "Invalid first packet offset\n" ); |
249 |
return DRM_ERR( EINVAL ); |
227 |
return DRM_ERR( EINVAL ); |
250 |
} |
228 |
} |
251 |
tmp[2] = ( tmp[2] & 0xffc00000 ) | offset >> 10; |
229 |
cmd[2] = ( cmd[2] & 0xffc00000 ) | offset >> 10; |
252 |
} |
230 |
} |
253 |
|
231 |
|
254 |
if ( ( tmp[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL ) && |
232 |
if ( ( cmd[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL ) && |
255 |
( tmp[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL ) ) { |
233 |
( cmd[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL ) ) { |
256 |
offset = tmp[3] << 10; |
234 |
offset = cmd[3] << 10; |
257 |
if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, &offset ) ) { |
235 |
if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, &offset ) ) { |
258 |
DRM_ERROR( "Invalid second packet offset\n" ); |
236 |
DRM_ERROR( "Invalid second packet offset\n" ); |
259 |
return DRM_ERR( EINVAL ); |
237 |
return DRM_ERR( EINVAL ); |
260 |
} |
238 |
} |
261 |
tmp[3] = ( tmp[3] & 0xffc00000 ) | offset >> 10; |
239 |
cmd[3] = ( cmd[3] & 0xffc00000 ) | offset >> 10; |
262 |
} |
|
|
263 |
|
264 |
if ( DRM_COPY_TO_USER_UNCHECKED( cmd, tmp, sizeof( tmp ) ) ) { |
265 |
DRM_ERROR( "Failed to copy data to user space\n" ); |
266 |
return DRM_ERR( EFAULT ); |
267 |
} |
240 |
} |
268 |
} |
241 |
} |
269 |
|
242 |
|
Lines 2087-2093
Link Here
|
2087 |
{ |
2060 |
{ |
2088 |
int id = (int)header.packet.packet_id; |
2061 |
int id = (int)header.packet.packet_id; |
2089 |
int sz, reg; |
2062 |
int sz, reg; |
2090 |
int __user *data = (int __user *)cmdbuf->buf; |
2063 |
int *data = (int *)cmdbuf->buf; |
2091 |
RING_LOCALS; |
2064 |
RING_LOCALS; |
2092 |
|
2065 |
|
2093 |
if (id >= RADEON_MAX_STATE_PACKETS) |
2066 |
if (id >= RADEON_MAX_STATE_PACKETS) |
Lines 2108-2114
Link Here
|
2108 |
|
2081 |
|
2109 |
BEGIN_RING(sz+1); |
2082 |
BEGIN_RING(sz+1); |
2110 |
OUT_RING( CP_PACKET0( reg, (sz-1) ) ); |
2083 |
OUT_RING( CP_PACKET0( reg, (sz-1) ) ); |
2111 |
OUT_RING_USER_TABLE( data, sz ); |
2084 |
OUT_RING_TABLE( data, sz ); |
2112 |
ADVANCE_RING(); |
2085 |
ADVANCE_RING(); |
2113 |
|
2086 |
|
2114 |
cmdbuf->buf += sz * sizeof(int); |
2087 |
cmdbuf->buf += sz * sizeof(int); |
Lines 2122-2128
Link Here
|
2122 |
drm_radeon_cmd_buffer_t *cmdbuf ) |
2095 |
drm_radeon_cmd_buffer_t *cmdbuf ) |
2123 |
{ |
2096 |
{ |
2124 |
int sz = header.scalars.count; |
2097 |
int sz = header.scalars.count; |
2125 |
int __user *data = (int __user *)cmdbuf->buf; |
|
|
2126 |
int start = header.scalars.offset; |
2098 |
int start = header.scalars.offset; |
2127 |
int stride = header.scalars.stride; |
2099 |
int stride = header.scalars.stride; |
2128 |
RING_LOCALS; |
2100 |
RING_LOCALS; |
Lines 2131-2137
Link Here
|
2131 |
OUT_RING( CP_PACKET0( RADEON_SE_TCL_SCALAR_INDX_REG, 0 ) ); |
2103 |
OUT_RING( CP_PACKET0( RADEON_SE_TCL_SCALAR_INDX_REG, 0 ) ); |
2132 |
OUT_RING( start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT)); |
2104 |
OUT_RING( start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT)); |
2133 |
OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_SCALAR_DATA_REG, sz-1 ) ); |
2105 |
OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_SCALAR_DATA_REG, sz-1 ) ); |
2134 |
OUT_RING_USER_TABLE( data, sz ); |
2106 |
OUT_RING_TABLE( cmdbuf->buf, sz ); |
2135 |
ADVANCE_RING(); |
2107 |
ADVANCE_RING(); |
2136 |
cmdbuf->buf += sz * sizeof(int); |
2108 |
cmdbuf->buf += sz * sizeof(int); |
2137 |
cmdbuf->bufsz -= sz * sizeof(int); |
2109 |
cmdbuf->bufsz -= sz * sizeof(int); |
Lines 2146-2152
Link Here
|
2146 |
drm_radeon_cmd_buffer_t *cmdbuf ) |
2118 |
drm_radeon_cmd_buffer_t *cmdbuf ) |
2147 |
{ |
2119 |
{ |
2148 |
int sz = header.scalars.count; |
2120 |
int sz = header.scalars.count; |
2149 |
int __user *data = (int __user *)cmdbuf->buf; |
|
|
2150 |
int start = ((unsigned int)header.scalars.offset) + 0x100; |
2121 |
int start = ((unsigned int)header.scalars.offset) + 0x100; |
2151 |
int stride = header.scalars.stride; |
2122 |
int stride = header.scalars.stride; |
2152 |
RING_LOCALS; |
2123 |
RING_LOCALS; |
Lines 2155-2161
Link Here
|
2155 |
OUT_RING( CP_PACKET0( RADEON_SE_TCL_SCALAR_INDX_REG, 0 ) ); |
2126 |
OUT_RING( CP_PACKET0( RADEON_SE_TCL_SCALAR_INDX_REG, 0 ) ); |
2156 |
OUT_RING( start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT)); |
2127 |
OUT_RING( start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT)); |
2157 |
OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_SCALAR_DATA_REG, sz-1 ) ); |
2128 |
OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_SCALAR_DATA_REG, sz-1 ) ); |
2158 |
OUT_RING_USER_TABLE( data, sz ); |
2129 |
OUT_RING_TABLE( cmdbuf->buf, sz ); |
2159 |
ADVANCE_RING(); |
2130 |
ADVANCE_RING(); |
2160 |
cmdbuf->buf += sz * sizeof(int); |
2131 |
cmdbuf->buf += sz * sizeof(int); |
2161 |
cmdbuf->bufsz -= sz * sizeof(int); |
2132 |
cmdbuf->bufsz -= sz * sizeof(int); |
Lines 2168-2174
Link Here
|
2168 |
drm_radeon_cmd_buffer_t *cmdbuf ) |
2139 |
drm_radeon_cmd_buffer_t *cmdbuf ) |
2169 |
{ |
2140 |
{ |
2170 |
int sz = header.vectors.count; |
2141 |
int sz = header.vectors.count; |
2171 |
int __user *data = (int __user *)cmdbuf->buf; |
|
|
2172 |
int start = header.vectors.offset; |
2142 |
int start = header.vectors.offset; |
2173 |
int stride = header.vectors.stride; |
2143 |
int stride = header.vectors.stride; |
2174 |
RING_LOCALS; |
2144 |
RING_LOCALS; |
Lines 2177-2183
Link Here
|
2177 |
OUT_RING( CP_PACKET0( RADEON_SE_TCL_VECTOR_INDX_REG, 0 ) ); |
2147 |
OUT_RING( CP_PACKET0( RADEON_SE_TCL_VECTOR_INDX_REG, 0 ) ); |
2178 |
OUT_RING( start | (stride << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT)); |
2148 |
OUT_RING( start | (stride << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT)); |
2179 |
OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_VECTOR_DATA_REG, (sz-1) ) ); |
2149 |
OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_VECTOR_DATA_REG, (sz-1) ) ); |
2180 |
OUT_RING_USER_TABLE( data, sz ); |
2150 |
OUT_RING_TABLE( cmdbuf->buf, sz ); |
2181 |
ADVANCE_RING(); |
2151 |
ADVANCE_RING(); |
2182 |
|
2152 |
|
2183 |
cmdbuf->buf += sz * sizeof(int); |
2153 |
cmdbuf->buf += sz * sizeof(int); |
Lines 2192-2198
Link Here
|
2192 |
{ |
2162 |
{ |
2193 |
drm_radeon_private_t *dev_priv = dev->dev_private; |
2163 |
drm_radeon_private_t *dev_priv = dev->dev_private; |
2194 |
unsigned int cmdsz; |
2164 |
unsigned int cmdsz; |
2195 |
int __user *cmd = (int __user *)cmdbuf->buf; |
|
|
2196 |
int ret; |
2165 |
int ret; |
2197 |
RING_LOCALS; |
2166 |
RING_LOCALS; |
2198 |
|
2167 |
|
Lines 2205-2211
Link Here
|
2205 |
} |
2174 |
} |
2206 |
|
2175 |
|
2207 |
BEGIN_RING( cmdsz ); |
2176 |
BEGIN_RING( cmdsz ); |
2208 |
OUT_RING_USER_TABLE( cmd, cmdsz ); |
2177 |
OUT_RING_TABLE( cmdbuf->buf, cmdsz ); |
2209 |
ADVANCE_RING(); |
2178 |
ADVANCE_RING(); |
2210 |
|
2179 |
|
2211 |
cmdbuf->buf += cmdsz * 4; |
2180 |
cmdbuf->buf += cmdsz * 4; |
Lines 2222-2228
Link Here
|
2222 |
drm_radeon_private_t *dev_priv = dev->dev_private; |
2191 |
drm_radeon_private_t *dev_priv = dev->dev_private; |
2223 |
drm_clip_rect_t box; |
2192 |
drm_clip_rect_t box; |
2224 |
unsigned int cmdsz; |
2193 |
unsigned int cmdsz; |
2225 |
int __user *cmd = (int __user *)cmdbuf->buf; |
|
|
2226 |
int ret; |
2194 |
int ret; |
2227 |
drm_clip_rect_t __user *boxes = cmdbuf->boxes; |
2195 |
drm_clip_rect_t __user *boxes = cmdbuf->boxes; |
2228 |
int i = 0; |
2196 |
int i = 0; |
Lines 2241-2247
Link Here
|
2241 |
|
2209 |
|
2242 |
do { |
2210 |
do { |
2243 |
if ( i < cmdbuf->nbox ) { |
2211 |
if ( i < cmdbuf->nbox ) { |
2244 |
if (DRM_COPY_FROM_USER_UNCHECKED( &box, &boxes[i], sizeof(box) )) |
2212 |
if (DRM_COPY_FROM_USER( &box, &boxes[i], sizeof(box) )) |
2245 |
return DRM_ERR(EFAULT); |
2213 |
return DRM_ERR(EFAULT); |
2246 |
/* FIXME The second and subsequent times round |
2214 |
/* FIXME The second and subsequent times round |
2247 |
* this loop, send a WAIT_UNTIL_3D_IDLE before |
2215 |
* this loop, send a WAIT_UNTIL_3D_IDLE before |
Lines 2264-2270
Link Here
|
2264 |
} |
2232 |
} |
2265 |
|
2233 |
|
2266 |
BEGIN_RING( cmdsz ); |
2234 |
BEGIN_RING( cmdsz ); |
2267 |
OUT_RING_USER_TABLE( cmd, cmdsz ); |
2235 |
OUT_RING_TABLE( cmdbuf->buf, cmdsz ); |
2268 |
ADVANCE_RING(); |
2236 |
ADVANCE_RING(); |
2269 |
|
2237 |
|
2270 |
} while ( ++i < cmdbuf->nbox ); |
2238 |
} while ( ++i < cmdbuf->nbox ); |
Lines 2317-2323
Link Here
|
2317 |
int idx; |
2285 |
int idx; |
2318 |
drm_radeon_cmd_buffer_t cmdbuf; |
2286 |
drm_radeon_cmd_buffer_t cmdbuf; |
2319 |
drm_radeon_cmd_header_t header; |
2287 |
drm_radeon_cmd_header_t header; |
2320 |
int orig_nbox; |
2288 |
int orig_nbox, orig_bufsz; |
|
|
2289 |
char *kbuf=NULL; |
2321 |
|
2290 |
|
2322 |
LOCK_TEST_WITH_RETURN( dev, filp ); |
2291 |
LOCK_TEST_WITH_RETURN( dev, filp ); |
2323 |
|
2292 |
|
Lines 2334-2357
Link Here
|
2334 |
RING_SPACE_TEST_WITH_RETURN( dev_priv ); |
2303 |
RING_SPACE_TEST_WITH_RETURN( dev_priv ); |
2335 |
VB_AGE_TEST_WITH_RETURN( dev_priv ); |
2304 |
VB_AGE_TEST_WITH_RETURN( dev_priv ); |
2336 |
|
2305 |
|
|
|
2306 |
if (cmdbuf.bufsz > 64*1024 || cmdbuf.bufsz<0) { |
2307 |
return DRM_ERR(EINVAL); |
2308 |
} |
2337 |
|
2309 |
|
2338 |
if (DRM_VERIFYAREA_READ( cmdbuf.buf, cmdbuf.bufsz )) |
2310 |
/* Allocate an in-kernel area and copy in the cmdbuf. Do this to avoid |
2339 |
return DRM_ERR(EFAULT); |
2311 |
* races between checking values and using those values in other code, |
2340 |
|
2312 |
* and simply to avoid a lot of function calls to copy in data. |
2341 |
if (cmdbuf.nbox && |
2313 |
*/ |
2342 |
DRM_VERIFYAREA_READ(cmdbuf.boxes, |
2314 |
orig_bufsz = cmdbuf.bufsz; |
2343 |
cmdbuf.nbox * sizeof(drm_clip_rect_t))) |
2315 |
if (orig_bufsz != 0) { |
2344 |
return DRM_ERR(EFAULT); |
2316 |
kbuf = DRM_MALLOC(cmdbuf.bufsz); |
|
|
2317 |
if (kbuf == NULL) |
2318 |
return DRM_ERR(ENOMEM); |
2319 |
if (DRM_COPY_FROM_USER(kbuf, cmdbuf.buf, cmdbuf.bufsz)) |
2320 |
return DRM_ERR(EFAULT); |
2321 |
cmdbuf.buf = kbuf; |
2322 |
} |
2345 |
|
2323 |
|
2346 |
orig_nbox = cmdbuf.nbox; |
2324 |
orig_nbox = cmdbuf.nbox; |
2347 |
|
2325 |
|
2348 |
while ( cmdbuf.bufsz >= sizeof(header) ) { |
2326 |
while ( cmdbuf.bufsz >= sizeof(header) ) { |
2349 |
|
|
|
2350 |
if (DRM_GET_USER_UNCHECKED( header.i, (int __user *)cmdbuf.buf )) { |
2351 |
DRM_ERROR("__get_user %p\n", cmdbuf.buf); |
2352 |
return DRM_ERR(EFAULT); |
2353 |
} |
2354 |
|
2327 |
|
|
|
2328 |
header.i = *(int *)cmdbuf.buf; |
2355 |
cmdbuf.buf += sizeof(header); |
2329 |
cmdbuf.buf += sizeof(header); |
2356 |
cmdbuf.bufsz -= sizeof(header); |
2330 |
cmdbuf.bufsz -= sizeof(header); |
2357 |
|
2331 |
|
Lines 2360-2366
Link Here
|
2360 |
DRM_DEBUG("RADEON_CMD_PACKET\n"); |
2334 |
DRM_DEBUG("RADEON_CMD_PACKET\n"); |
2361 |
if (radeon_emit_packets( dev_priv, filp_priv, header, &cmdbuf )) { |
2335 |
if (radeon_emit_packets( dev_priv, filp_priv, header, &cmdbuf )) { |
2362 |
DRM_ERROR("radeon_emit_packets failed\n"); |
2336 |
DRM_ERROR("radeon_emit_packets failed\n"); |
2363 |
return DRM_ERR(EINVAL); |
2337 |
goto err; |
2364 |
} |
2338 |
} |
2365 |
break; |
2339 |
break; |
2366 |
|
2340 |
|
Lines 2368-2374
Link Here
|
2368 |
DRM_DEBUG("RADEON_CMD_SCALARS\n"); |
2342 |
DRM_DEBUG("RADEON_CMD_SCALARS\n"); |
2369 |
if (radeon_emit_scalars( dev_priv, header, &cmdbuf )) { |
2343 |
if (radeon_emit_scalars( dev_priv, header, &cmdbuf )) { |
2370 |
DRM_ERROR("radeon_emit_scalars failed\n"); |
2344 |
DRM_ERROR("radeon_emit_scalars failed\n"); |
2371 |
return DRM_ERR(EINVAL); |
2345 |
goto err; |
2372 |
} |
2346 |
} |
2373 |
break; |
2347 |
break; |
2374 |
|
2348 |
|
Lines 2376-2382
Link Here
|
2376 |
DRM_DEBUG("RADEON_CMD_VECTORS\n"); |
2350 |
DRM_DEBUG("RADEON_CMD_VECTORS\n"); |
2377 |
if (radeon_emit_vectors( dev_priv, header, &cmdbuf )) { |
2351 |
if (radeon_emit_vectors( dev_priv, header, &cmdbuf )) { |
2378 |
DRM_ERROR("radeon_emit_vectors failed\n"); |
2352 |
DRM_ERROR("radeon_emit_vectors failed\n"); |
2379 |
return DRM_ERR(EINVAL); |
2353 |
goto err; |
2380 |
} |
2354 |
} |
2381 |
break; |
2355 |
break; |
2382 |
|
2356 |
|
Lines 2386-2399
Link Here
|
2386 |
if ( idx < 0 || idx >= dma->buf_count ) { |
2360 |
if ( idx < 0 || idx >= dma->buf_count ) { |
2387 |
DRM_ERROR( "buffer index %d (of %d max)\n", |
2361 |
DRM_ERROR( "buffer index %d (of %d max)\n", |
2388 |
idx, dma->buf_count - 1 ); |
2362 |
idx, dma->buf_count - 1 ); |
2389 |
return DRM_ERR(EINVAL); |
2363 |
goto err; |
2390 |
} |
2364 |
} |
2391 |
|
2365 |
|
2392 |
buf = dma->buflist[idx]; |
2366 |
buf = dma->buflist[idx]; |
2393 |
if ( buf->filp != filp || buf->pending ) { |
2367 |
if ( buf->filp != filp || buf->pending ) { |
2394 |
DRM_ERROR( "bad buffer %p %p %d\n", |
2368 |
DRM_ERROR( "bad buffer %p %p %d\n", |
2395 |
buf->filp, filp, buf->pending); |
2369 |
buf->filp, filp, buf->pending); |
2396 |
return DRM_ERR(EINVAL); |
2370 |
goto err; |
2397 |
} |
2371 |
} |
2398 |
|
2372 |
|
2399 |
radeon_cp_discard_buffer( dev, buf ); |
2373 |
radeon_cp_discard_buffer( dev, buf ); |
Lines 2403-2409
Link Here
|
2403 |
DRM_DEBUG("RADEON_CMD_PACKET3\n"); |
2377 |
DRM_DEBUG("RADEON_CMD_PACKET3\n"); |
2404 |
if (radeon_emit_packet3( dev, filp_priv, &cmdbuf )) { |
2378 |
if (radeon_emit_packet3( dev, filp_priv, &cmdbuf )) { |
2405 |
DRM_ERROR("radeon_emit_packet3 failed\n"); |
2379 |
DRM_ERROR("radeon_emit_packet3 failed\n"); |
2406 |
return DRM_ERR(EINVAL); |
2380 |
goto err; |
2407 |
} |
2381 |
} |
2408 |
break; |
2382 |
break; |
2409 |
|
2383 |
|
Lines 2411-2417
Link Here
|
2411 |
DRM_DEBUG("RADEON_CMD_PACKET3_CLIP\n"); |
2385 |
DRM_DEBUG("RADEON_CMD_PACKET3_CLIP\n"); |
2412 |
if (radeon_emit_packet3_cliprect( dev, filp_priv, &cmdbuf, orig_nbox )) { |
2386 |
if (radeon_emit_packet3_cliprect( dev, filp_priv, &cmdbuf, orig_nbox )) { |
2413 |
DRM_ERROR("radeon_emit_packet3_clip failed\n"); |
2387 |
DRM_ERROR("radeon_emit_packet3_clip failed\n"); |
2414 |
return DRM_ERR(EINVAL); |
2388 |
goto err; |
2415 |
} |
2389 |
} |
2416 |
break; |
2390 |
break; |
2417 |
|
2391 |
|
Lines 2419-2425
Link Here
|
2419 |
DRM_DEBUG("RADEON_CMD_SCALARS2\n"); |
2393 |
DRM_DEBUG("RADEON_CMD_SCALARS2\n"); |
2420 |
if (radeon_emit_scalars2( dev_priv, header, &cmdbuf )) { |
2394 |
if (radeon_emit_scalars2( dev_priv, header, &cmdbuf )) { |
2421 |
DRM_ERROR("radeon_emit_scalars2 failed\n"); |
2395 |
DRM_ERROR("radeon_emit_scalars2 failed\n"); |
2422 |
return DRM_ERR(EINVAL); |
2396 |
goto err; |
2423 |
} |
2397 |
} |
2424 |
break; |
2398 |
break; |
2425 |
|
2399 |
|
Lines 2427-2447
Link Here
|
2427 |
DRM_DEBUG("RADEON_CMD_WAIT\n"); |
2401 |
DRM_DEBUG("RADEON_CMD_WAIT\n"); |
2428 |
if (radeon_emit_wait( dev, header.wait.flags )) { |
2402 |
if (radeon_emit_wait( dev, header.wait.flags )) { |
2429 |
DRM_ERROR("radeon_emit_wait failed\n"); |
2403 |
DRM_ERROR("radeon_emit_wait failed\n"); |
2430 |
return DRM_ERR(EINVAL); |
2404 |
goto err; |
2431 |
} |
2405 |
} |
2432 |
break; |
2406 |
break; |
2433 |
default: |
2407 |
default: |
2434 |
DRM_ERROR("bad cmd_type %d at %p\n", |
2408 |
DRM_ERROR("bad cmd_type %d at %p\n", |
2435 |
header.header.cmd_type, |
2409 |
header.header.cmd_type, |
2436 |
cmdbuf.buf - sizeof(header)); |
2410 |
cmdbuf.buf - sizeof(header)); |
2437 |
return DRM_ERR(EINVAL); |
2411 |
goto err; |
2438 |
} |
2412 |
} |
2439 |
} |
2413 |
} |
2440 |
|
2414 |
|
|
|
2415 |
if (orig_bufsz != 0) |
2416 |
DRM_FREE(kbuf, orig_bufsz); |
2441 |
|
2417 |
|
2442 |
DRM_DEBUG("DONE\n"); |
2418 |
DRM_DEBUG("DONE\n"); |
2443 |
COMMIT_RING(); |
2419 |
COMMIT_RING(); |
2444 |
return 0; |
2420 |
return 0; |
|
|
2421 |
|
2422 |
err: |
2423 |
if (orig_bufsz != 0) |
2424 |
DRM_FREE(kbuf, orig_bufsz); |
2425 |
return DRM_ERR(EINVAL); |
2445 |
} |
2426 |
} |
2446 |
|
2427 |
|
2447 |
|
2428 |
|