[PATCH 10/10] arm64: stacktrace: unwind exception boundaries
Miroslav Benes
mbenes at suse.cz
Fri Oct 11 08:16:23 PDT 2024
Hi,
> +static __always_inline int
> +kunwind_next_frame_record(struct kunwind_state *state)
> +{
> + unsigned long fp = state->common.fp;
> + struct frame_record *record;
> + struct stack_info *info;
> + unsigned long new_fp, new_pc;
> +
> + if (fp & 0x7)
> + return -EINVAL;
> +
> + info = unwind_find_stack(&state->common, fp, sizeof(*record));
> + if (!info)
> + return -EINVAL;
> +
> + record = (struct frame_record *)fp;
> + new_fp = READ_ONCE(record->fp);
> + new_pc = READ_ONCE(record->lr);
> +
> + if (!new_fp && !new_pc)
> + return kunwind_next_frame_record_meta(state);
> +
> + unwind_consume_stack(&state->common, info, fp, sizeof(*record));
> +
> + state->common.fp = new_fp;
> + state->common.pc = new_pc;
> + state->source = KUNWIND_SOURCE_FRAME;
> +
> + return 0;
> +}
> +
> /*
> * Unwind from one frame record (A) to the next frame record (B).
> *
> @@ -165,30 +266,27 @@ kunwind_recover_return_address(struct kunwind_state *state)
> static __always_inline int
> kunwind_next(struct kunwind_state *state)
> {
> - struct task_struct *tsk = state->task;
> - unsigned long fp = state->common.fp;
> int err;
>
> state->flags.all = 0;
>
> - /* Final frame; nothing to unwind */
> - if (fp == (unsigned long)&task_pt_regs(tsk)->stackframe)
> - return -ENOENT;
> -
> switch (state->source) {
> case KUNWIND_SOURCE_FRAME:
> case KUNWIND_SOURCE_CALLER:
> case KUNWIND_SOURCE_TASK:
> + case KUNWIND_SOURCE_REGS_LR:
> + err = kunwind_next_frame_record(state);
> + break;
> case KUNWIND_SOURCE_REGS_PC:
> - err = unwind_next_frame_record(&state->common);
> - if (err)
> - return err;
> - state->source = KUNWIND_SOURCE_FRAME;
> + err = kunwind_next_regs_lr(state);
the remaining users of unwind_next_frame_record() after this change are in
KVM. How does it work there? What is the difference?
Miroslav
More information about the linux-arm-kernel
mailing list