summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorLuiz Souza <luiz@netgate.com>2018-02-23 19:41:35 -0300
committerLuiz Souza <luiz@netgate.com>2018-02-23 19:41:35 -0300
commit30d0ddbaac6a3884072d2b39e558d836ebf27ae8 (patch)
tree78c311b0614ec94933420aac5883bc15b489bdb1 /sys
parente6a7cb1ff4807e029eee190a3dba721444ec0090 (diff)
downloadFreeBSD-src-30d0ddbaac6a3884072d2b39e558d836ebf27ae8.zip
FreeBSD-src-30d0ddbaac6a3884072d2b39e558d836ebf27ae8.tar.gz
Revert "Revert "MFC r322720,r322723:""
This reverts commit 3ec7f23324c3579430d2fd9a3408dcfdad78e53b.
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/amd64/trap.c182
1 files changed, 86 insertions, 96 deletions
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
index c2593ce..070d722b 100644
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -172,12 +172,12 @@ trap(struct trapframe *frame)
#ifdef KDB
register_t dr6;
#endif
- int i, ucode;
+ int signo, ucode;
u_int type;
td = curthread;
p = td->td_proc;
- i = 0;
+ signo = 0;
ucode = 0;
addr = 0;
@@ -186,22 +186,20 @@ trap(struct trapframe *frame)
#ifdef SMP
/* Handler for NMI IPIs used for stopping CPUs. */
- if (type == T_NMI) {
- if (ipi_nmi_handler() == 0)
- goto out;
- }
-#endif /* SMP */
+ if (type == T_NMI && ipi_nmi_handler() == 0)
+ return;
+#endif
#ifdef KDB
if (kdb_active) {
kdb_reenter();
- goto out;
+ return;
}
#endif
if (type == T_RESERVED) {
trap_fatal(frame, 0);
- goto out;
+ return;
}
if (type == T_NMI) {
@@ -214,18 +212,18 @@ trap(struct trapframe *frame)
*/
if (pmc_intr != NULL &&
(*pmc_intr)(PCPU_GET(cpuid), frame) != 0)
- goto out;
+ return;
#endif
#ifdef STACK
if (stack_nmi_handler(frame) != 0)
- goto out;
+ return;
#endif
}
if (type == T_MCHK) {
mca_intr();
- goto out;
+ return;
}
if ((frame->tf_rflags & PSL_I) == 0) {
@@ -269,7 +267,7 @@ trap(struct trapframe *frame)
switch (type) {
case T_PRIVINFLT: /* privileged instruction fault */
- i = SIGILL;
+ signo = SIGILL;
ucode = ILL_PRVOPC;
break;
@@ -281,41 +279,41 @@ trap(struct trapframe *frame)
fill_frame_regs(frame, &regs);
if (dtrace_pid_probe_ptr != NULL &&
dtrace_pid_probe_ptr(&regs) == 0)
- goto out;
+ return;
}
#endif
frame->tf_rflags &= ~PSL_T;
- i = SIGTRAP;
+ signo = SIGTRAP;
ucode = (type == T_TRCTRAP ? TRAP_TRACE : TRAP_BRKPT);
break;
case T_ARITHTRAP: /* arithmetic trap */
ucode = fputrap_x87();
if (ucode == -1)
- goto userout;
- i = SIGFPE;
+ return;
+ signo = SIGFPE;
break;
case T_PROTFLT: /* general protection fault */
- i = SIGBUS;
+ signo = SIGBUS;
ucode = BUS_OBJERR;
break;
case T_STKFLT: /* stack fault */
case T_SEGNPFLT: /* segment not present fault */
- i = SIGBUS;
+ signo = SIGBUS;
ucode = BUS_ADRERR;
break;
case T_TSSFLT: /* invalid TSS fault */
- i = SIGBUS;
+ signo = SIGBUS;
ucode = BUS_OBJERR;
break;
case T_ALIGNFLT:
- i = SIGBUS;
+ signo = SIGBUS;
ucode = BUS_ADRALN;
break;
case T_DOUBLEFLT: /* double fault */
default:
- i = SIGBUS;
+ signo = SIGBUS;
ucode = BUS_OBJERR;
break;
@@ -325,67 +323,64 @@ trap(struct trapframe *frame)
*/
if (*p->p_sysent->sv_trap != NULL &&
(*p->p_sysent->sv_trap)(td) == 0)
- goto userout;
+ return;
addr = frame->tf_addr;
- i = trap_pfault(frame, TRUE);
- if (i == -1)
- goto userout;
- if (i == 0)
- goto user;
-
- if (i == SIGSEGV)
+ signo = trap_pfault(frame, TRUE);
+ if (signo == -1)
+ return;
+ if (signo == 0)
+ goto userret;
+ if (signo == SIGSEGV) {
ucode = SEGV_MAPERR;
- else {
- if (prot_fault_translation == 0) {
- /*
- * Autodetect.
- * This check also covers the images
- * without the ABI-tag ELF note.
- */
- if (SV_CURPROC_ABI() == SV_ABI_FREEBSD
- && p->p_osrel >= P_OSREL_SIGSEGV) {
- i = SIGSEGV;
- ucode = SEGV_ACCERR;
- } else {
- i = SIGBUS;
- ucode = BUS_PAGE_FAULT;
- }
- } else if (prot_fault_translation == 1) {
- /*
- * Always compat mode.
- */
- i = SIGBUS;
- ucode = BUS_PAGE_FAULT;
- } else {
- /*
- * Always SIGSEGV mode.
- */
- i = SIGSEGV;
+ } else if (prot_fault_translation == 0) {
+ /*
+ * Autodetect. This check also covers
+ * the images without the ABI-tag ELF
+ * note.
+ */
+ if (SV_CURPROC_ABI() == SV_ABI_FREEBSD &&
+ p->p_osrel >= P_OSREL_SIGSEGV) {
+ signo = SIGSEGV;
ucode = SEGV_ACCERR;
+ } else {
+ signo = SIGBUS;
+ ucode = BUS_PAGE_FAULT;
}
+ } else if (prot_fault_translation == 1) {
+ /*
+ * Always compat mode.
+ */
+ signo = SIGBUS;
+ ucode = BUS_PAGE_FAULT;
+ } else {
+ /*
+ * Always SIGSEGV mode.
+ */
+ signo = SIGSEGV;
+ ucode = SEGV_ACCERR;
}
break;
case T_DIVIDE: /* integer divide fault */
ucode = FPE_INTDIV;
- i = SIGFPE;
+ signo = SIGFPE;
break;
#ifdef DEV_ISA
case T_NMI:
nmi_handle_intr(type, frame);
- goto out;
-#endif /* DEV_ISA */
+ return;
+#endif
case T_OFLOW: /* integer overflow fault */
ucode = FPE_INTOVF;
- i = SIGFPE;
+ signo = SIGFPE;
break;
case T_BOUND: /* bounds check fault */
ucode = FPE_FLTSUB;
- i = SIGFPE;
+ signo = SIGFPE;
break;
case T_DNA:
@@ -393,27 +388,26 @@ trap(struct trapframe *frame)
KASSERT(PCB_USER_FPU(td->td_pcb),
("kernel FPU ctx has leaked"));
fpudna();
- goto userout;
+ return;
case T_FPOPFLT: /* FPU operand fetch fault */
ucode = ILL_COPROC;
- i = SIGILL;
+ signo = SIGILL;
break;
case T_XMMFLT: /* SIMD floating-point exception */
ucode = fputrap_sse();
if (ucode == -1)
- goto userout;
- i = SIGFPE;
+ return;
+ signo = SIGFPE;
break;
#ifdef KDTRACE_HOOKS
case T_DTRACE_RET:
enable_intr();
fill_frame_regs(frame, &regs);
- if (dtrace_return_probe_ptr != NULL &&
- dtrace_return_probe_ptr(&regs) == 0)
- goto out;
- goto userout;
+ if (dtrace_return_probe_ptr != NULL)
+ dtrace_return_probe_ptr(&regs);
+ return;
#endif
}
} else {
@@ -424,13 +418,13 @@ trap(struct trapframe *frame)
switch (type) {
case T_PAGEFLT: /* page fault */
(void) trap_pfault(frame, FALSE);
- goto out;
+ return;
case T_DNA:
if (PCB_USER_FPU(td->td_pcb))
panic("Unregistered use of FPU in kernel");
fpudna();
- goto out;
+ return;
case T_ARITHTRAP: /* arithmetic trap */
case T_XMMFLT: /* SIMD floating-point exception */
@@ -440,7 +434,7 @@ trap(struct trapframe *frame)
* registration for FPU traps is overkill.
*/
trap_fatal(frame, 0);
- goto out;
+ return;
case T_STKFLT: /* stack fault */
case T_PROTFLT: /* general protection fault */
@@ -460,35 +454,35 @@ trap(struct trapframe *frame)
*/
if (frame->tf_rip == (long)doreti_iret) {
frame->tf_rip = (long)doreti_iret_fault;
- goto out;
+ return;
}
if (frame->tf_rip == (long)ld_ds) {
frame->tf_rip = (long)ds_load_fault;
- goto out;
+ return;
}
if (frame->tf_rip == (long)ld_es) {
frame->tf_rip = (long)es_load_fault;
- goto out;
+ return;
}
if (frame->tf_rip == (long)ld_fs) {
frame->tf_rip = (long)fs_load_fault;
- goto out;
+ return;
}
if (frame->tf_rip == (long)ld_gs) {
frame->tf_rip = (long)gs_load_fault;
- goto out;
+ return;
}
if (frame->tf_rip == (long)ld_gsbase) {
frame->tf_rip = (long)gsbase_load_fault;
- goto out;
+ return;
}
if (frame->tf_rip == (long)ld_fsbase) {
frame->tf_rip = (long)fsbase_load_fault;
- goto out;
+ return;
}
if (curpcb->pcb_onfault != NULL) {
frame->tf_rip = (long)curpcb->pcb_onfault;
- goto out;
+ return;
}
break;
@@ -504,7 +498,7 @@ trap(struct trapframe *frame)
*/
if (frame->tf_rflags & PSL_NT) {
frame->tf_rflags &= ~PSL_NT;
- goto out;
+ return;
}
break;
@@ -525,7 +519,7 @@ trap(struct trapframe *frame)
* processor doesn't
*/
load_dr6(rdr6() & ~0xf);
- goto out;
+ return;
}
/*
* FALLTHROUGH (TRCTRAP kernel mode, kernel address)
@@ -540,27 +534,27 @@ trap(struct trapframe *frame)
dr6 = rdr6();
load_dr6(dr6 & ~0x4000);
if (kdb_trap(type, dr6, frame))
- goto out;
+ return;
#endif
break;
#ifdef DEV_ISA
case T_NMI:
nmi_handle_intr(type, frame);
- goto out;
-#endif /* DEV_ISA */
+ return;
+#endif
}
trap_fatal(frame, 0);
- goto out;
+ return;
}
/* Translate fault for emulators (e.g. Linux) */
- if (*p->p_sysent->sv_transtrap)
- i = (*p->p_sysent->sv_transtrap)(i, type);
+ if (*p->p_sysent->sv_transtrap != NULL)
+ signo = (*p->p_sysent->sv_transtrap)(signo, type);
ksiginfo_init_trap(&ksi);
- ksi.ksi_signo = i;
+ ksi.ksi_signo = signo;
ksi.ksi_code = ucode;
ksi.ksi_trapno = type;
ksi.ksi_addr = (void *)addr;
@@ -568,8 +562,8 @@ trap(struct trapframe *frame)
uprintf("pid %d comm %s: signal %d err %lx code %d type %d "
"addr 0x%lx rsp 0x%lx rip 0x%lx "
"<%02x %02x %02x %02x %02x %02x %02x %02x>\n",
- p->p_pid, p->p_comm, i, frame->tf_err, ucode, type, addr,
- frame->tf_rsp, frame->tf_rip,
+ p->p_pid, p->p_comm, signo, frame->tf_err, ucode, type,
+ addr, frame->tf_rsp, frame->tf_rip,
fubyte((void *)(frame->tf_rip + 0)),
fubyte((void *)(frame->tf_rip + 1)),
fubyte((void *)(frame->tf_rip + 2)),
@@ -581,14 +575,10 @@ trap(struct trapframe *frame)
}
KASSERT((read_rflags() & PSL_I) != 0, ("interrupts disabled"));
trapsignal(td, &ksi);
-
-user:
+userret:
userret(td, frame);
KASSERT(PCB_USER_FPU(td->td_pcb),
("Return from trap with kernel FPU ctx leaked"));
-userout:
-out:
- return;
}
/*
OpenPOWER on IntegriCloud