Blame SOURCES/kvm-ide-Clear-DRQ-after-handling-all-expected-accesses.patch

9ae3a8
From c887704e6425ee43d8b65e34dc0f57a4878231cf Mon Sep 17 00:00:00 2001
9ae3a8
From: Kevin Wolf <kwolf@redhat.com>
9ae3a8
Date: Thu, 16 Jul 2015 16:16:00 +0200
9ae3a8
Subject: [PATCH 3/3] ide: Clear DRQ after handling all expected accesses
9ae3a8
9ae3a8
Message-id: <1437056160-3284-4-git-send-email-kwolf@redhat.com>
9ae3a8
Patchwork-id: n/a
9ae3a8
O-Subject: [virt-devel] [RHEL/RHEV-7 qemu-kvm(-rhev) EMBARGOED PATCH 3/3] ide:
9ae3a8
        Clear DRQ after handling all expected accesses
9ae3a8
Bugzilla: 1243690
9ae3a8
RH-Acked-by: Petr Matousek <pmatouse@redhat.com>
9ae3a8
RH-Acked-by: John Snow <jsnow@redhat.com>
9ae3a8
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
9ae3a8
9ae3a8
This is additional hardening against an end_transfer_func that fails to
9ae3a8
clear the DRQ status bit. The bit must be unset as soon as the PIO
9ae3a8
transfer has completed, so it's better to do this in a central place
9ae3a8
instead of duplicating the code in all commands (and forgetting it in
9ae3a8
some).
9ae3a8
9ae3a8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9ae3a8
---
9ae3a8
 hw/ide/core.c | 16 ++++++++++++----
9ae3a8
 1 file changed, 12 insertions(+), 4 deletions(-)
9ae3a8
9ae3a8
diff --git a/hw/ide/core.c b/hw/ide/core.c
9ae3a8
index 29bda6b..5d40093 100644
9ae3a8
--- a/hw/ide/core.c
9ae3a8
+++ b/hw/ide/core.c
9ae3a8
@@ -1857,8 +1857,10 @@ void ide_data_writew(void *opaque, uint32_t addr, uint32_t val)
9ae3a8
     *(uint16_t *)p = le16_to_cpu(val);
9ae3a8
     p += 2;
9ae3a8
     s->data_ptr = p;
9ae3a8
-    if (p >= s->data_end)
9ae3a8
+    if (p >= s->data_end) {
9ae3a8
+        s->status &= ~DRQ_STAT;
9ae3a8
         s->end_transfer_func(s);
9ae3a8
+    }
9ae3a8
 }
9ae3a8
 
9ae3a8
 uint32_t ide_data_readw(void *opaque, uint32_t addr)
9ae3a8
@@ -1882,8 +1884,10 @@ uint32_t ide_data_readw(void *opaque, uint32_t addr)
9ae3a8
     ret = cpu_to_le16(*(uint16_t *)p);
9ae3a8
     p += 2;
9ae3a8
     s->data_ptr = p;
9ae3a8
-    if (p >= s->data_end)
9ae3a8
+    if (p >= s->data_end) {
9ae3a8
+        s->status &= ~DRQ_STAT;
9ae3a8
         s->end_transfer_func(s);
9ae3a8
+    }
9ae3a8
     return ret;
9ae3a8
 }
9ae3a8
 
9ae3a8
@@ -1907,8 +1911,10 @@ void ide_data_writel(void *opaque, uint32_t addr, uint32_t val)
9ae3a8
     *(uint32_t *)p = le32_to_cpu(val);
9ae3a8
     p += 4;
9ae3a8
     s->data_ptr = p;
9ae3a8
-    if (p >= s->data_end)
9ae3a8
+    if (p >= s->data_end) {
9ae3a8
+        s->status &= ~DRQ_STAT;
9ae3a8
         s->end_transfer_func(s);
9ae3a8
+    }
9ae3a8
 }
9ae3a8
 
9ae3a8
 uint32_t ide_data_readl(void *opaque, uint32_t addr)
9ae3a8
@@ -1932,8 +1938,10 @@ uint32_t ide_data_readl(void *opaque, uint32_t addr)
9ae3a8
     ret = cpu_to_le32(*(uint32_t *)p);
9ae3a8
     p += 4;
9ae3a8
     s->data_ptr = p;
9ae3a8
-    if (p >= s->data_end)
9ae3a8
+    if (p >= s->data_end) {
9ae3a8
+        s->status &= ~DRQ_STAT;
9ae3a8
         s->end_transfer_func(s);
9ae3a8
+    }
9ae3a8
     return ret;
9ae3a8
 }
9ae3a8
 
9ae3a8
-- 
9ae3a8
1.8.3.1
9ae3a8