From Cy.Schubert@komquats.com  Tue Feb  7 17:02:53 2006
Return-Path: <Cy.Schubert@komquats.com>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 0E87A16A423
	for <FreeBSD-gnats-submit@FreeBSD.org>; Tue,  7 Feb 2006 17:02:53 +0000 (GMT)
	(envelope-from Cy.Schubert@komquats.com)
Received: from spqr.komquats.com (S0106002078125c0c.gv.shawcable.net [24.108.150.239])
	by mx1.FreeBSD.org (Postfix) with ESMTP id C8A1D43D49
	for <FreeBSD-gnats-submit@FreeBSD.org>; Tue,  7 Feb 2006 17:02:51 +0000 (GMT)
	(envelope-from Cy.Schubert@komquats.com)
Received: from cwsys.cwsent.com (cwsys [10.1.1.1])
	by spqr.komquats.com (Postfix) with ESMTP id 10A834C5C5
	for <FreeBSD-gnats-submit@FreeBSD.org>; Tue,  7 Feb 2006 09:02:50 -0800 (PST)
Received: from cwsys.cwsent.com (localhost [127.0.0.1])
	by cwsys.cwsent.com (8.13.4/8.13.4) with ESMTP id k17H2nHt048942
	for <FreeBSD-gnats-submit@FreeBSD.org>; Tue, 7 Feb 2006 09:02:49 -0800 (PST)
	(envelope-from Cy.Schubert@komquats.com)
Received: (from cy@localhost)
	by cwsys.cwsent.com (8.13.4/8.13.1/Submit) id k17H2nVW048924;
	Tue, 7 Feb 2006 09:02:49 -0800 (PST)
	(envelope-from cy)
Message-Id: <200602071702.k17H2nVW048924@cwsys.cwsent.com>
Date: Tue, 7 Feb 2006 09:02:49 -0800 (PST)
From: Cy Schubert <cy@FreeBSD.org>
Reply-To: Cy Schubert <cy@FreeBSD.org>
To: FreeBSD-gnats-submit@FreeBSD.org
Cc:
Subject: virutal infinite loop in identcpu.c
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         92977
>Category:       i386
>Synopsis:       virutal infinite loop in identcpu.c
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    yar
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Feb 07 17:10:03 GMT 2006
>Closed-Date:    Thu Feb 09 09:13:22 GMT 2006
>Last-Modified:  Thu Feb 09 09:13:22 GMT 2006
>Originator:     Cy Schubert
>Release:        FreeBSD-2.0
>Organization:
FreeBSD
>Environment:
System: FreeBSD cwsys 7.0-CURRENT FreeBSD 7.0-CURRENT #0: Fri Jan 27 13:49:18 PST 2006 root@cwsys:/export/obj/opt/src/cvs-current/src/sys/GENERIC


>Description:
 I'm experiencing the following hang on my -CURRENT testbed (which also 
 serves as a 4.11, 5.4, and 6.0 testbed). Only under 7.0-CURRENT does it 
 hang during boot using a stock out of the box GENERIC kernel. The machine 
 is an old P120. Any ideas?
 
 OK include /boot/cwtest/foobar
 |
 
 cwtest.foobar loader file selected
 unload complete
 currdev set to disk2s1a:
 /boot/kernel/kernel text=0x4e15c4 data=0x84900+0xa026c 
 syms=[0x4+0x67ea0+0x4+0x7f4ff]
 new kernel has been loaded
 
 OK boot -s
 GDB: no debug ports present
 KDB: debugger backends: ddb
 KDB: current backend: ddb
 Copyright (c) 1992-2006 The FreeBSD Project.
 Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
         The Regents of the University of California. All rights reserved.
 FreeBSD 7.0-CURRENT #0: Fri Jan 27 13:49:18 PST 2006
     root@cwsys:/export/obj/opt/src/cvs-current/src/sys/GENERIC
 WARNING: WITNESS option enabled, expect reduced performance.
 
 At this point I need to reset the machine.
precise description of the problem (multiple lines)>
>How-To-Repeat:
 See description.
>Fix:

I identified the problem (see my original discussion about this in attached 
the email below).

On the Pentium P54C model (that's an old 120 MHz Pentium I use as a 4.x, 
5.x, and 7.x ports build testbed) the CPUID instruction when called with AL 
= 0x02, CPUID returns EAX = EBX = ECX = EDX = 0. The code fragment in 
identcpu.c below results in "rounds" becoming 0xffffffff.

	do_cpuid(0x2, regs);
	rounds = (regs[0] & 0xff) - 1;

The subsequent loop of the following will loop virtually for ever (it takes 
forever tor this machine to count down from 0xffffffff performing a very 
great many calls to get_INTEL_TLB in the process, virtually hanging the 
machine in the process.

	while (rounds > 0) {
		[... code ...]
		rounds--;
	}

To resolve my problem I cobbled up the following patch to identcpu.c:

--- sys/i386/i386/identcpu.c.orig	Thu Feb  2 04:44:09 2006
+++ sys/i386/i386/identcpu.c	Mon Feb  6 18:47:16 2006
@@ -1237,7 +1237,7 @@
 
 	do_cpuid(0x2, regs);
 
-	rounds = (regs[0] & 0xff) - 1;
+	rounds = (regs[0] & 0xff);
 
 	for (regnum = 0; regnum <= 3; ++regnum) {
 		if ((regs[regnum] & (1<<31)) == 0) {
@@ -1249,7 +1249,7 @@
 		}
 	}
 
-	while (rounds > 0) {
+	while (rounds > 1) {
 		do_cpuid(0x2, regs);
 
 		for (regnum = 0; regnum <= 3; ++regnum) {
@@ -1452,7 +1452,7 @@
 	u_int nwaycode;
 
 	do_cpuid(0x2, regs);
-	rounds = (regs[0] & 0xff) - 1;
+	rounds = (regs[0] & 0xff);
 
 	for (regnum = 0; regnum <= 3; ++regnum) {
 		if ((regs[regnum] & (1<<31)) == 0) {
@@ -1468,7 +1468,7 @@
 		}
 	}
 
-	while (rounds > 0) {
+	while (rounds > 1) {
 		do_cpuid(0x2, regs);
 
 		for (regnum = 0; regnum <= 3; ++regnum) {

It fixes the hang.



>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->closed 
State-Changed-By: yar 
State-Changed-When: Thu Feb 9 09:07:46 UTC 2006 
State-Changed-Why:  
CURRENT fixed, thanks! 
(The bug wasn't in other branches.) 


Responsible-Changed-From-To: freebsd-i386->yar 
Responsible-Changed-By: yar 
Responsible-Changed-When: Thu Feb 9 09:07:46 UTC 2006 
Responsible-Changed-Why:  
I fixed this so I'd like to see feedback. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=92977 
>Unformatted:
