aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arc/mm/fault.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arc/mm/fault.c')
-rw-r--r--arch/arc/mm/fault.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/arch/arc/mm/fault.c b/arch/arc/mm/fault.c
index 689ffd86d5e9..318164cabdfc 100644
--- a/arch/arc/mm/fault.c
+++ b/arch/arc/mm/fault.c
@@ -15,6 +15,7 @@
15#include <linux/uaccess.h> 15#include <linux/uaccess.h>
16#include <linux/kdebug.h> 16#include <linux/kdebug.h>
17#include <asm/pgalloc.h> 17#include <asm/pgalloc.h>
18#include <asm/mmu.h>
18 19
19static int handle_vmalloc_fault(struct mm_struct *mm, unsigned long address) 20static int handle_vmalloc_fault(struct mm_struct *mm, unsigned long address)
20{ 21{
@@ -51,14 +52,14 @@ bad_area:
51 return 1; 52 return 1;
52} 53}
53 54
54void do_page_fault(struct pt_regs *regs, int write, unsigned long address, 55void do_page_fault(struct pt_regs *regs, unsigned long address)
55 unsigned long cause_code)
56{ 56{
57 struct vm_area_struct *vma = NULL; 57 struct vm_area_struct *vma = NULL;
58 struct task_struct *tsk = current; 58 struct task_struct *tsk = current;
59 struct mm_struct *mm = tsk->mm; 59 struct mm_struct *mm = tsk->mm;
60 siginfo_t info; 60 siginfo_t info;
61 int fault, ret; 61 int fault, ret;
62 int write = regs->ecr_cause & ECR_C_PROTV_STORE; /* ST/EX */
62 unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | 63 unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE |
63 (write ? FAULT_FLAG_WRITE : 0); 64 (write ? FAULT_FLAG_WRITE : 0);
64 65
@@ -109,7 +110,8 @@ good_area:
109 110
110 /* Handle protection violation, execute on heap or stack */ 111 /* Handle protection violation, execute on heap or stack */
111 112
112 if (cause_code == ((ECR_V_PROTV << 16) | ECR_C_PROTV_INST_FETCH)) 113 if ((regs->ecr_vec == ECR_V_PROTV) &&
114 (regs->ecr_cause == ECR_C_PROTV_INST_FETCH))
113 goto bad_area; 115 goto bad_area;
114 116
115 if (write) { 117 if (write) {
@@ -176,7 +178,6 @@ bad_area_nosemaphore:
176 /* User mode accesses just cause a SIGSEGV */ 178 /* User mode accesses just cause a SIGSEGV */
177 if (user_mode(regs)) { 179 if (user_mode(regs)) {
178 tsk->thread.fault_address = address; 180 tsk->thread.fault_address = address;
179 tsk->thread.cause_code = cause_code;
180 info.si_signo = SIGSEGV; 181 info.si_signo = SIGSEGV;
181 info.si_errno = 0; 182 info.si_errno = 0;
182 /* info.si_code has been set above */ 183 /* info.si_code has been set above */
@@ -197,7 +198,7 @@ no_context:
197 if (fixup_exception(regs)) 198 if (fixup_exception(regs))
198 return; 199 return;
199 200
200 die("Oops", regs, address, cause_code); 201 die("Oops", regs, address);
201 202
202out_of_memory: 203out_of_memory:
203 if (is_global_init(tsk)) { 204 if (is_global_init(tsk)) {
@@ -218,7 +219,6 @@ do_sigbus:
218 goto no_context; 219 goto no_context;
219 220
220 tsk->thread.fault_address = address; 221 tsk->thread.fault_address = address;
221 tsk->thread.cause_code = cause_code;
222 info.si_signo = SIGBUS; 222 info.si_signo = SIGBUS;
223 info.si_errno = 0; 223 info.si_errno = 0;
224 info.si_code = BUS_ADRERR; 224 info.si_code = BUS_ADRERR;