Miroslav Benes f86a9f
From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
Miroslav Benes f86a9f
Date: Thu, 29 Oct 2020 17:31:45 -0400
Miroslav Benes f86a9f
Subject: ftrace: Fix recursion check for NMI test
Miroslav Benes f86a9f
Git-commit: ee11b93f95eabdf8198edd4668bf9102e7248270
Miroslav Benes f86a9f
Patch-mainline: v5.10-rc3
Miroslav Benes f86a9f
References: git-fixes
Miroslav Benes f86a9f
Miroslav Benes f86a9f
The code that checks recursion will work to only do the recursion check once
Miroslav Benes f86a9f
if there's nested checks. The top one will do the check, the other nested
Miroslav Benes f86a9f
checks will see recursion was already checked and return zero for its "bit".
Miroslav Benes f86a9f
On the return side, nothing will be done if the "bit" is zero.
Miroslav Benes f86a9f
Miroslav Benes f86a9f
The problem is that zero is returned for the "good" bit when in NMI context.
Miroslav Benes f86a9f
This will set the bit for NMIs making it look like *all* NMI tracing is
Miroslav Benes f86a9f
recursing, and prevent tracing of anything in NMI context!
Miroslav Benes f86a9f
Miroslav Benes f86a9f
The simple fix is to return "bit + 1" and subtract that bit on the end to
Miroslav Benes f86a9f
get the real bit.
Miroslav Benes f86a9f
Miroslav Benes f86a9f
Cc: stable@vger.kernel.org
Miroslav Benes f86a9f
Fixes: edc15cafcbfa3 ("tracing: Avoid unnecessary multiple recursion checks")
Miroslav Benes f86a9f
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Miroslav Benes f86a9f
Acked-by: Miroslav Benes <mbenes@suse.cz>
Miroslav Benes f86a9f
---
Miroslav Benes f86a9f
 kernel/trace/trace.h | 3 ++-
Miroslav Benes f86a9f
 1 file changed, 2 insertions(+), 1 deletion(-)
Miroslav Benes f86a9f
Miroslav Benes f86a9f
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
Miroslav Benes f86a9f
index f3f5e77123ad..fee535a89560 100644
Miroslav Benes f86a9f
--- a/kernel/trace/trace.h
Miroslav Benes f86a9f
+++ b/kernel/trace/trace.h
Miroslav Benes f86a9f
@@ -698,7 +698,7 @@ static __always_inline int trace_test_and_set_recursion(int start, int max)
Miroslav Benes f86a9f
 	current->trace_recursion = val;
Miroslav Benes f86a9f
 	barrier();
Miroslav Benes f86a9f
 
Miroslav Benes f86a9f
-	return bit;
Miroslav Benes f86a9f
+	return bit + 1;
Miroslav Benes f86a9f
 }
Miroslav Benes f86a9f
 
Miroslav Benes f86a9f
 static __always_inline void trace_clear_recursion(int bit)
Miroslav Benes f86a9f
@@ -708,6 +708,7 @@ static __always_inline void trace_clear_recursion(int bit)
Miroslav Benes f86a9f
 	if (!bit)
Miroslav Benes f86a9f
 		return;
Miroslav Benes f86a9f
 
Miroslav Benes f86a9f
+	bit--;
Miroslav Benes f86a9f
 	bit = 1 << bit;
Miroslav Benes f86a9f
 	val &= ~bit;
Miroslav Benes f86a9f
 
Miroslav Benes f86a9f