aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorCatalin Marinas <catalin.marinas@arm.com>2013-05-07 16:57:06 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-05-11 07:18:24 -0700
commit0661e5659a502db6c989318628365fc34242481d (patch)
tree51e84e4b5ea0c9c46caa75e301db3158403b619a /arch
parentb548047b3ed2ff999744c89277d40ef494e387d9 (diff)
arm64: Ignore the 'write' ESR flag on cache maintenance faults
commit 0e7f7bcc3fc87489cda5aa6aff8ce40eed912279 upstream. ESR.WnR bit is always set on data cache maintenance faults even though the page is not required to have write permission. If a translation fault (page not yet mapped) happens for read-only user address range, Linux incorrectly assumes a permission fault. This patch adds the check of the ESR.CM bit during the page fault handling to ignore the 'write' flag. Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> Reported-by: Tim Northover <Tim.Northover@arm.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm64/mm/fault.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index afadae6682e..0782eaf4913 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -148,6 +148,7 @@ void do_bad_area(unsigned long addr, unsigned int esr, struct pt_regs *regs)
#define VM_FAULT_BADACCESS 0x020000
#define ESR_WRITE (1 << 6)
+#define ESR_CM (1 << 8)
#define ESR_LNX_EXEC (1 << 24)
/*
@@ -206,7 +207,7 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr,
struct task_struct *tsk;
struct mm_struct *mm;
int fault, sig, code;
- int write = esr & ESR_WRITE;
+ bool write = (esr & ESR_WRITE) && !(esr & ESR_CM);
unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE |
(write ? FAULT_FLAG_WRITE : 0);