Skip to content

Commit

Permalink
x86_64: Add Linux 5.8+ exception functions to check exception frame
Browse files Browse the repository at this point in the history
Fix for 'bt' command and options on Linux 5.8-rc1 and later kernels
that contain merge commit 076f14be7fc942e112c94c841baec44124275cd0.
The merged patches changed the name of exception functions that
have been used by the crash utility to check the exception frame.
Without the patch, the command and options cannot display it.

Before:
  crash> bt
  PID: 8752   TASK: ffff8f80cb244380  CPU: 2   COMMAND: "insmod"
   #0 [ffffa3e40187f9f8] machine_kexec at ffffffffab25d267
   #1 [ffffa3e40187fa48] __crash_kexec at ffffffffab38e2ed
   #2 [ffffa3e40187fb10] crash_kexec at ffffffffab38f1dd
   #3 [ffffa3e40187fb28] oops_end at ffffffffab222cbd
   #4 [ffffa3e40187fb48] do_trap at ffffffffab21fea1
   #5 [ffffa3e40187fb90] do_error_trap at ffffffffab21ff75
   #6 [ffffa3e40187fbd0] exc_invalid_op at ffffffffabb76a2c
   #7 [ffffa3e40187fbf0] asm_exc_invalid_op at ffffffffabc00a72
   #8 [ffffa3e40187fc78] init_module at ffffffffc042b018 [invalid]
   #9 [ffffa3e40187fca0] init_module at ffffffffc042b018 [invalid]
  #10 [ffffa3e40187fca8] do_one_initcall at ffffffffab202806
  #11 [ffffa3e40187fd18] do_init_module at ffffffffab3888ba
  #12 [ffffa3e40187fd38] load_module at ffffffffab38afde

After:
  crash> bt
  PID: 8752   TASK: ffff8f80cb244380  CPU: 2   COMMAND: "insmod"
   #0 [ffffa3e40187f9f8] machine_kexec at ffffffffab25d267
   #1 [ffffa3e40187fa48] __crash_kexec at ffffffffab38e2ed
   #2 [ffffa3e40187fb10] crash_kexec at ffffffffab38f1dd
   #3 [ffffa3e40187fb28] oops_end at ffffffffab222cbd
   #4 [ffffa3e40187fb48] do_trap at ffffffffab21fea1
   #5 [ffffa3e40187fb90] do_error_trap at ffffffffab21ff75
   #6 [ffffa3e40187fbd0] exc_invalid_op at ffffffffabb76a2c
   #7 [ffffa3e40187fbf0] asm_exc_invalid_op at ffffffffabc00a72
      [exception RIP: init_module+24]
      RIP: ffffffffc042b018  RSP: ffffa3e40187fca8  RFLAGS: 00010246
      RAX: 000000000000001c  RBX: 0000000000000000  RCX: 0000000000000000
      RDX: 0000000000000000  RSI: ffff8f80fbd18000  RDI: ffff8f80fbd18000
      RBP: ffffffffc042b000   R8: 000000000000029d   R9: 000000000000002c
      R10: 0000000000000000  R11: ffffa3e40187fb58  R12: ffffffffc042d018
      R13: ffffa3e40187fdf0  R14: ffffffffc042d000  R15: ffffa3e40187fe90
      ORIG_RAX: ffffffffffffffff  CS: 0010  SS: 0018
   #8 [ffffa3e40187fca0] init_module at ffffffffc042b018 [invalid]
   #9 [ffffa3e40187fca8] do_one_initcall at ffffffffab202806
  #10 [ffffa3e40187fd18] do_init_module at ffffffffab3888ba
  #11 [ffffa3e40187fd38] load_module at ffffffffab38afde

Signed-off-by: Kazuhito Hagio <[email protected]>
  • Loading branch information
k-hagio committed Apr 16, 2021
1 parent 506da42 commit 6c04376
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 3 deletions.
1 change: 1 addition & 0 deletions defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -6026,6 +6026,7 @@ struct machine_specific {
ulong cpu_entry_area_start;
ulong cpu_entry_area_end;
ulong page_offset_force;
char **exception_functions;
};

#define KSYMS_START (0x1)
Expand Down
43 changes: 40 additions & 3 deletions x86_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ static void orc_dump(ulong);

struct machine_specific x86_64_machine_specific = { 0 };

static const char *exception_functions_orig[];
static const char *exception_functions_5_8[];

/*
* Do all necessary machine-specific setup here. This is called several
* times during initialization.
Expand Down Expand Up @@ -735,6 +738,12 @@ x86_64_init(int when)
STRUCT_SIZE_INIT(percpu_data, "percpu_data");

GART_init();

if (kernel_symbol_exists("asm_exc_divide_error"))
machdep->machspec->exception_functions = (char **)exception_functions_5_8;
else
machdep->machspec->exception_functions = (char **)exception_functions_orig;

break;

case POST_VM:
Expand Down Expand Up @@ -1104,6 +1113,12 @@ x86_64_dump_machdep_table(ulong arg)
fprintf(fp, "%016lx\n", (ulong)ms->cpu_entry_area_end);
else
fprintf(fp, "(unused)\n");

fprintf(fp, " excpetion_functions: ");
if (ms->exception_functions == (char **)exception_functions_5_8)
fprintf(fp, "excpetion_functions_5_8\n");
else
fprintf(fp, "excpetion_functions_orig\n");
}

/*
Expand Down Expand Up @@ -3086,7 +3101,7 @@ text_lock_function(char *name, struct bt_info *bt, ulong locktext)
* zeroentry xen_debug do_debug
* zeroentry xen_int3 do_int3
*/
static const char *exception_functions[] = {
static const char *exception_functions_orig[] = {
"invalid_TSS",
"segment_not_present",
"alignment_check",
Expand All @@ -3109,6 +3124,28 @@ static const char *exception_functions[] = {
NULL,
};

static const char *exception_functions_5_8[] = {
"asm_exc_invalid_tss",
"asm_exc_segment_not_present",
"asm_exc_alignment_check",
"asm_exc_general_protection",
"asm_exc_page_fault",
"asm_exc_divide_error",
"asm_exc_overflow",
"asm_exc_bounds",
"asm_exc_invalid_op",
"asm_exc_device_not_available",
"asm_exc_coproc_segment_overrun",
"asm_exc_spurious_interrupt_bug",
"asm_exc_coprocessor_error",
"asm_exc_simd_coprocessor_error",
"asm_exc_debug",
"xen_asm_exc_stack_segment",
"xen_asm_exc_xen_hypervisor_callback",
"xen_asm_exc_int3",
NULL,
};

/*
* print one entry of a stack trace
*/
Expand Down Expand Up @@ -3185,8 +3222,8 @@ x86_64_print_stack_entry(struct bt_info *bt, FILE *ofp, int level,
if ((THIS_KERNEL_VERSION >= LINUX(2,6,29)) &&
(eframe_check == -1) && offset &&
!(bt->flags & (BT_EXCEPTION_FRAME|BT_START|BT_SCHEDULE))) {
for (i = 0; exception_functions[i]; i++) {
if (STREQ(name, exception_functions[i])) {
for (i = 0; machdep->machspec->exception_functions[i]; i++) {
if (STREQ(name, machdep->machspec->exception_functions[i])) {
eframe_check = 8;
break;
}
Expand Down

0 comments on commit 6c04376

Please sign in to comment.