To fully isolate #DB and #BP from instrumentable code it's necessary to
avoid invoking the hardware latency tracer on nmi_enter/exit().

Provide nmi_enter/exit() variants which are not invoking the hardware
latency tracer. That allows to put calls explicitely into the call sites
outside of the kprobe handling.

Signed-off-by: Thomas Gleixner <[email protected]>

---
 include/linux/hardirq.h |   23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

--- a/include/linux/hardirq.h
+++ b/include/linux/hardirq.h
@@ -76,8 +76,16 @@ extern void irq_exit(void);
 
 /*
  * nmi_enter() can nest up to 15 times; see NMI_BITS.
+ *
+ * ftrace_count_nmi() only increments a counter and is noinstr safe so it
+ * can be invoked in nmi_enter_notrace(). ftrace_nmi_handler_enter/exit()
+ * does time stamping and will be invoked in the actual NMI handling after
+ * an instrumentable section has been reached.
+ *
+ * nmi_enter/exit() still calls into the tracer so existing callers
+ * wont break.
  */
-#define nmi_enter()                                            \
+#define nmi_enter_notrace()                                    \
        do {                                                    \
                arch_nmi_enter();                               \
                printk_nmi_enter();                             \
@@ -87,10 +95,15 @@ extern void irq_exit(void);
                rcu_nmi_enter();                                \
                lockdep_hardirq_enter();                        \
                ftrace_count_nmi();                             \
+       } while (0)
+
+#define nmi_enter()                                            \
+       do {                                                    \
+               nmi_enter_notrace();                            \
                ftrace_nmi_handler_enter();                     \
        } while (0)
 
-#define nmi_exit()                                             \
+#define nmi_exit_notrace()                                     \
        do {                                                    \
                ftrace_nmi_handler_exit();                      \
                lockdep_hardirq_exit();                         \
@@ -102,4 +115,10 @@ extern void irq_exit(void);
                arch_nmi_exit();                                \
        } while (0)
 
+#define nmi_exit()                                             \
+       do {                                                    \
+               ftrace_nmi_handler_exit();                      \
+               nmi_exit_notrace();                             \
+       } while (0)
+
 #endif /* LINUX_HARDIRQ_H */

Reply via email to