Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.34-rc3 472 lines 11 kB view raw
1/* 2 * arch/sh/mm/tlb-flush_64.c 3 * 4 * Copyright (C) 2000, 2001 Paolo Alberelli 5 * Copyright (C) 2003 Richard Curnow (/proc/tlb, bug fixes) 6 * Copyright (C) 2003 - 2009 Paul Mundt 7 * 8 * This file is subject to the terms and conditions of the GNU General Public 9 * License. See the file "COPYING" in the main directory of this archive 10 * for more details. 11 */ 12#include <linux/signal.h> 13#include <linux/rwsem.h> 14#include <linux/sched.h> 15#include <linux/kernel.h> 16#include <linux/errno.h> 17#include <linux/string.h> 18#include <linux/types.h> 19#include <linux/ptrace.h> 20#include <linux/mman.h> 21#include <linux/mm.h> 22#include <linux/smp.h> 23#include <linux/perf_event.h> 24#include <linux/interrupt.h> 25#include <asm/system.h> 26#include <asm/io.h> 27#include <asm/tlb.h> 28#include <asm/uaccess.h> 29#include <asm/pgalloc.h> 30#include <asm/mmu_context.h> 31 32extern void die(const char *,struct pt_regs *,long); 33 34#define PFLAG(val,flag) (( (val) & (flag) ) ? #flag : "" ) 35#define PPROT(flag) PFLAG(pgprot_val(prot),flag) 36 37static inline void print_prots(pgprot_t prot) 38{ 39 printk("prot is 0x%016llx\n",pgprot_val(prot)); 40 41 printk("%s %s %s %s %s\n",PPROT(_PAGE_SHARED),PPROT(_PAGE_READ), 42 PPROT(_PAGE_EXECUTE),PPROT(_PAGE_WRITE),PPROT(_PAGE_USER)); 43} 44 45static inline void print_vma(struct vm_area_struct *vma) 46{ 47 printk("vma start 0x%08lx\n", vma->vm_start); 48 printk("vma end 0x%08lx\n", vma->vm_end); 49 50 print_prots(vma->vm_page_prot); 51 printk("vm_flags 0x%08lx\n", vma->vm_flags); 52} 53 54static inline void print_task(struct task_struct *tsk) 55{ 56 printk("Task pid %d\n", task_pid_nr(tsk)); 57} 58 59static pte_t *lookup_pte(struct mm_struct *mm, unsigned long address) 60{ 61 pgd_t *dir; 62 pud_t *pud; 63 pmd_t *pmd; 64 pte_t *pte; 65 pte_t entry; 66 67 dir = pgd_offset(mm, address); 68 if (pgd_none(*dir)) 69 return NULL; 70 71 pud = pud_offset(dir, address); 72 if (pud_none(*pud)) 73 return NULL; 74 75 pmd = pmd_offset(pud, address); 76 if (pmd_none(*pmd)) 77 return NULL; 78 79 pte = pte_offset_kernel(pmd, address); 80 entry = *pte; 81 if (pte_none(entry) || !pte_present(entry)) 82 return NULL; 83 84 return pte; 85} 86 87/* 88 * This routine handles page faults. It determines the address, 89 * and the problem, and then passes it off to one of the appropriate 90 * routines. 91 */ 92asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess, 93 unsigned long textaccess, unsigned long address) 94{ 95 struct task_struct *tsk; 96 struct mm_struct *mm; 97 struct vm_area_struct * vma; 98 const struct exception_table_entry *fixup; 99 pte_t *pte; 100 int fault; 101 102 /* SIM 103 * Note this is now called with interrupts still disabled 104 * This is to cope with being called for a missing IO port 105 * address with interrupts disabled. This should be fixed as 106 * soon as we have a better 'fast path' miss handler. 107 * 108 * Plus take care how you try and debug this stuff. 109 * For example, writing debug data to a port which you 110 * have just faulted on is not going to work. 111 */ 112 113 tsk = current; 114 mm = tsk->mm; 115 116 /* Not an IO address, so reenable interrupts */ 117 local_irq_enable(); 118 119 perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address); 120 121 /* 122 * If we're in an interrupt or have no user 123 * context, we must not take the fault.. 124 */ 125 if (in_atomic() || !mm) 126 goto no_context; 127 128 /* TLB misses upon some cache flushes get done under cli() */ 129 down_read(&mm->mmap_sem); 130 131 vma = find_vma(mm, address); 132 133 if (!vma) { 134#ifdef DEBUG_FAULT 135 print_task(tsk); 136 printk("%s:%d fault, address is 0x%08x PC %016Lx textaccess %d writeaccess %d\n", 137 __func__, __LINE__, 138 address,regs->pc,textaccess,writeaccess); 139 show_regs(regs); 140#endif 141 goto bad_area; 142 } 143 if (vma->vm_start <= address) { 144 goto good_area; 145 } 146 147 if (!(vma->vm_flags & VM_GROWSDOWN)) { 148#ifdef DEBUG_FAULT 149 print_task(tsk); 150 printk("%s:%d fault, address is 0x%08x PC %016Lx textaccess %d writeaccess %d\n", 151 __func__, __LINE__, 152 address,regs->pc,textaccess,writeaccess); 153 show_regs(regs); 154 155 print_vma(vma); 156#endif 157 goto bad_area; 158 } 159 if (expand_stack(vma, address)) { 160#ifdef DEBUG_FAULT 161 print_task(tsk); 162 printk("%s:%d fault, address is 0x%08x PC %016Lx textaccess %d writeaccess %d\n", 163 __func__, __LINE__, 164 address,regs->pc,textaccess,writeaccess); 165 show_regs(regs); 166#endif 167 goto bad_area; 168 } 169/* 170 * Ok, we have a good vm_area for this memory access, so 171 * we can handle it.. 172 */ 173good_area: 174 if (textaccess) { 175 if (!(vma->vm_flags & VM_EXEC)) 176 goto bad_area; 177 } else { 178 if (writeaccess) { 179 if (!(vma->vm_flags & VM_WRITE)) 180 goto bad_area; 181 } else { 182 if (!(vma->vm_flags & VM_READ)) 183 goto bad_area; 184 } 185 } 186 187 /* 188 * If for any reason at all we couldn't handle the fault, 189 * make sure we exit gracefully rather than endlessly redo 190 * the fault. 191 */ 192survive: 193 fault = handle_mm_fault(mm, vma, address, writeaccess ? FAULT_FLAG_WRITE : 0); 194 if (unlikely(fault & VM_FAULT_ERROR)) { 195 if (fault & VM_FAULT_OOM) 196 goto out_of_memory; 197 else if (fault & VM_FAULT_SIGBUS) 198 goto do_sigbus; 199 BUG(); 200 } 201 202 if (fault & VM_FAULT_MAJOR) { 203 tsk->maj_flt++; 204 perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0, 205 regs, address); 206 } else { 207 tsk->min_flt++; 208 perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0, 209 regs, address); 210 } 211 212 /* If we get here, the page fault has been handled. Do the TLB refill 213 now from the newly-setup PTE, to avoid having to fault again right 214 away on the same instruction. */ 215 pte = lookup_pte (mm, address); 216 if (!pte) { 217 /* From empirical evidence, we can get here, due to 218 !pte_present(pte). (e.g. if a swap-in occurs, and the page 219 is swapped back out again before the process that wanted it 220 gets rescheduled?) */ 221 goto no_pte; 222 } 223 224 __do_tlb_refill(address, textaccess, pte); 225 226no_pte: 227 228 up_read(&mm->mmap_sem); 229 return; 230 231/* 232 * Something tried to access memory that isn't in our memory map.. 233 * Fix it, but check if it's kernel or user first.. 234 */ 235bad_area: 236#ifdef DEBUG_FAULT 237 printk("fault:bad area\n"); 238#endif 239 up_read(&mm->mmap_sem); 240 241 if (user_mode(regs)) { 242 static int count=0; 243 siginfo_t info; 244 if (count < 4) { 245 /* This is really to help debug faults when starting 246 * usermode, so only need a few */ 247 count++; 248 printk("user mode bad_area address=%08lx pid=%d (%s) pc=%08lx\n", 249 address, task_pid_nr(current), current->comm, 250 (unsigned long) regs->pc); 251#if 0 252 show_regs(regs); 253#endif 254 } 255 if (is_global_init(tsk)) { 256 panic("INIT had user mode bad_area\n"); 257 } 258 tsk->thread.address = address; 259 tsk->thread.error_code = writeaccess; 260 info.si_signo = SIGSEGV; 261 info.si_errno = 0; 262 info.si_addr = (void *) address; 263 force_sig_info(SIGSEGV, &info, tsk); 264 return; 265 } 266 267no_context: 268#ifdef DEBUG_FAULT 269 printk("fault:No context\n"); 270#endif 271 /* Are we prepared to handle this kernel fault? */ 272 fixup = search_exception_tables(regs->pc); 273 if (fixup) { 274 regs->pc = fixup->fixup; 275 return; 276 } 277 278/* 279 * Oops. The kernel tried to access some bad page. We'll have to 280 * terminate things with extreme prejudice. 281 * 282 */ 283 if (address < PAGE_SIZE) 284 printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference"); 285 else 286 printk(KERN_ALERT "Unable to handle kernel paging request"); 287 printk(" at virtual address %08lx\n", address); 288 printk(KERN_ALERT "pc = %08Lx%08Lx\n", regs->pc >> 32, regs->pc & 0xffffffff); 289 die("Oops", regs, writeaccess); 290 do_exit(SIGKILL); 291 292/* 293 * We ran out of memory, or some other thing happened to us that made 294 * us unable to handle the page fault gracefully. 295 */ 296out_of_memory: 297 if (is_global_init(current)) { 298 panic("INIT out of memory\n"); 299 yield(); 300 goto survive; 301 } 302 printk("fault:Out of memory\n"); 303 up_read(&mm->mmap_sem); 304 if (is_global_init(current)) { 305 yield(); 306 down_read(&mm->mmap_sem); 307 goto survive; 308 } 309 printk("VM: killing process %s\n", tsk->comm); 310 if (user_mode(regs)) 311 do_group_exit(SIGKILL); 312 goto no_context; 313 314do_sigbus: 315 printk("fault:Do sigbus\n"); 316 up_read(&mm->mmap_sem); 317 318 /* 319 * Send a sigbus, regardless of whether we were in kernel 320 * or user mode. 321 */ 322 tsk->thread.address = address; 323 tsk->thread.error_code = writeaccess; 324 tsk->thread.trap_no = 14; 325 force_sig(SIGBUS, tsk); 326 327 /* Kernel mode? Handle exceptions or die */ 328 if (!user_mode(regs)) 329 goto no_context; 330} 331 332void local_flush_tlb_one(unsigned long asid, unsigned long page) 333{ 334 unsigned long long match, pteh=0, lpage; 335 unsigned long tlb; 336 337 /* 338 * Sign-extend based on neff. 339 */ 340 lpage = neff_sign_extend(page); 341 match = (asid << PTEH_ASID_SHIFT) | PTEH_VALID; 342 match |= lpage; 343 344 for_each_itlb_entry(tlb) { 345 asm volatile ("getcfg %1, 0, %0" 346 : "=r" (pteh) 347 : "r" (tlb) ); 348 349 if (pteh == match) { 350 __flush_tlb_slot(tlb); 351 break; 352 } 353 } 354 355 for_each_dtlb_entry(tlb) { 356 asm volatile ("getcfg %1, 0, %0" 357 : "=r" (pteh) 358 : "r" (tlb) ); 359 360 if (pteh == match) { 361 __flush_tlb_slot(tlb); 362 break; 363 } 364 365 } 366} 367 368void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) 369{ 370 unsigned long flags; 371 372 if (vma->vm_mm) { 373 page &= PAGE_MASK; 374 local_irq_save(flags); 375 local_flush_tlb_one(get_asid(), page); 376 local_irq_restore(flags); 377 } 378} 379 380void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, 381 unsigned long end) 382{ 383 unsigned long flags; 384 unsigned long long match, pteh=0, pteh_epn, pteh_low; 385 unsigned long tlb; 386 unsigned int cpu = smp_processor_id(); 387 struct mm_struct *mm; 388 389 mm = vma->vm_mm; 390 if (cpu_context(cpu, mm) == NO_CONTEXT) 391 return; 392 393 local_irq_save(flags); 394 395 start &= PAGE_MASK; 396 end &= PAGE_MASK; 397 398 match = (cpu_asid(cpu, mm) << PTEH_ASID_SHIFT) | PTEH_VALID; 399 400 /* Flush ITLB */ 401 for_each_itlb_entry(tlb) { 402 asm volatile ("getcfg %1, 0, %0" 403 : "=r" (pteh) 404 : "r" (tlb) ); 405 406 pteh_epn = pteh & PAGE_MASK; 407 pteh_low = pteh & ~PAGE_MASK; 408 409 if (pteh_low == match && pteh_epn >= start && pteh_epn <= end) 410 __flush_tlb_slot(tlb); 411 } 412 413 /* Flush DTLB */ 414 for_each_dtlb_entry(tlb) { 415 asm volatile ("getcfg %1, 0, %0" 416 : "=r" (pteh) 417 : "r" (tlb) ); 418 419 pteh_epn = pteh & PAGE_MASK; 420 pteh_low = pteh & ~PAGE_MASK; 421 422 if (pteh_low == match && pteh_epn >= start && pteh_epn <= end) 423 __flush_tlb_slot(tlb); 424 } 425 426 local_irq_restore(flags); 427} 428 429void local_flush_tlb_mm(struct mm_struct *mm) 430{ 431 unsigned long flags; 432 unsigned int cpu = smp_processor_id(); 433 434 if (cpu_context(cpu, mm) == NO_CONTEXT) 435 return; 436 437 local_irq_save(flags); 438 439 cpu_context(cpu, mm) = NO_CONTEXT; 440 if (mm == current->mm) 441 activate_context(mm, cpu); 442 443 local_irq_restore(flags); 444} 445 446void local_flush_tlb_all(void) 447{ 448 /* Invalidate all, including shared pages, excluding fixed TLBs */ 449 unsigned long flags, tlb; 450 451 local_irq_save(flags); 452 453 /* Flush each ITLB entry */ 454 for_each_itlb_entry(tlb) 455 __flush_tlb_slot(tlb); 456 457 /* Flush each DTLB entry */ 458 for_each_dtlb_entry(tlb) 459 __flush_tlb_slot(tlb); 460 461 local_irq_restore(flags); 462} 463 464void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) 465{ 466 /* FIXME: Optimize this later.. */ 467 flush_tlb_all(); 468} 469 470void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte) 471{ 472}