diff options
author | Jose Fonseca <jrfonseca@users.sourceforge.net> | 2002-10-31 16:36:39 +0000 |
---|---|---|
committer | Jose Fonseca <jrfonseca@users.sourceforge.net> | 2002-10-31 16:36:39 +0000 |
commit | 4e4cf3dd5c8e997d748005c0d8f6ae96b421b331 (patch) | |
tree | c37282bcdfe5bbf6d01f1fadf2cf7c0eba883b2f | |
parent | 35d28f91667dabc9629c647b1f3a347b1939a4f2 (diff) |
Revamped copy_and_verify to use linux user memory access routines to cope
with bad virtual memory accesses.
-rw-r--r-- | linux/mach64_state.c | 65 |
1 files changed, 36 insertions, 29 deletions
diff --git a/linux/mach64_state.c b/linux/mach64_state.c index 3f005a82..5c03754a 100644 --- a/linux/mach64_state.c +++ b/linux/mach64_state.c @@ -467,43 +467,50 @@ static int mach64_do_get_frames_queued( drm_mach64_private_t *dev_priv ) /* Copy and verify a client submited buffer. * FIXME: Make an assembly optimized version */ -u32 copy_and_verify( u32 *dst, u32 *src, u32 used) +unsigned long copy_and_verify_from_user( u32 *to, const u32 *from, unsigned long n) { - u32 copied = 0; - used >>= 2; + unsigned long copied = 0; - while ( used ) { - u32 data, reg, count; - - data = *src++; - used--; +#if 0 + if ( access_ok( VERIFY_READ, from, n ) ) { +#else + /* FIXME: Don't verify the area while we're reading from DMA buffers. */ + { +#endif + n >>= 2; - reg = le32_to_cpu(data); - count = (reg >> 16) + 1; - if( count <= used ) { - used -= count; - reg &= 0xffff; - - /* This is an exact match of Mach64's Setup Engine registers, - * excluding SETUP_CNTL (1_C1). - */ - if( (reg >= 0x0190 && reg < 0x01c1) || (reg >= 0x01ca && reg <= 0x01cf) ) { - *dst++ = data; - copied += 1 + count; - while( count-- ) { - *dst++ = *src++; + while ( n ) { + u32 data, reg, count; + + if ( __get_user( data, from++ ) ) + break; + n--; + + reg = le32_to_cpu(data); + count = (reg >> 16) + 1; + if( count <= n ) { + n -= count; + reg &= 0xffff; + + /* This is an exact match of Mach64's Setup Engine registers, + * excluding SETUP_CNTL (1_C1). + */ + if( (reg >= 0x0190 && reg < 0x01c1) || (reg >= 0x01ca && reg <= 0x01cf) ) { + *to++ = data; + __copy_from_user( to, from, count << 2 ); + to += count; + copied += 1 + count; } + + from += count; } else { - while( count-- ) { - src++; - } + break; } - } else { - used = 0; } + + copied <<= 2; } - copied <<= 2; return copied; } @@ -532,7 +539,7 @@ static int mach64_dma_dispatch_vertex( drm_device_t *dev, drm_buf_t *buf, } /* FIXME: This should be done from a client space buffer and not from a DMA buffer. */ - copy_buf->used = copy_and_verify( GETBUFPTR( copy_buf ), GETBUFPTR( buf ), buf->used ); + copy_buf->used = copy_and_verify_from_user( GETBUFPTR( copy_buf ), GETBUFPTR( buf ), buf->used ); DMASETPTR( copy_buf ); #else |