With CONFIG_KASAN_HW_TAGS enabled kvaddr can be tagged and this results in readmem, vtop etc. fail like below. " please wait... (gathering kmem slab cache data) crash: invalid kernel virtual address: f0ffff878000201c type: "kmem_cache objsize/object_size" crash: get_active_set: no tasks found? please wait... (gathering task table data) crash: invalid kernel virtual address: f1ffff87f51e3530 type: "xa_node shift" " Make the mask introduced for pointer authentication generic and use it in vtop and kvaddr validation. Signed-off-by: Vinayak Menon <vinayakm.list@xxxxxxxxx> --- arm64.c | 50 +++++++++++++++++++++++++++++++------------------- defs.h | 2 +- 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/arm64.c b/arm64.c index 5b59972..bb41cbb 100644 --- a/arm64.c +++ b/arm64.c @@ -85,7 +85,8 @@ static int arm64_get_kvaddr_ranges(struct vaddr_range *); 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 int arm64_is_kvaddr(ulong); +static void arm64_calc_KERNELTAGMASK(void); /* @@ -215,7 +216,7 @@ arm64_init(int when) machdep->pagemask = ~((ulonglong)machdep->pageoffset); arm64_calc_VA_BITS(); - arm64_calc_KERNELPACMASK(); + arm64_calc_KERNELTAGMASK(); ms = machdep->machspec; if (ms->VA_BITS_ACTUAL) { ms->page_offset = ARM64_PAGE_OFFSET_ACTUAL; @@ -228,7 +229,7 @@ arm64_init(int when) machdep->kvbase = ARM64_VA_START; ms->userspace_top = ARM64_USERSPACE_TOP; } - machdep->is_kvaddr = generic_is_kvaddr; + machdep->is_kvaddr = arm64_is_kvaddr; machdep->kvtop = arm64_kvtop; if (machdep->flags & NEW_VMEMMAP) { struct syment *sp; @@ -477,7 +478,7 @@ arm64_init(int when) case LOG_ONLY: machdep->machspec = &arm64_machine_specific; arm64_calc_VA_BITS(); - arm64_calc_KERNELPACMASK(); + arm64_calc_KERNELTAGMASK(); arm64_calc_phys_offset(); machdep->machspec->page_offset = ARM64_PAGE_OFFSET; arm64_calc_physvirt_offset(); @@ -608,7 +609,7 @@ arm64_dump_machdep_table(ulong arg) fprintf(fp, " dis_filter: arm64_dis_filter()\n"); fprintf(fp, " cmd_mach: arm64_cmd_mach()\n"); fprintf(fp, " get_smp_cpus: arm64_get_smp_cpus()\n"); - fprintf(fp, " is_kvaddr: generic_is_kvaddr()\n"); + fprintf(fp, " is_kvaddr: arm64_is_kvaddr()\n"); fprintf(fp, " is_uvaddr: arm64_is_uvaddr()\n"); fprintf(fp, " value_to_symbol: generic_machdep_value_to_symbol()\n"); fprintf(fp, " init_kernel_pgd: arm64_init_kernel_pgd\n"); @@ -668,9 +669,9 @@ arm64_dump_machdep_table(ulong arg) fprintf(fp, "%ld\n", ms->VA_BITS_ACTUAL); else fprintf(fp, "(unused)\n"); - fprintf(fp, "CONFIG_ARM64_KERNELPACMASK: "); - if (ms->CONFIG_ARM64_KERNELPACMASK) - fprintf(fp, "%lx\n", ms->CONFIG_ARM64_KERNELPACMASK); + fprintf(fp, "CONFIG_ARM64_KERNELTAGMASK: "); + if (ms->CONFIG_ARM64_KERNELTAGMASK) + fprintf(fp, "%lx\n", ms->CONFIG_ARM64_KERNELTAGMASK); else fprintf(fp, "(unused)\n"); fprintf(fp, " userspace_top: %016lx\n", ms->userspace_top); @@ -1208,6 +1209,9 @@ arm64_kvtop(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbos if (!IS_KVADDR(kvaddr)) return FALSE; + if (kvaddr & (1UL << 63)) + kvaddr |= machdep->machspec->CONFIG_ARM64_KERNELTAGMASK; + if (!vt->vmalloc_start) { *paddr = VTOP(kvaddr); return TRUE; @@ -1828,7 +1832,7 @@ arm64_is_kernel_exception_frame(struct bt_info *bt, ulong stkptr) if (INSTACK(regs->sp, bt) && INSTACK(regs->regs[29], bt) && !(regs->pstate & (0xffffffff00000000ULL | PSR_MODE32_BIT)) && is_kernel_text(regs->pc) && - is_kernel_text(regs->regs[30] | ms->CONFIG_ARM64_KERNELPACMASK)) { + is_kernel_text(regs->regs[30] | ms->CONFIG_ARM64_KERNELTAGMASK)) { switch (regs->pstate & PSR_MODE_MASK) { case PSR_MODE_EL1t: @@ -2198,8 +2202,8 @@ arm64_unwind_frame(struct bt_info *bt, struct arm64_stackframe *frame) frame->sp = fp + 0x10; frame->fp = GET_STACK_ULONG(fp); frame->pc = GET_STACK_ULONG(fp + 8); - if (is_kernel_text(frame->pc | ms->CONFIG_ARM64_KERNELPACMASK)) - frame->pc |= ms->CONFIG_ARM64_KERNELPACMASK; + if (is_kernel_text(frame->pc | ms->CONFIG_ARM64_KERNELTAGMASK)) + frame->pc |= ms->CONFIG_ARM64_KERNELTAGMASK; if ((frame->fp == 0) && (frame->pc == 0)) return FALSE; @@ -2869,8 +2873,8 @@ arm64_print_text_symbols(struct bt_info *bt, struct arm64_stackframe *frame, FIL for (i = (start - bt->stackbase)/sizeof(ulong); i < LONGS_PER_STACK; i++) { up = (ulong *)(&bt->stackbuf[i*sizeof(ulong)]); val = *up; - if (is_kernel_text(val | ms->CONFIG_ARM64_KERNELPACMASK)) { - val |= ms->CONFIG_ARM64_KERNELPACMASK; + if (is_kernel_text(val | ms->CONFIG_ARM64_KERNELTAGMASK)) { + val |= ms->CONFIG_ARM64_KERNELTAGMASK; name = closest_symbol(val); fprintf(ofp, " %s[%s] %s at %lx", bt->flags & BT_ERROR_MASK ? @@ -3205,8 +3209,8 @@ arm64_print_exception_frame(struct bt_info *bt, ulong pt_regs, int mode, FILE *o rows = 4; } else { LR = regs->regs[30]; - if (is_kernel_text (LR | ms->CONFIG_ARM64_KERNELPACMASK)) - LR |= ms->CONFIG_ARM64_KERNELPACMASK; + if (is_kernel_text (LR | ms->CONFIG_ARM64_KERNELTAGMASK)) + LR |= ms->CONFIG_ARM64_KERNELTAGMASK; SP = regs->sp; top_reg = 29; is_64_bit = TRUE; @@ -4102,6 +4106,14 @@ arm64_calc_virtual_memory_ranges(void) } static int +arm64_is_kvaddr(ulong addr) +{ + if (addr & (1UL << 63)) + addr |= machdep->machspec->CONFIG_ARM64_KERNELTAGMASK; + return generic_is_kvaddr(addr); +} + +static int arm64_is_uvaddr(ulong addr, struct task_context *tc) { return (addr < machdep->machspec->userspace_top); @@ -4129,21 +4141,21 @@ arm64_swp_offset(ulong pte) return pte; } -static void arm64_calc_KERNELPACMASK(void) +static void arm64_calc_KERNELTAGMASK(void) { ulong value = 0; char *string; - if ((string = pc->read_vmcoreinfo("NUMBER(KERNELPACMASK)"))) { + if ((string = pc->read_vmcoreinfo("NUMBER(KERNELTAGMASK)"))) { value = htol(string, QUIET, NULL); free(string); } else if (machdep->machspec->tag_mask) { value = machdep->machspec->tag_mask; } - machdep->machspec->CONFIG_ARM64_KERNELPACMASK = value; + machdep->machspec->CONFIG_ARM64_KERNELTAGMASK = value; if (CRASHDEBUG(1)) - fprintf(fp, "CONFIG_ARM64_KERNELPACMASK: %lx\n", value); + fprintf(fp, "CONFIG_ARM64_KERNELTAGMASK: %lx\n", value); } #endif /* ARM64 */ diff --git a/defs.h b/defs.h index d406f5f..770c335 100644 --- a/defs.h +++ b/defs.h @@ -3329,7 +3329,7 @@ struct machine_specific { ulong VA_BITS_ACTUAL; ulong CONFIG_ARM64_VA_BITS; ulong VA_START; - ulong CONFIG_ARM64_KERNELPACMASK; + ulong CONFIG_ARM64_KERNELTAGMASK; ulong physvirt_offset; ulong tag_mask; }; -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://listman.redhat.com/mailman/listinfo/crash-utility