--- /dev/null
+From 464468fa29f9244613add91dd38810189c07b54b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Nov 2024 13:02:34 -0800
+Subject: kasan: make report_lock a raw spinlock
+
+From: Jared Kangas <jkangas@redhat.com>
+
+[ Upstream commit e30a0361b8515d424c73c67de1a43e45a13b8ba2 ]
+
+If PREEMPT_RT is enabled, report_lock is a sleeping spinlock and must not
+be locked when IRQs are disabled. However, KASAN reports may be triggered
+in such contexts. For example:
+
+ char *s = kzalloc(1, GFP_KERNEL);
+ kfree(s);
+ local_irq_disable();
+ char c = *s; /* KASAN report here leads to spin_lock() */
+ local_irq_enable();
+
+Make report_spinlock a raw spinlock to prevent rescheduling when
+PREEMPT_RT is enabled.
+
+Link: https://lkml.kernel.org/r/20241119210234.1602529-1-jkangas@redhat.com
+Fixes: 342a93247e08 ("locking/spinlock: Provide RT variant header: <linux/spinlock_rt.h>")
+Signed-off-by: Jared Kangas <jkangas@redhat.com>
+Cc: Alexander Potapenko <glider@google.com>
+Cc: Andrey Konovalov <andreyknvl@gmail.com>
+Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
+Cc: Dmitry Vyukov <dvyukov@google.com>
+Cc: Vincenzo Frascino <vincenzo.frascino@arm.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/kasan/report.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/mm/kasan/report.c b/mm/kasan/report.c
+index 821cd12e8c8a7..6ad986c267b5e 100644
+--- a/mm/kasan/report.c
++++ b/mm/kasan/report.c
+@@ -173,7 +173,7 @@ static void update_kunit_status(bool sync)
+ static void update_kunit_status(bool sync) { }
+ #endif
+
+-static DEFINE_SPINLOCK(report_lock);
++static DEFINE_RAW_SPINLOCK(report_lock);
+
+ static void start_report(unsigned long *flags, bool sync)
+ {
+@@ -185,7 +185,7 @@ static void start_report(unsigned long *flags, bool sync)
+ lockdep_off();
+ /* Make sure we don't end up in loop. */
+ report_suppress_start();
+- spin_lock_irqsave(&report_lock, *flags);
++ raw_spin_lock_irqsave(&report_lock, *flags);
+ pr_err("==================================================================\n");
+ }
+
+@@ -195,7 +195,7 @@ static void end_report(unsigned long *flags, void *addr)
+ trace_error_report_end(ERROR_DETECTOR_KASAN,
+ (unsigned long)addr);
+ pr_err("==================================================================\n");
+- spin_unlock_irqrestore(&report_lock, *flags);
++ raw_spin_unlock_irqrestore(&report_lock, *flags);
+ if (!test_bit(KASAN_BIT_MULTI_SHOT, &kasan_flags))
+ check_panic_on_warn("KASAN");
+ if (kasan_arg_fault == KASAN_ARG_FAULT_PANIC)
+--
+2.43.0
+
--- /dev/null
+From f5de8091ce62f9f4dc0ac8ec176cf827bf39c1b0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Mar 2023 00:43:33 +0100
+Subject: kasan: suppress recursive reports for HW_TAGS
+
+From: Andrey Konovalov <andreyknvl@google.com>
+
+[ Upstream commit c6a690e0c978bda8106e7a489c13323f90b087d0 ]
+
+KASAN suppresses reports for bad accesses done by the KASAN reporting
+code. The reporting code might access poisoned memory for reporting
+purposes.
+
+Software KASAN modes do this by suppressing reports during reporting via
+current->kasan_depth, the same way they suppress reports during accesses
+to poisoned slab metadata.
+
+Hardware Tag-Based KASAN does not use current->kasan_depth, and instead
+resets pointer tags for accesses to poisoned memory done by the reporting
+code.
+
+Despite that, a recursive report can still happen:
+
+1. On hardware with faulty MTE support. This was observed by Weizhao
+ Ouyang on a faulty hardware that caused memory tags to randomly change
+ from time to time.
+
+2. Theoretically, due to a previous MTE-undetected memory corruption.
+
+A recursive report can happen via:
+
+1. Accessing a pointer with a non-reset tag in the reporting code, e.g.
+ slab->slab_cache, which is what Weizhao Ouyang observed.
+
+2. Theoretically, via external non-annotated routines, e.g. stackdepot.
+
+To resolve this issue, resetting tags for all of the pointers in the
+reporting code and all the used external routines would be impractical.
+
+Instead, disable tag checking done by the CPU for the duration of KASAN
+reporting for Hardware Tag-Based KASAN.
+
+Without this fix, Hardware Tag-Based KASAN reporting code might deadlock.
+
+[andreyknvl@google.com: disable preemption instead of migration, fix comment typo]
+ Link: https://lkml.kernel.org/r/d14417c8bc5eea7589e99381203432f15c0f9138.1680114854.git.andreyknvl@google.com
+Link: https://lkml.kernel.org/r/59f433e00f7fa985e8bf9f7caf78574db16b67ab.1678491668.git.andreyknvl@google.com
+Fixes: 2e903b914797 ("kasan, arm64: implement HW_TAGS runtime")
+Signed-off-by: Andrey Konovalov <andreyknvl@google.com>
+Reported-by: Weizhao Ouyang <ouyangweizhao@zeku.com>
+Reviewed-by: Marco Elver <elver@google.com>
+Cc: Alexander Potapenko <glider@google.com>
+Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Dmitry Vyukov <dvyukov@google.com>
+Cc: Evgenii Stepanov <eugenis@google.com>
+Cc: Peter Collingbourne <pcc@google.com>
+Cc: Vincenzo Frascino <vincenzo.frascino@arm.com>
+Cc: Will Deacon <will@kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Stable-dep-of: e30a0361b851 ("kasan: make report_lock a raw spinlock")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/kasan/report.c | 59 ++++++++++++++++++++++++++++++++++++++---------
+ 1 file changed, 48 insertions(+), 11 deletions(-)
+
+diff --git a/mm/kasan/report.c b/mm/kasan/report.c
+index 5d9ae80df4954..821cd12e8c8a7 100644
+--- a/mm/kasan/report.c
++++ b/mm/kasan/report.c
+@@ -73,10 +73,18 @@ static int __init kasan_set_multi_shot(char *str)
+ __setup("kasan_multi_shot", kasan_set_multi_shot);
+
+ /*
+- * Used to suppress reports within kasan_disable/enable_current() critical
+- * sections, which are used for marking accesses to slab metadata.
++ * This function is used to check whether KASAN reports are suppressed for
++ * software KASAN modes via kasan_disable/enable_current() critical sections.
++ *
++ * This is done to avoid:
++ * 1. False-positive reports when accessing slab metadata,
++ * 2. Deadlocking when poisoned memory is accessed by the reporting code.
++ *
++ * Hardware Tag-Based KASAN instead relies on:
++ * For #1: Resetting tags via kasan_reset_tag().
++ * For #2: Suppression of tag checks via CPU, see report_suppress_start/end().
+ */
+-static bool report_suppressed(void)
++static bool report_suppressed_sw(void)
+ {
+ #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
+ if (current->kasan_depth)
+@@ -85,6 +93,30 @@ static bool report_suppressed(void)
+ return false;
+ }
+
++static void report_suppress_start(void)
++{
++#ifdef CONFIG_KASAN_HW_TAGS
++ /*
++ * Disable preemption for the duration of printing a KASAN report, as
++ * hw_suppress_tag_checks_start() disables checks on the current CPU.
++ */
++ preempt_disable();
++ hw_suppress_tag_checks_start();
++#else
++ kasan_disable_current();
++#endif
++}
++
++static void report_suppress_stop(void)
++{
++#ifdef CONFIG_KASAN_HW_TAGS
++ hw_suppress_tag_checks_stop();
++ preempt_enable();
++#else
++ kasan_enable_current();
++#endif
++}
++
+ /*
+ * Used to avoid reporting more than one KASAN bug unless kasan_multi_shot
+ * is enabled. Note that KASAN tests effectively enable kasan_multi_shot
+@@ -152,7 +184,7 @@ static void start_report(unsigned long *flags, bool sync)
+ /* Do not allow LOCKDEP mangling KASAN reports. */
+ lockdep_off();
+ /* Make sure we don't end up in loop. */
+- kasan_disable_current();
++ report_suppress_start();
+ spin_lock_irqsave(&report_lock, *flags);
+ pr_err("==================================================================\n");
+ }
+@@ -170,7 +202,7 @@ static void end_report(unsigned long *flags, void *addr)
+ panic("kasan.fault=panic set ...\n");
+ add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE);
+ lockdep_on();
+- kasan_enable_current();
++ report_suppress_stop();
+ }
+
+ static void print_error_description(struct kasan_report_info *info)
+@@ -439,9 +471,13 @@ void kasan_report_invalid_free(void *ptr, unsigned long ip, enum kasan_report_ty
+ struct kasan_report_info info;
+
+ /*
+- * Do not check report_suppressed(), as an invalid-free cannot be
+- * caused by accessing slab metadata and thus should not be
+- * suppressed by kasan_disable/enable_current() critical sections.
++ * Do not check report_suppressed_sw(), as an invalid-free cannot be
++ * caused by accessing poisoned memory and thus should not be suppressed
++ * by kasan_disable/enable_current() critical sections.
++ *
++ * Note that for Hardware Tag-Based KASAN, kasan_report_invalid_free()
++ * is triggered by explicit tag checks and not by the ones performed by
++ * the CPU. Thus, reporting invalid-free is not suppressed as well.
+ */
+ if (unlikely(!report_enabled()))
+ return;
+@@ -476,7 +512,7 @@ bool kasan_report(unsigned long addr, size_t size, bool is_write,
+ unsigned long irq_flags;
+ struct kasan_report_info info;
+
+- if (unlikely(report_suppressed()) || unlikely(!report_enabled())) {
++ if (unlikely(report_suppressed_sw()) || unlikely(!report_enabled())) {
+ ret = false;
+ goto out;
+ }
+@@ -508,8 +544,9 @@ void kasan_report_async(void)
+ unsigned long flags;
+
+ /*
+- * Do not check report_suppressed(), as kasan_disable/enable_current()
+- * critical sections do not affect Hardware Tag-Based KASAN.
++ * Do not check report_suppressed_sw(), as
++ * kasan_disable/enable_current() critical sections do not affect
++ * Hardware Tag-Based KASAN.
+ */
+ if (unlikely(!report_enabled()))
+ return;
+--
+2.43.0
+