1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License.  See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 *
7 * Copyright (C) 1995, 1996, 1997, 1998 by Ralf Baechle
8 * Copyright 1999 SuSE GmbH (Philipp Rumpf, prumpf@tux.org)
9 * Copyright 1999 Hewlett Packard Co.
10 *
11 */
12
13#include <linux/mm.h>
14#include <linux/ptrace.h>
15#include <linux/sched.h>
16#include <linux/interrupt.h>
17#include <linux/module.h>
18
19#include <asm/uaccess.h>
20#include <asm/traps.h>
21
22/* Various important other fields */
23#define bit22set(x)		(x & 0x00000200)
24#define bits23_25set(x)		(x & 0x000001c0)
25#define isGraphicsFlushRead(x)	((x & 0xfc003fdf) == 0x04001a80)
26				/* extended opcode is 0x6a */
27
28#define BITSSET		0x1c0	/* for identifying LDCW */
29
30
31DEFINE_PER_CPU(struct exception_data, exception_data);
32
33int show_unhandled_signals = 1;
34
35/*
36 * parisc_acctyp(unsigned int inst) --
37 *    Given a PA-RISC memory access instruction, determine if the
38 *    the instruction would perform a memory read or memory write
39 *    operation.
40 *
41 *    This function assumes that the given instruction is a memory access
42 *    instruction (i.e. you should really only call it if you know that
43 *    the instruction has generated some sort of a memory access fault).
44 *
45 * Returns:
46 *   VM_READ  if read operation
47 *   VM_WRITE if write operation
48 *   VM_EXEC  if execute operation
49 */
50static unsigned long
51parisc_acctyp(unsigned long code, unsigned int inst)
52{
53	if (code == 6 || code == 16)
54	    return VM_EXEC;
55
56	switch (inst & 0xf0000000) {
57	case 0x40000000: /* load */
58	case 0x50000000: /* new load */
59		return VM_READ;
60
61	case 0x60000000: /* store */
62	case 0x70000000: /* new store */
63		return VM_WRITE;
64
65	case 0x20000000: /* coproc */
66	case 0x30000000: /* coproc2 */
67		if (bit22set(inst))
68			return VM_WRITE;
69
70	case 0x0: /* indexed/memory management */
71		if (bit22set(inst)) {
72			/*
73			 * Check for the 'Graphics Flush Read' instruction.
74			 * It resembles an FDC instruction, except for bits
75			 * 20 and 21. Any combination other than zero will
76			 * utilize the block mover functionality on some
77			 * older PA-RISC platforms.  The case where a block
78			 * move is performed from VM to graphics IO space
79			 * should be treated as a READ.
80			 *
81			 * The significance of bits 20,21 in the FDC
82			 * instruction is:
83			 *
84			 *   00  Flush data cache (normal instruction behavior)
85			 *   01  Graphics flush write  (IO space -> VM)
86			 *   10  Graphics flush read   (VM -> IO space)
87			 *   11  Graphics flush read/write (VM <-> IO space)
88			 */
89			if (isGraphicsFlushRead(inst))
90				return VM_READ;
91			return VM_WRITE;
92		} else {
93			/*
94			 * Check for LDCWX and LDCWS (semaphore instructions).
95			 * If bits 23 through 25 are all 1's it is one of
96			 * the above two instructions and is a write.
97			 *
98			 * Note: With the limited bits we are looking at,
99			 * this will also catch PROBEW and PROBEWI. However,
100			 * these should never get in here because they don't
101			 * generate exceptions of the type:
102			 *   Data TLB miss fault/data page fault
103			 *   Data memory protection trap
104			 */
105			if (bits23_25set(inst) == BITSSET)
106				return VM_WRITE;
107		}
108		return VM_READ; /* Default */
109	}
110	return VM_READ; /* Default */
111}
112
113#undef bit22set
114#undef bits23_25set
115#undef isGraphicsFlushRead
116#undef BITSSET
117
118
119#if 0
120/* This is the treewalk to find a vma which is the highest that has
121 * a start < addr.  We're using find_vma_prev instead right now, but
122 * we might want to use this at some point in the future.  Probably
123 * not, but I want it committed to CVS so I don't lose it :-)
124 */
125			while (tree != vm_avl_empty) {
126				if (tree->vm_start > addr) {
127					tree = tree->vm_avl_left;
128				} else {
129					prev = tree;
130					if (prev->vm_next == NULL)
131						break;
132					if (prev->vm_next->vm_start > addr)
133						break;
134					tree = tree->vm_avl_right;
135				}
136			}
137#endif
138
139int fixup_exception(struct pt_regs *regs)
140{
141	const struct exception_table_entry *fix;
142
143	/* If we only stored 32bit addresses in the exception table we can drop
144	 * out if we faulted on a 64bit address. */
145	if ((sizeof(regs->iaoq[0]) > sizeof(fix->insn))
146		&& (regs->iaoq[0] >> 32))
147			return 0;
148
149	fix = search_exception_tables(regs->iaoq[0]);
150	if (fix) {
151		struct exception_data *d;
152		d = this_cpu_ptr(&exception_data);
153		d->fault_ip = regs->iaoq[0];
154		d->fault_gp = regs->gr[27];
155		d->fault_space = regs->isr;
156		d->fault_addr = regs->ior;
157
158		regs->iaoq[0] = ((fix->fixup) & ~3);
159		/*
160		 * NOTE: In some cases the faulting instruction
161		 * may be in the delay slot of a branch. We
162		 * don't want to take the branch, so we don't
163		 * increment iaoq[1], instead we set it to be
164		 * iaoq[0]+4, and clear the B bit in the PSW
165		 */
166		regs->iaoq[1] = regs->iaoq[0] + 4;
167		regs->gr[0] &= ~PSW_B; /* IPSW in gr[0] */
168
169		return 1;
170	}
171
172	return 0;
173}
174
175/*
176 * Print out info about fatal segfaults, if the show_unhandled_signals
177 * sysctl is set:
178 */
179static inline void
180show_signal_msg(struct pt_regs *regs, unsigned long code,
181		unsigned long address, struct task_struct *tsk,
182		struct vm_area_struct *vma)
183{
184	if (!unhandled_signal(tsk, SIGSEGV))
185		return;
186
187	if (!printk_ratelimit())
188		return;
189
190	pr_warn("\n");
191	pr_warn("do_page_fault() command='%s' type=%lu address=0x%08lx",
192	    tsk->comm, code, address);
193	print_vma_addr(KERN_CONT " in ", regs->iaoq[0]);
194	if (vma)
195		pr_warn(" vm_start = 0x%08lx, vm_end = 0x%08lx\n",
196				vma->vm_start, vma->vm_end);
197
198	show_regs(regs);
199}
200
201void do_page_fault(struct pt_regs *regs, unsigned long code,
202			      unsigned long address)
203{
204	struct vm_area_struct *vma, *prev_vma;
205	struct task_struct *tsk;
206	struct mm_struct *mm;
207	unsigned long acc_type;
208	int fault;
209	unsigned int flags;
210
211	if (in_atomic())
212		goto no_context;
213
214	tsk = current;
215	mm = tsk->mm;
216	if (!mm)
217		goto no_context;
218
219	flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
220	if (user_mode(regs))
221		flags |= FAULT_FLAG_USER;
222
223	acc_type = parisc_acctyp(code, regs->iir);
224	if (acc_type & VM_WRITE)
225		flags |= FAULT_FLAG_WRITE;
226retry:
227	down_read(&mm->mmap_sem);
228	vma = find_vma_prev(mm, address, &prev_vma);
229	if (!vma || address < vma->vm_start)
230		goto check_expansion;
231/*
232 * Ok, we have a good vm_area for this memory access. We still need to
233 * check the access permissions.
234 */
235
236good_area:
237
238	if ((vma->vm_flags & acc_type) != acc_type)
239		goto bad_area;
240
241	/*
242	 * If for any reason at all we couldn't handle the fault, make
243	 * sure we exit gracefully rather than endlessly redo the
244	 * fault.
245	 */
246
247	fault = handle_mm_fault(mm, vma, address, flags);
248
249	if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
250		return;
251
252	if (unlikely(fault & VM_FAULT_ERROR)) {
253		/*
254		 * We hit a shared mapping outside of the file, or some
255		 * other thing happened to us that made us unable to
256		 * handle the page fault gracefully.
257		 */
258		if (fault & VM_FAULT_OOM)
259			goto out_of_memory;
260		else if (fault & VM_FAULT_SIGSEGV)
261			goto bad_area;
262		else if (fault & VM_FAULT_SIGBUS)
263			goto bad_area;
264		BUG();
265	}
266	if (flags & FAULT_FLAG_ALLOW_RETRY) {
267		if (fault & VM_FAULT_MAJOR)
268			current->maj_flt++;
269		else
270			current->min_flt++;
271		if (fault & VM_FAULT_RETRY) {
272			flags &= ~FAULT_FLAG_ALLOW_RETRY;
273
274			/*
275			 * No need to up_read(&mm->mmap_sem) as we would
276			 * have already released it in __lock_page_or_retry
277			 * in mm/filemap.c.
278			 */
279
280			goto retry;
281		}
282	}
283	up_read(&mm->mmap_sem);
284	return;
285
286check_expansion:
287	vma = prev_vma;
288	if (vma && (expand_stack(vma, address) == 0))
289		goto good_area;
290
291/*
292 * Something tried to access memory that isn't in our memory map..
293 */
294bad_area:
295	up_read(&mm->mmap_sem);
296
297	if (user_mode(regs)) {
298		struct siginfo si;
299
300		show_signal_msg(regs, code, address, tsk, vma);
301
302		switch (code) {
303		case 15:	/* Data TLB miss fault/Data page fault */
304			/* send SIGSEGV when outside of vma */
305			if (!vma ||
306			    address < vma->vm_start || address > vma->vm_end) {
307				si.si_signo = SIGSEGV;
308				si.si_code = SEGV_MAPERR;
309				break;
310			}
311
312			/* send SIGSEGV for wrong permissions */
313			if ((vma->vm_flags & acc_type) != acc_type) {
314				si.si_signo = SIGSEGV;
315				si.si_code = SEGV_ACCERR;
316				break;
317			}
318
319			/* probably address is outside of mapped file */
320			/* fall through */
321		case 17:	/* NA data TLB miss / page fault */
322		case 18:	/* Unaligned access - PCXS only */
323			si.si_signo = SIGBUS;
324			si.si_code = (code == 18) ? BUS_ADRALN : BUS_ADRERR;
325			break;
326		case 16:	/* Non-access instruction TLB miss fault */
327		case 26:	/* PCXL: Data memory access rights trap */
328		default:
329			si.si_signo = SIGSEGV;
330			si.si_code = (code == 26) ? SEGV_ACCERR : SEGV_MAPERR;
331			break;
332		}
333		si.si_errno = 0;
334		si.si_addr = (void __user *) address;
335		force_sig_info(si.si_signo, &si, current);
336		return;
337	}
338
339no_context:
340
341	if (!user_mode(regs) && fixup_exception(regs)) {
342		return;
343	}
344
345	parisc_terminate("Bad Address (null pointer deref?)", regs, code, address);
346
347  out_of_memory:
348	up_read(&mm->mmap_sem);
349	if (!user_mode(regs))
350		goto no_context;
351	pagefault_out_of_memory();
352}
353