summaryrefslogtreecommitdiff
path: root/arch/unicore32/mm/fault.c
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2012-11-26 01:09:30 -0800
committerOlof Johansson <olof@lixom.net>2012-11-26 01:09:53 -0800
commit0dfeada90989833d0144b4df25d2b9ce3746624f (patch)
tree0773c2f81a94ca99b8b07b0d984754c81fdd16cc /arch/unicore32/mm/fault.c
parentd408c5dcc524dfc8e687c443719a3d6be86e2ea0 (diff)
parent2a18588c0ce336933be3c99c91e74e21db56a0fe (diff)
Merge tag 'orion_dt_for_3.8' of git://git.infradead.org/users/jcooper/linux into next/dt
From Jason Cooper: orion dt for v3.8 - ehci-orion dt binding - gpio-poweroff - use dt regulators - move mpp to DT/pinctrl Depends on: - orion/boards - merge conflicts - keep all 'select's in Kconfig - remove all #includes in board-*.c - pinctrl/devel up to: - 06763c7 pinctrl: mvebu: move to its own directory * tag 'orion_dt_for_3.8' of git://git.infradead.org/users/jcooper/linux: (211 commits) ARM: Kirkwood: remove kirkwood_ehci_init() from new boards ARM: Kirkwood: Add support LED of OpenBlocks A6 ARM: Kirkwood: Convert to EHCI via DT for OpenBlocks A6 ARM: kirkwood: Add NAND partiton map for OpenBlocks A6 ARM: kirkwood: Add support second I2C bus and RTC on OpenBlocks A6 ARM: kirkwood: Add support DT of second I2C bus ARM: kirkwood: Convert mplcec4 board to pinctrl ARM: Kirkwood: Convert km_kirkwood to pinctrl ARM: Kirkwood: support 98DX412x kirkwoods with pinctrl ARM: Kirkwood: Convert IX2-200 to pinctrl. ARM: Kirkwood: Convert lsxl boards to pinctrl. ARM: Kirkwood: Convert ib62x0 to pinctrl. ARM: Kirkwood: Convert GoFlex Net to pinctrl. ARM: Kirkwood: Convert dreamplug to pinctrl. ARM: Kirkwood: Convert dockstar to pinctrl. ARM: Kirkwood: Convert dnskw to pinctrl ARM: Kirkwood: Convert iConnect to pinctrl. ARM: Kirkwood: Convert TS219 to pinctrl. ARM: Kirkwood: Add DTSI files for pinctrl ARM: Kirkwood: Make use of mvebu pincltl and gpio drivers ... Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'arch/unicore32/mm/fault.c')
-rw-r--r--arch/unicore32/mm/fault.c37
1 files changed, 27 insertions, 10 deletions
diff --git a/arch/unicore32/mm/fault.c b/arch/unicore32/mm/fault.c
index 2eeb9c04cab0..f9b5c10bccee 100644
--- a/arch/unicore32/mm/fault.c
+++ b/arch/unicore32/mm/fault.c
@@ -168,7 +168,7 @@ static inline bool access_error(unsigned int fsr, struct vm_area_struct *vma)
}
static int __do_pf(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
- struct task_struct *tsk)
+ unsigned int flags, struct task_struct *tsk)
{
struct vm_area_struct *vma;
int fault;
@@ -194,14 +194,7 @@ good_area:
* If for any reason at all we couldn't handle the fault, make
* sure we exit gracefully rather than endlessly redo the fault.
*/
- fault = handle_mm_fault(mm, vma, addr & PAGE_MASK,
- (!(fsr ^ 0x12)) ? FAULT_FLAG_WRITE : 0);
- if (unlikely(fault & VM_FAULT_ERROR))
- return fault;
- if (fault & VM_FAULT_MAJOR)
- tsk->maj_flt++;
- else
- tsk->min_flt++;
+ fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, flags);
return fault;
check_stack:
@@ -216,6 +209,8 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
struct task_struct *tsk;
struct mm_struct *mm;
int fault, sig, code;
+ unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE |
+ ((!(fsr ^ 0x12)) ? FAULT_FLAG_WRITE : 0);
tsk = current;
mm = tsk->mm;
@@ -236,6 +231,7 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
if (!user_mode(regs)
&& !search_exception_tables(regs->UCreg_pc))
goto no_context;
+retry:
down_read(&mm->mmap_sem);
} else {
/*
@@ -251,7 +247,28 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
#endif
}
- fault = __do_pf(mm, addr, fsr, tsk);
+ fault = __do_pf(mm, addr, fsr, flags, tsk);
+
+ /* If we need to retry but a fatal signal is pending, handle the
+ * signal first. We do not need to release the mmap_sem because
+ * it would already be released in __lock_page_or_retry in
+ * mm/filemap.c. */
+ if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
+ return 0;
+
+ if (!(fault & VM_FAULT_ERROR) && (flags & FAULT_FLAG_ALLOW_RETRY)) {
+ if (fault & VM_FAULT_MAJOR)
+ tsk->maj_flt++;
+ else
+ tsk->min_flt++;
+ if (fault & VM_FAULT_RETRY) {
+ /* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk
+ * of starvation. */
+ flags &= ~FAULT_FLAG_ALLOW_RETRY;
+ goto retry;
+ }
+ }
+
up_read(&mm->mmap_sem);
/*