On Mon, 2003-08-04 at 17:51, Benjamin Herrenschmidt wrote: 
> 
> It's actually dying in drm_ioremapfree() called by radeon_takedown(),
> This is a uninorth based PowerMac, so it's using the vmap mecanism
> (cant_use_aperture is 1).  It's accessing a freed object (apparently,
> a pointer set to 6b6b6b6b, so a pointer retreived within a freed
> object). This is obviously triggered by slab poisoning.
> 
> One strange thing though is that only maps of type _DRM_REGISTERS and
> _DRM_FRAME_BUFFER are freed via this codepath. Also, the above address
> shows, in the disassembly, that we did enter the "AGP" case of
> drm_ioremapfree(), we didn't just do iounmap(). It seems the actual
> crash location is within drm_lookup_map(). Like if a freed map was
> still in there...

Indeed, the maplist entry is freed before the DRM(ioremapfree) call.
Does this patch fix it?


-- 
Earthling Michel Dänzer   \  Debian (powerpc), XFree86 and DRI developer
Software libre enthusiast  \     http://svcs.affero.net/rm.php?r=daenzer
Index: programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_drv.h
===================================================================
RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_drv.h,v
retrieving revision 1.41
diff -p -u -r1.41 drm_drv.h
--- programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_drv.h	11 Jul 2003 15:27:55 -0000	1.41
+++ programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_drv.h	6 Aug 2003 10:47:29 -0000
@@ -458,46 +458,46 @@ static int DRM(takedown)( drm_device_t *
 		    list = list_next) {
 			list_next = list->next;
 			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 );
-				}
+					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;
+					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.
-				 */
+				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)(r_list, sizeof(*r_list), DRM_MEM_MAPS);
  		}
 		DRM(free)(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS);
 		dev->maplist = NULL;

Reply via email to