Benjamin Herrenschmidt <b...@kernel.crashing.org> wrote on 06/10/2009 00:37:28: > > On Tue, 2009-10-06 at 00:31 +0200, Joakim Tjernlund wrote: > > > > regs or regs->nip is NULL? Either one does not make sense > > In any case it might be a secondary problem as DAR is NULL already > > when you > > enter the page fault. > > > > > > insn = *((unsigned long *)regs->nip); > > > c000e110: 80 a9 00 00 lwz r5,0(r9) > > > > > > fails. > > > > hmm, I wonder if you managed to invalidate the a kernel TLB? > > Are you using pinned kernel TLBs? > > You should not dereference a user address like that. Use get_user !
So how does this look? Does it change anything? It should as the previous way was way off :( diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c index c33c6de..08a392f 100644 --- a/arch/powerpc/mm/fault.c +++ b/arch/powerpc/mm/fault.c @@ -153,7 +153,7 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, #ifdef DEBUG_DCBX const char *istr = NULL; - insn = *((unsigned long *)regs->nip); + __get_user(insn, (unsigned long __user *)regs->nip); if (((insn >> (31-5)) & 0x3f) == 31) { if (((insn >> 1) & 0x3ff) == 1014) /* dcbz ? 0x3f6 */ istr = "dcbz"; @@ -178,11 +178,12 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, ra, rb, dar); is_write = 0; } - +#if 0 if (trap == 0x300 && address != dar) { __asm__ ("mtdar %0" : : "r" (dar)); return 0; } +#endif } } #endif @@ -191,7 +192,7 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, /* This is from a dcbX or icbi insn gone bad, these * insn do not set DAR so we have to do it here instead */ - insn = *((unsigned long *)regs->nip); + __get_user(insn, (unsigned long __user *)regs->nip); ra = (insn >> (31-15)) & 0x1f; /* Reg RA */ rb = (insn >> (31-20)) & 0x1f; /* Reg RB */ _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev