Skip to content

Commit

Permalink
[PATCH] arm64: Fix bt command show wrong stacktrace on ramdump source
Browse files Browse the repository at this point in the history
If we use crash to parse ramdump(Qcom phone device) rathen than vmcore.
Start command should be like: crash vmlinux --kaslr=xxx DDRCS0_0.BIN@0x0000000080000000,... --machdep vabits_actual=39
Then We will see bt command show misleading backtrace information below:

crash> bt 16930
PID: 16930    TASK: ffffff89b3eada00  CPU: 2    COMMAND: "Firebase Backgr"
 #0 [ffffffc034c437f0] __switch_to at ffffffe0036832d4
 crash-utility#1 [ffffffc034c43850] __kvm_nvhe_$d.2314 at 6be732e004cf05a0
 crash-utility#2 [ffffffc034c438b0] __kvm_nvhe_$d.2314 at 86c54c6004ceff80
 crash-utility#3 [ffffffc034c43950] __kvm_nvhe_$d.2314 at 55d6f96003a7b120
 crash-utility#4 [ffffffc034c439f0] __kvm_nvhe_$d.2314 at 9ccec46003a80a64
 crash-utility#5 [ffffffc034c43ac0] __kvm_nvhe_$d.2314 at 8cf41e6003a945c4
 crash-utility#6 [ffffffc034c43b10] __kvm_nvhe_$d.2314 at a8f181e00372c818
 crash-utility#7 [ffffffc034c43b40] __kvm_nvhe_$d.2314 at 6dedde600372c0d0
 crash-utility#8 [ffffffc034c43b90] __kvm_nvhe_$d.2314 at 62cc07e00373d0ac
 crash-utility#9 [ffffffc034c43c00] __kvm_nvhe_$d.2314 at 72fb1de00373bedc
...
     PC: 00000073f5294840   LR: 00000070d8f39ba4   SP: 00000070d4afd5d0
    X29: 00000070d4afd600  X28: b4000071efcda7f0  X27: 00000070d4afe000
    X26: 0000000000000000  X25: 00000070d9616000  X24: 0000000000000000
    X23: 0000000000000000  X22: 0000000000000000  X21: 0000000000000000
    X20: b40000728fd27520  X19: b40000728fd27550  X18: 000000702daba000
    X17: 00000073f5294820  X16: 00000070d940f9d8  X15: 00000000000000bf
    X14: 0000000000000000  X13: 00000070d8ad2fac  X12: b40000718fce5040
    X11: 0000000000000000  X10: 0000000000000070   X9: 0000000000000001
     X8: 0000000000000062   X7: 0000000000000020   X6: 0000000000000000
     X5: 0000000000000000   X4: 0000000000000000   X3: 0000000000000000
     X2: 0000000000000002   X1: 0000000000000080   X0: b40000728fd27550
    ORIG_X0: b40000728fd27550  SYSCALLNO: ffffffff  PSTATE: 40001000

By checking the raw data below, will see the lr (fp+8) data show the pointer which already been replaced by PAC prefix.

crash> bt -f
PID: 16930    TASK: ffffff89b3eada00  CPU: 2    COMMAND: "Firebase Backgr"
 #0 [ffffffc034c437f0] __switch_to at ffffffe0036832d4
    ffffffc034c437f0: ffffffc034c43850 6be732e004cf05a4
    ffffffc034c43800: ffffffe006186108 a0ed07e004cf09c4
    ffffffc034c43810: ffffff8a1a340000 ffffff8a8d343c00
    ffffffc034c43820: ffffff89b3eada00 ffffff8b780db540
    ffffffc034c43830: ffffff89b3eada00 0000000000000000
    ffffffc034c43840: 0000000000000004 712b828118484a00
 crash-utility#1 [ffffffc034c43850] __kvm_nvhe_$d.2314 at 6be732e004cf05a0
    ffffffc034c43850: ffffffc034c438b0 86c54c6004ceff84
    ffffffc034c43860: 000000708070f000 ffffffc034c43938
    ffffffc034c43870: ffffff88bd822878 ffffff89b3eada00
...

So we check the CONFIG_ARM64_PTR_AUTH and CONFIG_ARM64_PTR_AUTH_KERNEL to double check if pac mechanism been enabled on this ramdump.
Then we use vabits to figure it out.
Fix then show the right backtrace below:
crash> bt 16930
PID: 16930    TASK: ffffff89b3eada00  CPU: 2    COMMAND: "Firebase Backgr"
 #0 [ffffffc034c437f0] __switch_to at ffffffe0036832d4
 crash-utility#1 [ffffffc034c43850] __schedule at ffffffe004cf05a0
 crash-utility#2 [ffffffc034c438b0] preempt_schedule_common at ffffffe004ceff80
 crash-utility#3 [ffffffc034c43950] unmap_page_range at ffffffe003a7b120
 crash-utility#4 [ffffffc034c439f0] unmap_vmas at ffffffe003a80a64
 crash-utility#5 [ffffffc034c43ac0] exit_mmap at ffffffe003a945c4
 crash-utility#6 [ffffffc034c43b10] __mmput at ffffffe00372c818
 crash-utility#7 [ffffffc034c43b40] mmput at ffffffe00372c0d0
 crash-utility#8 [ffffffc034c43b90] exit_mm at ffffffe00373d0ac
 crash-utility#9 [ffffffc034c43c00] do_exit at ffffffe00373bedc
     PC: 00000073f5294840   LR: 00000070d8f39ba4   SP: 00000070d4afd5d0
    X29: 00000070d4afd600  X28: b4000071efcda7f0  X27: 00000070d4afe000
    X26: 0000000000000000  X25: 00000070d9616000  X24: 0000000000000000
    X23: 0000000000000000  X22: 0000000000000000  X21: 0000000000000000
    X20: b40000728fd27520  X19: b40000728fd27550  X18: 000000702daba000
    X17: 00000073f5294820  X16: 00000070d940f9d8  X15: 00000000000000bf
    X14: 0000000000000000  X13: 00000070d8ad2fac  X12: b40000718fce5040
    X11: 0000000000000000  X10: 0000000000000070   X9: 0000000000000001
     X8: 0000000000000062   X7: 0000000000000020   X6: 0000000000000000
     X5: 0000000000000000   X4: 0000000000000000   X3: 0000000000000000
     X2: 0000000000000002   X1: 0000000000000080   X0: b40000728fd27550
    ORIG_X0: b40000728fd27550  SYSCALLNO: ffffffff  PSTATE: 40001000

Let's use GENMASK to replace the pac pointer to fix it.
gki related commit url here:
https://lore.kernel.org/all/[email protected]/

Signed-off-by: bevis_chen <[email protected]>
  • Loading branch information
bevis_chen committed Jul 3, 2024
1 parent ce4ddc7 commit ec9e35d
Showing 1 changed file with 37 additions and 0 deletions.
37 changes: 37 additions & 0 deletions arm64.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ static void arm64_get_crash_notes(void);
static void arm64_calc_VA_BITS(void);
static int arm64_is_uvaddr(ulong, struct task_context *);
static void arm64_calc_KERNELPACMASK(void);
static void arm64_recalc_KERNELPACMASK(void);
static int arm64_get_vmcoreinfo(unsigned long *vaddr, const char *label, int base);

struct kernel_range {
Expand Down Expand Up @@ -499,6 +500,7 @@ arm64_init(int when)

arm64_get_section_size_bits();


if (!machdep->max_physmem_bits) {
if (arm64_get_vmcoreinfo(&machdep->max_physmem_bits, "NUMBER(MAX_PHYSMEM_BITS)", NUM_DEC)) {
/* nothing */
Expand Down Expand Up @@ -581,6 +583,18 @@ arm64_init(int when)
if (!machdep->hz)
machdep->hz = 100;

/*
* In the case of using ramdump rather than vmcore,
* Will fail to parse out KERNELPAC.
* So let's try again from kconfig to ensure if PAC enabled.
* If yes, then we use vabits to figure it out.
* gki related commit url:
* https://lore.kernel.org/all/[email protected]/
*/
if(!machdep->machspec->CONFIG_ARM64_KERNELPACMASK)
arm64_recalc_KERNELPACMASK();


arm64_irq_stack_init();
arm64_overflow_stack_init();
arm64_stackframe_init();
Expand Down Expand Up @@ -4910,6 +4924,7 @@ arm64_swp_offset(ulong pte)
return pte;
}


static void arm64_calc_KERNELPACMASK(void)
{
ulong value;
Expand All @@ -4921,6 +4936,28 @@ static void arm64_calc_KERNELPACMASK(void)
}
}


#define GENMASK_UL(h, l) \
(((~0UL) << (l)) & (~0UL >> (BITS_PER_LONG - 1 - (h))))

static void arm64_recalc_KERNELPACMASK(void){
int ret = IKCONFIG_N;

if (kt->ikconfig_flags & IKCONFIG_AVAIL){
/* arm64: check pac already enabled yet.*/
if ((ret = get_kernel_config("CONFIG_ARM64_PTR_AUTH", NULL)) == IKCONFIG_Y
&& (ret = get_kernel_config("CONFIG_ARM64_PTR_AUTH_KERNEL", NULL)) == IKCONFIG_Y){
if (machdep->machspec->VA_BITS_ACTUAL){
machdep->machspec->CONFIG_ARM64_KERNELPACMASK =
GENMASK_UL(63, machdep->machspec->VA_BITS_ACTUAL);
if (CRASHDEBUG(1))
fprintf(fp, "CONFIG_ARM64_KERNELPACMASK: %lx\n",
machdep->machspec->CONFIG_ARM64_KERNELPACMASK);
}
}
}
}

#endif /* ARM64 */


0 comments on commit ec9e35d

Please sign in to comment.