hc
2024-11-01 2f529f9b558ca1c1bd74be7437a84e4711743404
kernel/kernel/panic.c
....@@ -27,6 +27,7 @@
2727 #include <linux/sysrq.h>
2828 #include <linux/init.h>
2929 #include <linux/nmi.h>
30
+#include <linux/irq_pipeline.h>
3031 #include <linux/console.h>
3132 #include <linux/bug.h>
3233 #include <linux/ratelimit.h>
....@@ -49,7 +50,7 @@
4950 IS_ENABLED(CONFIG_GCC_PLUGIN_RANDSTRUCT) ? (1 << TAINT_RANDSTRUCT) : 0;
5051 static int pause_on_oops;
5152 static int pause_on_oops_flag;
52
-static DEFINE_SPINLOCK(pause_on_oops_lock);
53
+static DEFINE_HARD_SPINLOCK(pause_on_oops_lock);
5354 bool crash_kexec_post_notifiers;
5455 int panic_on_warn __read_mostly;
5556 unsigned long panic_on_taint;
....@@ -189,8 +190,9 @@
189190 * there is nothing to prevent an interrupt handler (that runs
190191 * after setting panic_cpu) from invoking panic() again.
191192 */
192
- local_irq_disable();
193
+ hard_local_irq_disable();
193194 preempt_disable_notrace();
195
+ irq_pipeline_oops();
194196
195197 /*
196198 * It's possible to come here directly from a panic-assertion and
....@@ -267,9 +269,12 @@
267269
268270 /*
269271 * Run any panic handlers, including those that might need to
270
- * add information to the kmsg dump output.
272
+ * add information to the kmsg dump output. Skip panic
273
+ * handlers if running over the oob stage, as they would most
274
+ * likely break.
271275 */
272
- atomic_notifier_call_chain(&panic_notifier_list, 0, buf);
276
+ if (running_inband())
277
+ atomic_notifier_call_chain(&panic_notifier_list, 0, buf);
273278
274279 /* Call flush even twice. It tries harder with a single online CPU */
275280 printk_safe_flush_on_panic();
....@@ -474,7 +479,7 @@
474479 if (!pause_on_oops)
475480 return;
476481
477
- spin_lock_irqsave(&pause_on_oops_lock, flags);
482
+ raw_spin_lock_irqsave(&pause_on_oops_lock, flags);
478483 if (pause_on_oops_flag == 0) {
479484 /* This CPU may now print the oops message */
480485 pause_on_oops_flag = 1;
....@@ -484,21 +489,21 @@
484489 /* This CPU gets to do the counting */
485490 spin_counter = pause_on_oops;
486491 do {
487
- spin_unlock(&pause_on_oops_lock);
492
+ raw_spin_unlock(&pause_on_oops_lock);
488493 spin_msec(MSEC_PER_SEC);
489
- spin_lock(&pause_on_oops_lock);
494
+ raw_spin_lock(&pause_on_oops_lock);
490495 } while (--spin_counter);
491496 pause_on_oops_flag = 0;
492497 } else {
493498 /* This CPU waits for a different one */
494499 while (spin_counter) {
495
- spin_unlock(&pause_on_oops_lock);
500
+ raw_spin_unlock(&pause_on_oops_lock);
496501 spin_msec(1);
497
- spin_lock(&pause_on_oops_lock);
502
+ raw_spin_lock(&pause_on_oops_lock);
498503 }
499504 }
500505 }
501
- spin_unlock_irqrestore(&pause_on_oops_lock, flags);
506
+ raw_spin_unlock_irqrestore(&pause_on_oops_lock, flags);
502507 }
503508
504509 /*
....@@ -528,6 +533,7 @@
528533 {
529534 tracing_off();
530535 /* can't trust the integrity of the kernel anymore: */
536
+ irq_pipeline_oops();
531537 debug_locks_off();
532538 do_oops_enter_exit();
533539