usr/src/uts/common/os/panic.c
author jpk
Fri, 24 Mar 2006 12:29:20 -0800
changeset 1676 37f4a3e2bd99
parent 1414 b4126407ac5b
child 5084 7d838c5c0eed
permissions -rw-r--r--
PSARC/2002/762 Layered Trusted Solaris PSARC/2005/060 TSNET: Trusted Networking with Security Labels PSARC/2005/259 Layered Trusted Solaris Label Interfaces PSARC/2005/573 Solaris Trusted Extensions for Printing PSARC/2005/691 Trusted Extensions for Device Allocation PSARC/2005/723 Solaris Trusted Extensions Filesystem Labeling PSARC/2006/009 Labeled Auditing PSARC/2006/155 Trusted Extensions RBAC Changes PSARC/2006/191 is_system_labeled 6293271 Zone processes should use zone_kcred instead of kcred 6394554 integrate Solaris Trusted Extensions
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     1
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     2
 * CDDL HEADER START
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     3
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     5
 * Common Development and Distribution License, Version 1.0 only
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     6
 * (the "License").  You may not use this file except in compliance
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     7
 * with the License.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     8
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     9
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    10
 * or http://www.opensolaris.org/os/licensing.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    11
 * See the License for the specific language governing permissions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    12
 * and limitations under the License.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    13
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    14
 * When distributing Covered Code, include this CDDL HEADER in each
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    15
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    16
 * If applicable, add the following below this CDDL HEADER, with the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    17
 * fields enclosed by brackets "[]" replaced with your own identifying
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    18
 * information: Portions Copyright [yyyy] [name of copyright owner]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    19
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    20
 * CDDL HEADER END
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    21
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    22
/*
1414
b4126407ac5b PSARC 2006/020 FMA for Athlon 64 and Opteron Processors
cindi
parents: 136
diff changeset
    23
 * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    24
 * Use is subject to license terms.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    25
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    26
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    27
#pragma ident	"%Z%%M%	%I%	%E% SMI"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    28
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    29
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    30
 * When the operating system detects that it is in an invalid state, a panic
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    31
 * is initiated in order to minimize potential damage to user data and to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    32
 * facilitate debugging.  There are three major tasks to be performed in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    33
 * a system panic: recording information about the panic in memory (and thus
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    34
 * making it part of the crash dump), synchronizing the file systems to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    35
 * preserve user file data, and generating the crash dump.  We define the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    36
 * system to be in one of four states with respect to the panic code:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    37
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    38
 * CALM    - the state of the system prior to any thread initiating a panic
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    39
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    40
 * QUIESCE - the state of the system when the first thread to initiate
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    41
 *           a system panic records information about the cause of the panic
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    42
 *           and renders the system quiescent by stopping other processors
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    43
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    44
 * SYNC    - the state of the system when we synchronize the file systems
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    45
 * DUMP    - the state when we generate the crash dump.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    46
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    47
 * The transitions between these states are irreversible: once we begin
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    48
 * panicking, we only make one attempt to perform the actions associated with
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    49
 * each state.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    50
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    51
 * The panic code itself must be re-entrant because actions taken during any
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    52
 * state may lead to another system panic.  Additionally, any Solaris
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    53
 * thread may initiate a panic at any time, and so we must have synchronization
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    54
 * between threads which attempt to initiate a state transition simultaneously.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    55
 * The panic code makes use of a special locking primitive, a trigger, to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    56
 * perform this synchronization.  A trigger is simply a word which is set
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    57
 * atomically and can only be set once.  We declare three triggers, one for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    58
 * each transition between the four states.  When a thread enters the panic
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    59
 * code it attempts to set each trigger; if it fails it moves on to the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    60
 * next trigger.  A special case is the first trigger: if two threads race
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    61
 * to perform the transition to QUIESCE, the losing thread may execute before
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    62
 * the winner has a chance to stop its CPU.  To solve this problem, we have
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    63
 * the loser look ahead to see if any other triggers are set; if not, it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    64
 * presumes a panic is underway and simply spins.  Unfortunately, since we
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    65
 * are panicking, it is not possible to know this with absolute certainty.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    66
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    67
 * There are two common reasons for re-entering the panic code once a panic
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    68
 * has been initiated: (1) after we debug_enter() at the end of QUIESCE,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    69
 * the operator may type "sync" instead of "go", and the PROM's sync callback
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    70
 * routine will invoke panic(); (2) if the clock routine decides that sync
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    71
 * or dump is not making progress, it will invoke panic() to force a timeout.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    72
 * The design assumes that a third possibility, another thread causing an
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    73
 * unrelated panic while sync or dump is still underway, is extremely unlikely.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    74
 * If this situation occurs, we may end up triggering dump while sync is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    75
 * still in progress.  This third case is considered extremely unlikely because
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    76
 * all other CPUs are stopped and low-level interrupts have been blocked.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    77
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    78
 * The panic code is entered via a call directly to the vpanic() function,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    79
 * or its varargs wrappers panic() and cmn_err(9F).  The vpanic routine
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    80
 * is implemented in assembly language to record the current machine
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    81
 * registers, attempt to set the trigger for the QUIESCE state, and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    82
 * if successful, switch stacks on to the panic_stack before calling into
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    83
 * the common panicsys() routine.  The first thread to initiate a panic
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    84
 * is allowed to make use of the reserved panic_stack so that executing
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    85
 * the panic code itself does not overwrite valuable data on that thread's
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    86
 * stack *ahead* of the current stack pointer.  This data will be preserved
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    87
 * in the crash dump and may prove invaluable in determining what this
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    88
 * thread has previously been doing.  The first thread, saved in panic_thread,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    89
 * is also responsible for stopping the other CPUs as quickly as possible,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    90
 * and then setting the various panic_* variables.  Most important among
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    91
 * these is panicstr, which allows threads to subsequently bypass held
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    92
 * locks so that we can proceed without ever blocking.  We must stop the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    93
 * other CPUs *prior* to setting panicstr in case threads running there are
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    94
 * currently spinning to acquire a lock; we want that state to be preserved.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    95
 * Every thread which initiates a panic has its T_PANIC flag set so we can
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    96
 * identify all such threads in the crash dump.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    97
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    98
 * The panic_thread is also allowed to make use of the special memory buffer
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    99
 * panicbuf, which on machines with appropriate hardware is preserved across
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   100
 * reboots.  We allow the panic_thread to store its register set and panic
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   101
 * message in this buffer, so even if we fail to obtain a crash dump we will
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   102
 * be able to examine the machine after reboot and determine some of the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   103
 * state at the time of the panic.  If we do get a dump, the panic buffer
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   104
 * data is structured so that a debugger can easily consume the information
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   105
 * therein (see <sys/panic.h>).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   106
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   107
 * Each platform or architecture is required to implement the functions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   108
 * panic_savetrap() to record trap-specific information to panicbuf,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   109
 * panic_saveregs() to record a register set to panicbuf, panic_stopcpus()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   110
 * to halt all CPUs but the panicking CPU, panic_quiesce_hw() to perform
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   111
 * miscellaneous platform-specific tasks *after* panicstr is set,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   112
 * panic_showtrap() to print trap-specific information to the console,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   113
 * and panic_dump_hw() to perform platform tasks prior to calling dumpsys().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   114
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   115
 * A Note on Word Formation, courtesy of the Oxford Guide to English Usage:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   116
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   117
 * Words ending in -c interpose k before suffixes which otherwise would
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   118
 * indicate a soft c, and thus the verb and adjective forms of 'panic' are
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   119
 * spelled "panicked", "panicking", and "panicky" respectively.  Use of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   120
 * the ill-conceived "panicing" and "panic'd" is discouraged.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   121
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   122
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   123
#include <sys/types.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   124
#include <sys/varargs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   125
#include <sys/sysmacros.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   126
#include <sys/cmn_err.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   127
#include <sys/cpuvar.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   128
#include <sys/thread.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   129
#include <sys/t_lock.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   130
#include <sys/cred.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   131
#include <sys/systm.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   132
#include <sys/uadmin.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   133
#include <sys/callb.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   134
#include <sys/vfs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   135
#include <sys/log.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   136
#include <sys/disp.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   137
#include <sys/param.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   138
#include <sys/dumphdr.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   139
#include <sys/ftrace.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   140
#include <sys/reboot.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   141
#include <sys/debug.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   142
#include <sys/stack.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   143
#include <sys/spl.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   144
#include <sys/errorq.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   145
#include <sys/panic.h>
1414
b4126407ac5b PSARC 2006/020 FMA for Athlon 64 and Opteron Processors
cindi
parents: 136
diff changeset
   146
#include <sys/fm/util.h>
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   147
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   148
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   149
 * Panic variables which are set once during the QUIESCE state by the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   150
 * first thread to initiate a panic.  These are examined by post-mortem
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   151
 * debugging tools; the inconsistent use of 'panic' versus 'panic_' in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   152
 * the variable naming is historical and allows legacy tools to work.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   153
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   154
#pragma align STACK_ALIGN(panic_stack)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   155
char panic_stack[PANICSTKSIZE];		/* reserved stack for panic_thread */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   156
kthread_t *panic_thread;		/* first thread to call panicsys() */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   157
cpu_t panic_cpu;			/* cpu from first call to panicsys() */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   158
label_t panic_regs;			/* setjmp label from panic_thread */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   159
struct regs *panic_reg;			/* regs struct from first panicsys() */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   160
char *volatile panicstr;		/* format string to first panicsys() */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   161
va_list panicargs;			/* arguments to first panicsys() */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   162
clock_t panic_lbolt;			/* lbolt at time of panic */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   163
int64_t panic_lbolt64;			/* lbolt64 at time of panic */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   164
hrtime_t panic_hrtime;			/* hrtime at time of panic */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   165
timespec_t panic_hrestime;		/* hrestime at time of panic */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   166
int panic_ipl;				/* ipl on panic_cpu at time of panic */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   167
ushort_t panic_schedflag;		/* t_schedflag for panic_thread */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   168
cpu_t *panic_bound_cpu;			/* t_bound_cpu for panic_thread */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   169
char panic_preempt;			/* t_preempt for panic_thread */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   170
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   171
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   172
 * Panic variables which can be set via /etc/system or patched while
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   173
 * the system is in operation.  Again, the stupid names are historic.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   174
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   175
char *panic_bootstr = NULL;		/* mdboot string to use after panic */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   176
int panic_bootfcn = AD_BOOT;		/* mdboot function to use after panic */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   177
int halt_on_panic = 0;  		/* halt after dump instead of reboot? */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   178
int nopanicdebug = 0;			/* reboot instead of call debugger? */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   179
int in_sync = 0;			/* skip vfs_syncall() and just dump? */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   180
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   181
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   182
 * The do_polled_io flag is set by the panic code to inform the SCSI subsystem
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   183
 * to use polled mode instead of interrupt-driven i/o.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   184
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   185
int do_polled_io = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   186
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   187
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   188
 * The panic_forced flag is set by the uadmin A_DUMP code to inform the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   189
 * panic subsystem that it should not attempt an initial debug_enter.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   190
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   191
int panic_forced = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   192
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   193
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   194
 * Triggers for panic state transitions:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   195
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   196
int panic_quiesce;			/* trigger for CALM    -> QUIESCE */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   197
int panic_sync;				/* trigger for QUIESCE -> SYNC */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   198
int panic_dump;				/* trigger for SYNC    -> DUMP */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   199
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   200
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   201
panicsys(const char *format, va_list alist, struct regs *rp, int on_panic_stack)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   202
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   203
	int s = spl8();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   204
	kthread_t *t = curthread;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   205
	cpu_t *cp = CPU;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   206
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   207
	caddr_t intr_stack = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   208
	uint_t intr_actv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   209
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   210
	ushort_t schedflag = t->t_schedflag;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   211
	cpu_t *bound_cpu = t->t_bound_cpu;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   212
	char preempt = t->t_preempt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   213
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   214
	(void) setjmp(&t->t_pcb);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   215
	t->t_flag |= T_PANIC;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   216
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   217
	t->t_schedflag |= TS_DONT_SWAP;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   218
	t->t_bound_cpu = cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   219
	t->t_preempt++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   220
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   221
	panic_enter_hw(s);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   222
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   223
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   224
	 * If we're on the interrupt stack and an interrupt thread is available
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   225
	 * in this CPU's pool, preserve the interrupt stack by detaching an
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   226
	 * interrupt thread and making its stack the intr_stack.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   227
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   228
	if (CPU_ON_INTR(cp) && cp->cpu_intr_thread != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   229
		kthread_t *it = cp->cpu_intr_thread;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   230
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   231
		intr_stack = cp->cpu_intr_stack;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   232
		intr_actv = cp->cpu_intr_actv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   233
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   234
		cp->cpu_intr_stack = thread_stk_init(it->t_stk);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   235
		cp->cpu_intr_thread = it->t_link;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   236
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   237
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   238
		 * Clear only the high level bits of cpu_intr_actv.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   239
		 * We want to indicate that high-level interrupts are
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   240
		 * not active without destroying the low-level interrupt
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   241
		 * information stored there.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   242
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   243
		cp->cpu_intr_actv &= ((1 << (LOCK_LEVEL + 1)) - 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   244
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   245
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   246
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   247
	 * Record one-time panic information and quiesce the other CPUs.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   248
	 * Then print out the panic message and stack trace.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   249
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   250
	if (on_panic_stack) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   251
		panic_data_t *pdp = (panic_data_t *)panicbuf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   252
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   253
		pdp->pd_version = PANICBUFVERS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   254
		pdp->pd_msgoff = sizeof (panic_data_t) - sizeof (panic_nv_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   255
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   256
		if (t->t_panic_trap != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   257
			panic_savetrap(pdp, t->t_panic_trap);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   258
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   259
			panic_saveregs(pdp, rp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   260
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   261
		(void) vsnprintf(&panicbuf[pdp->pd_msgoff],
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   262
		    PANICBUFSIZE - pdp->pd_msgoff, format, alist);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   263
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   264
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   265
		 * Call into the platform code to stop the other CPUs.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   266
		 * We currently have all interrupts blocked, and expect that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   267
		 * the platform code will lower ipl only as far as needed to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   268
		 * perform cross-calls, and will acquire as *few* locks as is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   269
		 * possible -- panicstr is not set so we can still deadlock.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   270
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   271
		panic_stopcpus(cp, t, s);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   272
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   273
		panicstr = (char *)format;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   274
		va_copy(panicargs, alist);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   275
		panic_lbolt = lbolt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   276
		panic_lbolt64 = lbolt64;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   277
		panic_hrestime = hrestime;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   278
		panic_hrtime = gethrtime_waitfree();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   279
		panic_thread = t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   280
		panic_regs = t->t_pcb;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   281
		panic_reg = rp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   282
		panic_cpu = *cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   283
		panic_ipl = spltoipl(s);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   284
		panic_schedflag = schedflag;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   285
		panic_bound_cpu = bound_cpu;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   286
		panic_preempt = preempt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   287
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   288
		if (intr_stack != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   289
			panic_cpu.cpu_intr_stack = intr_stack;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   290
			panic_cpu.cpu_intr_actv = intr_actv;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   291
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   292
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   293
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   294
		 * Lower ipl to 10 to keep clock() from running, but allow
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   295
		 * keyboard interrupts to enter the debugger.  These callbacks
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   296
		 * are executed with panicstr set so they can bypass locks.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   297
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   298
		splx(ipltospl(CLOCK_LEVEL));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   299
		panic_quiesce_hw(pdp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   300
		(void) FTRACE_STOP();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   301
		(void) callb_execute_class(CB_CL_PANIC, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   302
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   303
		if (log_intrq != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   304
			log_flushq(log_intrq);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   305
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   306
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   307
		 * If log_consq has been initialized and syslogd has started,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   308
		 * print any messages in log_consq that haven't been consumed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   309
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   310
		if (log_consq != NULL && log_consq != log_backlogq)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   311
			log_printq(log_consq);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   312
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   313
		fm_banner();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   314
		errorq_panic();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   315
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   316
		printf("\n\rpanic[cpu%d]/thread=%p: ", cp->cpu_id, (void *)t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   317
		vprintf(format, alist);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   318
		printf("\n\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   319
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   320
		if (t->t_panic_trap != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   321
			panic_showtrap(t->t_panic_trap);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   322
			printf("\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   323
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   324
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   325
		traceregs(rp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   326
		printf("\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   327
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   328
		if (((boothowto & RB_DEBUG) || obpdebug) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   329
		    !nopanicdebug && !panic_forced) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   330
			if (dumpvp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   331
				debug_enter("panic: entering debugger "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   332
				    "(continue to save dump)");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   333
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   334
				debug_enter("panic: entering debugger "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   335
				    "(no dump device, continue to reboot)");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   336
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   337
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   338
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   339
	} else if (panic_dump != 0 || panic_sync != 0 || panicstr != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   340
		printf("\n\rpanic[cpu%d]/thread=%p: ", cp->cpu_id, (void *)t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   341
		vprintf(format, alist);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   342
		printf("\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   343
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   344
		goto spin;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   345
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   346
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   347
	 * Prior to performing sync or dump, we make sure that do_polled_io is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   348
	 * set, but we'll leave ipl at 10; deadman(), a CY_HIGH_LEVEL cyclic,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   349
	 * will re-enter panic if we are not making progress with sync or dump.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   350
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   351
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   352
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   353
	 * Sync the filesystems.  Reset t_cred if not set because much of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   354
	 * the filesystem code depends on CRED() being valid.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   355
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   356
	if (!in_sync && panic_trigger(&panic_sync)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   357
		if (t->t_cred == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   358
			t->t_cred = kcred;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   359
		splx(ipltospl(CLOCK_LEVEL));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   360
		do_polled_io = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   361
		vfs_syncall();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   362
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   363
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   364
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   365
	 * Take the crash dump.  If the dump trigger is already set, try to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   366
	 * enter the debugger again before rebooting the system.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   367
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   368
	if (panic_trigger(&panic_dump)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   369
		panic_dump_hw(s);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   370
		splx(ipltospl(CLOCK_LEVEL));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   371
		do_polled_io = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   372
		dumpsys();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   373
	} else if (((boothowto & RB_DEBUG) || obpdebug) && !nopanicdebug) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   374
		debug_enter("panic: entering debugger (continue to reboot)");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   375
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   376
		printf("dump aborted: please record the above information!\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   377
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   378
	if (halt_on_panic)
136
19bbb3246a07 4745648 cluster node panics because mdboot takes too much time
achartre
parents: 0
diff changeset
   379
		mdboot(A_REBOOT, AD_HALT, NULL, B_FALSE);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   380
	else
136
19bbb3246a07 4745648 cluster node panics because mdboot takes too much time
achartre
parents: 0
diff changeset
   381
		mdboot(A_REBOOT, panic_bootfcn, panic_bootstr, B_FALSE);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   382
spin:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   383
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   384
	 * Restore ipl to at most CLOCK_LEVEL so we don't end up spinning
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   385
	 * and unable to jump into the debugger.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   386
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   387
	splx(MIN(s, ipltospl(CLOCK_LEVEL)));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   388
	for (;;);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   389
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   390
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   391
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   392
panic(const char *format, ...)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   393
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   394
	va_list alist;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   395
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   396
	va_start(alist, format);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   397
	vpanic(format, alist);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   398
	va_end(alist);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   399
}