arm64: Ignore the 'write' ESR flag on cache maintenance faults
authorCatalin Marinas <catalin.marinas@arm.com>
Tue, 7 May 2013 15:57:06 +0000 (16:57 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 11 May 2013 14:18:24 +0000 (07:18 -0700)
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>
arch/arm64/mm/fault.c

index afadae6682ed8b867f6165b0e92860f0f0cc566d..0782eaf491363c5bdd08673dfe57a65fae48b89c 100644 (file)
@@ -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);