o) Make pcb_onfault a pointer rather than an obscure integer value.
o) Mask off PAGE_MASK bits in pmap_update_page, etc., rather than modifying the badvaddr in trapframe. Some nearby interfaces already did this. o) Make PTEs "unsigned int" for now, not "unsigned long" -- we are only ready for them to be 32-bit on 64-bit platforms. o) Rather than using pmap_segmap and calculating the offset into the page table by hand in trap.c, use pmap_pte(). o) Remove unused quad_syscall variable in trap.c. o) Log things for illegal instructions like we do for bad page faults. o) Various cast cleanups related to how to print registers. o) When logging page faults, show the page table information not just for the program counter, but for the fault address. o) Modify support.S to use ABI-neutral macros for operating on pointers. o) Consistently use CALLFRAME_SIZ rather than STAND_FRAME_SIZE, etc. o) Remove unused insque/remque functions. o) Remove some coprocessor 0 accessor functions implemented in assembly that are unused and have inline assembly counterparts.
This commit is contained in:
parent
2ab78e3ca5
commit
a27e66e8f5
@ -458,13 +458,9 @@ extern union cpuprid fpu_id;
|
||||
struct tlb;
|
||||
struct user;
|
||||
|
||||
u_int32_t mips_cp0_config1_read(void);
|
||||
int Mips_ConfigCache(void);
|
||||
void Mips_SetWIRED(int);
|
||||
void Mips_SetPID(int);
|
||||
u_int Mips_GetCOUNT(void);
|
||||
void Mips_SetCOMPARE(u_int);
|
||||
u_int Mips_GetCOMPARE(void);
|
||||
|
||||
void Mips_SyncCache(void);
|
||||
void Mips_SyncDCache(vm_offset_t, int);
|
||||
|
@ -51,7 +51,7 @@ struct pcb
|
||||
{
|
||||
struct trapframe pcb_regs; /* saved CPU and registers */
|
||||
__register_t pcb_context[14]; /* kernel context for resume */
|
||||
int pcb_onfault; /* for copyin/copyout faults */
|
||||
void *pcb_onfault; /* for copyin/copyout faults */
|
||||
register_t pcb_tpc;
|
||||
};
|
||||
|
||||
|
@ -83,7 +83,7 @@ struct tlb {
|
||||
int tlb_lo1;
|
||||
};
|
||||
|
||||
typedef unsigned long pt_entry_t;
|
||||
typedef unsigned int pt_entry_t;
|
||||
typedef pt_entry_t *pd_entry_t;
|
||||
|
||||
#define PDESIZE sizeof(pd_entry_t) /* for assembly files */
|
||||
|
@ -660,7 +660,7 @@ pmap_update_page_action(void *arg)
|
||||
pmap->pm_asid[PCPU_GET(cpuid)].gen = 0;
|
||||
return;
|
||||
}
|
||||
va = pmap_va_asid(pmap, va);
|
||||
va = pmap_va_asid(pmap, (va & ~PAGE_MASK));
|
||||
MachTLBUpdate(va, pte);
|
||||
}
|
||||
|
||||
@ -669,6 +669,8 @@ pmap_TLB_update_kernel(vm_offset_t va, pt_entry_t pte)
|
||||
{
|
||||
u_int32_t pid;
|
||||
|
||||
va &= ~PAGE_MASK;
|
||||
|
||||
MachTLBGetPID(pid);
|
||||
va = va | (pid << VMTLB_PID_SHIFT);
|
||||
|
||||
@ -1885,7 +1887,7 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_prot_t access, vm_page_t m,
|
||||
if (origpte & PTE_M) {
|
||||
KASSERT((origpte & PTE_RW),
|
||||
("pmap_enter: modified page not writable:"
|
||||
" va: %p, pte: 0x%lx", (void *)va, origpte));
|
||||
" va: %p, pte: 0x%x", (void *)va, origpte));
|
||||
if (page_is_managed(opa))
|
||||
vm_page_dirty(om);
|
||||
}
|
||||
@ -2381,7 +2383,7 @@ pmap_remove_pages(pmap_t pmap)
|
||||
m = PHYS_TO_VM_PAGE(mips_tlbpfn_to_paddr(tpte));
|
||||
|
||||
KASSERT(m < &vm_page_array[vm_page_array_size],
|
||||
("pmap_remove_pages: bad tpte %lx", tpte));
|
||||
("pmap_remove_pages: bad tpte %x", tpte));
|
||||
|
||||
pv->pv_pmap->pm_stats.resident_count--;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -99,8 +99,7 @@ __FBSDID("$FreeBSD$");
|
||||
int trap_debug = 1;
|
||||
#endif
|
||||
|
||||
extern unsigned onfault_table[];
|
||||
|
||||
static void log_illegal_instruction(const char *, struct trapframe *);
|
||||
static void log_bad_page_fault(char *, struct trapframe *, int);
|
||||
static void log_frame_dump(struct trapframe *frame);
|
||||
static void get_mapping_info(vm_offset_t, pd_entry_t **, pt_entry_t **);
|
||||
@ -226,8 +225,8 @@ void stacktrace(struct trapframe *);
|
||||
void logstacktrace(struct trapframe *);
|
||||
#endif
|
||||
|
||||
#define KERNLAND(x) ((int)(x) < 0)
|
||||
#define DELAYBRANCH(x) ((int)(x) < 0)
|
||||
#define KERNLAND(x) ((vm_offset_t)(x) >= VM_MIN_KERNEL_ADDRESS && (vm_offset_t)(x) < VM_MAX_KERNEL_ADDRESS)
|
||||
#define DELAYBRANCH(x) ((int)(x) < 0)
|
||||
|
||||
/*
|
||||
* MIPS load/store access type
|
||||
@ -263,6 +262,7 @@ SYSCTL_INT(_vm, OID_AUTO, allow_unaligned_acc, CTLFLAG_RW,
|
||||
static int emulate_unaligned_access(struct trapframe *frame);
|
||||
|
||||
extern char *syscallnames[];
|
||||
extern void fswintrberr(void); /* XXX */
|
||||
|
||||
/*
|
||||
* Handle an exception.
|
||||
@ -281,13 +281,12 @@ trap(struct trapframe *trapframe)
|
||||
struct proc *p = curproc;
|
||||
vm_prot_t ftype;
|
||||
pt_entry_t *pte;
|
||||
unsigned int entry;
|
||||
pmap_t pmap;
|
||||
int quad_syscall = 0;
|
||||
int access_type;
|
||||
ksiginfo_t ksi;
|
||||
char *msg = NULL;
|
||||
register_t addr = 0;
|
||||
intptr_t addr = 0;
|
||||
register_t pc;
|
||||
|
||||
trapdebug_enter(trapframe, 0);
|
||||
|
||||
@ -330,9 +329,9 @@ trap(struct trapframe *trapframe)
|
||||
printf("cpuid = %d\n", PCPU_GET(cpuid));
|
||||
#endif
|
||||
MachTLBGetPID(pid);
|
||||
printf("badaddr = 0x%0x, pc = 0x%0x, ra = 0x%0x, sp = 0x%0x, sr = 0x%x, pid = %d, ASID = 0x%x\n",
|
||||
trapframe->badvaddr, trapframe->pc, trapframe->ra,
|
||||
trapframe->sp, trapframe->sr,
|
||||
printf("badaddr = %#jx, pc = %#jx, ra = %#jx, sp = %#jx, sr = %jx, pid = %d, ASID = %u\n",
|
||||
(intmax_t)trapframe->badvaddr, (intmax_t)trapframe->pc, (intmax_t)trapframe->ra,
|
||||
(intmax_t)trapframe->sp, (intmax_t)trapframe->sr,
|
||||
(curproc ? curproc->p_pid : -1), pid);
|
||||
|
||||
switch (type & ~T_USER) {
|
||||
@ -354,7 +353,7 @@ trap(struct trapframe *trapframe)
|
||||
((type & ~T_USER) != T_SYSCALL)) {
|
||||
if (++count == 3) {
|
||||
trap_frame_dump(trapframe);
|
||||
panic("too many faults at %x\n", last_badvaddr);
|
||||
panic("too many faults at %p\n", (void *)last_badvaddr);
|
||||
}
|
||||
} else {
|
||||
last_badvaddr = this_badvaddr;
|
||||
@ -375,35 +374,30 @@ trap(struct trapframe *trapframe)
|
||||
vm_offset_t pa;
|
||||
|
||||
PMAP_LOCK(kernel_pmap);
|
||||
if (!(pte = pmap_segmap(kernel_pmap,
|
||||
trapframe->badvaddr)))
|
||||
panic("trap: ktlbmod: invalid segmap");
|
||||
pte += (trapframe->badvaddr >> PAGE_SHIFT) & (NPTEPG - 1);
|
||||
entry = *pte;
|
||||
pte = pmap_pte(kernel_pmap, trapframe->badvaddr);
|
||||
if (pte == NULL)
|
||||
panic("trap: ktlbmod: can't find PTE");
|
||||
#ifdef SMP
|
||||
/* It is possible that some other CPU changed m-bit */
|
||||
if (!mips_pg_v(entry) || (entry & mips_pg_m_bit())) {
|
||||
trapframe->badvaddr &= ~PAGE_MASK;
|
||||
if (!mips_pg_v(*pte) || (*pte & mips_pg_m_bit())) {
|
||||
pmap_update_page(kernel_pmap,
|
||||
trapframe->badvaddr, entry);
|
||||
trapframe->badvaddr, *pte);
|
||||
PMAP_UNLOCK(kernel_pmap);
|
||||
return (trapframe->pc);
|
||||
}
|
||||
#else
|
||||
if (!mips_pg_v(entry) || (entry & mips_pg_m_bit()))
|
||||
if (!mips_pg_v(*pte) || (*pte & mips_pg_m_bit()))
|
||||
panic("trap: ktlbmod: invalid pte");
|
||||
#endif
|
||||
if (entry & mips_pg_ro_bit()) {
|
||||
if (*pte & mips_pg_ro_bit()) {
|
||||
/* write to read only page in the kernel */
|
||||
ftype = VM_PROT_WRITE;
|
||||
PMAP_UNLOCK(kernel_pmap);
|
||||
goto kernel_fault;
|
||||
}
|
||||
entry |= mips_pg_m_bit();
|
||||
*pte = entry;
|
||||
trapframe->badvaddr &= ~PAGE_MASK;
|
||||
pmap_update_page(kernel_pmap, trapframe->badvaddr, entry);
|
||||
pa = mips_tlbpfn_to_paddr(entry);
|
||||
*pte |= mips_pg_m_bit();
|
||||
pmap_update_page(kernel_pmap, trapframe->badvaddr, *pte);
|
||||
pa = mips_tlbpfn_to_paddr(*pte);
|
||||
if (!page_is_managed(pa))
|
||||
panic("trap: ktlbmod: unmanaged page");
|
||||
pmap_set_modified(pa);
|
||||
@ -419,36 +413,30 @@ trap(struct trapframe *trapframe)
|
||||
pmap = &p->p_vmspace->vm_pmap;
|
||||
|
||||
PMAP_LOCK(pmap);
|
||||
if (!(pte = pmap_segmap(pmap, trapframe->badvaddr)))
|
||||
panic("trap: utlbmod: invalid segmap");
|
||||
pte += (trapframe->badvaddr >> PAGE_SHIFT) & (NPTEPG - 1);
|
||||
entry = *pte;
|
||||
pte = pmap_pte(pmap, trapframe->badvaddr);
|
||||
if (pte == NULL)
|
||||
panic("trap: utlbmod: can't find PTE");
|
||||
#ifdef SMP
|
||||
/* It is possible that some other CPU changed m-bit */
|
||||
if (!mips_pg_v(entry) || (entry & mips_pg_m_bit())) {
|
||||
trapframe->badvaddr = (trapframe->badvaddr & ~PAGE_MASK);
|
||||
pmap_update_page(pmap, trapframe->badvaddr, entry);
|
||||
if (!mips_pg_v(*pte) || (*pte & mips_pg_m_bit())) {
|
||||
pmap_update_page(pmap, trapframe->badvaddr, *pte);
|
||||
PMAP_UNLOCK(pmap);
|
||||
goto out;
|
||||
}
|
||||
#else
|
||||
if (!mips_pg_v(entry) || (entry & mips_pg_m_bit())) {
|
||||
if (!mips_pg_v(*pte) || (*pte & mips_pg_m_bit()))
|
||||
panic("trap: utlbmod: invalid pte");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (entry & mips_pg_ro_bit()) {
|
||||
if (*pte & mips_pg_ro_bit()) {
|
||||
/* write to read only page */
|
||||
ftype = VM_PROT_WRITE;
|
||||
PMAP_UNLOCK(pmap);
|
||||
goto dofault;
|
||||
}
|
||||
entry |= mips_pg_m_bit();
|
||||
*pte = entry;
|
||||
trapframe->badvaddr = (trapframe->badvaddr & ~PAGE_MASK);
|
||||
pmap_update_page(pmap, trapframe->badvaddr, entry);
|
||||
trapframe->badvaddr |= (pmap->pm_asid[PCPU_GET(cpuid)].asid << VMTLB_PID_SHIFT);
|
||||
pa = mips_tlbpfn_to_paddr(entry);
|
||||
*pte |= mips_pg_m_bit();
|
||||
pmap_update_page(pmap, trapframe->badvaddr, *pte);
|
||||
pa = mips_tlbpfn_to_paddr(*pte);
|
||||
if (!page_is_managed(pa))
|
||||
panic("trap: utlbmod: unmanaged page");
|
||||
pmap_set_modified(pa);
|
||||
@ -473,22 +461,29 @@ trap(struct trapframe *trapframe)
|
||||
rv = vm_fault(kernel_map, va, ftype, VM_FAULT_NORMAL);
|
||||
if (rv == KERN_SUCCESS)
|
||||
return (trapframe->pc);
|
||||
if ((i = td->td_pcb->pcb_onfault) != 0) {
|
||||
td->td_pcb->pcb_onfault = 0;
|
||||
return (onfault_table[i]);
|
||||
if (td->td_pcb->pcb_onfault != NULL) {
|
||||
pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault;
|
||||
td->td_pcb->pcb_onfault = NULL;
|
||||
return (pc);
|
||||
}
|
||||
goto err;
|
||||
}
|
||||
/*
|
||||
|
||||
/*
|
||||
* It is an error for the kernel to access user space except
|
||||
* through the copyin/copyout routines.
|
||||
*/
|
||||
if ((i = td->td_pcb->pcb_onfault) == 0)
|
||||
if (td->td_pcb->pcb_onfault == NULL)
|
||||
goto err;
|
||||
|
||||
/* check for fuswintr() or suswintr() getting a page fault */
|
||||
if (i == 4) {
|
||||
return (onfault_table[i]);
|
||||
/* XXX There must be a nicer way to do this. */
|
||||
if (td->td_pcb->pcb_onfault == fswintrberr) {
|
||||
pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault;
|
||||
td->td_pcb->pcb_onfault = NULL;
|
||||
return (pc);
|
||||
}
|
||||
|
||||
goto dofault;
|
||||
|
||||
case T_TLB_LD_MISS + T_USER:
|
||||
@ -507,7 +502,7 @@ trap(struct trapframe *trapframe)
|
||||
vm = p->p_vmspace;
|
||||
map = &vm->vm_map;
|
||||
va = trunc_page((vm_offset_t)trapframe->badvaddr);
|
||||
if ((vm_offset_t)trapframe->badvaddr >= VM_MIN_KERNEL_ADDRESS) {
|
||||
if (KERNLAND(trapframe->badvaddr)) {
|
||||
/*
|
||||
* Don't allow user-mode faults in kernel
|
||||
* address space.
|
||||
@ -529,9 +524,9 @@ trap(struct trapframe *trapframe)
|
||||
--p->p_lock;
|
||||
PROC_UNLOCK(p);
|
||||
#ifdef VMFAULT_TRACE
|
||||
printf("vm_fault(%p (pmap %p), %x (%x), %x, %d) -> %x at pc %x\n",
|
||||
map, &vm->vm_pmap, va, trapframe->badvaddr, ftype, VM_FAULT_NORMAL,
|
||||
rv, trapframe->pc);
|
||||
printf("vm_fault(%p (pmap %p), %p (%p), %x, %d) -> %x at pc %p\n",
|
||||
map, &vm->vm_pmap, (void *)va, (void *)(intptr_t)trapframe->badvaddr,
|
||||
ftype, VM_FAULT_NORMAL, rv, (void *)(intptr_t)trapframe->pc);
|
||||
#endif
|
||||
|
||||
if (rv == KERN_SUCCESS) {
|
||||
@ -542,9 +537,10 @@ trap(struct trapframe *trapframe)
|
||||
}
|
||||
nogo:
|
||||
if (!usermode) {
|
||||
if ((i = td->td_pcb->pcb_onfault) != 0) {
|
||||
td->td_pcb->pcb_onfault = 0;
|
||||
return (onfault_table[i]);
|
||||
if (td->td_pcb->pcb_onfault != NULL) {
|
||||
pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault;
|
||||
td->td_pcb->pcb_onfault = NULL;
|
||||
return (pc);
|
||||
}
|
||||
goto err;
|
||||
}
|
||||
@ -606,6 +602,8 @@ trap(struct trapframe *trapframe)
|
||||
int nargs, nsaved;
|
||||
register_t args[8];
|
||||
|
||||
bzero(args, sizeof args);
|
||||
|
||||
/*
|
||||
* note: PCPU_LAZY_INC() can only be used if we can
|
||||
* afford occassional inaccuracy in the count.
|
||||
@ -654,7 +652,6 @@ trap(struct trapframe *trapframe)
|
||||
args[0] = locr0->a2;
|
||||
args[1] = locr0->a3;
|
||||
nsaved = 2;
|
||||
quad_syscall = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -679,7 +676,7 @@ trap(struct trapframe *trapframe)
|
||||
nargs = callp->sy_narg;
|
||||
|
||||
if (nargs > nsaved) {
|
||||
i = copyin((caddr_t)(locr0->sp +
|
||||
i = copyin((caddr_t)(intptr_t)(locr0->sp +
|
||||
4 * sizeof(register_t)), (caddr_t)&args[nsaved],
|
||||
(u_int)(nargs - nsaved) * sizeof(register_t));
|
||||
if (i) {
|
||||
@ -770,7 +767,8 @@ trap(struct trapframe *trapframe)
|
||||
|
||||
case T_BREAK + T_USER:
|
||||
{
|
||||
uintptr_t va, instr;
|
||||
intptr_t va;
|
||||
uint32_t instr;
|
||||
|
||||
/* compute address of break instruction */
|
||||
va = trapframe->pc;
|
||||
@ -803,7 +801,7 @@ trap(struct trapframe *trapframe)
|
||||
case T_IWATCH + T_USER:
|
||||
case T_DWATCH + T_USER:
|
||||
{
|
||||
uintptr_t va;
|
||||
intptr_t va;
|
||||
|
||||
/* compute address of trapped instruction */
|
||||
va = trapframe->pc;
|
||||
@ -817,7 +815,8 @@ trap(struct trapframe *trapframe)
|
||||
|
||||
case T_TRAP + T_USER:
|
||||
{
|
||||
uintptr_t va, instr;
|
||||
intptr_t va;
|
||||
uint32_t instr;
|
||||
struct trapframe *locr0 = td->td_frame;
|
||||
|
||||
/* compute address of trap instruction */
|
||||
@ -839,6 +838,7 @@ trap(struct trapframe *trapframe)
|
||||
}
|
||||
|
||||
case T_RES_INST + T_USER:
|
||||
log_illegal_instruction("RES_INST", trapframe);
|
||||
i = SIGILL;
|
||||
addr = trapframe->pc;
|
||||
break;
|
||||
@ -853,11 +853,13 @@ trap(struct trapframe *trapframe)
|
||||
#if !defined(CPU_HAVEFPU)
|
||||
/* FP (COP1) instruction */
|
||||
if ((trapframe->cause & CR_COP_ERR) == 0x10000000) {
|
||||
log_illegal_instruction("COP1_UNUSABLE", trapframe);
|
||||
i = SIGILL;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if ((trapframe->cause & CR_COP_ERR) != 0x10000000) {
|
||||
log_illegal_instruction("COPn_UNUSABLE", trapframe);
|
||||
i = SIGILL; /* only FPU instructions allowed */
|
||||
break;
|
||||
}
|
||||
@ -872,13 +874,13 @@ trap(struct trapframe *trapframe)
|
||||
#if !defined(SMP) && (defined(DDB) || defined(DEBUG))
|
||||
trapDump("fpintr");
|
||||
#else
|
||||
printf("FPU Trap: PC %x CR %x SR %x\n",
|
||||
trapframe->pc, trapframe->cause, trapframe->sr);
|
||||
printf("FPU Trap: PC %#jx CR %x SR %x\n",
|
||||
(intmax_t)trapframe->pc, (unsigned)trapframe->cause, (unsigned)trapframe->sr);
|
||||
goto err;
|
||||
#endif
|
||||
|
||||
case T_FPE + T_USER:
|
||||
MachFPTrap(trapframe->sr, trapframe->cause, trapframe->pc);
|
||||
MipsFPTrap(trapframe->sr, trapframe->cause, trapframe->pc);
|
||||
goto out;
|
||||
|
||||
case T_OVFLOW + T_USER:
|
||||
@ -889,8 +891,8 @@ trap(struct trapframe *trapframe)
|
||||
case T_ADDR_ERR_LD: /* misaligned access */
|
||||
case T_ADDR_ERR_ST: /* misaligned access */
|
||||
#ifdef TRAP_DEBUG
|
||||
printf("+++ ADDR_ERR: type = %d, badvaddr = %x\n", type,
|
||||
trapframe->badvaddr);
|
||||
printf("+++ ADDR_ERR: type = %d, badvaddr = %#jx\n", type,
|
||||
(intmax_t)trapframe->badvaddr);
|
||||
#endif
|
||||
/* Only allow emulation on a user address */
|
||||
if (allow_unaligned_acc &&
|
||||
@ -922,10 +924,12 @@ trap(struct trapframe *trapframe)
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case T_BUS_ERR_LD_ST: /* BERR asserted to cpu */
|
||||
if ((i = td->td_pcb->pcb_onfault) != 0) {
|
||||
td->td_pcb->pcb_onfault = 0;
|
||||
return (onfault_table[i]);
|
||||
if (td->td_pcb->pcb_onfault != NULL) {
|
||||
pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault;
|
||||
td->td_pcb->pcb_onfault = NULL;
|
||||
return (pc);
|
||||
}
|
||||
|
||||
/* FALLTHROUGH */
|
||||
|
||||
default:
|
||||
@ -947,9 +951,9 @@ trap(struct trapframe *trapframe)
|
||||
printf("kernel mode)\n");
|
||||
|
||||
#ifdef TRAP_DEBUG
|
||||
printf("badvaddr = %x, pc = %x, ra = %x, sr = 0x%x\n",
|
||||
trapframe->badvaddr, trapframe->pc, trapframe->ra,
|
||||
trapframe->sr);
|
||||
printf("badvaddr = %#jx, pc = %#jx, ra = %#jx, sr = %#jxx\n",
|
||||
(intmax_t)trapframe->badvaddr, (intmax_t)trapframe->pc, (intmax_t)trapframe->ra,
|
||||
(intmax_t)trapframe->sr);
|
||||
#endif
|
||||
|
||||
#ifdef KDB
|
||||
@ -997,11 +1001,11 @@ trapDump(char *msg)
|
||||
if (trp->cause == 0)
|
||||
break;
|
||||
|
||||
printf("%s: ADR %x PC %x CR %x SR %x\n",
|
||||
printf("%s: ADR %jx PC %jx CR %jx SR %jx\n",
|
||||
trap_type[(trp->cause & CR_EXC_CODE) >> CR_EXC_CODE_SHIFT],
|
||||
trp->vadr, trp->pc, trp->cause, trp->status);
|
||||
(intmax_t)trp->vadr, (intmax_t)trp->pc, (intmax_t)trp->cause, (intmax_t)trp->status);
|
||||
|
||||
printf(" RA %x SP %x code %d\n", trp->ra, trp->sp, trp->code);
|
||||
printf(" RA %jx SP %jx code %d\n", (intmax_t)trp->ra, (intmax_t)trp->sp, (int)trp->code);
|
||||
}
|
||||
intr_restore(s);
|
||||
}
|
||||
@ -1165,39 +1169,39 @@ static void
|
||||
log_frame_dump(struct trapframe *frame)
|
||||
{
|
||||
log(LOG_ERR, "Trapframe Register Dump:\n");
|
||||
log(LOG_ERR, "\tzero: %p\tat: %p\tv0: %p\tv1: %p\n",
|
||||
(void *)0, (void *)frame->ast, (void *)frame->v0, (void *)frame->v1);
|
||||
log(LOG_ERR, "\tzero: %#jx\tat: %#jx\tv0: %#jx\tv1: %#jx\n",
|
||||
(intmax_t)0, (intmax_t)frame->ast, (intmax_t)frame->v0, (intmax_t)frame->v1);
|
||||
|
||||
log(LOG_ERR, "\ta0: %p\ta1: %p\ta2: %p\ta3: %p\n",
|
||||
(void *)frame->a0, (void *)frame->a1, (void *)frame->a2, (void *)frame->a3);
|
||||
log(LOG_ERR, "\ta0: %#jx\ta1: %#jx\ta2: %#jx\ta3: %#jx\n",
|
||||
(intmax_t)frame->a0, (intmax_t)frame->a1, (intmax_t)frame->a2, (intmax_t)frame->a3);
|
||||
|
||||
log(LOG_ERR, "\tt0: %p\tt1: %p\tt2: %p\tt3: %p\n",
|
||||
(void *)frame->t0, (void *)frame->t1, (void *)frame->t2, (void *)frame->t3);
|
||||
log(LOG_ERR, "\tt0: %#jx\tt1: %#jx\tt2: %#jx\tt3: %#jx\n",
|
||||
(intmax_t)frame->t0, (intmax_t)frame->t1, (intmax_t)frame->t2, (intmax_t)frame->t3);
|
||||
|
||||
log(LOG_ERR, "\tt4: %p\tt5: %p\tt6: %p\tt7: %p\n",
|
||||
(void *)frame->t4, (void *)frame->t5, (void *)frame->t6, (void *)frame->t7);
|
||||
log(LOG_ERR, "\tt4: %#jx\tt5: %#jx\tt6: %#jx\tt7: %#jx\n",
|
||||
(intmax_t)frame->t4, (intmax_t)frame->t5, (intmax_t)frame->t6, (intmax_t)frame->t7);
|
||||
|
||||
log(LOG_ERR, "\tt8: %p\tt9: %p\ts0: %p\ts1: %p\n",
|
||||
(void *)frame->t8, (void *)frame->t9, (void *)frame->s0, (void *)frame->s1);
|
||||
log(LOG_ERR, "\tt8: %#jx\tt9: %#jx\ts0: %#jx\ts1: %#jx\n",
|
||||
(intmax_t)frame->t8, (intmax_t)frame->t9, (intmax_t)frame->s0, (intmax_t)frame->s1);
|
||||
|
||||
log(LOG_ERR, "\ts2: %p\ts3: %p\ts4: %p\ts5: %p\n",
|
||||
(void *)frame->s2, (void *)frame->s3, (void *)frame->s4, (void *)frame->s5);
|
||||
log(LOG_ERR, "\ts2: %#jx\ts3: %#jx\ts4: %#jx\ts5: %#jx\n",
|
||||
(intmax_t)frame->s2, (intmax_t)frame->s3, (intmax_t)frame->s4, (intmax_t)frame->s5);
|
||||
|
||||
log(LOG_ERR, "\ts6: %p\ts7: %p\tk0: %p\tk1: %p\n",
|
||||
(void *)frame->s6, (void *)frame->s7, (void *)frame->k0, (void *)frame->k1);
|
||||
log(LOG_ERR, "\ts6: %#jx\ts7: %#jx\tk0: %#jx\tk1: %#jx\n",
|
||||
(intmax_t)frame->s6, (intmax_t)frame->s7, (intmax_t)frame->k0, (intmax_t)frame->k1);
|
||||
|
||||
log(LOG_ERR, "\tgp: %p\tsp: %p\ts8: %p\tra: %p\n",
|
||||
(void *)frame->gp, (void *)frame->sp, (void *)frame->s8, (void *)frame->ra);
|
||||
log(LOG_ERR, "\tgp: %#jx\tsp: %#jx\ts8: %#jx\tra: %#jx\n",
|
||||
(intmax_t)frame->gp, (intmax_t)frame->sp, (intmax_t)frame->s8, (intmax_t)frame->ra);
|
||||
|
||||
log(LOG_ERR, "\tsr: %p\tmullo: %p\tmulhi: %p\tbadvaddr: %p\n",
|
||||
(void *)frame->sr, (void *)frame->mullo, (void *)frame->mulhi, (void *)frame->badvaddr);
|
||||
log(LOG_ERR, "\tsr: %#jx\tmullo: %#jx\tmulhi: %#jx\tbadvaddr: %#jx\n",
|
||||
(intmax_t)frame->sr, (intmax_t)frame->mullo, (intmax_t)frame->mulhi, (intmax_t)frame->badvaddr);
|
||||
|
||||
#ifdef IC_REG
|
||||
log(LOG_ERR, "\tcause: %p\tpc: %p\tic: %p\n",
|
||||
(void *)frame->cause, (void *)frame->pc, (void *)frame->ic);
|
||||
log(LOG_ERR, "\tcause: %#jx\tpc: %#jx\tic: %#jx\n",
|
||||
(intmax_t)frame->cause, (intmax_t)frame->pc, (intmax_t)frame->ic);
|
||||
#else
|
||||
log(LOG_ERR, "\tcause: %p\tpc: %p\n",
|
||||
(void *)frame->cause, (void *)frame->pc);
|
||||
log(LOG_ERR, "\tcause: %#jx\tpc: %#jx\n",
|
||||
(intmax_t)frame->cause, (intmax_t)frame->pc);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1206,39 +1210,39 @@ static void
|
||||
trap_frame_dump(struct trapframe *frame)
|
||||
{
|
||||
printf("Trapframe Register Dump:\n");
|
||||
printf("\tzero: %p\tat: %p\tv0: %p\tv1: %p\n",
|
||||
(void *)0, (void *)frame->ast, (void *)frame->v0, (void *)frame->v1);
|
||||
printf("\tzero: %#jx\tat: %#jx\tv0: %#jx\tv1: %#jx\n",
|
||||
(intmax_t)0, (intmax_t)frame->ast, (intmax_t)frame->v0, (intmax_t)frame->v1);
|
||||
|
||||
printf("\ta0: %p\ta1: %p\ta2: %p\ta3: %p\n",
|
||||
(void *)frame->a0, (void *)frame->a1, (void *)frame->a2, (void *)frame->a3);
|
||||
printf("\ta0: %#jx\ta1: %#jx\ta2: %#jx\ta3: %#jx\n",
|
||||
(intmax_t)frame->a0, (intmax_t)frame->a1, (intmax_t)frame->a2, (intmax_t)frame->a3);
|
||||
|
||||
printf("\tt0: %p\tt1: %p\tt2: %p\tt3: %p\n",
|
||||
(void *)frame->t0, (void *)frame->t1, (void *)frame->t2, (void *)frame->t3);
|
||||
printf("\tt0: %#jx\tt1: %#jx\tt2: %#jx\tt3: %#jx\n",
|
||||
(intmax_t)frame->t0, (intmax_t)frame->t1, (intmax_t)frame->t2, (intmax_t)frame->t3);
|
||||
|
||||
printf("\tt4: %p\tt5: %p\tt6: %p\tt7: %p\n",
|
||||
(void *)frame->t4, (void *)frame->t5, (void *)frame->t6, (void *)frame->t7);
|
||||
printf("\tt4: %#jx\tt5: %#jx\tt6: %#jx\tt7: %#jx\n",
|
||||
(intmax_t)frame->t4, (intmax_t)frame->t5, (intmax_t)frame->t6, (intmax_t)frame->t7);
|
||||
|
||||
printf("\tt8: %p\tt9: %p\ts0: %p\ts1: %p\n",
|
||||
(void *)frame->t8, (void *)frame->t9, (void *)frame->s0, (void *)frame->s1);
|
||||
printf("\tt8: %#jx\tt9: %#jx\ts0: %#jx\ts1: %#jx\n",
|
||||
(intmax_t)frame->t8, (intmax_t)frame->t9, (intmax_t)frame->s0, (intmax_t)frame->s1);
|
||||
|
||||
printf("\ts2: %p\ts3: %p\ts4: %p\ts5: %p\n",
|
||||
(void *)frame->s2, (void *)frame->s3, (void *)frame->s4, (void *)frame->s5);
|
||||
printf("\ts2: %#jx\ts3: %#jx\ts4: %#jx\ts5: %#jx\n",
|
||||
(intmax_t)frame->s2, (intmax_t)frame->s3, (intmax_t)frame->s4, (intmax_t)frame->s5);
|
||||
|
||||
printf("\ts6: %p\ts7: %p\tk0: %p\tk1: %p\n",
|
||||
(void *)frame->s6, (void *)frame->s7, (void *)frame->k0, (void *)frame->k1);
|
||||
printf("\ts6: %#jx\ts7: %#jx\tk0: %#jx\tk1: %#jx\n",
|
||||
(intmax_t)frame->s6, (intmax_t)frame->s7, (intmax_t)frame->k0, (intmax_t)frame->k1);
|
||||
|
||||
printf("\tgp: %p\tsp: %p\ts8: %p\tra: %p\n",
|
||||
(void *)frame->gp, (void *)frame->sp, (void *)frame->s8, (void *)frame->ra);
|
||||
printf("\tgp: %#jx\tsp: %#jx\ts8: %#jx\tra: %#jx\n",
|
||||
(intmax_t)frame->gp, (intmax_t)frame->sp, (intmax_t)frame->s8, (intmax_t)frame->ra);
|
||||
|
||||
printf("\tsr: %p\tmullo: %p\tmulhi: %p\tbadvaddr: %p\n",
|
||||
(void *)frame->sr, (void *)frame->mullo, (void *)frame->mulhi, (void *)frame->badvaddr);
|
||||
printf("\tsr: %#jx\tmullo: %#jx\tmulhi: %#jx\tbadvaddr: %#jx\n",
|
||||
(intmax_t)frame->sr, (intmax_t)frame->mullo, (intmax_t)frame->mulhi, (intmax_t)frame->badvaddr);
|
||||
|
||||
#ifdef IC_REG
|
||||
printf("\tcause: %p\tpc: %p\tic: %p\n",
|
||||
(void *)frame->cause, (void *)frame->pc, (void *)frame->ic);
|
||||
printf("\tcause: %#jx\tpc: %#jx\tic: %#jx\n",
|
||||
(intmax_t)frame->cause, (intmax_t)frame->pc, (intmax_t)frame->ic);
|
||||
#else
|
||||
printf("\tcause: %p\tpc: %p\n",
|
||||
(void *)frame->cause, (void *)frame->pc);
|
||||
printf("\tcause: %#jx\tpc: %#jx\n",
|
||||
(intmax_t)frame->cause, (intmax_t)frame->pc);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1252,7 +1256,7 @@ get_mapping_info(vm_offset_t va, pd_entry_t **pdepp, pt_entry_t **ptepp)
|
||||
pd_entry_t *pdep;
|
||||
struct proc *p = curproc;
|
||||
|
||||
pdep = (&(p->p_vmspace->vm_pmap.pm_segtab[va >> SEGSHIFT]));
|
||||
pdep = (&(p->p_vmspace->vm_pmap.pm_segtab[(va >> SEGSHIFT) & (NPDEPG - 1)]));
|
||||
if (*pdep)
|
||||
ptep = pmap_pte(&p->p_vmspace->vm_pmap, va);
|
||||
else
|
||||
@ -1262,6 +1266,50 @@ get_mapping_info(vm_offset_t va, pd_entry_t **pdepp, pt_entry_t **ptepp)
|
||||
*ptepp = ptep;
|
||||
}
|
||||
|
||||
static void
|
||||
log_illegal_instruction(const char *msg, struct trapframe *frame)
|
||||
{
|
||||
pt_entry_t *ptep;
|
||||
pd_entry_t *pdep;
|
||||
unsigned int *addr;
|
||||
struct proc *p = curproc;
|
||||
register_t pc;
|
||||
|
||||
#ifdef SMP
|
||||
printf("cpuid = %d\n", PCPU_GET(cpuid));
|
||||
#endif
|
||||
pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0);
|
||||
log(LOG_ERR, "%s: pid %d (%s), uid %d: pc %#jx ra %#jx\n",
|
||||
msg, p->p_pid, p->p_comm,
|
||||
p->p_ucred ? p->p_ucred->cr_uid : -1,
|
||||
(intmax_t)pc,
|
||||
(intmax_t)frame->ra);
|
||||
|
||||
/* log registers in trap frame */
|
||||
log_frame_dump(frame);
|
||||
|
||||
get_mapping_info((vm_offset_t)pc, &pdep, &ptep);
|
||||
|
||||
/*
|
||||
* Dump a few words around faulting instruction, if the addres is
|
||||
* valid.
|
||||
*/
|
||||
if (!(pc & 3) &&
|
||||
useracc((caddr_t)(intptr_t)pc, sizeof(int) * 4, VM_PROT_READ)) {
|
||||
/* dump page table entry for faulting instruction */
|
||||
log(LOG_ERR, "Page table info for pc address %#jx: pde = %p, pte = %#x\n",
|
||||
(intmax_t)pc, (void *)(intptr_t)*pdep, ptep ? *ptep : 0);
|
||||
|
||||
addr = (unsigned int *)(intptr_t)pc;
|
||||
log(LOG_ERR, "Dumping 4 words starting at pc address %p: \n",
|
||||
addr);
|
||||
log(LOG_ERR, "%08x %08x %08x %08x\n",
|
||||
addr[0], addr[1], addr[2], addr[3]);
|
||||
} else {
|
||||
log(LOG_ERR, "pc address %#jx is inaccessible, pde = %p, pte = %#x\n",
|
||||
(intmax_t)pc, (void *)(intptr_t)*pdep, ptep ? *ptep : 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
log_bad_page_fault(char *msg, struct trapframe *frame, int trap_type)
|
||||
@ -1293,12 +1341,12 @@ log_bad_page_fault(char *msg, struct trapframe *frame, int trap_type)
|
||||
}
|
||||
|
||||
pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0);
|
||||
log(LOG_ERR, "%s: pid %d (%s), uid %d: pc %p got a %s fault at %p\n",
|
||||
log(LOG_ERR, "%s: pid %d (%s), uid %d: pc %#jx got a %s fault at %#jx\n",
|
||||
msg, p->p_pid, p->p_comm,
|
||||
p->p_ucred ? p->p_ucred->cr_uid : -1,
|
||||
(void *)pc,
|
||||
(intmax_t)pc,
|
||||
read_or_write,
|
||||
(void *)frame->badvaddr);
|
||||
(intmax_t)frame->badvaddr);
|
||||
|
||||
/* log registers in trap frame */
|
||||
log_frame_dump(frame);
|
||||
@ -1311,21 +1359,24 @@ log_bad_page_fault(char *msg, struct trapframe *frame, int trap_type)
|
||||
*/
|
||||
if (!(pc & 3) && (pc != frame->badvaddr) &&
|
||||
(trap_type != T_BUS_ERR_IFETCH) &&
|
||||
useracc((caddr_t)pc, sizeof(int) * 4, VM_PROT_READ)) {
|
||||
useracc((caddr_t)(intptr_t)pc, sizeof(int) * 4, VM_PROT_READ)) {
|
||||
/* dump page table entry for faulting instruction */
|
||||
log(LOG_ERR, "Page table info for pc address %p: pde = %p, pte = 0x%lx\n",
|
||||
(void *)pc, *pdep, ptep ? *ptep : 0);
|
||||
log(LOG_ERR, "Page table info for pc address %#jx: pde = %p, pte = %#x\n",
|
||||
(intmax_t)pc, (void *)(intptr_t)*pdep, ptep ? *ptep : 0);
|
||||
|
||||
addr = (unsigned int *)pc;
|
||||
addr = (unsigned int *)(intptr_t)pc;
|
||||
log(LOG_ERR, "Dumping 4 words starting at pc address %p: \n",
|
||||
addr);
|
||||
log(LOG_ERR, "%08x %08x %08x %08x\n",
|
||||
addr[0], addr[1], addr[2], addr[3]);
|
||||
} else {
|
||||
log(LOG_ERR, "pc address %p is inaccessible, pde = 0x%p, pte = 0x%lx\n",
|
||||
(void *)pc, *pdep, ptep ? *ptep : 0);
|
||||
log(LOG_ERR, "pc address %#jx is inaccessible, pde = %p, pte = %#x\n",
|
||||
(intmax_t)pc, (void *)(intptr_t)*pdep, ptep ? *ptep : 0);
|
||||
}
|
||||
/* panic("Bad trap");*/
|
||||
|
||||
get_mapping_info((vm_offset_t)frame->badvaddr, &pdep, &ptep);
|
||||
log(LOG_ERR, "Page table info for bad address %#jx: pde = %p, pte = %#x\n",
|
||||
(intmax_t)frame->badvaddr, (void *)(intptr_t)*pdep, ptep ? *ptep : 0);
|
||||
}
|
||||
|
||||
|
||||
@ -1336,7 +1387,7 @@ static int
|
||||
mips_unaligned_load_store(struct trapframe *frame, register_t addr, register_t pc)
|
||||
{
|
||||
register_t *reg = (register_t *) frame;
|
||||
u_int32_t inst = *((u_int32_t *) pc);
|
||||
u_int32_t inst = *((u_int32_t *)(intptr_t)pc);
|
||||
u_int32_t value_msb, value;
|
||||
int access_type = 0;
|
||||
|
||||
@ -1432,9 +1483,9 @@ emulate_unaligned_access(struct trapframe *frame)
|
||||
else
|
||||
frame->pc += 4;
|
||||
|
||||
log(LOG_INFO, "Unaligned %s: pc=%p, badvaddr=%p\n",
|
||||
access_name[access_type - 1], (void *)pc,
|
||||
(void *)frame->badvaddr);
|
||||
log(LOG_INFO, "Unaligned %s: pc=%#jx, badvaddr=%#jx\n",
|
||||
access_name[access_type - 1], (intmax_t)pc,
|
||||
(intmax_t)frame->badvaddr);
|
||||
}
|
||||
}
|
||||
return access_type;
|
||||
|
@ -647,7 +647,7 @@ DB_SHOW_COMMAND(pcb, ddb_dump_pcb)
|
||||
DB_PRINT_REG_ARRAY(pcb, pcb_context, PCB_REG_GP);
|
||||
DB_PRINT_REG_ARRAY(pcb, pcb_context, PCB_REG_PC);
|
||||
|
||||
db_printf("PCB onfault = %d\n", pcb->pcb_onfault);
|
||||
db_printf("PCB onfault = %p\n", pcb->pcb_onfault);
|
||||
db_printf("md_saved_intr = 0x%0lx\n", (long)td->td_md.md_saved_intr);
|
||||
db_printf("md_spinlock_count = %d\n", td->td_md.md_spinlock_count);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user