Fix DTrace's panic() action.

It would previously call into some unfinished Solaris compatibility code and
return without actually calling panic(9). The compatibility code is
unneeded, however, so just remove it and have dtrace_panic() call vpanic(9)
directly.

Differential Revision:	https://reviews.freebsd.org/D2349
Reviewed by:	avg
MFC after:	2 weeks
Sponsored by:	EMC / Isilon Storage Division
This commit is contained in:
Mark Johnston 2015-04-24 03:19:30 +00:00
parent da10a60340
commit 8241ee3b2c
7 changed files with 4 additions and 477 deletions

View file

@ -611,7 +611,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

@ -169,24 +169,6 @@ ENTRY(dtrace_copystr)
RET
END(dtrace_copystr)
/*
void
vpanic(const char *format, va_list alist)
*/
ENTRY(vpanic) /* Initial stack layout: */
vpanic_common:
RET
END(vpanic)
/*
void
dtrace_vpanic(const char *format, va_list alist)
*/
ENTRY(dtrace_vpanic) /* Initial stack layout: */
b vpanic
RET
END(dtrace_vpanic) /* Initial stack layout: */
/*
uintptr_t
dtrace_caller(int aframes)

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)