]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
bug: Add report_bug_entry()
authorPeter Zijlstra <peterz@infradead.org>
Sat, 7 Jun 2025 08:52:28 +0000 (10:52 +0200)
committerPeter Zijlstra <peterz@infradead.org>
Fri, 21 Nov 2025 10:21:31 +0000 (11:21 +0100)
Add a report_bug() variant where the bug_entry is already known. This
is useful when the exception instruction is not instantiated per-site.
But instead has a single instance. In such a case the bug_entry
address might be passed along in a known register or something.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20251110115757.575795595@infradead.org
include/linux/bug.h
lib/bug.c

index a9948a9f1093beeb112a55dcfa706d8cf6c74b75..17a4933c611b047a833a8342bdaf4ecb49c09d5b 100644 (file)
@@ -42,6 +42,7 @@ void bug_get_file_line(struct bug_entry *bug, const char **file,
 struct bug_entry *find_bug(unsigned long bugaddr);
 
 enum bug_trap_type report_bug(unsigned long bug_addr, struct pt_regs *regs);
+enum bug_trap_type report_bug_entry(struct bug_entry *bug, struct pt_regs *regs);
 
 /* These are defined by the architecture */
 int is_valid_bugaddr(unsigned long addr);
@@ -62,6 +63,13 @@ static inline enum bug_trap_type report_bug(unsigned long bug_addr,
 }
 
 struct bug_entry;
+
+static inline enum bug_trap_type
+report_bug_entry(struct bug_entry *bug, struct pt_regs *regs)
+{
+       return BUG_TRAP_TYPE_BUG;
+}
+
 static inline void bug_get_file_line(struct bug_entry *bug, const char **file,
                                     unsigned int *line)
 {
index 8100258a200487d719b3bdca8761c9d7debd9886..581a66b88c5c04646bbc9000c97a014494995e75 100644 (file)
--- a/lib/bug.c
+++ b/lib/bug.c
@@ -183,18 +183,20 @@ static void __warn_printf(const char *fmt, struct pt_regs *regs)
        printk("%s", fmt);
 }
 
-static enum bug_trap_type __report_bug(unsigned long bugaddr, struct pt_regs *regs)
+static enum bug_trap_type __report_bug(struct bug_entry *bug, unsigned long bugaddr, struct pt_regs *regs)
 {
        bool warning, once, done, no_cut, has_args;
        const char *file, *fmt;
        unsigned line;
 
-       if (!is_valid_bugaddr(bugaddr))
-               return BUG_TRAP_TYPE_NONE;
+       if (!bug) {
+               if (!is_valid_bugaddr(bugaddr))
+                       return BUG_TRAP_TYPE_NONE;
 
-       bug = find_bug(bugaddr);
-       if (!bug)
-               return BUG_TRAP_TYPE_NONE;
+               bug = find_bug(bugaddr);
+               if (!bug)
+                       return BUG_TRAP_TYPE_NONE;
+       }
 
        disable_trace_on_warning();
 
@@ -244,13 +246,25 @@ static enum bug_trap_type __report_bug(unsigned long bugaddr, struct pt_regs *re
        return BUG_TRAP_TYPE_BUG;
 }
 
+enum bug_trap_type report_bug_entry(struct bug_entry *bug, struct pt_regs *regs)
+{
+       enum bug_trap_type ret;
+       bool rcu = false;
+
+       rcu = warn_rcu_enter();
+       ret = __report_bug(bug, 0, regs);
+       warn_rcu_exit(rcu);
+
+       return ret;
+}
+
 enum bug_trap_type report_bug(unsigned long bugaddr, struct pt_regs *regs)
 {
        enum bug_trap_type ret;
        bool rcu = false;
 
        rcu = warn_rcu_enter();
-       ret = __report_bug(bugaddr, regs);
+       ret = __report_bug(NULL, bugaddr, regs);
        warn_rcu_exit(rcu);
 
        return ret;