From cc56ff5af011c6f18f52b9bd29184be26a3ef1a2 Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Fri, 1 Aug 2014 16:30:57 -0500 Subject: [CHANGE 4/4] ide: Reset BMIDEA bit when the bus master is stopped To: rhvirt-patches@redhat.com, jen@redhat.com RH-Author: Kevin Wolf Message-id: <1406910657-19808-4-git-send-email-kwolf@redhat.com> Patchwork-id: 60406 O-Subject: [RHEL-6.6 qemu-kvm PATCH 3/3] ide: Reset BMIDEA bit when the bus master is stopped Bugzilla: 1104573 RH-Acked-by: Max Reitz RH-Acked-by: Marcel Apfelbaum RH-Acked-by: Stefan Hajnoczi Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1104573 The device is supposed to reset the Bus Master IDE Active bit in the status register when 0 is written to the Start/Stop Bus Master bit in the command register. In the common cases this happens automatically because bdrv_drain_all() flushes the requests, but with a large PRDT it could remain set. [ RHEL 6 note: It also fixes cases where the guest sets BMIDEA and then resets it again without having performed any DMA. In this case, the bit remains incorrectly set without this patch, causing requests to be processed when they shouldn't be yet and exposing a wrong status register. In the reported bug this became visible as Linux disabling DMA and installation with PIO taking so long that the test case timed out. ] Signed-off-by: Kevin Wolf (cherry picked from commit b39f96126549e2834152211a99919917423d2212) --- hw/ide/pci.c | 1 + 1 file changed, 1 insertion(+) Signed-off-by: jen --- hw/ide/pci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/ide/pci.c b/hw/ide/pci.c index a10a9fc..a02ae4a 100644 --- a/hw/ide/pci.c +++ b/hw/ide/pci.c @@ -62,6 +62,7 @@ void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val) if (bm->status & BM_STATUS_DMAING) printf("ide_dma_cancel: BM_STATUS_DMAING still pending\n"); } + bm->status &= ~BM_STATUS_DMAING; } else { bm->cur_addr = bm->addr; if (!(bm->status & BM_STATUS_DMAING)) { -- 1.9.3