diff options
-rw-r--r-- | arch/sh/mm/fault_32.c | 97 |
1 files changed, 74 insertions, 23 deletions
diff --git a/arch/sh/mm/fault_32.c b/arch/sh/mm/fault_32.c index e99b104d967a..c5cd87868c73 100644 --- a/arch/sh/mm/fault_32.c +++ b/arch/sh/mm/fault_32.c | |||
@@ -35,6 +35,74 @@ static inline int notify_page_fault(struct pt_regs *regs, int trap) | |||
35 | return ret; | 35 | return ret; |
36 | } | 36 | } |
37 | 37 | ||
38 | /* | ||
39 | * This is useful to dump out the page tables associated with | ||
40 | * 'addr' in mm 'mm'. | ||
41 | */ | ||
42 | static void show_pte(struct mm_struct *mm, unsigned long addr) | ||
43 | { | ||
44 | pgd_t *pgd; | ||
45 | |||
46 | if (mm) | ||
47 | pgd = mm->pgd; | ||
48 | else | ||
49 | pgd = get_TTB(); | ||
50 | |||
51 | printk(KERN_ALERT "pgd = %p\n", pgd); | ||
52 | pgd += pgd_index(addr); | ||
53 | printk(KERN_ALERT "[%08lx] *pgd=%0*Lx", addr, | ||
54 | sizeof(*pgd) * 2, (u64)pgd_val(*pgd)); | ||
55 | |||
56 | do { | ||
57 | pud_t *pud; | ||
58 | pmd_t *pmd; | ||
59 | pte_t *pte; | ||
60 | |||
61 | if (pgd_none(*pgd)) | ||
62 | break; | ||
63 | |||
64 | if (pgd_bad(*pgd)) { | ||
65 | printk("(bad)"); | ||
66 | break; | ||
67 | } | ||
68 | |||
69 | pud = pud_offset(pgd, addr); | ||
70 | if (PTRS_PER_PUD != 1) | ||
71 | printk(", *pud=%0*Lx", sizeof(*pud) * 2, | ||
72 | (u64)pud_val(*pud)); | ||
73 | |||
74 | if (pud_none(*pud)) | ||
75 | break; | ||
76 | |||
77 | if (pud_bad(*pud)) { | ||
78 | printk("(bad)"); | ||
79 | break; | ||
80 | } | ||
81 | |||
82 | pmd = pmd_offset(pud, addr); | ||
83 | if (PTRS_PER_PMD != 1) | ||
84 | printk(", *pmd=%0*Lx", sizeof(*pmd) * 2, | ||
85 | (u64)pmd_val(*pmd)); | ||
86 | |||
87 | if (pmd_none(*pmd)) | ||
88 | break; | ||
89 | |||
90 | if (pmd_bad(*pmd)) { | ||
91 | printk("(bad)"); | ||
92 | break; | ||
93 | } | ||
94 | |||
95 | /* We must not map this if we have highmem enabled */ | ||
96 | if (PageHighMem(pfn_to_page(pmd_val(*pmd) >> PAGE_SHIFT))) | ||
97 | break; | ||
98 | |||
99 | pte = pte_offset_kernel(pmd, addr); | ||
100 | printk(", *pte=%0*Lx", sizeof(*pte) * 2, (u64)pte_val(*pte)); | ||
101 | } while (0); | ||
102 | |||
103 | printk("\n"); | ||
104 | } | ||
105 | |||
38 | static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address) | 106 | static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address) |
39 | { | 107 | { |
40 | unsigned index = pgd_index(address); | 108 | unsigned index = pgd_index(address); |
@@ -254,29 +322,12 @@ no_context: | |||
254 | bust_spinlocks(1); | 322 | bust_spinlocks(1); |
255 | 323 | ||
256 | if (oops_may_print()) { | 324 | if (oops_may_print()) { |
257 | unsigned long page; | 325 | printk(KERN_ALERT |
258 | 326 | "Unable to handle kernel %s at virtual address %08lx\n", | |
259 | if (address < PAGE_SIZE) | 327 | (address < PAGE_SIZE) ? "NULL pointer dereference" : |
260 | printk(KERN_ALERT "Unable to handle kernel NULL " | 328 | "paging request", address); |
261 | "pointer dereference"); | 329 | |
262 | else | 330 | show_pte(mm, address); |
263 | printk(KERN_ALERT "Unable to handle kernel paging " | ||
264 | "request"); | ||
265 | printk(" at virtual address %08lx\n", address); | ||
266 | printk(KERN_ALERT "pc = %08lx\n", regs->pc); | ||
267 | page = (unsigned long)get_TTB(); | ||
268 | if (page) { | ||
269 | page = ((__typeof__(page) *)page)[address >> PGDIR_SHIFT]; | ||
270 | printk(KERN_ALERT "*pde = %08lx\n", page); | ||
271 | if (page & _PAGE_PRESENT) { | ||
272 | page &= PAGE_MASK; | ||
273 | address &= 0x003ff000; | ||
274 | page = ((__typeof__(page) *) | ||
275 | __va(page))[address >> | ||
276 | PAGE_SHIFT]; | ||
277 | printk(KERN_ALERT "*pte = %08lx\n", page); | ||
278 | } | ||
279 | } | ||
280 | } | 331 | } |
281 | 332 | ||
282 | die("Oops", regs, writeaccess); | 333 | die("Oops", regs, writeaccess); |