Back to home page

LXR

 
 

    


0001 /*
0002  * MMU fault handling support.
0003  *
0004  * Copyright (C) 1998-2002 Hewlett-Packard Co
0005  *  David Mosberger-Tang <davidm@hpl.hp.com>
0006  */
0007 #include <linux/sched.h>
0008 #include <linux/kernel.h>
0009 #include <linux/mm.h>
0010 #include <linux/interrupt.h>
0011 #include <linux/kprobes.h>
0012 #include <linux/kdebug.h>
0013 #include <linux/prefetch.h>
0014 #include <linux/uaccess.h>
0015 
0016 #include <asm/pgtable.h>
0017 #include <asm/processor.h>
0018 
0019 extern int die(char *, struct pt_regs *, long);
0020 
0021 #ifdef CONFIG_KPROBES
0022 static inline int notify_page_fault(struct pt_regs *regs, int trap)
0023 {
0024     int ret = 0;
0025 
0026     if (!user_mode(regs)) {
0027         /* kprobe_running() needs smp_processor_id() */
0028         preempt_disable();
0029         if (kprobe_running() && kprobe_fault_handler(regs, trap))
0030             ret = 1;
0031         preempt_enable();
0032     }
0033 
0034     return ret;
0035 }
0036 #else
0037 static inline int notify_page_fault(struct pt_regs *regs, int trap)
0038 {
0039     return 0;
0040 }
0041 #endif
0042 
0043 /*
0044  * Return TRUE if ADDRESS points at a page in the kernel's mapped segment
0045  * (inside region 5, on ia64) and that page is present.
0046  */
0047 static int
0048 mapped_kernel_page_is_present (unsigned long address)
0049 {
0050     pgd_t *pgd;
0051     pud_t *pud;
0052     pmd_t *pmd;
0053     pte_t *ptep, pte;
0054 
0055     pgd = pgd_offset_k(address);
0056     if (pgd_none(*pgd) || pgd_bad(*pgd))
0057         return 0;
0058 
0059     pud = pud_offset(pgd, address);
0060     if (pud_none(*pud) || pud_bad(*pud))
0061         return 0;
0062 
0063     pmd = pmd_offset(pud, address);
0064     if (pmd_none(*pmd) || pmd_bad(*pmd))
0065         return 0;
0066 
0067     ptep = pte_offset_kernel(pmd, address);
0068     if (!ptep)
0069         return 0;
0070 
0071     pte = *ptep;
0072     return pte_present(pte);
0073 }
0074 
0075 #   define VM_READ_BIT  0
0076 #   define VM_WRITE_BIT 1
0077 #   define VM_EXEC_BIT  2
0078 
0079 void __kprobes
0080 ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
0081 {
0082     int signal = SIGSEGV, code = SEGV_MAPERR;
0083     struct vm_area_struct *vma, *prev_vma;
0084     struct mm_struct *mm = current->mm;
0085     struct siginfo si;
0086     unsigned long mask;
0087     int fault;
0088     unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
0089 
0090     mask = ((((isr >> IA64_ISR_X_BIT) & 1UL) << VM_EXEC_BIT)
0091         | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT));
0092 
0093     /* mmap_sem is performance critical.... */
0094     prefetchw(&mm->mmap_sem);
0095 
0096     /*
0097      * If we're in an interrupt or have no user context, we must not take the fault..
0098      */
0099     if (faulthandler_disabled() || !mm)
0100         goto no_context;
0101 
0102 #ifdef CONFIG_VIRTUAL_MEM_MAP
0103     /*
0104      * If fault is in region 5 and we are in the kernel, we may already
0105      * have the mmap_sem (pfn_valid macro is called during mmap). There
0106      * is no vma for region 5 addr's anyway, so skip getting the semaphore
0107      * and go directly to the exception handling code.
0108      */
0109 
0110     if ((REGION_NUMBER(address) == 5) && !user_mode(regs))
0111         goto bad_area_no_up;
0112 #endif
0113 
0114     /*
0115      * This is to handle the kprobes on user space access instructions
0116      */
0117     if (notify_page_fault(regs, TRAP_BRKPT))
0118         return;
0119 
0120     if (user_mode(regs))
0121         flags |= FAULT_FLAG_USER;
0122     if (mask & VM_WRITE)
0123         flags |= FAULT_FLAG_WRITE;
0124 retry:
0125     down_read(&mm->mmap_sem);
0126 
0127     vma = find_vma_prev(mm, address, &prev_vma);
0128     if (!vma && !prev_vma )
0129         goto bad_area;
0130 
0131         /*
0132          * find_vma_prev() returns vma such that address < vma->vm_end or NULL
0133          *
0134          * May find no vma, but could be that the last vm area is the
0135          * register backing store that needs to expand upwards, in
0136          * this case vma will be null, but prev_vma will ne non-null
0137          */
0138         if (( !vma && prev_vma ) || (address < vma->vm_start) )
0139         goto check_expansion;
0140 
0141   good_area:
0142     code = SEGV_ACCERR;
0143 
0144     /* OK, we've got a good vm_area for this memory area.  Check the access permissions: */
0145 
0146 #   if (((1 << VM_READ_BIT) != VM_READ || (1 << VM_WRITE_BIT) != VM_WRITE) \
0147         || (1 << VM_EXEC_BIT) != VM_EXEC)
0148 #       error File is out of sync with <linux/mm.h>.  Please update.
0149 #   endif
0150 
0151     if (((isr >> IA64_ISR_R_BIT) & 1UL) && (!(vma->vm_flags & (VM_READ | VM_WRITE))))
0152         goto bad_area;
0153 
0154     if ((vma->vm_flags & mask) != mask)
0155         goto bad_area;
0156 
0157     /*
0158      * If for any reason at all we couldn't handle the fault, make
0159      * sure we exit gracefully rather than endlessly redo the
0160      * fault.
0161      */
0162     fault = handle_mm_fault(vma, address, flags);
0163 
0164     if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
0165         return;
0166 
0167     if (unlikely(fault & VM_FAULT_ERROR)) {
0168         /*
0169          * We ran out of memory, or some other thing happened
0170          * to us that made us unable to handle the page fault
0171          * gracefully.
0172          */
0173         if (fault & VM_FAULT_OOM) {
0174             goto out_of_memory;
0175         } else if (fault & VM_FAULT_SIGSEGV) {
0176             goto bad_area;
0177         } else if (fault & VM_FAULT_SIGBUS) {
0178             signal = SIGBUS;
0179             goto bad_area;
0180         }
0181         BUG();
0182     }
0183 
0184     if (flags & FAULT_FLAG_ALLOW_RETRY) {
0185         if (fault & VM_FAULT_MAJOR)
0186             current->maj_flt++;
0187         else
0188             current->min_flt++;
0189         if (fault & VM_FAULT_RETRY) {
0190             flags &= ~FAULT_FLAG_ALLOW_RETRY;
0191             flags |= FAULT_FLAG_TRIED;
0192 
0193              /* No need to up_read(&mm->mmap_sem) as we would
0194              * have already released it in __lock_page_or_retry
0195              * in mm/filemap.c.
0196              */
0197 
0198             goto retry;
0199         }
0200     }
0201 
0202     up_read(&mm->mmap_sem);
0203     return;
0204 
0205   check_expansion:
0206     if (!(prev_vma && (prev_vma->vm_flags & VM_GROWSUP) && (address == prev_vma->vm_end))) {
0207         if (!vma)
0208             goto bad_area;
0209         if (!(vma->vm_flags & VM_GROWSDOWN))
0210             goto bad_area;
0211         if (REGION_NUMBER(address) != REGION_NUMBER(vma->vm_start)
0212             || REGION_OFFSET(address) >= RGN_MAP_LIMIT)
0213             goto bad_area;
0214         if (expand_stack(vma, address))
0215             goto bad_area;
0216     } else {
0217         vma = prev_vma;
0218         if (REGION_NUMBER(address) != REGION_NUMBER(vma->vm_start)
0219             || REGION_OFFSET(address) >= RGN_MAP_LIMIT)
0220             goto bad_area;
0221         /*
0222          * Since the register backing store is accessed sequentially,
0223          * we disallow growing it by more than a page at a time.
0224          */
0225         if (address > vma->vm_end + PAGE_SIZE - sizeof(long))
0226             goto bad_area;
0227         if (expand_upwards(vma, address))
0228             goto bad_area;
0229     }
0230     goto good_area;
0231 
0232   bad_area:
0233     up_read(&mm->mmap_sem);
0234 #ifdef CONFIG_VIRTUAL_MEM_MAP
0235   bad_area_no_up:
0236 #endif
0237     if ((isr & IA64_ISR_SP)
0238         || ((isr & IA64_ISR_NA) && (isr & IA64_ISR_CODE_MASK) == IA64_ISR_CODE_LFETCH))
0239     {
0240         /*
0241          * This fault was due to a speculative load or lfetch.fault, set the "ed"
0242          * bit in the psr to ensure forward progress.  (Target register will get a
0243          * NaT for ld.s, lfetch will be canceled.)
0244          */
0245         ia64_psr(regs)->ed = 1;
0246         return;
0247     }
0248     if (user_mode(regs)) {
0249         si.si_signo = signal;
0250         si.si_errno = 0;
0251         si.si_code = code;
0252         si.si_addr = (void __user *) address;
0253         si.si_isr = isr;
0254         si.si_flags = __ISR_VALID;
0255         force_sig_info(signal, &si, current);
0256         return;
0257     }
0258 
0259   no_context:
0260     if ((isr & IA64_ISR_SP)
0261         || ((isr & IA64_ISR_NA) && (isr & IA64_ISR_CODE_MASK) == IA64_ISR_CODE_LFETCH))
0262     {
0263         /*
0264          * This fault was due to a speculative load or lfetch.fault, set the "ed"
0265          * bit in the psr to ensure forward progress.  (Target register will get a
0266          * NaT for ld.s, lfetch will be canceled.)
0267          */
0268         ia64_psr(regs)->ed = 1;
0269         return;
0270     }
0271 
0272     /*
0273      * Since we have no vma's for region 5, we might get here even if the address is
0274      * valid, due to the VHPT walker inserting a non present translation that becomes
0275      * stale. If that happens, the non present fault handler already purged the stale
0276      * translation, which fixed the problem. So, we check to see if the translation is
0277      * valid, and return if it is.
0278      */
0279     if (REGION_NUMBER(address) == 5 && mapped_kernel_page_is_present(address))
0280         return;
0281 
0282     if (ia64_done_with_exception(regs))
0283         return;
0284 
0285     /*
0286      * Oops. The kernel tried to access some bad page. We'll have to terminate things
0287      * with extreme prejudice.
0288      */
0289     bust_spinlocks(1);
0290 
0291     if (address < PAGE_SIZE)
0292         printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference (address %016lx)\n", address);
0293     else
0294         printk(KERN_ALERT "Unable to handle kernel paging request at "
0295                "virtual address %016lx\n", address);
0296     if (die("Oops", regs, isr))
0297         regs = NULL;
0298     bust_spinlocks(0);
0299     if (regs)
0300         do_exit(SIGKILL);
0301     return;
0302 
0303   out_of_memory:
0304     up_read(&mm->mmap_sem);
0305     if (!user_mode(regs))
0306         goto no_context;
0307     pagefault_out_of_memory();
0308 }