License cleanup: add SPDX GPL-2.0 license identifier to files with no license
[linux-2.6-block.git] / arch / metag / mm / fault.c
CommitLineData
b2441318 1// SPDX-License-Identifier: GPL-2.0
f5df8e26
JH
2/*
3 * Meta page fault handling.
4 *
5 * Copyright (C) 2005-2012 Imagination Technologies Ltd.
6 */
7
8#include <linux/mman.h>
9#include <linux/mm.h>
10#include <linux/kernel.h>
11#include <linux/ptrace.h>
b17b0153 12#include <linux/sched/debug.h>
f5df8e26
JH
13#include <linux/interrupt.h>
14#include <linux/uaccess.h>
15
16#include <asm/tlbflush.h>
17#include <asm/mmu.h>
18#include <asm/traps.h>
19
20/* Clear any pending catch buffer state. */
21static void clear_cbuf_entry(struct pt_regs *regs, unsigned long addr,
22 unsigned int trapno)
23{
24 PTBICTXEXTCB0 cbuf = regs->extcb0;
25
26 switch (trapno) {
27 /* Instruction fetch faults leave no catch buffer state. */
28 case TBIXXF_SIGNUM_IGF:
29 case TBIXXF_SIGNUM_IPF:
30 return;
31 default:
32 if (cbuf[0].CBAddr == addr) {
33 cbuf[0].CBAddr = 0;
34 cbuf[0].CBFlags &= ~TXCATCH0_FAULT_BITS;
35
36 /* And, as this is the ONLY catch entry, we
37 * need to clear the cbuf bit from the context!
38 */
39 regs->ctx.SaveMask &= ~(TBICTX_CBUF_BIT |
40 TBICTX_XCBF_BIT);
41
42 return;
43 }
44 pr_err("Failed to clear cbuf entry!\n");
45 }
46}
47
48int show_unhandled_signals = 1;
49
50int do_page_fault(struct pt_regs *regs, unsigned long address,
51 unsigned int write_access, unsigned int trapno)
52{
53 struct task_struct *tsk;
54 struct mm_struct *mm;
55 struct vm_area_struct *vma, *prev_vma;
56 siginfo_t info;
57 int fault;
759496ba 58 unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
f5df8e26
JH
59
60 tsk = current;
61
62 if ((address >= VMALLOC_START) && (address < VMALLOC_END)) {
63 /*
64 * Synchronize this task's top level page-table
65 * with the 'reference' page table.
66 *
67 * Do _not_ use "tsk" here. We might be inside
68 * an interrupt in the middle of a task switch..
69 */
70 int offset = pgd_index(address);
71 pgd_t *pgd, *pgd_k;
72 pud_t *pud, *pud_k;
73 pmd_t *pmd, *pmd_k;
74 pte_t *pte_k;
75
76 pgd = ((pgd_t *)mmu_get_base()) + offset;
77 pgd_k = swapper_pg_dir + offset;
78
79 /* This will never happen with the folded page table. */
80 if (!pgd_present(*pgd)) {
81 if (!pgd_present(*pgd_k))
82 goto bad_area_nosemaphore;
83 set_pgd(pgd, *pgd_k);
84 return 0;
85 }
86
87 pud = pud_offset(pgd, address);
88 pud_k = pud_offset(pgd_k, address);
89 if (!pud_present(*pud_k))
90 goto bad_area_nosemaphore;
91 set_pud(pud, *pud_k);
92
93 pmd = pmd_offset(pud, address);
94 pmd_k = pmd_offset(pud_k, address);
95 if (!pmd_present(*pmd_k))
96 goto bad_area_nosemaphore;
97 set_pmd(pmd, *pmd_k);
98
99 pte_k = pte_offset_kernel(pmd_k, address);
100 if (!pte_present(*pte_k))
101 goto bad_area_nosemaphore;
102
103 /* May only be needed on Chorus2 */
104 flush_tlb_all();
105 return 0;
106 }
107
108 mm = tsk->mm;
109
70ffdb93 110 if (faulthandler_disabled() || !mm)
f5df8e26
JH
111 goto no_context;
112
759496ba
JW
113 if (user_mode(regs))
114 flags |= FAULT_FLAG_USER;
f5df8e26
JH
115retry:
116 down_read(&mm->mmap_sem);
117
118 vma = find_vma_prev(mm, address, &prev_vma);
119
120 if (!vma || address < vma->vm_start)
121 goto check_expansion;
122
123good_area:
124 if (write_access) {
125 if (!(vma->vm_flags & VM_WRITE))
126 goto bad_area;
759496ba 127 flags |= FAULT_FLAG_WRITE;
f5df8e26
JH
128 } else {
129 if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
130 goto bad_area;
131 }
132
133 /*
134 * If for any reason at all we couldn't handle the fault,
135 * make sure we exit gracefully rather than endlessly redo
136 * the fault.
137 */
dcddffd4 138 fault = handle_mm_fault(vma, address, flags);
f5df8e26
JH
139
140 if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
141 return 0;
142
143 if (unlikely(fault & VM_FAULT_ERROR)) {
144 if (fault & VM_FAULT_OOM)
145 goto out_of_memory;
33692f27
LT
146 else if (fault & VM_FAULT_SIGSEGV)
147 goto bad_area;
f5df8e26
JH
148 else if (fault & VM_FAULT_SIGBUS)
149 goto do_sigbus;
150 BUG();
151 }
152 if (flags & FAULT_FLAG_ALLOW_RETRY) {
153 if (fault & VM_FAULT_MAJOR)
154 tsk->maj_flt++;
155 else
156 tsk->min_flt++;
157 if (fault & VM_FAULT_RETRY) {
158 flags &= ~FAULT_FLAG_ALLOW_RETRY;
159 flags |= FAULT_FLAG_TRIED;
160
161 /*
162 * No need to up_read(&mm->mmap_sem) as we would
163 * have already released it in __lock_page_or_retry
164 * in mm/filemap.c.
165 */
166
167 goto retry;
168 }
169 }
170
171 up_read(&mm->mmap_sem);
172 return 0;
173
174check_expansion:
175 vma = prev_vma;
176 if (vma && (expand_stack(vma, address) == 0))
177 goto good_area;
178
179bad_area:
180 up_read(&mm->mmap_sem);
181
182bad_area_nosemaphore:
183 if (user_mode(regs)) {
184 info.si_signo = SIGSEGV;
185 info.si_errno = 0;
186 info.si_code = SEGV_MAPERR;
187 info.si_addr = (__force void __user *)address;
188 info.si_trapno = trapno;
189
190 if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) &&
191 printk_ratelimit()) {
fb2bb461 192 printk("%s%s[%d]: segfault at %lx pc %08x sp %08x write %d trap %#x (%s)",
f5df8e26
JH
193 task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
194 tsk->comm, task_pid_nr(tsk), address,
195 regs->ctx.CurrPC, regs->ctx.AX[0].U0,
196 write_access, trapno, trap_name(trapno));
197 print_vma_addr(" in ", regs->ctx.CurrPC);
198 print_vma_addr(" rtp in ", regs->ctx.DX[4].U1);
199 printk("\n");
200 show_regs(regs);
201 }
202 force_sig_info(SIGSEGV, &info, tsk);
203 return 1;
204 }
205 goto no_context;
206
207do_sigbus:
208 up_read(&mm->mmap_sem);
209
210 /*
211 * Send a sigbus, regardless of whether we were in kernel
212 * or user mode.
213 */
214 info.si_signo = SIGBUS;
215 info.si_errno = 0;
216 info.si_code = BUS_ADRERR;
217 info.si_addr = (__force void __user *)address;
218 info.si_trapno = trapno;
219 force_sig_info(SIGBUS, &info, tsk);
220
221 /* Kernel mode? Handle exceptions or die */
222 if (!user_mode(regs))
223 goto no_context;
224
225 return 1;
226
227 /*
228 * We ran out of memory, or some other thing happened to us that made
229 * us unable to handle the page fault gracefully.
230 */
231out_of_memory:
232 up_read(&mm->mmap_sem);
609838cf
JW
233 if (user_mode(regs)) {
234 pagefault_out_of_memory();
235 return 1;
236 }
f5df8e26
JH
237
238no_context:
239 /* Are we prepared to handle this kernel fault? */
240 if (fixup_exception(regs)) {
241 clear_cbuf_entry(regs, address, trapno);
242 return 1;
243 }
244
245 die("Oops", regs, (write_access << 15) | trapno, address);
246 do_exit(SIGKILL);
247}