2022-01-18 02:33:55

by Madhavan T. Venkataraman

[permalink] [raw]
Subject: [PATCH v13 00/11] arm64: Reorganize the unwinder and implement stack trace reliability checks

From: "Madhavan T. Venkataraman" <[email protected]>

I have rebased this patch series on top of Linus' tree as of Jan 15, 2022.
The base commit is provided at the end of this email.

Remove NULL task check
======================

Currently, there is a check for a NULL task in unwind_frame(). It is not
needed since all current consumers pass a non-NULL task.

Rename unwinder functions
=========================

Rename unwinder functions to unwind*() similar to other architectures
for naming consistency.

start_backtrace() ==> unwind_init()
unwind_frame() ==> unwind_next()
walk_stackframe() ==> unwind()

Rename struct stackframe
========================

Rename "struct stackframe" to "struct unwind_state" for better naming
and consistency.

Split unwind_init()
===================

Unwind initialization has 3 cases. Accordingly, define 3 separate init
functions as follows:

- unwind_init_from_regs()
- unwind_init_from_current()
- unwind_init_from_task()

This makes it easier to understand and add specialized code to each case
in the future.

Copy task argument
==================

Copy the task argument passed to arch_stack_walk() to unwind_state so that
it can be passed to unwind functions via unwind_state rather than as a
separate argument. The task is a fundamental part of the unwind state.

Use stack_trace_consume_fn
==========================

stack_trace_consume_fn is a typedef already defined. unwind() does not
use this for its consume_entry() argument. Fix this. Also, rename the
arguments to unwind() for better naming consistency.

Redefine the unwinder loop
==========================

Redefine the unwinder loop and make it simple and somewhat similar to other
architectures. Define the following:

while (unwind_continue(&state, consume_entry, cookie))
unwind_next(&state);

unwind_continue()
This new function implements checks to determine whether the
unwind should continue or terminate.

Reliability checks
==================

There are some kernel features and conditions that make a stack trace
unreliable. Callers may require the unwinder to detect these cases.
E.g., livepatch.

Introduce a new function called unwind_check_reliability() that will detect
these cases and set a boolean "reliable" in the stackframe. Call
unwind_check_reliability() for every frame.

Introduce the first reliability check in unwind_check_reliability() - If
a return PC is not a valid kernel text address, consider the stack
trace unreliable. It could be some generated code.

Other reliability checks will be added in the future.

Make unwind() return a boolean to indicate reliability of the stack trace.

SYM_CODE check
==============

This is the second reliability check implemented.

SYM_CODE functions do not follow normal calling conventions. They cannot
be unwound reliably using the frame pointer. Collect the address ranges
of these functions in a special section called "sym_code_functions".

In unwind_check_reliability(), check the return PC against these ranges. If
a match is found, then mark the stack trace unreliable.

Last stack frame
================

If a SYM_CODE function occurs in the very last frame in the stack trace,
then the stack trace is not considered unreliable. This is because there
is no more unwinding to do. Examples:

- EL0 exception stack traces end in the top level EL0 exception
handlers.

- All kernel thread stack traces end in ret_from_fork().

arch_stack_walk_reliable()
==========================

Introduce arch_stack_walk_reliable() for ARM64. This works like
arch_stack_walk() except that it returns an error if the stack trace is
found to be unreliable.

Until all of the reliability checks are in place in
unwind_check_reliability(), arch_stack_walk_reliable() may not be used by
livepatch. But it may be used by debug and test code.

HAVE_RELIABLE_STACKTRACE
========================

Select this config for arm64. However, make it conditional on
STACK_VALIDATION. When objtool is enhanced to implement stack
validation for arm64, STACK_VALIDATION will be defined.

---
Changelog:
v13:
From Mark Brown:

- Reviewed-by for the following:

[PATCH v12 03/10] arm64: Rename stackframe to unwind_state
[PATCH v11 05/10] arm64: Copy unwind arguments to unwind_state
[PATCH v11 07/10] arm64: Introduce stack trace reliability checks
in the unwinder
[PATCH v11 5/5] arm64: Create a list of SYM_CODE functions, check
return PC against list

From Mark Rutland:

- Reviewed-by for the following:

[PATCH v12 01/10] arm64: Remove NULL task check from unwind_frame()
[PATCH v12 02/10] arm64: Rename unwinder functions
[PATCH v12 03/10] arm64: Rename stackframe to unwind_state

- For each of the 3 cases of unwind initialization, have a separate
init function. Call the common init from each of these init
functions rather than call it separately.

- Only copy the task argument to arch_stack_walk() into
unwind state. Pass the rest of the arguments as arguments to
unwind functions.

v12:
From Mark Brown:

- Reviewed-by for the following:

[PATCH v11 1/5] arm64: Call stack_backtrace() only from within
walk_stackframe()
[PATCH v11 2/5] arm64: Rename unwinder functions
[PATCH v11 3/5] arm64: Make the unwind loop in unwind() similar to
other architectures
[PATCH v11 5/5] arm64: Create a list of SYM_CODE functions, check
return PC against list

- Add an extra patch at the end to select HAVE_RELIABLE_STACKTRACE
just as a place holder for the review. I have added it and made
it conditional on STACK_VALIDATION which has not yet been
implemented.

- Mark had a concern about the code for the check for the final
frame being repeated in two places. I have now added a new
field called "final_fp" in struct stackframe which I compute
once in stacktrace initialization. I have added an explicit
comment that the stacktrace must terminate at the final_fp.

- Place the implementation of arch_stack_walk_reliable() in a
separate patch after all the reliability checks have been
implemented.

From Mark Rutland:

- Place the removal of the NULL task check in unwind_frame() in
a separate patch.

- Add a task field to struct stackframe so the task pointer can be
passed around via the frame instead of as a separate argument. I have
taken this a step further by copying all of the arguments to
arch_stack_walk() into struct stackframe so that only that
struct needs to be passed to unwind functions.

- Rename start_backtrace() to unwind_init() instead of unwind_start().

- Acked-by for the following:

[PATCH v11 2/5] arm64: Rename unwinder functions

- Rename "struct stackframe" to "struct unwind_state".

- Define separate inline functions for initializing the starting
FP and PC from regs, or caller, or blocked task. Don't merge
unwind_init() into unwind().

v11:
From Mark Rutland:

- Peter Zijlstra has submitted patches that make ARCH_STACKWALK
independent of STACKTRACE. Mark Rutland extracted some of the
patches from my v10 series and added his own patches and comments,
rebased it on top of Peter's changes and submitted the series.

So, I have rebased the rest of the patches from v10 on top of
Mark Rutland's changes.

- Split the renaming of the unwinder functions and annotating them
with notrace and NOKPROBE_SYMBOL(). Also, there is currently no
need to annotate unwind_start() as its caller is already annotated
properly. So, I am removing the annotation patch from the series.
This can be done separately later if deemed necessary. Similarly,
I have removed the annotations from unwind_check_reliability() and
unwind_continue().

From Nobuta Keiya:

- unwind_start() should check for final frame and not mark the
final frame unreliable.

v9, v10:
- v9 had a threading problem. So, I resent it as v10.

From me:

- Removed the word "RFC" from the subject line as I believe this
is mature enough to be a regular patch.

From Mark Brown, Mark Rutland:

- Split the patches into smaller, self-contained ones.

- Always enable STACKTRACE so that arch_stack_walk() is always
defined.

From Mark Rutland:

- Update callchain_trace() take the return value of
perf_callchain_store() into acount.

- Restore get_wchan() behavior to the original code.

- Simplify an if statement in dump_backtrace().

From Mark Brown:

- Do not abort the stack trace on the first unreliable frame.


v8:
- Synced to v5.14-rc5.

From Mark Rutland:

- Make the unwinder loop similar to other architectures.

- Keep details to within the unwinder functions and return a simple
boolean to the caller.

- Convert some of the current code that contains unwinder logic to
simply use arch_stack_walk(). I have converted all of them.

- Do not copy sym_code_functions[]. Just place it in rodata for now.

- Have the main loop check for termination conditions rather than
having unwind_frame() check for them. In other words, let
unwind_frame() assume that the fp is valid.

- Replace the big comment for SYM_CODE functions with a shorter
comment.

/*
* As SYM_CODE functions don't follow the usual calling
* conventions, we assume by default that any SYM_CODE function
* cannot be unwound reliably.
*
* Note that this includes:
*
* - Exception handlers and entry assembly
* - Trampoline assembly (e.g., ftrace, kprobes)
* - Hypervisor-related assembly
* - Hibernation-related assembly
* - CPU start-stop, suspend-resume assembly
* - Kernel relocation assembly
*/

v7:
The Mailer screwed up the threading on this. So, I have resent this
same series as version 8 with proper threading to avoid confusion.
v6:
From Mark Rutland:

- The per-frame reliability concept and flag are acceptable. But more
work is needed to make the per-frame checks more accurate and more
complete. E.g., some code reorg is being worked on that will help.

I have now removed the frame->reliable flag and deleted the whole
concept of per-frame status. This is orthogonal to this patch series.
Instead, I have improved the unwinder to return proper return codes
so a caller can take appropriate action without needing per-frame
status.

- Remove the mention of PLTs and update the comment.

I have replaced the comment above the call to __kernel_text_address()
with the comment suggested by Mark Rutland.

Other comments:

- Other comments on the per-frame stuff are not relevant because
that approach is not there anymore.

v5:
From Keiya Nobuta:

- The term blacklist(ed) is not to be used anymore. I have changed it
to unreliable. So, the function unwinder_blacklisted() has been
changed to unwinder_is_unreliable().

From Mark Brown:

- Add a comment for the "reliable" flag in struct stackframe. The
reliability attribute is not complete until all the checks are
in place. Added a comment above struct stackframe.

- Include some of the comments in the cover letter in the actual
code so that we can compare it with the reliable stack trace
requirements document for completeness. I have added a comment:

- above unwinder_is_unreliable() that lists the requirements
that are addressed by the function.

- above the __kernel_text_address() call about all the cases
the call covers.

v4:
From Mark Brown:

- I was checking the return PC with __kernel_text_address() before
the Function Graph trace handling. Mark Brown felt that all the
reliability checks should be performed on the original return PC
once that is obtained. So, I have moved all the reliability checks
to after the Function Graph Trace handling code in the unwinder.
Basically, the unwinder should perform PC translations first (for
rhe return trampoline for Function Graph Tracing, Kretprobes, etc).
Then, the reliability checks should be applied to the resulting
PC.

- Mark said to improve the naming of the new functions so they don't
collide with existing ones. I have used a prefix "unwinder_" for
all the new functions.

From Josh Poimboeuf:

- In the error scenarios in the unwinder, the reliable flag in the
stack frame should be set. Implemented this.

- Some of the other comments are not relevant to the new code as
I have taken a different approach in the new code. That is why
I have not made those changes. E.g., Ard wanted me to add the
"const" keyword to the global section array. That array does not
exist in v4. Similarly, Mark Brown said to use ARRAY_SIZE() for
the same array in a for loop.

Other changes:

- Add a new definition for SYM_CODE_END() that adds the address
range of the function to a special section called
"sym_code_functions".

- Include the new section under initdata in vmlinux.lds.S.

- Define an early_initcall() to copy the contents of the
"sym_code_functions" section to an array by the same name.

- Define a function unwinder_blacklisted() that compares a return
PC against sym_code_sections[]. If there is a match, mark the
stack trace unreliable. Call this from unwind_frame().

v3:
- Implemented a sym_code_ranges[] array to contains sections bounds
for text sections that contain SYM_CODE_*() functions. The unwinder
checks each return PC against the sections. If it falls in any of
the sections, the stack trace is marked unreliable.

- Moved SYM_CODE functions from .text and .init.text into a new
text section called ".code.text". Added this section to
vmlinux.lds.S and sym_code_ranges[].

- Fixed the logic in the unwinder that handles Function Graph
Tracer return trampoline.

- Removed all the previous code that handles:
- ftrace entry code for traced function
- special_functions[] array that lists individual functions
- kretprobe_trampoline() special case

v2
- Removed the terminating entry { 0, 0 } in special_functions[]
and replaced it with the idiom { /* sentinel */ }.

- Change the ftrace trampoline entry ftrace_graph_call in
special_functions[] to ftrace_call + 4 and added explanatory
comments.

- Unnested #ifdefs in special_functions[] for FTRACE.

v1
- Define a bool field in struct stackframe. This will indicate if
a stack trace is reliable.

- Implement a special_functions[] array that will be populated
with special functions in which the stack trace is considered
unreliable.

- Using kallsyms_lookup(), get the address ranges for the special
functions and record them.

- Implement an is_reliable_function(pc). This function will check
if a given return PC falls in any of the special functions. If
it does, the stack trace is unreliable.

- Implement check_reliability() function that will check if a
stack frame is reliable. Call is_reliable_function() from
check_reliability().

- Before a return PC is checked against special_funtions[], it
must be validates as a proper kernel text address. Call
__kernel_text_address() from check_reliability().

- Finally, call check_reliability() from unwind_frame() for
each stack frame.

- Add EL1 exception handlers to special_functions[].

el1_sync();
el1_irq();
el1_error();
el1_sync_invalid();
el1_irq_invalid();
el1_fiq_invalid();
el1_error_invalid();

- The above functions are currently defined as LOCAL symbols.
Make them global so that they can be referenced from the
unwinder code.

- Add FTRACE trampolines to special_functions[]:

ftrace_graph_call()
ftrace_graph_caller()
return_to_handler()

- Add the kretprobe trampoline to special functions[]:

kretprobe_trampoline()

Previous versions and discussion
================================

v12: https://lore.kernel.org/linux-arm-kernel/[email protected]/T/#m21e86eecb9b8f0831196568f0bf62c3b56f65bf0
v11: https://lore.kernel.org/linux-arm-kernel/[email protected]/T/#t
v10: https://lore.kernel.org/linux-arm-kernel/[email protected]/T/#t
v9: Mailer screwed up the threading. Sent the same as v10 with proper threading.
v8: https://lore.kernel.org/linux-arm-kernel/[email protected]/
v7: Mailer screwed up the threading. Sent the same as v8 with proper threading.
v6: https://lore.kernel.org/linux-arm-kernel/[email protected]/
v5: https://lore.kernel.org/linux-arm-kernel/[email protected]/
v4: https://lore.kernel.org/linux-arm-kernel/[email protected]/
v3: https://lore.kernel.org/linux-arm-kernel/[email protected]/
v2: https://lore.kernel.org/linux-arm-kernel/[email protected]/
v1: https://lore.kernel.org/linux-arm-kernel/[email protected]/

Madhavan T. Venkataraman (11):
arm64: Remove NULL task check from unwind_frame()
arm64: Rename unwinder functions
arm64: Rename stackframe to unwind_state
arm64: Split unwind_init()
arm64: Copy the task argument to unwind_state
arm64: Use stack_trace_consume_fn and rename args to unwind()
arm64: Make the unwind loop in unwind() similar to other architectures
arm64: Introduce stack trace reliability checks in the unwinder
arm64: Create a list of SYM_CODE functions, check return PC against
list
arm64: Introduce arch_stack_walk_reliable()
arm64: Select HAVE_RELIABLE_STACKTRACE

arch/arm64/Kconfig | 1 +
arch/arm64/include/asm/linkage.h | 12 ++
arch/arm64/include/asm/sections.h | 1 +
arch/arm64/include/asm/stacktrace.h | 14 +-
arch/arm64/kernel/stacktrace.c | 287 +++++++++++++++++++++-------
arch/arm64/kernel/vmlinux.lds.S | 10 +
6 files changed, 258 insertions(+), 67 deletions(-)


base-commit: a33f5c380c4bd3fa5278d690421b72052456d9fe
--
2.25.1


2022-01-18 02:33:57

by Madhavan T. Venkataraman

[permalink] [raw]
Subject: [PATCH v13 05/11] arm64: Copy the task argument to unwind_state

From: "Madhavan T. Venkataraman" <[email protected]>

Copy the task argument passed to arch_stack_walk() to unwind_state so that
it can be passed to unwind functions via unwind_state rather than as a
separate argument. The task is a fundamental part of the unwind state.

Signed-off-by: Madhavan T. Venkataraman <[email protected]>
---
arch/arm64/include/asm/stacktrace.h | 3 +++
arch/arm64/kernel/stacktrace.c | 29 ++++++++++++++++-------------
2 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h
index 41ec360515f6..af423f5d7ad8 100644
--- a/arch/arm64/include/asm/stacktrace.h
+++ b/arch/arm64/include/asm/stacktrace.h
@@ -51,6 +51,8 @@ struct stack_info {
* @kr_cur: When KRETPROBES is selected, holds the kretprobe instance
* associated with the most recently encountered replacement lr
* value.
+ *
+ * @task: Pointer to the task structure.
*/
struct unwind_state {
unsigned long fp;
@@ -61,6 +63,7 @@ struct unwind_state {
#ifdef CONFIG_KRETPROBES
struct llist_node *kr_cur;
#endif
+ struct task_struct *task;
};

extern void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk,
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index b2b568e5deba..1b32e55735aa 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -33,8 +33,10 @@
*/


-static void unwind_init_common(struct unwind_state *state)
+static void unwind_init_common(struct unwind_state *state,
+ struct task_struct *task)
{
+ state->task = task;
#ifdef CONFIG_KRETPROBES
state->kr_cur = NULL;
#endif
@@ -57,9 +59,10 @@ static void unwind_init_common(struct unwind_state *state)
* TODO: document requirements here.
*/
static inline void unwind_init_from_regs(struct unwind_state *state,
+ struct task_struct *task,
struct pt_regs *regs)
{
- unwind_init_common(state);
+ unwind_init_common(state, task);

state->fp = regs->regs[29];
state->pc = regs->pc;
@@ -71,9 +74,10 @@ static inline void unwind_init_from_regs(struct unwind_state *state,
* Note: this is always inlined, and we expect our caller to be a noinline
* function, such that this starts from our caller's caller.
*/
-static __always_inline void unwind_init_from_current(struct unwind_state *state)
+static __always_inline void unwind_init_from_current(struct unwind_state *state,
+ struct task_struct *task)
{
- unwind_init_common(state);
+ unwind_init_common(state, task);

state->fp = (unsigned long)__builtin_frame_address(1);
state->pc = (unsigned long)__builtin_return_address(0);
@@ -87,7 +91,7 @@ static __always_inline void unwind_init_from_current(struct unwind_state *state)
static inline void unwind_init_from_task(struct unwind_state *state,
struct task_struct *task)
{
- unwind_init_common(state);
+ unwind_init_common(state, task);

state->fp = thread_saved_fp(task);
state->pc = thread_saved_pc(task);
@@ -100,11 +104,11 @@ static inline void unwind_init_from_task(struct unwind_state *state,
* records (e.g. a cycle), determined based on the location and fp value of A
* and the location (but not the fp value) of B.
*/
-static int notrace unwind_next(struct task_struct *tsk,
- struct unwind_state *state)
+static int notrace unwind_next(struct unwind_state *state)
{
unsigned long fp = state->fp;
struct stack_info info;
+ struct task_struct *tsk = state->task;

/* Final frame; nothing to unwind */
if (fp == (unsigned long)task_pt_regs(tsk)->stackframe)
@@ -176,8 +180,7 @@ static int notrace unwind_next(struct task_struct *tsk,
}
NOKPROBE_SYMBOL(unwind_next);

-static void notrace unwind(struct task_struct *tsk,
- struct unwind_state *state,
+static void notrace unwind(struct unwind_state *state,
bool (*fn)(void *, unsigned long), void *data)
{
while (1) {
@@ -185,7 +188,7 @@ static void notrace unwind(struct task_struct *tsk,

if (!fn(data, state->pc))
break;
- ret = unwind_next(tsk, state);
+ ret = unwind_next(state);
if (ret < 0)
break;
}
@@ -232,11 +235,11 @@ noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry,
struct unwind_state state;

if (regs)
- unwind_init_from_regs(&state, regs);
+ unwind_init_from_regs(&state, task, regs);
else if (task == current)
- unwind_init_from_current(&state);
+ unwind_init_from_current(&state, task);
else
unwind_init_from_task(&state, task);

- unwind(task, &state, consume_entry, cookie);
+ unwind(&state, consume_entry, cookie);
}
--
2.25.1

2022-01-18 02:33:58

by Madhavan T. Venkataraman

[permalink] [raw]
Subject: [PATCH v13 06/11] arm64: Use stack_trace_consume_fn and rename args to unwind()

From: "Madhavan T. Venkataraman" <[email protected]>

Rename the arguments to unwind() for better consistency. Also, use the
typedef stack_trace_consume_fn for the consume_entry function as it is
already defined in linux/stacktrace.h.

Signed-off-by: Madhavan T. Venkataraman <[email protected]>
---
arch/arm64/kernel/stacktrace.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index 1b32e55735aa..f772dac78b11 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -181,12 +181,12 @@ static int notrace unwind_next(struct unwind_state *state)
NOKPROBE_SYMBOL(unwind_next);

static void notrace unwind(struct unwind_state *state,
- bool (*fn)(void *, unsigned long), void *data)
+ stack_trace_consume_fn consume_entry, void *cookie)
{
while (1) {
int ret;

- if (!fn(data, state->pc))
+ if (!consume_entry(cookie, state->pc))
break;
ret = unwind_next(state);
if (ret < 0)
--
2.25.1

2022-01-18 02:33:58

by Madhavan T. Venkataraman

[permalink] [raw]
Subject: [PATCH v13 09/11] arm64: Create a list of SYM_CODE functions, check return PC against list

From: "Madhavan T. Venkataraman" <[email protected]>

SYM_CODE functions don't follow the usual calling conventions. Check if the
return PC in a stack frame falls in any of these. If it does, consider the
stack trace unreliable.

Define a special section for unreliable functions
=================================================

Define a SYM_CODE_END() macro for arm64 that adds the function address
range to a new section called "sym_code_functions".

Linker file
===========

Include the "sym_code_functions" section under read-only data in
vmlinux.lds.S.

Initialization
==============

Define an early_initcall() to create a sym_code_functions[] array from
the linker data.

Unwinder check
==============

Add a reliability check in unwind_check_reliability() that compares a
return PC with sym_code_functions[]. If there is a match, then return
failure.

Signed-off-by: Madhavan T. Venkataraman <[email protected]>
Reviewed-by: Mark Brown <[email protected]>
---
arch/arm64/include/asm/linkage.h | 12 +++++++
arch/arm64/include/asm/sections.h | 1 +
arch/arm64/kernel/stacktrace.c | 55 +++++++++++++++++++++++++++++++
arch/arm64/kernel/vmlinux.lds.S | 10 ++++++
4 files changed, 78 insertions(+)

diff --git a/arch/arm64/include/asm/linkage.h b/arch/arm64/include/asm/linkage.h
index b77e9b3f5371..a47e7914b289 100644
--- a/arch/arm64/include/asm/linkage.h
+++ b/arch/arm64/include/asm/linkage.h
@@ -63,4 +63,16 @@
SYM_FUNC_END_ALIAS(x); \
SYM_FUNC_END_ALIAS(__pi_##x)

+/*
+ * Record the address range of each SYM_CODE function in a struct code_range
+ * in a special section.
+ */
+#define SYM_CODE_END(name) \
+ SYM_END(name, SYM_T_NONE) ;\
+ 99: ;\
+ .pushsection "sym_code_functions", "aw" ;\
+ .quad name ;\
+ .quad 99b ;\
+ .popsection
+
#endif
diff --git a/arch/arm64/include/asm/sections.h b/arch/arm64/include/asm/sections.h
index 152cb35bf9df..ac01189668c5 100644
--- a/arch/arm64/include/asm/sections.h
+++ b/arch/arm64/include/asm/sections.h
@@ -22,5 +22,6 @@ extern char __irqentry_text_start[], __irqentry_text_end[];
extern char __mmuoff_data_start[], __mmuoff_data_end[];
extern char __entry_tramp_text_start[], __entry_tramp_text_end[];
extern char __relocate_new_kernel_start[], __relocate_new_kernel_end[];
+extern char __sym_code_functions_start[], __sym_code_functions_end[];

#endif /* __ASM_SECTIONS_H */
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index 3dc0374e83f7..8bfe31cbee46 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -18,11 +18,40 @@
#include <asm/stack_pointer.h>
#include <asm/stacktrace.h>

+struct code_range {
+ unsigned long start;
+ unsigned long end;
+};
+
+static struct code_range *sym_code_functions;
+static int num_sym_code_functions;
+
+int __init init_sym_code_functions(void)
+{
+ size_t size = (unsigned long)__sym_code_functions_end -
+ (unsigned long)__sym_code_functions_start;
+
+ sym_code_functions = (struct code_range *)__sym_code_functions_start;
+ /*
+ * Order it so that sym_code_functions is not visible before
+ * num_sym_code_functions.
+ */
+ smp_mb();
+ num_sym_code_functions = size / sizeof(struct code_range);
+
+ return 0;
+}
+early_initcall(init_sym_code_functions);
+
/*
* Check the stack frame for conditions that make further unwinding unreliable.
*/
static void unwind_check_reliability(struct unwind_state *state)
{
+ const struct code_range *range;
+ unsigned long pc;
+ int i;
+
if (state->fp == state->final_fp) {
/* Final frame; no more unwind, no need to check reliability */
return;
@@ -35,6 +64,32 @@ static void unwind_check_reliability(struct unwind_state *state)
*/
if (!__kernel_text_address(state->pc))
state->reliable = false;
+
+ /*
+ * Check the return PC against sym_code_functions[]. If there is a
+ * match, then the consider the stack frame unreliable.
+ *
+ * As SYM_CODE functions don't follow the usual calling conventions,
+ * we assume by default that any SYM_CODE function cannot be unwound
+ * reliably.
+ *
+ * Note that this includes:
+ *
+ * - Exception handlers and entry assembly
+ * - Trampoline assembly (e.g., ftrace, kprobes)
+ * - Hypervisor-related assembly
+ * - Hibernation-related assembly
+ * - CPU start-stop, suspend-resume assembly
+ * - Kernel relocation assembly
+ */
+ pc = state->pc;
+ for (i = 0; i < num_sym_code_functions; i++) {
+ range = &sym_code_functions[i];
+ if (pc >= range->start && pc < range->end) {
+ state->reliable = false;
+ return;
+ }
+ }
}

/*
diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
index 50bab186c49b..6381e75e566e 100644
--- a/arch/arm64/kernel/vmlinux.lds.S
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -122,6 +122,14 @@ jiffies = jiffies_64;
#define TRAMP_TEXT
#endif

+#define SYM_CODE_FUNCTIONS \
+ . = ALIGN(16); \
+ .symcode : AT(ADDR(.symcode) - LOAD_OFFSET) { \
+ __sym_code_functions_start = .; \
+ KEEP(*(sym_code_functions)) \
+ __sym_code_functions_end = .; \
+ }
+
/*
* The size of the PE/COFF section that covers the kernel image, which
* runs from _stext to _edata, must be a round multiple of the PE/COFF
@@ -209,6 +217,8 @@ SECTIONS
swapper_pg_dir = .;
. += PAGE_SIZE;

+ SYM_CODE_FUNCTIONS
+
. = ALIGN(SEGMENT_ALIGN);
__init_begin = .;
__inittext_begin = .;
--
2.25.1

2022-02-02 18:58:32

by Mark Brown

[permalink] [raw]
Subject: Re: [PATCH v13 05/11] arm64: Copy the task argument to unwind_state

On Mon, Jan 17, 2022 at 08:56:02AM -0600, [email protected] wrote:
> From: "Madhavan T. Venkataraman" <[email protected]>
>
> Copy the task argument passed to arch_stack_walk() to unwind_state so that
> it can be passed to unwind functions via unwind_state rather than as a
> separate argument. The task is a fundamental part of the unwind state.

Reviewed-by: Mark Brown <[email protected]>


Attachments:
(No filename) (424.00 B)
signature.asc (499.00 B)
Download all attachments

2022-02-03 06:49:57

by Madhavan T. Venkataraman

[permalink] [raw]
Subject: Re: [PATCH v13 06/11] arm64: Use stack_trace_consume_fn and rename args to unwind()



On 2/2/22 12:46, Mark Brown wrote:
> On Mon, Jan 17, 2022 at 08:56:03AM -0600, [email protected] wrote:
>> From: "Madhavan T. Venkataraman" <[email protected]>
>>
>> Rename the arguments to unwind() for better consistency. Also, use the
>> typedef stack_trace_consume_fn for the consume_entry function as it is
>> already defined in linux/stacktrace.h.
>
> Consistency with...? But otherwise:

Naming consistency. E.g., the name consume_entry is used in a lot of places.
This code used to use fn() instead of consume_entry(). arch_stack_walk()
names the argument to consume_entry as cookie. This code calls it data
instead of cookie. That is all. It is minor in nature. But I thought I might
as well make it conform while I am at it.

Madhavan

2022-02-03 15:15:25

by Mark Brown

[permalink] [raw]
Subject: Re: [PATCH v13 06/11] arm64: Use stack_trace_consume_fn and rename args to unwind()

On Mon, Jan 17, 2022 at 08:56:03AM -0600, [email protected] wrote:
> From: "Madhavan T. Venkataraman" <[email protected]>
>
> Rename the arguments to unwind() for better consistency. Also, use the
> typedef stack_trace_consume_fn for the consume_entry function as it is
> already defined in linux/stacktrace.h.

Consistency with...? But otherwise:

Reviewed-by: Mark Brown <[email protected]>


Attachments:
(No filename) (428.00 B)
signature.asc (499.00 B)
Download all attachments

2022-02-07 14:18:16

by Madhavan T. Venkataraman

[permalink] [raw]
Subject: Re: [PATCH v13 06/11] arm64: Use stack_trace_consume_fn and rename args to unwind()



On 2/3/22 05:30, Mark Brown wrote:
> On Wed, Feb 02, 2022 at 06:34:43PM -0600, Madhavan T. Venkataraman wrote:
>> On 2/2/22 12:46, Mark Brown wrote:
>>> On Mon, Jan 17, 2022 at 08:56:03AM -0600, [email protected] wrote:
>
>>>> Rename the arguments to unwind() for better consistency. Also, use the
>>>> typedef stack_trace_consume_fn for the consume_entry function as it is
>>>> already defined in linux/stacktrace.h.
>
>>> Consistency with...? But otherwise:
>
>> Naming consistency. E.g., the name consume_entry is used in a lot of places.
>> This code used to use fn() instead of consume_entry(). arch_stack_walk()
>> names the argument to consume_entry as cookie. This code calls it data
>> instead of cookie. That is all. It is minor in nature. But I thought I might
>> as well make it conform while I am at it.
>
> The commit message should probably say some of that then.

OK. Will add that to the commit message in the next version.

Madhavan

2022-02-15 14:46:55

by Mark Rutland

[permalink] [raw]
Subject: Re: [PATCH v13 06/11] arm64: Use stack_trace_consume_fn and rename args to unwind()

On Mon, Jan 17, 2022 at 08:56:03AM -0600, [email protected] wrote:
> From: "Madhavan T. Venkataraman" <[email protected]>
>
> Rename the arguments to unwind() for better consistency. Also, use the
> typedef stack_trace_consume_fn for the consume_entry function as it is
> already defined in linux/stacktrace.h.
>
> Signed-off-by: Madhavan T. Venkataraman <[email protected]>

How about:

| arm64: align with common stracktrace naming
|
| For historical reasons, the naming of parameters and their types in the arm64
| stacktrace code differs from that used in generic code and other
| architectures, even though the types are equivalent.
|
| For consistency and clarity, use the generic names.

Either way:

Reviewed-by: Mark Rutland <[email protected]>

Mark.

> ---
> arch/arm64/kernel/stacktrace.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
> index 1b32e55735aa..f772dac78b11 100644
> --- a/arch/arm64/kernel/stacktrace.c
> +++ b/arch/arm64/kernel/stacktrace.c
> @@ -181,12 +181,12 @@ static int notrace unwind_next(struct unwind_state *state)
> NOKPROBE_SYMBOL(unwind_next);
>
> static void notrace unwind(struct unwind_state *state,
> - bool (*fn)(void *, unsigned long), void *data)
> + stack_trace_consume_fn consume_entry, void *cookie)
> {
> while (1) {
> int ret;
>
> - if (!fn(data, state->pc))
> + if (!consume_entry(cookie, state->pc))
> break;
> ret = unwind_next(state);
> if (ret < 0)
> --
> 2.25.1
>

2022-02-15 16:01:18

by Mark Rutland

[permalink] [raw]
Subject: Re: [PATCH v13 05/11] arm64: Copy the task argument to unwind_state

On Mon, Jan 17, 2022 at 08:56:02AM -0600, [email protected] wrote:
> From: "Madhavan T. Venkataraman" <[email protected]>
>
> Copy the task argument passed to arch_stack_walk() to unwind_state so that
> it can be passed to unwind functions via unwind_state rather than as a
> separate argument. The task is a fundamental part of the unwind state.
>
> Signed-off-by: Madhavan T. Venkataraman <[email protected]>
> ---
> arch/arm64/include/asm/stacktrace.h | 3 +++
> arch/arm64/kernel/stacktrace.c | 29 ++++++++++++++++-------------
> 2 files changed, 19 insertions(+), 13 deletions(-)
>
> diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h
> index 41ec360515f6..af423f5d7ad8 100644
> --- a/arch/arm64/include/asm/stacktrace.h
> +++ b/arch/arm64/include/asm/stacktrace.h
> @@ -51,6 +51,8 @@ struct stack_info {
> * @kr_cur: When KRETPROBES is selected, holds the kretprobe instance
> * associated with the most recently encountered replacement lr
> * value.
> + *
> + * @task: Pointer to the task structure.

Can we please say:

@task: The task being unwound.

> */
> struct unwind_state {
> unsigned long fp;
> @@ -61,6 +63,7 @@ struct unwind_state {
> #ifdef CONFIG_KRETPROBES
> struct llist_node *kr_cur;
> #endif
> + struct task_struct *task;
> };
>
> extern void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk,
> diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
> index b2b568e5deba..1b32e55735aa 100644
> --- a/arch/arm64/kernel/stacktrace.c
> +++ b/arch/arm64/kernel/stacktrace.c
> @@ -33,8 +33,10 @@
> */
>
>
> -static void unwind_init_common(struct unwind_state *state)
> +static void unwind_init_common(struct unwind_state *state,
> + struct task_struct *task)
> {
> + state->task = task;
> #ifdef CONFIG_KRETPROBES
> state->kr_cur = NULL;
> #endif
> @@ -57,9 +59,10 @@ static void unwind_init_common(struct unwind_state *state)
> * TODO: document requirements here.
> */
> static inline void unwind_init_from_regs(struct unwind_state *state,
> + struct task_struct *task,

Please drop the `task` parameter here ...

> struct pt_regs *regs)
> {
> - unwind_init_common(state);
> + unwind_init_common(state, task);

... and make this:

unwind_init_common(state, current);

... since that way it's *impossible* to have ismatched parameters, which is one
of the reasons for having separate functions in the first place.

> state->fp = regs->regs[29];
> state->pc = regs->pc;
> @@ -71,9 +74,10 @@ static inline void unwind_init_from_regs(struct unwind_state *state,
> * Note: this is always inlined, and we expect our caller to be a noinline
> * function, such that this starts from our caller's caller.
> */
> -static __always_inline void unwind_init_from_current(struct unwind_state *state)
> +static __always_inline void unwind_init_from_current(struct unwind_state *state,
> + struct task_struct *task)
> {
> - unwind_init_common(state);
> + unwind_init_common(state, task);

Same comments as for unwind_init_from_regs(): please drop the `task` parameter
and hard-code `current` in the call to unwind_init_common().

> state->fp = (unsigned long)__builtin_frame_address(1);
> state->pc = (unsigned long)__builtin_return_address(0);
> @@ -87,7 +91,7 @@ static __always_inline void unwind_init_from_current(struct unwind_state *state)
> static inline void unwind_init_from_task(struct unwind_state *state,
> struct task_struct *task)
> {
> - unwind_init_common(state);
> + unwind_init_common(state, task);
>
> state->fp = thread_saved_fp(task);
> state->pc = thread_saved_pc(task);
> @@ -100,11 +104,11 @@ static inline void unwind_init_from_task(struct unwind_state *state,
> * records (e.g. a cycle), determined based on the location and fp value of A
> * and the location (but not the fp value) of B.
> */
> -static int notrace unwind_next(struct task_struct *tsk,
> - struct unwind_state *state)
> +static int notrace unwind_next(struct unwind_state *state)
> {
> unsigned long fp = state->fp;
> struct stack_info info;
> + struct task_struct *tsk = state->task;
>
> /* Final frame; nothing to unwind */
> if (fp == (unsigned long)task_pt_regs(tsk)->stackframe)
> @@ -176,8 +180,7 @@ static int notrace unwind_next(struct task_struct *tsk,
> }
> NOKPROBE_SYMBOL(unwind_next);
>
> -static void notrace unwind(struct task_struct *tsk,
> - struct unwind_state *state,
> +static void notrace unwind(struct unwind_state *state,
> bool (*fn)(void *, unsigned long), void *data)
> {
> while (1) {
> @@ -185,7 +188,7 @@ static void notrace unwind(struct task_struct *tsk,
>
> if (!fn(data, state->pc))
> break;
> - ret = unwind_next(tsk, state);
> + ret = unwind_next(state);
> if (ret < 0)
> break;
> }
> @@ -232,11 +235,11 @@ noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry,
> struct unwind_state state;
>
> if (regs)
> - unwind_init_from_regs(&state, regs);
> + unwind_init_from_regs(&state, task, regs);
> else if (task == current)
> - unwind_init_from_current(&state);
> + unwind_init_from_current(&state, task);
> else
> unwind_init_from_task(&state, task);

As above we shouldn't need these two changes.

For the regs case we might want to sanity-check that task == current.

> - unwind(task, &state, consume_entry, cookie);
> + unwind(&state, consume_entry, cookie);

Otherwise, this looks good to me.

Thanks,
Mark.

2022-02-15 19:12:38

by Madhavan T. Venkataraman

[permalink] [raw]
Subject: Re: [PATCH v13 06/11] arm64: Use stack_trace_consume_fn and rename args to unwind()



On 2/15/22 07:39, Mark Rutland wrote:
> On Mon, Jan 17, 2022 at 08:56:03AM -0600, [email protected] wrote:
>> From: "Madhavan T. Venkataraman" <[email protected]>
>>
>> Rename the arguments to unwind() for better consistency. Also, use the
>> typedef stack_trace_consume_fn for the consume_entry function as it is
>> already defined in linux/stacktrace.h.
>>
>> Signed-off-by: Madhavan T. Venkataraman <[email protected]>
>
> How about:
>
> | arm64: align with common stracktrace naming
> |
> | For historical reasons, the naming of parameters and their types in the arm64
> | stacktrace code differs from that used in generic code and other
> | architectures, even though the types are equivalent.
> |
> | For consistency and clarity, use the generic names.
>

Will add this.

Madhavan

> Either way:
>
> Reviewed-by: Mark Rutland <[email protected]>
>
> Mark.
>
>> ---
>> arch/arm64/kernel/stacktrace.c | 4 ++--
>> 1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
>> index 1b32e55735aa..f772dac78b11 100644
>> --- a/arch/arm64/kernel/stacktrace.c
>> +++ b/arch/arm64/kernel/stacktrace.c
>> @@ -181,12 +181,12 @@ static int notrace unwind_next(struct unwind_state *state)
>> NOKPROBE_SYMBOL(unwind_next);
>>
>> static void notrace unwind(struct unwind_state *state,
>> - bool (*fn)(void *, unsigned long), void *data)
>> + stack_trace_consume_fn consume_entry, void *cookie)
>> {
>> while (1) {
>> int ret;
>>
>> - if (!fn(data, state->pc))
>> + if (!consume_entry(cookie, state->pc))
>> break;
>> ret = unwind_next(state);
>> if (ret < 0)
>> --
>> 2.25.1
>>

2022-02-23 02:30:55

by Madhavan T. Venkataraman

[permalink] [raw]
Subject: Re: [PATCH v13 05/11] arm64: Copy the task argument to unwind_state

It looks like I forgot to reply to this. Sorry about that.

On 2/15/22 07:22, Mark Rutland wrote:
> On Mon, Jan 17, 2022 at 08:56:02AM -0600, [email protected] wrote:
>> From: "Madhavan T. Venkataraman" <[email protected]>
>>
>> Copy the task argument passed to arch_stack_walk() to unwind_state so that
>> it can be passed to unwind functions via unwind_state rather than as a
>> separate argument. The task is a fundamental part of the unwind state.
>>
>> Signed-off-by: Madhavan T. Venkataraman <[email protected]>
>> ---
>> arch/arm64/include/asm/stacktrace.h | 3 +++
>> arch/arm64/kernel/stacktrace.c | 29 ++++++++++++++++-------------
>> 2 files changed, 19 insertions(+), 13 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h
>> index 41ec360515f6..af423f5d7ad8 100644
>> --- a/arch/arm64/include/asm/stacktrace.h
>> +++ b/arch/arm64/include/asm/stacktrace.h
>> @@ -51,6 +51,8 @@ struct stack_info {
>> * @kr_cur: When KRETPROBES is selected, holds the kretprobe instance
>> * associated with the most recently encountered replacement lr
>> * value.
>> + *
>> + * @task: Pointer to the task structure.
>
> Can we please say:
>
> @task: The task being unwound.
>

Will do.

>> */
>> struct unwind_state {
>> unsigned long fp;
>> @@ -61,6 +63,7 @@ struct unwind_state {
>> #ifdef CONFIG_KRETPROBES
>> struct llist_node *kr_cur;
>> #endif
>> + struct task_struct *task;
>> };
>>
>> extern void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk,
>> diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
>> index b2b568e5deba..1b32e55735aa 100644
>> --- a/arch/arm64/kernel/stacktrace.c
>> +++ b/arch/arm64/kernel/stacktrace.c
>> @@ -33,8 +33,10 @@
>> */
>>
>>
>> -static void unwind_init_common(struct unwind_state *state)
>> +static void unwind_init_common(struct unwind_state *state,
>> + struct task_struct *task)
>> {
>> + state->task = task;
>> #ifdef CONFIG_KRETPROBES
>> state->kr_cur = NULL;
>> #endif
>> @@ -57,9 +59,10 @@ static void unwind_init_common(struct unwind_state *state)
>> * TODO: document requirements here.
>> */
>> static inline void unwind_init_from_regs(struct unwind_state *state,
>> + struct task_struct *task,
>
> Please drop the `task` parameter here ...

OK.

>
>> struct pt_regs *regs)
>> {
>> - unwind_init_common(state);
>> + unwind_init_common(state, task);
>
> ... and make this:
>
> unwind_init_common(state, current);

OK.

>
> ... since that way it's *impossible* to have ismatched parameters, which is one
> of the reasons for having separate functions in the first place.
>
>> state->fp = regs->regs[29];
>> state->pc = regs->pc;
>> @@ -71,9 +74,10 @@ static inline void unwind_init_from_regs(struct unwind_state *state,
>> * Note: this is always inlined, and we expect our caller to be a noinline
>> * function, such that this starts from our caller's caller.
>> */
>> -static __always_inline void unwind_init_from_current(struct unwind_state *state)
>> +static __always_inline void unwind_init_from_current(struct unwind_state *state,
>> + struct task_struct *task)
>> {
>> - unwind_init_common(state);
>> + unwind_init_common(state, task);
>
> Same comments as for unwind_init_from_regs(): please drop the `task` parameter
> and hard-code `current` in the call to unwind_init_common().
>

OK.

>> state->fp = (unsigned long)__builtin_frame_address(1);
>> state->pc = (unsigned long)__builtin_return_address(0);
>> @@ -87,7 +91,7 @@ static __always_inline void unwind_init_from_current(struct unwind_state *state)
>> static inline void unwind_init_from_task(struct unwind_state *state,
>> struct task_struct *task)
>> {
>> - unwind_init_common(state);
>> + unwind_init_common(state, task);
>>
>> state->fp = thread_saved_fp(task);
>> state->pc = thread_saved_pc(task);
>> @@ -100,11 +104,11 @@ static inline void unwind_init_from_task(struct unwind_state *state,
>> * records (e.g. a cycle), determined based on the location and fp value of A
>> * and the location (but not the fp value) of B.
>> */
>> -static int notrace unwind_next(struct task_struct *tsk,
>> - struct unwind_state *state)
>> +static int notrace unwind_next(struct unwind_state *state)
>> {
>> unsigned long fp = state->fp;
>> struct stack_info info;
>> + struct task_struct *tsk = state->task;
>>
>> /* Final frame; nothing to unwind */
>> if (fp == (unsigned long)task_pt_regs(tsk)->stackframe)
>> @@ -176,8 +180,7 @@ static int notrace unwind_next(struct task_struct *tsk,
>> }
>> NOKPROBE_SYMBOL(unwind_next);
>>
>> -static void notrace unwind(struct task_struct *tsk,
>> - struct unwind_state *state,
>> +static void notrace unwind(struct unwind_state *state,
>> bool (*fn)(void *, unsigned long), void *data)
>> {
>> while (1) {
>> @@ -185,7 +188,7 @@ static void notrace unwind(struct task_struct *tsk,
>>
>> if (!fn(data, state->pc))
>> break;
>> - ret = unwind_next(tsk, state);
>> + ret = unwind_next(state);
>> if (ret < 0)
>> break;
>> }
>> @@ -232,11 +235,11 @@ noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry,
>> struct unwind_state state;
>>
>> if (regs)
>> - unwind_init_from_regs(&state, regs);
>> + unwind_init_from_regs(&state, task, regs);
>> else if (task == current)
>> - unwind_init_from_current(&state);
>> + unwind_init_from_current(&state, task);
>> else
>> unwind_init_from_task(&state, task);
>
> As above we shouldn't need these two changes.
>
> For the regs case we might want to sanity-check that task == current.
>

Will do.

>> - unwind(task, &state, consume_entry, cookie);
>> + unwind(&state, consume_entry, cookie);
>
> Otherwise, this looks good to me.

Thanks.

Madhavan

2022-03-08 22:09:18

by Madhavan T. Venkataraman

[permalink] [raw]
Subject: Re: [PATCH v13 06/11] arm64: Use stack_trace_consume_fn and rename args to unwind()

Hey Mark Rutland, Mark Brown,

Could you please review the rest of the patches in the series when you can?

Also, many of the patches have received a Reviewed-By from you both. So, after I send the next version out, can we upstream those ones?

Thanks.

Madhavan

On 2/15/22 07:39, Mark Rutland wrote:
> On Mon, Jan 17, 2022 at 08:56:03AM -0600, [email protected] wrote:
>> From: "Madhavan T. Venkataraman" <[email protected]>
>>
>> Rename the arguments to unwind() for better consistency. Also, use the
>> typedef stack_trace_consume_fn for the consume_entry function as it is
>> already defined in linux/stacktrace.h.
>>
>> Signed-off-by: Madhavan T. Venkataraman <[email protected]>
>
> How about:
>
> | arm64: align with common stracktrace naming
> |
> | For historical reasons, the naming of parameters and their types in the arm64
> | stacktrace code differs from that used in generic code and other
> | architectures, even though the types are equivalent.
> |
> | For consistency and clarity, use the generic names.
>
> Either way:
>
> Reviewed-by: Mark Rutland <[email protected]>
>
> Mark.
>
>> ---
>> arch/arm64/kernel/stacktrace.c | 4 ++--
>> 1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
>> index 1b32e55735aa..f772dac78b11 100644
>> --- a/arch/arm64/kernel/stacktrace.c
>> +++ b/arch/arm64/kernel/stacktrace.c
>> @@ -181,12 +181,12 @@ static int notrace unwind_next(struct unwind_state *state)
>> NOKPROBE_SYMBOL(unwind_next);
>>
>> static void notrace unwind(struct unwind_state *state,
>> - bool (*fn)(void *, unsigned long), void *data)
>> + stack_trace_consume_fn consume_entry, void *cookie)
>> {
>> while (1) {
>> int ret;
>>
>> - if (!fn(data, state->pc))
>> + if (!consume_entry(cookie, state->pc))
>> break;
>> ret = unwind_next(state);
>> if (ret < 0)
>> --
>> 2.25.1
>>

2022-03-09 01:18:20

by Madhavan T. Venkataraman

[permalink] [raw]
Subject: Re: [PATCH v13 06/11] arm64: Use stack_trace_consume_fn and rename args to unwind()



On 3/7/22 11:01, Mark Brown wrote:
> On Mon, Mar 07, 2022 at 10:51:38AM -0600, Madhavan T. Venkataraman wrote:
>> Hey Mark Rutland, Mark Brown,
>>
>> Could you please review the rest of the patches in the series when you can?
>>
>
> Please don't send content free pings. As far as I remember I'd reviewed
> or was expecting changes based on review or dependent patches for
> everything that you'd sent.
>

Indeed you did! Many thanks!

It is just that patch 11 that defines "select HAVE_RELIABLE_STACKTRACE" did not receive any comments from you (unless I missed a comment that came from you. That is entirely possible. If I missed it, my bad). Since you suggested that change, I just wanted to make sure that that patch looks OK to you.

>> Also, many of the patches have received a Reviewed-By from you both. So, after I send the next version out, can we upstream those ones?
>
> That's more a question for Catalin and Will. If myself and Mark have
> reviewed patches then we're saying we think those patches are good to
> go.

Got it!

Thanks!

Madhavan

2022-03-09 01:32:26

by Mark Brown

[permalink] [raw]
Subject: Re: [PATCH v13 06/11] arm64: Use stack_trace_consume_fn and rename args to unwind()

On Mon, Mar 07, 2022 at 10:51:38AM -0600, Madhavan T. Venkataraman wrote:
> Hey Mark Rutland, Mark Brown,
>
> Could you please review the rest of the patches in the series when you can?
>

Please don't send content free pings. As far as I remember I'd reviewed
or was expecting changes based on review or dependent patches for
everything that you'd sent.

> Also, many of the patches have received a Reviewed-By from you both. So, after I send the next version out, can we upstream those ones?

That's more a question for Catalin and Will. If myself and Mark have
reviewed patches then we're saying we think those patches are good to
go.


Attachments:
(No filename) (657.00 B)
signature.asc (499.00 B)
Download all attachments

2022-03-09 16:11:23

by Mark Brown

[permalink] [raw]
Subject: Re: [PATCH v13 06/11] arm64: Use stack_trace_consume_fn and rename args to unwind()

On Tue, Mar 08, 2022 at 04:00:35PM -0600, Madhavan T. Venkataraman wrote:

> It is just that patch 11 that defines "select
> HAVE_RELIABLE_STACKTRACE" did not receive any comments from you
> (unless I missed a comment that came from you. That is entirely
> possible. If I missed it, my bad). Since you suggested that change, I
> just wanted to make sure that that patch looks OK to you.

I think that's more a question for the livepatch people to be honest -
it's not entirely a technical one, there's a bunch of confidence level
stuff going on. For example there was some suggestion that people might
insist on having objtool support, though there's also substantial
pushback on making objtool a requirement for anything from other
quarters. I was hoping that posting that patch would provoke some
discussion about what exactly is needed but that's not happened thus
far.


Attachments:
(No filename) (891.00 B)
signature.asc (499.00 B)
Download all attachments

2022-03-09 16:22:18

by Madhavan T. Venkataraman

[permalink] [raw]
Subject: Re: [PATCH v13 06/11] arm64: Use stack_trace_consume_fn and rename args to unwind()



On 3/9/22 05:47, Mark Brown wrote:
> On Tue, Mar 08, 2022 at 04:00:35PM -0600, Madhavan T. Venkataraman wrote:
>
>> It is just that patch 11 that defines "select
>> HAVE_RELIABLE_STACKTRACE" did not receive any comments from you
>> (unless I missed a comment that came from you. That is entirely
>> possible. If I missed it, my bad). Since you suggested that change, I
>> just wanted to make sure that that patch looks OK to you.
>
> I think that's more a question for the livepatch people to be honest -
> it's not entirely a technical one, there's a bunch of confidence level
> stuff going on. For example there was some suggestion that people might
> insist on having objtool support, though there's also substantial
> pushback on making objtool a requirement for anything from other
> quarters. I was hoping that posting that patch would provoke some
> discussion about what exactly is needed but that's not happened thus
> far.

Understood. In that case, I will remove that patch because it is not really required for my current work on the unwinder. I will bring this up later in a different patch series where it will trigger a discussion.

Thanks.

Madhavan

2022-03-10 14:20:37

by Madhavan T. Venkataraman

[permalink] [raw]
Subject: Re: [PATCH v13 06/11] arm64: Use stack_trace_consume_fn and rename args to unwind()



On 3/10/22 02:33, Miroslav Benes wrote:
> On Wed, 9 Mar 2022, Mark Brown wrote:
>
>> On Tue, Mar 08, 2022 at 04:00:35PM -0600, Madhavan T. Venkataraman wrote:
>>
>>> It is just that patch 11 that defines "select
>>> HAVE_RELIABLE_STACKTRACE" did not receive any comments from you
>>> (unless I missed a comment that came from you. That is entirely
>>> possible. If I missed it, my bad). Since you suggested that change, I
>>> just wanted to make sure that that patch looks OK to you.
>>
>> I think that's more a question for the livepatch people to be honest -
>> it's not entirely a technical one, there's a bunch of confidence level
>> stuff going on. For example there was some suggestion that people might
>> insist on having objtool support, though there's also substantial
>> pushback on making objtool a requirement for anything from other
>> quarters. I was hoping that posting that patch would provoke some
>> discussion about what exactly is needed but that's not happened thus
>> far.
>
> I think everyone will be happy with HAVE_RELIABLE_STACKTRACE on arm64 as
> long as there is a guarantee that stack traces are really reliable. My
> understanding is that there is still some work to be done on arm64 arch
> side (but I may have misunderstood what Mark R. said elsewhere). And yes,
> then there is a question of objtool. It is one option but not the only
> one. There have been proposals of implementing guarantees on a compiler
> side and leaving objtool for x86_64 only (albeit objtool may bring more
> features to the table... ORC, arch features checking).
>
> Madhavan also mentioned that he enhanced objtool and he planned to submit
> it eventually
> (https://lore.kernel.org/all/[email protected]/T/#u),
> so maybe arm64 maintainers could decide on a future direction based on
> that?
>

Yes. I am working on that right now. Hope to send it out soon.

Madhavan

2022-03-11 07:23:41

by Miroslav Benes

[permalink] [raw]
Subject: Re: [PATCH v13 06/11] arm64: Use stack_trace_consume_fn and rename args to unwind()

On Wed, 9 Mar 2022, Mark Brown wrote:

> On Tue, Mar 08, 2022 at 04:00:35PM -0600, Madhavan T. Venkataraman wrote:
>
> > It is just that patch 11 that defines "select
> > HAVE_RELIABLE_STACKTRACE" did not receive any comments from you
> > (unless I missed a comment that came from you. That is entirely
> > possible. If I missed it, my bad). Since you suggested that change, I
> > just wanted to make sure that that patch looks OK to you.
>
> I think that's more a question for the livepatch people to be honest -
> it's not entirely a technical one, there's a bunch of confidence level
> stuff going on. For example there was some suggestion that people might
> insist on having objtool support, though there's also substantial
> pushback on making objtool a requirement for anything from other
> quarters. I was hoping that posting that patch would provoke some
> discussion about what exactly is needed but that's not happened thus
> far.

I think everyone will be happy with HAVE_RELIABLE_STACKTRACE on arm64 as
long as there is a guarantee that stack traces are really reliable. My
understanding is that there is still some work to be done on arm64 arch
side (but I may have misunderstood what Mark R. said elsewhere). And yes,
then there is a question of objtool. It is one option but not the only
one. There have been proposals of implementing guarantees on a compiler
side and leaving objtool for x86_64 only (albeit objtool may bring more
features to the table... ORC, arch features checking).

Madhavan also mentioned that he enhanced objtool and he planned to submit
it eventually
(https://lore.kernel.org/all/[email protected]/T/#u),
so maybe arm64 maintainers could decide on a future direction based on
that?

Regards
Miroslav

2022-03-17 04:44:27

by Josh Poimboeuf

[permalink] [raw]
Subject: Re: [PATCH v13 06/11] arm64: Use stack_trace_consume_fn and rename args to unwind()

On Wed, Mar 09, 2022 at 11:47:38AM +0000, Mark Brown wrote:
> On Tue, Mar 08, 2022 at 04:00:35PM -0600, Madhavan T. Venkataraman wrote:
>
> > It is just that patch 11 that defines "select
> > HAVE_RELIABLE_STACKTRACE" did not receive any comments from you
> > (unless I missed a comment that came from you. That is entirely
> > possible. If I missed it, my bad). Since you suggested that change, I
> > just wanted to make sure that that patch looks OK to you.
>
> I think that's more a question for the livepatch people to be honest -
> it's not entirely a technical one, there's a bunch of confidence level
> stuff going on. For example there was some suggestion that people might
> insist on having objtool support, though there's also substantial
> pushback on making objtool a requirement for anything from other
> quarters. I was hoping that posting that patch would provoke some
> discussion about what exactly is needed but that's not happened thus
> far.

That patch has HAVE_RELIABLE_STACKTRACE depending on STACK_VALIDATION,
which doesn't exist on arm64.

So it didn't seem controversial enough to warrant discussion ;-)

--
Josh

2022-04-08 19:55:12

by Mark Rutland

[permalink] [raw]
Subject: Re: [PATCH v13 06/11] arm64: Use stack_trace_consume_fn and rename args to unwind()

On Mon, Mar 07, 2022 at 10:51:38AM -0600, Madhavan T. Venkataraman wrote:
> Hey Mark Rutland, Mark Brown,
>
> Could you please review the rest of the patches in the series when you can?

Sorry, I was expecting a new version with some of my comments
addressed, in case that had effects on subsequent patches.

> Also, many of the patches have received a Reviewed-By from you both.
> So, after I send the next version out, can we upstream those ones?

I would very much like to upstream the ones I have given a Reviewed-by.

Given those were conditional on some adjustments (e.g. actually filling
out comments), do you mind if I pick those into a series now?

Then, once that's picked, you can rebase the rest atop, and we can
review that.

Thanks,
Mark.

> On 2/15/22 07:39, Mark Rutland wrote:
> > On Mon, Jan 17, 2022 at 08:56:03AM -0600, [email protected] wrote:
> >> From: "Madhavan T. Venkataraman" <[email protected]>
> >>
> >> Rename the arguments to unwind() for better consistency. Also, use the
> >> typedef stack_trace_consume_fn for the consume_entry function as it is
> >> already defined in linux/stacktrace.h.
> >>
> >> Signed-off-by: Madhavan T. Venkataraman <[email protected]>
> >
> > How about:
> >
> > | arm64: align with common stracktrace naming
> > |
> > | For historical reasons, the naming of parameters and their types in the arm64
> > | stacktrace code differs from that used in generic code and other
> > | architectures, even though the types are equivalent.
> > |
> > | For consistency and clarity, use the generic names.
> >
> > Either way:
> >
> > Reviewed-by: Mark Rutland <[email protected]>
> >
> > Mark.
> >
> >> ---
> >> arch/arm64/kernel/stacktrace.c | 4 ++--
> >> 1 file changed, 2 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
> >> index 1b32e55735aa..f772dac78b11 100644
> >> --- a/arch/arm64/kernel/stacktrace.c
> >> +++ b/arch/arm64/kernel/stacktrace.c
> >> @@ -181,12 +181,12 @@ static int notrace unwind_next(struct unwind_state *state)
> >> NOKPROBE_SYMBOL(unwind_next);
> >>
> >> static void notrace unwind(struct unwind_state *state,
> >> - bool (*fn)(void *, unsigned long), void *data)
> >> + stack_trace_consume_fn consume_entry, void *cookie)
> >> {
> >> while (1) {
> >> int ret;
> >>
> >> - if (!fn(data, state->pc))
> >> + if (!consume_entry(cookie, state->pc))
> >> break;
> >> ret = unwind_next(state);
> >> if (ret < 0)
> >> --
> >> 2.25.1
> >>

2022-04-10 10:53:01

by Mark Rutland

[permalink] [raw]
Subject: Re: [PATCH v13 06/11] arm64: Use stack_trace_consume_fn and rename args to unwind()

On Fri, Apr 08, 2022 at 03:44:34PM +0100, Mark Rutland wrote:
> On Mon, Mar 07, 2022 at 10:51:38AM -0600, Madhavan T. Venkataraman wrote:
> > Hey Mark Rutland, Mark Brown,
> >
> > Could you please review the rest of the patches in the series when you can?
>
> Sorry, I was expecting a new version with some of my comments
> addressed, in case that had effects on subsequent patches.
>
> > Also, many of the patches have received a Reviewed-By from you both.
> > So, after I send the next version out, can we upstream those ones?
>
> I would very much like to upstream the ones I have given a Reviewed-by.
>
> Given those were conditional on some adjustments (e.g. actually filling
> out comments), do you mind if I pick those into a series now?

FWIW, I've picked up the set I'm trivially happy with, rebased that on
v5.18-rc1, and put that on a branch with a couple of other cleanups:

https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=arm64/stacktrace/cleanups

I'll send that out on Monday if there are no objections.

Thanks,
Mark.

2022-04-11 07:58:36

by Madhavan T. Venkataraman

[permalink] [raw]
Subject: Re: [PATCH v13 06/11] arm64: Use stack_trace_consume_fn and rename args to unwind()



On 4/8/22 12:58, Mark Rutland wrote:
> On Fri, Apr 08, 2022 at 03:44:34PM +0100, Mark Rutland wrote:
>> On Mon, Mar 07, 2022 at 10:51:38AM -0600, Madhavan T. Venkataraman wrote:
>>> Hey Mark Rutland, Mark Brown,
>>>
>>> Could you please review the rest of the patches in the series when you can?
>>
>> Sorry, I was expecting a new version with some of my comments
>> addressed, in case that had effects on subsequent patches.
>>
>>> Also, many of the patches have received a Reviewed-By from you both.
>>> So, after I send the next version out, can we upstream those ones?
>>
>> I would very much like to upstream the ones I have given a Reviewed-by.
>>
>> Given those were conditional on some adjustments (e.g. actually filling
>> out comments), do you mind if I pick those into a series now?
>
> FWIW, I've picked up the set I'm trivially happy with, rebased that on
> v5.18-rc1, and put that on a branch with a couple of other cleanups:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=arm64/stacktrace/cleanups
>
> I'll send that out on Monday if there are no objections.
>
> Thanks,
> Mark.

LGTM.

Madhavan

2022-04-11 14:34:51

by Madhavan T. Venkataraman

[permalink] [raw]
Subject: Re: [PATCH v13 06/11] arm64: Use stack_trace_consume_fn and rename args to unwind()



On 4/8/22 09:44, Mark Rutland wrote:
> On Mon, Mar 07, 2022 at 10:51:38AM -0600, Madhavan T. Venkataraman wrote:
>> Hey Mark Rutland, Mark Brown,
>>
>> Could you please review the rest of the patches in the series when you can?
>
> Sorry, I was expecting a new version with some of my comments
> addressed, in case that had effects on subsequent patches.
>

Yes. I realized that. I am actually working on the next version addressing the
comments I have received.

>> Also, many of the patches have received a Reviewed-By from you both.
>> So, after I send the next version out, can we upstream those ones?
>
> I would very much like to upstream the ones I have given a Reviewed-by.
>
> Given those were conditional on some adjustments (e.g. actually filling
> out comments), do you mind if I pick those into a series now?
>
> Then, once that's picked, you can rebase the rest atop, and we can
> review that.
>

That would be great! Thanks!

Madhavan

2022-04-11 16:08:40

by Madhavan T. Venkataraman

[permalink] [raw]
Subject: Re: [PATCH v13 06/11] arm64: Use stack_trace_consume_fn and rename args to unwind()



On 4/8/22 09:44, Mark Rutland wrote:
> On Mon, Mar 07, 2022 at 10:51:38AM -0600, Madhavan T. Venkataraman wrote:
>> Hey Mark Rutland, Mark Brown,
>>
>> Could you please review the rest of the patches in the series when you can?
>
> Sorry, I was expecting a new version with some of my comments
> addressed, in case that had effects on subsequent patches.
>
>> Also, many of the patches have received a Reviewed-By from you both.
>> So, after I send the next version out, can we upstream those ones?
>
> I would very much like to upstream the ones I have given a Reviewed-by.
>
> Given those were conditional on some adjustments (e.g. actually filling
> out comments), do you mind if I pick those into a series now?
>
> Then, once that's picked, you can rebase the rest atop, and we can
> review that.
>

So, do you want me to address the comments so far and send the next version?
I can do it ASAP.

Madhavan