From patchwork Tue Mar 20 02:17:32 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin O'Connor X-Patchwork-Id: 147721 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 81B75B7019 for ; Tue, 20 Mar 2012 13:17:50 +1100 (EST) Received: from localhost ([::1]:46749 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S9odw-0000ER-BL for incoming@patchwork.ozlabs.org; Mon, 19 Mar 2012 22:17:48 -0400 Received: from eggs.gnu.org ([208.118.235.92]:33236) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S9odn-0000Dn-Gr for qemu-devel@nongnu.org; Mon, 19 Mar 2012 22:17:40 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1S9odl-0003S8-LO for qemu-devel@nongnu.org; Mon, 19 Mar 2012 22:17:39 -0400 Received: from mail-qa0-f45.google.com ([209.85.216.45]:41648) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S9odl-0003S4-HH for qemu-devel@nongnu.org; Mon, 19 Mar 2012 22:17:37 -0400 Received: by qafi31 with SMTP id i31so1001715qaf.4 for ; Mon, 19 Mar 2012 19:17:35 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=date:from:to:cc:subject:message-id:references:mime-version :content-type:content-disposition:in-reply-to:user-agent :x-gm-message-state; bh=327vGgTCNi1ZDSKv0McbBYQRs9H5K8AHpg+AJKLlTF0=; b=hswLhwEHy+vMyRNDfjz1A3y0Ql+AeIgi6iZJsHXOvhin1atUNLpHm5QogGXDiPWXi+ /vFYlEt8WlPTQF51V/VKHT/hCCUpSTGkUz9QmEk4+sz7QMDaUFw+TFdX8pEKkkl3a5fZ CWZ3b75FBMsDNKp3FxImVlIzx9RV+jOackTkC8Yd1/EGUuPVlU5o0ONIFumLwlkyv8N2 v5P84c2AZmW/mKIQ8/bX0nK92z6DQTjzkPK429L1v6bjzI06jCTU4FU4Rnc3UFN+0oRH 8G+9Cnt46aN+jjDQTsxaZPJs+sctqy2vbPLmsV5YEWcBHw6wr/13msyTH27GfJCwGwGG oUwg== Received: by 10.229.135.141 with SMTP id n13mr5357088qct.25.1332209855286; Mon, 19 Mar 2012 19:17:35 -0700 (PDT) Received: from localhost (207-172-165-101.c3-0.avec-ubr1.nyr-avec.ny.cable.rcn.com. [207.172.165.101]) by mx.google.com with ESMTPS id eo4sm290142qab.16.2012.03.19.19.17.33 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 19 Mar 2012 19:17:34 -0700 (PDT) Date: Mon, 19 Mar 2012 22:17:32 -0400 From: Kevin O'Connor To: Jan Kiszka Message-ID: <20120320021732.GA28726@morn.localdomain> References: <20120227095156.GA24607@redhat.com> <4F4BA055.9010005@siemens.com> <20120319002947.GA22937@morn.localdomain> <4F6790FD.6030500@siemens.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <4F6790FD.6030500@siemens.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Gm-Message-State: ALoCoQkV4tGoKTh5kHdndtEsRghk1l93cI+3XIXAr+Bx8aEZC1YJ73gtj/y1khyO+5062YbjC5AB X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.216.45 Cc: seabios , "qemu-devel@nongnu.org" Subject: Re: [Qemu-devel] Boot failure with MS-Dos 6.22 (due to bad BIOS build?) X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org On Mon, Mar 19, 2012 at 09:03:09PM +0100, Jan Kiszka wrote: > On 2012-03-19 01:29, Kevin O'Connor wrote: > > On Mon, Feb 27, 2012 at 04:25:09PM +0100, Jan Kiszka wrote: > >>> EAX=ffffffff EBX=ffffffff ECX=0000c934 EDX=00000068 > >>> ESI=00006801 EDI=00000000 EBP=0000002b ESP=0000fff5 > > > > I traced this down, and it appears to be a stack size issue. It looks > > like MSDOS calls "int 0x13" with 229 bytes of stack space during its > > boot. On my build gcc generates the handle_13() function with a > > maximum of 140 bytes of stack space utilized (according to > > tools/checkstack.py). On your build, gcc created it with a maximum of > > 216 bytes. The entry functions use 42 bytes of stack space. Add it > > up and you can see that the additional stack space that gcc used > > caused %esp to wrap and the stack was corrupted. > > > > I'm not sure how to best work around this. One way is to sprinkle > > "noinline" keywords through disk.c. (It seems like gcc got in trouble > > on your build by inlining many functions into disk_13().) Another way > > would be to jump into the extra stack (the disk code already uses its > > own stack) earlier in the handle_13 code. > > > > Also, can you see what happens if you change "--param > > large-stack-frame=4" to "--param large-stack-frame=0" in the build? > > This makes no difference here, still 216 bytes. I've noticed that if one takes a pointer to a variable on the stack, gcc seems to do a poor job managing stack space. I'm guessing the patch below would fix the issue. It's a bit ugly though. -Kevin diff --git a/src/disk.c b/src/disk.c index 7a58af4..706b9f4 100644 --- a/src/disk.c +++ b/src/disk.c @@ -76,7 +76,7 @@ fillLCHS(struct drive_s *drive_g, u16 *nlc, u16 *nlh, u16 *nlspt) } // Perform read/write/verify using old-style chs accesses -static void +static void noinline basic_access(struct bregs *regs, struct drive_s *drive_g, u16 command) { struct disk_op_s dop; @@ -119,7 +119,7 @@ basic_access(struct bregs *regs, struct drive_s *drive_g, u16 command) } // Perform read/write/verify using new-style "int13ext" accesses. -static void +static void noinline extended_access(struct bregs *regs, struct drive_s *drive_g, u16 command) { struct disk_op_s dop; @@ -201,7 +201,7 @@ disk_1304(struct bregs *regs, struct drive_s *drive_g) } // format disk track -static void +static void noinline disk_1305(struct bregs *regs, struct drive_s *drive_g) { debug_stub(regs); @@ -228,7 +228,7 @@ disk_1305(struct bregs *regs, struct drive_s *drive_g) } // read disk drive parameters -static void +static void noinline disk_1308(struct bregs *regs, struct drive_s *drive_g) { u16 ebda_seg = get_ebda_seg(); @@ -329,7 +329,7 @@ disk_1314(struct bregs *regs, struct drive_s *drive_g) } // read disk drive size -static void +static void noinline disk_1315(struct bregs *regs, struct drive_s *drive_g) { disk_ret(regs, DISK_RET_SUCCESS); @@ -463,7 +463,7 @@ disk_1345(struct bregs *regs, struct drive_s *drive_g) } // IBM/MS eject media -static void +static void noinline disk_1346(struct bregs *regs, struct drive_s *drive_g) { if (regs->dl < EXTSTART_CD) {