Commit 0e7f7bcc authored by Catalin Marinas's avatar Catalin Marinas

arm64: Ignore the 'write' ESR flag on cache maintenance faults

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: default avatarCatalin Marinas <catalin.marinas@arm.com>
Reported-by: default avatarTim Northover <Tim.Northover@arm.com>
Cc: stable@vger.kernel.org
parent ed1f2363
...@@ -148,6 +148,7 @@ void do_bad_area(unsigned long addr, unsigned int esr, struct pt_regs *regs) ...@@ -148,6 +148,7 @@ void do_bad_area(unsigned long addr, unsigned int esr, struct pt_regs *regs)
#define VM_FAULT_BADACCESS 0x020000 #define VM_FAULT_BADACCESS 0x020000
#define ESR_WRITE (1 << 6) #define ESR_WRITE (1 << 6)
#define ESR_CM (1 << 8)
#define ESR_LNX_EXEC (1 << 24) #define ESR_LNX_EXEC (1 << 24)
/* /*
...@@ -206,7 +207,7 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr, ...@@ -206,7 +207,7 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr,
struct task_struct *tsk; struct task_struct *tsk;
struct mm_struct *mm; struct mm_struct *mm;
int fault, sig, code; 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 | unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE |
(write ? FAULT_FLAG_WRITE : 0); (write ? FAULT_FLAG_WRITE : 0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment