Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/ic Don't call bus_dmamap_load(9) and bus_dmamap_sync...



details:   https://anonhg.NetBSD.org/src/rev/088b2269d4f4
branches:  trunk
changeset: 760653:088b2269d4f4
user:      tsutsui <tsutsui%NetBSD.org@localhost>
date:      Mon Jan 10 11:18:14 2011 +0000

description:
Don't call bus_dmamap_load(9) and bus_dmamap_sync(9) on command xfers
if (AT_READ|AT_WRITE) in ata_c->flags is set but ata_c->bcount is zero.
Someone actually tries to put such a command and it causes
DIAGNOSTIC panic in x86/bus_dma.c:_bus_dmamap_sync().
I think bus_dma(9) API itself may allow calls with mapsize==0
but there are many MD code that asserts offset>=mapsize or len==0.

The problem is reported and fix is confirmed by Takuro KUBOTA
with XEN DOM0 kernel (which has options DIAGNOSTIC).

diffstat:

 sys/dev/ic/ahcisata_core.c |  9 +++++----
 1 files changed, 5 insertions(+), 4 deletions(-)

diffs (37 lines):

diff -r f3bb6c12566f -r 088b2269d4f4 sys/dev/ic/ahcisata_core.c
--- a/sys/dev/ic/ahcisata_core.c        Mon Jan 10 11:13:03 2011 +0000
+++ b/sys/dev/ic/ahcisata_core.c        Mon Jan 10 11:18:14 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ahcisata_core.c,v 1.30 2010/11/13 13:52:00 uebayasi Exp $      */
+/*     $NetBSD: ahcisata_core.c,v 1.31 2011/01/10 11:18:14 tsutsui Exp $       */
 
 /*
  * Copyright (c) 2006 Manuel Bouyer.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.30 2010/11/13 13:52:00 uebayasi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.31 2011/01/10 11:18:14 tsutsui Exp $");
 
 #include <sys/types.h>
 #include <sys/malloc.h>
@@ -769,7 +769,8 @@
        AHCIDEBUG_PRINT(("%s port %d header %p\n", AHCINAME(sc),
            chp->ch_channel, cmd_h), DEBUG_XFERS);
        if (ahci_dma_setup(chp, slot,
-           (ata_c->flags & (AT_READ|AT_WRITE)) ? ata_c->data : NULL,
+           (ata_c->flags & (AT_READ|AT_WRITE) && ata_c->bcount > 0) ?
+           ata_c->data : NULL,
            ata_c->bcount,
            (ata_c->flags & AT_READ) ? BUS_DMA_READ : BUS_DMA_WRITE)) {
                ata_c->flags |= AT_DF;
@@ -904,7 +905,7 @@
        /* this comamnd is not active any more */
        achp->ahcic_cmds_active &= ~(1 << slot);
 
-       if (ata_c->flags & (AT_READ|AT_WRITE)) {
+       if (ata_c->flags & (AT_READ|AT_WRITE) && ata_c->bcount > 0) {
                bus_dmamap_sync(sc->sc_dmat, achp->ahcic_datad[slot], 0,
                    achp->ahcic_datad[slot]->dm_mapsize,
                    (ata_c->flags & AT_READ) ? BUS_DMASYNC_POSTREAD :



Home | Main Index | Thread Index | Old Index