ae23c9
From 93623a848fba7757a0840b78d7b3874bab4d7a1b Mon Sep 17 00:00:00 2001
ae23c9
From: John Snow <jsnow@redhat.com>
ae23c9
Date: Tue, 10 Jul 2018 23:06:15 +0200
ae23c9
Subject: [PATCH 206/268] ahci: fix PxCI register race
ae23c9
MIME-Version: 1.0
ae23c9
Content-Type: text/plain; charset=UTF-8
ae23c9
Content-Transfer-Encoding: 8bit
ae23c9
ae23c9
RH-Author: John Snow <jsnow@redhat.com>
ae23c9
Message-id: <20180710230616.11000-3-jsnow@redhat.com>
ae23c9
Patchwork-id: 81293
ae23c9
O-Subject: [RHEL-7.6 qemu-kvm-rhev PATCH 2/3] ahci: fix PxCI register race
ae23c9
Bugzilla: 1584914
ae23c9
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
ae23c9
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
ae23c9
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
ae23c9
ae23c9
Fixes: https://bugs.launchpad.net/qemu/+bug/1769189
ae23c9
ae23c9
AHCI presently signals completion prior to the PxCI register being
ae23c9
cleared to indicate completion. If a guest driver attempts to issue
ae23c9
a new command in its IRQ handler, it might be surprised to learn there
ae23c9
is still a command pending.
ae23c9
ae23c9
In the case of Windows 10's boot driver, it will actually poll the IRQ
ae23c9
register hoping to find out when the command is done running -- which
ae23c9
will never happen, as there isn't a command running.
ae23c9
ae23c9
Fix this: clear PxCI in ahci_cmd_done and not in the asynchronous BH.
ae23c9
Because it now runs synchronously, we don't need to check if the command
ae23c9
is actually done by spying on the ATA registers. We know it's done.
ae23c9
ae23c9
CC: qemu-stable <qemu-stable@nongnu.org>
ae23c9
Reported-by: François Guerraz <kubrick@fgv6.net>
ae23c9
Tested-by: Bruce Rogers <brogers@suse.com>
ae23c9
Signed-off-by: John Snow <jsnow@redhat.com>
ae23c9
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
ae23c9
Reviewed-by: Jeff Cody <jcody@redhat.com>
ae23c9
Message-id: 20180531004323.4611-3-jsnow@redhat.com
ae23c9
Signed-off-by: John Snow <jsnow@redhat.com>
ae23c9
(cherry picked from commit 5694c7eacce6b263ad7497cc1bb76aad746cfd4e)
ae23c9
Signed-off-by: John Snow <jsnow@redhat.com>
ae23c9
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
ae23c9
---
ae23c9
 hw/ide/ahci.c | 13 ++++++-------
ae23c9
 1 file changed, 6 insertions(+), 7 deletions(-)
ae23c9
ae23c9
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
ae23c9
index b7a6f68..a9558e4 100644
ae23c9
--- a/hw/ide/ahci.c
ae23c9
+++ b/hw/ide/ahci.c
ae23c9
@@ -532,13 +532,6 @@ static void ahci_check_cmd_bh(void *opaque)
ae23c9
     qemu_bh_delete(ad->check_bh);
ae23c9
     ad->check_bh = NULL;
ae23c9
 
ae23c9
-    if ((ad->busy_slot != -1) &&
ae23c9
-        !(ad->port.ifs[0].status & (BUSY_STAT|DRQ_STAT))) {
ae23c9
-        /* no longer busy */
ae23c9
-        ad->port_regs.cmd_issue &= ~(1 << ad->busy_slot);
ae23c9
-        ad->busy_slot = -1;
ae23c9
-    }
ae23c9
-
ae23c9
     check_cmd(ad->hba, ad->port_no);
ae23c9
 }
ae23c9
 
ae23c9
@@ -1425,6 +1418,12 @@ static void ahci_cmd_done(IDEDMA *dma)
ae23c9
 
ae23c9
     trace_ahci_cmd_done(ad->hba, ad->port_no);
ae23c9
 
ae23c9
+    /* no longer busy */
ae23c9
+    if (ad->busy_slot != -1) {
ae23c9
+        ad->port_regs.cmd_issue &= ~(1 << ad->busy_slot);
ae23c9
+        ad->busy_slot = -1;
ae23c9
+    }
ae23c9
+
ae23c9
     /* update d2h status */
ae23c9
     ahci_write_fis_d2h(ad);
ae23c9
 
ae23c9
-- 
ae23c9
1.8.3.1
ae23c9