diff options
author | Vineet Gupta <vgupta@synopsys.com> | 2013-06-12 04:19:02 -0400 |
---|---|---|
committer | Vineet Gupta <vgupta@synopsys.com> | 2013-06-22 09:53:20 -0400 |
commit | 3e1ae441886b82fbf605f37ac0756b811d55f3d5 (patch) | |
tree | 36c7e28d41922288ae1b3a466cf851f7a64da68e | |
parent | 3abc94480225677ea08af817d56edfb0df9e9b80 (diff) |
ARC: [mm] Remove @write argument to do_page_fault()
This can be ascertained within do_page_fault() since it gets the full
ECR (Exception Cause Register).
Further, for both the callers of do_page_fault(): Prot-V / D-TLB-Miss,
the cause sub-fields in ECR are same for same type of access, making the
code much more simpler.
D-TLB-Miss [LD] 0x00_21_01_00
Prot-V [LD] 0x00_23_01_00
^^
D-TLB-Miss [ST] 0x00_21_02_00
Prot-V [ST] 0x00_23_02_00
^^
D-TLB-Miss [EX] 0x00_21_03_00
Prot-V [EX] 0x00_23_03_00
^^
This helps code consolidation, which is even better when moving code from
assembler to "C".
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
-rw-r--r-- | arch/arc/kernel/entry.S | 14 | ||||
-rw-r--r-- | arch/arc/mm/fault.c | 3 | ||||
-rw-r--r-- | arch/arc/mm/tlbex.S | 14 |
3 files changed, 8 insertions, 23 deletions
diff --git a/arch/arc/kernel/entry.S b/arch/arc/kernel/entry.S index 0c6d664d4a83..53655bf4c9d7 100644 --- a/arch/arc/kernel/entry.S +++ b/arch/arc/kernel/entry.S | |||
@@ -355,8 +355,8 @@ ARC_ENTRY EV_TLBProtV | |||
355 | ; ecr and efa were not saved in case an Intr sneaks in | 355 | ; ecr and efa were not saved in case an Intr sneaks in |
356 | ; after fake rtie | 356 | ; after fake rtie |
357 | ; | 357 | ; |
358 | lr r3, [ecr] | 358 | lr r2, [ecr] |
359 | lr r4, [efa] | 359 | lr r1, [efa] ; Faulting Data address |
360 | 360 | ||
361 | ; --------(4) Return from CPU Exception Mode --------- | 361 | ; --------(4) Return from CPU Exception Mode --------- |
362 | ; Fake a rtie, but rtie to next label | 362 | ; Fake a rtie, but rtie to next label |
@@ -371,23 +371,17 @@ ARC_ENTRY EV_TLBProtV | |||
371 | ; -Access Violaton (WRITE to READ ONLY Page) - for linux COW | 371 | ; -Access Violaton (WRITE to READ ONLY Page) - for linux COW |
372 | ; -Unaligned Access (READ/WRITE on odd boundary) | 372 | ; -Unaligned Access (READ/WRITE on odd boundary) |
373 | ; | 373 | ; |
374 | cmp r3, 0x230400 ; Misaligned data access ? | 374 | cmp r2, 0x230400 ; Misaligned data access ? |
375 | beq 4f | 375 | beq 4f |
376 | 376 | ||
377 | ;========= (6a) Access Violation Processing ======== | 377 | ;========= (6a) Access Violation Processing ======== |
378 | cmp r3, 0x230100 | ||
379 | mov r1, 0x0 ; if LD exception ? write = 0 | ||
380 | mov.ne r1, 0x1 ; else write = 1 | ||
381 | |||
382 | mov r2, r4 ; faulting address | ||
383 | mov r0, sp ; pt_regs | 378 | mov r0, sp ; pt_regs |
384 | bl do_page_fault | 379 | bl do_page_fault |
385 | b ret_from_exception | 380 | b ret_from_exception |
386 | 381 | ||
387 | ;========== (6b) Non aligned access ============ | 382 | ;========== (6b) Non aligned access ============ |
388 | 4: | 383 | 4: |
389 | mov r0, r3 ; cause code | 384 | mov r0, r2 ; cause code |
390 | mov r1, r4 ; faulting address | ||
391 | mov r2, sp ; pt_regs | 385 | mov r2, sp ; pt_regs |
392 | 386 | ||
393 | #ifdef CONFIG_ARC_MISALIGN_ACCESS | 387 | #ifdef CONFIG_ARC_MISALIGN_ACCESS |
diff --git a/arch/arc/mm/fault.c b/arch/arc/mm/fault.c index c0decc1f8d22..fdafeb1917cc 100644 --- a/arch/arc/mm/fault.c +++ b/arch/arc/mm/fault.c | |||
@@ -52,7 +52,7 @@ bad_area: | |||
52 | return 1; | 52 | return 1; |
53 | } | 53 | } |
54 | 54 | ||
55 | void do_page_fault(struct pt_regs *regs, int write, unsigned long address, | 55 | void do_page_fault(struct pt_regs *regs, unsigned long address, |
56 | unsigned long cause_code) | 56 | unsigned long cause_code) |
57 | { | 57 | { |
58 | struct vm_area_struct *vma = NULL; | 58 | struct vm_area_struct *vma = NULL; |
@@ -60,6 +60,7 @@ void do_page_fault(struct pt_regs *regs, int write, unsigned long address, | |||
60 | struct mm_struct *mm = tsk->mm; | 60 | struct mm_struct *mm = tsk->mm; |
61 | siginfo_t info; | 61 | siginfo_t info; |
62 | int fault, ret; | 62 | int fault, ret; |
63 | int write = cause_code & (1 << ECR_C_BIT_DTLB_ST_MISS); /* ST/EX */ | ||
63 | unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | | 64 | unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | |
64 | (write ? FAULT_FLAG_WRITE : 0); | 65 | (write ? FAULT_FLAG_WRITE : 0); |
65 | 66 | ||
diff --git a/arch/arc/mm/tlbex.S b/arch/arc/mm/tlbex.S index 7bf811d51af8..bd8bc90f61d3 100644 --- a/arch/arc/mm/tlbex.S +++ b/arch/arc/mm/tlbex.S | |||
@@ -381,18 +381,8 @@ do_slow_path_pf: | |||
381 | 381 | ||
382 | ; ------- setup args for Linux Page fault Hanlder --------- | 382 | ; ------- setup args for Linux Page fault Hanlder --------- |
383 | mov_s r0, sp | 383 | mov_s r0, sp |
384 | lr r2, [efa] | 384 | lr r1, [efa] |
385 | lr r3, [ecr] | 385 | lr r2, [ecr] |
386 | |||
387 | ; Both st and ex imply WRITE access of some sort, hence do_page_fault( ) | ||
388 | ; invoked with write=1 for DTLB-st/ex Miss and write=0 for ITLB miss or | ||
389 | ; DTLB-ld Miss | ||
390 | ; DTLB Miss Cause code is ld = 0x01 , st = 0x02, ex = 0x03 | ||
391 | ; Following code uses that fact that st/ex have one bit in common | ||
392 | |||
393 | btst_s r3, ECR_C_BIT_DTLB_ST_MISS | ||
394 | mov.z r1, 0 | ||
395 | mov.nz r1, 1 | ||
396 | 386 | ||
397 | ; We don't want exceptions to be disabled while the fault is handled. | 387 | ; We don't want exceptions to be disabled while the fault is handled. |
398 | ; Now that we have saved the context we return from exception hence | 388 | ; Now that we have saved the context we return from exception hence |