linux/arch/s390/kernel/unwind_bc.c
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2#include <linux/sched.h>
   3#include <linux/sched/task.h>
   4#include <linux/sched/task_stack.h>
   5#include <linux/interrupt.h>
   6#include <asm/sections.h>
   7#include <asm/ptrace.h>
   8#include <asm/bitops.h>
   9#include <asm/stacktrace.h>
  10#include <asm/unwind.h>
  11
  12unsigned long unwind_get_return_address(struct unwind_state *state)
  13{
  14        if (unwind_done(state))
  15                return 0;
  16        return __kernel_text_address(state->ip) ? state->ip : 0;
  17}
  18EXPORT_SYMBOL_GPL(unwind_get_return_address);
  19
  20static bool outside_of_stack(struct unwind_state *state, unsigned long sp)
  21{
  22        return (sp <= state->sp) ||
  23                (sp > state->stack_info.end - sizeof(struct stack_frame));
  24}
  25
  26static bool update_stack_info(struct unwind_state *state, unsigned long sp)
  27{
  28        struct stack_info *info = &state->stack_info;
  29        unsigned long *mask = &state->stack_mask;
  30
  31        /* New stack pointer leaves the current stack */
  32        if (get_stack_info(sp, state->task, info, mask) != 0 ||
  33            !on_stack(info, sp, sizeof(struct stack_frame)))
  34                /* 'sp' does not point to a valid stack */
  35                return false;
  36        return true;
  37}
  38
  39static inline bool is_final_pt_regs(struct unwind_state *state,
  40                                    struct pt_regs *regs)
  41{
  42        /* user mode or kernel thread pt_regs at the bottom of task stack */
  43        if (task_pt_regs(state->task) == regs)
  44                return true;
  45
  46        /* user mode pt_regs at the bottom of irq stack */
  47        return state->stack_info.type == STACK_TYPE_IRQ &&
  48               state->stack_info.end - sizeof(struct pt_regs) == (unsigned long)regs &&
  49               READ_ONCE_NOCHECK(regs->psw.mask) & PSW_MASK_PSTATE;
  50}
  51
  52bool unwind_next_frame(struct unwind_state *state)
  53{
  54        struct stack_info *info = &state->stack_info;
  55        struct stack_frame *sf;
  56        struct pt_regs *regs;
  57        unsigned long sp, ip;
  58        bool reliable;
  59
  60        regs = state->regs;
  61        if (unlikely(regs)) {
  62                sp = state->sp;
  63                sf = (struct stack_frame *) sp;
  64                ip = READ_ONCE_NOCHECK(sf->gprs[8]);
  65                reliable = false;
  66                regs = NULL;
  67                if (!__kernel_text_address(ip)) {
  68                        /* skip bogus %r14 */
  69                        state->regs = NULL;
  70                        return unwind_next_frame(state);
  71                }
  72        } else {
  73                sf = (struct stack_frame *) state->sp;
  74                sp = READ_ONCE_NOCHECK(sf->back_chain);
  75                if (likely(sp)) {
  76                        /* Non-zero back-chain points to the previous frame */
  77                        if (unlikely(outside_of_stack(state, sp))) {
  78                                if (!update_stack_info(state, sp))
  79                                        goto out_err;
  80                        }
  81                        sf = (struct stack_frame *) sp;
  82                        ip = READ_ONCE_NOCHECK(sf->gprs[8]);
  83                        reliable = true;
  84                } else {
  85                        /* No back-chain, look for a pt_regs structure */
  86                        sp = state->sp + STACK_FRAME_OVERHEAD;
  87                        if (!on_stack(info, sp, sizeof(struct pt_regs)))
  88                                goto out_err;
  89                        regs = (struct pt_regs *) sp;
  90                        if (is_final_pt_regs(state, regs))
  91                                goto out_stop;
  92                        ip = READ_ONCE_NOCHECK(regs->psw.addr);
  93                        sp = READ_ONCE_NOCHECK(regs->gprs[15]);
  94                        if (unlikely(outside_of_stack(state, sp))) {
  95                                if (!update_stack_info(state, sp))
  96                                        goto out_err;
  97                        }
  98                        reliable = true;
  99                }
 100        }
 101
 102        /* Sanity check: ABI requires SP to be aligned 8 bytes. */
 103        if (sp & 0x7)
 104                goto out_err;
 105
 106        ip = ftrace_graph_ret_addr(state->task, &state->graph_idx, ip, (void *) sp);
 107
 108        /* Update unwind state */
 109        state->sp = sp;
 110        state->ip = ip;
 111        state->regs = regs;
 112        state->reliable = reliable;
 113        return true;
 114
 115out_err:
 116        state->error = true;
 117out_stop:
 118        state->stack_info.type = STACK_TYPE_UNKNOWN;
 119        return false;
 120}
 121EXPORT_SYMBOL_GPL(unwind_next_frame);
 122
 123void __unwind_start(struct unwind_state *state, struct task_struct *task,
 124                    struct pt_regs *regs, unsigned long first_frame)
 125{
 126        struct stack_info *info = &state->stack_info;
 127        struct stack_frame *sf;
 128        unsigned long ip, sp;
 129
 130        memset(state, 0, sizeof(*state));
 131        state->task = task;
 132        state->regs = regs;
 133
 134        /* Don't even attempt to start from user mode regs: */
 135        if (regs && user_mode(regs)) {
 136                info->type = STACK_TYPE_UNKNOWN;
 137                return;
 138        }
 139
 140        /* Get the instruction pointer from pt_regs or the stack frame */
 141        if (regs) {
 142                ip = regs->psw.addr;
 143                sp = regs->gprs[15];
 144        } else if (task == current) {
 145                sp = current_frame_address();
 146        } else {
 147                sp = task->thread.ksp;
 148        }
 149
 150        /* Get current stack pointer and initialize stack info */
 151        if (!update_stack_info(state, sp)) {
 152                /* Something is wrong with the stack pointer */
 153                info->type = STACK_TYPE_UNKNOWN;
 154                state->error = true;
 155                return;
 156        }
 157
 158        if (!regs) {
 159                /* Stack frame is within valid stack */
 160                sf = (struct stack_frame *)sp;
 161                ip = READ_ONCE_NOCHECK(sf->gprs[8]);
 162        }
 163
 164        ip = ftrace_graph_ret_addr(state->task, &state->graph_idx, ip, NULL);
 165
 166        /* Update unwind state */
 167        state->sp = sp;
 168        state->ip = ip;
 169        state->reliable = true;
 170
 171        if (!first_frame)
 172                return;
 173        /* Skip through the call chain to the specified starting frame */
 174        while (!unwind_done(state)) {
 175                if (on_stack(&state->stack_info, first_frame, sizeof(struct stack_frame))) {
 176                        if (state->sp >= first_frame)
 177                                break;
 178                }
 179                unwind_next_frame(state);
 180        }
 181}
 182EXPORT_SYMBOL_GPL(__unwind_start);
 183