| 180 | */ |
| 181 | |
| 182 | void |
| 183 | trap(struct trapframe *frame) |
| 184 | { |
| 185 | ksiginfo_t ksi; |
| 186 | struct thread *td; |
| 187 | struct proc *p; |
| 188 | register_t addr, dr6; |
| 189 | int pf, signo, ucode; |
| 190 | u_int type; |
| 191 | |
| 192 | td = curthread; |
| 193 | p = td->td_proc; |
| 194 | dr6 = 0; |
| 195 | |
| 196 | VM_CNT_INC(v_trap); |
| 197 | type = frame->tf_trapno; |
| 198 | |
| 199 | #ifdef SMP |
| 200 | /* Handler for NMI IPIs used for stopping CPUs. */ |
| 201 | if (type == T_NMI && ipi_nmi_handler() == 0) |
| 202 | return; |
| 203 | #endif |
| 204 | |
| 205 | #ifdef KDB |
| 206 | if (kdb_active) { |
| 207 | kdb_reenter(); |
| 208 | return; |
| 209 | } |
| 210 | #endif |
| 211 | |
| 212 | if (type == T_RESERVED) { |
| 213 | trap_fatal(frame, 0); |
| 214 | return; |
| 215 | } |
| 216 | |
| 217 | if (type == T_NMI) { |
| 218 | #ifdef HWPMC_HOOKS |
| 219 | /* |
| 220 | * CPU PMCs interrupt using an NMI. If the PMC module is |
| 221 | * active, pass the 'rip' value to the PMC module's interrupt |
| 222 | * handler. A non-zero return value from the handler means that |
| 223 | * the NMI was consumed by it and we can return immediately. |
| 224 | */ |
| 225 | if (pmc_intr != NULL && |
| 226 | (*pmc_intr)(frame) != 0) |
| 227 | return; |
| 228 | #endif |
| 229 | } |
| 230 | |
| 231 | if ((frame->tf_rflags & PSL_I) == 0) { |
| 232 | /* |
| 233 | * Buggy application or kernel code has disabled |
| 234 | * interrupts and then trapped. Enabling interrupts |
| 235 | * now is wrong, but it is better than running with |
| 236 | * interrupts disabled until they are accidentally |
| 237 | * enabled later. |
| 238 | */ |
| 239 | if (TRAPF_USERMODE(frame)) |
no test coverage detected