From smp@rick.systemsix.com  Mon Sep  9 16:23:17 1996
Received: from rick.systemsix.com (rick.systemsix.com [198.99.86.136])
          by freefall.freebsd.org (8.7.5/8.7.3) with ESMTP id QAA28399
          for <FreeBSD-gnats-submit@freebsd.org>; Mon, 9 Sep 1996 16:23:15 -0700 (PDT)
Received: (from smp@localhost) by rick.systemsix.com (8.7.5/8.7.3) id RAA03816; Mon, 9 Sep 1996 17:23:57 -0600 (MDT)
Message-Id: <199609092323.RAA03816@rick.systemsix.com>
Date: Mon, 9 Sep 1996 17:23:57 -0600 (MDT)
From: smp@csn.net
Reply-To: smp@csn.net
To: FreeBSD-gnats-submit@freebsd.org
Subject: SMP kernel fix 960909.2
X-Send-Pr-Version: 3.2

>Number:         1592
>Category:       kern
>Synopsis:       kernel incorrectly reads CPU # from APIC ID register
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:
>Keywords:
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Sep  9 16:30:01 PDT 1996
>Closed-Date:    Wed Sep 11 15:43:40 PDT 1996
>Last-Modified:  Wed Sep 11 15:44:16 PDT 1996
>Originator:     Steve Passe
>Release:        FreeBSD 2.2-CURRENT i386
>Organization:
New Ideas
>Environment:

	smp-sys as of August 27, 1996
	Intel XXPRESS motherboard.

>Description:

	The kernel determines the 'number' of the current CPU by
	reading the 'local APIC ID Register' and masking off the high
	byte (ie 8 bits) of this 32 bit register.  In the 80489
	discrete APIC this is an 8-bit field, but in the P5
	integrated APIC, it is only a 4-bit field.  Although the
	data book shows the high nibble being zero-ed out on reset,
	experiments with the Intel XXPRESS motherboard suggests otherwise.
	There are also other modes where this register becomes a bitfield
	as oppossed to a discrete number.  Since extra bits are sometime
	set in the high nibble the code fails to detect the proper CPU #.

>How-To-Repeat:

	not relevant.

>Fix:
	
	1: in include/apic.h:

	#define APIC_ID_FIELD	0x0f000000

	2: change all places that mask off this field, typically:

 	andl	$0xff000000,%e?x

	to:

 	andl	$APIC_ID_FIELD,%e?x

	these places are:

	i386/i386/locore.s, line 268
	i386/i386/swtch.s, line 452
	i386/i386/mplock.s, lines 48, 59, 87, and 99

	3: fix cpunumber() in i386/include/smp.h:

	change line 25:

	return (apic_base[APIC_ID] >> 24);

	to:

	return ((apic_base[APIC_ID] & APIC_ID_FIELD) >> 24);

	4: fix  macro in i386/include/smpasm.h:

	change: lines 9-12

	#define GETCPUID(reg)	\
		movl _apic_base, reg; \
		movl APIC_ID(reg), reg; \
		shrl $24, reg 

	to:

	#define GETCPUID(reg)		\
	 	movl _apic_base, reg;	\
 		movl APIC_ID(reg), reg;	\
	 	shrl $24, reg;		\
 		andl $0xf, reg
>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->closed 
State-Changed-By: peter 
State-Changed-When: Wed Sep 11 15:43:40 PDT 1996 
State-Changed-Why:  
Suggested fix applied (with tweaks :-), thanks! 
>Unformatted:
