* [RFC PATCH 0/4] makedumpfile/arm64: support flipped VA and 52-bit kernel VA @ 2021-01-14 8:25 kazuhito.hagio 2021-01-14 8:25 ` [RFC PATCH 1/4] Use ELF vmcoreinfo note for --mem-usage option kazuhito.hagio ` (3 more replies) 0 siblings, 4 replies; 10+ messages in thread From: kazuhito.hagio @ 2021-01-14 8:25 UTC (permalink / raw) To: bhsharma, bhupesh.linux, alexander.kamensky42, piliu, kexec Cc: aadiga, ioanna-maria.alifieraki Hi Bhupesh, Alexander, Pingfan and arm64 guys, I've rewritten Bhupesh's v5 patch [1] in order to avoid some limitations and now this patchset - can be built on some old arm64 environments hopefully, - can be built on x86_64 machines with TARGET=aarch64, - can process vmcores on different version of kernel from captured version. Could you test this? The patchset is also on GitHub [2] and the commit messages are to be written later. However the following conditions are probably not supported: - 5.11-rc is not taken into account - 5.4 <= kernels <= 5.8 (*1) * if PA_BITS=52 && VA_BITS!=52 * with -x option if vabits_actual=52 - kernels < 5.4 with CONFIG_ARM64_USER_VA_BITS_52=y (e.g. RHEL8 kernels) (*1) supported with kernel commit bbdbc11804ff and 1d50e5d0c5052. I think especially MAX_PHYSMEM_BITS cannot be guessed correctly only with the entries in vmcoreinfo (even with Bhupesh's original patch), so basically I would like distributions that uses 5.4 to 5.8 to backport Bhupesh's kernel patches above if the patchset does not work well. [1] http://lists.infradead.org/pipermail/kexec/2020-September/021336.html [2] https://github.com/k-hagio/makedumpfile/commits/arm64.kh.test2 Kazuhito Hagio (4): Use ELF vmcoreinfo note for --mem-usage option arm64: use NUMBER(VA_BITS) in vmcoreinfo Get kernel version from OSRELEASE in vmcoreinfo arm64: support flipped VA and 52-bit kernel VA arch/arm64.c | 155 ++++++++++++++++++++++++++++++++++++++++++++------------- makedumpfile.c | 32 ++++++++++-- makedumpfile.h | 1 + 3 files changed, 149 insertions(+), 39 deletions(-) -- 2.9.3 _______________________________________________ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec ^ permalink raw reply [flat|nested] 10+ messages in thread
* [RFC PATCH 1/4] Use ELF vmcoreinfo note for --mem-usage option 2021-01-14 8:25 [RFC PATCH 0/4] makedumpfile/arm64: support flipped VA and 52-bit kernel VA kazuhito.hagio @ 2021-01-14 8:25 ` kazuhito.hagio 2021-01-14 8:25 ` [RFC PATCH 2/4] arm64: use NUMBER(VA_BITS) in vmcoreinfo kazuhito.hagio ` (2 subsequent siblings) 3 siblings, 0 replies; 10+ messages in thread From: kazuhito.hagio @ 2021-01-14 8:25 UTC (permalink / raw) To: bhsharma, bhupesh.linux, alexander.kamensky42, piliu, kexec Cc: aadiga, ioanna-maria.alifieraki From: Kazuhito Hagio <k-hagio-ab@nec.com> Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com> --- makedumpfile.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/makedumpfile.c b/makedumpfile.c index ecd63fa..199748b 100644 --- a/makedumpfile.c +++ b/makedumpfile.c @@ -11426,6 +11426,7 @@ int show_mem_usage(void) { uint64_t vmcoreinfo_addr, vmcoreinfo_len; struct cycle cycle = {0}; + int vmcoreinfo = FALSE; if (!is_crashkernel_mem_reserved()) { ERRMSG("No memory is reserved for crashkernel!\n"); @@ -11437,9 +11438,22 @@ int show_mem_usage(void) if (!open_files_for_creating_dumpfile()) return FALSE; - if (!get_elf_loads(info->fd_memory, info->name_memory)) + if (!get_elf_info(info->fd_memory, info->name_memory)) return FALSE; + /* + * /proc/kcore on Linux 4.19 and later kernels have vmcoreinfo note in + * NOTE segment. See commit 23c85094fe18. + */ + if (has_vmcoreinfo()) { + off_t offset; + unsigned long size; + + get_vmcoreinfo(&offset, &size); + vmcoreinfo = read_vmcoreinfo_from_vmcore(offset, size, FALSE); + DEBUG_MSG("Read vmcoreinfo from NOTE segment: %d\n", vmcoreinfo); + } + if (!get_page_offset()) return FALSE; @@ -11447,11 +11461,13 @@ int show_mem_usage(void) if (!get_phys_base()) return FALSE; - if (!get_sys_kernel_vmcoreinfo(&vmcoreinfo_addr, &vmcoreinfo_len)) - return FALSE; + if (!vmcoreinfo) { + if (!get_sys_kernel_vmcoreinfo(&vmcoreinfo_addr, &vmcoreinfo_len)) + return FALSE; - if (!set_kcore_vmcoreinfo(vmcoreinfo_addr, vmcoreinfo_len)) - return FALSE; + if (!set_kcore_vmcoreinfo(vmcoreinfo_addr, vmcoreinfo_len)) + return FALSE; + } if (!initial()) return FALSE; -- 2.9.3 _______________________________________________ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [RFC PATCH 2/4] arm64: use NUMBER(VA_BITS) in vmcoreinfo 2021-01-14 8:25 [RFC PATCH 0/4] makedumpfile/arm64: support flipped VA and 52-bit kernel VA kazuhito.hagio 2021-01-14 8:25 ` [RFC PATCH 1/4] Use ELF vmcoreinfo note for --mem-usage option kazuhito.hagio @ 2021-01-14 8:25 ` kazuhito.hagio 2021-01-14 8:25 ` [RFC PATCH 3/4] Get kernel version from OSRELEASE " kazuhito.hagio 2021-01-14 8:25 ` [RFC PATCH 4/4] arm64: support flipped VA and 52-bit kernel VA kazuhito.hagio 3 siblings, 0 replies; 10+ messages in thread From: kazuhito.hagio @ 2021-01-14 8:25 UTC (permalink / raw) To: bhsharma, bhupesh.linux, alexander.kamensky42, piliu, kexec Cc: aadiga, ioanna-maria.alifieraki From: Kazuhito Hagio <k-hagio-ab@nec.com> Signed-off-by: Bhupesh Sharma <bhsharma@redhat.com> Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com> --- arch/arm64.c | 64 ++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 21 deletions(-) diff --git a/arch/arm64.c b/arch/arm64.c index 3d7b416..61ec89a 100644 --- a/arch/arm64.c +++ b/arch/arm64.c @@ -345,6 +345,44 @@ get_stext_symbol(void) return(found ? kallsym : FALSE); } +static int +get_va_bits_from_stext_arm64(void) +{ + ulong _stext; + + _stext = get_stext_symbol(); + if (!_stext) { + ERRMSG("Can't get the symbol of _stext.\n"); + return FALSE; + } + + /* + * Derive va_bits as per arch/arm64/Kconfig. Note that this is a + * best case approximation at the moment, as there can be + * inconsistencies in this calculation (for e.g., for + * 52-bit kernel VA case, the 48th bit is set in + * the _stext symbol). + */ + if ((_stext & PAGE_OFFSET_48) == PAGE_OFFSET_48) { + va_bits = 48; + } else if ((_stext & PAGE_OFFSET_47) == PAGE_OFFSET_47) { + va_bits = 47; + } else if ((_stext & PAGE_OFFSET_42) == PAGE_OFFSET_42) { + va_bits = 42; + } else if ((_stext & PAGE_OFFSET_39) == PAGE_OFFSET_39) { + va_bits = 39; + } else if ((_stext & PAGE_OFFSET_36) == PAGE_OFFSET_36) { + va_bits = 36; + } else { + ERRMSG("Cannot find a proper _stext for calculating VA_BITS\n"); + return FALSE; + } + + DEBUG_MSG("va_bits : %d (approximation via _stext)\n", va_bits); + + return TRUE; +} + int get_machdep_info_arm64(void) { @@ -398,27 +436,11 @@ get_xen_info_arm64(void) int get_versiondep_info_arm64(void) { - ulong _stext; - - _stext = get_stext_symbol(); - if (!_stext) { - ERRMSG("Can't get the symbol of _stext.\n"); - return FALSE; - } - - /* Derive va_bits as per arch/arm64/Kconfig */ - if ((_stext & PAGE_OFFSET_36) == PAGE_OFFSET_36) { - va_bits = 36; - } else if ((_stext & PAGE_OFFSET_39) == PAGE_OFFSET_39) { - va_bits = 39; - } else if ((_stext & PAGE_OFFSET_42) == PAGE_OFFSET_42) { - va_bits = 42; - } else if ((_stext & PAGE_OFFSET_47) == PAGE_OFFSET_47) { - va_bits = 47; - } else if ((_stext & PAGE_OFFSET_48) == PAGE_OFFSET_48) { - va_bits = 48; - } else { - ERRMSG("Cannot find a proper _stext for calculating VA_BITS\n"); + if (NUMBER(VA_BITS) != NOT_FOUND_NUMBER) { + va_bits = NUMBER(VA_BITS); + DEBUG_MSG("va_bits : %d (vmcoreinfo)\n", va_bits); + } else if (get_va_bits_from_stext_arm64() == FALSE) { + ERRMSG("Can't determine va_bits.\n"); return FALSE; } -- 2.9.3 _______________________________________________ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [RFC PATCH 3/4] Get kernel version from OSRELEASE in vmcoreinfo 2021-01-14 8:25 [RFC PATCH 0/4] makedumpfile/arm64: support flipped VA and 52-bit kernel VA kazuhito.hagio 2021-01-14 8:25 ` [RFC PATCH 1/4] Use ELF vmcoreinfo note for --mem-usage option kazuhito.hagio 2021-01-14 8:25 ` [RFC PATCH 2/4] arm64: use NUMBER(VA_BITS) in vmcoreinfo kazuhito.hagio @ 2021-01-14 8:25 ` kazuhito.hagio 2021-01-14 8:25 ` [RFC PATCH 4/4] arm64: support flipped VA and 52-bit kernel VA kazuhito.hagio 3 siblings, 0 replies; 10+ messages in thread From: kazuhito.hagio @ 2021-01-14 8:25 UTC (permalink / raw) To: bhsharma, bhupesh.linux, alexander.kamensky42, piliu, kexec Cc: aadiga, ioanna-maria.alifieraki From: Kazuhito Hagio <k-hagio-ab@nec.com> Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com> --- makedumpfile.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/makedumpfile.c b/makedumpfile.c index 199748b..fdfe437 100644 --- a/makedumpfile.c +++ b/makedumpfile.c @@ -1182,6 +1182,7 @@ check_release(void) } } + info->kernel_version = FALSE; info->kernel_version = get_kernel_version(info->system_utsname.release); if (info->kernel_version == FALSE) { ERRMSG("Can't get the kernel version.\n"); @@ -2480,6 +2481,9 @@ read_vmcoreinfo_basic_info(void) if (strlen(info->release)) continue; strcpy(info->release, buf + strlen(STR_OSRELEASE)); + + if (!info->kernel_version) + info->kernel_version = get_kernel_version(info->release); } if (strncmp(buf, STR_PAGESIZE, strlen(STR_PAGESIZE)) == 0) { page_size = strtol(buf+strlen(STR_PAGESIZE),&endp,10); -- 2.9.3 _______________________________________________ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [RFC PATCH 4/4] arm64: support flipped VA and 52-bit kernel VA 2021-01-14 8:25 [RFC PATCH 0/4] makedumpfile/arm64: support flipped VA and 52-bit kernel VA kazuhito.hagio ` (2 preceding siblings ...) 2021-01-14 8:25 ` [RFC PATCH 3/4] Get kernel version from OSRELEASE " kazuhito.hagio @ 2021-01-14 8:25 ` kazuhito.hagio 2021-01-14 10:03 ` piliu 3 siblings, 1 reply; 10+ messages in thread From: kazuhito.hagio @ 2021-01-14 8:25 UTC (permalink / raw) To: bhsharma, bhupesh.linux, alexander.kamensky42, piliu, kexec Cc: aadiga, ioanna-maria.alifieraki From: Kazuhito Hagio <k-hagio-ab@nec.com> Based on Bhupesh's patch and contains Pingfan's idea. Signed-off-by: Bhupesh Sharma <bhsharma@redhat.com> Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com> --- arch/arm64.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++---------- makedumpfile.c | 2 ++ makedumpfile.h | 1 + 3 files changed, 83 insertions(+), 15 deletions(-) diff --git a/arch/arm64.c b/arch/arm64.c index 61ec89a..4ece19d 100644 --- a/arch/arm64.c +++ b/arch/arm64.c @@ -47,6 +47,8 @@ typedef struct { static int lpa_52_bit_support_available; static int pgtable_level; static int va_bits; +static int vabits_actual; +static int flipped_va; static unsigned long kimage_voffset; #define SZ_4K 4096 @@ -58,7 +60,6 @@ static unsigned long kimage_voffset; #define PAGE_OFFSET_42 ((0xffffffffffffffffUL) << 42) #define PAGE_OFFSET_47 ((0xffffffffffffffffUL) << 47) #define PAGE_OFFSET_48 ((0xffffffffffffffffUL) << 48) -#define PAGE_OFFSET_52 ((0xffffffffffffffffUL) << 52) #define pgd_val(x) ((x).pgd) #define pud_val(x) (pgd_val((x).pgd)) @@ -218,12 +219,20 @@ pmd_page_paddr(pmd_t pmd) #define pte_index(vaddr) (((vaddr) >> PAGESHIFT()) & (PTRS_PER_PTE - 1)) #define pte_offset(dir, vaddr) (pmd_page_paddr((*dir)) + pte_index(vaddr) * sizeof(pte_t)) +/* + * The linear kernel range starts at the bottom of the virtual address + * space. Testing the top bit for the start of the region is a + * sufficient check and avoids having to worry about the tag. + */ +#define is_linear_addr(addr) (flipped_va ? \ + (!((unsigned long)(addr) & (1UL << (vabits_actual - 1)))) : \ + (!!((unsigned long)(addr) & (1UL << (vabits_actual - 1))))) + static unsigned long long __pa(unsigned long vaddr) { - if (kimage_voffset == NOT_FOUND_NUMBER || - (vaddr >= PAGE_OFFSET)) - return (vaddr - PAGE_OFFSET + info->phys_base); + if (kimage_voffset == NOT_FOUND_NUMBER || is_linear_addr(vaddr)) + return ((vaddr & ~PAGE_OFFSET) + info->phys_base); else return (vaddr - kimage_voffset); } @@ -253,6 +262,7 @@ static int calculate_plat_config(void) (PAGESIZE() == SZ_64K && va_bits == 42)) { pgtable_level = 2; } else if ((PAGESIZE() == SZ_64K && va_bits == 48) || + (PAGESIZE() == SZ_64K && va_bits == 52) || (PAGESIZE() == SZ_4K && va_bits == 39) || (PAGESIZE() == SZ_16K && va_bits == 47)) { pgtable_level = 3; @@ -263,6 +273,7 @@ static int calculate_plat_config(void) PAGESIZE(), va_bits); return FALSE; } + DEBUG_MSG("pgtable_level: %d\n", pgtable_level); return TRUE; } @@ -383,22 +394,54 @@ get_va_bits_from_stext_arm64(void) return TRUE; } +static void +get_page_offset_arm64(void) +{ + ulong page_end; + int vabits_min; + + /* + * See arch/arm64/include/asm/memory.h for more details of + * the PAGE_OFFSET calculation. + */ + vabits_min = (va_bits > 48) ? 48 : va_bits; + page_end = -(1UL << (vabits_min - 1)); + + if (SYMBOL(_stext) > page_end) { + flipped_va = TRUE; + info->page_offset = -(1UL << vabits_actual); + } else { + flipped_va = FALSE; + info->page_offset = -(1UL << (vabits_actual - 1)); + } + + DEBUG_MSG("page_offset : %lx (from page_end check)\n", + info->page_offset); +} + int get_machdep_info_arm64(void) { + /* Check if va_bits is still not initialized. If still 0, call + * get_versiondep_info() to initialize the same. + */ + if (!va_bits) + get_versiondep_info_arm64(); + /* Determine if the PA address range is 52-bits: ARMv8.2-LPA */ if (NUMBER(MAX_PHYSMEM_BITS) != NOT_FOUND_NUMBER) { info->max_physmem_bits = NUMBER(MAX_PHYSMEM_BITS); + DEBUG_MSG("max_physmem_bits : %ld (vmcoreinfo)\n", info->max_physmem_bits); if (info->max_physmem_bits == 52) lpa_52_bit_support_available = 1; - } else - info->max_physmem_bits = 48; + } else { + if (va_bits == 52) + info->max_physmem_bits = 52; /* just guess */ + else + info->max_physmem_bits = 48; - /* Check if va_bits is still not initialized. If still 0, call - * get_versiondep_info() to initialize the same. - */ - if (!va_bits) - get_versiondep_info_arm64(); + DEBUG_MSG("max_physmem_bits : %ld (guess)\n", info->max_physmem_bits); + } if (!calculate_plat_config()) { ERRMSG("Can't determine platform config values\n"); @@ -409,7 +452,6 @@ get_machdep_info_arm64(void) info->section_size_bits = SECTIONS_SIZE_BITS; DEBUG_MSG("kimage_voffset : %lx\n", kimage_voffset); - DEBUG_MSG("max_physmem_bits : %ld\n", info->max_physmem_bits); DEBUG_MSG("section_size_bits: %ld\n", info->section_size_bits); return TRUE; @@ -444,10 +486,33 @@ get_versiondep_info_arm64(void) return FALSE; } - info->page_offset = (0xffffffffffffffffUL) << (va_bits - 1); + /* + * See TCR_EL1, Translation Control Register (EL1) register + * description in the ARMv8 Architecture Reference Manual. + * Basically, we can use the TCR_EL1.T1SZ + * value to determine the virtual addressing range supported + * in the kernel-space (i.e. vabits_actual) since Linux 5.9. + */ + if (NUMBER(TCR_EL1_T1SZ) != NOT_FOUND_NUMBER) { + vabits_actual = 64 - NUMBER(TCR_EL1_T1SZ); + DEBUG_MSG("vabits_actual : %d (vmcoreinfo)\n", vabits_actual); + } else if ((va_bits == 52) && (SYMBOL(mem_section) != NOT_FOUND_SYMBOL)) { + /* + * Linux 5.4 through 5.10 have the following linear space: + * 48-bit: 0xffff000000000000 - 0xffff7fffffffffff + * 58-bit: 0xfff0000000000000 - 0xfff7ffffffffffff + */ + if (SYMBOL(mem_section) & (1UL << (52 - 1))) + vabits_actual = 48; + else + vabits_actual = 52; + DEBUG_MSG("vabits_actual : %d (guess from mem_section)\n", vabits_actual); + } else { + vabits_actual = va_bits; + DEBUG_MSG("vabits_actual : %d (same as va_bits)\n", vabits_actual); + } - DEBUG_MSG("va_bits : %d\n", va_bits); - DEBUG_MSG("page_offset : %lx\n", info->page_offset); + get_page_offset_arm64(); return TRUE; } diff --git a/makedumpfile.c b/makedumpfile.c index fdfe437..37788ff 100644 --- a/makedumpfile.c +++ b/makedumpfile.c @@ -2396,6 +2396,7 @@ write_vmcoreinfo_data(void) WRITE_NUMBER("HUGETLB_PAGE_DTOR", HUGETLB_PAGE_DTOR); #ifdef __aarch64__ WRITE_NUMBER("VA_BITS", VA_BITS); + /* WRITE_NUMBER("TCR_EL1_T1SZ", TCR_EL1_T1SZ); should not exists */ WRITE_NUMBER_UNSIGNED("PHYS_OFFSET", PHYS_OFFSET); WRITE_NUMBER_UNSIGNED("kimage_voffset", kimage_voffset); #endif @@ -2838,6 +2839,7 @@ read_vmcoreinfo(void) READ_NUMBER("KERNEL_IMAGE_SIZE", KERNEL_IMAGE_SIZE); #ifdef __aarch64__ READ_NUMBER("VA_BITS", VA_BITS); + READ_NUMBER("TCR_EL1_T1SZ", TCR_EL1_T1SZ); READ_NUMBER_UNSIGNED("PHYS_OFFSET", PHYS_OFFSET); READ_NUMBER_UNSIGNED("kimage_voffset", kimage_voffset); #endif diff --git a/makedumpfile.h b/makedumpfile.h index 5f50080..a151da2 100644 --- a/makedumpfile.h +++ b/makedumpfile.h @@ -1999,6 +1999,7 @@ struct number_table { long KERNEL_IMAGE_SIZE; #ifdef __aarch64__ long VA_BITS; + long TCR_EL1_T1SZ; unsigned long PHYS_OFFSET; unsigned long kimage_voffset; #endif -- 2.9.3 _______________________________________________ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [RFC PATCH 4/4] arm64: support flipped VA and 52-bit kernel VA 2021-01-14 8:25 ` [RFC PATCH 4/4] arm64: support flipped VA and 52-bit kernel VA kazuhito.hagio @ 2021-01-14 10:03 ` piliu 2021-01-14 18:25 ` Bhupesh SHARMA 0 siblings, 1 reply; 10+ messages in thread From: piliu @ 2021-01-14 10:03 UTC (permalink / raw) To: kazuhito.hagio, bhsharma, bhupesh.linux, alexander.kamensky42, kexec Cc: aadiga, ioanna-maria.alifieraki On 1/14/21 4:25 PM, kazuhito.hagio@gmail.com wrote: > From: Kazuhito Hagio <k-hagio-ab@nec.com> > > Based on Bhupesh's patch and contains Pingfan's idea. > > Signed-off-by: Bhupesh Sharma <bhsharma@redhat.com> > Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com> > --- > arch/arm64.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++---------- > makedumpfile.c | 2 ++ > makedumpfile.h | 1 + > 3 files changed, 83 insertions(+), 15 deletions(-) > > diff --git a/arch/arm64.c b/arch/arm64.c > index 61ec89a..4ece19d 100644 > --- a/arch/arm64.c > +++ b/arch/arm64.c > @@ -47,6 +47,8 @@ typedef struct { > static int lpa_52_bit_support_available; > static int pgtable_level; > static int va_bits; > +static int vabits_actual; > +static int flipped_va; > static unsigned long kimage_voffset; > > #define SZ_4K 4096 > @@ -58,7 +60,6 @@ static unsigned long kimage_voffset; > #define PAGE_OFFSET_42 ((0xffffffffffffffffUL) << 42) > #define PAGE_OFFSET_47 ((0xffffffffffffffffUL) << 47) > #define PAGE_OFFSET_48 ((0xffffffffffffffffUL) << 48) > -#define PAGE_OFFSET_52 ((0xffffffffffffffffUL) << 52) > > #define pgd_val(x) ((x).pgd) > #define pud_val(x) (pgd_val((x).pgd)) > @@ -218,12 +219,20 @@ pmd_page_paddr(pmd_t pmd) > #define pte_index(vaddr) (((vaddr) >> PAGESHIFT()) & (PTRS_PER_PTE - 1)) > #define pte_offset(dir, vaddr) (pmd_page_paddr((*dir)) + pte_index(vaddr) * sizeof(pte_t)) > > +/* > + * The linear kernel range starts at the bottom of the virtual address > + * space. Testing the top bit for the start of the region is a > + * sufficient check and avoids having to worry about the tag. > + */ > +#define is_linear_addr(addr) (flipped_va ? \ > + (!((unsigned long)(addr) & (1UL << (vabits_actual - 1)))) : \ > + (!!((unsigned long)(addr) & (1UL << (vabits_actual - 1))))) > + > static unsigned long long > __pa(unsigned long vaddr) > { > - if (kimage_voffset == NOT_FOUND_NUMBER || > - (vaddr >= PAGE_OFFSET)) > - return (vaddr - PAGE_OFFSET + info->phys_base); > + if (kimage_voffset == NOT_FOUND_NUMBER || is_linear_addr(vaddr)) > + return ((vaddr & ~PAGE_OFFSET) + info->phys_base); > else > return (vaddr - kimage_voffset); > } > @@ -253,6 +262,7 @@ static int calculate_plat_config(void) > (PAGESIZE() == SZ_64K && va_bits == 42)) { > pgtable_level = 2; > } else if ((PAGESIZE() == SZ_64K && va_bits == 48) || > + (PAGESIZE() == SZ_64K && va_bits == 52) || > (PAGESIZE() == SZ_4K && va_bits == 39) || > (PAGESIZE() == SZ_16K && va_bits == 47)) { > pgtable_level = 3; > @@ -263,6 +273,7 @@ static int calculate_plat_config(void) > PAGESIZE(), va_bits); > return FALSE; > } > + DEBUG_MSG("pgtable_level: %d\n", pgtable_level); > > return TRUE; > } > @@ -383,22 +394,54 @@ get_va_bits_from_stext_arm64(void) > return TRUE; > } > > +static void > +get_page_offset_arm64(void) > +{ > + ulong page_end; > + int vabits_min; > + > + /* > + * See arch/arm64/include/asm/memory.h for more details of > + * the PAGE_OFFSET calculation. > + */ > + vabits_min = (va_bits > 48) ? 48 : va_bits; > + page_end = -(1UL << (vabits_min - 1)); > + > + if (SYMBOL(_stext) > page_end) { > + flipped_va = TRUE; > + info->page_offset = -(1UL << vabits_actual); > + } else { > + flipped_va = FALSE; > + info->page_offset = -(1UL << (vabits_actual - 1)); > + } > + > + DEBUG_MSG("page_offset : %lx (from page_end check)\n", > + info->page_offset); > +} > + > int > get_machdep_info_arm64(void) > { > + /* Check if va_bits is still not initialized. If still 0, call > + * get_versiondep_info() to initialize the same. > + */ > + if (!va_bits) > + get_versiondep_info_arm64(); > + > /* Determine if the PA address range is 52-bits: ARMv8.2-LPA */ > if (NUMBER(MAX_PHYSMEM_BITS) != NOT_FOUND_NUMBER) { > info->max_physmem_bits = NUMBER(MAX_PHYSMEM_BITS); > + DEBUG_MSG("max_physmem_bits : %ld (vmcoreinfo)\n", info->max_physmem_bits); > if (info->max_physmem_bits == 52) > lpa_52_bit_support_available = 1; > - } else > - info->max_physmem_bits = 48; > + } else { > + if (va_bits == 52) > + info->max_physmem_bits = 52; /* just guess */ > + else > + info->max_physmem_bits = 48; > > - /* Check if va_bits is still not initialized. If still 0, call > - * get_versiondep_info() to initialize the same. > - */ > - if (!va_bits) > - get_versiondep_info_arm64(); > + DEBUG_MSG("max_physmem_bits : %ld (guess)\n", info->max_physmem_bits); > + } > > if (!calculate_plat_config()) { > ERRMSG("Can't determine platform config values\n"); > @@ -409,7 +452,6 @@ get_machdep_info_arm64(void) > info->section_size_bits = SECTIONS_SIZE_BITS; > > DEBUG_MSG("kimage_voffset : %lx\n", kimage_voffset); > - DEBUG_MSG("max_physmem_bits : %ld\n", info->max_physmem_bits); > DEBUG_MSG("section_size_bits: %ld\n", info->section_size_bits); > > return TRUE; > @@ -444,10 +486,33 @@ get_versiondep_info_arm64(void) > return FALSE; > } > > - info->page_offset = (0xffffffffffffffffUL) << (va_bits - 1); > + /* > + * See TCR_EL1, Translation Control Register (EL1) register > + * description in the ARMv8 Architecture Reference Manual. > + * Basically, we can use the TCR_EL1.T1SZ > + * value to determine the virtual addressing range supported > + * in the kernel-space (i.e. vabits_actual) since Linux 5.9. > + */ > + if (NUMBER(TCR_EL1_T1SZ) != NOT_FOUND_NUMBER) { > + vabits_actual = 64 - NUMBER(TCR_EL1_T1SZ); > + DEBUG_MSG("vabits_actual : %d (vmcoreinfo)\n", vabits_actual); > + } else if ((va_bits == 52) && (SYMBOL(mem_section) != NOT_FOUND_SYMBOL)) { > + /* > + * Linux 5.4 through 5.10 have the following linear space: > + * 48-bit: 0xffff000000000000 - 0xffff7fffffffffff > + * 58-bit: 0xfff0000000000000 - 0xfff7ffffffffffff > + */ > + if (SYMBOL(mem_section) & (1UL << (52 - 1))) Sorry but I do not think any SYMBOL(x) is inside the range of linear mapping address. All of them should be beyond kimage_vaddr. Having vabits_actual is introduced and precise to resolve is_lm_address(), but if it is not available, could we survive? _PAGE_OFFSET(52) < _PAGE_END(52) < _PAGE_OFFSET(48) < _PAGE_END(48) Translating into numbers: 0xfff0000000000000 < 0xfff8000000000000 < 0xffff000000000000 < 0xffff800000000000 Refer to linux/Documentation/arm64/memory.rst, the line ffffa00010000000 fffff81ffffeffff ~88TB vmalloc It comes to the conclusion that any symbol > SYMBOL(_text) > _PAGE_END(48). So is_lm_address() can looks like if (addr > _PAGE_END(48)), it is kimage else, it is linear mapping So even more aggressive, we can exclude the need of vabits_actual totally in this patch. Thanks, Pingfan _______________________________________________ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC PATCH 4/4] arm64: support flipped VA and 52-bit kernel VA 2021-01-14 10:03 ` piliu @ 2021-01-14 18:25 ` Bhupesh SHARMA 2021-01-15 0:40 ` HAGIO KAZUHITO(萩尾 一仁) 0 siblings, 1 reply; 10+ messages in thread From: Bhupesh SHARMA @ 2021-01-14 18:25 UTC (permalink / raw) To: piliu Cc: Bhupesh Sharma, kexec, aadiga, Alexander Kamensky, Ioanna Alifieraki, kazuhito.hagio Hi Kazu, On Thu, Jan 14, 2021 at 3:33 PM piliu <piliu@redhat.com> wrote: > > > > On 1/14/21 4:25 PM, kazuhito.hagio@gmail.com wrote: > > From: Kazuhito Hagio <k-hagio-ab@nec.com> > > > > Based on Bhupesh's patch and contains Pingfan's idea. > > > > Signed-off-by: Bhupesh Sharma <bhsharma@redhat.com> > > Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com> > > --- > > arch/arm64.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++---------- > > makedumpfile.c | 2 ++ > > makedumpfile.h | 1 + > > 3 files changed, 83 insertions(+), 15 deletions(-) > > > > diff --git a/arch/arm64.c b/arch/arm64.c > > index 61ec89a..4ece19d 100644 > > --- a/arch/arm64.c > > +++ b/arch/arm64.c > > @@ -47,6 +47,8 @@ typedef struct { > > static int lpa_52_bit_support_available; > > static int pgtable_level; > > static int va_bits; > > +static int vabits_actual; > > +static int flipped_va; > > static unsigned long kimage_voffset; > > > > #define SZ_4K 4096 > > @@ -58,7 +60,6 @@ static unsigned long kimage_voffset; > > #define PAGE_OFFSET_42 ((0xffffffffffffffffUL) << 42) > > #define PAGE_OFFSET_47 ((0xffffffffffffffffUL) << 47) > > #define PAGE_OFFSET_48 ((0xffffffffffffffffUL) << 48) > > -#define PAGE_OFFSET_52 ((0xffffffffffffffffUL) << 52) > > > > #define pgd_val(x) ((x).pgd) > > #define pud_val(x) (pgd_val((x).pgd)) > > @@ -218,12 +219,20 @@ pmd_page_paddr(pmd_t pmd) > > #define pte_index(vaddr) (((vaddr) >> PAGESHIFT()) & (PTRS_PER_PTE - 1)) > > #define pte_offset(dir, vaddr) (pmd_page_paddr((*dir)) + pte_index(vaddr) * sizeof(pte_t)) > > > > +/* > > + * The linear kernel range starts at the bottom of the virtual address > > + * space. Testing the top bit for the start of the region is a > > + * sufficient check and avoids having to worry about the tag. > > + */ > > +#define is_linear_addr(addr) (flipped_va ? \ > > + (!((unsigned long)(addr) & (1UL << (vabits_actual - 1)))) : \ > > + (!!((unsigned long)(addr) & (1UL << (vabits_actual - 1))))) > > + > > static unsigned long long > > __pa(unsigned long vaddr) > > { > > - if (kimage_voffset == NOT_FOUND_NUMBER || > > - (vaddr >= PAGE_OFFSET)) > > - return (vaddr - PAGE_OFFSET + info->phys_base); > > + if (kimage_voffset == NOT_FOUND_NUMBER || is_linear_addr(vaddr)) > > + return ((vaddr & ~PAGE_OFFSET) + info->phys_base); > > else > > return (vaddr - kimage_voffset); > > } > > @@ -253,6 +262,7 @@ static int calculate_plat_config(void) > > (PAGESIZE() == SZ_64K && va_bits == 42)) { > > pgtable_level = 2; > > } else if ((PAGESIZE() == SZ_64K && va_bits == 48) || > > + (PAGESIZE() == SZ_64K && va_bits == 52) || > > (PAGESIZE() == SZ_4K && va_bits == 39) || > > (PAGESIZE() == SZ_16K && va_bits == 47)) { > > pgtable_level = 3; > > @@ -263,6 +273,7 @@ static int calculate_plat_config(void) > > PAGESIZE(), va_bits); > > return FALSE; > > } > > + DEBUG_MSG("pgtable_level: %d\n", pgtable_level); > > > > return TRUE; > > } > > @@ -383,22 +394,54 @@ get_va_bits_from_stext_arm64(void) > > return TRUE; > > } > > > > +static void > > +get_page_offset_arm64(void) > > +{ > > + ulong page_end; > > + int vabits_min; > > + > > + /* > > + * See arch/arm64/include/asm/memory.h for more details of > > + * the PAGE_OFFSET calculation. > > + */ > > + vabits_min = (va_bits > 48) ? 48 : va_bits; > > + page_end = -(1UL << (vabits_min - 1)); > > + > > + if (SYMBOL(_stext) > page_end) { > > + flipped_va = TRUE; > > + info->page_offset = -(1UL << vabits_actual); > > + } else { > > + flipped_va = FALSE; > > + info->page_offset = -(1UL << (vabits_actual - 1)); > > + } > > + > > + DEBUG_MSG("page_offset : %lx (from page_end check)\n", > > + info->page_offset); > > +} > > + > > int > > get_machdep_info_arm64(void) > > { > > + /* Check if va_bits is still not initialized. If still 0, call > > + * get_versiondep_info() to initialize the same. > > + */ > > + if (!va_bits) > > + get_versiondep_info_arm64(); > > + > > /* Determine if the PA address range is 52-bits: ARMv8.2-LPA */ > > if (NUMBER(MAX_PHYSMEM_BITS) != NOT_FOUND_NUMBER) { > > info->max_physmem_bits = NUMBER(MAX_PHYSMEM_BITS); > > + DEBUG_MSG("max_physmem_bits : %ld (vmcoreinfo)\n", info->max_physmem_bits); > > if (info->max_physmem_bits == 52) > > lpa_52_bit_support_available = 1; > > - } else > > - info->max_physmem_bits = 48; > > + } else { > > + if (va_bits == 52) > > + info->max_physmem_bits = 52; /* just guess */ > > + else > > + info->max_physmem_bits = 48; > > > > - /* Check if va_bits is still not initialized. If still 0, call > > - * get_versiondep_info() to initialize the same. > > - */ > > - if (!va_bits) > > - get_versiondep_info_arm64(); > > + DEBUG_MSG("max_physmem_bits : %ld (guess)\n", info->max_physmem_bits); > > + } > > > > if (!calculate_plat_config()) { > > ERRMSG("Can't determine platform config values\n"); > > @@ -409,7 +452,6 @@ get_machdep_info_arm64(void) > > info->section_size_bits = SECTIONS_SIZE_BITS; > > > > DEBUG_MSG("kimage_voffset : %lx\n", kimage_voffset); > > - DEBUG_MSG("max_physmem_bits : %ld\n", info->max_physmem_bits); > > DEBUG_MSG("section_size_bits: %ld\n", info->section_size_bits); > > > > return TRUE; > > @@ -444,10 +486,33 @@ get_versiondep_info_arm64(void) > > return FALSE; > > } > > > > - info->page_offset = (0xffffffffffffffffUL) << (va_bits - 1); > > + /* > > + * See TCR_EL1, Translation Control Register (EL1) register > > + * description in the ARMv8 Architecture Reference Manual. > > + * Basically, we can use the TCR_EL1.T1SZ > > + * value to determine the virtual addressing range supported > > + * in the kernel-space (i.e. vabits_actual) since Linux 5.9. > > + */ > > + if (NUMBER(TCR_EL1_T1SZ) != NOT_FOUND_NUMBER) { > > + vabits_actual = 64 - NUMBER(TCR_EL1_T1SZ); > > + DEBUG_MSG("vabits_actual : %d (vmcoreinfo)\n", vabits_actual); > > + } else if ((va_bits == 52) && (SYMBOL(mem_section) != NOT_FOUND_SYMBOL)) { > > + /* > > + * Linux 5.4 through 5.10 have the following linear space: > > + * 48-bit: 0xffff000000000000 - 0xffff7fffffffffff > > + * 58-bit: 0xfff0000000000000 - 0xfff7ffffffffffff > > + */ > > + if (SYMBOL(mem_section) & (1UL << (52 - 1))) > > Sorry but I do not think any SYMBOL(x) is inside the range of linear > mapping address. All of them should be beyond kimage_vaddr. > > Having vabits_actual is introduced and precise to resolve > is_lm_address(), but if it is not available, could we survive? > > _PAGE_OFFSET(52) < _PAGE_END(52) < _PAGE_OFFSET(48) < _PAGE_END(48) > Translating into numbers: > 0xfff0000000000000 < 0xfff8000000000000 < 0xffff000000000000 < > 0xffff800000000000 > > Refer to linux/Documentation/arm64/memory.rst, the line > ffffa00010000000 fffff81ffffeffff ~88TB vmalloc > > It comes to the conclusion that any symbol > SYMBOL(_text) > _PAGE_END(48). > > So is_lm_address() can looks like > if (addr > _PAGE_END(48)), it is kimage > else, it is linear mapping > > So even more aggressive, we can exclude the need of vabits_actual > totally in this patch. As Pingfan noted, this approach still has issues and it failed on my arm64 board in the limited testing I did today. I will do some more testing tomorrow and come back with an approach which addresses the same and also takes into account Pingfan's concerns. Thanks, Bhupesh _______________________________________________ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec ^ permalink raw reply [flat|nested] 10+ messages in thread
* RE: [RFC PATCH 4/4] arm64: support flipped VA and 52-bit kernel VA 2021-01-14 18:25 ` Bhupesh SHARMA @ 2021-01-15 0:40 ` HAGIO KAZUHITO(萩尾 一仁) 2021-01-15 1:41 ` piliu 0 siblings, 1 reply; 10+ messages in thread From: HAGIO KAZUHITO(萩尾 一仁) @ 2021-01-15 0:40 UTC (permalink / raw) To: Bhupesh SHARMA, piliu Cc: Bhupesh Sharma, kexec, aadiga, kazuhito.hagio, Ioanna Alifieraki, Alexander Kamensky Hi Pingfan, Bhupesh, Thank you for your comments! -----Original Message----- > Hi Kazu, > > On Thu, Jan 14, 2021 at 3:33 PM piliu <piliu@redhat.com> wrote: > > > > > > > > On 1/14/21 4:25 PM, kazuhito.hagio@gmail.com wrote: > > > From: Kazuhito Hagio <k-hagio-ab@nec.com> > > > > > > Based on Bhupesh's patch and contains Pingfan's idea. > > > > > > Signed-off-by: Bhupesh Sharma <bhsharma@redhat.com> > > > Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com> > > > --- > > > arch/arm64.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++---------- > > > makedumpfile.c | 2 ++ > > > makedumpfile.h | 1 + > > > 3 files changed, 83 insertions(+), 15 deletions(-) > > > > > > diff --git a/arch/arm64.c b/arch/arm64.c > > > index 61ec89a..4ece19d 100644 > > > --- a/arch/arm64.c > > > +++ b/arch/arm64.c > > > @@ -47,6 +47,8 @@ typedef struct { > > > static int lpa_52_bit_support_available; > > > static int pgtable_level; > > > static int va_bits; > > > +static int vabits_actual; > > > +static int flipped_va; > > > static unsigned long kimage_voffset; > > > > > > #define SZ_4K 4096 > > > @@ -58,7 +60,6 @@ static unsigned long kimage_voffset; > > > #define PAGE_OFFSET_42 ((0xffffffffffffffffUL) << 42) > > > #define PAGE_OFFSET_47 ((0xffffffffffffffffUL) << 47) > > > #define PAGE_OFFSET_48 ((0xffffffffffffffffUL) << 48) > > > -#define PAGE_OFFSET_52 ((0xffffffffffffffffUL) << 52) > > > > > > #define pgd_val(x) ((x).pgd) > > > #define pud_val(x) (pgd_val((x).pgd)) > > > @@ -218,12 +219,20 @@ pmd_page_paddr(pmd_t pmd) > > > #define pte_index(vaddr) (((vaddr) >> PAGESHIFT()) & (PTRS_PER_PTE - 1)) > > > #define pte_offset(dir, vaddr) (pmd_page_paddr((*dir)) + pte_index(vaddr) * > sizeof(pte_t)) > > > > > > +/* > > > + * The linear kernel range starts at the bottom of the virtual address > > > + * space. Testing the top bit for the start of the region is a > > > + * sufficient check and avoids having to worry about the tag. > > > + */ > > > +#define is_linear_addr(addr) (flipped_va ? \ > > > + (!((unsigned long)(addr) & (1UL << (vabits_actual - 1)))) : \ > > > + (!!((unsigned long)(addr) & (1UL << (vabits_actual - 1))))) > > > + > > > static unsigned long long > > > __pa(unsigned long vaddr) > > > { > > > - if (kimage_voffset == NOT_FOUND_NUMBER || > > > - (vaddr >= PAGE_OFFSET)) > > > - return (vaddr - PAGE_OFFSET + info->phys_base); > > > + if (kimage_voffset == NOT_FOUND_NUMBER || is_linear_addr(vaddr)) > > > + return ((vaddr & ~PAGE_OFFSET) + info->phys_base); > > > else > > > return (vaddr - kimage_voffset); > > > } > > > @@ -253,6 +262,7 @@ static int calculate_plat_config(void) > > > (PAGESIZE() == SZ_64K && va_bits == 42)) { > > > pgtable_level = 2; > > > } else if ((PAGESIZE() == SZ_64K && va_bits == 48) || > > > + (PAGESIZE() == SZ_64K && va_bits == 52) || > > > (PAGESIZE() == SZ_4K && va_bits == 39) || > > > (PAGESIZE() == SZ_16K && va_bits == 47)) { > > > pgtable_level = 3; > > > @@ -263,6 +273,7 @@ static int calculate_plat_config(void) > > > PAGESIZE(), va_bits); > > > return FALSE; > > > } > > > + DEBUG_MSG("pgtable_level: %d\n", pgtable_level); > > > > > > return TRUE; > > > } > > > @@ -383,22 +394,54 @@ get_va_bits_from_stext_arm64(void) > > > return TRUE; > > > } > > > > > > +static void > > > +get_page_offset_arm64(void) > > > +{ > > > + ulong page_end; > > > + int vabits_min; > > > + > > > + /* > > > + * See arch/arm64/include/asm/memory.h for more details of > > > + * the PAGE_OFFSET calculation. > > > + */ > > > + vabits_min = (va_bits > 48) ? 48 : va_bits; > > > + page_end = -(1UL << (vabits_min - 1)); > > > + > > > + if (SYMBOL(_stext) > page_end) { > > > + flipped_va = TRUE; > > > + info->page_offset = -(1UL << vabits_actual); > > > + } else { > > > + flipped_va = FALSE; > > > + info->page_offset = -(1UL << (vabits_actual - 1)); > > > + } > > > + > > > + DEBUG_MSG("page_offset : %lx (from page_end check)\n", > > > + info->page_offset); > > > +} > > > + > > > int > > > get_machdep_info_arm64(void) > > > { > > > + /* Check if va_bits is still not initialized. If still 0, call > > > + * get_versiondep_info() to initialize the same. > > > + */ > > > + if (!va_bits) > > > + get_versiondep_info_arm64(); > > > + > > > /* Determine if the PA address range is 52-bits: ARMv8.2-LPA */ > > > if (NUMBER(MAX_PHYSMEM_BITS) != NOT_FOUND_NUMBER) { > > > info->max_physmem_bits = NUMBER(MAX_PHYSMEM_BITS); > > > + DEBUG_MSG("max_physmem_bits : %ld (vmcoreinfo)\n", info->max_physmem_bits); > > > if (info->max_physmem_bits == 52) > > > lpa_52_bit_support_available = 1; > > > - } else > > > - info->max_physmem_bits = 48; > > > + } else { > > > + if (va_bits == 52) > > > + info->max_physmem_bits = 52; /* just guess */ > > > + else > > > + info->max_physmem_bits = 48; > > > > > > - /* Check if va_bits is still not initialized. If still 0, call > > > - * get_versiondep_info() to initialize the same. > > > - */ > > > - if (!va_bits) > > > - get_versiondep_info_arm64(); > > > + DEBUG_MSG("max_physmem_bits : %ld (guess)\n", info->max_physmem_bits); > > > + } > > > > > > if (!calculate_plat_config()) { > > > ERRMSG("Can't determine platform config values\n"); > > > @@ -409,7 +452,6 @@ get_machdep_info_arm64(void) > > > info->section_size_bits = SECTIONS_SIZE_BITS; > > > > > > DEBUG_MSG("kimage_voffset : %lx\n", kimage_voffset); > > > - DEBUG_MSG("max_physmem_bits : %ld\n", info->max_physmem_bits); > > > DEBUG_MSG("section_size_bits: %ld\n", info->section_size_bits); > > > > > > return TRUE; > > > @@ -444,10 +486,33 @@ get_versiondep_info_arm64(void) > > > return FALSE; > > > } > > > > > > - info->page_offset = (0xffffffffffffffffUL) << (va_bits - 1); > > > + /* > > > + * See TCR_EL1, Translation Control Register (EL1) register > > > + * description in the ARMv8 Architecture Reference Manual. > > > + * Basically, we can use the TCR_EL1.T1SZ > > > + * value to determine the virtual addressing range supported > > > + * in the kernel-space (i.e. vabits_actual) since Linux 5.9. > > > + */ > > > + if (NUMBER(TCR_EL1_T1SZ) != NOT_FOUND_NUMBER) { > > > + vabits_actual = 64 - NUMBER(TCR_EL1_T1SZ); > > > + DEBUG_MSG("vabits_actual : %d (vmcoreinfo)\n", vabits_actual); > > > + } else if ((va_bits == 52) && (SYMBOL(mem_section) != NOT_FOUND_SYMBOL)) { > > > + /* > > > + * Linux 5.4 through 5.10 have the following linear space: > > > + * 48-bit: 0xffff000000000000 - 0xffff7fffffffffff > > > + * 58-bit: 0xfff0000000000000 - 0xfff7ffffffffffff > > > + */ > > > + if (SYMBOL(mem_section) & (1UL << (52 - 1))) > > > > Sorry but I do not think any SYMBOL(x) is inside the range of linear > > mapping address. All of them should be beyond kimage_vaddr. As for this, SYMBOL(mem_section) is a bit special and shows the value in the mem_section variable, not the address of it, by kernel commit a0b1280368d1. Actually on my tiny arm64 board.. # strings /proc/kcore | less ... OSRELEASE=5.4.0-1025-raspi PAGESIZE=4096 SYMBOL(init_uts_ns)=ffffd6db0fa10568 SYMBOL(node_online_map)=ffffd6db0fa0a808 SYMBOL(swapper_pg_dir)=ffffd6db0f42b000 SYMBOL(_stext)=ffffd6db0e481000 SYMBOL(vmap_area_list)=ffffd6db0fa51680 SYMBOL(mem_map)=ffffd6db0fbc0240 SYMBOL(contig_page_data)=ffffd6db0faed6c0 SYMBOL(mem_section)=ffff0000eb809300 <<-- LENGTH(mem_section)=1024 SIZE(mem_section)=16 OFFSET(mem_section.section_mem_map)=0 ... NUMBER(VA_BITS)=48 So at least if the kernel is configured with CONFIG_SPARSEMEM_EXTREME, I thought this would work. This is just a user tool effort to broaden supported kernels, instead of necessary information from the kernel, no need to support all kernels. And the current makedumpfile's implementation, SYMBOL(mem_section) is set to the address of the mem_section variable with -x option, so I wrote on the cover letter that this patchset doesn't support "with -x option if vabits_actual=52" case yet. > > > > Having vabits_actual is introduced and precise to resolve > > is_lm_address(), but if it is not available, could we survive? > > > > _PAGE_OFFSET(52) < _PAGE_END(52) < _PAGE_OFFSET(48) < _PAGE_END(48) > > Translating into numbers: > > 0xfff0000000000000 < 0xfff8000000000000 < 0xffff000000000000 < > > 0xffff800000000000 > > > > Refer to linux/Documentation/arm64/memory.rst, the line > > ffffa00010000000 fffff81ffffeffff ~88TB vmalloc > > > > It comes to the conclusion that any symbol > SYMBOL(_text) > _PAGE_END(48). > > > > So is_lm_address() can looks like > > if (addr > _PAGE_END(48)), it is kimage > > else, it is linear mapping This sounds good and will work. > > > > So even more aggressive, we can exclude the need of vabits_actual > > totally in this patch. Interesting, but if vabits_actual is not available, I wonder how we can get info->page_offset. Seems it's used mainly for p2v conversion and is_kvaddr(), which still has a problem though. > > As Pingfan noted, this approach still has issues and it failed on my > arm64 board in the limited testing I did today. Can I have what configuration, error and debug messages you see, for reference? > I will do some more testing tomorrow and come back with an approach > which addresses the same and also takes into account Pingfan's > concerns. ok, thanks! Kazu _______________________________________________ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC PATCH 4/4] arm64: support flipped VA and 52-bit kernel VA 2021-01-15 0:40 ` HAGIO KAZUHITO(萩尾 一仁) @ 2021-01-15 1:41 ` piliu 2021-01-15 3:16 ` HAGIO KAZUHITO(萩尾 一仁) 0 siblings, 1 reply; 10+ messages in thread From: piliu @ 2021-01-15 1:41 UTC (permalink / raw) To: HAGIO KAZUHITO(萩尾 一仁), Bhupesh SHARMA Cc: Bhupesh Sharma, kexec, aadiga, kazuhito.hagio, Ioanna Alifieraki, Alexander Kamensky On 1/15/21 8:40 AM, HAGIO KAZUHITO(萩尾 一仁) wrote: > Hi Pingfan, Bhupesh, > > Thank you for your comments! > > -----Original Message----- >> Hi Kazu, >> >> On Thu, Jan 14, 2021 at 3:33 PM piliu <piliu@redhat.com> wrote: >>> >>> >>> >>> On 1/14/21 4:25 PM, kazuhito.hagio@gmail.com wrote: >>>> From: Kazuhito Hagio <k-hagio-ab@nec.com> >>>> >>>> Based on Bhupesh's patch and contains Pingfan's idea. >>>> >>>> Signed-off-by: Bhupesh Sharma <bhsharma@redhat.com> >>>> Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com> >>>> --- >>>> arch/arm64.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++---------- >>>> makedumpfile.c | 2 ++ >>>> makedumpfile.h | 1 + >>>> 3 files changed, 83 insertions(+), 15 deletions(-) >>>> >>>> diff --git a/arch/arm64.c b/arch/arm64.c >>>> index 61ec89a..4ece19d 100644 >>>> --- a/arch/arm64.c >>>> +++ b/arch/arm64.c >>>> @@ -47,6 +47,8 @@ typedef struct { >>>> static int lpa_52_bit_support_available; >>>> static int pgtable_level; >>>> static int va_bits; >>>> +static int vabits_actual; >>>> +static int flipped_va; >>>> static unsigned long kimage_voffset; >>>> >>>> #define SZ_4K 4096 >>>> @@ -58,7 +60,6 @@ static unsigned long kimage_voffset; >>>> #define PAGE_OFFSET_42 ((0xffffffffffffffffUL) << 42) >>>> #define PAGE_OFFSET_47 ((0xffffffffffffffffUL) << 47) >>>> #define PAGE_OFFSET_48 ((0xffffffffffffffffUL) << 48) >>>> -#define PAGE_OFFSET_52 ((0xffffffffffffffffUL) << 52) >>>> >>>> #define pgd_val(x) ((x).pgd) >>>> #define pud_val(x) (pgd_val((x).pgd)) >>>> @@ -218,12 +219,20 @@ pmd_page_paddr(pmd_t pmd) >>>> #define pte_index(vaddr) (((vaddr) >> PAGESHIFT()) & (PTRS_PER_PTE - 1)) >>>> #define pte_offset(dir, vaddr) (pmd_page_paddr((*dir)) + pte_index(vaddr) * >> sizeof(pte_t)) >>>> >>>> +/* >>>> + * The linear kernel range starts at the bottom of the virtual address >>>> + * space. Testing the top bit for the start of the region is a >>>> + * sufficient check and avoids having to worry about the tag. >>>> + */ >>>> +#define is_linear_addr(addr) (flipped_va ? \ >>>> + (!((unsigned long)(addr) & (1UL << (vabits_actual - 1)))) : \ >>>> + (!!((unsigned long)(addr) & (1UL << (vabits_actual - 1))))) >>>> + >>>> static unsigned long long >>>> __pa(unsigned long vaddr) >>>> { >>>> - if (kimage_voffset == NOT_FOUND_NUMBER || >>>> - (vaddr >= PAGE_OFFSET)) >>>> - return (vaddr - PAGE_OFFSET + info->phys_base); >>>> + if (kimage_voffset == NOT_FOUND_NUMBER || is_linear_addr(vaddr)) >>>> + return ((vaddr & ~PAGE_OFFSET) + info->phys_base); >>>> else >>>> return (vaddr - kimage_voffset); >>>> } >>>> @@ -253,6 +262,7 @@ static int calculate_plat_config(void) >>>> (PAGESIZE() == SZ_64K && va_bits == 42)) { >>>> pgtable_level = 2; >>>> } else if ((PAGESIZE() == SZ_64K && va_bits == 48) || >>>> + (PAGESIZE() == SZ_64K && va_bits == 52) || >>>> (PAGESIZE() == SZ_4K && va_bits == 39) || >>>> (PAGESIZE() == SZ_16K && va_bits == 47)) { >>>> pgtable_level = 3; >>>> @@ -263,6 +273,7 @@ static int calculate_plat_config(void) >>>> PAGESIZE(), va_bits); >>>> return FALSE; >>>> } >>>> + DEBUG_MSG("pgtable_level: %d\n", pgtable_level); >>>> >>>> return TRUE; >>>> } >>>> @@ -383,22 +394,54 @@ get_va_bits_from_stext_arm64(void) >>>> return TRUE; >>>> } >>>> >>>> +static void >>>> +get_page_offset_arm64(void) >>>> +{ >>>> + ulong page_end; >>>> + int vabits_min; >>>> + >>>> + /* >>>> + * See arch/arm64/include/asm/memory.h for more details of >>>> + * the PAGE_OFFSET calculation. >>>> + */ >>>> + vabits_min = (va_bits > 48) ? 48 : va_bits; >>>> + page_end = -(1UL << (vabits_min - 1)); >>>> + >>>> + if (SYMBOL(_stext) > page_end) { >>>> + flipped_va = TRUE; >>>> + info->page_offset = -(1UL << vabits_actual); >>>> + } else { >>>> + flipped_va = FALSE; >>>> + info->page_offset = -(1UL << (vabits_actual - 1)); >>>> + } >>>> + >>>> + DEBUG_MSG("page_offset : %lx (from page_end check)\n", >>>> + info->page_offset); >>>> +} >>>> + >>>> int >>>> get_machdep_info_arm64(void) >>>> { >>>> + /* Check if va_bits is still not initialized. If still 0, call >>>> + * get_versiondep_info() to initialize the same. >>>> + */ >>>> + if (!va_bits) >>>> + get_versiondep_info_arm64(); >>>> + >>>> /* Determine if the PA address range is 52-bits: ARMv8.2-LPA */ >>>> if (NUMBER(MAX_PHYSMEM_BITS) != NOT_FOUND_NUMBER) { >>>> info->max_physmem_bits = NUMBER(MAX_PHYSMEM_BITS); >>>> + DEBUG_MSG("max_physmem_bits : %ld (vmcoreinfo)\n", info->max_physmem_bits); >>>> if (info->max_physmem_bits == 52) >>>> lpa_52_bit_support_available = 1; >>>> - } else >>>> - info->max_physmem_bits = 48; >>>> + } else { >>>> + if (va_bits == 52) >>>> + info->max_physmem_bits = 52; /* just guess */ >>>> + else >>>> + info->max_physmem_bits = 48; >>>> >>>> - /* Check if va_bits is still not initialized. If still 0, call >>>> - * get_versiondep_info() to initialize the same. >>>> - */ >>>> - if (!va_bits) >>>> - get_versiondep_info_arm64(); >>>> + DEBUG_MSG("max_physmem_bits : %ld (guess)\n", info->max_physmem_bits); >>>> + } >>>> >>>> if (!calculate_plat_config()) { >>>> ERRMSG("Can't determine platform config values\n"); >>>> @@ -409,7 +452,6 @@ get_machdep_info_arm64(void) >>>> info->section_size_bits = SECTIONS_SIZE_BITS; >>>> >>>> DEBUG_MSG("kimage_voffset : %lx\n", kimage_voffset); >>>> - DEBUG_MSG("max_physmem_bits : %ld\n", info->max_physmem_bits); >>>> DEBUG_MSG("section_size_bits: %ld\n", info->section_size_bits); >>>> >>>> return TRUE; >>>> @@ -444,10 +486,33 @@ get_versiondep_info_arm64(void) >>>> return FALSE; >>>> } >>>> >>>> - info->page_offset = (0xffffffffffffffffUL) << (va_bits - 1); >>>> + /* >>>> + * See TCR_EL1, Translation Control Register (EL1) register >>>> + * description in the ARMv8 Architecture Reference Manual. >>>> + * Basically, we can use the TCR_EL1.T1SZ >>>> + * value to determine the virtual addressing range supported >>>> + * in the kernel-space (i.e. vabits_actual) since Linux 5.9. >>>> + */ >>>> + if (NUMBER(TCR_EL1_T1SZ) != NOT_FOUND_NUMBER) { >>>> + vabits_actual = 64 - NUMBER(TCR_EL1_T1SZ); >>>> + DEBUG_MSG("vabits_actual : %d (vmcoreinfo)\n", vabits_actual); >>>> + } else if ((va_bits == 52) && (SYMBOL(mem_section) != NOT_FOUND_SYMBOL)) { >>>> + /* >>>> + * Linux 5.4 through 5.10 have the following linear space: >>>> + * 48-bit: 0xffff000000000000 - 0xffff7fffffffffff >>>> + * 58-bit: 0xfff0000000000000 - 0xfff7ffffffffffff >>>> + */ >>>> + if (SYMBOL(mem_section) & (1UL << (52 - 1))) >>> >>> Sorry but I do not think any SYMBOL(x) is inside the range of linear >>> mapping address. All of them should be beyond kimage_vaddr. > > As for this, SYMBOL(mem_section) is a bit special and shows the value in the > mem_section variable, not the address of it, by kernel commit a0b1280368d1. > > Actually on my tiny arm64 board.. > > # strings /proc/kcore | less > ... > OSRELEASE=5.4.0-1025-raspi > PAGESIZE=4096 > SYMBOL(init_uts_ns)=ffffd6db0fa10568 > SYMBOL(node_online_map)=ffffd6db0fa0a808 > SYMBOL(swapper_pg_dir)=ffffd6db0f42b000 > SYMBOL(_stext)=ffffd6db0e481000 > SYMBOL(vmap_area_list)=ffffd6db0fa51680 > SYMBOL(mem_map)=ffffd6db0fbc0240 > SYMBOL(contig_page_data)=ffffd6db0faed6c0 > SYMBOL(mem_section)=ffff0000eb809300 <<-- > LENGTH(mem_section)=1024 > SIZE(mem_section)=16 > OFFSET(mem_section.section_mem_map)=0 > ... > NUMBER(VA_BITS)=48 > > So at least if the kernel is configured with CONFIG_SPARSEMEM_EXTREME, You are right. Exactly, your method works in this case. > I thought this would work. This is just a user tool effort to broaden > supported kernels, instead of necessary information from the kernel, > no need to support all kernels. I hold a private opinion against the solution based on kernel version, since it raises extra effort to cope with different releases which back port some upstream patches without advancing kernel version. > > And the current makedumpfile's implementation, SYMBOL(mem_section) is set > to the address of the mem_section variable with -x option, so I wrote on > the cover letter that this patchset doesn't support "with -x option if > vabits_actual=52" case yet. > >>> >>> Having vabits_actual is introduced and precise to resolve >>> is_lm_address(), but if it is not available, could we survive? >>> >>> _PAGE_OFFSET(52) < _PAGE_END(52) < _PAGE_OFFSET(48) < _PAGE_END(48) >>> Translating into numbers: >>> 0xfff0000000000000 < 0xfff8000000000000 < 0xffff000000000000 < >>> 0xffff800000000000 >>> >>> Refer to linux/Documentation/arm64/memory.rst, the line >>> ffffa00010000000 fffff81ffffeffff ~88TB vmalloc >>> >>> It comes to the conclusion that any symbol > SYMBOL(_text) > _PAGE_END(48). >>> >>> So is_lm_address() can looks like >>> if (addr > _PAGE_END(48)), it is kimage >>> else, it is linear mapping > > This sounds good and will work. > >>> >>> So even more aggressive, we can exclude the need of vabits_actual >>> totally in this patch. > > Interesting, but if vabits_actual is not available, I wonder how we can > get info->page_offset. Seems it's used mainly for p2v conversion and Ashamed. I will make the best of the fact that va_bits=52 kernel only has _PAGE_OFFSET(52). It looks not elegant, but should work. Regards, Pingfan _______________________________________________ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec ^ permalink raw reply [flat|nested] 10+ messages in thread
* RE: [RFC PATCH 4/4] arm64: support flipped VA and 52-bit kernel VA 2021-01-15 1:41 ` piliu @ 2021-01-15 3:16 ` HAGIO KAZUHITO(萩尾 一仁) 0 siblings, 0 replies; 10+ messages in thread From: HAGIO KAZUHITO(萩尾 一仁) @ 2021-01-15 3:16 UTC (permalink / raw) To: piliu, Bhupesh SHARMA Cc: Bhupesh Sharma, kexec, aadiga, kazuhito.hagio, Ioanna Alifieraki, Alexander Kamensky Hi Pingfan, -----Original Message----- > >>> On 1/14/21 4:25 PM, kazuhito.hagio@gmail.com wrote: > >>>> From: Kazuhito Hagio <k-hagio-ab@nec.com> > >>>> > >>>> Based on Bhupesh's patch and contains Pingfan's idea. > >>>> > >>>> Signed-off-by: Bhupesh Sharma <bhsharma@redhat.com> > >>>> Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com> > >>>> --- > >>>> arch/arm64.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++---------- > >>>> makedumpfile.c | 2 ++ > >>>> makedumpfile.h | 1 + > >>>> 3 files changed, 83 insertions(+), 15 deletions(-) > >>>> > >>>> diff --git a/arch/arm64.c b/arch/arm64.c > >>>> index 61ec89a..4ece19d 100644 > >>>> --- a/arch/arm64.c > >>>> +++ b/arch/arm64.c > >>>> @@ -47,6 +47,8 @@ typedef struct { > >>>> static int lpa_52_bit_support_available; > >>>> static int pgtable_level; > >>>> static int va_bits; > >>>> +static int vabits_actual; > >>>> +static int flipped_va; > >>>> static unsigned long kimage_voffset; > >>>> > >>>> #define SZ_4K 4096 > >>>> @@ -58,7 +60,6 @@ static unsigned long kimage_voffset; > >>>> #define PAGE_OFFSET_42 ((0xffffffffffffffffUL) << 42) > >>>> #define PAGE_OFFSET_47 ((0xffffffffffffffffUL) << 47) > >>>> #define PAGE_OFFSET_48 ((0xffffffffffffffffUL) << 48) > >>>> -#define PAGE_OFFSET_52 ((0xffffffffffffffffUL) << 52) > >>>> > >>>> #define pgd_val(x) ((x).pgd) > >>>> #define pud_val(x) (pgd_val((x).pgd)) > >>>> @@ -218,12 +219,20 @@ pmd_page_paddr(pmd_t pmd) > >>>> #define pte_index(vaddr) (((vaddr) >> PAGESHIFT()) & (PTRS_PER_PTE - 1)) > >>>> #define pte_offset(dir, vaddr) (pmd_page_paddr((*dir)) + pte_index(vaddr) * > >> sizeof(pte_t)) > >>>> > >>>> +/* > >>>> + * The linear kernel range starts at the bottom of the virtual address > >>>> + * space. Testing the top bit for the start of the region is a > >>>> + * sufficient check and avoids having to worry about the tag. > >>>> + */ > >>>> +#define is_linear_addr(addr) (flipped_va ? \ > >>>> + (!((unsigned long)(addr) & (1UL << (vabits_actual - 1)))) : \ > >>>> + (!!((unsigned long)(addr) & (1UL << (vabits_actual - 1))))) > >>>> + > >>>> static unsigned long long > >>>> __pa(unsigned long vaddr) > >>>> { > >>>> - if (kimage_voffset == NOT_FOUND_NUMBER || > >>>> - (vaddr >= PAGE_OFFSET)) > >>>> - return (vaddr - PAGE_OFFSET + info->phys_base); > >>>> + if (kimage_voffset == NOT_FOUND_NUMBER || is_linear_addr(vaddr)) > >>>> + return ((vaddr & ~PAGE_OFFSET) + info->phys_base); > >>>> else > >>>> return (vaddr - kimage_voffset); > >>>> } > >>>> @@ -253,6 +262,7 @@ static int calculate_plat_config(void) > >>>> (PAGESIZE() == SZ_64K && va_bits == 42)) { > >>>> pgtable_level = 2; > >>>> } else if ((PAGESIZE() == SZ_64K && va_bits == 48) || > >>>> + (PAGESIZE() == SZ_64K && va_bits == 52) || > >>>> (PAGESIZE() == SZ_4K && va_bits == 39) || > >>>> (PAGESIZE() == SZ_16K && va_bits == 47)) { > >>>> pgtable_level = 3; > >>>> @@ -263,6 +273,7 @@ static int calculate_plat_config(void) > >>>> PAGESIZE(), va_bits); > >>>> return FALSE; > >>>> } > >>>> + DEBUG_MSG("pgtable_level: %d\n", pgtable_level); > >>>> > >>>> return TRUE; > >>>> } > >>>> @@ -383,22 +394,54 @@ get_va_bits_from_stext_arm64(void) > >>>> return TRUE; > >>>> } > >>>> > >>>> +static void > >>>> +get_page_offset_arm64(void) > >>>> +{ > >>>> + ulong page_end; > >>>> + int vabits_min; > >>>> + > >>>> + /* > >>>> + * See arch/arm64/include/asm/memory.h for more details of > >>>> + * the PAGE_OFFSET calculation. > >>>> + */ > >>>> + vabits_min = (va_bits > 48) ? 48 : va_bits; > >>>> + page_end = -(1UL << (vabits_min - 1)); > >>>> + > >>>> + if (SYMBOL(_stext) > page_end) { > >>>> + flipped_va = TRUE; > >>>> + info->page_offset = -(1UL << vabits_actual); > >>>> + } else { > >>>> + flipped_va = FALSE; > >>>> + info->page_offset = -(1UL << (vabits_actual - 1)); > >>>> + } > >>>> + > >>>> + DEBUG_MSG("page_offset : %lx (from page_end check)\n", > >>>> + info->page_offset); > >>>> +} > >>>> + > >>>> int > >>>> get_machdep_info_arm64(void) > >>>> { > >>>> + /* Check if va_bits is still not initialized. If still 0, call > >>>> + * get_versiondep_info() to initialize the same. > >>>> + */ > >>>> + if (!va_bits) > >>>> + get_versiondep_info_arm64(); > >>>> + > >>>> /* Determine if the PA address range is 52-bits: ARMv8.2-LPA */ > >>>> if (NUMBER(MAX_PHYSMEM_BITS) != NOT_FOUND_NUMBER) { > >>>> info->max_physmem_bits = NUMBER(MAX_PHYSMEM_BITS); > >>>> + DEBUG_MSG("max_physmem_bits : %ld (vmcoreinfo)\n", info->max_physmem_bits); > >>>> if (info->max_physmem_bits == 52) > >>>> lpa_52_bit_support_available = 1; > >>>> - } else > >>>> - info->max_physmem_bits = 48; > >>>> + } else { > >>>> + if (va_bits == 52) > >>>> + info->max_physmem_bits = 52; /* just guess */ > >>>> + else > >>>> + info->max_physmem_bits = 48; > >>>> > >>>> - /* Check if va_bits is still not initialized. If still 0, call > >>>> - * get_versiondep_info() to initialize the same. > >>>> - */ > >>>> - if (!va_bits) > >>>> - get_versiondep_info_arm64(); > >>>> + DEBUG_MSG("max_physmem_bits : %ld (guess)\n", info->max_physmem_bits); > >>>> + } > >>>> > >>>> if (!calculate_plat_config()) { > >>>> ERRMSG("Can't determine platform config values\n"); > >>>> @@ -409,7 +452,6 @@ get_machdep_info_arm64(void) > >>>> info->section_size_bits = SECTIONS_SIZE_BITS; > >>>> > >>>> DEBUG_MSG("kimage_voffset : %lx\n", kimage_voffset); > >>>> - DEBUG_MSG("max_physmem_bits : %ld\n", info->max_physmem_bits); > >>>> DEBUG_MSG("section_size_bits: %ld\n", info->section_size_bits); > >>>> > >>>> return TRUE; > >>>> @@ -444,10 +486,33 @@ get_versiondep_info_arm64(void) > >>>> return FALSE; > >>>> } > >>>> > >>>> - info->page_offset = (0xffffffffffffffffUL) << (va_bits - 1); > >>>> + /* > >>>> + * See TCR_EL1, Translation Control Register (EL1) register > >>>> + * description in the ARMv8 Architecture Reference Manual. > >>>> + * Basically, we can use the TCR_EL1.T1SZ > >>>> + * value to determine the virtual addressing range supported > >>>> + * in the kernel-space (i.e. vabits_actual) since Linux 5.9. > >>>> + */ > >>>> + if (NUMBER(TCR_EL1_T1SZ) != NOT_FOUND_NUMBER) { > >>>> + vabits_actual = 64 - NUMBER(TCR_EL1_T1SZ); > >>>> + DEBUG_MSG("vabits_actual : %d (vmcoreinfo)\n", vabits_actual); > >>>> + } else if ((va_bits == 52) && (SYMBOL(mem_section) != NOT_FOUND_SYMBOL)) { > >>>> + /* > >>>> + * Linux 5.4 through 5.10 have the following linear space: > >>>> + * 48-bit: 0xffff000000000000 - 0xffff7fffffffffff > >>>> + * 58-bit: 0xfff0000000000000 - 0xfff7ffffffffffff > >>>> + */ > >>>> + if (SYMBOL(mem_section) & (1UL << (52 - 1))) > >>> > >>> Sorry but I do not think any SYMBOL(x) is inside the range of linear > >>> mapping address. All of them should be beyond kimage_vaddr. > > > > As for this, SYMBOL(mem_section) is a bit special and shows the value in the > > mem_section variable, not the address of it, by kernel commit a0b1280368d1. > > > > Actually on my tiny arm64 board.. > > > > # strings /proc/kcore | less > > ... > > OSRELEASE=5.4.0-1025-raspi > > PAGESIZE=4096 > > SYMBOL(init_uts_ns)=ffffd6db0fa10568 > > SYMBOL(node_online_map)=ffffd6db0fa0a808 > > SYMBOL(swapper_pg_dir)=ffffd6db0f42b000 > > SYMBOL(_stext)=ffffd6db0e481000 > > SYMBOL(vmap_area_list)=ffffd6db0fa51680 > > SYMBOL(mem_map)=ffffd6db0fbc0240 > > SYMBOL(contig_page_data)=ffffd6db0faed6c0 > > SYMBOL(mem_section)=ffff0000eb809300 <<-- > > LENGTH(mem_section)=1024 > > SIZE(mem_section)=16 > > OFFSET(mem_section.section_mem_map)=0 > > ... > > NUMBER(VA_BITS)=48 > > > > So at least if the kernel is configured with CONFIG_SPARSEMEM_EXTREME, > You are right. Exactly, your method works in this case. > > > I thought this would work. This is just a user tool effort to broaden > > supported kernels, instead of necessary information from the kernel, > > no need to support all kernels. > > I hold a private opinion against the solution based on kernel version, > since it raises extra effort to cope with different releases which back > port some upstream patches without advancing kernel version. I agree with you, we should avoid depending on kernel version if we can. I left the 3/4 patch intact for possible use of kernel version method, but for now, the patchset doesn't use kernel version with your idea! :) > > > > And the current makedumpfile's implementation, SYMBOL(mem_section) is set > > to the address of the mem_section variable with -x option, so I wrote on > > the cover letter that this patchset doesn't support "with -x option if > > vabits_actual=52" case yet. > > > >>> > >>> Having vabits_actual is introduced and precise to resolve > >>> is_lm_address(), but if it is not available, could we survive? > >>> > >>> _PAGE_OFFSET(52) < _PAGE_END(52) < _PAGE_OFFSET(48) < _PAGE_END(48) > >>> Translating into numbers: > >>> 0xfff0000000000000 < 0xfff8000000000000 < 0xffff000000000000 < > >>> 0xffff800000000000 > >>> > >>> Refer to linux/Documentation/arm64/memory.rst, the line > >>> ffffa00010000000 fffff81ffffeffff ~88TB vmalloc > >>> > >>> It comes to the conclusion that any symbol > SYMBOL(_text) > _PAGE_END(48). > >>> > >>> So is_lm_address() can looks like > >>> if (addr > _PAGE_END(48)), it is kimage > >>> else, it is linear mapping > > > > This sounds good and will work. > > > >>> > >>> So even more aggressive, we can exclude the need of vabits_actual > >>> totally in this patch. > > > > Interesting, but if vabits_actual is not available, I wonder how we can > > get info->page_offset. Seems it's used mainly for p2v conversion and > > Ashamed. I will make the best of the fact that va_bits=52 kernel only > has _PAGE_OFFSET(52). It looks not elegant, but should work. ok, thanks for your help! Kazu _______________________________________________ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2021-01-15 3:16 UTC | newest] Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2021-01-14 8:25 [RFC PATCH 0/4] makedumpfile/arm64: support flipped VA and 52-bit kernel VA kazuhito.hagio 2021-01-14 8:25 ` [RFC PATCH 1/4] Use ELF vmcoreinfo note for --mem-usage option kazuhito.hagio 2021-01-14 8:25 ` [RFC PATCH 2/4] arm64: use NUMBER(VA_BITS) in vmcoreinfo kazuhito.hagio 2021-01-14 8:25 ` [RFC PATCH 3/4] Get kernel version from OSRELEASE " kazuhito.hagio 2021-01-14 8:25 ` [RFC PATCH 4/4] arm64: support flipped VA and 52-bit kernel VA kazuhito.hagio 2021-01-14 10:03 ` piliu 2021-01-14 18:25 ` Bhupesh SHARMA 2021-01-15 0:40 ` HAGIO KAZUHITO(萩尾 一仁) 2021-01-15 1:41 ` piliu 2021-01-15 3:16 ` HAGIO KAZUHITO(萩尾 一仁)
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.