From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1L7Exf-0002BF-4d for qemu-devel@nongnu.org; Mon, 01 Dec 2008 15:01:39 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1L7Exc-0002AK-K7 for qemu-devel@nongnu.org; Mon, 01 Dec 2008 15:01:38 -0500 Received: from [199.232.76.173] (port=43395 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1L7Exc-0002AF-9m for qemu-devel@nongnu.org; Mon, 01 Dec 2008 15:01:36 -0500 Received: from mx2.redhat.com ([66.187.237.31]:40819) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1L7Exb-0000Ie-H0 for qemu-devel@nongnu.org; Mon, 01 Dec 2008 15:01:35 -0500 From: Glauber Costa Date: Mon, 1 Dec 2008 15:01:32 -0500 Message-Id: <1228161692-13200-1-git-send-email-glommer@redhat.com> Subject: [Qemu-devel] [PATCH] extboot: properly set int 0x13 return value Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: kvm@vger.kernel.org Cc: aliguori@us.ibm.com, qemu-devel@nongnu.org Callers of int 0x13 usually rely on the carry flag being clear/set to indicate the status of the interrupt execution. However, our current code clear or set the flags register, which is totally useless. Whichever value it has, will be overwritten by the flags value _before_ the interrupt, due to the iret instruction. This fixes a bug that prevents slackware (and possibly win2k, untested) to boot. Signed-off-by: Glauber Costa --- extboot/extboot.S | 52 ++++++++++++++++++++++++++-------------------------- 1 files changed, 26 insertions(+), 26 deletions(-) diff --git a/extboot/extboot.S b/extboot/extboot.S index 2630abb..e3d1adf 100644 --- a/extboot/extboot.S +++ b/extboot/extboot.S @@ -99,24 +99,24 @@ int19_handler: #define FLAGS_CF 0x01 -.macro clc - push %ax - pushf - pop %ax - and $(~FLAGS_CF), %ax - push %ax - popf - pop %ax +/* The two macro below clear/set the carry flag to indicate the status + * of the interrupt execution. It is not enough to issue a clc/stc instruction, + * since the value of the flags register will be overwritten by whatever is + * in the stack frame + */ +.macro clc_stack + push %bp + mov %sp, %bp + /* 8 = 2 (bp, just pushed) + 2 (ip) + 3 (real mode interrupt frame) */ + and $(~FLAGS_CF), 8(%bp) + pop %bp .endm -.macro stc - push %ax - pushf - pop %ax - or $(FLAGS_CF), %ax - push %ax - popf - pop %ax +.macro stc_stack + push %bp + /* 8 = 2 (bp, just pushed) + 2 (ip) + 3 (real mode interrupt frame) */ + or $(FLAGS_CF), 8(%bp) + pop %bp .endm /* we clobber %bx */ @@ -292,7 +292,7 @@ mul32: /* lo, hi, lo, hi */ disk_reset: movb $0, %ah - clc + clc_stack ret /* this really should be a function, not a macro but i'm lazy */ @@ -395,7 +395,7 @@ disk_reset: pop %ax mov $0, %ah - clc + clc_stack ret .endm @@ -454,12 +454,12 @@ read_disk_drive_parameters: pop %bx /* do this last since it's the most sensitive */ - clc + clc_stack ret alternate_disk_reset: movb $0, %ah - clc + clc_stack ret read_disk_drive_size: @@ -498,21 +498,21 @@ read_disk_drive_size: freea pop %bx - clc + clc_stack ret check_if_extensions_present: mov $0x30, %ah mov $0xAA55, %bx mov $0x07, %cx - clc + clc_stack ret .macro extended_read_write_sectors cmd cmpb $10, 0(%si) jg 1f mov $1, %ah - stc + stc_stack ret 1: push %ax @@ -544,7 +544,7 @@ check_if_extensions_present: pop %ax mov $0, %ah - clc + clc_stack ret .endm @@ -612,12 +612,12 @@ get_extended_drive_parameters: pop %ax mov $0, %ah - clc + clc_stack ret terminate_disk_emulation: mov $1, %ah - stc + stc_stack ret int13_handler: -- 1.5.6.5