diff options
author | Michel Daenzer <michel@daenzer.net> | 2003-08-06 11:46:21 +0000 |
---|---|---|
committer | Michel Daenzer <michel@daenzer.net> | 2003-08-06 11:46:21 +0000 |
commit | da16867c8433516c361944e6e4265bd511ac72c8 (patch) | |
tree | fb46b5adee9a3f14a5ffb20acec28d8f2178db14 | |
parent | 4b60cae90e0f689f68167c2e3419df7574cae1ab (diff) |
Fix maplist entries being used after they were freed; thanks to Benjamin
Herrenschmidt for tracking this down
-rw-r--r-- | linux-core/drm_drv.c | 76 | ||||
-rw-r--r-- | linux/drm_drv.h | 76 |
2 files changed, 74 insertions, 78 deletions
diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index 016f9195..5f3eebe3 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -453,51 +453,49 @@ static int DRM(takedown)( drm_device_t *dev ) } if( dev->maplist ) { - for(list = dev->maplist->head.next; - list != &dev->maplist->head; - list = list_next) { - list_next = list->next; + list_for_each_safe( list, list_next, &dev->maplist->head ) { r_list = (drm_map_list_t *)list; - map = r_list->map; - DRM(free)(r_list, sizeof(*r_list), DRM_MEM_MAPS); - if(!map) continue; - switch ( map->type ) { - case _DRM_REGISTERS: - case _DRM_FRAME_BUFFER: + if ( ( map = r_list->map ) ) { + switch ( map->type ) { + case _DRM_REGISTERS: + case _DRM_FRAME_BUFFER: #if __REALLY_HAVE_MTRR - if ( map->mtrr >= 0 ) { - int retcode; - retcode = mtrr_del( map->mtrr, - map->offset, - map->size ); - DRM_DEBUG( "mtrr_del=%d\n", retcode ); - } -#endif - DRM(ioremapfree)( map->handle, map->size, dev ); - break; - case _DRM_SHM: - vfree(map->handle); - break; - - case _DRM_AGP: - /* Do nothing here, because this is all - * handled in the AGP/GART driver. - */ - break; - case _DRM_SCATTER_GATHER: - /* Handle it, but do nothing, if HAVE_SG - * isn't defined. - */ + if ( map->mtrr >= 0 ) { + int retcode; + retcode = mtrr_del( map->mtrr, + map->offset, + map->size ); + DRM_DEBUG( "mtrr_del=%d\n", retcode ); + } +#endif + DRM(ioremapfree)( map->handle, map->size, dev ); + break; + case _DRM_SHM: + vfree(map->handle); + break; + + case _DRM_AGP: + /* Do nothing here, because this is all + * handled in the AGP/GART driver. + */ + break; + case _DRM_SCATTER_GATHER: + /* Handle it, but do nothing, if HAVE_SG + * isn't defined. + */ #if __HAVE_SG - if(dev->sg) { - DRM(sg_cleanup)(dev->sg); - dev->sg = NULL; - } + if(dev->sg) { + DRM(sg_cleanup)(dev->sg); + dev->sg = NULL; + } #endif - break; + break; + } + DRM(free)(map, sizeof(*map), DRM_MEM_MAPS); } - DRM(free)(map, sizeof(*map), DRM_MEM_MAPS); + list_del( list ); + DRM(free)(r_list, sizeof(*r_list), DRM_MEM_MAPS); } DRM(free)(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS); dev->maplist = NULL; diff --git a/linux/drm_drv.h b/linux/drm_drv.h index 016f9195..5f3eebe3 100644 --- a/linux/drm_drv.h +++ b/linux/drm_drv.h @@ -453,51 +453,49 @@ static int DRM(takedown)( drm_device_t *dev ) } if( dev->maplist ) { - for(list = dev->maplist->head.next; - list != &dev->maplist->head; - list = list_next) { - list_next = list->next; + list_for_each_safe( list, list_next, &dev->maplist->head ) { r_list = (drm_map_list_t *)list; - map = r_list->map; - DRM(free)(r_list, sizeof(*r_list), DRM_MEM_MAPS); - if(!map) continue; - switch ( map->type ) { - case _DRM_REGISTERS: - case _DRM_FRAME_BUFFER: + if ( ( map = r_list->map ) ) { + switch ( map->type ) { + case _DRM_REGISTERS: + case _DRM_FRAME_BUFFER: #if __REALLY_HAVE_MTRR - if ( map->mtrr >= 0 ) { - int retcode; - retcode = mtrr_del( map->mtrr, - map->offset, - map->size ); - DRM_DEBUG( "mtrr_del=%d\n", retcode ); - } -#endif - DRM(ioremapfree)( map->handle, map->size, dev ); - break; - case _DRM_SHM: - vfree(map->handle); - break; - - case _DRM_AGP: - /* Do nothing here, because this is all - * handled in the AGP/GART driver. - */ - break; - case _DRM_SCATTER_GATHER: - /* Handle it, but do nothing, if HAVE_SG - * isn't defined. - */ + if ( map->mtrr >= 0 ) { + int retcode; + retcode = mtrr_del( map->mtrr, + map->offset, + map->size ); + DRM_DEBUG( "mtrr_del=%d\n", retcode ); + } +#endif + DRM(ioremapfree)( map->handle, map->size, dev ); + break; + case _DRM_SHM: + vfree(map->handle); + break; + + case _DRM_AGP: + /* Do nothing here, because this is all + * handled in the AGP/GART driver. + */ + break; + case _DRM_SCATTER_GATHER: + /* Handle it, but do nothing, if HAVE_SG + * isn't defined. + */ #if __HAVE_SG - if(dev->sg) { - DRM(sg_cleanup)(dev->sg); - dev->sg = NULL; - } + if(dev->sg) { + DRM(sg_cleanup)(dev->sg); + dev->sg = NULL; + } #endif - break; + break; + } + DRM(free)(map, sizeof(*map), DRM_MEM_MAPS); } - DRM(free)(map, sizeof(*map), DRM_MEM_MAPS); + list_del( list ); + DRM(free)(r_list, sizeof(*r_list), DRM_MEM_MAPS); } DRM(free)(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS); dev->maplist = NULL; |