staticvoid do_fault_siginfo(int code, int sig, struct pt_regs *regs, unsignedlong fault_addr, unsignedint insn, int fault_code)
{ unsignedlong addr;
if (fault_code & FAULT_CODE_ITLB) {
addr = regs->tpc;
} else { /* If we were able to probe the faulting instruction, use it *tocomputeaprecisefaultaddress.Otherwiseusethefault *timeprovidedaddresswhichmayonlyhavepagegranularity.
*/ if (insn)
addr = compute_effective_address(regs, insn, 0); else
addr = fault_addr;
}
if (unlikely(show_unhandled_signals))
show_signal_msg(regs, sig, code, addr, current);
if (!mmap_read_trylock(mm)) { if ((regs->tstate & TSTATE_PRIV) &&
!search_exception_tables(regs->tpc)) {
insn = get_fault_insn(regs, insn); goto handle_kernel_fault;
}
retry:
mmap_read_lock(mm);
}
if (fault_code & FAULT_CODE_BAD_RA) goto do_sigbus;
vma = find_vma(mm, address); if (!vma) goto bad_area;
/* Pure DTLB misses do not tell us whether the fault causing *load/store/atomicwasawriteornot,itonlysaysthatthere *wasnomatch.Soinsuchacasewe(carefully)readthe *instructiontotryandfigurethisout.It'sanoptimization *soit'sokifwecan'tdothis. * *Specialhack,windowspill/fillknowstheexactfaulttype.
*/ if (((fault_code &
(FAULT_CODE_DTLB | FAULT_CODE_WRITE | FAULT_CODE_WINFIXUP)) == FAULT_CODE_DTLB) &&
(vma->vm_flags & VM_WRITE) != 0) {
insn = get_fault_insn(regs, 0); if (!insn) goto continue_fault; /* All loads, stores and atomics have bits 30 and 31 both set *intheinstruction.Bit21issetinallstores,butwe *havetoavoidprefetcheswhichalsohavebit21set.
*/ if ((insn & 0xc0200000) == 0xc0200000 &&
(insn & 0x01780000) != 0x01680000) { /* Don't bother updating thread struct value, *becauseupdate_mmu_cacheonlycareswhichtlb *theaccesscamefrom.
*/
fault_code |= FAULT_CODE_WRITE;
}
}
continue_fault:
if (vma->vm_start <= address) goto good_area; if (!(vma->vm_flags & VM_GROWSDOWN)) goto bad_area; if (!(fault_code & FAULT_CODE_WRITE)) { /* Non-faulting loads shouldn't expand stack. */
insn = get_fault_insn(regs, insn); if ((insn & 0xc0800000) == 0xc0800000) { unsignedchar asi;
if (insn & 0x2000)
asi = (regs->tstate >> 24); else
asi = (insn >> 5); if ((asi & 0xf2) == 0x82) goto bad_area;
}
}
vma = expand_stack(mm, address); if (!vma) goto bad_area_nosemaphore; /* *Ok,wehaveagoodvm_areaforthismemoryaccess,so *wecanhandleit..
*/
good_area:
si_code = SEGV_ACCERR;
/* If we took a ITLB miss on a non-executable page, catch *thathere.
*/ if ((fault_code & FAULT_CODE_ITLB) && !(vma->vm_flags & VM_EXEC)) {
WARN(address != regs->tpc, "address (%lx) != regs->tpc (%lx)\n", address, regs->tpc);
WARN_ON(regs->tstate & TSTATE_PRIV); goto bad_area;
}
if (fault_code & FAULT_CODE_WRITE) { if (!(vma->vm_flags & VM_WRITE)) goto bad_area;
/* Spitfire has an icache which does not snoop *processorstores.Laterprocessorsdo...
*/ if (tlb_type == spitfire &&
(vma->vm_flags & VM_EXEC) != 0 &&
vma->vm_file != NULL)
set_thread_fault_code(fault_code |
FAULT_CODE_BLKCOMMIT);
flags |= FAULT_FLAG_WRITE;
} else { /* Allow reads even for write-only mappings */ if (!(vma->vm_flags & (VM_READ | VM_EXEC))) goto bad_area;
}
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.