]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - arch/arm64/mm/fault.c
scsi_dh: don't try to load a device handler during async probing
[karo-tx-linux.git] / arch / arm64 / mm / fault.c
index 94d98cd1aad8a1e98472b95189e87f50f973156f..aba9ead1384c036a0d6a441c92ced63cfd7ed4ae 100644 (file)
 #include <linux/highmem.h>
 #include <linux/perf_event.h>
 
+#include <asm/cpufeature.h>
 #include <asm/exception.h>
 #include <asm/debug-monitors.h>
 #include <asm/esr.h>
+#include <asm/sysreg.h>
 #include <asm/system_misc.h>
 #include <asm/pgtable.h>
 #include <asm/tlbflush.h>
@@ -223,6 +225,13 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr,
                mm_flags |= FAULT_FLAG_WRITE;
        }
 
+       /*
+        * PAN bit set implies the fault happened in kernel space, but not
+        * in the arch's user access functions.
+        */
+       if (IS_ENABLED(CONFIG_ARM64_PAN) && (regs->pstate & PSR_PAN_BIT))
+               goto no_context;
+
        /*
         * As per x86, we may deadlock here. However, since the kernel only
         * validly references user space from well defined areas of the code,
@@ -492,14 +501,22 @@ asmlinkage void __exception do_sp_pc_abort(unsigned long addr,
        arm64_notify_die("Oops - SP/PC alignment exception", regs, &info, esr);
 }
 
-static struct fault_info debug_fault_info[] = {
+int __init early_brk64(unsigned long addr, unsigned int esr,
+                      struct pt_regs *regs);
+
+/*
+ * __refdata because early_brk64 is __init, but the reference to it is
+ * clobbered at arch_initcall time.
+ * See traps.c and debug-monitors.c:debug_traps_init().
+ */
+static struct fault_info __refdata debug_fault_info[] = {
        { do_bad,       SIGTRAP,        TRAP_HWBKPT,    "hardware breakpoint"   },
        { do_bad,       SIGTRAP,        TRAP_HWBKPT,    "hardware single-step"  },
        { do_bad,       SIGTRAP,        TRAP_HWBKPT,    "hardware watchpoint"   },
        { do_bad,       SIGBUS,         0,              "unknown 3"             },
        { do_bad,       SIGTRAP,        TRAP_BRKPT,     "aarch32 BKPT"          },
        { do_bad,       SIGTRAP,        0,              "aarch32 vector catch"  },
-       { do_bad,       SIGTRAP,        TRAP_BRKPT,     "aarch64 BRK"           },
+       { early_brk64,  SIGTRAP,        TRAP_BRKPT,     "aarch64 BRK"           },
        { do_bad,       SIGBUS,         0,              "unknown 7"             },
 };
 
@@ -536,3 +553,10 @@ asmlinkage int __exception do_debug_exception(unsigned long addr,
 
        return 0;
 }
+
+#ifdef CONFIG_ARM64_PAN
+void cpu_enable_pan(void)
+{
+       config_sctlr_el1(SCTLR_EL1_SPAN, 0);
+}
+#endif /* CONFIG_ARM64_PAN */