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 <[email protected]>
---
 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
[email protected]
https://listman.redhat.com/mailman/listinfo/crash-utility

Reply via email to