Subject: port-i386/8120: cpu_reset() is unreliable
To: None <gnats-bugs@gnats.netbsd.org>
From: Ed Gould <ed@pa.dec.com>
List: netbsd-bugs
Date: 07/30/1999 11:21:01
>Number:         8120
>Category:       port-i386
>Synopsis:       cpu_reset() is unreliable
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    port-i386-maintainer (NetBSD/i386 Portmaster)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Jul 30 11:20:01 1999
>Last-Modified:
>Originator:     Ed Gould
>Organization:
--
Ed Gould	 Palo Alto Advanced Development	 Compaq Computer Corp.
+1 650 853 2108	 ed@pa.dec.com			 130 Lytton Avenue
		 ed.gould@compaq.com		 Palo Alto, CA 94301
>Release:        20 July 1999
>Environment:
System: NetBSD toblerone.pa.dec.com 1.4G NetBSD 1.4G (TOBLERONE) #22: Wed Jul 28 11:35:27 PDT 1999 ed@toblerone.pa.dec.com:/usr/src/current/sys/arch/i386/compile/TOBLERONE i386


>Description:
	System reboot on a Digital Celebris GL 6200 (200 MHz Pentium Pro)
	is unreliable.  The code in 1.3.2 worked well.
>How-To-Repeat:
	reboot(8) many times.  Sometimes it works, sometimes it hangs forever.
>Fix:
    The code in 1.4 is

        /*
         * Try to cause a triple fault and watchdog reset by making the IDT
         * invalid and causing a fault.
         */
        memset((caddr_t)idt, 0, NIDT * sizeof(idt[0]));
        __asm __volatile("divl %0,%1" : : "q" (0), "a" (0));

    The code in 1.3.2 that's different was

        /*
         * Try to cause a triple fault and watchdog reset by making the IDT
         * invalid and causing a fault.
         */
        bzero((caddr_t)idt, NIDT * sizeof(idt[0]));
        setregion(&region, idt, NIDT * sizeof(idt[0]) - 1);
        lidt(&region);
        __asm __volatile("divl %0,%1" : : "q" (0), "a" (0));


    If the 1.3.2 method is still valid, use it.  Otherwise, find a
    real fix.  I don't know the VM code at all, so I don't know if the
    old code will still work.
>Audit-Trail:
>Unformatted: