1/* 2 * linux/arch/frv/mm/fault.c 3 * 4 * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. 5 * - Written by David Howells (dhowells@redhat.com) 6 * - Derived from arch/m68knommu/mm/fault.c 7 * - Copyright (C) 1998 D. Jeff Dionne <jeff@lineo.ca>, 8 * - Copyright (C) 2000 Lineo, Inc. (www.lineo.com) 9 * 10 * Based on: 11 * 12 * linux/arch/m68k/mm/fault.c 13 * 14 * Copyright (C) 1995 Hamish Macdonald 15 */ 16 17#include <linux/mman.h> 18#include <linux/mm.h> 19#include <linux/kernel.h> 20#include <linux/ptrace.h> 21#include <linux/hardirq.h> 22 23#include <asm/pgtable.h> 24#include <asm/uaccess.h> 25#include <asm/gdb-stub.h> 26 27/*****************************************************************************/ 28/* 29 * This routine handles page faults. It determines the problem, and 30 * then passes it off to one of the appropriate routines. 31 */ 32asmlinkage void do_page_fault(int datammu, unsigned long esr0, unsigned long ear0) 33{ 34 struct vm_area_struct *vma; 35 struct mm_struct *mm; 36 unsigned long _pme, lrai, lrad, fixup; 37 unsigned long flags = 0; 38 siginfo_t info; 39 pgd_t *pge; 40 pud_t *pue; 41 pte_t *pte; 42 int fault; 43 44#if 0 45 const char *atxc[16] = { 46 [0x0] = "mmu-miss", [0x8] = "multi-dat", [0x9] = "multi-sat", 47 [0xa] = "tlb-miss", [0xc] = "privilege", [0xd] = "write-prot", 48 }; 49 50 printk("do_page_fault(%d,%lx [%s],%lx)\n", 51 datammu, esr0, atxc[esr0 >> 20 & 0xf], ear0); 52#endif 53 54 mm = current->mm; 55 56 /* 57 * We fault-in kernel-space virtual memory on-demand. The 58 * 'reference' page table is init_mm.pgd. 59 * 60 * NOTE! We MUST NOT take any locks for this case. We may 61 * be in an interrupt or a critical region, and should 62 * only copy the information from the master page table, 63 * nothing more. 64 * 65 * This verifies that the fault happens in kernel space 66 * and that the fault was a page not present (invalid) error 67 */ 68 if (!user_mode(__frame) && (esr0 & ESR0_ATXC) == ESR0_ATXC_AMRTLB_MISS) { 69 if (ear0 >= VMALLOC_START && ear0 < VMALLOC_END) 70 goto kernel_pte_fault; 71 if (ear0 >= PKMAP_BASE && ear0 < PKMAP_END) 72 goto kernel_pte_fault; 73 } 74 75 info.si_code = SEGV_MAPERR; 76 77 /* 78 * If we're in an interrupt or have no user 79 * context, we must not take the fault.. 80 */ 81 if (in_atomic() || !mm) 82 goto no_context; 83 84 if (user_mode(__frame)) 85 flags |= FAULT_FLAG_USER; 86 87 down_read(&mm->mmap_sem); 88 89 vma = find_vma(mm, ear0); 90 if (!vma) 91 goto bad_area; 92 if (vma->vm_start <= ear0) 93 goto good_area; 94 if (!(vma->vm_flags & VM_GROWSDOWN)) 95 goto bad_area; 96 97 if (user_mode(__frame)) { 98 /* 99 * accessing the stack below %esp is always a bug. 100 * The "+ 32" is there due to some instructions (like 101 * pusha) doing post-decrement on the stack and that 102 * doesn't show up until later.. 103 */ 104 if ((ear0 & PAGE_MASK) + 2 * PAGE_SIZE < __frame->sp) { 105#if 0 106 printk("[%d] ### Access below stack @%lx (sp=%lx)\n", 107 current->pid, ear0, __frame->sp); 108 show_registers(__frame); 109 printk("[%d] ### Code: [%08lx] %02x %02x %02x %02x %02x %02x %02x %02x\n", 110 current->pid, 111 __frame->pc, 112 ((u8*)__frame->pc)[0], 113 ((u8*)__frame->pc)[1], 114 ((u8*)__frame->pc)[2], 115 ((u8*)__frame->pc)[3], 116 ((u8*)__frame->pc)[4], 117 ((u8*)__frame->pc)[5], 118 ((u8*)__frame->pc)[6], 119 ((u8*)__frame->pc)[7] 120 ); 121#endif 122 goto bad_area; 123 } 124 } 125 126 if (expand_stack(vma, ear0)) 127 goto bad_area; 128 129/* 130 * Ok, we have a good vm_area for this memory access, so 131 * we can handle it.. 132 */ 133 good_area: 134 info.si_code = SEGV_ACCERR; 135 switch (esr0 & ESR0_ATXC) { 136 default: 137 /* handle write to write protected page */ 138 case ESR0_ATXC_WP_EXCEP: 139#ifdef TEST_VERIFY_AREA 140 if (!(user_mode(__frame))) 141 printk("WP fault at %08lx\n", __frame->pc); 142#endif 143 if (!(vma->vm_flags & VM_WRITE)) 144 goto bad_area; 145 flags |= FAULT_FLAG_WRITE; 146 break; 147 148 /* handle read from protected page */ 149 case ESR0_ATXC_PRIV_EXCEP: 150 goto bad_area; 151 152 /* handle read, write or exec on absent page 153 * - can't support write without permitting read 154 * - don't support execute without permitting read and vice-versa 155 */ 156 case ESR0_ATXC_AMRTLB_MISS: 157 if (!(vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC))) 158 goto bad_area; 159 break; 160 } 161 162 /* 163 * If for any reason at all we couldn't handle the fault, 164 * make sure we exit gracefully rather than endlessly redo 165 * the fault. 166 */ 167 fault = handle_mm_fault(mm, vma, ear0, flags); 168 if (unlikely(fault & VM_FAULT_ERROR)) { 169 if (fault & VM_FAULT_OOM) 170 goto out_of_memory; 171 else if (fault & VM_FAULT_SIGSEGV) 172 goto bad_area; 173 else if (fault & VM_FAULT_SIGBUS) 174 goto do_sigbus; 175 BUG(); 176 } 177 if (fault & VM_FAULT_MAJOR) 178 current->maj_flt++; 179 else 180 current->min_flt++; 181 182 up_read(&mm->mmap_sem); 183 return; 184 185/* 186 * Something tried to access memory that isn't in our memory map.. 187 * Fix it, but check if it's kernel or user first.. 188 */ 189 bad_area: 190 up_read(&mm->mmap_sem); 191 192 /* User mode accesses just cause a SIGSEGV */ 193 if (user_mode(__frame)) { 194 info.si_signo = SIGSEGV; 195 info.si_errno = 0; 196 /* info.si_code has been set above */ 197 info.si_addr = (void *) ear0; 198 force_sig_info(SIGSEGV, &info, current); 199 return; 200 } 201 202 no_context: 203 /* are we prepared to handle this kernel fault? */ 204 if ((fixup = search_exception_table(__frame->pc)) != 0) { 205 __frame->pc = fixup; 206 return; 207 } 208 209/* 210 * Oops. The kernel tried to access some bad page. We'll have to 211 * terminate things with extreme prejudice. 212 */ 213 214 bust_spinlocks(1); 215 216 if (ear0 < PAGE_SIZE) 217 printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference"); 218 else 219 printk(KERN_ALERT "Unable to handle kernel paging request"); 220 printk(" at virtual addr %08lx\n", ear0); 221 printk(" PC : %08lx\n", __frame->pc); 222 printk(" EXC : esr0=%08lx ear0=%08lx\n", esr0, ear0); 223 224 asm("lrai %1,%0,#1,#0,#0" : "=&r"(lrai) : "r"(ear0)); 225 asm("lrad %1,%0,#1,#0,#0" : "=&r"(lrad) : "r"(ear0)); 226 227 printk(KERN_ALERT " LRAI: %08lx\n", lrai); 228 printk(KERN_ALERT " LRAD: %08lx\n", lrad); 229 230 __break_hijack_kernel_event(); 231 232 pge = pgd_offset(current->mm, ear0); 233 pue = pud_offset(pge, ear0); 234 _pme = pue->pue[0].ste[0]; 235 236 printk(KERN_ALERT " PGE : %8p { PME %08lx }\n", pge, _pme); 237 238 if (_pme & xAMPRx_V) { 239 unsigned long dampr, damlr, val; 240 241 asm volatile("movsg dampr2,%0 ! movgs %2,dampr2 ! movsg damlr2,%1" 242 : "=&r"(dampr), "=r"(damlr) 243 : "r" (_pme | xAMPRx_L|xAMPRx_SS_16Kb|xAMPRx_S|xAMPRx_C|xAMPRx_V) 244 ); 245 246 pte = (pte_t *) damlr + __pte_index(ear0); 247 val = pte_val(*pte); 248 249 asm volatile("movgs %0,dampr2" :: "r" (dampr)); 250 251 printk(KERN_ALERT " PTE : %8p { %08lx }\n", pte, val); 252 } 253 254 die_if_kernel("Oops\n"); 255 do_exit(SIGKILL); 256 257/* 258 * We ran out of memory, or some other thing happened to us that made 259 * us unable to handle the page fault gracefully. 260 */ 261 out_of_memory: 262 up_read(&mm->mmap_sem); 263 if (!user_mode(__frame)) 264 goto no_context; 265 pagefault_out_of_memory(); 266 return; 267 268 do_sigbus: 269 up_read(&mm->mmap_sem); 270 271 /* 272 * Send a sigbus, regardless of whether we were in kernel 273 * or user mode. 274 */ 275 info.si_signo = SIGBUS; 276 info.si_errno = 0; 277 info.si_code = BUS_ADRERR; 278 info.si_addr = (void *) ear0; 279 force_sig_info(SIGBUS, &info, current); 280 281 /* Kernel mode? Handle exceptions or die */ 282 if (!user_mode(__frame)) 283 goto no_context; 284 return; 285 286/* 287 * The fault was caused by a kernel PTE (such as installed by vmalloc or kmap) 288 */ 289 kernel_pte_fault: 290 { 291 /* 292 * Synchronize this task's top level page-table 293 * with the 'reference' page table. 294 * 295 * Do _not_ use "tsk" here. We might be inside 296 * an interrupt in the middle of a task switch.. 297 */ 298 int index = pgd_index(ear0); 299 pgd_t *pgd, *pgd_k; 300 pud_t *pud, *pud_k; 301 pmd_t *pmd, *pmd_k; 302 pte_t *pte_k; 303 304 pgd = (pgd_t *) __get_TTBR(); 305 pgd = (pgd_t *)__va(pgd) + index; 306 pgd_k = ((pgd_t *)(init_mm.pgd)) + index; 307 308 if (!pgd_present(*pgd_k)) 309 goto no_context; 310 //set_pgd(pgd, *pgd_k); /////// gcc ICE's on this line 311 312 pud_k = pud_offset(pgd_k, ear0); 313 if (!pud_present(*pud_k)) 314 goto no_context; 315 316 pmd_k = pmd_offset(pud_k, ear0); 317 if (!pmd_present(*pmd_k)) 318 goto no_context; 319 320 pud = pud_offset(pgd, ear0); 321 pmd = pmd_offset(pud, ear0); 322 set_pmd(pmd, *pmd_k); 323 324 pte_k = pte_offset_kernel(pmd_k, ear0); 325 if (!pte_present(*pte_k)) 326 goto no_context; 327 return; 328 } 329} /* end do_page_fault() */ 330