| 1444 | } |
| 1445 | |
| 1446 | static void |
| 1447 | log_bad_page_fault(char *msg, struct trapframe *frame, int trap_type) |
| 1448 | { |
| 1449 | pt_entry_t *ptep; |
| 1450 | pd_entry_t *pdep; |
| 1451 | unsigned int *addr, instr[4]; |
| 1452 | struct thread *td; |
| 1453 | struct proc *p; |
| 1454 | char *read_or_write; |
| 1455 | register_t pc; |
| 1456 | |
| 1457 | trap_type &= ~T_USER; |
| 1458 | |
| 1459 | td = curthread; |
| 1460 | p = td->td_proc; |
| 1461 | |
| 1462 | #ifdef SMP |
| 1463 | printf("cpuid = %d\n", PCPU_GET(cpuid)); |
| 1464 | #endif |
| 1465 | switch (trap_type) { |
| 1466 | case T_TLB_MOD: |
| 1467 | case T_TLB_ST_MISS: |
| 1468 | case T_ADDR_ERR_ST: |
| 1469 | read_or_write = "write"; |
| 1470 | break; |
| 1471 | case T_TLB_LD_MISS: |
| 1472 | case T_ADDR_ERR_LD: |
| 1473 | case T_BUS_ERR_IFETCH: |
| 1474 | read_or_write = "read"; |
| 1475 | break; |
| 1476 | default: |
| 1477 | read_or_write = "unknown"; |
| 1478 | } |
| 1479 | |
| 1480 | pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0); |
| 1481 | log(LOG_ERR, "%s: pid %d tid %ld (%s), uid %d: pc %#jx got a %s fault " |
| 1482 | "(type %#x) at %#jx\n", |
| 1483 | msg, p->p_pid, (long)td->td_tid, p->p_comm, |
| 1484 | p->p_ucred ? p->p_ucred->cr_uid : -1, |
| 1485 | (intmax_t)pc, |
| 1486 | read_or_write, |
| 1487 | trap_type, |
| 1488 | (intmax_t)frame->badvaddr); |
| 1489 | |
| 1490 | /* log registers in trap frame */ |
| 1491 | log_frame_dump(frame); |
| 1492 | |
| 1493 | get_mapping_info((vm_offset_t)pc, &pdep, &ptep); |
| 1494 | |
| 1495 | /* |
| 1496 | * Dump a few words around faulting instruction, if the addres is |
| 1497 | * valid. |
| 1498 | */ |
| 1499 | addr = (unsigned int *)(intptr_t)pc; |
| 1500 | if ((pc & 3) == 0 && pc != frame->badvaddr && |
| 1501 | trap_type != T_BUS_ERR_IFETCH && |
| 1502 | copyin((caddr_t)(intptr_t)pc, instr, sizeof(instr)) == 0) { |
| 1503 | /* dump page table entry for faulting instruction */ |
no test coverage detected