LCOV - code coverage report
Current view: top level - arch/x86/kernel - unwind_orc.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 174 284 61.3 %
Date: 2022-03-28 16:04:14 Functions: 13 13 100.0 %
Branches: 81 201 40.3 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0-only
       2                 :            : #include <linux/module.h>
       3                 :            : #include <linux/sort.h>
       4                 :            : #include <asm/ptrace.h>
       5                 :            : #include <asm/stacktrace.h>
       6                 :            : #include <asm/unwind.h>
       7                 :            : #include <asm/orc_types.h>
       8                 :            : #include <asm/orc_lookup.h>
       9                 :            : 
      10                 :            : #define orc_warn(fmt, ...) \
      11                 :            :         printk_deferred_once(KERN_WARNING pr_fmt("WARNING: " fmt), ##__VA_ARGS__)
      12                 :            : 
      13                 :            : extern int __start_orc_unwind_ip[];
      14                 :            : extern int __stop_orc_unwind_ip[];
      15                 :            : extern struct orc_entry __start_orc_unwind[];
      16                 :            : extern struct orc_entry __stop_orc_unwind[];
      17                 :            : 
      18                 :            : static DEFINE_MUTEX(sort_mutex);
      19                 :            : int *cur_orc_ip_table = __start_orc_unwind_ip;
      20                 :            : struct orc_entry *cur_orc_table = __start_orc_unwind;
      21                 :            : 
      22                 :            : unsigned int lookup_num_blocks;
      23                 :            : bool orc_init;
      24                 :            : 
      25                 :   49592380 : static inline unsigned long orc_ip(const int *ip)
      26                 :            : {
      27                 :   49592380 :         return (unsigned long)ip + *ip;
      28                 :            : }
      29                 :            : 
      30                 :    2997512 : static struct orc_entry *__orc_find(int *ip_table, struct orc_entry *u_table,
      31                 :            :                                     unsigned int num_entries, unsigned long ip)
      32                 :            : {
      33                 :    2997512 :         int *first = ip_table;
      34                 :    2997512 :         int *last = ip_table + num_entries - 1;
      35                 :    2997512 :         int *mid = first, *found = first;
      36                 :            : 
      37         [ +  - ]:    2997512 :         if (!num_entries)
      38                 :            :                 return NULL;
      39                 :            : 
      40                 :            :         /*
      41                 :            :          * Do a binary range search to find the rightmost duplicate of a given
      42                 :            :          * starting address.  Some entries are section terminators which are
      43                 :            :          * "weak" entries for ensuring there are no gaps.  They should be
      44                 :            :          * ignored when they conflict with a real entry.
      45                 :            :          */
      46         [ +  + ]:   51844850 :         while (first <= last) {
      47                 :   48847320 :                 mid = first + ((last - first) / 2);
      48                 :            : 
      49         [ +  + ]:   48847320 :                 if (orc_ip(mid) <= ip) {
      50                 :   25672120 :                         found = mid;
      51                 :   25672120 :                         first = mid + 1;
      52                 :            :                 } else
      53                 :   23175200 :                         last = mid - 1;
      54                 :            :         }
      55                 :            : 
      56                 :    2997512 :         return u_table + (found - ip_table);
      57                 :            : }
      58                 :            : 
      59                 :            : #ifdef CONFIG_MODULES
      60                 :      14582 : static struct orc_entry *orc_module_find(unsigned long ip)
      61                 :            : {
      62                 :      14582 :         struct module *mod;
      63                 :            : 
      64                 :      14582 :         mod = __module_address(ip);
      65   [ +  -  +  -  :      14582 :         if (!mod || !mod->arch.orc_unwind || !mod->arch.orc_unwind_ip)
                   +  - ]
      66                 :            :                 return NULL;
      67                 :      14582 :         return __orc_find(mod->arch.orc_unwind_ip, mod->arch.orc_unwind,
      68                 :            :                           mod->arch.num_orcs, ip);
      69                 :            : }
      70                 :            : #else
      71                 :            : static struct orc_entry *orc_module_find(unsigned long ip)
      72                 :            : {
      73                 :            :         return NULL;
      74                 :            : }
      75                 :            : #endif
      76                 :            : 
      77                 :            : #ifdef CONFIG_DYNAMIC_FTRACE
      78                 :            : static struct orc_entry *orc_find(unsigned long ip);
      79                 :            : 
      80                 :            : /*
      81                 :            :  * Ftrace dynamic trampolines do not have orc entries of their own.
      82                 :            :  * But they are copies of the ftrace entries that are static and
      83                 :            :  * defined in ftrace_*.S, which do have orc entries.
      84                 :            :  *
      85                 :            :  * If the unwinder comes across a ftrace trampoline, then find the
      86                 :            :  * ftrace function that was used to create it, and use that ftrace
      87                 :            :  * function's orc entry, as the placement of the return code in
      88                 :            :  * the stack will be identical.
      89                 :            :  */
      90                 :            : static struct orc_entry *orc_ftrace_find(unsigned long ip)
      91                 :            : {
      92                 :            :         struct ftrace_ops *ops;
      93                 :            :         unsigned long caller;
      94                 :            : 
      95                 :            :         ops = ftrace_ops_trampoline(ip);
      96                 :            :         if (!ops)
      97                 :            :                 return NULL;
      98                 :            : 
      99                 :            :         if (ops->flags & FTRACE_OPS_FL_SAVE_REGS)
     100                 :            :                 caller = (unsigned long)ftrace_regs_call;
     101                 :            :         else
     102                 :            :                 caller = (unsigned long)ftrace_call;
     103                 :            : 
     104                 :            :         /* Prevent unlikely recursion */
     105                 :            :         if (ip == caller)
     106                 :            :                 return NULL;
     107                 :            : 
     108                 :            :         return orc_find(caller);
     109                 :            : }
     110                 :            : #else
     111                 :            : static struct orc_entry *orc_ftrace_find(unsigned long ip)
     112                 :            : {
     113                 :            :         return NULL;
     114                 :            : }
     115                 :            : #endif
     116                 :            : 
     117                 :            : /*
     118                 :            :  * If we crash with IP==0, the last successfully executed instruction
     119                 :            :  * was probably an indirect function call with a NULL function pointer,
     120                 :            :  * and we don't have unwind information for NULL.
     121                 :            :  * This hardcoded ORC entry for IP==0 allows us to unwind from a NULL function
     122                 :            :  * pointer into its parent and then continue normally from there.
     123                 :            :  */
     124                 :            : static struct orc_entry null_orc_entry = {
     125                 :            :         .sp_offset = sizeof(long),
     126                 :            :         .sp_reg = ORC_REG_SP,
     127                 :            :         .bp_reg = ORC_REG_UNDEFINED,
     128                 :            :         .type = ORC_TYPE_CALL
     129                 :            : };
     130                 :            : 
     131                 :            : /* Fake frame pointer entry -- used as a fallback for generated code */
     132                 :            : static struct orc_entry orc_fp_entry = {
     133                 :            :         .type           = ORC_TYPE_CALL,
     134                 :            :         .sp_reg         = ORC_REG_BP,
     135                 :            :         .sp_offset      = 16,
     136                 :            :         .bp_reg         = ORC_REG_PREV_SP,
     137                 :            :         .bp_offset      = -16,
     138                 :            :         .end            = 0,
     139                 :            : };
     140                 :            : 
     141                 :     547779 : static struct orc_entry *orc_find(unsigned long ip)
     142                 :            : {
     143                 :     547779 :         static struct orc_entry *orc;
     144                 :            : 
     145         [ +  - ]:     547779 :         if (!orc_init)
     146                 :            :                 return NULL;
     147                 :            : 
     148         [ +  - ]:     547779 :         if (ip == 0)
     149                 :            :                 return &null_orc_entry;
     150                 :            : 
     151                 :            :         /* For non-init vmlinux addresses, use the fast lookup table: */
     152   [ +  -  +  + ]:     547779 :         if (ip >= LOOKUP_START_IP && ip < LOOKUP_STOP_IP) {
     153                 :     533145 :                 unsigned int idx, start, stop;
     154                 :            : 
     155                 :     533145 :                 idx = (ip - LOOKUP_START_IP) / LOOKUP_BLOCK_SIZE;
     156                 :            : 
     157         [ -  + ]:     533145 :                 if (unlikely((idx >= lookup_num_blocks-1))) {
     158         [ #  # ]:          0 :                         orc_warn("WARNING: bad lookup idx: idx=%u num=%u ip=%pB\n",
     159                 :            :                                  idx, lookup_num_blocks, (void *)ip);
     160                 :          0 :                         return NULL;
     161                 :            :                 }
     162                 :            : 
     163                 :     533145 :                 start = orc_lookup[idx];
     164                 :     533145 :                 stop = orc_lookup[idx + 1] + 1;
     165                 :            : 
     166   [ +  -  -  + ]:     533145 :                 if (unlikely((__start_orc_unwind + start >= __stop_orc_unwind) ||
     167                 :            :                              (__start_orc_unwind + stop > __stop_orc_unwind))) {
     168         [ #  # ]:          0 :                         orc_warn("WARNING: bad lookup value: idx=%u num=%u start=%u stop=%u ip=%pB\n",
     169                 :            :                                  idx, lookup_num_blocks, start, stop, (void *)ip);
     170                 :          0 :                         return NULL;
     171                 :            :                 }
     172                 :            : 
     173                 :     533145 :                 return __orc_find(__start_orc_unwind_ip + start,
     174                 :            :                                   __start_orc_unwind + start, stop - start, ip);
     175                 :            :         }
     176                 :            : 
     177                 :            :         /* vmlinux .init slow lookup: */
     178         [ +  + ]:      14634 :         if (init_kernel_text(ip))
     179                 :         52 :                 return __orc_find(__start_orc_unwind_ip, __start_orc_unwind,
     180                 :         52 :                                   __stop_orc_unwind_ip - __start_orc_unwind_ip, ip);
     181                 :            : 
     182                 :            :         /* Module lookup: */
     183                 :      14582 :         orc = orc_module_find(ip);
     184         [ +  - ]:      14582 :         if (orc)
     185                 :      14582 :                 return orc;
     186                 :            : 
     187                 :            :         return orc_ftrace_find(ip);
     188                 :            : }
     189                 :            : 
     190                 :            : #ifdef CONFIG_MODULES
     191                 :            : 
     192                 :     709878 : static void orc_sort_swap(void *_a, void *_b, int size)
     193                 :            : {
     194                 :     709878 :         struct orc_entry *orc_a, *orc_b;
     195                 :     709878 :         struct orc_entry orc_tmp;
     196                 :     709878 :         int *a = _a, *b = _b, tmp;
     197                 :     709878 :         int delta = _b - _a;
     198                 :            : 
     199                 :            :         /* Swap the .orc_unwind_ip entries: */
     200                 :     709878 :         tmp = *a;
     201                 :     709878 :         *a = *b + delta;
     202                 :     709878 :         *b = tmp - delta;
     203                 :            : 
     204                 :            :         /* Swap the corresponding .orc_unwind entries: */
     205                 :     709878 :         orc_a = cur_orc_table + (a - cur_orc_ip_table);
     206                 :     709878 :         orc_b = cur_orc_table + (b - cur_orc_ip_table);
     207                 :     709878 :         orc_tmp = *orc_a;
     208                 :     709878 :         *orc_a = *orc_b;
     209                 :     709878 :         *orc_b = orc_tmp;
     210                 :     709878 : }
     211                 :            : 
     212                 :     745056 : static int orc_sort_cmp(const void *_a, const void *_b)
     213                 :            : {
     214                 :     745056 :         struct orc_entry *orc_a;
     215                 :     745056 :         const int *a = _a, *b = _b;
     216                 :     745056 :         unsigned long a_val = orc_ip(a);
     217                 :     745056 :         unsigned long b_val = orc_ip(b);
     218                 :            : 
     219         [ +  + ]:     745056 :         if (a_val > b_val)
     220                 :            :                 return 1;
     221         [ +  + ]:     418821 :         if (a_val < b_val)
     222                 :            :                 return -1;
     223                 :            : 
     224                 :            :         /*
     225                 :            :          * The "weak" section terminator entries need to always be on the left
     226                 :            :          * to ensure the lookup code skips them in favor of real entries.
     227                 :            :          * These terminator entries exist to handle any gaps created by
     228                 :            :          * whitelisted .o files which didn't get objtool generation.
     229                 :            :          */
     230                 :         13 :         orc_a = cur_orc_table + (a - cur_orc_ip_table);
     231   [ +  -  -  + ]:         13 :         return orc_a->sp_reg == ORC_REG_UNDEFINED && !orc_a->end ? -1 : 1;
     232                 :            : }
     233                 :            : 
     234                 :         26 : void unwind_module_init(struct module *mod, void *_orc_ip, size_t orc_ip_size,
     235                 :            :                         void *_orc, size_t orc_size)
     236                 :            : {
     237                 :         26 :         int *orc_ip = _orc_ip;
     238                 :         26 :         struct orc_entry *orc = _orc;
     239                 :         26 :         unsigned int num_entries = orc_ip_size / sizeof(int);
     240                 :            : 
     241   [ +  -  +  -  :         52 :         WARN_ON_ONCE(orc_ip_size % sizeof(int) != 0 ||
             +  -  -  + ]
     242                 :            :                      orc_size % sizeof(*orc) != 0 ||
     243                 :            :                      num_entries != orc_size / sizeof(*orc));
     244                 :            : 
     245                 :            :         /*
     246                 :            :          * The 'cur_orc_*' globals allow the orc_sort_swap() callback to
     247                 :            :          * associate an .orc_unwind_ip table entry with its corresponding
     248                 :            :          * .orc_unwind entry so they can both be swapped.
     249                 :            :          */
     250                 :         26 :         mutex_lock(&sort_mutex);
     251                 :         26 :         cur_orc_ip_table = orc_ip;
     252                 :         26 :         cur_orc_table = orc;
     253                 :         26 :         sort(orc_ip, num_entries, sizeof(int), orc_sort_cmp, orc_sort_swap);
     254                 :         26 :         mutex_unlock(&sort_mutex);
     255                 :            : 
     256                 :         26 :         mod->arch.orc_unwind_ip = orc_ip;
     257                 :         26 :         mod->arch.orc_unwind = orc;
     258                 :         26 :         mod->arch.num_orcs = num_entries;
     259                 :         26 : }
     260                 :            : #endif
     261                 :            : 
     262                 :         13 : void __init unwind_init(void)
     263                 :            : {
     264                 :         13 :         size_t orc_ip_size = (void *)__stop_orc_unwind_ip - (void *)__start_orc_unwind_ip;
     265                 :         13 :         size_t orc_size = (void *)__stop_orc_unwind - (void *)__start_orc_unwind;
     266                 :         13 :         size_t num_entries = orc_ip_size / sizeof(int);
     267                 :         13 :         struct orc_entry *orc;
     268                 :         13 :         int i;
     269                 :            : 
     270   [ +  -  +  - ]:         13 :         if (!num_entries || orc_ip_size % sizeof(int) != 0 ||
     271         [ +  - ]:         13 :             orc_size % sizeof(struct orc_entry) != 0 ||
     272         [ -  + ]:         13 :             num_entries != orc_size / sizeof(struct orc_entry)) {
     273         [ #  # ]:          0 :                 orc_warn("WARNING: Bad or missing .orc_unwind table.  Disabling unwinder.\n");
     274                 :          0 :                 return;
     275                 :            :         }
     276                 :            : 
     277                 :            :         /*
     278                 :            :          * Note, the orc_unwind and orc_unwind_ip tables were already
     279                 :            :          * sorted at build time via the 'sorttable' tool.
     280                 :            :          * It's ready for binary search straight away, no need to sort it.
     281                 :            :          */
     282                 :            : 
     283                 :            :         /* Initialize the fast lookup table: */
     284                 :         13 :         lookup_num_blocks = orc_lookup_end - orc_lookup;
     285         [ +  + ]:    2449733 :         for (i = 0; i < lookup_num_blocks-1; i++) {
     286                 :    2449720 :                 orc = __orc_find(__start_orc_unwind_ip, __start_orc_unwind,
     287                 :            :                                  num_entries,
     288                 :    2449720 :                                  LOOKUP_START_IP + (LOOKUP_BLOCK_SIZE * i));
     289         [ -  + ]:    2449720 :                 if (!orc) {
     290         [ #  # ]:          0 :                         orc_warn("WARNING: Corrupt .orc_unwind table.  Disabling unwinder.\n");
     291                 :          0 :                         return;
     292                 :            :                 }
     293                 :            : 
     294                 :    2449720 :                 orc_lookup[i] = orc - __start_orc_unwind;
     295                 :            :         }
     296                 :            : 
     297                 :            :         /* Initialize the ending block: */
     298                 :         13 :         orc = __orc_find(__start_orc_unwind_ip, __start_orc_unwind, num_entries,
     299                 :            :                          LOOKUP_STOP_IP);
     300         [ -  + ]:         13 :         if (!orc) {
     301         [ #  # ]:          0 :                 orc_warn("WARNING: Corrupt .orc_unwind table.  Disabling unwinder.\n");
     302                 :          0 :                 return;
     303                 :            :         }
     304                 :         13 :         orc_lookup[lookup_num_blocks-1] = orc - __start_orc_unwind;
     305                 :            : 
     306                 :         13 :         orc_init = true;
     307                 :            : }
     308                 :            : 
     309                 :     479227 : unsigned long unwind_get_return_address(struct unwind_state *state)
     310                 :            : {
     311         [ +  - ]:     479227 :         if (unwind_done(state))
     312                 :            :                 return 0;
     313                 :            : 
     314         [ +  - ]:     479227 :         return __kernel_text_address(state->ip) ? state->ip : 0;
     315                 :            : }
     316                 :            : EXPORT_SYMBOL_GPL(unwind_get_return_address);
     317                 :            : 
     318                 :        676 : unsigned long *unwind_get_return_address_ptr(struct unwind_state *state)
     319                 :            : {
     320         [ +  + ]:        676 :         if (unwind_done(state))
     321                 :            :                 return NULL;
     322                 :            : 
     323         [ -  + ]:        403 :         if (state->regs)
     324                 :          0 :                 return &state->regs->ip;
     325                 :            : 
     326         [ +  - ]:        403 :         if (state->sp)
     327                 :        403 :                 return (unsigned long *)state->sp - 1;
     328                 :            : 
     329                 :            :         return NULL;
     330                 :            : }
     331                 :            : 
     332                 :    1027032 : static bool stack_access_ok(struct unwind_state *state, unsigned long _addr,
     333                 :            :                             size_t len)
     334                 :            : {
     335                 :    1027032 :         struct stack_info *info = &state->stack_info;
     336                 :    1027032 :         void *addr = (void *)_addr;
     337                 :            : 
     338   [ +  -  -  +  :    2054064 :         if (!on_stack(info, addr, len) &&
                   -  - ]
     339                 :          0 :             (get_stack_info(addr, state->task, info, &state->stack_mask)))
     340                 :          0 :                 return false;
     341                 :            : 
     342                 :            :         return true;
     343                 :            : }
     344                 :            : 
     345                 :    1027032 : static bool deref_stack_reg(struct unwind_state *state, unsigned long addr,
     346                 :            :                             unsigned long *val)
     347                 :            : {
     348         [ +  - ]:    1027032 :         if (!stack_access_ok(state, addr, sizeof(long)))
     349                 :            :                 return false;
     350                 :            : 
     351                 :    1027032 :         *val = READ_ONCE_NOCHECK(*(unsigned long *)addr);
     352                 :    1027032 :         return true;
     353                 :            : }
     354                 :            : 
     355                 :          0 : static bool deref_stack_regs(struct unwind_state *state, unsigned long addr,
     356                 :            :                              unsigned long *ip, unsigned long *sp)
     357                 :            : {
     358                 :          0 :         struct pt_regs *regs = (struct pt_regs *)addr;
     359                 :            : 
     360                 :            :         /* x86-32 support will be more complicated due to the &regs->sp hack */
     361                 :          0 :         BUILD_BUG_ON(IS_ENABLED(CONFIG_X86_32));
     362                 :            : 
     363         [ #  # ]:          0 :         if (!stack_access_ok(state, addr, sizeof(struct pt_regs)))
     364                 :            :                 return false;
     365                 :            : 
     366                 :          0 :         *ip = regs->ip;
     367                 :          0 :         *sp = regs->sp;
     368                 :          0 :         return true;
     369                 :            : }
     370                 :            : 
     371                 :          0 : static bool deref_stack_iret_regs(struct unwind_state *state, unsigned long addr,
     372                 :            :                                   unsigned long *ip, unsigned long *sp)
     373                 :            : {
     374                 :          0 :         struct pt_regs *regs = (void *)addr - IRET_FRAME_OFFSET;
     375                 :            : 
     376         [ #  # ]:          0 :         if (!stack_access_ok(state, addr, IRET_FRAME_SIZE))
     377                 :            :                 return false;
     378                 :            : 
     379                 :          0 :         *ip = regs->ip;
     380                 :          0 :         *sp = regs->sp;
     381                 :          0 :         return true;
     382                 :            : }
     383                 :            : 
     384                 :     547779 : bool unwind_next_frame(struct unwind_state *state)
     385                 :            : {
     386                 :     547779 :         unsigned long ip_p, sp, orig_ip = state->ip, prev_sp = state->sp;
     387                 :     547779 :         enum stack_type prev_type = state->stack_info.type;
     388                 :     547779 :         struct orc_entry *orc;
     389                 :     547779 :         bool indirect = false;
     390                 :            : 
     391         [ +  - ]:     547779 :         if (unwind_done(state))
     392                 :            :                 return false;
     393                 :            : 
     394                 :            :         /* Don't let modules unload while we're reading their ORC data. */
     395                 :     547779 :         preempt_disable();
     396                 :            : 
     397                 :            :         /* End-of-stack check for user tasks: */
     398   [ +  +  -  + ]:     547779 :         if (state->regs && user_mode(state->regs))
     399                 :          0 :                 goto the_end;
     400                 :            : 
     401                 :            :         /*
     402                 :            :          * Find the orc_entry associated with the text address.
     403                 :            :          *
     404                 :            :          * Decrement call return addresses by one so they work for sibling
     405                 :            :          * calls and calls to noreturn functions.
     406                 :            :          */
     407         [ +  + ]:     547779 :         orc = orc_find(state->signal ? state->ip : state->ip - 1);
     408         [ -  + ]:     547779 :         if (!orc) {
     409                 :            :                 /*
     410                 :            :                  * As a fallback, try to assume this code uses a frame pointer.
     411                 :            :                  * This is useful for generated code, like BPF, which ORC
     412                 :            :                  * doesn't know about.  This is just a guess, so the rest of
     413                 :            :                  * the unwind is no longer considered reliable.
     414                 :            :                  */
     415                 :          0 :                 orc = &orc_fp_entry;
     416                 :          0 :                 state->error = true;
     417                 :            :         }
     418                 :            : 
     419                 :            :         /* End-of-stack check for kernel threads: */
     420         [ +  + ]:     547779 :         if (orc->sp_reg == ORC_REG_UNDEFINED) {
     421         [ -  + ]:         13 :                 if (!orc->end)
     422                 :          0 :                         goto err;
     423                 :            : 
     424                 :         13 :                 goto the_end;
     425                 :            :         }
     426                 :            : 
     427                 :            :         /* Find the previous frame's stack: */
     428   [ +  +  -  -  :     547766 :         switch (orc->sp_reg) {
             -  -  -  -  
                      - ]
     429                 :     479305 :         case ORC_REG_SP:
     430                 :     479305 :                 sp = state->sp + orc->sp_offset;
     431                 :     479305 :                 break;
     432                 :            : 
     433                 :      68461 :         case ORC_REG_BP:
     434                 :      68461 :                 sp = state->bp + orc->sp_offset;
     435                 :      68461 :                 break;
     436                 :            : 
     437                 :          0 :         case ORC_REG_SP_INDIRECT:
     438                 :          0 :                 sp = state->sp + orc->sp_offset;
     439                 :          0 :                 indirect = true;
     440                 :          0 :                 break;
     441                 :            : 
     442                 :          0 :         case ORC_REG_BP_INDIRECT:
     443                 :          0 :                 sp = state->bp + orc->sp_offset;
     444                 :          0 :                 indirect = true;
     445                 :          0 :                 break;
     446                 :            : 
     447                 :          0 :         case ORC_REG_R10:
     448   [ #  #  #  # ]:          0 :                 if (!state->regs || !state->full_regs) {
     449         [ #  # ]:          0 :                         orc_warn("missing regs for base reg R10 at ip %pB\n",
     450                 :            :                                  (void *)state->ip);
     451                 :          0 :                         goto err;
     452                 :            :                 }
     453                 :          0 :                 sp = state->regs->r10;
     454                 :          0 :                 break;
     455                 :            : 
     456                 :          0 :         case ORC_REG_R13:
     457   [ #  #  #  # ]:          0 :                 if (!state->regs || !state->full_regs) {
     458         [ #  # ]:          0 :                         orc_warn("missing regs for base reg R13 at ip %pB\n",
     459                 :            :                                  (void *)state->ip);
     460                 :          0 :                         goto err;
     461                 :            :                 }
     462                 :          0 :                 sp = state->regs->r13;
     463                 :          0 :                 break;
     464                 :            : 
     465                 :          0 :         case ORC_REG_DI:
     466   [ #  #  #  # ]:          0 :                 if (!state->regs || !state->full_regs) {
     467         [ #  # ]:          0 :                         orc_warn("missing regs for base reg DI at ip %pB\n",
     468                 :            :                                  (void *)state->ip);
     469                 :          0 :                         goto err;
     470                 :            :                 }
     471                 :          0 :                 sp = state->regs->di;
     472                 :          0 :                 break;
     473                 :            : 
     474                 :          0 :         case ORC_REG_DX:
     475   [ #  #  #  # ]:          0 :                 if (!state->regs || !state->full_regs) {
     476         [ #  # ]:          0 :                         orc_warn("missing regs for base reg DX at ip %pB\n",
     477                 :            :                                  (void *)state->ip);
     478                 :          0 :                         goto err;
     479                 :            :                 }
     480                 :          0 :                 sp = state->regs->dx;
     481                 :          0 :                 break;
     482                 :            : 
     483                 :          0 :         default:
     484         [ #  # ]:          0 :                 orc_warn("unknown SP base reg %d for ip %pB\n",
     485                 :            :                          orc->sp_reg, (void *)state->ip);
     486                 :          0 :                 goto err;
     487                 :            :         }
     488                 :            : 
     489                 :     547766 :         if (indirect) {
     490         [ #  # ]:          0 :                 if (!deref_stack_reg(state, sp, &sp))
     491                 :          0 :                         goto err;
     492                 :            :         }
     493                 :            : 
     494                 :            :         /* Find IP, SP and possibly regs: */
     495   [ +  -  -  - ]:     547766 :         switch (orc->type) {
     496                 :     547766 :         case ORC_TYPE_CALL:
     497                 :     547766 :                 ip_p = sp - sizeof(long);
     498                 :            : 
     499         [ -  + ]:     547766 :                 if (!deref_stack_reg(state, ip_p, &state->ip))
     500                 :          0 :                         goto err;
     501                 :            : 
     502                 :     547766 :                 state->ip = ftrace_graph_ret_addr(state->task, &state->graph_idx,
     503                 :            :                                                   state->ip, (void *)ip_p);
     504                 :            : 
     505                 :     547766 :                 state->sp = sp;
     506                 :     547766 :                 state->regs = NULL;
     507                 :     547766 :                 state->signal = false;
     508                 :     547766 :                 break;
     509                 :            : 
     510                 :          0 :         case ORC_TYPE_REGS:
     511                 :          0 :                 if (!deref_stack_regs(state, sp, &state->ip, &state->sp)) {
     512         [ #  # ]:          0 :                         orc_warn("can't dereference registers at %p for ip %pB\n",
     513                 :            :                                  (void *)sp, (void *)orig_ip);
     514                 :          0 :                         goto err;
     515                 :            :                 }
     516                 :            : 
     517                 :          0 :                 state->regs = (struct pt_regs *)sp;
     518                 :          0 :                 state->full_regs = true;
     519                 :          0 :                 state->signal = true;
     520                 :          0 :                 break;
     521                 :            : 
     522                 :          0 :         case ORC_TYPE_REGS_IRET:
     523                 :          0 :                 if (!deref_stack_iret_regs(state, sp, &state->ip, &state->sp)) {
     524         [ #  # ]:          0 :                         orc_warn("can't dereference iret registers at %p for ip %pB\n",
     525                 :            :                                  (void *)sp, (void *)orig_ip);
     526                 :          0 :                         goto err;
     527                 :            :                 }
     528                 :            : 
     529                 :          0 :                 state->regs = (void *)sp - IRET_FRAME_OFFSET;
     530                 :          0 :                 state->full_regs = false;
     531                 :          0 :                 state->signal = true;
     532                 :          0 :                 break;
     533                 :            : 
     534                 :          0 :         default:
     535         [ #  # ]:          0 :                 orc_warn("unknown .orc_unwind entry type %d for ip %pB\n",
     536                 :            :                          orc->type, (void *)orig_ip);
     537                 :          0 :                 break;
     538                 :            :         }
     539                 :            : 
     540                 :            :         /* Find BP: */
     541   [ +  +  -  - ]:     547766 :         switch (orc->bp_reg) {
     542                 :      68500 :         case ORC_REG_UNDEFINED:
     543   [ -  +  -  - ]:      68500 :                 if (state->regs && state->full_regs)
     544                 :          0 :                         state->bp = state->regs->bp;
     545                 :            :                 break;
     546                 :            : 
     547                 :     479266 :         case ORC_REG_PREV_SP:
     548         [ -  + ]:     479266 :                 if (!deref_stack_reg(state, sp + orc->bp_offset, &state->bp))
     549                 :          0 :                         goto err;
     550                 :            :                 break;
     551                 :            : 
     552                 :          0 :         case ORC_REG_BP:
     553         [ #  # ]:          0 :                 if (!deref_stack_reg(state, state->bp + orc->bp_offset, &state->bp))
     554                 :          0 :                         goto err;
     555                 :            :                 break;
     556                 :            : 
     557                 :          0 :         default:
     558         [ #  # ]:          0 :                 orc_warn("unknown BP base reg %d for ip %pB\n",
     559                 :            :                          orc->bp_reg, (void *)orig_ip);
     560                 :          0 :                 goto err;
     561                 :            :         }
     562                 :            : 
     563                 :            :         /* Prevent a recursive loop due to bad ORC data: */
     564   [ +  -  +  - ]:    1095532 :         if (state->stack_info.type == prev_type &&
     565   [ +  -  -  + ]:    1095532 :             on_stack(&state->stack_info, (void *)state->sp, sizeof(long)) &&
     566                 :            :             state->sp <= prev_sp) {
     567         [ #  # ]:          0 :                 orc_warn("stack going in the wrong direction? ip=%pB\n",
     568                 :            :                          (void *)orig_ip);
     569                 :          0 :                 goto err;
     570                 :            :         }
     571                 :            : 
     572                 :     547766 :         preempt_enable();
     573                 :     547766 :         return true;
     574                 :            : 
     575                 :          0 : err:
     576                 :          0 :         state->error = true;
     577                 :            : 
     578                 :         13 : the_end:
     579                 :         13 :         preempt_enable();
     580                 :         13 :         state->stack_info.type = STACK_TYPE_UNKNOWN;
     581                 :         13 :         return false;
     582                 :            : }
     583                 :            : EXPORT_SYMBOL_GPL(unwind_next_frame);
     584                 :            : 
     585                 :      68474 : void __unwind_start(struct unwind_state *state, struct task_struct *task,
     586                 :            :                     struct pt_regs *regs, unsigned long *first_frame)
     587                 :            : {
     588                 :      68474 :         memset(state, 0, sizeof(*state));
     589                 :      68474 :         state->task = task;
     590                 :            : 
     591                 :            :         /*
     592                 :            :          * Refuse to unwind the stack of a task while it's executing on another
     593                 :            :          * CPU.  This check is racy, but that's ok: the unwinder has other
     594                 :            :          * checks to prevent it from going off the rails.
     595                 :            :          */
     596   [ -  +  -  + ]:     136948 :         if (task_on_another_cpu(task))
     597                 :          0 :                 goto done;
     598                 :            : 
     599         [ +  + ]:      68474 :         if (regs) {
     600         [ -  + ]:         13 :                 if (user_mode(regs))
     601                 :          0 :                         goto done;
     602                 :            : 
     603                 :         13 :                 state->ip = regs->ip;
     604                 :         13 :                 state->sp = regs->sp;
     605                 :         13 :                 state->bp = regs->bp;
     606                 :         13 :                 state->regs = regs;
     607                 :         13 :                 state->full_regs = true;
     608                 :         13 :                 state->signal = true;
     609                 :            : 
     610         [ +  - ]:      68461 :         } else if (task == current) {
     611                 :      68461 :                 asm volatile("lea (%%rip), %0\n\t"
     612                 :            :                              "mov %%rsp, %1\n\t"
     613                 :            :                              "mov %%rbp, %2\n\t"
     614                 :            :                              : "=r" (state->ip), "=r" (state->sp),
     615                 :            :                                "=r" (state->bp));
     616                 :            : 
     617                 :            :         } else {
     618                 :          0 :                 struct inactive_task_frame *frame = (void *)task->thread.sp;
     619                 :            : 
     620                 :          0 :                 state->sp = task->thread.sp;
     621                 :          0 :                 state->bp = READ_ONCE_NOCHECK(frame->bp);
     622                 :          0 :                 state->ip = READ_ONCE_NOCHECK(frame->ret_addr);
     623                 :            :         }
     624                 :            : 
     625         [ -  + ]:      68474 :         if (get_stack_info((unsigned long *)state->sp, state->task,
     626                 :            :                            &state->stack_info, &state->stack_mask)) {
     627                 :            :                 /*
     628                 :            :                  * We weren't on a valid stack.  It's possible that
     629                 :            :                  * we overflowed a valid stack into a guard page.
     630                 :            :                  * See if the next page up is valid so that we can
     631                 :            :                  * generate some kind of backtrace if this happens.
     632                 :            :                  */
     633                 :          0 :                 void *next_page = (void *)PAGE_ALIGN((unsigned long)state->sp);
     634         [ #  # ]:          0 :                 if (get_stack_info(next_page, state->task, &state->stack_info,
     635                 :            :                                    &state->stack_mask))
     636                 :            :                         return;
     637                 :            :         }
     638                 :            : 
     639                 :            :         /*
     640                 :            :          * The caller can provide the address of the first frame directly
     641                 :            :          * (first_frame) or indirectly (regs->sp) to indicate which stack frame
     642                 :            :          * to start unwinding at.  Skip ahead until we reach it.
     643                 :            :          */
     644                 :            : 
     645                 :            :         /* When starting from regs, skip the regs frame: */
     646         [ +  + ]:      68474 :         if (regs) {
     647                 :         13 :                 unwind_next_frame(state);
     648                 :         13 :                 return;
     649                 :            :         }
     650                 :            : 
     651                 :            :         /* Otherwise, skip ahead to the user-specified starting frame: */
     652   [ +  -  -  + ]:     410766 :         while (!unwind_done(state) &&
     653                 :     205383 :                (!on_stack(&state->stack_info, first_frame, sizeof(long)) ||
     654         [ +  + ]:     205383 :                         state->sp <= (unsigned long)first_frame))
     655                 :     136922 :                 unwind_next_frame(state);
     656                 :            : 
     657                 :            :         return;
     658                 :            : 
     659                 :          0 : done:
     660                 :          0 :         state->stack_info.type = STACK_TYPE_UNKNOWN;
     661                 :          0 :         return;
     662                 :            : }
     663                 :            : EXPORT_SYMBOL_GPL(__unwind_start);

Generated by: LCOV version 1.14