Subject: Re: lack of pciide transfer alignment checking causes crash
To: Jason Thorpe <thorpej@shagadelic.org>
From: Manuel Bouyer <bouyer@antioche.eu.org>
List: tech-kern
Date: 06/25/2005 21:12:52
On Sat, Jun 25, 2005 at 09:11:35PM +0200, Manuel Bouyer wrote:
> On Sat, Jun 25, 2005 at 10:52:13AM -0700, Jason Thorpe wrote:
> > 
> > On Jun 25, 2005, at 4:39 AM, Erik E. Fair wrote:
> > 
> > >The problem I want help with here on tech-kern is precisely where  
> > >to enforce
> > >the cache-line (16 byte) alignment requirement for IDE DMA  
> > >transfers. I have
> > >experimentally determined that any violation of that rule will  
> > >cause the system
> > >to lock up hard, requiring a Power-cycle to reset. User mode access  
> > >to the
> > >raw device, which, of course, invokes kern_physio().
> > >
> > >This is probably why the NetBSD install failed at the disklabelling  
> > >step (I
> > >subsequently installed NetBSD on an IDE disk on another system, and  
> > >then moved
> > >the disk over).
> > >
> > >The only reason that NetBSD runs at all on this box is that the  
> > >typical FFS
> > >filesystem I/O requests are apparently aligned properly.
> > >
> > >I think there are two basic choices for handling a misaligned  
> > >transfer request:
> > >
> > >1. return an error (e.g. EIO).
> > >
> > >2. use PIO mode for misaligned transfers.
> > >
> > >I think that sys/dev/pci/pciide_common.c should have facilities  
> > >added to it
> > >to enforce alignment (I didn't see any at a minimum, and I think it  
> > >would be
> > >nice if it handled them gracefully by degrading to PIO mode.
> > 
> > I think the best way to handle this would be:
> > 
> > 1. Change _wdc_ata_bio_start() handle the case where (*wdc->dma_init) 
> > () fails with EINVAL.  Fall back to PIO mode in that case (clear  
> > C_DMA flag bit in the xfer structure).
> > 
> > 2. Make same change to wdc_atapi_intr().
> > 
> > 3. Give geodeide its own dma_init routine that checks for the  
> > alignment of the buffer.  If the buffer is not aligned, it returns  
> > EINVAL.  Otherwise, it just calls the normal pciide_dma_init() routine.
> > 
> > 
> > Manuel -- does this seem feasible?
> 
> Yes, this should work. But I think it's better and easier to do the
> I/O to a properly aligned buffer and data copy to/from this buffer.
> This can easily be done in the dma_start and dma_finish callbacks.

s/dma_start/dma_init/

-- 
Manuel Bouyer <bouyer@antioche.eu.org>
     NetBSD: 26 ans d'experience feront toujours la difference
--