qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH] Re: DMA timeouts running a FreeBSD guest with l


From: Aurelien Jarno
Subject: Re: [Qemu-devel] [PATCH] Re: DMA timeouts running a FreeBSD guest with last CVS snapshot
Date: Mon, 22 Jan 2007 11:55:11 +0100
User-agent: IceDove 1.5.0.9 (X11/20061220)

Carlo Marcelo Arenas Belon a écrit :
> On Mon, Jan 15, 2007 at 03:21:36AM -0600, Carlo Marcelo Arenas Belon wrote:
>> FreeBSD 6.2 guest I noticed the following errors at boot time :
>>
>>   ad0: 2048MB <QEMU HARDDISK 0.8.3> at ata0-master WDMA2
>>   ad0: FAILURE - READ_DMA timed out LBA=4194301
>>   acd0: CDROM <QEMU CD-ROM/0.8.3> at ata1-master WDMA2
>>   acd0: TIMEOUT - READ BIG retrying (1 retry left)
>>
> 
> The problem is that FreeBSD is sending a WIN_READDMA (0xC8) command to the
> emulated PIIX3 controller before it sets the DMA address that will be used and
> therefore the code in ide_dma_start is not setting bm->cur_addr to the right
> value (it is left set to 0) and then it is failing the validation in
> dma_buf_rw where the distance between bm->cur_addr and bm->addr is expected to
> be smaller than 1 page (4K) and resulting in an EOT error and a timeout which
> FreeBSD handles by resetting the IDE controller.
> 
> Apparently all other guests I'd tried (Linux, Solaris, OpenBSD and Windows)
> set the address first (bmdma_addr_write) and then send the request for a DMA
> command and are therefore not affected by this, but even if FreeBSD behavior
> is peculiar, it should be OK if implemented against real hardware as per the
> spec in :
> 
>   http://www.intel.com/design/intarch/datashts/290550.htm
> 
> The following patch moves the initialization of bm->cur_addr to match FreeBSD
> behavior while being also compatible with all other guests but keeping in
> sync closely the values of the memory addresses which will be used for the DMA
> in a way that better emulates real hardware.
> 
> Tested with guests running FreeBSD 6.2 amd64, OpenBSD 4.0 amd64, Ubuntu Linux 
> 6.06 amd64, OpenSolaris b55b amd64, Windows 2000 Professional i386 and Gentoo
> Linux 2006.1 i386.
> 
> Carlo
> 
> 
> ------------------------------------------------------------------------
> 
> Index: hw/ide.c
> ===================================================================
> RCS file: /sources/qemu/qemu/hw/ide.c,v
> retrieving revision 1.51
> diff -u -r1.51 ide.c
> --- hw/ide.c  20 Jan 2007 01:12:17 -0000      1.51
> +++ hw/ide.c  22 Jan 2007 09:50:20 -0000
> @@ -2230,10 +2230,11 @@
>          return;
>      bm->ide_if = s;
>      bm->dma_cb = dma_cb;
> -    bm->cur_addr = bm->addr;
>      bm->cur_prd_last = 0;
>      bm->cur_prd_addr = 0;
>      bm->cur_prd_len = 0;
> +    if (bm->cur_addr != bm->addr)
> +        bm->cur_addr = bm->addr;

Why using a condition here? This will probably be slower than doing
bm->cur_addr = bm->addr and the result is the same.

>      if (bm->status & BM_STATUS_DMAING) {
>          bm->dma_cb(bm, 0);
>      }
> @@ -2363,6 +2364,7 @@
>      printf("%s: 0x%08x\n", __func__, val);
>  #endif
>      bm->addr = val & ~3;
> +    bm->cur_addr = bm->addr;
>  }
>  
>  static void bmdma_map(PCIDevice *pci_dev, int region_num, 
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> Qemu-devel mailing list
> address@hidden
> http://lists.nongnu.org/mailman/listinfo/qemu-devel


-- 
  .''`.  Aurelien Jarno             | GPG: 1024D/F1BCDB73
 : :' :  Debian developer           | Electrical Engineer
 `. `'   address@hidden         | address@hidden
   `-    people.debian.org/~aurel32 | www.aurel32.net




reply via email to

[Prev in Thread] Current Thread [Next in Thread]