[Crash-utility] [PATCH 2/2] arm64: make crash CONFIG_KASAN_HW_TAGS aware

lijiang lijiang at redhat.com
Thu Apr 22 02:20:51 UTC 2021


Hi, Vinayak
在 2021年03月31日 00:00, crash-utility-request at redhat.com 写道:
> Date: Tue, 30 Mar 2021 19:22:35 +0530
> From: Vinayak Menon <vinayakm.list at gmail.com>
> To: crash-utility at 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 at 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 at 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?

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;
>  };




More information about the Crash-utility mailing list