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