Hi Lianbo,
Sorry for the late reply.
On Thu, Apr 22, 2021 at 7:51 AM lijiang <lijiang(a)redhat.com> wrote:
Hi, Vinayak
在 2021年03月31日 00:00, crash-utility-request(a)redhat.com 写道:
> Date: Tue, 30 Mar 2021 19:22:35 +0530
> From: Vinayak Menon <vinayakm.list(a)gmail.com>
> To: crash-utility(a)redhat.com
> Subject: [Crash-utility] [PATCH 2/2] arm64: make crash
> CONFIG_KASAN_HW_TAGS aware
> Message-ID:
> <1617112355-19837-2-git-send-email-vinayakm.list(a)gmail.com>
> Content-Type: text/plain; charset="US-ASCII"
>
> 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(a)gmail.com>
> ---
> 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))
Here, the bit-63 indicates that the addr contains the TAG MASK, which means
the TAG is enabled, right? Or could you please describe more details about
this?
The 63rd bit is checked to make sure that it is indeed a kernel
virtual address. If yes, the
tag mask is ORed to it (0 if tagging not enabled). This is done to
make sure we do not
apply the tag mask on non-kernel addresses.
Thanks,
Vinayak
Other changes are good to me.
Thanks.
Lianbo
> + 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;
> };