44cf4a2
From 0c1e0d59ceb3c4c8909d7a7b6e62d19c7ad81bef Mon Sep 17 00:00:00 2001
44cf4a2
From: Radim Krcmar <rkrcmar@redhat.com>
44cf4a2
Date: Mon, 10 Mar 2014 15:14:27 +0100
44cf4a2
Subject: Workaround for a win8.1-32 S4 resume bug
44cf4a2
MIME-Version: 1.0
44cf4a2
Content-Type: text/plain; charset=UTF-8
44cf4a2
Content-Transfer-Encoding: 8bit
44cf4a2
44cf4a2
RH-Author: Radim Krcmar <rkrcmar@redhat.com>
44cf4a2
Message-id: <1394464467-23560-1-git-send-email-rkrcmar@redhat.com>
44cf4a2
Patchwork-id: 58069
44cf4a2
O-Subject: [RHEL7.0 seabios PATCH] Workaround for a win8.1-32 S4 resume bug
44cf4a2
Bugzilla: 1050775
44cf4a2
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
44cf4a2
RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
44cf4a2
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
44cf4a2
44cf4a2
bug:  https://bugzilla.redhat.com/show_bug.cgi?id=1050775
44cf4a2
brew: http://brewweb.devel.redhat.com/brew/taskinfo?taskID=7176174
44cf4a2
This patch has no upstream equivalent.
44cf4a2
44cf4a2
When a 32 bit version of windows 8.1 resumes from suspend, it writes 1
44cf4a2
into 0x72 in the early boot because it didn't expect a NULL pointer.
44cf4a2
0x72 is lower offset byte of 0x1c interrupt entry, so we jump into a
44cf4a2
middle of other function if this interrupt is triggered.
44cf4a2
44cf4a2
Because 0x1c is only triggered from our handle_08, we detect if our
44cf4a2
default value (function that does only iret) has its lower offset byte
44cf4a2
overwritten and skip it in that case.
44cf4a2
(Windows never sets own callback there, so we always detect this bug
44cf4a2
 correctly, as seabios doesn't use it either
44cf4a2
 Other sources shouldn't incorrectly overwrite it or use seabios code,
44cf4a2
 but it is quite ok even if the guest did this on purpose.)
44cf4a2
44cf4a2
The reason Windows uses NULL pointer is still unknown, but this bug is
44cf4a2
blocking WHQL certification, so we have to work around it in 7.0.
44cf4a2
44cf4a2
Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
44cf4a2
---
44cf4a2
(It is either a Windows bug that is going to be solved on their side,
44cf4a2
 or we will find a better solution after consulting what went wrong.
44cf4a2
 Happens on RHEL6 too.)
44cf4a2
44cf4a2
 src/clock.c | 8 +++++++-
44cf4a2
 1 file changed, 7 insertions(+), 1 deletion(-)
44cf4a2
44cf4a2
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
44cf4a2
(cherry picked from commit aa1c26538deecfd820b7da9b3be09ebc20b7fef9)
44cf4a2
---
44cf4a2
 src/clock.c | 8 +++++++-
44cf4a2
 1 file changed, 7 insertions(+), 1 deletion(-)
44cf4a2
44cf4a2
diff --git a/src/clock.c b/src/clock.c
44cf4a2
index e44e112..298a722 100644
44cf4a2
--- a/src/clock.c
44cf4a2
+++ b/src/clock.c
44cf4a2
@@ -309,7 +309,13 @@ handle_08(void)
44cf4a2
     struct bregs br;
44cf4a2
     memset(&br, 0, sizeof(br));
44cf4a2
     br.flags = F_IF;
44cf4a2
-    call16_int(0x1c, &br);
44cf4a2
+    struct segoff_s isr1c = GET_IVT(0x1c);
44cf4a2
+    // hardcoded address of entry_iret_official with lower segment byte
44cf4a2
+    // overwritten by 1
44cf4a2
+    if (isr1c.seg == ((SEG_BIOS & ~0xff) | 0x1) && isr1c.offset == 0xff53)
44cf4a2
+        dprintf(1, "Worked around win8.1-32 S4 resume bug\n");
44cf4a2
+    else
44cf4a2
+        call16_int(0x1c, &br);
44cf4a2
 
44cf4a2
     pic_eoi1();
44cf4a2
 }
44cf4a2
-- 
44cf4a2
1.8.3.1
44cf4a2