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