Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/ieee1394 Fix fwdma_free() for when bus_dmamap_unload...



details:   https://anonhg.NetBSD.org/src/rev/c3489ca7198d
branches:  trunk
changeset: 446665:c3489ca7198d
user:      jakllsch <jakllsch%NetBSD.org@localhost>
date:      Thu Dec 13 16:38:26 2018 +0000

description:
Fix fwdma_free() for when bus_dmamap_unload() clobbers the dmamap.

Prevents KASSERTs on detaches of sbp(4) and fwohci(4) on amd64.

We should pass the dmamem segs around seperately, not in loaded dmamap...

diffstat:

 sys/dev/ieee1394/fwdma.c |  19 +++++++++++++++----
 1 files changed, 15 insertions(+), 4 deletions(-)

diffs (50 lines):

diff -r 579c130c3839 -r c3489ca7198d sys/dev/ieee1394/fwdma.c
--- a/sys/dev/ieee1394/fwdma.c  Thu Dec 13 16:28:10 2018 +0000
+++ b/sys/dev/ieee1394/fwdma.c  Thu Dec 13 16:38:26 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fwdma.c,v 1.16 2010/05/23 18:56:58 christos Exp $      */
+/*     $NetBSD: fwdma.c,v 1.17 2018/12/13 16:38:26 jakllsch Exp $      */
 /*-
  * Copyright (c) 2003
  *     Hidetoshi Shimokawa. All rights reserved.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fwdma.c,v 1.16 2010/05/23 18:56:58 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fwdma.c,v 1.17 2018/12/13 16:38:26 jakllsch Exp $");
 #if defined(__FreeBSD__)
 __FBSDID("$FreeBSD: src/sys/dev/firewire/fwdma.c,v 1.9 2007/06/06 14:31:36 simokawa Exp $");
 #endif
@@ -47,6 +47,7 @@
 #include <sys/types.h>
 #include <sys/kernel.h>
 #include <sys/malloc.h>
+#include <sys/kmem.h>
 #include <sys/select.h>
 
 #include <machine/vmparam.h>
@@ -108,11 +109,21 @@
 void
 fwdma_free(bus_dma_tag_t dmat, bus_dmamap_t dmamap, void *vaddr)
 {
+       bus_dma_segment_t *segs;
 
+       /* XXX we shouldn't pass around the segs in the dmamap */
+       const bus_size_t mapsize = dmamap->dm_mapsize;
+       const int nsegs = dmamap->dm_nsegs;
+       const size_t segssz = sizeof(bus_dma_segment_t) * nsegs;
+       segs = kmem_alloc(segssz, KM_SLEEP);
+       memcpy(segs, dmamap->dm_segs, segssz);
+       
        bus_dmamap_unload(dmat, dmamap);
-       bus_dmamem_unmap(dmat, vaddr, dmamap->dm_mapsize);
-       bus_dmamem_free(dmat, dmamap->dm_segs, dmamap->dm_nsegs);
+       bus_dmamem_unmap(dmat, vaddr, mapsize);
+       bus_dmamem_free(dmat, segs, nsegs);
        bus_dmamap_destroy(dmat, dmamap);
+       
+       kmem_free(segs, segssz);
 }
 
 



Home | Main Index | Thread Index | Old Index