Re: [PATCH v2] arm64: fix regression for the determination of section_size_bits
by lijiang
Thank you for the update, qiwu.
On Wed, Jul 31, 2024 at 7:45 PM <devel-request(a)lists.crash-utility.osci.io>
wrote:
> Date: Wed, 31 Jul 2024 09:20:30 -0000
> From: qiwu.chen(a)transsion.com
> Subject: [Crash-utility] [PATCH v2] arm64: fix regression for the
> determination of section_size_bits
> To: devel(a)lists.crash-utility.osci.io
> Message-ID: <20240731092030.17290.83380(a)lists.crash-utility.osci.io>
> Content-Type: text/plain; charset="utf-8"
>
> 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(a)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;
> +};
> +
>
This is specific version information related to Android, to be honest, I'm
not very familiar with Android things.
Anyway, I'm wondering if it's possible to not add the specific Android
version information?
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)) {
>
It's not a good idea to decide how your code should be executed by checking
version information, although similar code exists in crash tools, I would
not recommend this way, unless we have no better solutions. Could you
please investigate it more?
Thanks
Lianbo
> 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
>
4 months, 1 week
[PATCH v2] Fix a "Bus error" issue caused by 'crash --osrelease' or crash loading
by Lianbo Jiang
Sometimes, in a production environment, there are still some vmcores
that are incomplete, such as partial header or the data is corrupted.
When crash tool attempts to parse such vmcores, it may fail as below:
$ ./crash --osrelease vmcore
Bus error (core dumped)
or
$ crash vmlinux vmcore
...
Bus error (core dumped)
$
Gdb calltrace:
$ gdb /home/lijiang/src/crash/crash /tmp/core.126301
Core was generated by `./crash --osrelease /home/lijiang/src/39317/vmcore'.
Program terminated with signal SIGBUS, Bus error.
#0 __memcpy_evex_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:831
831 LOAD_ONE_SET((%rsi), PAGE_SIZE, %VMM(4), %VMM(5), %VMM(6), %VMM(7))
(gdb) bt
#0 __memcpy_evex_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:831
#1 0x0000000000651096 in read_dump_header (file=0x7ffc59ddff5f "/home/lijiang/src/39317/vmcore") at diskdump.c:820
#2 0x0000000000651cf3 in is_diskdump (file=0x7ffc59ddff5f "/home/lijiang/src/39317/vmcore") at diskdump.c:1042
#3 0x0000000000502ac9 in get_osrelease (dumpfile=0x7ffc59ddff5f "/home/lijiang/src/39317/vmcore") at main.c:1938
#4 0x00000000004fb2e8 in main (argc=3, argv=0x7ffc59dde3a8) at main.c:271
(gdb) frame 1
#1 0x0000000000651096 in read_dump_header (file=0x7ffc59ddff5f "/home/lijiang/src/39317/vmcore") at diskdump.c:820
820 memcpy(dd->dumpable_bitmap, dd->bitmap + bitmap_len/2,
This may happen on attempting access to a page of the buffer that lies
beyond the end of the mapped file(see the mmap() man page).
Let's add a check to avoid such issues as much as possible, but still
not guarantee that it can work well in any extreme situation.
Fixes: a3344239743b ("diskdump: use mmap/madvise to improve the start-up")
Reported-by: Buland Kumar Singh <bsingh(a)redhat.com>
Signed-off-by: Lianbo Jiang <lijiang(a)redhat.com>
---
diskdump.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/diskdump.c b/diskdump.c
index 1f7118cacfc6..ce3cbb7b12dd 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -805,6 +805,22 @@ restart:
goto err;
}
} else {
+ struct stat sbuf;
+ if (fstat(dd->dfd, &sbuf) != 0) {
+ error(INFO, "Cannot fstat the dump file\n");
+ goto err;
+ }
+
+ /*
+ * For memory regions mapped with the mmap(), attempts access to
+ * a page of the buffer that lies beyond the end of the mapped file,
+ * which may cause SIGBUS(see the mmap() man page).
+ */
+ if (bitmap_len + offset > sbuf.st_size) {
+ error(INFO, "Mmap: Beyond the end of mapped file, corrupted?\n");
+ goto err;
+ }
+
dd->bitmap = mmap(NULL, bitmap_len, PROT_READ,
MAP_SHARED, dd->dfd, offset);
if (dd->bitmap == MAP_FAILED)
--
2.45.1
4 months, 1 week
Re: [PATCH v2 1/3] arm64: Introduction of support for 16K page with 2-level table support
by lijiang
On Fri, Aug 16, 2024 at 11:33 AM <devel-request(a)lists.crash-utility.osci.io>
wrote:
> Date: Fri, 16 Aug 2024 11:30:20 +0800
> From: Kuan-Ying Lee <kuan-ying.lee(a)canonical.com>
> Subject: [Crash-utility] [PATCH v2 1/3] arm64: Introduction of support
> for 16K page with 2-level table support
> To: kuan-ying.lee(a)canonical.com,
> devel(a)lists.crash-utility.osci.io
> Message-ID: <20240816033030.82655-2-kuan-ying.lee(a)canonical.com>
>
> Introduction of ARM64 support for 16K page size with 2-level page
> table and 36 VA bits.
>
> Signed-off-by: Kuan-Ying Lee <kuan-ying.lee(a)canonical.com>
> ---
> arm64.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---
> defs.h | 11 +++++++
> 2 files changed, 101 insertions(+), 4 deletions(-)
>
> diff --git a/arm64.c b/arm64.c
> index 8ed1aaf919d6..e484d20992c0 100644
> --- a/arm64.c
> +++ b/arm64.c
> @@ -42,6 +42,7 @@ static int arm64_kvtop(struct task_context *, ulong,
> physaddr_t *, int);
> static int arm64_uvtop(struct task_context *, ulong, physaddr_t *, int);
> static int arm64_vtop_2level_64k(ulong, ulong, physaddr_t *, int);
> static int arm64_vtop_3level_64k(ulong, ulong, physaddr_t *, int);
> +static int arm64_vtop_2level_16k(ulong, ulong, physaddr_t *, int);
> static int arm64_vtop_3level_16k(ulong, ulong, physaddr_t *, int);
> static int arm64_vtop_3level_4k(ulong, ulong, physaddr_t *, int);
> static int arm64_vtop_4level_4k(ulong, ulong, physaddr_t *, int);
> @@ -412,7 +413,7 @@ arm64_init(int when)
> break;
>
> case 16384:
> - if (machdep->machspec->VA_BITS >
> PGDIR_SHIFT_L3_16K) {
> + if (machdep->machspec->VA_BITS == 47) {
> machdep->flags |= VM_L3_16K;
> if (!machdep->ptrs_per_pgd)
> machdep->ptrs_per_pgd =
> PTRS_PER_PGD_L3_16K;
> @@ -425,8 +426,19 @@ arm64_init(int when)
> if ((machdep->ptbl =
> (char *)malloc(PTRS_PER_PTE_L3_16K *
> 8)) == NULL)
> error(FATAL, "cannot malloc ptbl
> space.");
> + } else if (machdep->machspec->VA_BITS == 36) {
> + machdep->flags |= VM_L2_16K;
> + if (!machdep->ptrs_per_pgd)
> + machdep->ptrs_per_pgd =
> PTRS_PER_PGD_L2_16K;
> + if ((machdep->pgd =
> + (char *)malloc(machdep->ptrs_per_pgd *
> 8)) == NULL)
> + error(FATAL, "cannot malloc pgd
> space.");
> + if ((machdep->ptbl =
> + (char *)malloc(PTRS_PER_PTE_L2_16K *
> 8)) == NULL)
> + error(FATAL, "cannot malloc ptbl
> space.");
> + machdep->pmd = NULL; /* not used */
> } else {
> - error(FATAL, "we only support 47 bits, 3
> level for 16K page now.");
> + error(FATAL, "Do not support 48 bits or 52
> bits, 4-level for 16K page now.");
>
Thank you for the update, Kuan-Ying.
I have no other comments, for v2: Ack
Lianbo
}
> machdep->pud = NULL; /* not used */
> break;
> @@ -1064,6 +1076,8 @@ arm64_dump_machdep_table(ulong arg)
> fprintf(fp, "%sVM_L2_64K", others++ ? "|" : "");
> if (machdep->flags & VM_L3_64K)
> fprintf(fp, "%sVM_L3_64K", others++ ? "|" : "");
> + if (machdep->flags & VM_L2_16K)
> + fprintf(fp, "%sVM_L2_16K", others++ ? "|" : "");
> if (machdep->flags & VM_L3_16K)
> fprintf(fp, "%sVM_L3_16K", others++ ? "|" : "");
> if (machdep->flags & VM_L3_4K)
> @@ -1113,6 +1127,8 @@ arm64_dump_machdep_table(ulong arg)
> "arm64_vtop_3level_4k" :
> machdep->flags & VM_L4_4K ?
> "arm64_vtop_4level_4k" :
> + machdep->flags & VM_L2_16K ?
> + "arm64_vtop_2level_16k" :
> machdep->flags & VM_L3_16K ?
> "arm64_vtop_3level_16k" :
> machdep->flags & VM_L3_64K ?
> @@ -1122,6 +1138,8 @@ arm64_dump_machdep_table(ulong arg)
> "arm64_vtop_3level_4k" :
> machdep->flags & VM_L4_4K ?
> "arm64_vtop_4level_4k" :
> + machdep->flags & VM_L2_16K ?
> + "arm64_vtop_2level_16k" :
> machdep->flags & VM_L3_16K ?
> "arm64_vtop_3level_16k" :
> machdep->flags & VM_L3_64K ?
> @@ -1814,7 +1832,7 @@ arm64_kvtop(struct task_context *tc, ulong kvaddr,
> physaddr_t *paddr, int verbos
> kernel_pgd = vt->kernel_pgd[0];
> *paddr = 0;
>
> - switch (machdep->flags &
> (VM_L2_64K|VM_L3_64K|VM_L3_4K|VM_L4_4K|VM_L3_16K))
> + switch (machdep->flags &
> (VM_L2_64K|VM_L3_64K|VM_L3_4K|VM_L4_4K|VM_L2_16K|VM_L3_16K))
> {
> case VM_L2_64K:
> return arm64_vtop_2level_64k(kernel_pgd, kvaddr, paddr,
> verbose);
> @@ -1824,6 +1842,8 @@ arm64_kvtop(struct task_context *tc, ulong kvaddr,
> physaddr_t *paddr, int verbos
> return arm64_vtop_3level_4k(kernel_pgd, kvaddr, paddr,
> verbose);
> case VM_L4_4K:
> return arm64_vtop_4level_4k(kernel_pgd, kvaddr, paddr,
> verbose);
> + case VM_L2_16K:
> + return arm64_vtop_2level_16k(kernel_pgd, kvaddr, paddr,
> verbose);
> case VM_L3_16K:
> return arm64_vtop_3level_16k(kernel_pgd, kvaddr, paddr,
> verbose);
> default:
> @@ -1841,7 +1861,7 @@ arm64_uvtop(struct task_context *tc, ulong uvaddr,
> physaddr_t *paddr, int verbos
>
> *paddr = 0;
>
> - switch (machdep->flags &
> (VM_L2_64K|VM_L3_64K|VM_L3_4K|VM_L4_4K|VM_L3_16K))
> + switch (machdep->flags &
> (VM_L2_64K|VM_L3_64K|VM_L3_4K|VM_L4_4K|VM_L2_16K|VM_L3_16K))
> {
> case VM_L2_64K:
> return arm64_vtop_2level_64k(user_pgd, uvaddr, paddr,
> verbose);
> @@ -1851,6 +1871,8 @@ arm64_uvtop(struct task_context *tc, ulong uvaddr,
> physaddr_t *paddr, int verbos
> return arm64_vtop_3level_4k(user_pgd, uvaddr, paddr,
> verbose);
> case VM_L4_4K:
> return arm64_vtop_4level_4k(user_pgd, uvaddr, paddr,
> verbose);
> + case VM_L2_16K:
> + return arm64_vtop_2level_16k(user_pgd, uvaddr, paddr,
> verbose);
> case VM_L3_16K:
> return arm64_vtop_3level_16k(user_pgd, uvaddr, paddr,
> verbose);
> default:
> @@ -2012,6 +2034,70 @@ no_page:
> return FALSE;
> }
>
> +static int
> +arm64_vtop_2level_16k(ulong pgd, ulong vaddr, physaddr_t *paddr, int
> verbose)
> +{
> + ulong *pgd_base, *pgd_ptr, pgd_val;
> + ulong *pte_base, *pte_ptr, pte_val;
> +
> + if (verbose)
> + fprintf(fp, "PAGE DIRECTORY: %lx\n", pgd);
> +
> + pgd_base = (ulong *)pgd;
> + FILL_PGD(pgd_base, KVADDR, machdep->ptrs_per_pgd * sizeof(ulong));
> + pgd_ptr = pgd_base + (((vaddr) >> PGDIR_SHIFT_L2_16K) &
> (machdep->ptrs_per_pgd - 1));
> + pgd_val = ULONG(machdep->pgd + PAGEOFFSET(pgd_ptr));
> + if (verbose)
> + fprintf(fp, " PGD: %lx => %lx\n", (ulong)pgd_ptr,
> pgd_val);
> + if (!pgd_val)
> + goto no_page;
> +
> + /*
> + * #define __PAGETABLE_PUD_FOLDED
> + * #define __PAGETABLE_PMD_FOLDED
> + */
> +
> + if ((pgd_val & PMD_TYPE_MASK) == PMD_TYPE_SECT) {
> + ulong sectionbase = (pgd_val & SECTION_PAGE_MASK_32MB) &
> PHYS_MASK;
> + if (verbose) {
> + fprintf(fp, " PAGE: %lx (32MB%s)\n\n",
> sectionbase,
> + IS_ZEROPAGE(sectionbase) ? ", ZERO PAGE" :
> "");
> + arm64_translate_pte(pgd_val, 0, 0);
> + }
> + *paddr = sectionbase + (vaddr & ~SECTION_PAGE_MASK_32MB);
> + return TRUE;
> + }
> +
> + pte_base = (ulong *)PTOV(pgd_val & PHYS_MASK &
> (s32)machdep->pagemask);
> + FILL_PTBL(pte_base, KVADDR, PTRS_PER_PTE_L2_16K * sizeof(ulong));
> + pte_ptr = pte_base + (((vaddr) >> machdep->pageshift) &
> (PTRS_PER_PTE_L2_16K - 1));
> + pte_val = ULONG(machdep->ptbl + PAGEOFFSET(pte_ptr));
> + if (verbose)
> + fprintf(fp, " PTE: %lx => %lx\n", (ulong)pte_ptr,
> pte_val);
> + if (!pte_val)
> + goto no_page;
> +
> + if (pte_val & PTE_VALID) {
> + *paddr = (PAGEBASE(pte_val) & PHYS_MASK) +
> PAGEOFFSET(vaddr);
> + if (verbose) {
> + fprintf(fp, " PAGE: %lx %s\n\n",
> PAGEBASE(*paddr),
> + IS_ZEROPAGE(PAGEBASE(*paddr)) ? "(ZERO
> PAGE)" : "");
> + arm64_translate_pte(pte_val, 0, 0);
> + }
> + } else {
> + if (IS_UVADDR(vaddr, NULL))
> + *paddr = pte_val;
> + if (verbose) {
> + fprintf(fp, "\n");
> + arm64_translate_pte(pte_val, 0, 0);
> + }
> + goto no_page;
> + }
> +
> + return TRUE;
> +no_page:
> + return FALSE;
> +}
> static int
> arm64_vtop_3level_16k(ulong pgd, ulong vaddr, physaddr_t *paddr, int
> verbose)
> {
> diff --git a/defs.h b/defs.h
> index 1b7649d9f05c..dfbd2419f969 100644
> --- a/defs.h
> +++ b/defs.h
> @@ -3302,6 +3302,16 @@ typedef signed int s32;
> #define PGDIR_MASK_48VA (~(PGDIR_SIZE_48VA - 1))
> #define PGDIR_OFFSET_48VA(X) (((ulong)(X)) & (PGDIR_SIZE_48VA - 1))
>
> +/*
> + * 2-levels / 16K pages
> + * 36-bit VA
> + */
> +#define PTRS_PER_PGD_L2_16K (2048)
> +#define PTRS_PER_PTE_L2_16K (2048)
> +#define PGDIR_SHIFT_L2_16K (25)
> +#define PGDIR_SIZE_L2_16K ((1UL) << PGDIR_SHIFT_L2_16K)
> +#define PGDIR_MASK_L2_16K (~(PGDIR_SIZE_L2_16K-1))
> +
> /*
> * 3-levels / 16K pages
> * 47-bit VA
> @@ -3383,6 +3393,7 @@ typedef signed int s32;
> #define OVERFLOW_STACKS (0x1000)
> #define ARM64_MTE (0x2000)
> #define VM_L3_16K (0x4000)
> +#define VM_L2_16K (0x8000)
>
> /*
> * Get kimage_voffset from /dev/crash
> --
> 2.43.0
>
4 months, 1 week
[PATCH v2 0/3] arm64: Introduction of support 16K page with 2-level table
by Kuan-Ying Lee
1. Add support to 16K page size and 2-level page table with 36 VA bits.
2. Fix pmd, pud description when we use 'help -m'.
v1 -> v2:
- Fix indent issue
- Check if VA_BITS is supported for 16K page. For now, we only
support [47 bits, 3-level] and [36 bits, 2-level]. Do not
support 48 or 52 bits for 16K page now.
Kuan-Ying Lee (3):
arm64: Introduction of support for 16K page with 2-level table support
arm64: fix pmd description
arm64: simplify pud description
arm64.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
defs.h | 11 +++++++
2 files changed, 103 insertions(+), 8 deletions(-)
--
2.43.0
4 months, 1 week
Re: [PATCH] s390x: Fix "bt -f/-F" command fail with seek error
by lijiang
On Thu, Aug 15, 2024 at 3:23 PM <devel-request(a)lists.crash-utility.osci.io>
wrote:
> Date: Wed, 14 Aug 2024 18:34:57 +1200
> From: Tao Liu <ltao(a)redhat.com>
> Subject: [Crash-utility] [PATCH] s390x: Fix "bt -f/-F" command fail
> with seek error
> To: devel(a)lists.crash-utility.osci.io
> Cc: Tao Liu <ltao(a)redhat.com>
> Message-ID: <20240814063457.17633-1-ltao(a)redhat.com>
> Content-Type: text/plain; charset="US-ASCII"; x-default=true
>
> Previously a fail of cmd "bt -f/-F" observed:
>
> crash> bt -f
> PID: 3359 TASK: 28b01a09400 CPU: 0 COMMAND: "runtest.sh"
> LOWCORE INFO:
> ...
> -general registers:
> 0x0000000034dd9140 0x0000039600000002
> 0x00000396cad7dfa0 0x0000028b03ba5000
> ...
> 0000028c6e9fffd8: 0000000000000000 0000000000000000
> 0000028c6e9fffe8: 0000000000000000 0000000000000000
> 0000028c6e9ffff8: 0000000000000000bt: seek error: kernel virtual
> address: 28c6ea00000 type: "readmem_ul"
>
> The root cause is kernel commit ce3dc447493ff ("s390: add support for
> virtually
> mapped kernel stacks") replaced "panic_task" by "nodat_stack", which
> leading a wrong stack base/top calculation.
>
> This patch fix the bug by checking if nodat_stack member is exist in struct
> lowcore.
>
>
Thank you for the fix, Tao.
Looks good. Applied:
https://github.com/crash-utility/crash/commit/5218919ec108bac0132b20fe18c...
Thanks
Lianbo
> Signed-off-by: Tao Liu <ltao(a)redhat.com>
> ---
> s390x.c | 8 +++++++-
> 1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/s390x.c b/s390x.c
> index 794ae82..ad69184 100644
> --- a/s390x.c
> +++ b/s390x.c
> @@ -1797,7 +1797,13 @@ static void s390x_back_trace_cmd(struct bt_info *bt)
> cpu, lowcore, &low, &high);
> sp = show_trace(bt, cnt, sp, low, high);
> }
> - get_int_stack("panic_stack", cpu, lowcore, &low, &high);
> + if (MEMBER_EXISTS("lowcore", "nodat_stack")) {
> + get_int_stack("nodat_stack",
> + cpu, lowcore, &low, &high);
> + } else {
> + get_int_stack("panic_stack",
> + cpu, lowcore, &low, &high);
> + }
> sp = show_trace(bt, cnt, sp, low, high);
> get_int_stack("async_stack", cpu, lowcore, &low, &high);
> sp = show_trace(bt, cnt, sp, low, high);
> --
> 2.40.1
>
4 months, 1 week
Re: [PATCH 1/3] arm64: Introduction of support for 16K page with 2-level table support
by lijiang
Thank you for the patch, Kuan-Ying.
On Thu, Aug 8, 2024 at 9:09 PM <devel-request(a)lists.crash-utility.osci.io>
wrote:
> Date: Thu, 8 Aug 2024 13:35:41 +0800
> From: Kuan-Ying Lee <kuan-ying.lee(a)canonical.com>
> Subject: [Crash-utility] [PATCH 1/3] arm64: Introduction of support
> for 16K page with 2-level table support
> To: kuan-ying.lee(a)canonical.com,
> devel(a)lists.crash-utility.osci.io
> Message-ID: <20240808053543.10910-2-kuan-ying.lee(a)canonical.com>
>
> Introduction of ARM64 support for 16K page size with 2-level page
> table and 36 VA bits.
>
> Signed-off-by: Kuan-Ying Lee <kuan-ying.lee(a)canonical.com>
> ---
> arm64.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
> defs.h | 11 +++++++
> 2 files changed, 98 insertions(+), 3 deletions(-)
>
> diff --git a/arm64.c b/arm64.c
> index 8ed1aaf919d6..002cc0078dad 100644
> --- a/arm64.c
> +++ b/arm64.c
> @@ -42,6 +42,7 @@ static int arm64_kvtop(struct task_context *, ulong,
> physaddr_t *, int);
> static int arm64_uvtop(struct task_context *, ulong, physaddr_t *, int);
> static int arm64_vtop_2level_64k(ulong, ulong, physaddr_t *, int);
> static int arm64_vtop_3level_64k(ulong, ulong, physaddr_t *, int);
> +static int arm64_vtop_2level_16k(ulong, ulong, physaddr_t *, int);
> static int arm64_vtop_3level_16k(ulong, ulong, physaddr_t *, int);
> static int arm64_vtop_3level_4k(ulong, ulong, physaddr_t *, int);
> static int arm64_vtop_4level_4k(ulong, ulong, physaddr_t *, int);
> @@ -426,7 +427,16 @@ arm64_init(int when)
> (char *)malloc(PTRS_PER_PTE_L3_16K *
> 8)) == NULL)
> error(FATAL, "cannot malloc ptbl
> space.");
> } else {
> - error(FATAL, "we only support 47 bits, 3
> level for 16K page now.");
>
I copied it from kernel code here:
config PGTABLE_LEVELS
int
default 2 if ARM64_16K_PAGES && ARM64_VA_BITS_36
default 2 if ARM64_64K_PAGES && ARM64_VA_BITS_42
default 3 if ARM64_64K_PAGES && (ARM64_VA_BITS_48 ||
ARM64_VA_BITS_52)
default 3 if ARM64_4K_PAGES && ARM64_VA_BITS_39
default 3 if ARM64_16K_PAGES && ARM64_VA_BITS_47
default 4 if ARM64_16K_PAGES && (ARM64_VA_BITS_48 ||
ARM64_VA_BITS_52)
default 4 if !ARM64_64K_PAGES && ARM64_VA_BITS_48
default 5 if ARM64_4K_PAGES && ARM64_VA_BITS_52
Crash tools do not support 16K pages with 4-level tables and 48 or 52 VA
bits, is it possible to add a similar check for this one? I'm not sure if
you have any plans to support it.
BTW: It also has the same issue in the [PATCH 3/3].
+ machdep->flags |= VM_L2_16K;
> + if (!machdep->ptrs_per_pgd)
> + machdep->ptrs_per_pgd =
> PTRS_PER_PGD_L2_16K;
> + if ((machdep->pgd =
> + (char *)malloc(machdep->ptrs_per_pgd *
> 8)) == NULL)
> + error(FATAL, "cannot malloc pgd
> space.");
> + if ((machdep->ptbl =
> + (char *)malloc(PTRS_PER_PTE_L2_16K *
> 8)) == NULL)
> + error(FATAL, "cannot malloc ptbl
> space.");
> + machdep->pmd = NULL; /* not used */
> }
> machdep->pud = NULL; /* not used */
> break;
> @@ -1064,6 +1074,8 @@ arm64_dump_machdep_table(ulong arg)
> fprintf(fp, "%sVM_L2_64K", others++ ? "|" : "");
> if (machdep->flags & VM_L3_64K)
> fprintf(fp, "%sVM_L3_64K", others++ ? "|" : "");
> + if (machdep->flags & VM_L2_16K)
> + fprintf(fp, "%sVM_L2_16K", others++ ? "|" : "");
> if (machdep->flags & VM_L3_16K)
> fprintf(fp, "%sVM_L3_16K", others++ ? "|" : "");
> if (machdep->flags & VM_L3_4K)
> @@ -1113,6 +1125,8 @@ arm64_dump_machdep_table(ulong arg)
> "arm64_vtop_3level_4k" :
> machdep->flags & VM_L4_4K ?
> "arm64_vtop_4level_4k" :
> + machdep->flags & VM_L2_16K ?
> + "arm64_vtop_2level_16k" :
> machdep->flags & VM_L3_16K ?
> "arm64_vtop_3level_16k" :
> machdep->flags & VM_L3_64K ?
> @@ -1122,6 +1136,8 @@ arm64_dump_machdep_table(ulong arg)
> "arm64_vtop_3level_4k" :
> machdep->flags & VM_L4_4K ?
> "arm64_vtop_4level_4k" :
> + machdep->flags & VM_L2_16K ?
> + "arm64_vtop_2level_16k" :
> machdep->flags & VM_L3_16K ?
> "arm64_vtop_3level_16k" :
> machdep->flags & VM_L3_64K ?
> @@ -1814,7 +1830,7 @@ arm64_kvtop(struct task_context *tc, ulong kvaddr,
> physaddr_t *paddr, int verbos
> kernel_pgd = vt->kernel_pgd[0];
> *paddr = 0;
>
> - switch (machdep->flags &
> (VM_L2_64K|VM_L3_64K|VM_L3_4K|VM_L4_4K|VM_L3_16K))
> + switch (machdep->flags &
> (VM_L2_64K|VM_L3_64K|VM_L3_4K|VM_L4_4K|VM_L2_16K|VM_L3_16K))
> {
> case VM_L2_64K:
> return arm64_vtop_2level_64k(kernel_pgd, kvaddr, paddr,
> verbose);
> @@ -1824,6 +1840,8 @@ arm64_kvtop(struct task_context *tc, ulong kvaddr,
> physaddr_t *paddr, int verbos
> return arm64_vtop_3level_4k(kernel_pgd, kvaddr, paddr,
> verbose);
> case VM_L4_4K:
> return arm64_vtop_4level_4k(kernel_pgd, kvaddr, paddr,
> verbose);
> + case VM_L2_16K:
> + return arm64_vtop_2level_16k(kernel_pgd, kvaddr, paddr,
> verbose);
> case VM_L3_16K:
> return arm64_vtop_3level_16k(kernel_pgd, kvaddr, paddr,
> verbose);
> default:
> @@ -1841,7 +1859,7 @@ arm64_uvtop(struct task_context *tc, ulong uvaddr,
> physaddr_t *paddr, int verbos
>
> *paddr = 0;
>
> - switch (machdep->flags &
> (VM_L2_64K|VM_L3_64K|VM_L3_4K|VM_L4_4K|VM_L3_16K))
> + switch (machdep->flags &
> (VM_L2_64K|VM_L3_64K|VM_L3_4K|VM_L4_4K|VM_L2_16K|VM_L3_16K))
> {
> case VM_L2_64K:
> return arm64_vtop_2level_64k(user_pgd, uvaddr, paddr,
> verbose);
> @@ -1851,6 +1869,8 @@ arm64_uvtop(struct task_context *tc, ulong uvaddr,
> physaddr_t *paddr, int verbos
> return arm64_vtop_3level_4k(user_pgd, uvaddr, paddr,
> verbose);
> case VM_L4_4K:
> return arm64_vtop_4level_4k(user_pgd, uvaddr, paddr,
> verbose);
> + case VM_L2_16K:
> + return arm64_vtop_2level_16k(user_pgd, uvaddr, paddr,
> verbose);
> case VM_L3_16K:
> return arm64_vtop_3level_16k(user_pgd, uvaddr, paddr,
> verbose);
> default:
> @@ -2012,6 +2032,70 @@ no_page:
> return FALSE;
> }
>
> +static int
> +arm64_vtop_2level_16k(ulong pgd, ulong vaddr, physaddr_t *paddr, int
> verbose)
> +{
> + ulong *pgd_base, *pgd_ptr, pgd_val;
> + ulong *pte_base, *pte_ptr, pte_val;
> +
> + if (verbose)
> + fprintf(fp, "PAGE DIRECTORY: %lx\n", pgd);
> +
> + pgd_base = (ulong *)pgd;
> + FILL_PGD(pgd_base, KVADDR, machdep->ptrs_per_pgd * sizeof(ulong));
> + pgd_ptr = pgd_base + (((vaddr) >> PGDIR_SHIFT_L2_16K) &
> (machdep->ptrs_per_pgd - 1));
> + pgd_val = ULONG(machdep->pgd + PAGEOFFSET(pgd_ptr));
> + if (verbose)
> + fprintf(fp, " PGD: %lx => %lx\n", (ulong)pgd_ptr,
> pgd_val);
> + if (!pgd_val)
> + goto no_page;
> +
> + /*
> + * #define __PAGETABLE_PUD_FOLDED
> + * #define __PAGETABLE_PMD_FOLDED
> + */
> +
> + if ((pgd_val & PMD_TYPE_MASK) == PMD_TYPE_SECT) {
> + ulong sectionbase = (pgd_val & SECTION_PAGE_MASK_32MB) &
> PHYS_MASK;
> + if (verbose) {
> + fprintf(fp, " PAGE: %lx (32MB%s)\n\n",
> sectionbase,
> + IS_ZEROPAGE(sectionbase) ? ", ZERO PAGE" :
> "");
> + arm64_translate_pte(pgd_val, 0, 0);
> + }
> + *paddr = sectionbase + (vaddr & ~SECTION_PAGE_MASK_32MB);
> + return TRUE;
> + }
> +
> + pte_base = (ulong *)PTOV(pgd_val & PHYS_MASK &
> (s32)machdep->pagemask);
> + FILL_PTBL(pte_base, KVADDR, PTRS_PER_PTE_L2_16K * sizeof(ulong));
> + pte_ptr = pte_base + (((vaddr) >> machdep->pageshift) &
> (PTRS_PER_PTE_L2_16K - 1));
> + pte_val = ULONG(machdep->ptbl + PAGEOFFSET(pte_ptr));
> + if (verbose)
> + fprintf(fp, " PTE: %lx => %lx\n", (ulong)pte_ptr,
> pte_val);
> + if (!pte_val)
> + goto no_page;
> +
> + if (pte_val & PTE_VALID) {
> + *paddr = (PAGEBASE(pte_val) & PHYS_MASK) +
> PAGEOFFSET(vaddr);
> + if (verbose) {
> + fprintf(fp, " PAGE: %lx %s\n\n",
> PAGEBASE(*paddr),
> + IS_ZEROPAGE(PAGEBASE(*paddr)) ? "(ZERO
> PAGE)" : "");
> + arm64_translate_pte(pte_val, 0, 0);
> + }
> + } else {
> + if (IS_UVADDR(vaddr, NULL))
> + *paddr = pte_val;
> + if (verbose) {
> + fprintf(fp, "\n");
> + arm64_translate_pte(pte_val, 0, 0);
> + }
> + goto no_page;
> + }
> +
> + return TRUE;
> +no_page:
> + return FALSE;
> +}
>
The above code seems to have an indentation issue, other changes are fine
to me.
Thanks
Lianbo
> static int
> arm64_vtop_3level_16k(ulong pgd, ulong vaddr, physaddr_t *paddr, int
> verbose)
> {
> diff --git a/defs.h b/defs.h
> index 1b7649d9f05c..dfbd2419f969 100644
> --- a/defs.h
> +++ b/defs.h
> @@ -3302,6 +3302,16 @@ typedef signed int s32;
> #define PGDIR_MASK_48VA (~(PGDIR_SIZE_48VA - 1))
> #define PGDIR_OFFSET_48VA(X) (((ulong)(X)) & (PGDIR_SIZE_48VA - 1))
>
> +/*
> + * 2-levels / 16K pages
> + * 36-bit VA
> + */
> +#define PTRS_PER_PGD_L2_16K (2048)
> +#define PTRS_PER_PTE_L2_16K (2048)
> +#define PGDIR_SHIFT_L2_16K (25)
> +#define PGDIR_SIZE_L2_16K ((1UL) << PGDIR_SHIFT_L2_16K)
> +#define PGDIR_MASK_L2_16K (~(PGDIR_SIZE_L2_16K-1))
> +
> /*
> * 3-levels / 16K pages
> * 47-bit VA
> @@ -3383,6 +3393,7 @@ typedef signed int s32;
> #define OVERFLOW_STACKS (0x1000)
> #define ARM64_MTE (0x2000)
> #define VM_L3_16K (0x4000)
> +#define VM_L2_16K (0x8000)
>
> /*
> * Get kimage_voffset from /dev/crash
> --
> 2.34.1
>
4 months, 1 week
[PATCH 0/3] arm64: Introduction of support 16K page with 2-level table
by Kuan-Ying Lee
1. Add support to 16K page size and 2-level page table with 36 VA bits.
2. Fix pmd, pud description when we use 'help -m'.
Kuan-Ying Lee (3):
arm64: Introduction of support for 16K page with 2-level table support
arm64: fix pmd description
arm64: simplify pud description
arm64.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++-----
defs.h | 11 +++++++
2 files changed, 100 insertions(+), 7 deletions(-)
--
2.34.1
4 months, 2 weeks
[PATCH] s390x: Fix "bt -f/-F" command fail with seek error
by Tao Liu
Previously a fail of cmd "bt -f/-F" observed:
crash> bt -f
PID: 3359 TASK: 28b01a09400 CPU: 0 COMMAND: "runtest.sh"
LOWCORE INFO:
...
-general registers:
0x0000000034dd9140 0x0000039600000002
0x00000396cad7dfa0 0x0000028b03ba5000
...
0000028c6e9fffd8: 0000000000000000 0000000000000000
0000028c6e9fffe8: 0000000000000000 0000000000000000
0000028c6e9ffff8: 0000000000000000bt: seek error: kernel virtual
address: 28c6ea00000 type: "readmem_ul"
The root cause is kernel commit ce3dc447493ff ("s390: add support for virtually
mapped kernel stacks") replaced "panic_task" by "nodat_stack", which
leading a wrong stack base/top calculation.
This patch fix the bug by checking if nodat_stack member is exist in struct
lowcore.
Signed-off-by: Tao Liu <ltao(a)redhat.com>
---
s390x.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/s390x.c b/s390x.c
index 794ae82..ad69184 100644
--- a/s390x.c
+++ b/s390x.c
@@ -1797,7 +1797,13 @@ static void s390x_back_trace_cmd(struct bt_info *bt)
cpu, lowcore, &low, &high);
sp = show_trace(bt, cnt, sp, low, high);
}
- get_int_stack("panic_stack", cpu, lowcore, &low, &high);
+ if (MEMBER_EXISTS("lowcore", "nodat_stack")) {
+ get_int_stack("nodat_stack",
+ cpu, lowcore, &low, &high);
+ } else {
+ get_int_stack("panic_stack",
+ cpu, lowcore, &low, &high);
+ }
sp = show_trace(bt, cnt, sp, low, high);
get_int_stack("async_stack", cpu, lowcore, &low, &high);
sp = show_trace(bt, cnt, sp, low, high);
--
2.40.1
4 months, 2 weeks
Re: [PATCH v2] Fix a segfault issue due to the incorrect irq_stack_size on ARM64
by lijiang
On Wed, Aug 14, 2024 at 9:44 AM <devel-request(a)lists.crash-utility.osci.io>
wrote:
> Date: Wed, 14 Aug 2024 11:25:24 +1200
> From: Tao Liu <ltao(a)redhat.com>
> Subject: [Crash-utility] [PATCH v2] Fix a segfault issue due to the
> incorrect irq_stack_size on ARM64
> To: devel(a)lists.crash-utility.osci.io
> Cc: "yeping . zheng" <yeping.zheng(a)nio.com>
> Message-ID: <20240813232523.7237-1-ltao(a)redhat.com>
> Content-Type: text/plain; charset="US-ASCII"; x-default=true
>
> See the following stack trace:
> (gdb) bt
> #0 0x00005635ac2b166b in arm64_unwind_frame (frame=0x7ffdaf35cb70,
> bt=0x7ffdaf35d430) at arm64.c:2821
> #1 arm64_back_trace_cmd (bt=0x7ffdaf35d430) at arm64.c:3306
> #2 0x00005635ac27b108 in back_trace (bt=bt@entry=0x7ffdaf35d430) at
> kernel.c:3239
> #3 0x00005635ac2880ae in cmd_bt () at kernel.c:2863
> #4 0x00005635ac1f16dc in exec_command () at main.c:893
> #5 0x00005635ac1f192a in main_loop () at main.c:840
> #6 0x00005635ac50df81 in captured_main (data=<optimized out>) at
> main.c:1284
> #7 gdb_main (args=<optimized out>) at main.c:1313
> #8 0x00005635ac50e000 in gdb_main_entry (argc=<optimized out>,
> argv=<optimized out>) at main.c:1338
> #9 0x00005635ac1ea2a5 in main (argc=5, argv=0x7ffdaf35dde8) at main.c:721
>
> The issue may be encountered when thread_union symbol not found in vmlinux
> due to compiling optimization.
>
> This patch will try the following 2 methods to get the irq_stack_size
> when thread_union symbol unavailable:
>
> 1. change the thread_shift when KASAN is enabled and with vmcoreinfo.
> In arm64/include/asm/memory.h:
>
> #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
> ...
> #define IRQ_STACK_SIZE THREAD_SIZE
>
> Since enabling the KASAN will affect the final value,
> this patch reset IRQ_STACK_SIZE according to the calculation process in
> kernel code.
>
> 2. Try getting the value from kernel code disassembly, to get
> THREAD_SHIFT directly from tbnz instruction.
>
> In arch/arm64/kernel/entry.S:
> .macro kernel_ventry, el:req, ht:req, regsize:req, label:req
> ...
> add sp, sp, x0
> sub x0, sp, x0
> tbnz x0, #THREAD_SHIFT, 0f
>
> $ gdb vmlinux
> (gdb) disass vectors
> Dump of assembler code for function vectors:
> ...
> 0xffff800080010804 <+4>: add sp, sp, x0
> 0xffff800080010808 <+8>: sub x0, sp, x0
> 0xffff80008001080c <+12>: tbnz w0, #16, 0xffff80008001081c
> <vectors+28>
>
> Signed-off-by: yeping.zheng <yeping.zheng(a)nio.com>
> Improved-by: Tao Liu <ltao(a)redhat.com>
> ---
>
> v2 -> v1: Add stack_vm_area member check for task_struct, and kernel
> file reference.
>
> Hi Yeping & lianbo,
>
> Please have a test on this version of patch, I guess this will be the
> last version if test is passed. Thanks in advance!
>
>
Thank you for working on it, Yeping and Tao.
This looks good to me. Applied:
https://github.com/crash-utility/crash/commit/321e1e85458876248c65149ed69...
Thanks
Lianbo
> Thanks,
> Tao Liu
>
> ---
> arm64.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 61 insertions(+), 2 deletions(-)
>
> diff --git a/arm64.c b/arm64.c
> index 067c879..332e3f0 100644
> --- a/arm64.c
> +++ b/arm64.c
> @@ -95,6 +95,7 @@ static int arm64_is_uvaddr(ulong, struct task_context *);
> 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);
> +static ulong arm64_set_irq_stack_size(void);
>
> struct kernel_range {
> unsigned long modules_vaddr, modules_end;
> @@ -2340,8 +2341,10 @@ arm64_irq_stack_init(void)
> if (MEMBER_EXISTS("thread_union", "stack")) {
> if ((sz = MEMBER_SIZE("thread_union", "stack")) >
> 0)
> ms->irq_stack_size = sz;
> - } else
> - ms->irq_stack_size = ARM64_IRQ_STACK_SIZE;
> + } else {
> + ulong res = arm64_set_irq_stack_size();
> + ms->irq_stack_size = (res > 0) ? res :
> ARM64_IRQ_STACK_SIZE;
> + }
>
> machdep->flags |= IRQ_STACKS;
>
> @@ -5056,6 +5059,62 @@ static void arm64_recalc_KERNELPACMASK(void){
> }
> }
>
> +static ulong arm64_set_irq_stack_size(void)
> +{
> + int min_thread_shift = 14;
> + ulong thread_shift = 0;
> + char buf1[BUFSIZE];
> + char *pos1, *pos2;
> + int errflag = 0;
> +
> + if (kernel_symbol_exists("vmcoreinfo_data") &&
> + kernel_symbol_exists("vmcoreinfo_size")) {
> + /*
> + * Referring to arch/arm64/include/asm/memory.h
> + */
> + if (kernel_symbol_exists("kasan_enable_current")) {
> + min_thread_shift += 1;
> + }
> + if (MEMBER_EXISTS("task_struct", "stack_vm_area") &&
> + min_thread_shift < machdep->pageshift) {
> + thread_shift = machdep->pageshift;
> + } else {
> + thread_shift = min_thread_shift;
> + }
> + } else {
> + sprintf(buf1, "x/32i vectors");
> + open_tmpfile();
> + if (!gdb_pass_through(buf1, pc->tmpfile,
> GNU_RETURN_ON_ERROR)) {
> + goto out;
> + }
> + rewind(pc->tmpfile);
> + while (fgets(buf1, BUFSIZE, pc->tmpfile)) {
> + if ((pos1 = strstr(buf1, "tbnz"))) {
> + if ((pos2 = strchr(pos1, '#'))) {
> + pos2 += 1;
> + for (pos1 = pos2;
> + *pos2 != '\0' && *pos2 != ',';
> + pos2++);
> + *pos2 = '\0';
> + thread_shift = stol(pos1,
> + RETURN_ON_ERROR|QUIET,
> &errflag);
> + if (errflag) {
> + thread_shift = 0;
> + }
> + break;
> + }
> + }
> + }
> +out:
> + close_tmpfile();
> + }
> +
> + if (thread_shift)
> + return ((1UL) << thread_shift);
> + else
> + return 0;
> +}
> +
> #endif /* ARM64 */
>
>
> --
> 2.40.1
>
4 months, 2 weeks
Fix irq_stack_size on ARM64
by wonderzyp@gmail.com
When using the crash tool to parse the ARM64 dump file with KASAN enabled, I found that using the bt -a command will cause this tool to crash, the following is the backtrace infomation.
(gdb) bt
#0 0x00005635ac2b166b in arm64_unwind_frame (frame=0x7ffdaf35cb70, bt=0x7ffdaf35d430)
at arm64.c:2821
#1 arm64_back_trace_cmd (bt=0x7ffdaf35d430) at arm64.c:3306
#2 0x00005635ac27b108 in back_trace (bt=bt@entry=0x7ffdaf35d430) at kernel.c:3239
#3 0x00005635ac2880ae in cmd_bt () at kernel.c:2863
#4 0x00005635ac1f16dc in exec_command () at main.c:893
#5 0x00005635ac1f192a in main_loop () at main.c:840
#6 0x00005635ac50df81 in captured_main (data=<optimized out>) at main.c:1284
#7 gdb_main (args=<optimized out>) at main.c:1313
#8 0x00005635ac50e000 in gdb_main_entry (argc=<optimized out>, argv=<optimized out>)
at main.c:1338
#9 0x00005635ac1ea2a5 in main (argc=5, argv=0x7ffdaf35dde8) at main.c:721
Eventually, I found that it was may caused by not setting irq_stack_size properly, and provide this patch to solve it.
From 34b28aa8c11e77d20adec4f7705a14d239c8a55f Mon Sep 17 00:00:00 2001
From: wonderzyp <wonderzyp(a)qq.com>
Date: Mon, 8 Jul 2024 20:11:38 +0800
Subject: [PATCH 1131/1131] set_arm64_irq_stack_size
Signed-off-by: Yeping Zheng <wonderzyp(a)gmail.com>
---
arm64.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 47 insertions(+), 2 deletions(-)
diff --git a/arm64.c b/arm64.c
index b3040d7..39d891b 100644
--- a/arm64.c
+++ b/arm64.c
@@ -93,6 +93,7 @@ static void arm64_calc_VA_BITS(void);
static int arm64_is_uvaddr(ulong, struct task_context *);
static void arm64_calc_KERNELPACMASK(void);
static int arm64_get_vmcoreinfo(unsigned long *vaddr, const char *label, int base);
+static ulong arm64_set_irq_stack_size(struct machine_specific *ms);
struct kernel_range {
unsigned long modules_vaddr, modules_end;
@@ -2223,8 +2224,14 @@ arm64_irq_stack_init(void)
if (MEMBER_EXISTS("thread_union", "stack")) {
if ((sz = MEMBER_SIZE("thread_union", "stack")) > 0)
ms->irq_stack_size = sz;
- } else
- ms->irq_stack_size = ARM64_IRQ_STACK_SIZE;
+ } else {
+ ulong res = arm64_set_irq_stack_size(ms);
+ if (res > 0){
+ ms->irq_stack_size = res;
+ } else {
+ ms->irq_stack_size = ARM64_IRQ_STACK_SIZE;
+ }
+ }
machdep->flags |= IRQ_STACKS;
@@ -4921,6 +4928,44 @@ static void arm64_calc_KERNELPACMASK(void)
}
}
+static ulong arm64_set_irq_stack_size(struct machine_specific *ms)
+{
+ char *string;
+ int ret;
+ int KASAN_THREAD_SHIFT = 0;
+ int MIN_THREAD_SHIFT;
+ ulong ARM64_PAGE_SHIFT;
+ ulong THREAD_SHIFT = 0;
+ ulong THREAD_SIZE;
+ if (kt->ikconfig_flags & IKCONFIG_AVAIL) {
+ if ((ret = get_kernel_config("CONFIG_KASAN_GENERIC", NULL) == IKCONFIG_Y) ||
+ (ret = get_kernel_config("CONFIG_KASAN_SW_TAGS", NULL) == IKCONFIG_Y)) {
+ KASAN_THREAD_SHIFT = 1;
+ }
+ }
+ MIN_THREAD_SHIFT = 14 + KASAN_THREAD_SHIFT;
+
+ if (kt->ikconfig_flags & IKCONFIG_AVAIL) {
+ if ((ret = get_kernel_config("CONFIG_VMAP_STACK", NULL)) == IKCONFIG_Y){
+ if ((ret = get_kernel_config("CONFIG_ARM64_PAGE_SHIFT", &string)) == IKCONFIG_STR){
+ ARM64_PAGE_SHIFT = atol(string);
+ }
+ if (MIN_THREAD_SHIFT < ARM64_PAGE_SHIFT){
+ THREAD_SHIFT = ARM64_PAGE_SHIFT;
+ } else {
+ THREAD_SHIFT = MIN_THREAD_SHIFT;
+ }
+ }
+ }
+
+ if (THREAD_SHIFT == 0) {
+ return -1;
+ }
+
+ THREAD_SIZE = ((1UL) << THREAD_SHIFT);
+ return THREAD_SIZE;
+}
+
#endif /* ARM64 */
--
2.25.1
4 months, 2 weeks