From owner-freebsd-hackers@FreeBSD.ORG Fri Jan 28 17:41:10 2011 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 7B8621065675 for ; Fri, 28 Jan 2011 17:41:10 +0000 (UTC) (envelope-from mdf356@gmail.com) Received: from mail-wy0-f182.google.com (mail-wy0-f182.google.com [74.125.82.182]) by mx1.freebsd.org (Postfix) with ESMTP id 11CD58FC0C for ; Fri, 28 Jan 2011 17:41:09 +0000 (UTC) Received: by wyf19 with SMTP id 19so3518214wyf.13 for ; Fri, 28 Jan 2011 09:41:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:date:message-id:subject:from:to :content-type; bh=iHa6ESFhL44Qvvr5AMoQSx8dCrU6eJtaA8JTFU+Aiso=; b=idXgDL4I4jBE/w0BITPjvz22BAf7WCwf2fIdqlO/fAFsnSKDrtdR3mCR8Ng8JGjffl auvHvn1dF16R5eIrj2Yol+n7xWfcG2HJrNtNDox8zComEilGRzpsUgURHpPAMRX6qrpk 2ZZb95LrLM3U3Bpno4iZVDRUd6jjbzJ2hUlW4= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:date:message-id:subject:from:to:content-type; b=uNSVH5A5y6plpvMbo+2Ch6mOGuQmsmGjKUApgVXvc9gy0YcPno8FtC/6F88q8ScZn8 P8dIm8D2Ed3UF7omAQYhfx9h3wMAjBNIs/NmbKwxC1f07qb2cuR9JcRXXhrmcHJha3iN OPIIeVYIqgH++oytTFF8m7UEGqoPyL9tlT51A= MIME-Version: 1.0 Received: by 10.216.156.6 with SMTP id l6mr8091412wek.55.1296236468370; Fri, 28 Jan 2011 09:41:08 -0800 (PST) Received: by 10.216.62.203 with HTTP; Fri, 28 Jan 2011 09:41:08 -0800 (PST) Date: Fri, 28 Jan 2011 09:41:08 -0800 Message-ID: From: Matthew Fleming To: freebsd-hackers Content-Type: text/plain; charset=ISO-8859-1 Subject: Divide-by-zero in loader X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 28 Jan 2011 17:41:10 -0000 I spent a few days chasing down a bug and I'm wondering if a loader change would be appropriate. So we have these new front-panel LCDs, and like everything these days it's a SoC. Normally it presents to FreeBSD as a USB communications device (ucom), but when the SoC is sitting in its own boot loader, it presents as storage (umass). If the box is rebooted in this state, the reboot gets into /boot/loader and then reboots itself. (It took a few days just to figure out I was getting into /boot/loader, since the only prompt I could definitively stop at was boot2). Anyways, I eventually debugged it to the device somehow presenting itself to /boot/loader with a geometry of 1024/256/0, and since od_sec is 0 that causes a divide-by-zero error in bd_io() while the loader is trying to figure out if this is GPT or MBR formatted. We're still trying to figure out why the loader sees this incorrect geometry. But meanwhile, this patch fixes the issue, and I wonder if it would be a useful safety-belt for other devices where an incorrect geometry can be seen? Thanks, matthew Index: i386/libi386/biosdisk.c =================================================================== --- i386/libi386/biosdisk.c (.../head/src/sys/boot) (revision 172978) +++ i386/libi386/biosdisk.c (.../branches/BR_BUG_73454/src/sys/boot) (revision 172978) @@ -2064,30 +2064,38 @@ bd_getgeom(struct open_disk *od) v86.addr = 0x13; v86.eax = 0x800; v86.edx = od->od_unit; v86int(); if ((v86.efl & 0x1) || /* carry set */ ((v86.edx & 0xff) <= (unsigned)(od->od_unit & 0x7f))) /* unit # bad */ return(1); /* convert max cyl # -> # of cylinders */ od->od_cyl = ((v86.ecx & 0xc0) << 2) + ((v86.ecx & 0xff00) >> 8) + 1; /* convert max head # -> # of heads */ od->od_hds = ((v86.edx & 0xff00) >> 8) + 1; od->od_sec = v86.ecx & 0x3f; + if (od->od_sec == 0) { + printf("Bad disk geometry on unit %d, bios unit %d, chs %d/%d/%d\n", + od->od_dkunit, od->od_unit, od->od_cyl, od->od_hds, od->od_sec); + return (1); + } + DEBUG("unit 0x%x geometry %d/%d/%d", od->od_unit, od->od_cyl, od->od_hds, od->od_sec); return(0); } /* * Return the BIOS geometry of a given "fixed drive" in a format * suitable for the legacy bootinfo structure. Since the kernel is * expecting raw int 0x13/0x8 values for N_BIOS_GEOM drives, we * prefer to get the information directly, rather than rely on being * able to put it together from information already maintained for * different purposes and for a probably different number of drives. * * For valid drives, the geometry is expected in the format (31..0) * "000000cc cccccccc hhhhhhhh 00ssssss"; and invalid drives are * indicated by returning the geometry of a "1.2M" PC-format floppy