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;