1 /* $Id: fault.c,v 1.5 2000/01/26 16:20:29 jsm Exp $ 2 * 3 * This file is subject to the terms and conditions of the GNU General Public 4 * License. See the file "COPYING" in the main directory of this archive 5 * for more details. 6 * 7 * 8 * Copyright (C) 1995, 1996, 1997, 1998 by Ralf Baechle 9 * Copyright 1999 SuSE GmbH (Philipp Rumpf, prumpf@tux.org) 10 * Copyright 1999 Hewlett Packard Co. 11 * 12 */ 13 14 #include <linux/mm.h> 15 #include <linux/ptrace.h> 16 #include <linux/sched.h> 17 #include <linux/interrupt.h> 18 #include <linux/module.h> 19 20 #include <asm/uaccess.h> 21 #include <asm/traps.h> 22 23 #define PRINT_USER_FAULTS /* (turn this on if you want user faults to be */ 24 /* dumped to the console via printk) */ 25 26 27 /* Defines for parisc_acctyp() */ 28 #define READ 0 29 #define WRITE 1 30 31 /* Various important other fields */ 32 #define bit22set(x) (x & 0x00000200) 33 #define bits23_25set(x) (x & 0x000001c0) 34 #define isGraphicsFlushRead(x) ((x & 0xfc003fdf) == 0x04001a80) 35 /* extended opcode is 0x6a */ 36 37 #define BITSSET 0x1c0 /* for identifying LDCW */ 38 39 40 DEFINE_PER_CPU(struct exception_data, exception_data); 41 42 /* 43 * parisc_acctyp(unsigned int inst) -- 44 * Given a PA-RISC memory access instruction, determine if the 45 * the instruction would perform a memory read or memory write 46 * operation. 47 * 48 * This function assumes that the given instruction is a memory access 49 * instruction (i.e. you should really only call it if you know that 50 * the instruction has generated some sort of a memory access fault). 51 * 52 * Returns: 53 * VM_READ if read operation 54 * VM_WRITE if write operation 55 * VM_EXEC if execute operation 56 */ 57 static unsigned long 58 parisc_acctyp(unsigned long code, unsigned int inst) 59 { 60 if (code == 6 || code == 16) 61 return VM_EXEC; 62 63 switch (inst & 0xf0000000) { 64 case 0x40000000: /* load */ 65 case 0x50000000: /* new load */ 66 return VM_READ; 67 68 case 0x60000000: /* store */ 69 case 0x70000000: /* new store */ 70 return VM_WRITE; 71 72 case 0x20000000: /* coproc */ 73 case 0x30000000: /* coproc2 */ 74 if (bit22set(inst)) 75 return VM_WRITE; 76 77 case 0x0: /* indexed/memory management */ 78 if (bit22set(inst)) { 79 /* 80 * Check for the 'Graphics Flush Read' instruction. 81 * It resembles an FDC instruction, except for bits 82 * 20 and 21. Any combination other than zero will 83 * utilize the block mover functionality on some 84 * older PA-RISC platforms. The case where a block 85 * move is performed from VM to graphics IO space 86 * should be treated as a READ. 87 * 88 * The significance of bits 20,21 in the FDC 89 * instruction is: 90 * 91 * 00 Flush data cache (normal instruction behavior) 92 * 01 Graphics flush write (IO space -> VM) 93 * 10 Graphics flush read (VM -> IO space) 94 * 11 Graphics flush read/write (VM <-> IO space) 95 */ 96 if (isGraphicsFlushRead(inst)) 97 return VM_READ; 98 return VM_WRITE; 99 } else { 100 /* 101 * Check for LDCWX and LDCWS (semaphore instructions). 102 * If bits 23 through 25 are all 1's it is one of 103 * the above two instructions and is a write. 104 * 105 * Note: With the limited bits we are looking at, 106 * this will also catch PROBEW and PROBEWI. However, 107 * these should never get in here because they don't 108 * generate exceptions of the type: 109 * Data TLB miss fault/data page fault 110 * Data memory protection trap 111 */ 112 if (bits23_25set(inst) == BITSSET) 113 return VM_WRITE; 114 } 115 return VM_READ; /* Default */ 116 } 117 return VM_READ; /* Default */ 118 } 119 120 #undef bit22set 121 #undef bits23_25set 122 #undef isGraphicsFlushRead 123 #undef BITSSET 124 125 126 #if 0 127 /* This is the treewalk to find a vma which is the highest that has 128 * a start < addr. We're using find_vma_prev instead right now, but 129 * we might want to use this at some point in the future. Probably 130 * not, but I want it committed to CVS so I don't lose it :-) 131 */ 132 while (tree != vm_avl_empty) { 133 if (tree->vm_start > addr) { 134 tree = tree->vm_avl_left; 135 } else { 136 prev = tree; 137 if (prev->vm_next == NULL) 138 break; 139 if (prev->vm_next->vm_start > addr) 140 break; 141 tree = tree->vm_avl_right; 142 } 143 } 144 #endif 145 146 void do_page_fault(struct pt_regs *regs, unsigned long code, 147 unsigned long address) 148 { 149 struct vm_area_struct *vma, *prev_vma; 150 struct task_struct *tsk = current; 151 struct mm_struct *mm = tsk->mm; 152 const struct exception_table_entry *fix; 153 unsigned long acc_type; 154 155 if (in_interrupt() || !mm) 156 goto no_context; 157 158 down_read(&mm->mmap_sem); 159 vma = find_vma_prev(mm, address, &prev_vma); 160 if (!vma || address < vma->vm_start) 161 goto check_expansion; 162 /* 163 * Ok, we have a good vm_area for this memory access. We still need to 164 * check the access permissions. 165 */ 166 167 good_area: 168 169 acc_type = parisc_acctyp(code,regs->iir); 170 171 if ((vma->vm_flags & acc_type) != acc_type) 172 goto bad_area; 173 174 /* 175 * If for any reason at all we couldn't handle the fault, make 176 * sure we exit gracefully rather than endlessly redo the 177 * fault. 178 */ 179 180 switch (handle_mm_fault(mm, vma, address, (acc_type & VM_WRITE) != 0)) { 181 case 1: 182 ++current->min_flt; 183 break; 184 case 2: 185 ++current->maj_flt; 186 break; 187 case 0: 188 /* 189 * We ran out of memory, or some other thing happened 190 * to us that made us unable to handle the page fault 191 * gracefully. 192 */ 193 goto bad_area; 194 default: 195 goto out_of_memory; 196 } 197 up_read(&mm->mmap_sem); 198 return; 199 200 check_expansion: 201 vma = prev_vma; 202 if (vma && (expand_stack(vma, address) == 0)) 203 goto good_area; 204 205 /* 206 * Something tried to access memory that isn't in our memory map.. 207 */ 208 bad_area: 209 up_read(&mm->mmap_sem); 210 211 if (user_mode(regs)) { 212 struct siginfo si; 213 214 #ifdef PRINT_USER_FAULTS 215 printk(KERN_DEBUG "\n"); 216 printk(KERN_DEBUG "do_page_fault() pid=%d command='%s' type=%lu address=0x%08lx\n", 217 tsk->pid, tsk->comm, code, address); 218 if (vma) { 219 printk(KERN_DEBUG "vm_start = 0x%08lx, vm_end = 0x%08lx\n", 220 vma->vm_start, vma->vm_end); 221 } 222 show_regs(regs); 223 #endif 224 /* FIXME: actually we need to get the signo and code correct */ 225 si.si_signo = SIGSEGV; 226 si.si_errno = 0; 227 si.si_code = SEGV_MAPERR; 228 si.si_addr = (void __user *) address; 229 force_sig_info(SIGSEGV, &si, current); 230 return; 231 } 232 233 no_context: 234 235 if (!user_mode(regs)) { 236 fix = search_exception_tables(regs->iaoq[0]); 237 238 if (fix) { 239 struct exception_data *d; 240 241 d = &__get_cpu_var(exception_data); 242 d->fault_ip = regs->iaoq[0]; 243 d->fault_space = regs->isr; 244 d->fault_addr = regs->ior; 245 246 regs->iaoq[0] = ((fix->fixup) & ~3); 247 248 /* 249 * NOTE: In some cases the faulting instruction 250 * may be in the delay slot of a branch. We 251 * don't want to take the branch, so we don't 252 * increment iaoq[1], instead we set it to be 253 * iaoq[0]+4, and clear the B bit in the PSW 254 */ 255 256 regs->iaoq[1] = regs->iaoq[0] + 4; 257 regs->gr[0] &= ~PSW_B; /* IPSW in gr[0] */ 258 259 return; 260 } 261 } 262 263 parisc_terminate("Bad Address (null pointer deref?)", regs, code, address); 264 265 out_of_memory: 266 up_read(&mm->mmap_sem); 267 printk(KERN_CRIT "VM: killing process %s\n", current->comm); 268 if (user_mode(regs)) 269 do_exit(SIGKILL); 270 goto no_context; 271 } 272