summaryrefslogtreecommitdiff
path: root/linux-core
diff options
context:
space:
mode:
authorMichel Daenzer <michel@daenzer.net>2003-08-06 11:46:21 +0000
committerMichel Daenzer <michel@daenzer.net>2003-08-06 11:46:21 +0000
commitda16867c8433516c361944e6e4265bd511ac72c8 (patch)
treefb46b5adee9a3f14a5ffb20acec28d8f2178db14 /linux-core
parent4b60cae90e0f689f68167c2e3419df7574cae1ab (diff)
Fix maplist entries being used after they were freed; thanks to Benjamin
Herrenschmidt for tracking this down
Diffstat (limited to 'linux-core')
-rw-r--r--linux-core/drm_drv.c76
1 files changed, 37 insertions, 39 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;