hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/arch/x86/kernel/unwind_orc.c
....@@ -1,3 +1,5 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
2
+#include <linux/objtool.h>
13 #include <linux/module.h>
24 #include <linux/sort.h>
35 #include <asm/ptrace.h>
....@@ -7,19 +9,21 @@
79 #include <asm/orc_lookup.h>
810
911 #define orc_warn(fmt, ...) \
10
- printk_deferred_once(KERN_WARNING pr_fmt("WARNING: " fmt), ##__VA_ARGS__)
12
+ printk_deferred_once(KERN_WARNING "WARNING: " fmt, ##__VA_ARGS__)
13
+
14
+#define orc_warn_current(args...) \
15
+({ \
16
+ if (state->task == current) \
17
+ orc_warn(args); \
18
+})
1119
1220 extern int __start_orc_unwind_ip[];
1321 extern int __stop_orc_unwind_ip[];
1422 extern struct orc_entry __start_orc_unwind[];
1523 extern struct orc_entry __stop_orc_unwind[];
1624
17
-static DEFINE_MUTEX(sort_mutex);
18
-int *cur_orc_ip_table = __start_orc_unwind_ip;
19
-struct orc_entry *cur_orc_table = __start_orc_unwind;
20
-
21
-unsigned int lookup_num_blocks;
22
-bool orc_init;
25
+static bool orc_init __ro_after_init;
26
+static unsigned int lookup_num_blocks __ro_after_init;
2327
2428 static inline unsigned long orc_ip(const int *ip)
2529 {
....@@ -81,30 +85,35 @@
8185 * But they are copies of the ftrace entries that are static and
8286 * defined in ftrace_*.S, which do have orc entries.
8387 *
84
- * If the undwinder comes across a ftrace trampoline, then find the
88
+ * If the unwinder comes across a ftrace trampoline, then find the
8589 * ftrace function that was used to create it, and use that ftrace
86
- * function's orc entrie, as the placement of the return code in
90
+ * function's orc entry, as the placement of the return code in
8791 * the stack will be identical.
8892 */
8993 static struct orc_entry *orc_ftrace_find(unsigned long ip)
9094 {
9195 struct ftrace_ops *ops;
92
- unsigned long caller;
96
+ unsigned long tramp_addr, offset;
9397
9498 ops = ftrace_ops_trampoline(ip);
9599 if (!ops)
96100 return NULL;
97101
102
+ /* Set tramp_addr to the start of the code copied by the trampoline */
98103 if (ops->flags & FTRACE_OPS_FL_SAVE_REGS)
99
- caller = (unsigned long)ftrace_regs_call;
104
+ tramp_addr = (unsigned long)ftrace_regs_caller;
100105 else
101
- caller = (unsigned long)ftrace_call;
106
+ tramp_addr = (unsigned long)ftrace_caller;
107
+
108
+ /* Now place tramp_addr to the location within the trampoline ip is at */
109
+ offset = ip - ops->trampoline;
110
+ tramp_addr += offset;
102111
103112 /* Prevent unlikely recursion */
104
- if (ip == caller)
113
+ if (ip == tramp_addr)
105114 return NULL;
106115
107
- return orc_find(caller);
116
+ return orc_find(tramp_addr);
108117 }
109118 #else
110119 static struct orc_entry *orc_ftrace_find(unsigned long ip)
....@@ -124,7 +133,17 @@
124133 .sp_offset = sizeof(long),
125134 .sp_reg = ORC_REG_SP,
126135 .bp_reg = ORC_REG_UNDEFINED,
127
- .type = ORC_TYPE_CALL
136
+ .type = UNWIND_HINT_TYPE_CALL
137
+};
138
+
139
+/* Fake frame pointer entry -- used as a fallback for generated code */
140
+static struct orc_entry orc_fp_entry = {
141
+ .type = UNWIND_HINT_TYPE_CALL,
142
+ .sp_reg = ORC_REG_BP,
143
+ .sp_offset = 16,
144
+ .bp_reg = ORC_REG_PREV_SP,
145
+ .bp_offset = -16,
146
+ .end = 0,
128147 };
129148
130149 static struct orc_entry *orc_find(unsigned long ip)
....@@ -173,6 +192,12 @@
173192 return orc_ftrace_find(ip);
174193 }
175194
195
+#ifdef CONFIG_MODULES
196
+
197
+static DEFINE_MUTEX(sort_mutex);
198
+static int *cur_orc_ip_table = __start_orc_unwind_ip;
199
+static struct orc_entry *cur_orc_table = __start_orc_unwind;
200
+
176201 static void orc_sort_swap(void *_a, void *_b, int size)
177202 {
178203 struct orc_entry *orc_a, *orc_b;
....@@ -215,7 +240,6 @@
215240 return orc_a->sp_reg == ORC_REG_UNDEFINED && !orc_a->end ? -1 : 1;
216241 }
217242
218
-#ifdef CONFIG_MODULES
219243 void unwind_module_init(struct module *mod, void *_orc_ip, size_t orc_ip_size,
220244 void *_orc, size_t orc_size)
221245 {
....@@ -259,9 +283,11 @@
259283 return;
260284 }
261285
262
- /* Sort the .orc_unwind and .orc_unwind_ip tables: */
263
- sort(__start_orc_unwind_ip, num_entries, sizeof(int), orc_sort_cmp,
264
- orc_sort_swap);
286
+ /*
287
+ * Note, the orc_unwind and orc_unwind_ip tables were already
288
+ * sorted at build time via the 'sorttable' tool.
289
+ * It's ready for binary search straight away, no need to sort it.
290
+ */
265291
266292 /* Initialize the fast lookup table: */
267293 lookup_num_blocks = orc_lookup_end - orc_lookup;
....@@ -420,8 +446,16 @@
420446 * call instruction itself.
421447 */
422448 orc = orc_find(state->signal ? state->ip : state->ip - 1);
423
- if (!orc)
424
- goto err;
449
+ if (!orc) {
450
+ /*
451
+ * As a fallback, try to assume this code uses a frame pointer.
452
+ * This is useful for generated code, like BPF, which ORC
453
+ * doesn't know about. This is just a guess, so the rest of
454
+ * the unwind is no longer considered reliable.
455
+ */
456
+ orc = &orc_fp_entry;
457
+ state->error = true;
458
+ }
425459
426460 /* End-of-stack check for kernel threads: */
427461 if (orc->sp_reg == ORC_REG_UNDEFINED) {
....@@ -453,38 +487,38 @@
453487
454488 case ORC_REG_R10:
455489 if (!get_reg(state, offsetof(struct pt_regs, r10), &sp)) {
456
- orc_warn("missing regs for base reg R10 at ip %pB\n",
457
- (void *)state->ip);
490
+ orc_warn_current("missing R10 value at %pB\n",
491
+ (void *)state->ip);
458492 goto err;
459493 }
460494 break;
461495
462496 case ORC_REG_R13:
463497 if (!get_reg(state, offsetof(struct pt_regs, r13), &sp)) {
464
- orc_warn("missing regs for base reg R13 at ip %pB\n",
465
- (void *)state->ip);
498
+ orc_warn_current("missing R13 value at %pB\n",
499
+ (void *)state->ip);
466500 goto err;
467501 }
468502 break;
469503
470504 case ORC_REG_DI:
471505 if (!get_reg(state, offsetof(struct pt_regs, di), &sp)) {
472
- orc_warn("missing regs for base reg DI at ip %pB\n",
473
- (void *)state->ip);
506
+ orc_warn_current("missing RDI value at %pB\n",
507
+ (void *)state->ip);
474508 goto err;
475509 }
476510 break;
477511
478512 case ORC_REG_DX:
479513 if (!get_reg(state, offsetof(struct pt_regs, dx), &sp)) {
480
- orc_warn("missing regs for base reg DX at ip %pB\n",
481
- (void *)state->ip);
514
+ orc_warn_current("missing DX value at %pB\n",
515
+ (void *)state->ip);
482516 goto err;
483517 }
484518 break;
485519
486520 default:
487
- orc_warn("unknown SP base reg %d for ip %pB\n",
521
+ orc_warn("unknown SP base reg %d at %pB\n",
488522 orc->sp_reg, (void *)state->ip);
489523 goto err;
490524 }
....@@ -496,7 +530,7 @@
496530
497531 /* Find IP, SP and possibly regs: */
498532 switch (orc->type) {
499
- case ORC_TYPE_CALL:
533
+ case UNWIND_HINT_TYPE_CALL:
500534 ip_p = sp - sizeof(long);
501535
502536 if (!deref_stack_reg(state, ip_p, &state->ip))
....@@ -511,10 +545,10 @@
511545 state->signal = false;
512546 break;
513547
514
- case ORC_TYPE_REGS:
548
+ case UNWIND_HINT_TYPE_REGS:
515549 if (!deref_stack_regs(state, sp, &state->ip, &state->sp)) {
516
- orc_warn("can't dereference registers at %p for ip %pB\n",
517
- (void *)sp, (void *)orig_ip);
550
+ orc_warn_current("can't access registers at %pB\n",
551
+ (void *)orig_ip);
518552 goto err;
519553 }
520554
....@@ -524,10 +558,10 @@
524558 state->signal = true;
525559 break;
526560
527
- case ORC_TYPE_REGS_IRET:
561
+ case UNWIND_HINT_TYPE_REGS_PARTIAL:
528562 if (!deref_stack_iret_regs(state, sp, &state->ip, &state->sp)) {
529
- orc_warn("can't dereference iret registers at %p for ip %pB\n",
530
- (void *)sp, (void *)orig_ip);
563
+ orc_warn_current("can't access iret registers at %pB\n",
564
+ (void *)orig_ip);
531565 goto err;
532566 }
533567
....@@ -539,7 +573,7 @@
539573 break;
540574
541575 default:
542
- orc_warn("unknown .orc_unwind entry type %d for ip %pB\n",
576
+ orc_warn("unknown .orc_unwind entry type %d at %pB\n",
543577 orc->type, (void *)orig_ip);
544578 goto err;
545579 }
....@@ -571,8 +605,8 @@
571605 if (state->stack_info.type == prev_type &&
572606 on_stack(&state->stack_info, (void *)state->sp, sizeof(long)) &&
573607 state->sp <= prev_sp) {
574
- orc_warn("stack going in the wrong direction? ip=%pB\n",
575
- (void *)orig_ip);
608
+ orc_warn_current("stack going in the wrong direction? at %pB\n",
609
+ (void *)orig_ip);
576610 goto err;
577611 }
578612
....@@ -611,7 +645,7 @@
611645 goto the_end;
612646
613647 state->ip = regs->ip;
614
- state->sp = kernel_stack_pointer(regs);
648
+ state->sp = regs->sp;
615649 state->bp = regs->bp;
616650 state->regs = regs;
617651 state->full_regs = true;
....@@ -663,7 +697,7 @@
663697 /* Otherwise, skip ahead to the user-specified starting frame: */
664698 while (!unwind_done(state) &&
665699 (!on_stack(&state->stack_info, first_frame, sizeof(long)) ||
666
- state->sp < (unsigned long)first_frame))
700
+ state->sp <= (unsigned long)first_frame))
667701 unwind_next_frame(state);
668702
669703 return;