The commit 568c6f04 will cause a regression issue for the determination of section_size_bits on kernel version before android12-5.10 or Linux-v5.12. The section_size_bits is supposed to be compatible with linux upstream and android GKI version: Before android12-5.10 or Linux-v5.12: SECTION_SIZE_BITS = 30 After android12-5.10 or Linux-v5.12: SECTION_SIZE_BITS = 27 when defined 4K_PAGES or 16K_PAGES. SECTION_SIZE_BITS = 29 when defined 64K_PAGES. Introduce arm64_get_andriod_gki_version() to get Andriod GKI version by ut->release. The Andriod GKI version is determined either by arm64_get_andriod_gki_version() or the kernel config "CONFIG_ANDROID_KABI_RESERVE". Fixes: 568c6f04 ("arm64: section_size_bits compatible with macro definitions") Signed-off-by: qiwu.chen <qiwu.chen@xxxxxxxxxxxxx> --- arm64.c | 68 ++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 51 insertions(+), 17 deletions(-) diff --git a/arm64.c b/arm64.c index 78e6609..679f2ab 100644 --- a/arm64.c +++ b/arm64.c @@ -95,6 +95,13 @@ static void arm64_calc_KERNELPACMASK(void); static void arm64_recalc_KERNELPACMASK(void); static int arm64_get_vmcoreinfo(unsigned long *vaddr, const char *label, int base); +/* Andriod GKI version definition */ +struct andriod_gki_version { + int kernel_version; + int kernel_patch_level; + int android_version; +}; + struct kernel_range { unsigned long modules_vaddr, modules_end; unsigned long vmalloc_start_addr, vmalloc_end; @@ -1615,6 +1622,30 @@ arm64_calc_phys_offset(void) fprintf(fp, "using %lx as phys_offset\n", ms->phys_offset); } +/* + * Determine Andriod GKI vmcore by reading "android" from ut->release. + * The prefix of Andriod GKI release version is: + * Kernel Version - Android release version + * For example: + * 5.10.209-android12, 5.15.148-android13 + */ +static bool arm64_get_andriod_gki_version(struct andriod_gki_version *version) +{ + char *p; + struct new_utsname *uts = &kt->utsname; + + if ((p = strstr(uts->release, "android"))) { + sscanf(uts->release, "%d.%d", &version->kernel_version, &version->kernel_patch_level); + sscanf(p, "android%d", &version->android_version); + if (CRASHDEBUG(1)) + fprintf(fp, "andriod_gki_version: andriod%d-%d.%d\n", + version->android_version, version->kernel_version, version->kernel_patch_level); + return true; + } + + return false; +} + /* * Determine SECTION_SIZE_BITS either by reading VMCOREINFO or the kernel * config, otherwise use the 64-bit ARM default definiton. @@ -1624,8 +1655,17 @@ arm64_get_section_size_bits(void) { int ret; char *string; + bool is_ikconfig_avail; + struct andriod_gki_version ver = {0}; - if (THIS_KERNEL_VERSION >= LINUX(5,12,0)) { + if (arm64_get_vmcoreinfo(&machdep->section_size_bits, "NUMBER(SECTION_SIZE_BITS)", NUM_DEC)) + goto exit; + + is_ikconfig_avail = kt->ikconfig_flags & IKCONFIG_AVAIL ? TRUE : FALSE; + /* The commit reduce section size for arm64 sparsemem is introduced since linux-v5.12 and android-12-5.10 */ + if (THIS_KERNEL_VERSION >= LINUX(5,12,0) || + (is_ikconfig_avail && get_kernel_config("CONFIG_ANDROID_KABI_RESERVE", NULL) == IKCONFIG_Y) || + (arm64_get_andriod_gki_version(&ver) && (ver.kernel_version * 100 + ver.kernel_patch_level >= 510) && ver.android_version >= 12)) { if (machdep->pagesize == 65536) machdep->section_size_bits = _SECTION_SIZE_BITS_5_12_64K; else @@ -1633,24 +1673,18 @@ arm64_get_section_size_bits(void) } else machdep->section_size_bits = _SECTION_SIZE_BITS; - if (arm64_get_vmcoreinfo(&machdep->section_size_bits, "NUMBER(SECTION_SIZE_BITS)", NUM_DEC)) { - /* nothing */ - } else if (kt->ikconfig_flags & IKCONFIG_AVAIL) { - if ((ret = get_kernel_config("CONFIG_MEMORY_HOTPLUG", NULL)) == IKCONFIG_Y) { - if ((ret = get_kernel_config("CONFIG_HOTPLUG_SIZE_BITS", &string)) == IKCONFIG_STR) - machdep->section_size_bits = atol(string); - } - - /* arm64: reduce section size for sparsemem */ - if ((ret = get_kernel_config("CONFIG_ARM64_4K_PAGES", NULL)) == IKCONFIG_Y - || (ret = get_kernel_config("CONFIG_ARM64_16K_PAGES", NULL)) == IKCONFIG_Y) - machdep->section_size_bits = _SECTION_SIZE_BITS_5_12; - else if ((ret = get_kernel_config("CONFIG_ARM64_64K_PAGES", NULL)) == IKCONFIG_Y) - machdep->section_size_bits = _SECTION_SIZE_BITS_5_12_64K; + /* section_size_bits for arm64 vendor special case */ + if (is_ikconfig_avail && get_kernel_config("CONFIG_MEMORY_HOTPLUG", NULL) == IKCONFIG_Y) { + if (get_kernel_config("CONFIG_HOTPLUG_SIZE_BITS", &string) == IKCONFIG_STR) + machdep->section_size_bits = atol(string); } - if (CRASHDEBUG(1)) - fprintf(fp, "SECTION_SIZE_BITS: %ld\n", machdep->section_size_bits); +exit: + if (machdep->section_size_bits) { + if (CRASHDEBUG(1)) + fprintf(fp, "SECTION_SIZE_BITS: %ld\n", machdep->section_size_bits); + } else + error(FATAL, "cannot determine SECTION_SIZE_BITS\n"); } /* -- 2.25.1 -- Crash-utility mailing list -- devel@xxxxxxxxxxxxxxxxxxxxxxxxxxx To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxxxxxxxxxxxx https://${domain_name}/admin/lists/devel.lists.crash-utility.osci.io/ Contribution Guidelines: https://github.com/crash-utility/crash/wiki