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)
committerCatalin Marinas <catalin.marinas@arm.com>
Wed, 8 May 2013 09:33:16 +0000 (10:33 +0100)
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>
Cc: stable@vger.kernel.org
arch/arm64/mm/fault.c

index 52638171d6fdc3f1e287442e1564fe48a41b526e..98af6e760cce6781a5b117d786bcd16fc136a0b1 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);