From 11b98cdd8d3f07f3b57fa7b4f531b52a4c1018f7 Mon Sep 17 00:00:00 2001 From: Radim Krcmar 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 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 RH-Acked-by: Gerd Hoffmann RH-Acked-by: Laszlo Ersek 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ář (cherry picked from commit 10883a49e78ba83e3667e4386b8f11b4aa18ddb2) Signed-off-by: Paweł Poławski --- 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.31.1