[PATCH 6/8] arm64: stacktrace: remove stack type from fp translator
Kalesh Singh
kaleshsingh at google.com
Mon Aug 1 22:32:01 PDT 2022
On Mon, Aug 1, 2022 at 5:12 AM Mark Rutland <mark.rutland at arm.com> wrote:
>
> In subsequent patches we'll remove the stack_type enum, and move the FP
> translation logic out of the raw FP unwind code.
>
> In preparation for doing so, this patch removes the type parameter from
> the FP translation callback, and modifies kvm_nvhe_stack_kern_va() to
> determine the relevant stack directly.
>
> So that kvm_nvhe_stack_kern_va() can use the stackinfo_*() helpers,
> these are moved earlier in the file, but are not modified in any way.
>
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> Cc: Fuad Tabba <tabba at google.com>
> Cc: Kalesh Singh <kaleshsingh at google.com>
> Cc: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
> Cc: Marc Zyngier <maz at kernel.org>
> Cc: Mark Brown <broonie at kernel.org>
Reviewed-by: Kalesh Singh <kaleshsingh at google.com>
> ---
> arch/arm64/include/asm/stacktrace/common.h | 6 +-
> arch/arm64/kvm/stacktrace.c | 78 ++++++++++++----------
> 2 files changed, 43 insertions(+), 41 deletions(-)
>
> diff --git a/arch/arm64/include/asm/stacktrace/common.h b/arch/arm64/include/asm/stacktrace/common.h
> index 0071f2459c703..0bd9d7ad295e0 100644
> --- a/arch/arm64/include/asm/stacktrace/common.h
> +++ b/arch/arm64/include/asm/stacktrace/common.h
> @@ -114,13 +114,11 @@ static inline void unwind_init_common(struct unwind_state *state,
> * a kernel address.
> *
> * @fp: the frame pointer to be updated to its kernel address.
> - * @type: the stack type associated with frame pointer @fp
> *
> * Returns true and success and @fp is updated to the corresponding
> * kernel virtual address; otherwise returns false.
> */
> -typedef bool (*stack_trace_translate_fp_fn)(unsigned long *fp,
> - enum stack_type type);
> +typedef bool (*stack_trace_translate_fp_fn)(unsigned long *fp);
>
> /*
> * on_accessible_stack_fn() - Check whether a stack range is on any
> @@ -165,7 +163,7 @@ unwind_next_frame_record(struct unwind_state *state,
> * If fp is not from the current address space perform the necessary
> * translation before dereferencing it to get the next fp.
> */
> - if (translate_fp && !translate_fp(&kern_fp, info.type))
> + if (translate_fp && !translate_fp(&kern_fp))
> return -EINVAL;
>
> /*
> diff --git a/arch/arm64/kvm/stacktrace.c b/arch/arm64/kvm/stacktrace.c
> index 3b005530ac02a..62ffa2b40da10 100644
> --- a/arch/arm64/kvm/stacktrace.c
> +++ b/arch/arm64/kvm/stacktrace.c
> @@ -21,6 +21,34 @@
>
> #include <asm/stacktrace/nvhe.h>
>
> +static struct stack_info stackinfo_get_overflow(void)
> +{
> + struct kvm_nvhe_stacktrace_info *stacktrace_info
> + = this_cpu_ptr_nvhe_sym(kvm_stacktrace_info);
> + unsigned long low = (unsigned long)stacktrace_info->overflow_stack_base;
> + unsigned long high = low + OVERFLOW_STACK_SIZE;
> +
> + return (struct stack_info) {
> + .low = low,
> + .high = high,
> + .type = STACK_TYPE_OVERFLOW,
> + };
> +}
> +
> +static struct stack_info stackinfo_get_hyp(void)
> +{
> + struct kvm_nvhe_stacktrace_info *stacktrace_info
> + = this_cpu_ptr_nvhe_sym(kvm_stacktrace_info);
> + unsigned long low = (unsigned long)stacktrace_info->stack_base;
> + unsigned long high = low + PAGE_SIZE;
> +
> + return (struct stack_info) {
> + .low = low,
> + .high = high,
> + .type = STACK_TYPE_HYP,
> + };
> +}
> +
> /*
> * kvm_nvhe_stack_kern_va - Convert KVM nVHE HYP stack addresses to a kernel VAs
> *
> @@ -34,27 +62,31 @@
> * Returns true on success and updates @addr to its corresponding kernel VA;
> * otherwise returns false.
> */
> -static bool kvm_nvhe_stack_kern_va(unsigned long *addr,
> - enum stack_type type)
> +static bool kvm_nvhe_stack_kern_va(unsigned long *addr)
> {
> struct kvm_nvhe_stacktrace_info *stacktrace_info;
> unsigned long hyp_base, kern_base, hyp_offset;
> + struct stack_info stack;
>
> stacktrace_info = this_cpu_ptr_nvhe_sym(kvm_stacktrace_info);
>
> - switch (type) {
> - case STACK_TYPE_HYP:
> + stack = stackinfo_get_hyp();
> + if (stackinfo_on_stack(&stack, *addr, 1)) {
> kern_base = (unsigned long)*this_cpu_ptr(&kvm_arm_hyp_stack_page);
> hyp_base = (unsigned long)stacktrace_info->stack_base;
> - break;
> - case STACK_TYPE_OVERFLOW:
> + goto found;
> + }
> +
> + stack = stackinfo_get_overflow();
> + if (stackinfo_on_stack(&stack, *addr, 1)) {
> kern_base = (unsigned long)this_cpu_ptr_nvhe_sym(overflow_stack);
> hyp_base = (unsigned long)stacktrace_info->overflow_stack_base;
> - break;
> - default:
> - return false;
> + goto found;
> }
>
> + return false;
> +
> +found:
> hyp_offset = *addr - hyp_base;
>
> *addr = kern_base + hyp_offset;
> @@ -62,34 +94,6 @@ static bool kvm_nvhe_stack_kern_va(unsigned long *addr,
> return true;
> }
>
> -static struct stack_info stackinfo_get_overflow(void)
> -{
> - struct kvm_nvhe_stacktrace_info *stacktrace_info
> - = this_cpu_ptr_nvhe_sym(kvm_stacktrace_info);
> - unsigned long low = (unsigned long)stacktrace_info->overflow_stack_base;
> - unsigned long high = low + OVERFLOW_STACK_SIZE;
> -
> - return (struct stack_info) {
> - .low = low,
> - .high = high,
> - .type = STACK_TYPE_OVERFLOW,
> - };
> -}
> -
> -static struct stack_info stackinfo_get_hyp(void)
> -{
> - struct kvm_nvhe_stacktrace_info *stacktrace_info
> - = this_cpu_ptr_nvhe_sym(kvm_stacktrace_info);
> - unsigned long low = (unsigned long)stacktrace_info->stack_base;
> - unsigned long high = low + PAGE_SIZE;
> -
> - return (struct stack_info) {
> - .low = low,
> - .high = high,
> - .type = STACK_TYPE_HYP,
> - };
> -}
> -
> static bool on_accessible_stack(const struct task_struct *tsk,
> unsigned long sp, unsigned long size,
> struct stack_info *info)
> --
> 2.30.2
>
More information about the linux-arm-kernel
mailing list