/* * Handle an unaligned access * Returns 0 if successfully handled, 1 if some error happened
*/ int misaligned_fixup(unsignedlong address, struct pt_regs *regs, struct callee_regs *cregs)
{ struct disasm_state state;
/* handle user mode only and only if enabled by sysadmin */ if (!user_mode(regs) || !unaligned_enabled) return 1;
if (no_unaligned_warning) {
pr_warn_once("%s(%d) made unaligned access which was emulated" " by kernel assist\n. This can degrade application" " performance significantly\n. To enable further" " logging of such instances, please \n" " echo 0 > /proc/sys/kernel/ignore-unaligned-usertrap\n",
current->comm, task_pid_nr(current));
} else { /* Add rate limiting if it gets down to it */
pr_warn("%s(%d): unaligned access to/from 0x%lx by PC: 0x%lx\n",
current->comm, task_pid_nr(current),
address, regs->ret);
}
disasm_instr(regs->ret, &state, 1, regs, cregs);
if (state.fault) goto fault;
/* ldb/stb should not have unaligned exception */ if ((state.zz == 1) || (state.di)) goto fault;
if (!state.write)
fixup_load(&state, regs, cregs); else
fixup_store(&state, regs, cregs);
if (state.fault) goto fault;
/* clear any remnants of delay slot */ if (delay_mode(regs)) {
regs->ret = regs->bta & ~1U;
regs->status32 &= ~STATUS_DE_MASK;
} else {
regs->ret += state.instr_len;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.