summaryrefslogtreecommitdiff
path: root/arch/arm/mm/fault.c
diff options
context:
space:
mode:
authorRussell King (Oracle) <rmk+kernel@armlinux.org.uk>2024-04-18 12:13:38 +0100
committerRussell King (Oracle) <rmk+kernel@armlinux.org.uk>2024-04-18 12:13:38 +0100
commit1add2e44a39028a9acf54587dcd0ad7084fcc2fa (patch)
tree9dd03a06734a3a9c65ae477a355607b08548d4f9 /arch/arm/mm/fault.c
parentaff00427579d4c915ee92553f712e4c632185e6e (diff)
parenta9a058031cfb7e1fcd7a03a4f7228179a0426cb4 (diff)
Merge branches 'amba' and 'misc' into for-next
Diffstat (limited to 'arch/arm/mm/fault.c')
-rw-r--r--arch/arm/mm/fault.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index 439dc6a26bb9..dfa9554ef331 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -242,6 +242,27 @@ static inline bool is_permission_fault(unsigned int fsr)
return false;
}
+#ifdef CONFIG_CPU_TTBR0_PAN
+static inline bool ttbr0_usermode_access_allowed(struct pt_regs *regs)
+{
+ struct svc_pt_regs *svcregs;
+
+ /* If we are in user mode: permission granted */
+ if (user_mode(regs))
+ return true;
+
+ /* uaccess state saved above pt_regs on SVC exception entry */
+ svcregs = to_svc_pt_regs(regs);
+
+ return !(svcregs->ttbcr & TTBCR_EPD0);
+}
+#else
+static inline bool ttbr0_usermode_access_allowed(struct pt_regs *regs)
+{
+ return true;
+}
+#endif
+
static int __kprobes
do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
{
@@ -285,6 +306,14 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, addr);
+ /*
+ * Privileged access aborts with CONFIG_CPU_TTBR0_PAN enabled are
+ * routed via the translation fault mechanism. Check whether uaccess
+ * is disabled while in kernel mode.
+ */
+ if (!ttbr0_usermode_access_allowed(regs))
+ goto no_context;
+
if (!(flags & FAULT_FLAG_USER))
goto lock_mmap;