]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
dtrace: ignore any and all PFs during NOFAULT memory acceses
authorKris Van Hees <kris.van.hees@oracle.com>
Wed, 8 Jul 2015 03:38:27 +0000 (23:38 -0400)
committerNick Alcock <nick.alcock@oracle.com>
Tue, 21 Jul 2015 14:30:19 +0000 (15:30 +0100)
Previously, memory access from DTrace probe handling could be marked
as NOFAULT (ignore faults) and/or NOPF (ignore page faults).  However,
when safe memory access support is necessary, it is required that no
faults of any kind are allowed to disrupt the system.

Signed-off-by: Kris Van Hees <kris.van.hees@oracle.com>
Acked-by: Nick Alcock <nick.alcock@oracle.com>
arch/sparc/kernel/dtrace_util.c
include/linux/dtrace_os.h
kernel/dtrace/dtrace_os.c

index 4c3126c99cea9e7cdbad4b22d2bcc4fa3961856c..cd68baf37acfc045b82825132e0b944d6f3b5efe 100644 (file)
 #include <linux/slab.h>
 #include <asm/ptrace.h>
 
-void dtrace_skip_instruction(struct pt_regs *regs) {
+void dtrace_skip_instruction(struct pt_regs *regs)
+{
        regs->tpc = regs->tnpc;
        regs->tnpc += 4;
 }
 
+void dtrace_handle_badaddr(struct pt_regs *regs) {
+       unsigned long   addr = current_thread_info()->fault_address;
+
+       DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
+       this_cpu_core->cpuc_dtrace_illval = addr;
+
+       dtrace_skip_instruction(regs);
+}
 
 int dtrace_die_notifier(struct notifier_block *nb, unsigned long val,
                        void *args)
@@ -24,15 +33,10 @@ int dtrace_die_notifier(struct notifier_block *nb, unsigned long val,
 
        switch (val) {
        case DIE_PAGE_FAULT: {
-               unsigned long   addr = current_thread_info()->fault_address;
-
                if (!DTRACE_CPUFLAG_ISSET(CPU_DTRACE_NOFAULT))
                        return NOTIFY_DONE;
 
-               DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
-               this_cpu_core->cpuc_dtrace_illval = addr;
-
-               dtrace_skip_instruction(dargs->regs);
+               dtrace_handle_badaddr(dargs->regs);
 
                return NOTIFY_OK | NOTIFY_STOP_MASK;
        }
@@ -47,16 +51,13 @@ int dtrace_die_notifier(struct notifier_block *nb, unsigned long val,
                return NOTIFY_OK | NOTIFY_STOP_MASK;
        }
        case DIE_TRAP: {
-               unsigned long   addr = current_thread_info()->fault_address;
-
                if (dargs->trapnr != 0x34)
                        return NOTIFY_DONE;
+
                if (!DTRACE_CPUFLAG_ISSET(CPU_DTRACE_NOFAULT))
                        return NOTIFY_DONE;
 
-               DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
-
-               dtrace_skip_instruction(dargs->regs);
+               dtrace_handle_badaddr(dargs->regs);
 
                return NOTIFY_OK | NOTIFY_STOP_MASK;
        }
index 74fa48609c3616ceb7320624b794993420c739f0..8c7819ae55c8707b1085332e6d876c569be673da 100644 (file)
@@ -60,7 +60,7 @@ typedef struct stacktrace_state {
 } stacktrace_state_t;
 
 extern void dtrace_stacktrace(stacktrace_state_t *);
-extern int dtrace_handle_no_pf(struct pt_regs *);
+extern void dtrace_handle_badaddr(struct pt_regs *);
 
 /*
  * This is only safe to call if we know this is a userspace fault
@@ -68,8 +68,11 @@ extern int dtrace_handle_no_pf(struct pt_regs *);
  */
 static inline int dtrace_no_pf(struct pt_regs *regs)
 {
-       if (unlikely(DTRACE_CPUFLAG_ISSET(CPU_DTRACE_NOPF)))
-               return dtrace_handle_no_pf(regs);
+       if (unlikely(DTRACE_CPUFLAG_ISSET(CPU_DTRACE_NOFAULT))) {
+               dtrace_handle_badaddr(regs);
+               return 1;
+       }
+
        return 0;
 }
 
index 06d9498d44e8c5c84795ccea1bed300631c001d3..415967fd56808450d3bb8d4c6cbbd728f6f8cd50 100644 (file)
@@ -443,20 +443,6 @@ void dtrace_disable(void)
 }
 EXPORT_SYMBOL(dtrace_disable);
 
-/*
- * The dtrace-is-active body of dtrace_no_pf(), split into a separate function
- * to keep icache pressure down while incurring function call overhead only in
- * the rare dtrace-active, pf-disabled case.
- */
-int dtrace_handle_no_pf(struct pt_regs *regs)
-{
-       DTRACE_CPUFLAG_SET(CPU_DTRACE_PF_TRAPPED);
-
-       dtrace_skip_instruction(regs);
-
-       return 1;
-}
-
 /*---------------------------------------------------------------------------*\
 (* USER SPACE TRACING (FASTTRAP) SUPPORT                                     *)
 \*---------------------------------------------------------------------------*/