From: "Jan Beulich" - make the page table contents printing PAE capable - make sure the address stored in current->thread.cr2 is unmodified from what was read from CR2 - don't call oops_may_print() multiple times, when one time suffices Signed-off-by: Jan Beulich Cc: Andi Kleen Signed-off-by: Andrew Morton --- arch/i386/mm/fault.c | 54 ++++++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 19 deletions(-) diff -puN arch/i386/mm/fault.c~i386-adjustments-to-page-table-dump-during-oops arch/i386/mm/fault.c --- a/arch/i386/mm/fault.c~i386-adjustments-to-page-table-dump-during-oops +++ a/arch/i386/mm/fault.c @@ -327,7 +327,6 @@ fastcall void __kprobes do_page_fault(st struct mm_struct *mm; struct vm_area_struct * vma; unsigned long address; - unsigned long page; int write, si_code; /* get the address */ @@ -538,7 +537,12 @@ no_context: bust_spinlocks(1); if (oops_may_print()) { - #ifdef CONFIG_X86_PAE + unsigned long page; +#ifndef CONFIG_X86_PAE + typedef unsigned long pgt_t; +#else + typedef unsigned long long pgt_t; + if (error_code & 16) { pte_t *pte = lookup_address(address); @@ -547,7 +551,7 @@ no_context: "NX-protected page - exploit attempt? " "(uid: %d)\n", current->uid); } - #endif +#endif if (address < PAGE_SIZE) printk(KERN_ALERT "BUG: unable to handle kernel NULL " "pointer dereference"); @@ -557,25 +561,37 @@ no_context: printk(" at virtual address %08lx\n",address); printk(KERN_ALERT " printing eip:\n"); printk("%08lx\n", regs->eip); - } - page = read_cr3(); - page = ((unsigned long *) __va(page))[address >> 22]; - if (oops_may_print()) + + page = read_cr3(); + page = ((pgt_t *) __va(page))[address >> PGDIR_SHIFT]; +#ifdef CONFIG_X86_PAE + printk(KERN_ALERT "*pdpt = %08lx\n", page); + if (page & 1) { + page &= PAGE_MASK; + page = ((pgt_t *) __va(page))[(address >> PMD_SHIFT) + & (PTRS_PER_PMD - 1)]; + printk(KERN_ALERT "*pde = %08lx\n", page); + } +#else printk(KERN_ALERT "*pde = %08lx\n", page); - /* - * We must not directly access the pte in the highpte - * case, the page table might be allocated in highmem. - * And lets rather not kmap-atomic the pte, just in case - * it's allocated already. - */ +#endif + + /* + * We must not directly access the pte in the highpte + * case, the page table might be allocated in highmem. + * And lets rather not kmap-atomic the pte, just in case + * it's allocated already. + */ #ifndef CONFIG_HIGHPTE - if ((page & 1) && oops_may_print()) { - page &= PAGE_MASK; - address &= 0x003ff000; - page = ((unsigned long *) __va(page))[address >> PAGE_SHIFT]; - printk(KERN_ALERT "*pte = %08lx\n", page); - } + if (page & 1) { + page &= PAGE_MASK; + page = ((pgt_t *) __va(page))[(address >> PAGE_SHIFT) + & (PTRS_PER_PTE - 1)]; + printk(KERN_ALERT "*pte = %08lx\n", page); + } #endif + } + tsk->thread.cr2 = address; tsk->thread.trap_no = 14; tsk->thread.error_code = error_code; _