162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * arch/microblaze/mm/fault.c 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Copyright (C) 2007 Xilinx, Inc. All rights reserved. 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Derived from "arch/ppc/mm/fault.c" 762306a36Sopenharmony_ci * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) 862306a36Sopenharmony_ci * 962306a36Sopenharmony_ci * Derived from "arch/i386/mm/fault.c" 1062306a36Sopenharmony_ci * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds 1162306a36Sopenharmony_ci * 1262306a36Sopenharmony_ci * Modified by Cort Dougan and Paul Mackerras. 1362306a36Sopenharmony_ci * 1462306a36Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General 1562306a36Sopenharmony_ci * Public License. See the file COPYING in the main directory of this 1662306a36Sopenharmony_ci * archive for more details. 1762306a36Sopenharmony_ci * 1862306a36Sopenharmony_ci */ 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci#include <linux/extable.h> 2162306a36Sopenharmony_ci#include <linux/signal.h> 2262306a36Sopenharmony_ci#include <linux/sched.h> 2362306a36Sopenharmony_ci#include <linux/kernel.h> 2462306a36Sopenharmony_ci#include <linux/errno.h> 2562306a36Sopenharmony_ci#include <linux/string.h> 2662306a36Sopenharmony_ci#include <linux/types.h> 2762306a36Sopenharmony_ci#include <linux/ptrace.h> 2862306a36Sopenharmony_ci#include <linux/mman.h> 2962306a36Sopenharmony_ci#include <linux/mm.h> 3062306a36Sopenharmony_ci#include <linux/interrupt.h> 3162306a36Sopenharmony_ci#include <linux/perf_event.h> 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci#include <asm/page.h> 3462306a36Sopenharmony_ci#include <asm/mmu.h> 3562306a36Sopenharmony_ci#include <linux/mmu_context.h> 3662306a36Sopenharmony_ci#include <linux/uaccess.h> 3762306a36Sopenharmony_ci#include <asm/exceptions.h> 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_cistatic unsigned long pte_misses; /* updated by do_page_fault() */ 4062306a36Sopenharmony_cistatic unsigned long pte_errors; /* updated by do_page_fault() */ 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci/* 4362306a36Sopenharmony_ci * Check whether the instruction at regs->pc is a store using 4462306a36Sopenharmony_ci * an update addressing form which will update r1. 4562306a36Sopenharmony_ci */ 4662306a36Sopenharmony_cistatic int store_updates_sp(struct pt_regs *regs) 4762306a36Sopenharmony_ci{ 4862306a36Sopenharmony_ci unsigned int inst; 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci if (get_user(inst, (unsigned int __user *)regs->pc)) 5162306a36Sopenharmony_ci return 0; 5262306a36Sopenharmony_ci /* check for 1 in the rD field */ 5362306a36Sopenharmony_ci if (((inst >> 21) & 0x1f) != 1) 5462306a36Sopenharmony_ci return 0; 5562306a36Sopenharmony_ci /* check for store opcodes */ 5662306a36Sopenharmony_ci if ((inst & 0xd0000000) == 0xd0000000) 5762306a36Sopenharmony_ci return 1; 5862306a36Sopenharmony_ci return 0; 5962306a36Sopenharmony_ci} 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci/* 6362306a36Sopenharmony_ci * bad_page_fault is called when we have a bad access from the kernel. 6462306a36Sopenharmony_ci * It is called from do_page_fault above and from some of the procedures 6562306a36Sopenharmony_ci * in traps.c. 6662306a36Sopenharmony_ci */ 6762306a36Sopenharmony_civoid bad_page_fault(struct pt_regs *regs, unsigned long address, int sig) 6862306a36Sopenharmony_ci{ 6962306a36Sopenharmony_ci const struct exception_table_entry *fixup; 7062306a36Sopenharmony_ci/* MS: no context */ 7162306a36Sopenharmony_ci /* Are we prepared to handle this fault? */ 7262306a36Sopenharmony_ci fixup = search_exception_tables(regs->pc); 7362306a36Sopenharmony_ci if (fixup) { 7462306a36Sopenharmony_ci regs->pc = fixup->fixup; 7562306a36Sopenharmony_ci return; 7662306a36Sopenharmony_ci } 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci /* kernel has accessed a bad area */ 7962306a36Sopenharmony_ci die("kernel access of bad area", regs, sig); 8062306a36Sopenharmony_ci} 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci/* 8362306a36Sopenharmony_ci * The error_code parameter is ESR for a data fault, 8462306a36Sopenharmony_ci * 0 for an instruction fault. 8562306a36Sopenharmony_ci */ 8662306a36Sopenharmony_civoid do_page_fault(struct pt_regs *regs, unsigned long address, 8762306a36Sopenharmony_ci unsigned long error_code) 8862306a36Sopenharmony_ci{ 8962306a36Sopenharmony_ci struct vm_area_struct *vma; 9062306a36Sopenharmony_ci struct mm_struct *mm = current->mm; 9162306a36Sopenharmony_ci int code = SEGV_MAPERR; 9262306a36Sopenharmony_ci int is_write = error_code & ESR_S; 9362306a36Sopenharmony_ci vm_fault_t fault; 9462306a36Sopenharmony_ci unsigned int flags = FAULT_FLAG_DEFAULT; 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci regs->ear = address; 9762306a36Sopenharmony_ci regs->esr = error_code; 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci /* On a kernel SLB miss we can only check for a valid exception entry */ 10062306a36Sopenharmony_ci if (unlikely(kernel_mode(regs) && (address >= TASK_SIZE))) { 10162306a36Sopenharmony_ci pr_warn("kernel task_size exceed"); 10262306a36Sopenharmony_ci _exception(SIGSEGV, regs, code, address); 10362306a36Sopenharmony_ci } 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci /* for instr TLB miss and instr storage exception ESR_S is undefined */ 10662306a36Sopenharmony_ci if ((error_code & 0x13) == 0x13 || (error_code & 0x11) == 0x11) 10762306a36Sopenharmony_ci is_write = 0; 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci if (unlikely(faulthandler_disabled() || !mm)) { 11062306a36Sopenharmony_ci if (kernel_mode(regs)) 11162306a36Sopenharmony_ci goto bad_area_nosemaphore; 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci /* faulthandler_disabled() in user mode is really bad, 11462306a36Sopenharmony_ci as is current->mm == NULL. */ 11562306a36Sopenharmony_ci pr_emerg("Page fault in user mode with faulthandler_disabled(), mm = %p\n", 11662306a36Sopenharmony_ci mm); 11762306a36Sopenharmony_ci pr_emerg("r15 = %lx MSR = %lx\n", 11862306a36Sopenharmony_ci regs->r15, regs->msr); 11962306a36Sopenharmony_ci die("Weird page fault", regs, SIGSEGV); 12062306a36Sopenharmony_ci } 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci if (user_mode(regs)) 12362306a36Sopenharmony_ci flags |= FAULT_FLAG_USER; 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address); 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci /* When running in the kernel we expect faults to occur only to 12862306a36Sopenharmony_ci * addresses in user space. All other faults represent errors in the 12962306a36Sopenharmony_ci * kernel and should generate an OOPS. Unfortunately, in the case of an 13062306a36Sopenharmony_ci * erroneous fault occurring in a code path which already holds mmap_lock 13162306a36Sopenharmony_ci * we will deadlock attempting to validate the fault against the 13262306a36Sopenharmony_ci * address space. Luckily the kernel only validly references user 13362306a36Sopenharmony_ci * space from well defined areas of code, which are listed in the 13462306a36Sopenharmony_ci * exceptions table. 13562306a36Sopenharmony_ci * 13662306a36Sopenharmony_ci * As the vast majority of faults will be valid we will only perform 13762306a36Sopenharmony_ci * the source reference check when there is a possibility of a deadlock. 13862306a36Sopenharmony_ci * Attempt to lock the address space, if we cannot we then validate the 13962306a36Sopenharmony_ci * source. If this is invalid we can skip the address space check, 14062306a36Sopenharmony_ci * thus avoiding the deadlock. 14162306a36Sopenharmony_ci */ 14262306a36Sopenharmony_ci if (unlikely(!mmap_read_trylock(mm))) { 14362306a36Sopenharmony_ci if (kernel_mode(regs) && !search_exception_tables(regs->pc)) 14462306a36Sopenharmony_ci goto bad_area_nosemaphore; 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ciretry: 14762306a36Sopenharmony_ci mmap_read_lock(mm); 14862306a36Sopenharmony_ci } 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci vma = find_vma(mm, address); 15162306a36Sopenharmony_ci if (unlikely(!vma)) 15262306a36Sopenharmony_ci goto bad_area; 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci if (vma->vm_start <= address) 15562306a36Sopenharmony_ci goto good_area; 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci if (unlikely(!(vma->vm_flags & VM_GROWSDOWN))) 15862306a36Sopenharmony_ci goto bad_area; 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci if (unlikely(!is_write)) 16162306a36Sopenharmony_ci goto bad_area; 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci /* 16462306a36Sopenharmony_ci * N.B. The ABI allows programs to access up to 16562306a36Sopenharmony_ci * a few hundred bytes below the stack pointer (TBD). 16662306a36Sopenharmony_ci * The kernel signal delivery code writes up to about 1.5kB 16762306a36Sopenharmony_ci * below the stack pointer (r1) before decrementing it. 16862306a36Sopenharmony_ci * The exec code can write slightly over 640kB to the stack 16962306a36Sopenharmony_ci * before setting the user r1. Thus we allow the stack to 17062306a36Sopenharmony_ci * expand to 1MB without further checks. 17162306a36Sopenharmony_ci */ 17262306a36Sopenharmony_ci if (unlikely(address + 0x100000 < vma->vm_end)) { 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci /* get user regs even if this fault is in kernel mode */ 17562306a36Sopenharmony_ci struct pt_regs *uregs = current->thread.regs; 17662306a36Sopenharmony_ci if (uregs == NULL) 17762306a36Sopenharmony_ci goto bad_area; 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci /* 18062306a36Sopenharmony_ci * A user-mode access to an address a long way below 18162306a36Sopenharmony_ci * the stack pointer is only valid if the instruction 18262306a36Sopenharmony_ci * is one which would update the stack pointer to the 18362306a36Sopenharmony_ci * address accessed if the instruction completed, 18462306a36Sopenharmony_ci * i.e. either stwu rs,n(r1) or stwux rs,r1,rb 18562306a36Sopenharmony_ci * (or the byte, halfword, float or double forms). 18662306a36Sopenharmony_ci * 18762306a36Sopenharmony_ci * If we don't check this then any write to the area 18862306a36Sopenharmony_ci * between the last mapped region and the stack will 18962306a36Sopenharmony_ci * expand the stack rather than segfaulting. 19062306a36Sopenharmony_ci */ 19162306a36Sopenharmony_ci if (address + 2048 < uregs->r1 19262306a36Sopenharmony_ci && (kernel_mode(regs) || !store_updates_sp(regs))) 19362306a36Sopenharmony_ci goto bad_area; 19462306a36Sopenharmony_ci } 19562306a36Sopenharmony_ci vma = expand_stack(mm, address); 19662306a36Sopenharmony_ci if (!vma) 19762306a36Sopenharmony_ci goto bad_area_nosemaphore; 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_cigood_area: 20062306a36Sopenharmony_ci code = SEGV_ACCERR; 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_ci /* a write */ 20362306a36Sopenharmony_ci if (unlikely(is_write)) { 20462306a36Sopenharmony_ci if (unlikely(!(vma->vm_flags & VM_WRITE))) 20562306a36Sopenharmony_ci goto bad_area; 20662306a36Sopenharmony_ci flags |= FAULT_FLAG_WRITE; 20762306a36Sopenharmony_ci /* a read */ 20862306a36Sopenharmony_ci } else { 20962306a36Sopenharmony_ci /* protection fault */ 21062306a36Sopenharmony_ci if (unlikely(error_code & 0x08000000)) 21162306a36Sopenharmony_ci goto bad_area; 21262306a36Sopenharmony_ci if (unlikely(!(vma->vm_flags & (VM_READ | VM_EXEC)))) 21362306a36Sopenharmony_ci goto bad_area; 21462306a36Sopenharmony_ci } 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ci /* 21762306a36Sopenharmony_ci * If for any reason at all we couldn't handle the fault, 21862306a36Sopenharmony_ci * make sure we exit gracefully rather than endlessly redo 21962306a36Sopenharmony_ci * the fault. 22062306a36Sopenharmony_ci */ 22162306a36Sopenharmony_ci fault = handle_mm_fault(vma, address, flags, regs); 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_ci if (fault_signal_pending(fault, regs)) { 22462306a36Sopenharmony_ci if (!user_mode(regs)) 22562306a36Sopenharmony_ci bad_page_fault(regs, address, SIGBUS); 22662306a36Sopenharmony_ci return; 22762306a36Sopenharmony_ci } 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ci /* The fault is fully completed (including releasing mmap lock) */ 23062306a36Sopenharmony_ci if (fault & VM_FAULT_COMPLETED) 23162306a36Sopenharmony_ci return; 23262306a36Sopenharmony_ci 23362306a36Sopenharmony_ci if (unlikely(fault & VM_FAULT_ERROR)) { 23462306a36Sopenharmony_ci if (fault & VM_FAULT_OOM) 23562306a36Sopenharmony_ci goto out_of_memory; 23662306a36Sopenharmony_ci else if (fault & VM_FAULT_SIGSEGV) 23762306a36Sopenharmony_ci goto bad_area; 23862306a36Sopenharmony_ci else if (fault & VM_FAULT_SIGBUS) 23962306a36Sopenharmony_ci goto do_sigbus; 24062306a36Sopenharmony_ci BUG(); 24162306a36Sopenharmony_ci } 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_ci if (fault & VM_FAULT_RETRY) { 24462306a36Sopenharmony_ci flags |= FAULT_FLAG_TRIED; 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci /* 24762306a36Sopenharmony_ci * No need to mmap_read_unlock(mm) as we would 24862306a36Sopenharmony_ci * have already released it in __lock_page_or_retry 24962306a36Sopenharmony_ci * in mm/filemap.c. 25062306a36Sopenharmony_ci */ 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_ci goto retry; 25362306a36Sopenharmony_ci } 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_ci mmap_read_unlock(mm); 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_ci /* 25862306a36Sopenharmony_ci * keep track of tlb+htab misses that are good addrs but 25962306a36Sopenharmony_ci * just need pte's created via handle_mm_fault() 26062306a36Sopenharmony_ci * -- Cort 26162306a36Sopenharmony_ci */ 26262306a36Sopenharmony_ci pte_misses++; 26362306a36Sopenharmony_ci return; 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_cibad_area: 26662306a36Sopenharmony_ci mmap_read_unlock(mm); 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_cibad_area_nosemaphore: 26962306a36Sopenharmony_ci pte_errors++; 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_ci /* User mode accesses cause a SIGSEGV */ 27262306a36Sopenharmony_ci if (user_mode(regs)) { 27362306a36Sopenharmony_ci _exception(SIGSEGV, regs, code, address); 27462306a36Sopenharmony_ci return; 27562306a36Sopenharmony_ci } 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_ci bad_page_fault(regs, address, SIGSEGV); 27862306a36Sopenharmony_ci return; 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_ci/* 28162306a36Sopenharmony_ci * We ran out of memory, or some other thing happened to us that made 28262306a36Sopenharmony_ci * us unable to handle the page fault gracefully. 28362306a36Sopenharmony_ci */ 28462306a36Sopenharmony_ciout_of_memory: 28562306a36Sopenharmony_ci mmap_read_unlock(mm); 28662306a36Sopenharmony_ci if (!user_mode(regs)) 28762306a36Sopenharmony_ci bad_page_fault(regs, address, SIGKILL); 28862306a36Sopenharmony_ci else 28962306a36Sopenharmony_ci pagefault_out_of_memory(); 29062306a36Sopenharmony_ci return; 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_cido_sigbus: 29362306a36Sopenharmony_ci mmap_read_unlock(mm); 29462306a36Sopenharmony_ci if (user_mode(regs)) { 29562306a36Sopenharmony_ci force_sig_fault(SIGBUS, BUS_ADRERR, (void __user *)address); 29662306a36Sopenharmony_ci return; 29762306a36Sopenharmony_ci } 29862306a36Sopenharmony_ci bad_page_fault(regs, address, SIGBUS); 29962306a36Sopenharmony_ci} 300