MFC r281915:

Make vpanic() externally visible.

MFC r281916:
Fix DTrace's panic() action.
This commit is contained in:
markj 2015-05-29 04:01:39 +00:00
parent aff03409ef
commit 9bbe24351d
10 changed files with 13 additions and 463 deletions

View File

@ -1002,6 +1002,7 @@ MLINKS+=mutex.9 mtx_assert.9 \
mutex.9 mtx_unlock_spin_flags.9
MLINKS+=namei.9 NDFREE.9 \
namei.9 NDINIT.9
MLINKS+=panic.9 vpanic.9
MLINKS+=pbuf.9 getpbuf.9 \
pbuf.9 relpbuf.9 \
pbuf.9 trypbuf.9

View File

@ -31,7 +31,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd August 11, 1995
.Dd April 23, 2015
.Dt PANIC 9
.Os
.Sh NAME
@ -42,10 +42,14 @@
.In sys/systm.h
.Ft void
.Fn panic "const char *fmt" ...
.Ft void
.Fn vpanic "const char *fmt" "va_list ap"
.Sh DESCRIPTION
The
.Fn panic
function terminates the running system.
and
.Fn vpanic
functions terminate the running system.
The message
.Fa fmt
is a

View File

@ -606,7 +606,11 @@ dtrace_panic(const char *format, ...)
va_list alist;
va_start(alist, format);
#ifdef __FreeBSD__
vpanic(format, alist);
#else
dtrace_vpanic(format, alist);
#endif
va_end(alist);
}

View File

@ -363,211 +363,3 @@ dtrace_interrupt_enable(dtrace_icookie_t cookie)
popfq
ret
END(dtrace_interrupt_enable)
/*
* The panic() and cmn_err() functions invoke vpanic() as a common entry point
* into the panic code implemented in panicsys(). vpanic() is responsible
* for passing through the format string and arguments, and constructing a
* regs structure on the stack into which it saves the current register
* values. If we are not dying due to a fatal trap, these registers will
* then be preserved in panicbuf as the current processor state. Before
* invoking panicsys(), vpanic() activates the first panic trigger (see
* common/os/panic.c) and switches to the panic_stack if successful. Note that
* DTrace takes a slightly different panic path if it must panic from probe
* context. Instead of calling panic, it calls into dtrace_vpanic(), which
* sets up the initial stack as vpanic does, calls dtrace_panic_trigger(), and
* branches back into vpanic().
*/
/*
void
vpanic(const char *format, va_list alist)
*/
ENTRY(vpanic) /* Initial stack layout: */
pushq %rbp /* | %rip | 0x60 */
movq %rsp, %rbp /* | %rbp | 0x58 */
pushfq /* | rfl | 0x50 */
pushq %r11 /* | %r11 | 0x48 */
pushq %r10 /* | %r10 | 0x40 */
pushq %rbx /* | %rbx | 0x38 */
pushq %rax /* | %rax | 0x30 */
pushq %r9 /* | %r9 | 0x28 */
pushq %r8 /* | %r8 | 0x20 */
pushq %rcx /* | %rcx | 0x18 */
pushq %rdx /* | %rdx | 0x10 */
pushq %rsi /* | %rsi | 0x8 alist */
pushq %rdi /* | %rdi | 0x0 format */
movq %rsp, %rbx /* %rbx = current %rsp */
leaq panic_quiesce(%rip), %rdi /* %rdi = &panic_quiesce */
call panic_trigger /* %eax = panic_trigger() */
vpanic_common:
/*
* The panic_trigger result is in %eax from the call above, and
* dtrace_panic places it in %eax before branching here.
* The rdmsr instructions that follow below will clobber %eax so
* we stash the panic_trigger result in %r11d.
*/
movl %eax, %r11d
cmpl $0, %r11d
je 0f
/*
* If panic_trigger() was successful, we are the first to initiate a
* panic: we now switch to the reserved panic_stack before continuing.
*/
leaq panic_stack(%rip), %rsp
addq $PANICSTKSIZE, %rsp
0: subq $REGSIZE, %rsp
/*
* Now that we've got everything set up, store the register values as
* they were when we entered vpanic() to the designated location in
* the regs structure we allocated on the stack.
*/
#ifdef notyet
movq 0x0(%rbx), %rcx
movq %rcx, REGOFF_RDI(%rsp)
movq 0x8(%rbx), %rcx
movq %rcx, REGOFF_RSI(%rsp)
movq 0x10(%rbx), %rcx
movq %rcx, REGOFF_RDX(%rsp)
movq 0x18(%rbx), %rcx
movq %rcx, REGOFF_RCX(%rsp)
movq 0x20(%rbx), %rcx
movq %rcx, REGOFF_R8(%rsp)
movq 0x28(%rbx), %rcx
movq %rcx, REGOFF_R9(%rsp)
movq 0x30(%rbx), %rcx
movq %rcx, REGOFF_RAX(%rsp)
movq 0x38(%rbx), %rcx
movq %rcx, REGOFF_RBX(%rsp)
movq 0x58(%rbx), %rcx
movq %rcx, REGOFF_RBP(%rsp)
movq 0x40(%rbx), %rcx
movq %rcx, REGOFF_R10(%rsp)
movq 0x48(%rbx), %rcx
movq %rcx, REGOFF_R11(%rsp)
movq %r12, REGOFF_R12(%rsp)
movq %r13, REGOFF_R13(%rsp)
movq %r14, REGOFF_R14(%rsp)
movq %r15, REGOFF_R15(%rsp)
xorl %ecx, %ecx
movw %ds, %cx
movq %rcx, REGOFF_DS(%rsp)
movw %es, %cx
movq %rcx, REGOFF_ES(%rsp)
movw %fs, %cx
movq %rcx, REGOFF_FS(%rsp)
movw %gs, %cx
movq %rcx, REGOFF_GS(%rsp)
movq $0, REGOFF_TRAPNO(%rsp)
movq $0, REGOFF_ERR(%rsp)
leaq vpanic(%rip), %rcx
movq %rcx, REGOFF_RIP(%rsp)
movw %cs, %cx
movzwq %cx, %rcx
movq %rcx, REGOFF_CS(%rsp)
movq 0x50(%rbx), %rcx
movq %rcx, REGOFF_RFL(%rsp)
movq %rbx, %rcx
addq $0x60, %rcx
movq %rcx, REGOFF_RSP(%rsp)
movw %ss, %cx
movzwq %cx, %rcx
movq %rcx, REGOFF_SS(%rsp)
/*
* panicsys(format, alist, rp, on_panic_stack)
*/
movq REGOFF_RDI(%rsp), %rdi /* format */
movq REGOFF_RSI(%rsp), %rsi /* alist */
movq %rsp, %rdx /* struct regs */
movl %r11d, %ecx /* on_panic_stack */
call panicsys
addq $REGSIZE, %rsp
#endif
popq %rdi
popq %rsi
popq %rdx
popq %rcx
popq %r8
popq %r9
popq %rax
popq %rbx
popq %r10
popq %r11
popfq
leave
ret
END(vpanic)
/*
void
dtrace_vpanic(const char *format, va_list alist)
*/
ENTRY(dtrace_vpanic) /* Initial stack layout: */
pushq %rbp /* | %rip | 0x60 */
movq %rsp, %rbp /* | %rbp | 0x58 */
pushfq /* | rfl | 0x50 */
pushq %r11 /* | %r11 | 0x48 */
pushq %r10 /* | %r10 | 0x40 */
pushq %rbx /* | %rbx | 0x38 */
pushq %rax /* | %rax | 0x30 */
pushq %r9 /* | %r9 | 0x28 */
pushq %r8 /* | %r8 | 0x20 */
pushq %rcx /* | %rcx | 0x18 */
pushq %rdx /* | %rdx | 0x10 */
pushq %rsi /* | %rsi | 0x8 alist */
pushq %rdi /* | %rdi | 0x0 format */
movq %rsp, %rbx /* %rbx = current %rsp */
leaq panic_quiesce(%rip), %rdi /* %rdi = &panic_quiesce */
call dtrace_panic_trigger /* %eax = dtrace_panic_trigger() */
jmp vpanic_common
END(dtrace_vpanic)
/*
int
panic_trigger(int *tp)
*/
ENTRY(panic_trigger)
xorl %eax, %eax
movl $0xdefacedd, %edx
lock
xchgl %edx, (%rdi)
cmpl $0, %edx
je 0f
movl $0, %eax
ret
0: movl $1, %eax
ret
END(panic_trigger)
/*
int
dtrace_panic_trigger(int *tp)
*/
ENTRY(dtrace_panic_trigger)
xorl %eax, %eax
movl $0xdefacedd, %edx
lock
xchgl %edx, (%rdi)
cmpl $0, %edx
je 0f
movl $0, %eax
ret
0: movl $1, %eax
ret
END(dtrace_panic_trigger)

View File

@ -3,9 +3,6 @@
dtrace_cacheid_t dtrace_predcache_id;
int panic_quiesce;
char panic_stack[PANICSTKSIZE];
boolean_t
priv_policy_only(const cred_t *a, int b, boolean_t c)
{

View File

@ -355,167 +355,3 @@ void dtrace_interrupt_enable(dtrace_icookie_t cookie)
popfl
ret
END(dtrace_interrupt_enable)
/*
* The panic() and cmn_err() functions invoke vpanic() as a common entry point
* into the panic code implemented in panicsys(). vpanic() is responsible
* for passing through the format string and arguments, and constructing a
* regs structure on the stack into which it saves the current register
* values. If we are not dying due to a fatal trap, these registers will
* then be preserved in panicbuf as the current processor state. Before
* invoking panicsys(), vpanic() activates the first panic trigger (see
* common/os/panic.c) and switches to the panic_stack if successful. Note that
* DTrace takes a slightly different panic path if it must panic from probe
* context. Instead of calling panic, it calls into dtrace_vpanic(), which
* sets up the initial stack as vpanic does, calls dtrace_panic_trigger(), and
* branches back into vpanic().
*/
/*
void vpanic(const char *format, va_list alist)
*/
ENTRY(vpanic) /* Initial stack layout: */
pushl %ebp /* | %eip | 20 */
movl %esp, %ebp /* | %ebp | 16 */
pushl %eax /* | %eax | 12 */
pushl %ebx /* | %ebx | 8 */
pushl %ecx /* | %ecx | 4 */
pushl %edx /* | %edx | 0 */
movl %esp, %ebx /* %ebx = current stack pointer */
lea panic_quiesce, %eax /* %eax = &panic_quiesce */
pushl %eax /* push &panic_quiesce */
call panic_trigger /* %eax = panic_trigger() */
addl $4, %esp /* reset stack pointer */
vpanic_common:
cmpl $0, %eax /* if (%eax == 0) */
je 0f /* goto 0f; */
/*
* If panic_trigger() was successful, we are the first to initiate a
* panic: we now switch to the reserved panic_stack before continuing.
*/
lea panic_stack, %esp /* %esp = panic_stack */
addl $PANICSTKSIZE, %esp /* %esp += PANICSTKSIZE */
0: subl $REGSIZE, %esp /* allocate struct regs */
/*
* Now that we've got everything set up, store the register values as
* they were when we entered vpanic() to the designated location in
* the regs structure we allocated on the stack.
*/
#ifdef notyet
mov %gs, %edx
mov %edx, REGOFF_GS(%esp)
mov %fs, %edx
mov %edx, REGOFF_FS(%esp)
mov %es, %edx
mov %edx, REGOFF_ES(%esp)
mov %ds, %edx
mov %edx, REGOFF_DS(%esp)
movl %edi, REGOFF_EDI(%esp)
movl %esi, REGOFF_ESI(%esp)
movl 16(%ebx), %ecx
movl %ecx, REGOFF_EBP(%esp)
movl %ebx, %ecx
addl $20, %ecx
movl %ecx, REGOFF_ESP(%esp)
movl 8(%ebx), %ecx
movl %ecx, REGOFF_EBX(%esp)
movl 0(%ebx), %ecx
movl %ecx, REGOFF_EDX(%esp)
movl 4(%ebx), %ecx
movl %ecx, REGOFF_ECX(%esp)
movl 12(%ebx), %ecx
movl %ecx, REGOFF_EAX(%esp)
movl $0, REGOFF_TRAPNO(%esp)
movl $0, REGOFF_ERR(%esp)
lea vpanic, %ecx
movl %ecx, REGOFF_EIP(%esp)
mov %cs, %edx
movl %edx, REGOFF_CS(%esp)
pushfl
popl %ecx
movl %ecx, REGOFF_EFL(%esp)
movl $0, REGOFF_UESP(%esp)
mov %ss, %edx
movl %edx, REGOFF_SS(%esp)
movl %esp, %ecx /* %ecx = &regs */
pushl %eax /* push on_panic_stack */
pushl %ecx /* push &regs */
movl 12(%ebp), %ecx /* %ecx = alist */
pushl %ecx /* push alist */
movl 8(%ebp), %ecx /* %ecx = format */
pushl %ecx /* push format */
call panicsys /* panicsys(); */
addl $16, %esp /* pop arguments */
addl $REGSIZE, %esp
#endif
popl %edx
popl %ecx
popl %ebx
popl %eax
leave
ret
END(vpanic)
/*
void dtrace_vpanic(const char *format, va_list alist)
*/
ENTRY(dtrace_vpanic) /* Initial stack layout: */
pushl %ebp /* | %eip | 20 */
movl %esp, %ebp /* | %ebp | 16 */
pushl %eax /* | %eax | 12 */
pushl %ebx /* | %ebx | 8 */
pushl %ecx /* | %ecx | 4 */
pushl %edx /* | %edx | 0 */
movl %esp, %ebx /* %ebx = current stack pointer */
lea panic_quiesce, %eax /* %eax = &panic_quiesce */
pushl %eax /* push &panic_quiesce */
call dtrace_panic_trigger /* %eax = dtrace_panic_trigger() */
addl $4, %esp /* reset stack pointer */
jmp vpanic_common /* jump back to common code */
END(dtrace_vpanic)
/*
int
panic_trigger(int *tp)
*/
ENTRY(panic_trigger)
xorl %eax, %eax
movl $0xdefacedd, %edx
lock
xchgl %edx, (%edi)
cmpl $0, %edx
je 0f
movl $0, %eax
ret
0: movl $1, %eax
ret
END(panic_trigger)
/*
int
dtrace_panic_trigger(int *tp)
*/
ENTRY(dtrace_panic_trigger)
xorl %eax, %eax
movl $0xdefacedd, %edx
lock
xchgl %edx, (%edi)
cmpl $0, %edx
je 0f
movl $0, %eax
ret
0: movl $1, %eax
ret
END(dtrace_panic_trigger)

View File

@ -248,49 +248,6 @@ LEAF(dtrace_invop_uninit)
nop
END(dtrace_invop_uninit)
/*
* The panic() and cmn_err() functions invoke vpanic() as a common entry point
* into the panic code implemented in panicsys(). vpanic() is responsible
* for passing through the format string and arguments, and constructing a
* regs structure on the stack into which it saves the current register
* values. If we are not dying due to a fatal trap, these registers will
* then be preserved in panicbuf as the current processor state. Before
* invoking panicsys(), vpanic() activates the first panic trigger (see
* common/os/panic.c) and switches to the panic_stack if successful. Note that
* DTrace takes a slightly different panic path if it must panic from probe
* context. Instead of calling panic, it calls into dtrace_vpanic(), which
* sets up the initial stack as vpanic does, calls dtrace_panic_trigger(), and
* branches back into vpanic().
*/
/*
void
vpanic(const char *format, va_list alist)
*/
LEAF(vpanic) /* Initial stack layout: */
vpanic_common:
j ra
nop
END(vpanic)
/*
void
dtrace_vpanic(const char *format, va_list alist)
*/
LEAF(dtrace_vpanic) /* Initial stack layout: */
#if 0
jal dtrace_panic_trigger /* %eax = dtrace_panic_trigger() */
nop
#endif
j vpanic_common
nop
END(dtrace_vpanic)
/*
uintptr_t
dtrace_caller(int aframes)
@ -300,4 +257,3 @@ LEAF(dtrace_caller)
j ra
nop
END(dtrace_caller)

View File

@ -160,45 +160,6 @@ ASENTRY_NOPROF(dtrace_copystr)
blr
END(dtrace_copystr)
/*
* The panic() and cmn_err() functions invoke vpanic() as a common entry point
* into the panic code implemented in panicsys(). vpanic() is responsible
* for passing through the format string and arguments, and constructing a
* regs structure on the stack into which it saves the current register
* values. If we are not dying due to a fatal trap, these registers will
* then be preserved in panicbuf as the current processor state. Before
* invoking panicsys(), vpanic() activates the first panic trigger (see
* common/os/panic.c) and switches to the panic_stack if successful. Note that
* DTrace takes a slightly different panic path if it must panic from probe
* context. Instead of calling panic, it calls into dtrace_vpanic(), which
* sets up the initial stack as vpanic does, calls dtrace_panic_trigger(), and
* branches back into vpanic().
*/
/*
void
vpanic(const char *format, va_list alist)
*/
ASENTRY_NOPROF(vpanic) /* Initial stack layout: */
vpanic_common:
blr
END(vpanic)
/*
void
dtrace_vpanic(const char *format, va_list alist)
*/
ASENTRY_NOPROF(dtrace_vpanic) /* Initial stack layout: */
#if 0
bl dtrace_panic_trigger /* %eax = dtrace_panic_trigger() */
#endif
b vpanic_common
END(dtrace_vpanic)
/*
uintptr_t
dtrace_caller(int aframes)
@ -207,4 +168,3 @@ ASENTRY_NOPROF(dtrace_caller)
li %r3, -1
blr
END(dtrace_caller)

View File

@ -157,7 +157,6 @@ static void poweroff_wait(void *, int);
static void shutdown_halt(void *junk, int howto);
static void shutdown_panic(void *junk, int howto);
static void shutdown_reset(void *junk, int howto);
static void vpanic(const char *fmt, va_list ap) __dead2;
/* register various local shutdown events */
static void
@ -688,7 +687,7 @@ panic(const char *fmt, ...)
vpanic(fmt, ap);
}
static void
void
vpanic(const char *fmt, va_list ap)
{
#ifdef SMP

View File

@ -187,6 +187,7 @@ void *phashinit(int count, struct malloc_type *type, u_long *nentries);
void g_waitidle(void);
void panic(const char *, ...) __dead2 __printflike(1, 2);
void vpanic(const char *, __va_list) __dead2 __printflike(1, 0);
void cpu_boot(int);
void cpu_flush_dcache(void *, size_t);