| 1650 | "limit number of userland unaligned log messages per second"); |
| 1651 | |
| 1652 | static int |
| 1653 | emulate_unaligned_access(struct trapframe *frame, int mode) |
| 1654 | { |
| 1655 | register_t pc; |
| 1656 | int access_type = 0; |
| 1657 | struct thread *td = curthread; |
| 1658 | struct proc *p = curproc; |
| 1659 | |
| 1660 | pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0); |
| 1661 | |
| 1662 | /* |
| 1663 | * Fall through if it's instruction fetch exception |
| 1664 | */ |
| 1665 | if (!((pc & 3) || (pc == frame->badvaddr))) { |
| 1666 | /* |
| 1667 | * Handle unaligned load and store |
| 1668 | */ |
| 1669 | |
| 1670 | /* |
| 1671 | * Return access type if the instruction was emulated. |
| 1672 | * Otherwise restore pc and fall through. |
| 1673 | */ |
| 1674 | access_type = mips_unaligned_load_store(frame, |
| 1675 | mode, frame->badvaddr, pc); |
| 1676 | |
| 1677 | if (access_type) { |
| 1678 | if (DELAYBRANCH(frame->cause)) |
| 1679 | frame->pc = MipsEmulateBranch(frame, frame->pc, |
| 1680 | 0, 0); |
| 1681 | else |
| 1682 | frame->pc += 4; |
| 1683 | |
| 1684 | if (ppsratecheck(&unaligned_lasterr, |
| 1685 | &unaligned_curerr, unaligned_pps_log_limit)) { |
| 1686 | /* XXX TODO: keep global/tid/pid counters? */ |
| 1687 | log(LOG_INFO, |
| 1688 | "Unaligned %s: pid=%ld (%s), tid=%ld, " |
| 1689 | "pc=%#jx, badvaddr=%#jx\n", |
| 1690 | access_name[access_type - 1], |
| 1691 | (long) p->p_pid, |
| 1692 | p->p_comm, |
| 1693 | (long) td->td_tid, |
| 1694 | (intmax_t)pc, |
| 1695 | (intmax_t)frame->badvaddr); |
| 1696 | } |
| 1697 | } |
| 1698 | } |
| 1699 | return access_type; |
| 1700 | } |
no test coverage detected