Subject: Re: lack of pciide transfer alignment checking causes crash
To: Erik E.Fair <fair@netbsd.org>
From: Jason Thorpe <thorpej@shagadelic.org>
List: tech-kern
Date: 06/25/2005 10:52:13
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?

-- thorpej