Rebase crash to upstream 8.0.6

Resolves: RHEL-59865
Resolves: RHEL-52221
Resolves: RHEL-49762

Signed-off-by: Tao Liu <ltao@redhat.com>
This commit is contained in:
Tao Liu 2024-11-19 10:21:28 +13:00
parent 48485aa655
commit fa67b0d9fe
21 changed files with 16 additions and 2215 deletions

1
.gitignore vendored
View File

@ -50,5 +50,6 @@ crash-5.0.6.tar.gz
/crash-8.0.3.tar.gz
/crash-8.0.4.tar.gz
/crash-8.0.5.tar.gz
/crash-8.0.6.tar.gz
/gdb-7.6.tar.gz
/gdb-10.2.tar.gz

View File

@ -1,492 +0,0 @@
From a584e9752fb2198c7f6d0130d8a94b17581f33c6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Yulong=20TANG=20=E6=B1=A4=E7=8E=89=E9=BE=99?=
<yulong.tang@nio.com>
Date: Tue, 20 Feb 2024 15:09:49 +0800
Subject: [PATCH 1/9] Adding the zram decompression algorithm "lzo-rle"
Port the improved decompression method for "lzo" in the kernel to
support decompression of "lzorle".
Since Linux 5.1, the default compression algorithm for zram was changed
from "lzo" to "lzo-rle". The crash-utility only supports decompression
for "lzo", when parsing vmcore files that utilize zram compression, such
as when using the gcore command to detach process core dump files,
parsing cannot be completed successfully.
before:
crash> gcore -v 0 1
gcore: WARNING: only the lzo compressor is supported
gcore: WARNING: only the lzo compressor is supported
gcore: WARNING: only the lzo compressor is supported
gcore: WARNING: only the lzo compressor is supported
after:
crash> gcore -v 0 1
Saved core.1.init
Signed-off-by: yulong.tang <yulong.t...@nio.com>
Reviewed-by: Tao Liu <l...@redhat.com>
Signed-off-by: Kazuhito Hagio <k-hagio...@nec.com>
---
Makefile | 13 +-
diskdump.c | 3 +
lzorle_decompress.c | 295 ++++++++++++++++++++++++++++++++++++++++++++
lzorle_decompress.h | 75 +++++++++++
4 files changed, 383 insertions(+), 3 deletions(-)
create mode 100644 lzorle_decompress.c
create mode 100644 lzorle_decompress.h
diff --git a/Makefile b/Makefile
index 9e97313..60dad18 100644
--- a/Makefile
+++ b/Makefile
@@ -60,6 +60,7 @@ SADUMP_HFILES=sadump.h
UNWIND_HFILES=unwind.h unwind_i.h rse.h unwind_x86.h unwind_x86_64.h
VMWARE_HFILES=vmware_vmss.h
MAPLE_TREE_HFILES=maple_tree.h
+LZORLE_HFILES=lzorle_decompress.h
CFILES=main.c tools.c global_data.c memory.c filesys.c help.c task.c \
kernel.c test.c gdb_interface.c configure.c net.c dev.c bpf.c \
@@ -74,12 +75,14 @@ CFILES=main.c tools.c global_data.c memory.c filesys.c help.c task.c \
xen_hyper.c xen_hyper_command.c xen_hyper_global_data.c \
xen_hyper_dump_tables.c kvmdump.c qemu.c qemu-load.c sadump.c ipcs.c \
ramdump.c vmware_vmss.c vmware_guestdump.c \
- xen_dom0.c kaslr_helper.c sbitmap.c maple_tree.c
+ xen_dom0.c kaslr_helper.c sbitmap.c maple_tree.c \
+ lzorle_decompress.c
SOURCE_FILES=${CFILES} ${GENERIC_HFILES} ${MCORE_HFILES} \
${REDHAT_CFILES} ${REDHAT_HFILES} ${UNWIND_HFILES} \
${LKCD_DUMP_HFILES} ${LKCD_TRACE_HFILES} ${LKCD_OBSOLETE_HFILES}\
- ${IBM_HFILES} ${SADUMP_HFILES} ${VMWARE_HFILES} ${MAPLE_TREE_HFILES}
+ ${IBM_HFILES} ${SADUMP_HFILES} ${VMWARE_HFILES} ${MAPLE_TREE_HFILES} \
+ ${LZORLE_HFILES}
OBJECT_FILES=main.o tools.o global_data.o memory.o filesys.o help.o task.o \
build_data.o kernel.o test.o gdb_interface.o net.o dev.o bpf.o \
@@ -94,7 +97,8 @@ OBJECT_FILES=main.o tools.o global_data.o memory.o filesys.o help.o task.o \
xen_hyper.o xen_hyper_command.o xen_hyper_global_data.o \
xen_hyper_dump_tables.o kvmdump.o qemu.o qemu-load.o sadump.o ipcs.o \
ramdump.o vmware_vmss.o vmware_guestdump.o \
- xen_dom0.o kaslr_helper.o sbitmap.o maple_tree.o
+ xen_dom0.o kaslr_helper.o sbitmap.o maple_tree.o \
+ lzorle_decompress.o
MEMORY_DRIVER_FILES=memory_driver/Makefile memory_driver/crash.c memory_driver/README
@@ -546,6 +550,9 @@ bpf.o: ${GENERIC_HFILES} bpf.c
maple_tree.o: ${GENERIC_HFILES} ${MAPLE_TREE_HFILES} maple_tree.c
${CC} -c ${CRASH_CFLAGS} maple_tree.c ${WARNING_OPTIONS} ${WARNING_ERROR}
+lzorle_decompress.o: lzorle_decompress.c
+ ${CC} -c ${CRASH_CFLAGS} lzorle_decompress.c ${WARNING_OPTIONS} ${WARNING_ERROR}
+
${PROGRAM}: force
@$(MAKE) all
diff --git a/diskdump.c b/diskdump.c
index 3ae7bf2..4a473e1 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -28,6 +28,7 @@
#include "xen_dom0.h"
#include "vmcore.h"
#include "maple_tree.h"
+#include "lzorle_decompress.h"
#define BITMAP_SECT_LEN 4096
@@ -3069,6 +3070,8 @@ try_zram_decompress(ulonglong pte_val, unsigned char *buf, ulong len, ulonglong
" with lzo library\n");
return 0;
#endif
+ } else if (STREQ(name, "lzo-rle")) {
+ decompressor = (void *)&lzorle_decompress_safe;
} else { /* todo: support more compressor */
error(WARNING, "only the lzo compressor is supported\n");
return 0;
diff --git a/lzorle_decompress.c b/lzorle_decompress.c
new file mode 100644
index 0000000..6c810ea
--- /dev/null
+++ b/lzorle_decompress.c
@@ -0,0 +1,295 @@
+/* lzorle_decompress.h
+ *
+ * from kernel lib/lzo/lzo1x_decompress_safe.c
+ *
+ * Copyright (C) 1996-2012 Markus F.X.J. Oberhumer <mar...@oberhumer.com>
+ * Copyright (C) 2024 NIO
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "defs.h"
+#include "lzorle_decompress.h"
+
+/* This MAX_255_COUNT is the maximum number of times we can add 255 to a base
+ * count without overflowing an integer. The multiply will overflow when
+ * multiplying 255 by more than MAXINT/255. The sum will overflow earlier
+ * depending on the base count. Since the base count is taken from a u8
+ * and a few bits, it is safe to assume that it will always be lower than
+ * or equal to 2*255, thus we can always prevent any overflow by accepting
+ * two less 255 steps. See Documentation/lzo.txt for more information.
+ */
+#define MAX_255_COUNT ((((ulong)~0) / 255) - 2)
+
+static inline uint16_t get_unaligned_le16 (const uint8_t *p) {
+ return p[0] | p[1] << 8;
+}
+
+int lzorle_decompress_safe(const unsigned char *in, ulong in_len,
+ unsigned char *out, ulong *out_len, void *other/* NOT USED */) {
+ unsigned char *op;
+ const unsigned char *ip;
+ ulong t, next;
+ ulong state = 0;
+ const unsigned char *m_pos;
+ const unsigned char * const ip_end = in + in_len;
+ unsigned char * const op_end = out + *out_len;
+
+ unsigned char bitstream_version;
+
+ static int efficient_unaligned_access = -1;
+
+ if (efficient_unaligned_access == -1) {
+#if defined(ARM) || defined(ARM64) || defined(X86) || defined(X86_64) || defined(PPC) || defined(PPC64) || defined(S390)|| defined(S390X)
+ efficient_unaligned_access = TRUE;
+#else
+ efficient_unaligned_access = FALSE;
+#endif
+
+ if ((kt->ikconfig_flags & IKCONFIG_AVAIL) &&
+ (get_kernel_config("CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS", NULL) == IKCONFIG_Y))
+ efficient_unaligned_access = TRUE;
+ }
+
+ op = out;
+ ip = in;
+
+ if (in_len < 3)
+ goto input_overrun;
+
+ if (in_len >= 5 && *ip == 17) {
+ bitstream_version = ip[1];
+ ip += 2;
+ } else {
+ bitstream_version = 0;
+ }
+
+ if (*ip > 17) {
+ t = *ip++ - 17;
+ if (t < 4) {
+ next = t;
+ goto match_next;
+ }
+ goto copy_literal_run;
+ }
+
+ for (;;) {
+ t = *ip++;
+ if (t < 16) {
+ if (state == 0) {
+ if (t == 0) {
+ ulong offset;
+ const unsigned char *ip_last = ip;
+
+ while (*ip == 0) {
+ ip++;
+ NEED_IP(1);
+ }
+ offset = ip - ip_last;
+ if (offset > MAX_255_COUNT)
+ return LZO_E_ERROR;
+
+ offset = (offset << 8) - offset;
+ t += offset + 15 + *ip++;
+ }
+ t += 3;
+copy_literal_run:
+ if (efficient_unaligned_access &&
+ (HAVE_IP(t + 15) && HAVE_OP(t + 15))) {
+ const unsigned char *ie = ip + t;
+ unsigned char *oe = op + t;
+ do {
+ COPY8(op, ip);
+ op += 8;
+ ip += 8;
+ COPY8(op, ip);
+ op += 8;
+ ip += 8;
+ } while (ip < ie);
+ ip = ie;
+ op = oe;
+ } else {
+ NEED_OP(t);
+ NEED_IP(t + 3);
+ do {
+ *op++ = *ip++;
+ } while (--t > 0);
+ }
+ state = 4;
+ continue;
+ } else if (state != 4) {
+ next = t & 3;
+ m_pos = op - 1;
+ m_pos -= t >> 2;
+ m_pos -= *ip++ << 2;
+ TEST_LB(m_pos);
+ NEED_OP(2);
+ op[0] = m_pos[0];
+ op[1] = m_pos[1];
+ op += 2;
+ goto match_next;
+ } else {
+ next = t & 3;
+ m_pos = op - (1 + M2_MAX_OFFSET);
+ m_pos -= t >> 2;
+ m_pos -= *ip++ << 2;
+ t = 3;
+ }
+ } else if (t >= 64) {
+ next = t & 3;
+ m_pos = op - 1;
+ m_pos -= (t >> 2) & 7;
+ m_pos -= *ip++ << 3;
+ t = (t >> 5) - 1 + (3 - 1);
+ } else if (t >= 32) {
+ t = (t & 31) + (3 - 1);
+ if (t == 2) {
+ ulong offset;
+ const unsigned char *ip_last = ip;
+
+ while (*ip == 0) {
+ ip++;
+ NEED_IP(1);
+ }
+ offset = ip - ip_last;
+ if (offset > MAX_255_COUNT)
+ return LZO_E_ERROR;
+
+ offset = (offset << 8) - offset;
+ t += offset + 31 + *ip++;
+ NEED_IP(2);
+ }
+ m_pos = op - 1;
+
+ next = get_unaligned_le16(ip);
+ ip += 2;
+ m_pos -= next >> 2;
+ next &= 3;
+ } else {
+ NEED_IP(2);
+ next = get_unaligned_le16(ip);
+ if (((next & 0xfffc) == 0xfffc) &&
+ ((t & 0xf8) == 0x18) &&
+ bitstream_version) {
+ NEED_IP(3);
+ t &= 7;
+ t |= ip[2] << 3;
+ t += MIN_ZERO_RUN_LENGTH;
+ NEED_OP(t);
+ memset(op, 0, t);
+ op += t;
+ next &= 3;
+ ip += 3;
+ goto match_next;
+ } else {
+ m_pos = op;
+ m_pos -= (t & 8) << 11;
+ t = (t & 7) + (3 - 1);
+ if (t == 2) {
+ ulong offset;
+ const unsigned char *ip_last = ip;
+
+ while (*ip == 0) {
+ ip++;
+ NEED_IP(1);
+ }
+ offset = ip - ip_last;
+ if (offset > MAX_255_COUNT)
+ return LZO_E_ERROR;
+
+ offset = (offset << 8) - offset;
+ t += offset + 7 + *ip++;
+ NEED_IP(2);
+ next = get_unaligned_le16(ip);
+ }
+ ip += 2;
+ m_pos -= next >> 2;
+ next &= 3;
+ if (m_pos == op)
+ goto eof_found;
+ m_pos -= 0x4000;
+ }
+ }
+ TEST_LB(m_pos);
+
+ if (efficient_unaligned_access &&
+ (op - m_pos >= 8)) {
+ unsigned char *oe = op + t;
+ if (HAVE_OP(t + 15)) {
+ do {
+ COPY8(op, m_pos);
+ op += 8;
+ m_pos += 8;
+ COPY8(op, m_pos);
+ op += 8;
+ m_pos += 8;
+ } while (op < oe);
+ op = oe;
+ if (HAVE_IP(6)) {
+ state = next;
+ COPY4(op, ip);
+ op += next;
+ ip += next;
+ continue;
+ }
+ } else {
+ NEED_OP(t);
+ do {
+ *op++ = *m_pos++;
+ } while (op < oe);
+ }
+ } else {
+ unsigned char *oe = op + t;
+ NEED_OP(t);
+ op[0] = m_pos[0];
+ op[1] = m_pos[1];
+ op += 2;
+ m_pos += 2;
+ do {
+ *op++ = *m_pos++;
+ } while (op < oe);
+ }
+match_next:
+ state = next;
+ t = next;
+ if (efficient_unaligned_access &&
+ (HAVE_IP(6) && HAVE_OP(4))) {
+ COPY4(op, ip);
+ op += t;
+ ip += t;
+ } else {
+ NEED_IP(t + 3);
+ NEED_OP(t);
+ while (t > 0) {
+ *op++ = *ip++;
+ t--;
+ }
+ }
+ }
+
+eof_found:
+ *out_len = op - out;
+ return (t != 3 ? LZO_E_ERROR :
+ ip == ip_end ? LZO_E_OK :
+ ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN);
+
+input_overrun:
+ *out_len = op - out;
+ return LZO_E_INPUT_OVERRUN;
+
+output_overrun:
+ *out_len = op - out;
+ return LZO_E_OUTPUT_OVERRUN;
+
+lookbehind_overrun:
+ *out_len = op - out;
+ return LZO_E_LOOKBEHIND_OVERRUN;
+}
diff --git a/lzorle_decompress.h b/lzorle_decompress.h
new file mode 100644
index 0000000..62d961b
--- /dev/null
+++ b/lzorle_decompress.h
@@ -0,0 +1,75 @@
+/* lzorle_decompress.h
+ *
+ * from kernel lib/lzo/lzodefs.h
+ *
+ * Copyright (C) 1996-2012 Markus F.X.J. Oberhumer <mar...@oberhumer.com>
+ * Copyright (C) 2024 NIO
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef LZODEFS_H
+#define LZODEFS_H
+
+#define COPY4(dst, src) memcpy((dst), (src), sizeof(uint32_t))
+#define COPY8(dst, src) memcpy((dst), (src), sizeof(uint64_t))
+
+#define M1_MAX_OFFSET 0x0400
+#define M2_MAX_OFFSET 0x0800
+#define M3_MAX_OFFSET 0x4000
+#define M4_MAX_OFFSET_V0 0xbfff
+#define M4_MAX_OFFSET_V1 0xbffe
+
+#define M1_MIN_LEN 2
+#define M1_MAX_LEN 2
+#define M2_MIN_LEN 3
+#define M2_MAX_LEN 8
+#define M3_MIN_LEN 3
+#define M3_MAX_LEN 33
+#define M4_MIN_LEN 3
+#define M4_MAX_LEN 9
+
+#define M1_MARKER 0
+#define M2_MARKER 64
+#define M3_MARKER 32
+#define M4_MARKER 16
+
+#define MIN_ZERO_RUN_LENGTH 4
+#define MAX_ZERO_RUN_LENGTH (2047 + MIN_ZERO_RUN_LENGTH)
+
+#define lzo_dict_t unsigned short
+#define D_BITS 13
+#define D_SIZE (1u << D_BITS)
+#define D_MASK (D_SIZE - 1)
+#define D_HIGH ((D_MASK >> 1) + 1)
+
+#define LZO_E_OK 0
+#define LZO_E_ERROR (-1)
+#define LZO_E_OUT_OF_MEMORY (-2)
+#define LZO_E_NOT_COMPRESSIBLE (-3)
+#define LZO_E_INPUT_OVERRUN (-4)
+#define LZO_E_OUTPUT_OVERRUN (-5)
+#define LZO_E_LOOKBEHIND_OVERRUN (-6)
+#define LZO_E_EOF_NOT_FOUND (-7)
+#define LZO_E_INPUT_NOT_CONSUMED (-8)
+#define LZO_E_NOT_YET_IMPLEMELZO_HFILESNTED (-9)
+#define LZO_E_INVALID_ARGUMENT (-10)
+
+#define HAVE_IP(x) ((unsigned long)(ip_end - ip) >= (unsigned long)(x))
+#define HAVE_OP(x) ((unsigned long)(op_end - op) >= (unsigned long)(x))
+#define NEED_IP(x) if (!HAVE_IP(x)) goto input_overrun
+#define NEED_OP(x) if (!HAVE_OP(x)) goto output_overrun
+#define TEST_LB(m_pos) if ((m_pos) < out) goto lookbehind_overrun
+
+int lzorle_decompress_safe(const unsigned char *in, unsigned long in_len,
+ unsigned char *out, unsigned long *out_len, void *other/* NOT USED */);
+
+#endif
--
2.40.1

View File

@ -1,127 +0,0 @@
From 3452fe802bf94d15879b3c5fd17c793a2b67a231 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?HAGIO=20KAZUHITO=28=E8=90=A9=E5=B0=BE=E3=80=80=E4=B8=80?=
=?UTF-8?q?=E4=BB=81=29?= <k-hagio-ab@nec.com>
Date: Tue, 11 Jun 2024 02:40:55 +0000
Subject: [PATCH 1/2] Fix "kmem -i" and "swap" commands on Linux 6.10-rc1 and
later kernels
Kernel commit 798cb7f9aec3 ("swapon(2)/swapoff(2): don't bother with
block size") removed swap_info_struct.old_block_size member at Linux
6.10-rc1. The crash-utility has used this to determine whether a swap
is a partition or file and to determine the way to get the swap path.
Withtout the patch, the "kmem -i" and "swap" commands fail with the
following error messsage:
crash> kmem -i
...
TOTAL HUGE 13179392 50.3 GB ----
HUGE FREE 13179392 50.3 GB 100% of TOTAL HUGE
swap: invalid (optional) structure member offsets: swap_info_struct_swap_device or swap_info_struct_old_block_size
FILE: memory.c LINE: 16032 FUNCTION: dump_swap_info()
The swap_file member of recent swap_info_struct is a pointer to a
struct file (once upon a time it was dentry), use this fact directly.
Tested-by: Li Zhijian <lizhijian@fujitsu.com>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
---
defs.h | 1 +
filesys.c | 1 +
memory.c | 28 +++++++++++++++++++++++-----
symbols.c | 1 +
4 files changed, 26 insertions(+), 5 deletions(-)
diff --git a/defs.h b/defs.h
index da856c0..49e6923 100644
--- a/defs.h
+++ b/defs.h
@@ -2242,6 +2242,7 @@ struct offset_table { /* stash of commonly-used offsets */
long log_caller_id;
long vmap_node_busy;
long rb_list_head;
+ long file_f_inode;
};
struct size_table { /* stash of commonly-used sizes */
diff --git a/filesys.c b/filesys.c
index 81fe856..406ebb2 100644
--- a/filesys.c
+++ b/filesys.c
@@ -2038,6 +2038,7 @@ vfs_init(void)
MEMBER_OFFSET_INIT(file_f_dentry, "file", "f_dentry");
MEMBER_OFFSET_INIT(file_f_vfsmnt, "file", "f_vfsmnt");
MEMBER_OFFSET_INIT(file_f_count, "file", "f_count");
+ MEMBER_OFFSET_INIT(file_f_inode, "file", "f_inode");
MEMBER_OFFSET_INIT(path_mnt, "path", "mnt");
MEMBER_OFFSET_INIT(path_dentry, "path", "dentry");
if (INVALID_MEMBER(file_f_dentry)) {
diff --git a/memory.c b/memory.c
index acb8507..a74ebaf 100644
--- a/memory.c
+++ b/memory.c
@@ -16075,6 +16075,8 @@ dump_swap_info(ulong swapflags, ulong *totalswap_pages, ulong *totalused_pages)
char buf3[BUFSIZE];
char buf4[BUFSIZE];
char buf5[BUFSIZE];
+ int swap_file_is_file =
+ STREQ(MEMBER_TYPE_NAME("swap_info_struct", "swap_file"), "file");
if (!symbol_exists("nr_swapfiles"))
error(FATAL, "nr_swapfiles doesn't exist in this kernel!\n");
@@ -16118,9 +16120,21 @@ dump_swap_info(ulong swapflags, ulong *totalswap_pages, ulong *totalused_pages)
swap_file = ULONG(vt->swap_info_struct +
OFFSET(swap_info_struct_swap_file));
- swap_device = INT(vt->swap_info_struct +
- OFFSET_OPTION(swap_info_struct_swap_device,
- swap_info_struct_old_block_size));
+ /* Linux 6.10 and later */
+ if (INVALID_MEMBER(swap_info_struct_swap_device) &&
+ INVALID_MEMBER(swap_info_struct_old_block_size) &&
+ swap_file_is_file) {
+ ulong inode;
+ ushort mode;
+ readmem(swap_file + OFFSET(file_f_inode), KVADDR, &inode,
+ sizeof(ulong), "swap_file.f_inode", FAULT_ON_ERROR);
+ readmem(inode + OFFSET(inode_i_mode), KVADDR, &mode,
+ sizeof(ushort), "inode.i_mode", FAULT_ON_ERROR);
+ swap_device = S_ISBLK(mode);
+ } else
+ swap_device = INT(vt->swap_info_struct +
+ OFFSET_OPTION(swap_info_struct_swap_device,
+ swap_info_struct_old_block_size));
pages = INT(vt->swap_info_struct +
OFFSET(swap_info_struct_pages));
@@ -16161,8 +16175,12 @@ dump_swap_info(ulong swapflags, ulong *totalswap_pages, ulong *totalused_pages)
OFFSET(swap_info_struct_swap_vfsmnt));
get_pathname(swap_file, buf, BUFSIZE,
1, vfsmnt);
- } else if (VALID_MEMBER
- (swap_info_struct_old_block_size)) {
+ } else if (VALID_MEMBER(swap_info_struct_old_block_size) ||
+ swap_file_is_file) {
+ /*
+ * Linux 6.10 and later kernels do not have old_block_size,
+ * but this still should work, if swap_file is file.
+ */
devname = vfsmount_devname(file_to_vfsmnt(swap_file),
buf1, BUFSIZE);
get_pathname(file_to_dentry(swap_file),
diff --git a/symbols.c b/symbols.c
index f3c94b0..69a1fbb 100644
--- a/symbols.c
+++ b/symbols.c
@@ -10522,6 +10522,7 @@ dump_offset_table(char *spec, ulong makestruct)
OFFSET(file_f_count));
fprintf(fp, " file_f_path: %ld\n",
OFFSET(file_f_path));
+ fprintf(fp, " file_f_inode: %ld\n", OFFSET(file_f_inode));
fprintf(fp, " path_mnt: %ld\n",
OFFSET(path_mnt));
fprintf(fp, " path_dentry: %ld\n",
--
2.40.1

View File

@ -1,68 +0,0 @@
From af895b219876b293d551e6dec825aba3905c0588 Mon Sep 17 00:00:00 2001
From: "qiwu.chen" <qiwu.chen@transsion.com>
Date: Wed, 24 Jul 2024 01:36:09 +0000
Subject: [PATCH 1/5] arm64: fix a potential segfault when unwind frame
The range of frame->fp is checked insufficiently, which may lead to a wrong
next fp. As a result, bt->stackbuf will be accessed out of range, and segfault.
crash> bt
[Detaching after fork from child process 11409]
PID: 7661 TASK: ffffff81858aa500 CPU: 4 COMMAND: "sh"
#0 [ffffffc008003f50] local_cpu_stop at ffffffdd7669444c
Thread 1 "crash" received signal SIGSEGV, Segmentation fault.
0x00005555558266cc in arm64_unwind_frame (bt=0x7fffffffd8f0, frame=0x7fffffffd080) at
arm64.c:2821
2821 frame->fp = GET_STACK_ULONG(fp);
(gdb) bt
arm64.c:2821
out>) at main.c:1338
gdb_interface.c:81
(gdb) p /x *(struct bt_info*) 0x7fffffffd8f0
$3 = {task = 0xffffff81858aa500, flags = 0x0, instptr = 0xffffffdd76694450, stkptr =
0xffffffc008003f40, bptr = 0x0, stackbase = 0xffffffc027288000,
stacktop = 0xffffffc02728c000, stackbuf = 0x555556115a40, tc = 0x55559d16fdc0, hp = 0x0,
textlist = 0x0, ref = 0x0, frameptr = 0xffffffc008003f50,
call_target = 0x0, machdep = 0x0, debug = 0x0, eframe_ip = 0x0, radix = 0x0, cpumask =
0x0}
(gdb) p /x *(struct arm64_stackframe*) 0x7fffffffd080
$4 = {fp = 0xffffffc008003f50, sp = 0xffffffc008003f60, pc = 0xffffffdd76694450}
crash> bt -S 0xffffffc008003f50
PID: 7661 TASK: ffffff81858aa500 CPU: 4 COMMAND: "sh"
bt: non-process stack address for this task: ffffffc008003f50
(valid range: ffffffc027288000 - ffffffc02728c000)
Check frame->fp value sufficiently before access it. Only frame->fp within
the range of bt->stackbase and bt->stacktop will be regarded as valid.
Signed-off-by: qiwu.chen <qiwu.chen@transsion.com>
---
arm64.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arm64.c b/arm64.c
index b3040d7..624dba2 100644
--- a/arm64.c
+++ b/arm64.c
@@ -2814,7 +2814,7 @@ arm64_unwind_frame(struct bt_info *bt, struct arm64_stackframe *frame)
low = frame->sp;
high = (low + stack_mask) & ~(stack_mask);
- if (fp < low || fp > high || fp & 0xf)
+ if (fp < low || fp > high || fp & 0xf || !INSTACK(fp, bt))
return FALSE;
frame->sp = fp + 0x10;
@@ -3024,7 +3024,7 @@ arm64_unwind_frame_v2(struct bt_info *bt, struct arm64_stackframe *frame,
low = frame->sp;
high = (low + stack_mask) & ~(stack_mask);
- if (fp < low || fp > high || fp & 0xf)
+ if (fp < low || fp > high || fp & 0xf || !INSTACK(fp, bt))
return FALSE;
if (CRASHDEBUG(1))
--
2.40.1

View File

@ -1,111 +0,0 @@
From af2ac4c41df6d87f090613ecf3521ca073754cb0 Mon Sep 17 00:00:00 2001
From: chenguanyou <chenguanyou@xiaomi.com>
Date: Wed, 24 Apr 2024 17:00:20 +0800
Subject: [PATCH 2/9] Cleanup: replace struct zspage_5_17 with union
This patch is a refactoring on commit [1], and has no functional
change. The reason is that the structure of zspage has not changed,
just new bits have been introduced. So a union is better to reduce
code replication.
[1] 0172e35083b5 ("Fix "rd" command to display data on zram on Linux 5.17 and later")
Signed-off-by: chenguanyou <chenguanyou@xiaomi.com>
---
defs.h | 32 +++++++++++++++-----------------
diskdump.c | 15 ++++++---------
2 files changed, 21 insertions(+), 26 deletions(-)
diff --git a/defs.h b/defs.h
index 3cb8e63..01f316e 100644
--- a/defs.h
+++ b/defs.h
@@ -7407,28 +7407,26 @@ ulong try_zram_decompress(ulonglong pte_val, unsigned char *buf, ulong len, ulon
#define SECTORS_PER_PAGE (1 << SECTORS_PER_PAGE_SHIFT)
struct zspage {
- struct {
- unsigned int fullness : 2;
- unsigned int class : 9;
- unsigned int isolated : 3;
- unsigned int magic : 8;
+ union {
+ unsigned int flag_bits;
+ struct {
+ unsigned int fullness : 2;
+ unsigned int class : 9;
+ unsigned int isolated : 3;
+ unsigned int magic : 8;
+ } v0;
+ struct {
+ unsigned int huge : 1;
+ unsigned int fullness : 2;
+ unsigned int class : 9;
+ unsigned int isolated : 3;
+ unsigned int magic : 8;
+ } v5_17;
};
unsigned int inuse;
unsigned int freeobj;
};
-struct zspage_5_17 {
- struct {
- unsigned int huge : 1;
- unsigned int fullness : 2;
- unsigned int class : 9;
- unsigned int isolated : 3;
- unsigned int magic : 8;
- };
- unsigned int inuse;
- unsigned int freeobj;
-};
-
/*
* makedumpfile.c
*/
diff --git a/diskdump.c b/diskdump.c
index 4a473e1..1f7118c 100644
--- a/diskdump.c
+++ b/diskdump.c
@@ -2820,7 +2820,6 @@ zram_object_addr(ulong pool, ulong handle, unsigned char *zram_buf)
{
ulong obj, off, class, page, zspage;
struct zspage zspage_s;
- struct zspage_5_17 zspage_5_17_s;
physaddr_t paddr;
unsigned int obj_idx, class_idx, size;
ulong pages[2], sizes[2];
@@ -2834,15 +2833,13 @@ zram_object_addr(ulong pool, ulong handle, unsigned char *zram_buf)
readmem(page + OFFSET(page_private), KVADDR, &zspage,
sizeof(void *), "page_private", FAULT_ON_ERROR);
+ readmem(zspage, KVADDR, &zspage_s, sizeof(struct zspage), "zspage", FAULT_ON_ERROR);
if (VALID_MEMBER(zspage_huge)) {
- readmem(zspage, KVADDR, &zspage_5_17_s,
- sizeof(struct zspage_5_17), "zspage_5_17", FAULT_ON_ERROR);
- class_idx = zspage_5_17_s.class;
- zs_magic = zspage_5_17_s.magic;
+ class_idx = zspage_s.v5_17.class;
+ zs_magic = zspage_s.v5_17.magic;
} else {
- readmem(zspage, KVADDR, &zspage_s, sizeof(struct zspage), "zspage", FAULT_ON_ERROR);
- class_idx = zspage_s.class;
- zs_magic = zspage_s.magic;
+ class_idx = zspage_s.v0.class;
+ zs_magic = zspage_s.v0.magic;
}
if (zs_magic != ZSPAGE_MAGIC)
@@ -2888,7 +2885,7 @@ zram_object_addr(ulong pool, ulong handle, unsigned char *zram_buf)
out:
if (VALID_MEMBER(zspage_huge)) {
- if (!zspage_5_17_s.huge)
+ if (!zspage_s.v5_17.huge)
return (zram_buf + ZS_HANDLE_SIZE);
} else {
readmem(page, KVADDR, &obj, sizeof(void *), "page flags", FAULT_ON_ERROR);
--
2.40.1

View File

@ -1,31 +0,0 @@
From ce4ddc742fbdde2fc966e79a19d6aa962e79448a Mon Sep 17 00:00:00 2001
From: Li Zhijian <lizhijian@fujitsu.com>
Date: Tue, 2 Jul 2024 14:31:30 +0800
Subject: [PATCH 2/2] List: enable LIST_HEAD_FORMAT for -r option
Currently, the LIST_HEAD_FORMAT is not set, 'list -r' will list the
traversal results in order, not in the reverse order. This is not
the expected behavior.
Let's enable the LIST_HEAD_FORMAT for -r option by default.
Signed-off-by: Li Zhijian <lizhijian@fujitsu.com>
---
tools.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/tools.c b/tools.c
index 0f2db10..1022d57 100644
--- a/tools.c
+++ b/tools.c
@@ -3370,6 +3370,7 @@ cmd_list(void)
break;
case 'r':
+ ld->flags |= LIST_HEAD_FORMAT;
ld->flags |= LIST_HEAD_REVERSE;
break;
--
2.40.1

View File

@ -1,126 +0,0 @@
From 1c6da3eaff820708d4286324051d153a01766b02 Mon Sep 17 00:00:00 2001
From: bevis_chen <bevis_chen@asus.com>
Date: Thu, 25 Jul 2024 09:38:59 +0800
Subject: [PATCH 2/5] arm64: Fix bt command show wrong stacktrace on ramdump
source
For ramdump(Qcom phone device) case with the kernel option
CONFIG_ARM64_PTR_AUTH_KERNEL enabled, the bt command may print
incorrect stacktrace as below:
crash> bt 16930
PID: 16930 TASK: ffffff89b3eada00 CPU: 2 COMMAND: "Firebase Backgr"
#0 [ffffffc034c437f0] __switch_to at ffffffe0036832d4
#1 [ffffffc034c43850] __kvm_nvhe_$d.2314 at 6be732e004cf05a0
#2 [ffffffc034c438b0] __kvm_nvhe_$d.2314 at 86c54c6004ceff80
#3 [ffffffc034c43950] __kvm_nvhe_$d.2314 at 55d6f96003a7b120
...
PC: 00000073f5294840 LR: 00000070d8f39ba4 SP: 00000070d4afd5d0
X29: 00000070d4afd600 X28: b4000071efcda7f0 X27: 00000070d4afe000
X26: 0000000000000000 X25: 00000070d9616000 X24: 0000000000000000
X23: 0000000000000000 X22: 0000000000000000 X21: 0000000000000000
X20: b40000728fd27520 X19: b40000728fd27550 X18: 000000702daba000
X17: 00000073f5294820 X16: 00000070d940f9d8 X15: 00000000000000bf
X14: 0000000000000000 X13: 00000070d8ad2fac X12: b40000718fce5040
X11: 0000000000000000 X10: 0000000000000070 X9: 0000000000000001
X8: 0000000000000062 X7: 0000000000000020 X6: 0000000000000000
X5: 0000000000000000 X4: 0000000000000000 X3: 0000000000000000
X2: 0000000000000002 X1: 0000000000000080 X0: b40000728fd27550
ORIG_X0: b40000728fd27550 SYSCALLNO: ffffffff PSTATE: 40001000
Crash tool can not get the KERNELPACMASK value from the vmcoreinfo, need
to calculate its value based on the vabits.
With the patch:
crash> bt 16930
PID: 16930 TASK: ffffff89b3eada00 CPU: 2 COMMAND: "Firebase Backgr"
#0 [ffffffc034c437f0] __switch_to at ffffffe0036832d4
#1 [ffffffc034c43850] __schedule at ffffffe004cf05a0
#2 [ffffffc034c438b0] preempt_schedule_common at ffffffe004ceff80
#3 [ffffffc034c43950] unmap_page_range at ffffffe003a7b120
#4 [ffffffc034c439f0] unmap_vmas at ffffffe003a80a64
#5 [ffffffc034c43ac0] exit_mmap at ffffffe003a945c4
#6 [ffffffc034c43b10] __mmput at ffffffe00372c818
#7 [ffffffc034c43b40] mmput at ffffffe00372c0d0
#8 [ffffffc034c43b90] exit_mm at ffffffe00373d0ac
#9 [ffffffc034c43c00] do_exit at ffffffe00373bedc
PC: 00000073f5294840 LR: 00000070d8f39ba4 SP: 00000070d4afd5d0
X29: 00000070d4afd600 X28: b4000071efcda7f0 X27: 00000070d4afe000
X26: 0000000000000000 X25: 00000070d9616000 X24: 0000000000000000
X23: 0000000000000000 X22: 0000000000000000 X21: 0000000000000000
X20: b40000728fd27520 X19: b40000728fd27550 X18: 000000702daba000
X17: 00000073f5294820 X16: 00000070d940f9d8 X15: 00000000000000bf
X14: 0000000000000000 X13: 00000070d8ad2fac X12: b40000718fce5040
X11: 0000000000000000 X10: 0000000000000070 X9: 0000000000000001
X8: 0000000000000062 X7: 0000000000000020 X6: 0000000000000000
X5: 0000000000000000 X4: 0000000000000000 X3: 0000000000000000
X2: 0000000000000002 X1: 0000000000000080 X0: b40000728fd27550
ORIG_X0: b40000728fd27550 SYSCALLNO: ffffffff PSTATE: 40001000
Related kernel commits:
689eae42afd7 ("arm64: mask PAC bits of __builtin_return_address")
de1702f65feb ("arm64: move PAC masks to <asm/pointer_auth.h>")
Signed-off-by: bevis_chen <bevis_chen@asus.com>
---
arm64.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/arm64.c b/arm64.c
index 624dba2..78e6609 100644
--- a/arm64.c
+++ b/arm64.c
@@ -92,6 +92,7 @@ static void arm64_get_crash_notes(void);
static void arm64_calc_VA_BITS(void);
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);
struct kernel_range {
@@ -581,6 +582,16 @@ arm64_init(int when)
if (!machdep->hz)
machdep->hz = 100;
+
+ /*
+ * Let's calculate the KERNELPACMASK value based on the
+ * vabits, see:
+ * arch/arm64/kernel/vmcore_info.c
+ * arch/arm64/include/asm/pointer_auth.h
+ */
+ if(!machdep->machspec->CONFIG_ARM64_KERNELPACMASK)
+ arm64_recalc_KERNELPACMASK();
+
arm64_irq_stack_init();
arm64_overflow_stack_init();
arm64_stackframe_init();
@@ -4921,6 +4932,24 @@ static void arm64_calc_KERNELPACMASK(void)
}
}
+#define GENMASK_UL(h, l) \
+ (((~0UL) << (l)) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
+
+static void arm64_recalc_KERNELPACMASK(void){
+ /*
+ * Check if PAC is enabled according to the existence of
+ * kernel symbol 'ptrauth_keys_kernel'.
+ */
+ if (STRUCT_EXISTS("ptrauth_keys_kernel") &&
+ machdep->machspec->VA_BITS_ACTUAL){
+ machdep->machspec->CONFIG_ARM64_KERNELPACMASK =
+ GENMASK_UL(63, machdep->machspec->VA_BITS_ACTUAL);
+ if (CRASHDEBUG(1))
+ fprintf(fp, "CONFIG_ARM64_KERNELPACMASK: %lx\n",
+ machdep->machspec->CONFIG_ARM64_KERNELPACMASK);
+ }
+}
+
#endif /* ARM64 */
--
2.40.1

View File

@ -1,261 +0,0 @@
From 93d7f647c45b80b584db815f78b7130508642c60 Mon Sep 17 00:00:00 2001
From: Kuan-Ying Lee <kuan-ying.lee@canonical.com>
Date: Sat, 13 Jul 2024 21:22:52 +0800
Subject: [PATCH 3/5] arm64: Introduction of support for 16K page with 3-level
table support
Introduction of ARM64 support for 16K page size with 3-level page
table and 47 VA bits.
Signed-off-by: Kuan-Ying Lee <kuan-ying.lee@canonical.com>
---
arm64.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
defs.h | 16 ++++++++
2 files changed, 126 insertions(+), 4 deletions(-)
diff --git a/arm64.c b/arm64.c
index 78e6609..067c879 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_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);
static ulong arm64_get_task_pgd(ulong);
@@ -262,8 +263,7 @@ arm64_init(int when)
machdep->pagesize = 4096;
break;
case 2:
- /* TODO: machdep->pagesize = 16384; */
- error(FATAL, "16K pages not supported.");
+ machdep->pagesize = 16384;
break;
case 3:
machdep->pagesize = 65536;
@@ -393,6 +393,26 @@ arm64_init(int when)
error(FATAL, "cannot malloc ptbl space.");
break;
+ case 16384:
+ if (machdep->machspec->VA_BITS > PGDIR_SHIFT_L3_16K) {
+ machdep->flags |= VM_L3_16K;
+ if (!machdep->ptrs_per_pgd)
+ machdep->ptrs_per_pgd = PTRS_PER_PGD_L3_16K;
+ if ((machdep->pgd =
+ (char *)malloc(machdep->ptrs_per_pgd * 8)) == NULL)
+ error(FATAL, "cannot malloc pgd space.");
+ if ((machdep->pmd =
+ (char *)malloc(PTRS_PER_PMD_L3_16K * 8)) == NULL)
+ error(FATAL, "cannot malloc pmd space.");
+ if ((machdep->ptbl =
+ (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.");
+ }
+ machdep->pud = NULL; /* not used */
+ break;
+
case 65536:
if (kernel_symbol_exists("idmap_ptrs_per_pgd") &&
readmem(symbol_value("idmap_ptrs_per_pgd"), KVADDR,
@@ -1029,6 +1049,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_L3_16K)
+ fprintf(fp, "%sVM_L3_16K", others++ ? "|" : "");
if (machdep->flags & VM_L3_4K)
fprintf(fp, "%sVM_L3_4K", others++ ? "|" : "");
if (machdep->flags & VM_L4_4K)
@@ -1076,6 +1098,8 @@ arm64_dump_machdep_table(ulong arg)
"arm64_vtop_3level_4k" :
machdep->flags & VM_L4_4K ?
"arm64_vtop_4level_4k" :
+ machdep->flags & VM_L3_16K ?
+ "arm64_vtop_3level_16k" :
machdep->flags & VM_L3_64K ?
"arm64_vtop_3level_64k" : "arm64_vtop_2level_64k");
fprintf(fp, " kvtop: arm64_kvtop()->%s()\n",
@@ -1083,6 +1107,8 @@ arm64_dump_machdep_table(ulong arg)
"arm64_vtop_3level_4k" :
machdep->flags & VM_L4_4K ?
"arm64_vtop_4level_4k" :
+ machdep->flags & VM_L3_16K ?
+ "arm64_vtop_3level_16k" :
machdep->flags & VM_L3_64K ?
"arm64_vtop_3level_64k" : "arm64_vtop_2level_64k");
fprintf(fp, " get_task_pgd: arm64_get_task_pgd()\n");
@@ -1118,6 +1144,7 @@ arm64_dump_machdep_table(ulong arg)
fprintf(fp, " last_pgd_read: %lx\n", machdep->last_pgd_read);
fprintf(fp, " last_pud_read: ");
if ((PAGESIZE() == 65536) ||
+ (PAGESIZE() == 16384) ||
((PAGESIZE() == 4096) && !(machdep->flags & VM_L4_4K)))
fprintf(fp, "(not used)\n");
else
@@ -1772,7 +1799,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))
+ switch (machdep->flags & (VM_L2_64K|VM_L3_64K|VM_L3_4K|VM_L4_4K|VM_L3_16K))
{
case VM_L2_64K:
return arm64_vtop_2level_64k(kernel_pgd, kvaddr, paddr, verbose);
@@ -1782,6 +1809,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_L3_16K:
+ return arm64_vtop_3level_16k(kernel_pgd, kvaddr, paddr, verbose);
default:
return FALSE;
}
@@ -1797,7 +1826,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))
+ switch (machdep->flags & (VM_L2_64K|VM_L3_64K|VM_L3_4K|VM_L4_4K|VM_L3_16K))
{
case VM_L2_64K:
return arm64_vtop_2level_64k(user_pgd, uvaddr, paddr, verbose);
@@ -1807,6 +1836,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_L3_16K:
+ return arm64_vtop_3level_16k(user_pgd, uvaddr, paddr, verbose);
default:
return FALSE;
}
@@ -1823,6 +1854,7 @@ arm64_uvtop(struct task_context *tc, ulong uvaddr, physaddr_t *paddr, int verbos
#define PMD_TYPE_SECT 1
#define PMD_TYPE_TABLE 2
#define SECTION_PAGE_MASK_2MB ((long)(~((MEGABYTES(2))-1)))
+#define SECTION_PAGE_MASK_32MB ((long)(~((MEGABYTES(32))-1)))
#define SECTION_PAGE_MASK_512MB ((long)(~((MEGABYTES(512))-1)))
#define SECTION_PAGE_MASK_1GB ((long)(~((GIGABYTES(1))-1)))
@@ -1965,6 +1997,80 @@ no_page:
return FALSE;
}
+static int
+arm64_vtop_3level_16k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
+{
+ ulong *pgd_base, *pgd_ptr, pgd_val;
+ ulong *pmd_base, *pmd_ptr, pmd_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_L3_16K) & (machdep->ptrs_per_pgd - 1));
+ pgd_val = ULONG(machdep->pgd + PGDIR_OFFSET_L3_16K(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
+ */
+
+ pmd_base = (ulong *)PTOV(PTE_TO_PHYS(pgd_val));
+ FILL_PMD(pmd_base, KVADDR, PTRS_PER_PMD_L3_16K * sizeof(ulong));
+ pmd_ptr = pmd_base + (((vaddr) >> PMD_SHIFT_L3_16K) & (PTRS_PER_PMD_L3_16K - 1));
+ pmd_val = ULONG(machdep->pmd + PAGEOFFSET(pmd_ptr));
+ if (verbose)
+ fprintf(fp, " PMD: %lx => %lx\n", (ulong)pmd_ptr, pmd_val);
+ if (!pmd_val)
+ goto no_page;
+
+ if ((pmd_val & PMD_TYPE_MASK) == PMD_TYPE_SECT) {
+ ulong sectionbase = PTE_TO_PHYS(pmd_val) & SECTION_PAGE_MASK_32MB;
+ if (verbose) {
+ fprintf(fp, " PAGE: %lx (32MB%s)\n\n", sectionbase,
+ IS_ZEROPAGE(sectionbase) ? ", ZERO PAGE" : "");
+ arm64_translate_pte(pmd_val, 0, 0);
+ }
+ *paddr = sectionbase + (vaddr & ~SECTION_PAGE_MASK_32MB);
+ return TRUE;
+ }
+
+ pte_base = (ulong *)PTOV(PTE_TO_PHYS(pmd_val));
+ FILL_PTBL(pte_base, KVADDR, PTRS_PER_PTE_L3_16K * sizeof(ulong));
+ pte_ptr = pte_base + (((vaddr) >> machdep->pageshift) & (PTRS_PER_PTE_L3_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 = PTE_TO_PHYS(pte_val) + 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_4k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
{
diff --git a/defs.h b/defs.h
index 49e6923..1b7649d 100644
--- a/defs.h
+++ b/defs.h
@@ -3302,6 +3302,21 @@ typedef signed int s32;
#define PGDIR_MASK_48VA (~(PGDIR_SIZE_48VA - 1))
#define PGDIR_OFFSET_48VA(X) (((ulong)(X)) & (PGDIR_SIZE_48VA - 1))
+/*
+ * 3-levels / 16K pages
+ * 47-bit VA
+ */
+#define PTRS_PER_PGD_L3_16K ((1UL) << (47 - 36))
+#define PTRS_PER_PMD_L3_16K (2048)
+#define PTRS_PER_PTE_L3_16K (2048)
+#define PGDIR_SHIFT_L3_16K (36)
+#define PGDIR_SIZE_L3_16K ((1UL) << PGDIR_SHIFT_L3_16K)
+#define PGDIR_MASK_L3_16K (~(PGDIR_SIZE_L3_16K-1))
+#define PMD_SHIFT_L3_16K (25)
+#define PMD_SIZE_L3_16K (1UL << PMD_SHIFT_L3_16K)
+#define PMD_MASK_L3_16K (~(PMD_SIZE_L3_16K-1))
+#define PGDIR_OFFSET_L3_16K(X) (((ulong)(X)) & ((machdep->ptrs_per_pgd * 8) - 1))
+
/*
* 3-levels / 64K pages
*/
@@ -3367,6 +3382,7 @@ typedef signed int s32;
#define HAS_PHYSVIRT_OFFSET (0x800)
#define OVERFLOW_STACKS (0x1000)
#define ARM64_MTE (0x2000)
+#define VM_L3_16K (0x4000)
/*
* Get kimage_voffset from /dev/crash
--
2.40.1

View File

@ -1,59 +0,0 @@
From 568c6f049ad4a20918afeb2db9bb7a15b17d9ff2 Mon Sep 17 00:00:00 2001
From: Guanyou Chen <chenguanyou9338@gmail.com>
Date: Wed, 17 Apr 2024 19:55:40 +0800
Subject: [PATCH 3/9] arm64: section_size_bits compatible with macro
definitions
Compatible with google android GKI changes,
SECTION_SIZE_BITS = 27 when defined 4K_PAGES or 16K_PAGES.
SECTION_SIZE_BITS = 29 when defined 64K_PAGES.
Before android-12-gki:
crash> help -m | grep section_size_bits
section_size_bits: 30
The first PFN error, the physical address should be 0x40000000.
crash> kmem -p
PAGE PHYSICAL MAPPING INDEX CNT FLAGS
ffffffff06e00000 200000000 ffffff80edf4fa12 ffffffff070f3640 1
4000000000002000 private
After android-12-gki:
crash> help -m | grep section
section_size_bits: 27
crash> kmem -p
PAGE PHYSICAL MAPPING INDEX CNT FLAGS
fffffffeffe00000 40000000 0 0 1 1000 reserved
Link: https://lore.kernel.org/lkml/15cf9a2359197fee0168f820c5c904650d07939e.1610146597.git.sudaraja@codeaurora.org
Link: https://lore.kernel.org/all/43843c5e092bfe3ec4c41e3c8c78a7ee35b69bb0.1611206601.git.sudaraja@codeaurora.org
Link: https://cs.android.com/android/_/android/kernel/common/+/673e9ab6b64f981159aeff3b65675bb7dbedecd8
Signed-off-by: chenguanyou <chenguanyou@xiaomi.com>
---
arm64.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/arm64.c b/arm64.c
index af0e0d7..b3040d7 100644
--- a/arm64.c
+++ b/arm64.c
@@ -1628,7 +1628,14 @@ arm64_get_section_size_bits(void)
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;
}
if (CRASHDEBUG(1))
--
2.40.1

View File

@ -1,44 +0,0 @@
From 38f26cc8b9304e79e7f8adb5fd8e6a533c70cfd2 Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
Date: Tue, 6 Aug 2024 14:31:45 +0800
Subject: [PATCH 4/5] LoongArch64: fix incorrect code in the main()
The commit c3939d2e1930 contains incorrect code that starts with "+",
for example:
- !machine_type("S390X") && !machine_type("RISCV64"))
+ !machine_type("S390X") && !machine_type("RISCV64") &&
++ !machine_type("LOONGARCH64"))
See the main() in the main.c
...
} else if (STREQ(long_options[option_index].name, "kaslr")) {
if (!machine_type("X86_64") &&
!machine_type("ARM64") && !machine_type("X86") &&
!machine_type("S390X") && !machine_type("RISCV64") &&
+ !machine_type("LOONGARCH64"))
Let's remove it from the main().
Link: https://lists.crash-utility.osci.io/archives/list/devel@lists.crash-utility.osci.io/message/LH3IRUA6ZDVFZFLWKW5EWR3DKE6MY25Z/
Fixes: c3939d2e1930 ("LoongArch64: Add "--kaslr" command line option support")
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/main.c b/main.c
index 0b6b927..71bcc15 100644
--- a/main.c
+++ b/main.c
@@ -229,7 +229,7 @@ main(int argc, char **argv)
if (!machine_type("X86_64") &&
!machine_type("ARM64") && !machine_type("X86") &&
!machine_type("S390X") && !machine_type("RISCV64") &&
-+ !machine_type("LOONGARCH64"))
+ !machine_type("LOONGARCH64"))
error(INFO, "--kaslr not valid "
"with this machine type.\n");
else if (STREQ(optarg, "auto"))
--
2.40.1

View File

@ -1,45 +0,0 @@
From 3879e9104826d5ae14a0824ec47ab60056a249a7 Mon Sep 17 00:00:00 2001
From: Alexander Gordeev <agordeev@linux.ibm.com>
Date: Wed, 10 Apr 2024 14:55:35 +0200
Subject: [PATCH 4/9] Reflect __{start,end}_init_task kernel symbols rename
Kernel commit 8f69cba096b5 ("x86: Rename __{start,end}_init_task to
__{start,end}_init_stack") leads to failure when crash loading:
crash: invalid count request: 0
Assume both __{start,end}_init_task and __{start,end}_init_stack
symbols could exist for backward compatibility.
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
---
task.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/task.c b/task.c
index ebdb5be..d52ce0b 100644
--- a/task.c
+++ b/task.c
@@ -496,10 +496,17 @@ task_init(void)
((len = SIZE(thread_union)) != STACKSIZE())) {
machdep->stacksize = len;
} else if (!VALID_SIZE(thread_union) && !VALID_SIZE(task_union)) {
- if (kernel_symbol_exists("__start_init_task") &&
- kernel_symbol_exists("__end_init_task")) {
+ len = 0;
+ if (kernel_symbol_exists("__start_init_stack") &&
+ kernel_symbol_exists("__end_init_stack")) {
+ len = symbol_value("__end_init_stack");
+ len -= symbol_value("__start_init_stack");
+ } else if (kernel_symbol_exists("__start_init_task") &&
+ kernel_symbol_exists("__end_init_task")) {
len = symbol_value("__end_init_task");
len -= symbol_value("__start_init_task");
+ }
+ if (len) {
ASSIGN_SIZE(thread_union) = len;
machdep->stacksize = len;
}
--
2.40.1

View File

@ -1,139 +0,0 @@
From f615f8fab7bf3d2d5d5cb00518124a06e6846be4 Mon Sep 17 00:00:00 2001
From: Tao Liu <ltao@redhat.com>
Date: Wed, 17 Jul 2024 16:17:00 +1200
Subject: [PATCH 5/5] Fix "irq -a" exceeding the memory range issue
Previously without the patch, there was an error observed as follows:
crash> irq -a
IRQ NAME AFFINITY
0 timer 0-191
4 ttyS0 0-23,96-119
...
84 smartpqi 72-73,168
irq: page excluded: kernel virtual address: ffff97d03ffff000 type: "irq_desc affinity"
The reason is the reading of irq affinity exceeded the memory range, see
the following debug info:
Thread 1 "crash" hit Breakpoint 1, generic_get_irq_affinity (irq=85) at kernel.c:7373
7375 irq_desc_addr = get_irq_desc_addr(irq);
(gdb) p/x irq_desc_addr
$1 = 0xffff97d03f21e800
crash> struct irq_desc 0xffff97d03f21e800
struct irq_desc {
irq_common_data = {
state_use_accessors = 425755136,
node = 3,
handler_data = 0x0,
msi_desc = 0xffff97ca51b83480,
affinity = 0xffff97d03fffee60,
effective_affinity = 0xffff97d03fffe6c0
},
crash> whatis cpumask_t
typedef struct cpumask {
unsigned long bits[128];
} cpumask_t;
SIZE: 1024
In order to get the affinity, crash will read the memory range 0xffff97d03fffee60
~ 0xffff97d03fffee60 + 1024(0x400) by line:
readmem(affinity_ptr, KVADDR, affinity, len,
"irq_desc affinity", FAULT_ON_ERROR);
However the reading will exceed the effective memory range:
crash> kmem 0xffff97d03fffee60
CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME
ffff97c900044400 32 123297 162944 1273 4k kmalloc-32
SLAB MEMORY NODE TOTAL ALLOCATED FREE
fffffca460ffff80 ffff97d03fffe000 3 128 81 47
FREE / [ALLOCATED]
[ffff97d03fffee60]
PAGE PHYSICAL MAPPING INDEX CNT FLAGS
fffffca460ffff80 83fffe000 dead000000000001 ffff97d03fffe340 1 d7ffffe0000800 slab
crash> kmem ffff97d03ffff000
PAGE PHYSICAL MAPPING INDEX CNT FLAGS
fffffca460ffffc0 83ffff000 0 0 1 d7ffffe0004000 reserved
crash> dmesg
...
[ 0.000000] BIOS-e820: [mem 0x00000000fe000000-0x00000000fe00ffff] reserved
[ 0.000000] BIOS-e820: [mem 0x0000000100000000-0x000000083fffefff] usable
[ 0.000000] BIOS-e820: [mem 0x000000083ffff000-0x000000083fffffff] reserved
...
The beginning physical address, aka 0x83fffe000, is located in the usable
area and is readable, however the later physical address, starting from
0x83ffff000, is located in reserved region and not readable. In fact,
the affinity member is allocated by alloc_cpumask_var_node(), for the 192 CPUs
system, the allocated size is only 24, and we can see it is within
the kmalloc-32 slab. So it is incorrect to read 1024 length(given by
STRUCT_SIZE("cpumask_t")), only 24 is enough.
Since there are plenty of places in crash which takes the value of
STRUCT_SIZE("cpumask_t"), and works fine for the past, this patch will
not modify them all, only the one which encountered this issue(hunk in
kernel.c), and the one with the same DIV_ROUND_UP() (hunk in tools.c).
Signed-off-by: Tao Liu <ltao@redhat.com>
---
kernel.c | 8 +++++---
tools.c | 10 +++++++---
2 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/kernel.c b/kernel.c
index 8a9d498..adb19ad 100644
--- a/kernel.c
+++ b/kernel.c
@@ -7362,7 +7362,7 @@ void
generic_get_irq_affinity(int irq)
{
ulong irq_desc_addr;
- long len;
+ long len, len_cpumask;
ulong affinity_ptr;
ulong *affinity;
ulong tmp_addr;
@@ -7382,8 +7382,10 @@ generic_get_irq_affinity(int irq)
if (!action)
return;
- if ((len = STRUCT_SIZE("cpumask_t")) < 0)
- len = DIV_ROUND_UP(kt->cpus, BITS_PER_LONG) * sizeof(ulong);
+ len = DIV_ROUND_UP(kt->cpus, BITS_PER_LONG) * sizeof(ulong);
+ len_cpumask = STRUCT_SIZE("cpumask_t");
+ if (len_cpumask > 0)
+ len = len_cpumask > len ? len : len_cpumask;
affinity = (ulong *)GETBUF(len);
if (VALID_MEMBER(irq_common_data_affinity))
diff --git a/tools.c b/tools.c
index 1022d57..2b78b95 100644
--- a/tools.c
+++ b/tools.c
@@ -6718,9 +6718,13 @@ swap64(uint64_t val, int swap)
ulong *
get_cpumask_buf(void)
{
- int cpulen;
- if ((cpulen = STRUCT_SIZE("cpumask_t")) < 0)
- cpulen = DIV_ROUND_UP(kt->cpus, BITS_PER_LONG) * sizeof(ulong);
+ int cpulen, len_cpumask;
+
+ cpulen = DIV_ROUND_UP(kt->cpus, BITS_PER_LONG) * sizeof(ulong);
+ len_cpumask = STRUCT_SIZE("cpumask_t");
+ if (len_cpumask > 0)
+ cpulen = len_cpumask > cpulen ? cpulen : len_cpumask;
+
return (ulong *)GETBUF(cpulen);
}
--
2.40.1

View File

@ -1,143 +0,0 @@
From 48764a14bc5856f0b0bb30685336c68b832154fc Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
Date: Fri, 7 Jun 2024 15:29:23 +0800
Subject: [PATCH 5/9] x86_64: fix for adding top_of_kernel_stack_padding for
kernel stack
With Kernel commit 65c9cc9e2c14 ("x86/fred: Reserve space for the FRED
stack frame") in Linux 6.9-rc1 and later, x86_64 will add extra padding
('TOP_OF_KERNEL_STACK_PADDING (2 * 8)', see: arch/x86/include/asm\
/thread_info.h,) for kernel stack when the CONFIG_X86_FRED is enabled.
As a result, the pt_regs will be moved downwards due to the offset of
padding, and the values of registers read from pt_regs will be incorrect
as below.
Without the patch:
crash> bt
PID: 2040 TASK: ffff969136fc4180 CPU: 16 COMMAND: "bash"
#0 [ffffa996409aba38] machine_kexec at ffffffff9f881eb7
#1 [ffffa996409aba90] __crash_kexec at ffffffff9fa1e49e
#2 [ffffa996409abb48] panic at ffffffff9f91a6cd
#3 [ffffa996409abbc8] sysrq_handle_crash at ffffffffa0015076
#4 [ffffa996409abbd0] __handle_sysrq at ffffffffa0015640
#5 [ffffa996409abc00] write_sysrq_trigger at ffffffffa0015ce5
#6 [ffffa996409abc28] proc_reg_write at ffffffff9fd35bf5
#7 [ffffa996409abc40] vfs_write at ffffffff9fc8d462
#8 [ffffa996409abcd0] ksys_write at ffffffff9fc8dadf
#9 [ffffa996409abd08] do_syscall_64 at ffffffffa0517429
#10 [ffffa996409abf40] entry_SYSCALL_64_after_hwframe at ffffffffa060012b
[exception RIP: unknown or invalid address]
RIP: 0000000000000246 RSP: 0000000000000000 RFLAGS: 0000002b
RAX: 0000000000000002 RBX: 00007f9b9f5b13e0 RCX: 000055cee7486fb0
RDX: 0000000000000001 RSI: 0000000000000001 RDI: 00007f9b9f4fda57
RBP: 0000000000000246 R8: 00007f9b9f4fda57 R9: ffffffffffffffda
R10: 0000000000000000 R11: 00007f9b9f5b14e0 R12: 0000000000000002
R13: 000055cee7486fb0 R14: 0000000000000002 R15: 00007f9b9f5fb780
ORIG_RAX: 0000000000000033 CS: 7ffe65327978 SS: 0000
bt: WARNING: possibly bogus exception frame
crash>
With the patch:
crash> bt
PID: 2040 TASK: ffff969136fc4180 CPU: 16 COMMAND: "bash"
#0 [ffffa996409aba38] machine_kexec at ffffffff9f881eb7
#1 [ffffa996409aba90] __crash_kexec at ffffffff9fa1e49e
#2 [ffffa996409abb48] panic at ffffffff9f91a6cd
#3 [ffffa996409abbc8] sysrq_handle_crash at ffffffffa0015076
#4 [ffffa996409abbd0] __handle_sysrq at ffffffffa0015640
#5 [ffffa996409abc00] write_sysrq_trigger at ffffffffa0015ce5
#6 [ffffa996409abc28] proc_reg_write at ffffffff9fd35bf5
#7 [ffffa996409abc40] vfs_write at ffffffff9fc8d462
#8 [ffffa996409abcd0] ksys_write at ffffffff9fc8dadf
#9 [ffffa996409abd08] do_syscall_64 at ffffffffa0517429
#10 [ffffa996409abf40] entry_SYSCALL_64_after_hwframe at ffffffffa060012b
RIP: 00007f9b9f4fda57 RSP: 00007ffe65327978 RFLAGS: 00000246
RAX: ffffffffffffffda RBX: 0000000000000002 RCX: 00007f9b9f4fda57
RDX: 0000000000000002 RSI: 000055cee7486fb0 RDI: 0000000000000001
RBP: 000055cee7486fb0 R8: 0000000000000000 R9: 00007f9b9f5b14e0
R10: 00007f9b9f5b13e0 R11: 0000000000000246 R12: 0000000000000002
R13: 00007f9b9f5fb780 R14: 0000000000000002 R15: 00007f9b9f5f69e0
ORIG_RAX: 0000000000000001 CS: 0033 SS: 002b
crash>
Link: https://www.mail-archive.com/devel@lists.crash-utility.osci.io/msg00754.html
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
Signed-off-by: Tao Liu <ltao@redhat.com>
---
defs.h | 1 +
kernel.c | 1 +
symbols.c | 1 +
x86_64.c | 6 ++++--
4 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/defs.h b/defs.h
index 01f316e..42d8759 100644
--- a/defs.h
+++ b/defs.h
@@ -2414,6 +2414,7 @@ struct size_table { /* stash of commonly-used sizes */
long maple_tree;
long maple_node;
long module_memory;
+ long fred_frame;
};
struct array_table {
diff --git a/kernel.c b/kernel.c
index 1728b70..cd3d604 100644
--- a/kernel.c
+++ b/kernel.c
@@ -668,6 +668,7 @@ kernel_init()
STRUCT_SIZE_INIT(softirq_state, "softirq_state");
STRUCT_SIZE_INIT(softirq_action, "softirq_action");
STRUCT_SIZE_INIT(desc_struct, "desc_struct");
+ STRUCT_SIZE_INIT(fred_frame, "fred_frame");
STRUCT_SIZE_INIT(char_device_struct, "char_device_struct");
if (VALID_STRUCT(char_device_struct)) {
diff --git a/symbols.c b/symbols.c
index b7627a8..301ce35 100644
--- a/symbols.c
+++ b/symbols.c
@@ -11847,6 +11847,7 @@ dump_offset_table(char *spec, ulong makestruct)
fprintf(fp, " task_struct_flags: %ld\n", SIZE(task_struct_flags));
fprintf(fp, " task_struct_policy: %ld\n", SIZE(task_struct_policy));
fprintf(fp, " thread_info: %ld\n", SIZE(thread_info));
+ fprintf(fp, " fred_frame: %ld\n", SIZE(fred_frame));
fprintf(fp, " softirq_state: %ld\n",
SIZE(softirq_state));
fprintf(fp, " softirq_action: %ld\n",
diff --git a/x86_64.c b/x86_64.c
index 0c21eb8..6777c93 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -4086,10 +4086,11 @@ in_exception_stack:
if (!irq_eframe && !is_kernel_thread(bt->tc->task) &&
(GET_STACKBASE(bt->tc->task) == bt->stackbase)) {
+ long stack_padding_size = SIZE(fred_frame) > 0 ? (2*8) : 0;
user_mode_eframe = bt->stacktop - SIZE(pt_regs);
if (last_process_stack_eframe < user_mode_eframe)
x86_64_exception_frame(EFRAME_PRINT, 0, bt->stackbuf +
- (bt->stacktop - bt->stackbase) - SIZE(pt_regs),
+ (bt->stacktop - stack_padding_size - bt->stackbase) - SIZE(pt_regs),
bt, ofp);
}
@@ -4407,10 +4408,11 @@ in_exception_stack:
if (!irq_eframe && !is_kernel_thread(bt->tc->task) &&
(GET_STACKBASE(bt->tc->task) == bt->stackbase)) {
+ long stack_padding_size = SIZE(fred_frame) > 0 ? (2*8) : 0;
user_mode_eframe = bt->stacktop - SIZE(pt_regs);
if (last_process_stack_eframe < user_mode_eframe)
x86_64_exception_frame(EFRAME_PRINT, 0, bt->stackbuf +
- (bt->stacktop - bt->stackbase) - SIZE(pt_regs),
+ (bt->stacktop - stack_padding_size - bt->stackbase) - SIZE(pt_regs),
bt, ofp);
}
--
2.40.1

View File

@ -1,304 +0,0 @@
From 7c2c90d0b06a0dad00819b7f22be204664a698ff Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?HAGIO=20KAZUHITO=28=E8=90=A9=E5=B0=BE=E3=80=80=E4=B8=80?=
=?UTF-8?q?=E4=BB=81=29?= <k-hagio-ab@nec.com>
Date: Wed, 5 Jun 2024 07:30:03 +0000
Subject: [PATCH 6/9] Fix "kmem -v" option on Linux 6.9 and later kernels
The following kernel commits removed vmap_area_list and vmap_area_root
rb-tree, and introduced vmap_nodes.
55c49fee57af mm/vmalloc: remove vmap_area_list
d093602919ad mm: vmalloc: remove global vmap_area_root rb-tree
Without the patch, the "kmem -v" option and functions that use
dump_vmlist() fail with or without an error:
crash> kmem -v
VM_STRUCT ADDRESS RANGE SIZE
kmem: invalid kernel virtual address: ccccccccccccccd4 type: "vmlist addr"
crash> kmem -v
crash>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
---
defs.h | 4 ++
memory.c | 135 +++++++++++++++++++++++++++++++++++++++++++++---------
symbols.c | 3 ++
3 files changed, 120 insertions(+), 22 deletions(-)
diff --git a/defs.h b/defs.h
index 42d8759..da856c0 100644
--- a/defs.h
+++ b/defs.h
@@ -2240,6 +2240,8 @@ struct offset_table { /* stash of commonly-used offsets */
long mnt_namespace_nr_mounts;
long mount_mnt_node;
long log_caller_id;
+ long vmap_node_busy;
+ long rb_list_head;
};
struct size_table { /* stash of commonly-used sizes */
@@ -2415,6 +2417,7 @@ struct size_table { /* stash of commonly-used sizes */
long maple_node;
long module_memory;
long fred_frame;
+ long vmap_node;
};
struct array_table {
@@ -2679,6 +2682,7 @@ struct vm_table { /* kernel VM-related data */
#define SLAB_OVERLOAD_PAGE (0x8000000)
#define SLAB_CPU_CACHE (0x10000000)
#define SLAB_ROOT_CACHES (0x20000000)
+#define USE_VMAP_NODES (0x40000000)
#define IS_FLATMEM() (vt->flags & FLATMEM)
#define IS_DISCONTIGMEM() (vt->flags & DISCONTIGMEM)
diff --git a/memory.c b/memory.c
index 34ed646..acb8507 100644
--- a/memory.c
+++ b/memory.c
@@ -235,6 +235,7 @@ static void dump_slab_objects(struct meminfo *);
static void dump_slab_objects_percpu(struct meminfo *);
static void dump_vmlist(struct meminfo *);
static void dump_vmap_area(struct meminfo *);
+static int get_vmap_area_list_from_nodes(ulong **);
static int dump_page_lists(struct meminfo *);
static void dump_kmeminfo(void);
static int page_to_phys(ulong, physaddr_t *);
@@ -433,9 +434,15 @@ vm_init(void)
if (VALID_MEMBER(vmap_area_va_start) &&
VALID_MEMBER(vmap_area_va_end) &&
VALID_MEMBER(vmap_area_list) &&
- VALID_MEMBER(vmap_area_vm) &&
- kernel_symbol_exists("vmap_area_list"))
- vt->flags |= USE_VMAP_AREA;
+ VALID_MEMBER(vmap_area_vm)) {
+ if (kernel_symbol_exists("vmap_nodes")) {
+ STRUCT_SIZE_INIT(vmap_node, "vmap_node");
+ MEMBER_OFFSET_INIT(vmap_node_busy, "vmap_node", "busy");
+ MEMBER_OFFSET_INIT(rb_list_head, "rb_list", "head");
+ vt->flags |= USE_VMAP_NODES;
+ } else if (kernel_symbol_exists("vmap_area_list"))
+ vt->flags |= USE_VMAP_AREA;
+ }
if (kernel_symbol_exists("hstates")) {
STRUCT_SIZE_INIT(hstate, "hstate");
@@ -8957,7 +8964,7 @@ dump_vmlist(struct meminfo *vi)
physaddr_t paddr;
int mod_vmlist;
- if (vt->flags & USE_VMAP_AREA) {
+ if (vt->flags & (USE_VMAP_AREA|USE_VMAP_NODES)) {
dump_vmap_area(vi);
return;
}
@@ -9067,6 +9074,77 @@ next_entry:
vi->retval = verified;
}
+static int
+sort_by_va_start(const void *arg1, const void *arg2)
+{
+ ulong va_start1, va_start2;
+
+ readmem(*(ulong *)arg1 + OFFSET(vmap_area_va_start), KVADDR, &va_start1,
+ sizeof(void *), "vmap_area.va_start", FAULT_ON_ERROR);
+ readmem(*(ulong *)arg2 + OFFSET(vmap_area_va_start), KVADDR, &va_start2,
+ sizeof(void *), "vmap_area.va_start", FAULT_ON_ERROR);
+
+ return va_start1 < va_start2 ? -1 : (va_start1 == va_start2 ? 0 : 1);
+}
+
+/* Linux 6.9 and later kernels use "vmap_nodes". */
+static int
+get_vmap_area_list_from_nodes(ulong **list_ptr)
+{
+ int i, cnt, c;
+ struct list_data list_data, *ld = &list_data;
+ uint nr_vmap_nodes;
+ ulong vmap_nodes, list_head;
+ ulong *list, *ptr;
+
+ get_symbol_data("nr_vmap_nodes", sizeof(uint), &nr_vmap_nodes);
+ get_symbol_data("vmap_nodes", sizeof(ulong), &vmap_nodes);
+
+ /* count up all vmap_areas. */
+ cnt = 0;
+ for (i = 0; i < nr_vmap_nodes; i++) {
+ BZERO(ld, sizeof(struct list_data));
+ list_head = vmap_nodes + SIZE(vmap_node) * i +
+ OFFSET(vmap_node_busy) + OFFSET(rb_list_head);
+ readmem(list_head, KVADDR, &ld->start, sizeof(void *),
+ "rb_list.head", FAULT_ON_ERROR);
+ ld->list_head_offset = OFFSET(vmap_area_list);
+ ld->end = list_head;
+ c = do_list(ld);
+ if (c < 0)
+ return -1;
+
+ cnt += c;
+ }
+
+ list = ptr = (ulong *)GETBUF(sizeof(void *) * cnt);
+
+ /* gather all vmap_areas into a list. */
+ for (i = 0; i < nr_vmap_nodes; i++) {
+ BZERO(ld, sizeof(struct list_data));
+ ld->flags = LIST_ALLOCATE;
+ list_head = vmap_nodes + SIZE(vmap_node) * i +
+ OFFSET(vmap_node_busy) + OFFSET(rb_list_head);
+ readmem(list_head, KVADDR, &ld->start, sizeof(void *),
+ "rb_list.head", FAULT_ON_ERROR);
+ ld->list_head_offset = OFFSET(vmap_area_list);
+ ld->end = list_head;
+ c = do_list(ld);
+ if (c < 0)
+ return -1;
+
+ memcpy(ptr, ld->list_ptr, sizeof(void *) * c);
+ ptr += c;
+
+ FREEBUF(ld->list_ptr);
+ }
+
+ qsort(list, cnt, sizeof(void *), sort_by_va_start);
+
+ *list_ptr = list;
+ return cnt;
+}
+
static void
dump_vmap_area(struct meminfo *vi)
{
@@ -9080,26 +9158,37 @@ dump_vmap_area(struct meminfo *vi)
char buf2[BUFSIZE];
char buf3[BUFSIZE];
char buf4[BUFSIZE];
+ ulong *list_ptr;
#define VM_VM_AREA 0x4 /* mm/vmalloc.c */
- vmap_area_buf = GETBUF(SIZE(vmap_area));
start = count = verified = size = 0;
- ld = &list_data;
- BZERO(ld, sizeof(struct list_data));
- ld->flags = LIST_HEAD_FORMAT|LIST_HEAD_POINTER|LIST_ALLOCATE;
- get_symbol_data("vmap_area_list", sizeof(void *), &ld->start);
- ld->list_head_offset = OFFSET(vmap_area_list);
- ld->end = symbol_value("vmap_area_list");
- cnt = do_list(ld);
- if (cnt < 0) {
- FREEBUF(vmap_area_buf);
- error(WARNING, "invalid/corrupt vmap_area_list\n");
- vi->retval = 0;
- return;
+ if (vt->flags & USE_VMAP_NODES) {
+ cnt = get_vmap_area_list_from_nodes(&list_ptr);
+ if (cnt < 0) {
+ error(WARNING, "invalid/corrupt vmap_nodes.busy list\n");
+ vi->retval = 0;
+ return;
+ }
+ } else {
+ ld = &list_data;
+ BZERO(ld, sizeof(struct list_data));
+ ld->flags = LIST_HEAD_FORMAT|LIST_HEAD_POINTER|LIST_ALLOCATE;
+ get_symbol_data("vmap_area_list", sizeof(void *), &ld->start);
+ ld->list_head_offset = OFFSET(vmap_area_list);
+ ld->end = symbol_value("vmap_area_list");
+ cnt = do_list(ld);
+ if (cnt < 0) {
+ error(WARNING, "invalid/corrupt vmap_area_list\n");
+ vi->retval = 0;
+ return;
+ }
+ list_ptr = ld->list_ptr;
}
+ vmap_area_buf = GETBUF(SIZE(vmap_area));
+
for (i = 0; i < cnt; i++) {
if (!(pc->curcmd_flags & HEADER_PRINTED) && (i == 0) &&
!(vi->flags & (GET_HIGHEST|GET_PHYS_TO_VMALLOC|
@@ -9116,7 +9205,7 @@ dump_vmap_area(struct meminfo *vi)
pc->curcmd_flags |= HEADER_PRINTED;
}
- readmem(ld->list_ptr[i], KVADDR, vmap_area_buf,
+ readmem(list_ptr[i], KVADDR, vmap_area_buf,
SIZE(vmap_area), "vmap_area struct", FAULT_ON_ERROR);
if (VALID_MEMBER(vmap_area_flags) &&
@@ -9158,7 +9247,7 @@ dump_vmap_area(struct meminfo *vi)
}
fprintf(fp, "%s%s %s%s %s - %s %7ld\n",
mkstring(buf1,VADDR_PRLEN, LONG_HEX|CENTER|LJUST,
- MKSTR(ld->list_ptr[i])), space(MINSPACE-1),
+ MKSTR(list_ptr[i])), space(MINSPACE-1),
mkstring(buf2,VADDR_PRLEN, LONG_HEX|CENTER|LJUST,
MKSTR(vm_struct)), space(MINSPACE-1),
mkstring(buf3, VADDR_PRLEN, LONG_HEX|RJUST,
@@ -9179,14 +9268,14 @@ dump_vmap_area(struct meminfo *vi)
if (vi->flags & GET_PHYS_TO_VMALLOC) {
vi->retval = pcheck +
PAGEOFFSET(vi->spec_addr);
- FREEBUF(ld->list_ptr);
+ FREEBUF(list_ptr);
return;
} else
fprintf(fp,
"%s%s %s%s %s - %s %7ld\n",
mkstring(buf1,VADDR_PRLEN,
LONG_HEX|CENTER|LJUST,
- MKSTR(ld->list_ptr[i])),
+ MKSTR(list_ptr[i])),
space(MINSPACE-1),
mkstring(buf2, VADDR_PRLEN,
LONG_HEX|CENTER|LJUST,
@@ -9204,7 +9293,7 @@ dump_vmap_area(struct meminfo *vi)
}
FREEBUF(vmap_area_buf);
- FREEBUF(ld->list_ptr);
+ FREEBUF(list_ptr);
if (vi->flags & GET_HIGHEST)
vi->retval = start+size;
@@ -14001,6 +14090,8 @@ dump_vm_table(int verbose)
fprintf(fp, "%sSLAB_ROOT_CACHES", others++ ? "|" : "");\
if (vt->flags & USE_VMAP_AREA)
fprintf(fp, "%sUSE_VMAP_AREA", others++ ? "|" : "");\
+ if (vt->flags & USE_VMAP_NODES)
+ fprintf(fp, "%sUSE_VMAP_NODES", others++ ? "|" : "");\
if (vt->flags & CONFIG_NUMA)
fprintf(fp, "%sCONFIG_NUMA", others++ ? "|" : "");\
if (vt->flags & VM_EVENT)
diff --git a/symbols.c b/symbols.c
index 301ce35..107920f 100644
--- a/symbols.c
+++ b/symbols.c
@@ -10167,6 +10167,8 @@ dump_offset_table(char *spec, ulong makestruct)
fprintf(fp, " vmap_area_flags: %ld\n",
OFFSET(vmap_area_flags));
fprintf(fp, " vmap_area_purge_list: %ld\n", OFFSET(vmap_area_purge_list));
+ fprintf(fp, " vmap_node_busy: %ld\n", OFFSET(vmap_node_busy));
+ fprintf(fp, " rb_list_head: %ld\n", OFFSET(rb_list_head));
fprintf(fp, " module_size_of_struct: %ld\n",
OFFSET(module_size_of_struct));
@@ -12041,6 +12043,7 @@ dump_offset_table(char *spec, ulong makestruct)
SIZE(task_group));
fprintf(fp, " vmap_area: %ld\n",
SIZE(vmap_area));
+ fprintf(fp, " vmap_node: %ld\n", SIZE(vmap_node));
fprintf(fp, " hrtimer_clock_base: %ld\n",
SIZE(hrtimer_clock_base));
fprintf(fp, " hrtimer_base: %ld\n",
--
2.40.1

View File

@ -1,70 +0,0 @@
From 6752571d8d782d07537a258a1ec8919ebd1308ad Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
Date: Wed, 5 Jun 2024 16:28:58 +0800
Subject: [PATCH 7/9] X86 64: fix for crash session loading failure
Kernel commit 223b5e57d0d5 ("mm/execmem, arch: convert remaining
overrides of module_alloc to execmem") makes crash session loading
failure as below:
# ./crash -s
crash: seek error: kernel virtual address: ffffffff826bb418 type: "page_offset_base"
For X86 64 architecture, currently crash will search for symbol
"module_load_offset" to determine if the KASLR is enabled, and go
into the relevant code block. But the symbols "module_load_offset"
has been removed since Linux v6.10-rc1, which caused the current
failure.
And this issue can occur with live debugging and core dump file
debugging.
Let's check the symbol "kaslr_regions" instead of "module_load_offset"
to fix it.
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
symbols.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/symbols.c b/symbols.c
index 107920f..f3c94b0 100644
--- a/symbols.c
+++ b/symbols.c
@@ -619,9 +619,9 @@ strip_symbol_end(const char *name, char *buf)
* or in /proc/kallsyms on a live system.
*
* Setting KASLR_CHECK will trigger a search for "module_load_offset"
- * during the initial symbol sort operation, and if found, will
- * set (RELOC_AUTO|KASLR). On live systems, the search is done
- * here by checking /proc/kallsyms.
+ * or "kaslr_regions" during the initial symbol sort operation, and
+ * if found, will set (RELOC_AUTO|KASLR). On live systems, the search
+ * is done here by checking /proc/kallsyms.
*/
static void
kaslr_init(void)
@@ -646,7 +646,8 @@ kaslr_init(void)
st->_stext_vmlinux = UNINITIALIZED;
if (ACTIVE() && /* Linux 3.15 */
- (symbol_value_from_proc_kallsyms("module_load_offset") != BADVAL)) {
+ ((symbol_value_from_proc_kallsyms("kaslr_regions") != BADVAL) ||
+ (symbol_value_from_proc_kallsyms("module_load_offset") != BADVAL))) {
kt->flags2 |= (RELOC_AUTO|KASLR);
st->_stext_vmlinux = UNINITIALIZED;
}
@@ -14251,7 +14252,9 @@ numeric_forward(const void *P_x, const void *P_y)
st->_stext_vmlinux = valueof(y);
}
if (kt->flags2 & KASLR_CHECK) {
- if (STREQ(x->name, "module_load_offset") ||
+ if (STREQ(x->name, "kaslr_regions") ||
+ STREQ(y->name, "kaslr_regions") ||
+ STREQ(x->name, "module_load_offset") ||
STREQ(y->name, "module_load_offset")) {
kt->flags2 &= ~KASLR_CHECK;
kt->flags2 |= (RELOC_AUTO|KASLR);
--
2.40.1

View File

@ -1,82 +0,0 @@
From a20eb05de3c1cab954d49eb8bb9dc7fe5224caa0 Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
Date: Wed, 5 Jun 2024 17:30:33 +0800
Subject: [PATCH 8/9] Fix for failing to load kernel module
In some kernel modules such as libie.ko, the mem[MOD_TEXT].size
may be zero, currently crash will only check its value to determine
if the module is valid, otherwise it fails to load kernel module with
the following warning and error:
WARNING: invalid kernel module size: 0
KERNEL: /lib/modules/6.10.0-rc1+/build/vmlinux
DUMPFILE: /proc/kcore
CPUS: 64
DATE: Wed Jun 5 12:49:02 IDT 2024
UPTIME: 5 days, 05:57:21
LOAD AVERAGE: 0.28, 0.06, 0.02
TASKS: 806
NODENAME: xxxx
RELEASE: 6.10.0-rc1+
VERSION: #1 SMP PREEMPT_DYNAMIC Fri May 31 04:56:59 IDT 2024
MACHINE: x86_64 (2100 Mhz)
MEMORY: 1.6 GB
PID: 203686
COMMAND: "crash"
TASK: ffff9f9bf66d0000 [THREAD_INFO: ffff9f9bf66d0000]
CPU: 52
STATE: TASK_RUNNING (ACTIVE)
crash> mod
mod: cannot access vmalloc'd module memory
crash>
Lets count the module size to check if the module is valid, that will
avoid the current failure.
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
kernel.c | 20 ++++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/kernel.c b/kernel.c
index cd3d604..8a9d498 100644
--- a/kernel.c
+++ b/kernel.c
@@ -3822,9 +3822,21 @@ module_init(void)
case KALLSYMS_V2:
if (THIS_KERNEL_VERSION >= LINUX(2,6,27)) {
numksyms = UINT(modbuf + OFFSET(module_num_symtab));
- if (MODULE_MEMORY())
- /* check mem[MOD_TEXT].size only */
- size = UINT(modbuf + OFFSET(module_mem) + OFFSET(module_memory_size));
+ if (MODULE_MEMORY()) {
+ /*
+ * The mem[MOD_TEXT].size may be zero, lets count
+ * the module size as below.
+ */
+ int t;
+ size = 0;
+ for_each_mod_mem_type(t) {
+ if (t == MOD_INIT_TEXT)
+ break;
+ size += UINT(modbuf + OFFSET(module_mem) +
+ SIZE(module_memory) * t +
+ OFFSET(module_memory_size));
+ }
+ }
else
size = UINT(modbuf + MODULE_OFFSET2(module_core_size, rx));
} else {
@@ -3927,7 +3939,7 @@ verify_modules(void)
for (i = 0, found = FALSE; i < kt->mods_installed; i++) {
lm = &st->load_modules[i];
- if (!kvtop(NULL, lm->mod_base, &paddr, 0)) {
+ if (lm->mod_base && !kvtop(NULL, lm->mod_base, &paddr, 0)) {
irregularities++;
break;
}
--
2.40.1

View File

@ -1,69 +0,0 @@
From 196c4b79c13d1c0e6d7b21c8321eca07d3838d6a Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
Date: Wed, 12 Jun 2024 11:00:00 +0800
Subject: [PATCH 9/9] X86 64: fix a regression issue about kernel stack padding
The commit 48764a14bc58 may cause a regression issue when the CONFIG_X86_FRED
is not enabled, this is because the SIZE(fred_frame) will call the
SIZE_verify() to determine if the fred_frame is valid, otherwise it will
emit an error:
crash> bt 1
bt: invalid structure size: fred_frame
FILE: x86_64.c LINE: 4089 FUNCTION: x86_64_low_budget_back_trace_cmd()
[/home/k-hagio/bin/crash] error trace: 588df3 => 5cbc72 => 5eb3e1 => 5eb366
PID: 1 TASK: ffff9f94c024b980 CPU: 2 COMMAND: "systemd"
#0 [ffffade44001bca8] __schedule at ffffffffb948ebbb
#1 [ffffade44001bd10] schedule at ffffffffb948f04d
#2 [ffffade44001bd20] schedule_hrtimeout_range_clock at ffffffffb9494fef
#3 [ffffade44001bda8] ep_poll at ffffffffb8c91be8
#4 [ffffade44001be48] do_epoll_wait at ffffffffb8c91d11
#5 [ffffade44001be80] __x64_sys_epoll_wait at ffffffffb8c92590
#6 [ffffade44001bed0] do_syscall_64 at ffffffffb947f459
#7 [ffffade44001bf50] entry_SYSCALL_64_after_hwframe at ffffffffb96000ea
5eb366: SIZE_verify.part.42+70
5eb3e1: SIZE_verify+49
5cbc72: x86_64_low_budget_back_trace_cmd+3010
588df3: back_trace+1523
bt: invalid structure size: fred_frame
FILE: x86_64.c LINE: 4089 FUNCTION: x86_64_low_budget_back_trace_cmd()
Let's replace the SIZE(fred_frame) with the VALID_SIZE(fred_frame) to
fix it.
Fixes: 48764a14bc58 ("x86_64: fix for adding top_of_kernel_stack_padding for kernel stack")
Reported-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
x86_64.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/x86_64.c b/x86_64.c
index 6777c93..469d26b 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -4086,7 +4086,7 @@ in_exception_stack:
if (!irq_eframe && !is_kernel_thread(bt->tc->task) &&
(GET_STACKBASE(bt->tc->task) == bt->stackbase)) {
- long stack_padding_size = SIZE(fred_frame) > 0 ? (2*8) : 0;
+ long stack_padding_size = VALID_SIZE(fred_frame) ? (2*8) : 0;
user_mode_eframe = bt->stacktop - SIZE(pt_regs);
if (last_process_stack_eframe < user_mode_eframe)
x86_64_exception_frame(EFRAME_PRINT, 0, bt->stackbuf +
@@ -4408,7 +4408,7 @@ in_exception_stack:
if (!irq_eframe && !is_kernel_thread(bt->tc->task) &&
(GET_STACKBASE(bt->tc->task) == bt->stackbase)) {
- long stack_padding_size = SIZE(fred_frame) > 0 ? (2*8) : 0;
+ long stack_padding_size = VALID_SIZE(fred_frame) ? (2*8) : 0;
user_mode_eframe = bt->stacktop - SIZE(pt_regs);
if (last_process_stack_eframe < user_mode_eframe)
x86_64_exception_frame(EFRAME_PRINT, 0, bt->stackbuf +
--
2.40.1

View File

@ -1,5 +1,5 @@
--- crash-8.0.5/Makefile.orig
+++ crash-8.0.5/Makefile
--- crash-8.0.6/Makefile.orig
+++ crash-8.0.6/Makefile
@@ -204,7 +204,7 @@ GDB_FLAGS=
# TARGET_CFLAGS will be configured automatically by configure
TARGET_CFLAGS=
@ -18,8 +18,8 @@
@echo "../../${PROGRAM} ../../${PROGRAM}lib.a" > ${GDB}/gdb/mergeobj
@rm -f ${PROGRAM}
@if [ ! -f ${GDB}/config.status ]; then \
--- crash-8.0.5/configure.c.orig
+++ crash-8.0.5/configure.c
--- crash-8.0.6/configure.c.orig
+++ crash-8.0.6/configure.c
@@ -810,7 +810,8 @@ build_configure(struct supported_gdb_version *sp)
fprintf(fp2, "%s\n", sp->GDB);
sprintf(target_data.gdb_version, "%s", &sp->GDB[4]);

View File

@ -3,8 +3,8 @@
#
Summary: Kernel analysis utility for live systems, netdump, diskdump, kdump, LKCD or mcore dumpfiles
Name: crash
Version: 8.0.5
Release: 6%{?dist}
Version: 8.0.6
Release: 1%{?dist}
License: GPL-3.0-only
Source0: https://github.com/crash-utility/crash/archive/crash-%{version}.tar.gz
Source1: http://ftp.gnu.org/gnu/gdb/gdb-10.2.tar.gz
@ -18,23 +18,7 @@ Requires: binutils
Provides: bundled(libiberty)
Provides: bundled(gdb) = 10.2
Patch0: lzo_snappy_zstd.patch
Patch1: crash-8.0.5_build.patch
Patch2: 0001-Adding-the-zram-decompression-algorithm-lzo-rle.patch
Patch3: 0002-Cleanup-replace-struct-zspage_5_17-with-union.patch
Patch4: 0003-arm64-section_size_bits-compatible-with-macro-defini.patch
Patch5: 0004-Reflect-__-start-end-_init_task-kernel-symbols-renam.patch
Patch6: 0005-x86_64-fix-for-adding-top_of_kernel_stack_padding-fo.patch
Patch7: 0006-Fix-kmem-v-option-on-Linux-6.9-and-later-kernels.patch
Patch8: 0007-X86-64-fix-for-crash-session-loading-failure.patch
Patch9: 0008-Fix-for-failing-to-load-kernel-module.patch
Patch10: 0009-X86-64-fix-a-regression-issue-about-kernel-stack-pad.patch
Patch11: 0001-Fix-kmem-i-and-swap-commands-on-Linux-6.10-rc1-and-l.patch
Patch12: 0002-List-enable-LIST_HEAD_FORMAT-for-r-option.patch
Patch13: 0001-arm64-fix-a-potential-segfault-when-unwind-frame.patch
Patch14: 0002-arm64-Fix-bt-command-show-wrong-stacktrace-on-ramdum.patch
Patch15: 0003-arm64-Introduction-of-support-for-16K-page-with-3-le.patch
Patch16: 0004-LoongArch64-fix-incorrect-code-in-the-main.patch
Patch17: 0005-Fix-irq-a-exceeding-the-memory-range-issue.patch
Patch1: crash-8.0.6_build.patch
%description
The core analysis suite is a self-contained tool that can be used to
@ -56,22 +40,6 @@ offered by Mission Critical Linux, or the LKCD kernel patch.
%setup -n %{name}-%{version} -q
%patch -P 0 -p1 -b lzo_snappy_zstd.patch
%patch -P 1 -p1
%patch -P 2 -p1
%patch -P 3 -p1
%patch -P 4 -p1
%patch -P 5 -p1
%patch -P 6 -p1
%patch -P 7 -p1
%patch -P 8 -p1
%patch -P 9 -p1
%patch -P 10 -p1
%patch -P 11 -p1
%patch -P 12 -p1
%patch -P 13 -p1
%patch -P 14 -p1
%patch -P 15 -p1
%patch -P 16 -p1
%patch -P 17 -p1
%build
@ -97,6 +65,9 @@ cp -p defs.h %{buildroot}%{_includedir}/crash
%{_includedir}/*
%changelog
* Tue Nov 19 2024 Tao Liu <ltao@redhat.com> - 8.0.6-1
- Rebase to upstream crash 8.0.6
* Tue Oct 29 2024 Troy Dawson <tdawson@redhat.com> - 8.0.5-6
- Bump release for October 2024 mass rebuild:
Resolves: RHEL-64018

View File

@ -1,5 +1,5 @@
--- crash-8.0.5/Makefile.orig
+++ crash-8.0.5/Makefile
--- crash-8.0.6/Makefile.orig
+++ crash-8.0.6/Makefile
@@ -256,7 +256,7 @@ all: make_configure
gdb_merge: force
@if [ ! -f ${GDB}/README ]; then \
@ -9,8 +9,8 @@
@echo "../../${PROGRAM} ../../${PROGRAM}lib.a" > ${GDB}/gdb/mergeobj
@rm -f ${PROGRAM}
@if [ ! -f ${GDB}/config.status ]; then \
--- crash-8.0.5/diskdump.c.orig
+++ crash-8.0.5/diskdump.c
--- crash-8.0.6/diskdump.c.orig
+++ crash-8.0.6/diskdump.c
@@ -23,6 +23,9 @@
* GNU General Public License for more details.
*/

View File

@ -1,2 +1,2 @@
SHA512 (crash-8.0.5.tar.gz) = 0e199899fcc479eeebd1177a88dfe26725d9f63361d5ff7dbf9cb0f8425d3c6b8d60aada0a4312f61eecfe0ed0cca346034e12accbf5896446db8d9fb7d55e05
SHA512 (gdb-10.2.tar.gz) = aa89caf47c1c84366020377d47e7c51ddbc48e5b7686f244e38797c8eb88411cf57fcdc37eb669961efb41ceeac4181747f429625fd1acce7712cb9a1fea9c41
SHA512 (crash-8.0.6.tar.gz) = a569c0e9cb9dddbdd4bf54b6157b33eb2ed0fef143fd8128e660cf3a7156a23c25d17736fb0711781457d92a1ec8c153a6c020d1847adc57ecc0b5b085ddbfdc