NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/38599: panic crashes in early bootstrap



>Number:         38599
>Category:       kern
>Synopsis:       panic crashes in early bootstrap
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue May 06 21:25:00 +0000 2008
>Originator:     Michael van Elst
>Release:        NetBSD 4.0_STABLE
>Organization:
-- 
                                Michael van Elst
Internet: mlelstv%serpens.de@localhost
                                "A potential Snark may lurk in every tree."
>Environment:
        
        
System: ELF 64-bit MSB executable, SPARC V9, version 1 (SYSV), statically 
linked, for NetBSD 4.99.62, not stripped
Architecture: sparc64
Machine: sparc64
>Description:
When panic is called early in bootstrap it crashes on a GENERIC kernel.
The reason is that it accesses curlwp and curcpu() to be safe on
multiprocessors. Those data structures haven't been initialized and
on sparc64 not even mapped before pmap_bootstrap() has run.

A panic in pmap_bootstrap() or earlier will therefore crash instead
of emitting a useful panic message.

>How-To-Repeat:
Try to boot a sparc64 kernel on a T2000.

>Fix:
Make the curlwp accesses conditional on wether the data
structures have been initialized. The first thing main()
does is initializing lwp0.l_cpu (unless LWP0_CPU_INFO
is #defined), therefore a possible check would be:

        if (lwp0.l_cpu && curlwp) {
                /*
                 * Disable preemption.  If already panicing on another CPU, sit
                 * here and spin until the system is rebooted.  Allow the CPU th
at
                 * first paniced to panic again.
                 */
                kpreempt_disable();
                ci = curcpu();
                oci = atomic_cas_ptr((void *)&paniccpu, NULL, ci);
                if (oci != NULL && oci != ci) {
                        /* Give interrupts a chance to try and prevent deadlock.
 */
                        spl0();
                        for (;;) {
                                DELAY(10);
                        }
                }

                /*
                 * Convert the current thread to a bound thread and prevent all
                 * CPUs from scheduling unbound jobs.  Do so without taking any
                 * locks.
                 */
                curlwp->l_pflag |= LP_BOUND;
                for (CPU_INFO_FOREACH(cii, ci)) {
                        ci->ci_schedstate.spc_flags |= SPCF_OFFLINE;
                }
        }

>Unformatted:
        
        


Home | Main Index | Thread Index | Old Index