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, 5 insertions, 7 deletions
diff --git a/arch/arc/mm/fault.c b/arch/arc/mm/fault.c
index fdafeb1917cc..318164cabdfc 100644
--- a/arch/arc/mm/fault.c
+++ b/arch/arc/mm/fault.c
@@ -52,15 +52,14 @@ bad_area:
52 return 1; 52 return 1;
53} 53}
54 54
55void do_page_fault(struct pt_regs *regs, unsigned long address, 55void do_page_fault(struct pt_regs *regs, unsigned long address)
56 unsigned long cause_code)
57{ 56{
58 struct vm_area_struct *vma = NULL; 57 struct vm_area_struct *vma = NULL;
59 struct task_struct *tsk = current; 58 struct task_struct *tsk = current;
60 struct mm_struct *mm = tsk->mm; 59 struct mm_struct *mm = tsk->mm;
61 siginfo_t info; 60 siginfo_t info;
62 int fault, ret; 61 int fault, ret;
63 int write = cause_code & (1 << ECR_C_BIT_DTLB_ST_MISS); /* ST/EX */ 62 int write = regs->ecr_cause & ECR_C_PROTV_STORE; /* ST/EX */
64 unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | 63 unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE |
65 (write ? FAULT_FLAG_WRITE : 0); 64 (write ? FAULT_FLAG_WRITE : 0);
66 65
@@ -111,7 +110,8 @@ good_area:
111 110
112 /* Handle protection violation, execute on heap or stack */ 111 /* Handle protection violation, execute on heap or stack */
113 112
114 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))
115 goto bad_area; 115 goto bad_area;
116 116
117 if (write) { 117 if (write) {
@@ -178,7 +178,6 @@ bad_area_nosemaphore:
178 /* User mode accesses just cause a SIGSEGV */ 178 /* User mode accesses just cause a SIGSEGV */
179 if (user_mode(regs)) { 179 if (user_mode(regs)) {
180 tsk->thread.fault_address = address; 180 tsk->thread.fault_address = address;
181 tsk->thread.cause_code = cause_code;
182 info.si_signo = SIGSEGV; 181 info.si_signo = SIGSEGV;
183 info.si_errno = 0; 182 info.si_errno = 0;
184 /* info.si_code has been set above */ 183 /* info.si_code has been set above */
@@ -199,7 +198,7 @@ no_context:
199 if (fixup_exception(regs)) 198 if (fixup_exception(regs))
200 return; 199 return;
201 200
202 die("Oops", regs, address, cause_code); 201 die("Oops", regs, address);
203 202
204out_of_memory: 203out_of_memory:
205 if (is_global_init(tsk)) { 204 if (is_global_init(tsk)) {
@@ -220,7 +219,6 @@ do_sigbus:
220 goto no_context; 219 goto no_context;
221 220
222 tsk->thread.fault_address = address; 221 tsk->thread.fault_address = address;
223 tsk->thread.cause_code = cause_code;
224 info.si_signo = SIGBUS; 222 info.si_signo = SIGBUS;
225 info.si_errno = 0; 223 info.si_errno = 0;
226 info.si_code = BUS_ADRERR; 224 info.si_code = BUS_ADRERR;