[Crash-utility] [PATCH v5] arm64: fix kernel memory map handling for kaslr-enabled

AKASHI Takahiro takahiro.akashi at linaro.org
Tue Jun 14 05:47:02 UTC 2016


Dave,

On Mon, Jun 13, 2016 at 04:06:22PM -0400, Dave Anderson wrote:
> 
> 
> ----- Original Message -----
> > In my next version of kdump patch, the following VMCOREINFO will be
> > added:
> >     NUMBER(VA_BITS)
> >     NUMBER(kimage_voffset)
> >     NUMBER(PHYS_OFFSET)
> >     KERNELOFFSET

Is "KERNELOFFSET" useful for arm64?
As you said, this value is used as a trigger of KASLR_CHECK,
but the current kernel doesn't have "randomize_modules".

Thanks,
-Takahiro AKASHI

> > I think that those will also satisfy mkdumpfile requirements.
> >         -> Pratyush
> > 
> > Thanks,
> > -Takahiro AKASHI
> 
>   
> Hi Takahiro,
> 
> This patch looks good.  From my end, I'm pretty much ready to check 
> it in, notwithstanding the lack of live system KASLR support.  And 
> even in that case, a live system with KASLR enabled could be brought
> up with --machdep arguments for now.
> 
> One minor nit:
> 
>   $ make warn
>   ...
>   arm64.c: In function 'arm64_kdump_phys_base':
>   arm64.c:814:2: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
>     if (string = pc->read_vmcoreinfo("NUMBER(PHYS_OFFSET)")) {
>     ^
>   ...
> 
> And speaking of arm64_kdump_phys_base(), I do have a question about the 3 FALSE returns:
> 
> @@ -720,7 +807,32 @@ arm64_calc_phys_offset(void)
>  static int
>  arm64_kdump_phys_base(ulong *phys_offset)
>  {
> -        return arm_kdump_phys_base(phys_offset);
> +        char *string;
> +        struct syment *sp;
> +        physaddr_t paddr;
> +
> +        if (string = pc->read_vmcoreinfo("NUMBER(PHYS_OFFSET)")) {
> +                *phys_offset = htol(string, QUIET, NULL);
> +                free(string);
> +                return TRUE;
> +        }
> +
> +        if (machdep->flags & NEW_VMEMMAP) {
> +                if (!(sp = kernel_symbol_search("memstart_addr")))
> +                        return FALSE;
> +
> +                /* sanity check */
> +                if (!machdep->machspec->kimage_voffset)
> +                        return FALSE;
> 
> How could NEW_VMEMMAP possibly be set if !machdep->machspec->kimage_voffset?
> 
> +
> +                paddr =        sp->value - machdep->machspec->kimage_voffset;
> +                if (READMEM(-1, phys_offset, sizeof(*phys_offset),
> +                                sp->value, paddr) > 0)
> +                        return TRUE;
> +                else
> +                        return FALSE;
> +        } else
> +                return arm_kdump_phys_base(phys_offset);
>  }
>  
> But regardless whether the "sanity check" needs to be made, shouldn't 
> all 3 of the FALSE returns above alternatively allow arm_kdump_phys_base()
> to go ahead with its PT_LOAD segment check?  
> 
> In any case, do you have anything else you would like to add to it?
> 
> Thanks,
>   Dave
> 
>  
> > changes in v5:
> > * Calcs PHYS_OFFSET by reading VMCOREINFO, "NUMBER(PHYS_OFFSET)"
> >   "memstart_addr"-based routine was also moved into arm64_calc_phys_base().
> > 
> > changes in v4:
> > * Fixed VA_BITS calculation for v4.5 or earlier
> > * Added 4-level address translation with 4KB page size
> > * Removed "fix a renaming of a member of struct page, _count to _refcount"
> > 
> > Chnages in v3:
> > * Refined KASLR handling
> >   hopefully the tool works even on a live system if CONFIG_RANDOMIZE_RAM is
> >   not configured
> > * Fixed a renaming of a member of struct page
> > * Removed a commit message regarding an issue of backtracing a panic'ed task
> >   because this is not a bug in this tool, but my kdump patch's.
> > * Reported "kmem <vmalloc addr>" issue in a commit message
> > 
> > changes in v2:
> > * Fixed build warnings
> > * Moved ARM64_NEW_VMEMMAP to machdep->flags
> > * Show additional kaslr-related parameters in arm64_dump_machdep_table()
> > * Handle a VMCOREINFO, "NUMBER(kimage_voffset)"
> > 
> > ======8<======
> > >From a6dd9d73120dcc3f2d68dbe9a8f2d16a128c4002 Mon Sep 17 00:00:00 2001
> > From: AKASHI Takahiro <takahiro.akashi at linaro.org>
> > Date: Mon, 16 May 2016 17:31:55 +0900
> > Subject: [PATCH v5] arm64: fix kernel memory map handling for kaslr-enabled
> >  kernel
> > 
> > In kernel v4.6, Kernel ASLR (KASLR) is supported on arm64, and the start
> > address of the kernel image can be randomized if CONFIG_RANDOMIZE_BASE is
> > enabled.
> > Even worse, the kernel image is no more mapped in the linear mapping, but
> > in vmalloc area (i.e. below PAGE_OFFSET).
> > 
> > Now, according to the kernel's memory.h, converting a virtual address to
> > a physical address should be done like below:
> > 
> > 	phys_addr_t __x = (phys_addr_t)(x);                             \
> > 	__x & BIT(VA_BITS - 1) ? (__x & ~PAGE_OFFSET) + PHYS_OFFSET :   \
> > 				 (__x - kimage_voffset); })
> > 
> > Please note that PHYS_OFFSET is no more equal to the start address of
> > the first usable memory block in SYSTEM RAM due to the fact mentioned
> > above.
> > 
> > This patch addresses this change and allows the crash utility to access
> > memory contents with correct addresses.
> > 
> > * On a live system, crash with this patch won't work, especially
> >   with CONFIG_RANDOMIZE_BASE configured, because we currently have no way
> >   to know kimage_voffset.
> > 
> > * For a core dump file, we can do simply:
> >        $ crash <vmlinux> <vmcore>
> >   as long as the file has "NUMBER(kimage_voffset)"
> >   (RELOC_AUTO|KASLR is automatically set.)
> > 
> > Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
> > ---
> >  arm64.c   | 232
> >  ++++++++++++++++++++++++++++++++++++++++++++++++--------------
> >  defs.h    |  26 ++++---
> >  main.c    |   7 +-
> >  symbols.c |  12 ++--
> >  4 files changed, 211 insertions(+), 66 deletions(-)
> > 
> > diff --git a/arm64.c b/arm64.c
> > index 86ec348..37524c8 100644
> > --- a/arm64.c
> > +++ b/arm64.c
> > @@ -73,6 +73,23 @@ static int arm64_get_crash_notes(void);
> >  static void arm64_calc_VA_BITS(void);
> >  static int arm64_is_uvaddr(ulong, struct task_context *);
> >  
> > +ulong
> > +arm64_VTOP(ulong addr)
> > +{
> > +	if (machdep->flags & NEW_VMEMMAP) {
> > +		if (addr >= machdep->machspec->page_offset)
> > +			return machdep->machspec->phys_offset
> > +				+ (addr - machdep->machspec->page_offset);
> > +		else if (machdep->machspec->kimage_voffset)
> > +			return addr - machdep->machspec->kimage_voffset;
> > +		else /* no randomness */
> > +			return machdep->machspec->phys_offset
> > +				+ (addr - machdep->machspec->vmalloc_start_addr);
> > +	} else {
> > +		return machdep->machspec->phys_offset
> > +			+ (addr - machdep->machspec->page_offset);
> > +	}
> > +}
> >  
> >  /*
> >   * Do all necessary machine-specific setup here. This is called several
> >   times
> > @@ -82,6 +99,7 @@ void
> >  arm64_init(int when)
> >  {
> >  	ulong value;
> > +	char *string;
> >  	struct machine_specific *ms;
> >  
> >  #if defined(__x86_64__)
> > @@ -103,9 +121,32 @@ arm64_init(int when)
> >  		if (machdep->cmdline_args[0])
> >  			arm64_parse_cmdline_args();
> >  		machdep->flags |= MACHDEP_BT_TEXT;
> > +
> > +		ms = machdep->machspec;
> > +		if (!ms->kimage_voffset &&
> > +		    (string = pc->read_vmcoreinfo("NUMBER(kimage_voffset)"))) {
> > +			ms->kimage_voffset = htol(string, QUIET, NULL);
> > +			free(string);
> > +		}
> > +
> > +		if (ms->kimage_voffset) {
> > +			machdep->flags |= NEW_VMEMMAP;
> > +
> > +			/*
> > +			 * Even if CONFIG_RANDOMIZE_BASE is not configured,
> > +			 * derive_kaslr_offset() should work and set
> > +			 * kt->relocate to 0
> > +			 */
> > +			if (!kt->relocate && !(kt->flags2 & (RELOC_AUTO|KASLR)))
> > +				kt->flags2 |= (RELOC_AUTO|KASLR);
> > +		}
> > +
> >  		break;
> >  
> >  	case PRE_GDB:
> > +		if (kernel_symbol_exists("kimage_voffset"))
> > +			machdep->flags |= NEW_VMEMMAP;
> > +
> >  		if (!machdep->pagesize) {
> >  			/*
> >  			 * Kerneldoc Documentation/arm64/booting.txt describes
> > @@ -161,16 +202,34 @@ arm64_init(int when)
> >  		machdep->pagemask = ~((ulonglong)machdep->pageoffset);
> >  
> >  		arm64_calc_VA_BITS();
> > -		machdep->machspec->page_offset = ARM64_PAGE_OFFSET;
> > +		ms = machdep->machspec;
> > +		ms->page_offset = ARM64_PAGE_OFFSET;
> >  		machdep->identity_map_base = ARM64_PAGE_OFFSET;
> > -		machdep->machspec->userspace_top = ARM64_USERSPACE_TOP;
> > -		machdep->machspec->modules_vaddr = ARM64_MODULES_VADDR;
> > -		machdep->machspec->modules_end = ARM64_MODULES_END;
> > -		machdep->machspec->vmalloc_start_addr = ARM64_VMALLOC_START;
> > -		machdep->machspec->vmalloc_end = ARM64_VMALLOC_END;
> > -		machdep->kvbase = ARM64_VMALLOC_START;
> > -		machdep->machspec->vmemmap_vaddr = ARM64_VMEMMAP_VADDR;
> > -		machdep->machspec->vmemmap_end = ARM64_VMEMMAP_END;
> > +		machdep->kvbase = ARM64_VA_START;
> > +		ms->userspace_top = ARM64_USERSPACE_TOP;
> > +		if (machdep->flags & NEW_VMEMMAP) {
> > +			struct syment *sp;
> > +
> > +			sp = kernel_symbol_search("_text");
> > +			ms->kimage_text = (sp ? sp->value : 0);
> > +			sp = kernel_symbol_search("_end");
> > +			ms->kimage_end = (sp ? sp->value : 0);
> > +
> > +			ms->modules_vaddr = ARM64_VA_START;
> > +			if (kernel_symbol_exists("kasan_init"))
> > +				ms->modules_vaddr += ARM64_KASAN_SHADOW_SIZE;
> > +			ms->modules_end = ms->modules_vaddr
> > +						+ ARM64_MODULES_VSIZE -1;
> > +
> > +			ms->vmalloc_start_addr = ms->modules_end + 1;
> > +		} else {
> > +			ms->modules_vaddr = ARM64_PAGE_OFFSET - MEGABYTES(64);
> > +			ms->modules_end = ARM64_PAGE_OFFSET - 1;
> > +			ms->vmalloc_start_addr = ARM64_VA_START;
> > +		}
> > +		ms->vmalloc_end = ARM64_VMALLOC_END;
> > +		ms->vmemmap_vaddr = ARM64_VMEMMAP_VADDR;
> > +		ms->vmemmap_end = ARM64_VMEMMAP_END;
> >  
> >  		switch (machdep->pagesize)
> >  		{
> > @@ -241,8 +300,6 @@ arm64_init(int when)
> >  		machdep->stacksize = ARM64_STACK_SIZE;
> >  		machdep->flags |= VMEMMAP;
> >  
> > -		arm64_calc_phys_offset();
> > -
> >  		machdep->uvtop = arm64_uvtop;
> >  		machdep->kvtop = arm64_kvtop;
> >  		machdep->is_kvaddr = generic_is_kvaddr;
> > @@ -271,6 +328,10 @@ arm64_init(int when)
> >  		machdep->dumpfile_init = NULL;
> >  		machdep->verify_line_number = NULL;
> >  		machdep->init_kernel_pgd = arm64_init_kernel_pgd;
> > +
> > +		/* use machdep parameters */
> > +		arm64_calc_phys_offset();
> > +
> >  		break;
> >  
> >  	case POST_GDB:
> > @@ -420,6 +481,8 @@ arm64_dump_machdep_table(ulong arg)
> >  		fprintf(fp, "%sIRQ_STACKS", others++ ? "|" : "");
> >  	if (machdep->flags & MACHDEP_BT_TEXT)
> >  		fprintf(fp, "%sMACHDEP_BT_TEXT", others++ ? "|" : "");
> > +	if (machdep->flags & NEW_VMEMMAP)
> > +		fprintf(fp, "%sNEW_VMEMMAP", others++ ? "|" : "");
> >  	fprintf(fp, ")\n");
> >  
> >  	fprintf(fp, "              kvbase: %lx\n", machdep->kvbase);
> > @@ -524,6 +587,11 @@ arm64_dump_machdep_table(ulong arg)
> >  	fprintf(fp, "           modules_end: %016lx\n", ms->modules_end);
> >  	fprintf(fp, "         vmemmap_vaddr: %016lx\n", ms->vmemmap_vaddr);
> >  	fprintf(fp, "           vmemmap_end: %016lx\n", ms->vmemmap_end);
> > +	if (machdep->flags & NEW_VMEMMAP) {
> > +		fprintf(fp, "           kimage_text: %016lx\n", ms->kimage_text);
> > +		fprintf(fp, "            kimage_end: %016lx\n", ms->kimage_end);
> > +		fprintf(fp, "        kimage_voffset: %016lx\n", ms->kimage_voffset);
> > +	}
> >  	fprintf(fp, "           phys_offset: %lx\n", ms->phys_offset);
> >  	fprintf(fp, "__exception_text_start: %lx\n", ms->__exception_text_start);
> >  	fprintf(fp, "  __exception_text_end: %lx\n", ms->__exception_text_end);
> > @@ -566,6 +634,42 @@ arm64_dump_machdep_table(ulong arg)
> >  	}
> >  }
> >  
> > +static int
> > +arm64_parse_machdep_arg_l(char *argstring, char *param, ulong *value)
> > +{
> > +	int len;
> > +	int megabytes = FALSE;
> > +	char *p;
> > +
> > +	len = strlen(param);
> > +	if (!STRNEQ(argstring, param) || (argstring[len] != '='))
> > +		return FALSE;
> > +
> > +	if ((LASTCHAR(argstring) == 'm') ||
> > +	    (LASTCHAR(argstring) == 'M')) {
> > +		LASTCHAR(argstring) = NULLCHAR;
> > +		megabytes = TRUE;
> > +	}
> > +
> > +	p = argstring + len + 1;
> > +	if (strlen(p)) {
> > +		int flags = RETURN_ON_ERROR | QUIET;
> > +		int err = 0;
> > +
> > +		if (megabytes) {
> > +			*value = dtol(p, flags, &err);
> > +			if (!err)
> > +				*value = MEGABYTES(*value);
> > +		} else {
> > +			*value = htol(p, flags, &err);
> > +		}
> > +
> > +		if (!err)
> > +			return TRUE;
> > +	}
> > +
> > +	return FALSE;
> > +}
> >  
> >  /*
> >   * Parse machine dependent command line arguments.
> > @@ -577,11 +681,10 @@ arm64_dump_machdep_table(ulong arg)
> >  static void
> >  arm64_parse_cmdline_args(void)
> >  {
> > -	int index, i, c, err;
> > +	int index, i, c;
> >  	char *arglist[MAXARGS];
> >  	char buf[BUFSIZE];
> >  	char *p;
> > -	ulong value = 0;
> >  
> >  	for (index = 0; index < MAX_MACHDEP_ARGS; index++) {
> >  		if (!machdep->cmdline_args[index])
> > @@ -603,39 +706,23 @@ arm64_parse_cmdline_args(void)
> >  		c = parse_line(buf, arglist);
> >  
> >  		for (i = 0; i < c; i++) {
> > -			err = 0;
> > -
> > -			if (STRNEQ(arglist[i], "phys_offset=")) {
> > -				int megabytes = FALSE;
> > -				int flags = RETURN_ON_ERROR | QUIET;
> > -
> > -				if ((LASTCHAR(arglist[i]) == 'm') ||
> > -				    (LASTCHAR(arglist[i]) == 'M')) {
> > -					LASTCHAR(arglist[i]) = NULLCHAR;
> > -					megabytes = TRUE;
> > -				}
> > -
> > -				p = arglist[i] + strlen("phys_offset=");
> > -				if (strlen(p)) {
> > -					if (megabytes)
> > -						value = dtol(p, flags, &err);
> > -					else
> > -						value = htol(p, flags, &err);
> > -				}
> > -
> > -				if (!err) {
> > -					if (megabytes)
> > -						value = MEGABYTES(value);
> > -
> > -					machdep->machspec->phys_offset = value;
> > -
> > -					error(NOTE,
> > -					    "setting phys_offset to: 0x%lx\n\n",
> > -						machdep->machspec->phys_offset);
> > +			if (arm64_parse_machdep_arg_l(arglist[i],
> > +					"phys_offset",
> > +					&machdep->machspec->phys_offset)) {
> > +				error(NOTE,
> > +					"setting phys_offset to: 0x%lx\n\n",
> > +					machdep->machspec->phys_offset);
> > +
> > +				machdep->flags |= PHYS_OFFSET;
> > +				continue;
> > +			} else if (arm64_parse_machdep_arg_l(arglist[i],
> > +					"kimage_voffset",
> > +					&machdep->machspec->kimage_voffset)) {
> > +				error(NOTE,
> > +					"setting kimage_voffset to: 0x%lx\n\n",
> > +					machdep->machspec->kimage_voffset);
> >  
> > -					machdep->flags |= PHYS_OFFSET;
> > -					continue;
> > -				}
> > +				continue;
> >  			}
> >  
> >  			error(WARNING, "ignoring --machdep option: %s\n",
> > @@ -720,7 +807,32 @@ arm64_calc_phys_offset(void)
> >  static int
> >  arm64_kdump_phys_base(ulong *phys_offset)
> >  {
> > -	return arm_kdump_phys_base(phys_offset);
> > +	char *string;
> > +	struct syment *sp;
> > +	physaddr_t paddr;
> > +
> > +	if (string = pc->read_vmcoreinfo("NUMBER(PHYS_OFFSET)")) {
> > +		*phys_offset = htol(string, QUIET, NULL);
> > +		free(string);
> > +		return TRUE;
> > +	}
> > +
> > +	if (machdep->flags & NEW_VMEMMAP) {
> > +		if (!(sp = kernel_symbol_search("memstart_addr")))
> > +			return FALSE;
> > +
> > +		/* sanity check */
> > +		if (!machdep->machspec->kimage_voffset)
> > +			return FALSE;
> > +
> > +		paddr =	sp->value - machdep->machspec->kimage_voffset;
> > +		if (READMEM(-1, phys_offset, sizeof(*phys_offset),
> > +				sp->value, paddr) > 0)
> > +			return TRUE;
> > +		else
> > +			return FALSE;
> > +	} else
> > +		return arm_kdump_phys_base(phys_offset);
> >  }
> >  
> >  static void
> > @@ -2509,6 +2621,11 @@ arm64_IS_VMALLOC_ADDR(ulong vaddr)
> >  {
> >  	struct machine_specific *ms = machdep->machspec;
> >  	
> > +	if ((machdep->flags & NEW_VMEMMAP) &&
> > +	    (vaddr >= machdep->machspec->kimage_text) &&
> > +	    (vaddr <= machdep->machspec->kimage_end))
> > +		return FALSE;
> > +
> >          return ((vaddr >= ms->vmalloc_start_addr && vaddr <=
> >          ms->vmalloc_end) ||
> >                  ((machdep->flags & VMEMMAP) &&
> >                   (vaddr >= ms->vmemmap_vaddr && vaddr <= ms->vmemmap_end))
> >                   ||
> > @@ -2539,7 +2656,10 @@ arm64_calc_VA_BITS(void)
> >  
> >  	for (bitval = highest_bit_long(value); bitval; bitval--) {
> >  		if ((value & (1UL << bitval)) == 0) {
> > -			machdep->machspec->VA_BITS = bitval + 2;
> > +			if (machdep->flags & NEW_VMEMMAP)
> > +				machdep->machspec->VA_BITS = bitval + 1;
> > +			else
> > +				machdep->machspec->VA_BITS = bitval + 2;
> >  			break;
> >  		}
> >  	}
> > @@ -2593,10 +2713,22 @@ arm64_calc_virtual_memory_ranges(void)
> >  		break;
> >          }
> >  
> > -	vmemmap_size = ALIGN((1UL << (ms->VA_BITS - machdep->pageshift)) *
> > SIZE(page), PUD_SIZE);
> > +	if (machdep->flags & NEW_VMEMMAP)
> > +#define STRUCT_PAGE_MAX_SHIFT   6
> > +		vmemmap_size = 1UL << (ms->VA_BITS - machdep->pageshift - 1
> > +						+ STRUCT_PAGE_MAX_SHIFT);
> > +	else
> > +		vmemmap_size = ALIGN((1UL << (ms->VA_BITS - machdep->pageshift)) *
> > SIZE(page), PUD_SIZE);
> > +
> >  	vmalloc_end = (ms->page_offset - PUD_SIZE - vmemmap_size - SZ_64K);
> > -	vmemmap_start = vmalloc_end + SZ_64K;
> > -	vmemmap_end = vmemmap_start + vmemmap_size;
> > +
> > +	if (machdep->flags & NEW_VMEMMAP) {
> > +		vmemmap_start = ms->page_offset - vmemmap_size;
> > +		vmemmap_end = ms->page_offset;
> > +	} else {
> > +		vmemmap_start = vmalloc_end + SZ_64K;
> > +		vmemmap_end = vmemmap_start + vmemmap_size;
> > +	}
> >  
> >  	ms->vmalloc_end = vmalloc_end - 1;
> >  	ms->vmemmap_vaddr = vmemmap_start;
> > diff --git a/defs.h b/defs.h
> > index 8eb601b..d6f719c 100644
> > --- a/defs.h
> > +++ b/defs.h
> > @@ -2846,8 +2846,8 @@ typedef u64 pte_t;
> >  
> >  #define PTOV(X) \
> >  	((unsigned
> >  	long)(X)-(machdep->machspec->phys_offset)+(machdep->machspec->page_offset))
> > -#define VTOP(X) \
> > -	((unsigned
> > long)(X)-(machdep->machspec->page_offset)+(machdep->machspec->phys_offset))
> > +
> > +#define VTOP(X)               arm64_VTOP((ulong)(X))
> >  
> >  #define USERSPACE_TOP   (machdep->machspec->userspace_top)
> >  #define PAGE_OFFSET     (machdep->machspec->page_offset)
> > @@ -2962,19 +2962,24 @@ typedef signed int s32;
> >  #define VM_L3_4K      (0x10)
> >  #define KDUMP_ENABLED (0x20)
> >  #define IRQ_STACKS    (0x40)
> > -#define VM_L4_4K      (0x80)
> > +#define NEW_VMEMMAP   (0x80)
> > +#define VM_L4_4K      (0x100)
> >  
> >  /*
> >   * sources: Documentation/arm64/memory.txt
> >   *          arch/arm64/include/asm/memory.h
> >   *          arch/arm64/include/asm/pgtable.h
> >   */
> > -
> > -#define ARM64_PAGE_OFFSET    ((0xffffffffffffffffUL) <<
> > (machdep->machspec->VA_BITS - 1))
> > +#define ARM64_VA_START       ((0xffffffffffffffffUL) \
> > +					<< machdep->machspec->VA_BITS)
> > +#define ARM64_PAGE_OFFSET    ((0xffffffffffffffffUL) \
> > +					<< (machdep->machspec->VA_BITS - 1))
> >  #define ARM64_USERSPACE_TOP  ((1UL) << machdep->machspec->VA_BITS)
> > -#define ARM64_MODULES_VADDR  (ARM64_PAGE_OFFSET - MEGABYTES(64))
> > -#define ARM64_MODULES_END    (ARM64_PAGE_OFFSET - 1)
> > -#define ARM64_VMALLOC_START  ((0xffffffffffffffffUL) <<
> > machdep->machspec->VA_BITS)
> > +
> > +/* only used for v4.6 or later */
> > +#define ARM64_MODULES_VSIZE     MEGABYTES(128)
> > +#define ARM64_KASAN_SHADOW_SIZE (1UL << (machdep->machspec->VA_BITS - 3))
> > +
> >  /*
> >   * The following 3 definitions are the original values, but are obsolete
> >   * for 3.17 and later kernels because they are now build-time calculations.
> > @@ -3055,6 +3060,10 @@ struct machine_specific {
> >  	ulong *irq_stacks;
> >  	ulong __irqentry_text_start;
> >  	ulong __irqentry_text_end;
> > +	/* only needed for v4.6 or later kernel */
> > +	ulong kimage_voffset;
> > +	ulong kimage_text;
> > +	ulong kimage_end;
> >  };
> >  
> >  struct arm64_stackframe {
> > @@ -5412,6 +5421,7 @@ void unwind_backtrace(struct bt_info *);
> >  #ifdef ARM64
> >  void arm64_init(int);
> >  void arm64_dump_machdep_table(ulong);
> > +ulong arm64_VTOP(ulong);
> >  int arm64_IS_VMALLOC_ADDR(ulong);
> >  ulong arm64_swp_type(ulong);
> >  ulong arm64_swp_offset(ulong);
> > diff --git a/main.c b/main.c
> > index 05787f0..4065e9a 100644
> > --- a/main.c
> > +++ b/main.c
> > @@ -227,9 +227,10 @@ main(int argc, char **argv)
> >  						optarg);
> >  				}
> >  			} else if (STREQ(long_options[option_index].name, "kaslr")) {
> > -				if (!machine_type("X86_64"))
> > -					error(INFO, "--kaslr only valid "
> > -						"with X86_64 machine type.\n");
> > +				if (!machine_type("X86_64") &&
> > +				    !machine_type("ARM64"))
> > +					error(INFO, "--kaslr not valid "
> > +						"with this machine type.\n");
> >  				else if (STREQ(optarg, "auto"))
> >  					kt->flags2 |= (RELOC_AUTO|KASLR);
> >  				else {
> > diff --git a/symbols.c b/symbols.c
> > index a8d3563..b0a6461 100644
> > --- a/symbols.c
> > +++ b/symbols.c
> > @@ -593,7 +593,8 @@ kaslr_init(void)
> >  {
> >  	char *string;
> >  
> > -	if (!machine_type("X86_64") || (kt->flags & RELOC_SET))
> > +	if ((!machine_type("X86_64") && !machine_type("ARM64")) ||
> > +	    (kt->flags & RELOC_SET))
> >  		return;
> >  
> >  	/*
> > @@ -712,7 +713,7 @@ store_symbols(bfd *abfd, int dynamic, void *minisyms,
> > long symcount,
> >  	if (machine_type("X86")) {
> >  		if (!(kt->flags & RELOC_SET))
> >  			kt->flags |= RELOC_FORCE;
> > -	} else if (machine_type("X86_64")) {
> > +	} else if (machine_type("X86_64") || machine_type("ARM64")) {
> >  		if ((kt->flags2 & RELOC_AUTO) && !(kt->flags & RELOC_SET))
> >  			derive_kaslr_offset(abfd, dynamic, from,
> >  				fromend, size, store);
> > @@ -783,7 +784,8 @@ store_sysmap_symbols(void)
> >                  error(FATAL, "symbol table namespace malloc: %s\n",
> >                          strerror(errno));
> >  
> > -	if (!machine_type("X86") && !machine_type("X86_64"))
> > +	if (!machine_type("X86") && !machine_type("X86_64") &&
> > +	    !machine_type("ARM64"))
> >  		kt->flags &= ~RELOC_SET;
> >  
> >  	first = 0;
> > @@ -833,7 +835,7 @@ store_sysmap_symbols(void)
> >  }
> >  
> >  /*
> > - *  Handle x86 kernels configured such that the vmlinux symbols
> > + *  Handle x86/arm64 kernels configured such that the vmlinux symbols
> >   *  are not as loaded into the kernel (not unity-mapped).
> >   */
> >  static ulong
> > @@ -4681,7 +4683,7 @@ value_search(ulong value, ulong *offset)
> >  	if ((sp = machdep->value_to_symbol(value, offset)))
> >  		return sp;
> >  
> > -	if (IS_VMALLOC_ADDR(value))
> > +	if (IS_VMALLOC_ADDR(value))
> >  		goto check_modules;
> >  
> >  	if ((sp = symval_hash_search(value)) == NULL)
> > --
> > 2.8.1
> > 
> > --
> > Crash-utility mailing list
> > Crash-utility at redhat.com
> > https://www.redhat.com/mailman/listinfo/crash-utility
> > 
> 
> --
> Crash-utility mailing list
> Crash-utility at redhat.com
> https://www.redhat.com/mailman/listinfo/crash-utility




More information about the Crash-utility mailing list