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.c...@transsion.com>
---
 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@lists.crash-utility.osci.io
To unsubscribe send an email to devel-le...@lists.crash-utility.osci.io
https://${domain_name}/admin/lists/devel.lists.crash-utility.osci.io/
Contribution Guidelines: https://github.com/crash-utility/crash/wiki

Reply via email to