import crash-7.2.6-2.el8

This commit is contained in:
CentOS Sources 2019-11-05 14:04:53 -05:00
parent 6087332729
commit bc6356dc5c
27 changed files with 78 additions and 5219 deletions

View File

@ -1 +1 @@
1a9fa8cd6869da42314ec47df6a750e053f4bece SOURCES/crash-7.2.3.tar.gz c972d50634ae15fac036bd1f8f9f84d87a54acba SOURCES/crash-7.2.6.tar.gz

2
.gitignore vendored
View File

@ -1 +1 @@
SOURCES/crash-7.2.3.tar.gz SOURCES/crash-7.2.6.tar.gz

View File

@ -1,154 +0,0 @@
commit 0f65ae0c36bf04e22219f28c32c3ae0cdee5acfe
Author: Dave Anderson <anderson@redhat.com>
Date: Fri Dec 7 15:17:37 2018 -0500
Implemented a new plugin function for the readline library's tab
completion feature. Without the patch, the use of the default plugin
from the embedded gdb module has been seen to cause segmentation
violations or other fatal malloc/free/corruption assertions. The new
plugin takes gdb out of the picture entirely, and also restricts the
matching options to just symbol names, so as not to clutter the
results with irrelevant filenames.
(anderson@redhat.com)
diff --git a/cmdline.c b/cmdline.c
index cf3e150..665f48c 100644
--- a/cmdline.c
+++ b/cmdline.c
@@ -40,6 +40,8 @@ int shell_command(char *);
static void modify_orig_line(char *, struct args_input_file *);
static void modify_expression_arg(char *, char **, struct args_input_file *);
static int verify_args_input_file(char *);
+static char *crash_readline_completion_generator(const char *, int);
+static char **crash_readline_completer(const char *, int, int);
#define READLINE_LIBRARY
@@ -2073,6 +2075,9 @@ readline_init(void)
if (STREQ(pc->editing_mode, "emacs")) {
rl_editing_mode = emacs_mode;
}
+
+ rl_attempted_completion_function = crash_readline_completer;
+ rl_attempted_completion_over = 1;
}
/*
@@ -2610,3 +2615,27 @@ exec_args_input_file(struct command_table_entry *ct, struct args_input_file *aif
fclose(pc->args_ifile);
pc->args_ifile = NULL;
}
+
+static char *
+crash_readline_completion_generator(const char *match, int state)
+{
+ static struct syment *sp_match;
+
+ if (state == 0)
+ sp_match = NULL;
+
+ sp_match = symbol_complete_match(match, sp_match);
+
+ if (sp_match)
+ return(strdup(sp_match->name));
+ else
+ return NULL;
+}
+
+static char **
+crash_readline_completer(const char *match, int start, int end)
+{
+ rl_attempted_completion_over = 1;
+ return rl_completion_matches(match, crash_readline_completion_generator);
+}
+
diff --git a/defs.h b/defs.h
index 9ce32c1..a3cb5a4 100644
--- a/defs.h
+++ b/defs.h
@@ -5153,6 +5153,7 @@ void parse_for_member_extended(struct datatype_member *, ulong);
void add_to_downsized(char *);
int is_downsized(char *);
int is_string(char *, char *);
+struct syment *symbol_complete_match(const char *, struct syment *);
/*
* memory.c
diff --git a/symbols.c b/symbols.c
index 05628ff..0769294 100644
--- a/symbols.c
+++ b/symbols.c
@@ -13108,3 +13108,73 @@ is_downsized(char *name)
return FALSE;
}
+
+struct syment *
+symbol_complete_match(const char *match, struct syment *sp_last)
+{
+ int i;
+ struct syment *sp, *sp_end, *sp_start;
+ struct load_module *lm;
+ int search_init;
+
+ if (sp_last) {
+ sp_start = next_symbol(NULL, sp_last);
+ if (!sp_start)
+ return NULL;
+ } else
+ sp_start = st->symtable;
+
+ if ((sp_start >= st->symtable) && (sp_start < st->symend)) {
+ for (sp = sp_start; sp < st->symend; sp++) {
+ if (STRNEQ(sp->name, match))
+ return sp;
+ }
+ sp_start = NULL;
+ }
+
+ search_init = FALSE;
+
+ for (i = 0; i < st->mods_installed; i++) {
+ lm = &st->load_modules[i];
+ if (lm->mod_flags & MOD_INIT)
+ search_init = TRUE;
+ sp_end = lm->mod_symend;
+ if (!sp_start)
+ sp_start = lm->mod_symtable;
+
+ if ((sp_start >= lm->mod_symtable) && (sp_start < sp_end)) {
+ for (sp = sp_start; sp < sp_end; sp++) {
+ if (MODULE_START(sp))
+ continue;
+
+ if (STRNEQ(sp->name, match))
+ return sp;
+ }
+ sp_start = NULL;
+ }
+ }
+
+ if (!search_init)
+ return NULL;
+
+ for (i = 0; i < st->mods_installed; i++) {
+ lm = &st->load_modules[i];
+ if (!lm->mod_init_symtable)
+ continue;
+ sp_end = lm->mod_init_symend;
+ if (!sp_start)
+ sp_start = lm->mod_init_symtable;
+
+ if ((sp_start >= lm->mod_init_symtable) && (sp_start < sp_end)) {
+ for (sp = sp_start; sp < sp_end; sp++) {
+ if (MODULE_START(sp))
+ continue;
+
+ if (STRNEQ(sp->name, match))
+ return sp;
+ }
+ }
+ }
+
+ return NULL;
+}

View File

@ -1,27 +0,0 @@
commit 1926150ee350e17fee2aeabb8ef781222d94366e
Author: Dave Anderson <anderson@redhat.com>
Date: Mon Jun 11 13:46:41 2018 -0400
Fix for the ppc64/ppc64le "bt" command on Linux 4.7 and later kernels
that contain commit d8bff643d81a58181356c0aa3ab771ac10da6894,
titled "[x86] asm: Make sure verify_cpu() has a good stack", which
inadvertently breaks the ppc64/ppc64le kernel stack size calculation
when running with crash-7.2.2 or later. Without the patch, "bt" may
fail with a filtered kdump dumpfile with the two error messages
"bt: page excluded: kernel virtual address: <address> type: stack
contents" and "bt: read of stack at <address> failed".
(anderson@redhat.com)
diff --git a/task.c b/task.c
index f6956d5..1b32629 100644
--- a/task.c
+++ b/task.c
@@ -440,7 +440,7 @@ task_init(void)
} else if (VALID_SIZE(thread_union) &&
((len = SIZE(thread_union)) != STACKSIZE())) {
machdep->stacksize = len;
- } else {
+ } else if (!VALID_SIZE(thread_union) && !VALID_SIZE(task_union)) {
if (kernel_symbol_exists("__start_init_task") &&
kernel_symbol_exists("__end_init_task")) {
len = symbol_value("__end_init_task");

View File

@ -1,412 +0,0 @@
commit 27a6ebd0cda386b1dfb7b0fffb4d8b489b391ccf
Author: Dave Anderson <anderson@redhat.com>
Date: Mon Sep 24 16:33:57 2018 -0400
Resurrection of the the "dev -p" option for displaying PCI device
data on Linux 2.6.26 and later kernels. The option was deprecated
as of Linux 2.6.26, and without the patch, the option would indicate
"dev: -p option not supported or applicable on this architecture
or kernel" when running against the newer kernel versions. PCI Bus
information will also be displayed with this patch.
(m.mizuma@jp.fujitsu.com)
diff --git a/defs.h b/defs.h
index d6492c5..80c61ef 100644
--- a/defs.h
+++ b/defs.h
@@ -2032,6 +2032,17 @@ struct offset_table {
long bpf_prog_aux_user;
long user_struct_uid;
long idr_cur;
+ long pci_dev_dev;
+ long pci_dev_hdr_type;
+ long pci_dev_pcie_flags_reg;
+ long pci_bus_node;
+ long pci_bus_devices;
+ long pci_bus_dev;
+ long pci_bus_children;
+ long pci_bus_parent;
+ long pci_bus_self;
+ long device_kobj;
+ long kobject_name;
};
struct size_table { /* stash of commonly-used sizes */
diff --git a/dev.c b/dev.c
index 3db898a..7ce2422 100644
--- a/dev.c
+++ b/dev.c
@@ -24,6 +24,7 @@ static void dump_blkdevs_v3(ulong);
static ulong search_cdev_map_probes(char *, int, int, ulong *);
static ulong search_bdev_map_probes(char *, int, int, ulong *);
static void do_pci(void);
+static void do_pci2(void);
static void do_io(void);
static void do_resource_list(ulong, char *, int);
@@ -51,11 +52,23 @@ dev_init(void)
MEMBER_OFFSET_INIT(pci_dev_global_list, "pci_dev", "global_list");
MEMBER_OFFSET_INIT(pci_dev_next, "pci_dev", "next");
MEMBER_OFFSET_INIT(pci_dev_bus, "pci_dev", "bus");
+ MEMBER_OFFSET_INIT(pci_dev_dev, "pci_dev", "dev");
MEMBER_OFFSET_INIT(pci_dev_devfn, "pci_dev", "devfn");
MEMBER_OFFSET_INIT(pci_dev_class, "pci_dev", "class");
MEMBER_OFFSET_INIT(pci_dev_device, "pci_dev", "device");
+ MEMBER_OFFSET_INIT(pci_dev_hdr_type, "pci_dev", "hdr_type");
+ MEMBER_OFFSET_INIT(pci_dev_pcie_flags_reg, "pci_dev", "pcie_flags_reg");
MEMBER_OFFSET_INIT(pci_dev_vendor, "pci_dev", "vendor");
MEMBER_OFFSET_INIT(pci_bus_number, "pci_bus", "number");
+ MEMBER_OFFSET_INIT(pci_bus_node, "pci_bus", "node");
+ MEMBER_OFFSET_INIT(pci_bus_devices, "pci_bus", "devices");
+ MEMBER_OFFSET_INIT(pci_bus_dev, "pci_bus", "dev");
+ MEMBER_OFFSET_INIT(pci_bus_children, "pci_bus", "children");
+ MEMBER_OFFSET_INIT(pci_bus_parent, "pci_bus", "parent");
+ MEMBER_OFFSET_INIT(pci_bus_self, "pci_bus", "self");
+
+ MEMBER_OFFSET_INIT(device_kobj, "device", "kobj");
+ MEMBER_OFFSET_INIT(kobject_name, "kobject", "name");
STRUCT_SIZE_INIT(resource, "resource");
if ((VALID_STRUCT(resource) && symbol_exists("do_resource_list")) ||
@@ -114,10 +127,14 @@ cmd_dev(void)
return;
case 'p':
- if (machine_type("S390X") ||
- (THIS_KERNEL_VERSION >= LINUX(2,6,26)))
+ if (machine_type("S390X"))
+ option_not_supported(c);
+ if (symbol_exists("pci_devices"))
+ do_pci();
+ else if (symbol_exists("pci_root_buses"))
+ do_pci2();
+ else
option_not_supported(c);
- do_pci();
return;
default:
@@ -2217,6 +2234,313 @@ do_resource_list(ulong first_entry, char *resource_buf, int size)
#endif /* USE_2_2_17_PCI_H */
+#define PCI_EXP_FLAGS_TYPE 0x00f0 /* Device/Port type */
+#define PCI_EXP_TYPE_ENDPOINT 0x0 /* Express Endpoint */
+#define PCI_EXP_TYPE_LEG_END 0x1 /* Legacy Endpoint */
+#define PCI_EXP_TYPE_ROOT_PORT 0x4 /* Root Port */
+#define PCI_EXP_TYPE_UPSTREAM 0x5 /* Upstream Port */
+#define PCI_EXP_TYPE_DOWNSTREAM 0x6 /* Downstream Port */
+#define PCI_EXP_TYPE_PCI_BRIDGE 0x7 /* PCIe to PCI/PCI-X Bridge */
+#define PCI_EXP_TYPE_PCIE_BRIDGE 0x8 /* PCI/PCI-X to PCIe Bridge */
+#define PCI_EXP_TYPE_RC_END 0x9 /* Root Complex Integrated Endpoint */
+#define PCI_EXP_TYPE_RC_EC 0xa /* Root Complex Event Collector */
+
+static void
+fill_dev_name(ulong pci_dev, char *name)
+{
+ ulong kobj, value;
+
+ memset(name, 0, sizeof(*name) * BUFSIZE);
+
+ kobj = pci_dev + OFFSET(pci_dev_dev) + OFFSET(device_kobj);
+
+ readmem(kobj + OFFSET(kobject_name),
+ KVADDR, &value, sizeof(void *), "kobject name",
+ FAULT_ON_ERROR);
+
+ read_string(value, name, BUFSIZE-1);
+}
+
+static void
+fill_bus_name(ulong pci_bus, char *name)
+{
+ ulong kobj, value;
+
+ memset(name, 0, sizeof(*name) * BUFSIZE);
+
+ kobj = pci_bus + OFFSET(pci_bus_dev) + OFFSET(device_kobj);
+
+ readmem(kobj + OFFSET(kobject_name),
+ KVADDR, &value, sizeof(void *), "kobject name",
+ FAULT_ON_ERROR);
+
+ read_string(value, name, BUFSIZE-1);
+}
+
+static void
+fill_dev_id(ulong pci_dev, char *id)
+{
+ unsigned short device, vendor;
+
+ memset(id, 0, sizeof(*id) * BUFSIZE);
+
+ readmem(pci_dev + OFFSET(pci_dev_device),
+ KVADDR, &device, sizeof(short), "pci dev device",
+ FAULT_ON_ERROR);
+ readmem(pci_dev + OFFSET(pci_dev_vendor), KVADDR,
+ &vendor, sizeof(short), "pci dev vendor", FAULT_ON_ERROR);
+
+ sprintf(id, "%x:%x", vendor, device);
+}
+
+static void
+fill_dev_class(ulong pci_dev, char *c)
+{
+ unsigned int class;
+
+ memset(c, 0, sizeof(*c) * BUFSIZE);
+ readmem(pci_dev + OFFSET(pci_dev_class), KVADDR,
+ &class, sizeof(int), "pci class", FAULT_ON_ERROR);
+
+ class >>= 8;
+
+ sprintf(c, "%04x", class);
+}
+
+static int
+pci_pcie_type(ulong cap)
+{
+ return (cap & PCI_EXP_FLAGS_TYPE) >> 4;
+}
+
+static int
+pci_is_bridge(unsigned char hdr_type)
+{
+ return hdr_type == PCI_HEADER_TYPE_BRIDGE ||
+ hdr_type == PCI_HEADER_TYPE_CARDBUS;
+}
+
+static void
+fill_pcie_type(ulong pcidev, char *t)
+{
+ int type, bufidx = 0;
+ unsigned short pciecap;
+ unsigned char hdr_type;
+
+ memset(t, 0, sizeof(*t) * BUFSIZE);
+
+ readmem(pcidev + OFFSET(pci_dev_hdr_type), KVADDR, &hdr_type,
+ sizeof(char), "pci dev hdr_type", FAULT_ON_ERROR);
+
+ if (!VALID_MEMBER(pci_dev_pcie_flags_reg))
+ goto bridge_chk;
+
+ readmem(pcidev + OFFSET(pci_dev_pcie_flags_reg), KVADDR, &pciecap,
+ sizeof(unsigned short), "pci dev pcie_flags_reg", FAULT_ON_ERROR);
+
+ type = pci_pcie_type(pciecap);
+
+ if (type == PCI_EXP_TYPE_ENDPOINT)
+ bufidx = sprintf(t, "ENDPOINT");
+ else if (type == PCI_EXP_TYPE_LEG_END)
+ bufidx = sprintf(t, "LEG_END");
+ else if (type == PCI_EXP_TYPE_ROOT_PORT)
+ bufidx = sprintf(t, "ROOT_PORT");
+ else if (type == PCI_EXP_TYPE_UPSTREAM)
+ bufidx = sprintf(t, "UPSTREAM");
+ else if (type == PCI_EXP_TYPE_DOWNSTREAM)
+ bufidx = sprintf(t, "DOWNSTREAM");
+ else if (type == PCI_EXP_TYPE_PCI_BRIDGE)
+ bufidx = sprintf(t, "PCI_BRIDGE");
+ else if (type == PCI_EXP_TYPE_PCIE_BRIDGE)
+ bufidx = sprintf(t, "PCIE_BRIDGE");
+ else if (type == PCI_EXP_TYPE_RC_END)
+ bufidx = sprintf(t, "RC_END");
+ else if (type == PCI_EXP_TYPE_RC_EC)
+ bufidx = sprintf(t, "RC_EC");
+
+bridge_chk:
+ if (pci_is_bridge(hdr_type))
+ sprintf(t + bufidx, " [BRIDGE]");
+}
+
+static void
+walk_devices(ulong pci_bus)
+{
+ struct list_data list_data, *ld;
+ int devcnt, i;
+ ulong *devlist, self;
+ char name[BUFSIZE], class[BUFSIZE], id[BUFSIZE], type[BUFSIZE];
+ char pcidev_hdr[BUFSIZE];
+ char buf1[BUFSIZE];
+ char buf2[BUFSIZE];
+ char buf3[BUFSIZE];
+ char buf4[BUFSIZE];
+ char buf5[BUFSIZE];
+
+ ld = &list_data;
+
+ BZERO(ld, sizeof(struct list_data));
+
+ readmem(pci_bus + OFFSET(pci_bus_devices), KVADDR,
+ &ld->start, sizeof(void *), "pci bus devices",
+ FAULT_ON_ERROR);
+
+ if (VALID_MEMBER(pci_dev_pcie_flags_reg))
+ snprintf(pcidev_hdr, sizeof(pcidev_hdr), "%s %s %s %s %s\n",
+ mkstring(buf1, VADDR_PRLEN, CENTER, "PCI DEV"),
+ mkstring(buf2, strlen("0000:00:00.0"), CENTER, "DO:BU:SL.FN"),
+ mkstring(buf3, strlen("0000") + 2, CENTER, "CLASS"),
+ mkstring(buf4, strlen("0000:0000"), CENTER, "PCI_ID"),
+ mkstring(buf5, 10, CENTER, "TYPE"));
+ else
+ snprintf(pcidev_hdr, sizeof(pcidev_hdr), "%s %s %s %s\n",
+ mkstring(buf1, VADDR_PRLEN, CENTER, "PCI DEV"),
+ mkstring(buf2, strlen("0000:00:00.0"), CENTER, "DO:BU:SL.FN"),
+ mkstring(buf3, strlen("0000") + 2, CENTER, "CLASS"),
+ mkstring(buf4, strlen("0000:0000"), CENTER, "PCI_ID"));
+
+ fprintf(fp, " %s", pcidev_hdr);
+
+ readmem(pci_bus + OFFSET(pci_bus_self), KVADDR, &self,
+ sizeof(void *), "pci bus self", FAULT_ON_ERROR);
+ if (self) {
+ fill_dev_name(self, name);
+ fill_dev_class(self, class);
+ fill_dev_id(self, id);
+ fill_pcie_type(self, type);
+ fprintf(fp, " %s %s %s %s %s\n",
+ mkstring(buf1, VADDR_PRLEN, LJUST|LONG_HEX,
+ MKSTR(self)),
+ mkstring(buf2, strlen("0000:00:00.0"), CENTER, name),
+ mkstring(buf3, strlen("0000") + 2, CENTER, class),
+ mkstring(buf4, strlen("0000:0000"), CENTER, id),
+ mkstring(buf5, 10, CENTER, type));
+ }
+
+ if (ld->start == (pci_bus + OFFSET(pci_bus_devices)))
+ return;
+
+ ld->end = pci_bus + OFFSET(pci_bus_devices);
+ hq_open();
+ devcnt = do_list(ld);
+ devlist = (ulong *)GETBUF(devcnt * sizeof(ulong));
+ devcnt = retrieve_list(devlist, devcnt);
+ hq_close();
+
+ for (i = 0; i < devcnt; i++) {
+ fill_dev_name(devlist[i], name);
+ fill_dev_class(devlist[i], class);
+ fill_dev_id(devlist[i], id);
+ fill_pcie_type(devlist[i], type);
+ fprintf(fp, " %s %s %s %s %s\n",
+ mkstring(buf1, VADDR_PRLEN, LJUST|LONG_HEX,
+ MKSTR(devlist[i])),
+ mkstring(buf2, strlen("0000:00:00.0"), CENTER, name),
+ mkstring(buf3, strlen("0000") + 2, CENTER, class),
+ mkstring(buf4, strlen("0000:0000"), CENTER, id),
+ mkstring(buf5, 10, CENTER, type));
+ }
+ FREEBUF(devlist);
+}
+
+static void
+walk_buses(ulong pci_bus)
+{
+ struct list_data list_data, *ld;
+ int buscnt, i;
+ ulong *buslist, parent;
+ char pcibus_hdr[BUFSIZE];
+ char buf1[BUFSIZE];
+ char buf2[BUFSIZE];
+
+ ld = &list_data;
+
+ BZERO(ld, sizeof(struct list_data));
+
+ readmem(pci_bus + OFFSET(pci_bus_children), KVADDR,
+ &ld->start, sizeof(void *), "pci bus children",
+ FAULT_ON_ERROR);
+
+ if (ld->start == (pci_bus + OFFSET(pci_bus_children)))
+ return;
+
+ ld->end = pci_bus + OFFSET(pci_bus_children);
+ hq_open();
+ buscnt = do_list(ld);
+ buslist = (ulong *)GETBUF(buscnt * sizeof(ulong));
+ buscnt = retrieve_list(buslist, buscnt);
+ hq_close();
+
+ snprintf(pcibus_hdr, sizeof(pcibus_hdr), "%s %s\n",
+ mkstring(buf1, VADDR_PRLEN, CENTER, "PCI BUS"),
+ mkstring(buf2, VADDR_PRLEN, CENTER, "PARENT BUS"));
+
+ for (i = 0; i < buscnt; i++) {
+ readmem(buslist[i] + OFFSET(pci_bus_parent), KVADDR, &parent,
+ sizeof(void *), "pci bus parent", FAULT_ON_ERROR);
+
+ fprintf(fp, " %s", pcibus_hdr);
+
+ fprintf(fp, " %s %s\n",
+ mkstring(buf1, VADDR_PRLEN, LJUST|LONG_HEX,
+ MKSTR(buslist[i])),
+ mkstring(buf2, VADDR_PRLEN, LJUST|LONG_HEX,
+ MKSTR(parent)));
+ walk_devices(buslist[i]);
+ fprintf(fp, "\n");
+ walk_buses(buslist[i]);
+ }
+ FREEBUF(buslist);
+}
+
+static void
+do_pci2(void)
+{
+ struct list_data list_data, *ld;
+ int rootbuscnt, i;
+ ulong *rootbuslist;
+ unsigned long pci_root_bus_addr = symbol_value("pci_root_buses");
+ char name[BUFSIZE];
+ char pcirootbus_hdr[BUFSIZE];
+ char buf1[BUFSIZE];
+ char buf2[BUFSIZE];
+
+ ld = &list_data;
+ BZERO(ld, sizeof(struct list_data));
+
+ get_symbol_data("pci_root_buses", sizeof(void *), &ld->start);
+
+ if (ld->start == pci_root_bus_addr)
+ error(FATAL, "no PCI devices found on this system.\n");
+
+ ld->end = pci_root_bus_addr;
+
+ hq_open();
+ rootbuscnt = do_list(ld);
+ rootbuslist = (ulong *)GETBUF(rootbuscnt * sizeof(ulong));
+ rootbuscnt = retrieve_list(rootbuslist, rootbuscnt);
+ hq_close();
+
+ snprintf(pcirootbus_hdr, sizeof(pcirootbus_hdr), "%s %s\n",
+ mkstring(buf1, VADDR_PRLEN, CENTER, "ROOT BUS"),
+ mkstring(buf2, strlen("0000:00"), CENTER, "BUSNAME"));
+
+ for (i = 0; i < rootbuscnt; i++) {
+ fprintf(fp, "%s", pcirootbus_hdr);
+ fill_bus_name(rootbuslist[i], name);
+ fprintf(fp, "%s %s\n",
+ mkstring(buf1, VADDR_PRLEN, LJUST|LONG_HEX,
+ MKSTR(rootbuslist[i])),
+ mkstring(buf2, strlen("0000:00"), CENTER, name));
+ walk_devices(rootbuslist[i]);
+ walk_buses(rootbuslist[i]);
+
+ fprintf(fp, "\n");
+ }
+ FREEBUF(rootbuslist);
+}
+
static void
do_pci(void)
{
@@ -2230,9 +2554,6 @@ do_pci(void)
char buf2[BUFSIZE];
char buf3[BUFSIZE];
- if (!symbol_exists("pci_devices"))
- error(FATAL, "no PCI devices found on this system.\n");
-
BZERO(&pcilist_data, sizeof(struct list_data));
if (VALID_MEMBER(pci_dev_global_list)) {

View File

@ -1,174 +0,0 @@
commit 28fa7bd09013455b5ddc020dea4706278cda0d65
Author: Dave Anderson <anderson@redhat.com>
Date: Tue Jun 19 16:31:54 2018 -0400
Fix for PPC64 kernel virtual address translation in Linux 4.17 and
later kernels with commit c2b4d8b7417a59b7f9a52d0d8402f5257cbbd398,
titled "powerpc/mm/hash64: Increase the VA range", in which the
maximum virtual address value has been increased to 4PB. Without
the patch, the translation/access of high vmalloc space addresses
fails; for example, the "kmem -[sS]" option fails the translation
of per-cpu kmem_cache_cpu addresses located in vmalloc space, with
the error messages "kmem: invalid kernel virtual address: <address>
type: kmem_cache_cpu.freelist" and "kmem: invalid kernel virtual
address: <address> type: kmem_cache_cpu.page", and the "vtop"
command shows the addresses as "(not mapped)".
(hbathini@linux.ibm.com)
diff --git a/defs.h b/defs.h
index 6e6f6be..e6e3850 100644
--- a/defs.h
+++ b/defs.h
@@ -3977,6 +3977,7 @@ struct efi_memory_desc_t {
#define PMD_INDEX_SIZE_L4_64K_4_12 10
#define PUD_INDEX_SIZE_L4_64K_4_12 7
#define PGD_INDEX_SIZE_L4_64K_4_12 8
+#define PUD_INDEX_SIZE_L4_64K_4_17 10
#define PTE_INDEX_SIZE_RADIX_64K 5
#define PMD_INDEX_SIZE_RADIX_64K 9
#define PUD_INDEX_SIZE_RADIX_64K 9
diff --git a/ppc64.c b/ppc64.c
index 0dd8a2a..f5d0dac 100644
--- a/ppc64.c
+++ b/ppc64.c
@@ -451,7 +451,10 @@ ppc64_init(int when)
if (THIS_KERNEL_VERSION >= LINUX(4,12,0)) {
m->l2_index_size = PMD_INDEX_SIZE_L4_64K_4_12;
- m->l3_index_size = PUD_INDEX_SIZE_L4_64K_4_12;
+ if (THIS_KERNEL_VERSION >= LINUX(4,17,0))
+ m->l3_index_size = PUD_INDEX_SIZE_L4_64K_4_17;
+ else
+ m->l3_index_size = PUD_INDEX_SIZE_L4_64K_4_12;
m->l4_index_size = PGD_INDEX_SIZE_L4_64K_4_12;
} else {
m->l2_index_size = PMD_INDEX_SIZE_L4_64K_4_6;
commit e5df29d54bbdb8b84cb1661233ed186b153be746
Author: Dave Anderson <anderson@redhat.com>
Date: Wed Jun 20 11:15:38 2018 -0400
Fix for the x86_64 "bt" command in which a legitimate exception
frame is appended with the message "bt: WARNING: possibly bogus
exception frame". This only happens in KASLR-enabled kernels when
the text address that was executing when the exception occurred
is marked as a "weak" symbol (type "W") instead of a text symbol
(type "T" or "t"). As a result, the exception frame's RIP is not
recognized as a text symbol, and the warning message is displayed.
(anderson@redhat.com)
diff --git a/symbols.c b/symbols.c
index bb4ae3a..bf55319 100644
--- a/symbols.c
+++ b/symbols.c
@@ -2755,9 +2755,14 @@ is_kernel_text(ulong value)
section);
end = start + (ulong)bfd_section_size(st->bfd,
section);
+
+ if (kt->flags2 & KASLR) {
+ start += (kt->relocate * -1);
+ end += (kt->relocate * -1);
+ }
- if ((value >= start) && (value < end))
- return TRUE;
+ if ((value >= start) && (value < end))
+ return TRUE;
}
}
}
@@ -2833,7 +2838,16 @@ is_kernel_text_offset(ulong value)
int
is_symbol_text(struct syment *sp)
{
- return ((sp->type == 'T') || (sp->type == 't'));
+ if ((sp->type == 'T') || (sp->type == 't'))
+ return TRUE;
+
+ if ((sp->type == 'W') || (sp->type == 'w')) {
+ if ((sp->value >= kt->stext) &&
+ (sp->value < kt->etext))
+ return TRUE;
+ }
+
+ return FALSE;
}
/*
commit a7e5b90757bb41ad5e148177c5b3aaf5d892243d
Author: Dave Anderson <anderson@redhat.com>
Date: Wed Jun 20 16:33:43 2018 -0400
Fix for the x86_64 "bt" command in Linux 4.16 and later kernels
containing commit 3aa99fc3e708b9cd9b4cfe2df0b7a66cf293e3cf, titled
"x86/entry/64: Remove 'interrupt' macro". Without the patch, the
exception frame display generated by an interrupt exception will
show incorrect contents, and be followed by the message "bt: WARNING:
possibly bogus exception frame".
(anderson@redhat.com)
diff --git a/x86_64.c b/x86_64.c
index e01082b..6d1ae2f 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -4285,6 +4285,12 @@ x86_64_exception_frame(ulong flags, ulong kvaddr, char *local,
long err;
char buf[BUFSIZE];
+ if (flags == EFRAME_VERIFY) {
+ if (!accessible(kvaddr) ||
+ !accessible(kvaddr + SIZE(pt_regs) - sizeof(long)))
+ return FALSE;
+ }
+
ms = machdep->machspec;
sp = NULL;
@@ -6283,6 +6289,9 @@ x86_64_irq_eframe_link(ulong stkref, struct bt_info *bt, FILE *ofp)
{
ulong irq_eframe;
+ if (x86_64_exception_frame(EFRAME_VERIFY, stkref, 0, bt, ofp))
+ return stkref;
+
irq_eframe = stkref - machdep->machspec->irq_eframe_link;
if (x86_64_exception_frame(EFRAME_VERIFY, irq_eframe, 0, bt, ofp))
commit 02efd0838f05ef8a7fe21b0b8ba6cad729270645
Author: Dave Anderson <anderson@redhat.com>
Date: Fri Jun 22 11:00:01 2018 -0400
Fix for the failure of several "kmem" command options, most notably
seen if the command is piped directly into a crash session, or if
the command is contained in an input file. For examples:
$ echo "kmem -i" | crash ...
$ crash -i <input-file> ...
Without the patch, the kmem command may fail with the error message
"<segmentation violation in gdb>". While the bug is due to a buffer
overflow that has always existed, it only is triggered by certain
kernel configurations.
(anderson@redhat.com)
diff --git a/memory.c b/memory.c
index 2f568d5..5c0a853 100644
--- a/memory.c
+++ b/memory.c
@@ -17498,13 +17498,12 @@ vm_stat_init(void)
STREQ(arglist[0], "NR_VM_ZONE_STAT_ITEMS")) {
continue;
} else {
- stringlen += strlen(arglist[0]);
+ stringlen += strlen(arglist[0]) + 1;
count++;
}
}
- total = stringlen + vt->nr_vm_stat_items +
- (sizeof(void *) * vt->nr_vm_stat_items);
+ total = stringlen + (sizeof(void *) * vt->nr_vm_stat_items);
if (!(vt->vm_stat_items = (char **)malloc(total))) {
close_tmpfile();
error(FATAL, "cannot malloc vm_stat_items cache\n");

View File

@ -1,58 +0,0 @@
commit 2f57a96ce27d8b121c2822de2a66c71b83bdad21
Author: Dave Anderson <anderson@redhat.com>
Date: Tue Sep 4 14:29:45 2018 -0400
Fix for the "files" command in Linux 4.17 and later kernels that
contain commit b93b016313b3ba8003c3b8bb71f569af91f19fc7, titled
"page cache: use xa_lock". Without the patch, the "files -c" option
fails with the message "files: -c option not supported or applicable
on this architecture or kernel", and the "files -p &lt;inode>" option
fails in a similar manner.
(k-hagio@ab.jp.nec.com)
diff --git a/filesys.c b/filesys.c
index 47f5a24..32daa5a 100644
--- a/filesys.c
+++ b/filesys.c
@@ -2207,6 +2207,11 @@ dump_inode_page_cache_info(ulong inode)
RJUST|LONG_DEC,
MKSTR(nrpages)));
+ FREEBUF(inode_buf);
+
+ if (!nrpages)
+ return;
+
root_rnode = i_mapping + OFFSET(address_space_page_tree);
rtp.index = 0;
rtp.value = (void *)&dump_inode_page;
@@ -2217,7 +2222,6 @@ dump_inode_page_cache_info(ulong inode)
error(INFO, "page_tree count: %ld nrpages: %ld\n",
count, nrpages);
- FREEBUF(inode_buf);
return;
}
@@ -2275,7 +2279,7 @@ cmd_files(void)
return;
case 'c':
- if (VALID_MEMBER(address_space_page_tree) &&
+ if (VALID_MEMBER(address_space_nrpages) &&
VALID_MEMBER(inode_i_mapping))
open_flags |= PRINT_NRPAGES;
else
diff --git a/memory.c b/memory.c
index 24fce5e..ea25047 100644
--- a/memory.c
+++ b/memory.c
@@ -485,6 +485,8 @@ vm_init(void)
MEMBER_OFFSET_INIT(block_device_bd_disk, "block_device", "bd_disk");
MEMBER_OFFSET_INIT(inode_i_mapping, "inode", "i_mapping");
MEMBER_OFFSET_INIT(address_space_page_tree, "address_space", "page_tree");
+ if (INVALID_MEMBER(address_space_page_tree))
+ MEMBER_OFFSET_INIT(address_space_page_tree, "address_space", "i_pages");
MEMBER_OFFSET_INIT(address_space_nrpages, "address_space", "nrpages");
if (INVALID_MEMBER(address_space_nrpages))
MEMBER_OFFSET_INIT(address_space_nrpages, "address_space", "__nrpages");

View File

@ -1,45 +0,0 @@
commit 3141bba98af302e2a7c5e2a19203bb8a40b6aa63
Author: Dave Anderson <anderson@redhat.com>
Date: Wed Oct 10 09:15:42 2018 -0400
Fix the calculation of the vmalloc memory region size to account for
Linux 4.17 commit a7412546d8cb5ad578805060b4006f2a021b5868, titled
"x86/mm: Adjust vmalloc base and size at boot-time", which increases
the region's size from 32TB to 1280TB when 5-level pagetables are
enabled. Also presume that virtual addresses above the end of the
vmalloc space up to the beginning of vmemmap space are translatable
via 5-level page tables. Without the patch, mapped virtual addresses
may fail translation in whatever command accesses them, with errors
indicating "seek error: kernel virtual address: <mapped-address>
type: <type-string>"
(anderson@redhat.com)
diff --git a/x86_64.c b/x86_64.c
index 6f547e8..345122c 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -393,8 +393,12 @@ x86_64_init(int when)
readmem(symbol_value("vmalloc_base"), KVADDR,
&machdep->machspec->vmalloc_start_addr,
sizeof(ulong), "vmalloc_base", FAULT_ON_ERROR);
- machdep->machspec->vmalloc_end =
- machdep->machspec->vmalloc_start_addr + TERABYTES(32) - 1;
+ if (machdep->flags & VM_5LEVEL)
+ machdep->machspec->vmalloc_end =
+ machdep->machspec->vmalloc_start_addr + TERABYTES(1280) - 1;
+ else
+ machdep->machspec->vmalloc_end =
+ machdep->machspec->vmalloc_start_addr + TERABYTES(32) - 1;
if (kernel_symbol_exists("vmemmap_base")) {
readmem(symbol_value("vmemmap_base"), KVADDR,
&machdep->machspec->vmemmap_vaddr, sizeof(ulong),
@@ -1626,7 +1630,8 @@ x86_64_IS_VMALLOC_ADDR(ulong vaddr)
(vaddr >= VSYSCALL_START && vaddr < VSYSCALL_END) ||
(machdep->machspec->cpu_entry_area_start &&
vaddr >= machdep->machspec->cpu_entry_area_start &&
- vaddr <= machdep->machspec->cpu_entry_area_end));
+ vaddr <= machdep->machspec->cpu_entry_area_end) ||
+ ((machdep->flags & VM_5LEVEL) && vaddr > VMALLOC_END && vaddr < VMEMMAP_VADDR));
}
static int

View File

@ -1,196 +0,0 @@
commit 361f050e3148c6188afb45942e06d4a509852b86
Author: Dave Anderson <anderson@redhat.com>
Date: Mon Jan 7 13:56:15 2019 -0500
Fix for the "dev -[dD]" options in kernels containing Linux 5.0-rc1
commit 7ff4f8035695984c513598e2d49c8277d5d234ca, titled "block:
remove dead queue members", in which the number of I/Os issued to
a disk driver are no longer stored in the request_queue structure.
Without the patch, the options indicate "dev: -d option not supported
or applicable on this architecture or kernel". With the patch, the
"DRV" column is not shown.
(m.mizuma@jp.fujitsu.com)
diff --git a/defs.h b/defs.h
index a3cb5a4..9ebdde6 100644
--- a/defs.h
+++ b/defs.h
@@ -2043,6 +2043,8 @@ struct offset_table {
long pci_bus_self;
long device_kobj;
long kobject_name;
+ long hd_struct_dkstats;
+ long disk_stats_in_flight;
};
struct size_table { /* stash of commonly-used sizes */
diff --git a/dev.c b/dev.c
index 7ce2422..24efea2 100644
--- a/dev.c
+++ b/dev.c
@@ -3974,7 +3974,7 @@ struct iter {
* this function reads request_list.count[2], and the first argument
* is the address of request_queue.
*/
- void (*get_diskio)(unsigned long , struct diskio *);
+ void (*get_diskio)(unsigned long , unsigned long, struct diskio *);
/*
* check if device.type == &disk_type
@@ -4187,24 +4187,55 @@ get_mq_diskio(unsigned long q, unsigned long *mq_count)
}
}
+static void
+get_one_diskio_from_dkstats(unsigned long dkstats, unsigned long *count)
+{
+ int cpu;
+ unsigned long dkstats_addr;
+ unsigned long in_flight[2];
+
+ for (cpu = 0; cpu < kt->cpus; cpu++) {
+ if ((kt->flags & SMP) && (kt->flags & PER_CPU_OFF)) {
+ dkstats_addr = dkstats + kt->__per_cpu_offset[cpu];
+ readmem(dkstats_addr + OFFSET(disk_stats_in_flight),
+ KVADDR, in_flight, sizeof(long) * 2,
+ "disk_stats.in_flight", FAULT_ON_ERROR);
+ count[0] += in_flight[0];
+ count[1] += in_flight[1];
+ }
+ }
+}
+
+
/* read request_queue.rq.count[2] */
static void
-get_diskio_1(unsigned long rq, struct diskio *io)
+get_diskio_1(unsigned long rq, unsigned long gendisk, struct diskio *io)
{
int count[2];
- unsigned long mq_count[2] = { 0 };
+ unsigned long io_counts[2] = { 0 };
+ unsigned long dkstats;
if (!use_mq_interface(rq)) {
- readmem(rq + OFFSET(request_queue_rq) +
- OFFSET(request_list_count), KVADDR, count,
- sizeof(int) * 2, "request_list.count", FAULT_ON_ERROR);
+ if (VALID_MEMBER(request_queue_rq)) {
+ readmem(rq + OFFSET(request_queue_rq) +
+ OFFSET(request_list_count), KVADDR, count,
+ sizeof(int) * 2, "request_list.count", FAULT_ON_ERROR);
+
+ io->read = count[0];
+ io->write = count[1];
+ } else {
+ readmem(gendisk + OFFSET(gendisk_part0) +
+ OFFSET(hd_struct_dkstats), KVADDR, &dkstats,
+ sizeof(ulong), "gendisk.part0.dkstats", FAULT_ON_ERROR);
+ get_one_diskio_from_dkstats(dkstats, io_counts);
- io->read = count[0];
- io->write = count[1];
+ io->read = io_counts[0];
+ io->write = io_counts[1];
+ }
} else {
- get_mq_diskio(rq, mq_count);
- io->read = mq_count[0];
- io->write = mq_count[1];
+ get_mq_diskio(rq, io_counts);
+ io->read = io_counts[0];
+ io->write = io_counts[1];
}
}
@@ -4250,9 +4281,6 @@ init_iter(struct iter *i)
i->get_in_flight = get_in_flight_1;
} else if (SIZE(rq_in_flight) == sizeof(int) * 2) {
i->get_in_flight = get_in_flight_2;
- } else {
- option_not_supported('d');
- return;
}
i->get_diskio = get_diskio_1;
@@ -4354,7 +4382,7 @@ display_one_diskio(struct iter *i, unsigned long gendisk, ulong flags)
sizeof(ulong), "gen_disk.queue", FAULT_ON_ERROR);
readmem(gendisk + OFFSET(gendisk_major), KVADDR, &major, sizeof(int),
"gen_disk.major", FAULT_ON_ERROR);
- i->get_diskio(queue_addr, &io);
+ i->get_diskio(queue_addr, gendisk, &io);
if ((flags & DIOF_NONZERO)
&& (io.read + io.write == 0))
@@ -4379,11 +4407,14 @@ display_one_diskio(struct iter *i, unsigned long gendisk, ulong flags)
(char *)(unsigned long)io.write),
space(MINSPACE));
- if (!use_mq_interface(queue_addr)) {
- in_flight = i->get_in_flight(queue_addr);
- fprintf(fp, "%5u\n", in_flight);
+ if (VALID_MEMBER(request_queue_in_flight)) {
+ if (!use_mq_interface(queue_addr)) {
+ in_flight = i->get_in_flight(queue_addr);
+ fprintf(fp, "%5u\n", in_flight);
+ } else
+ fprintf(fp, "%s\n", "N/A(MQ)");
} else
- fprintf(fp, "%s\n", "N/A(MQ)");
+ fprintf(fp, "\n");
}
static void
@@ -4418,7 +4449,7 @@ display_all_diskio(ulong flags)
i.sync_count ? mkstring(buf4, 5, RJUST, "SYNC") :
mkstring(buf4, 5, RJUST, "WRITE"),
space(MINSPACE),
- mkstring(buf5, 5, RJUST, "DRV"));
+ VALID_MEMBER(request_queue_in_flight) ? mkstring(buf5, 5, RJUST, "DRV") : "");
while ((gendisk = i.next_disk(&i)) != 0)
display_one_diskio(&i, gendisk, flags);
@@ -4446,6 +4477,7 @@ void diskio_init(void)
MEMBER_OFFSET_INIT(gendisk_part0, "gendisk", "part0");
MEMBER_OFFSET_INIT(gendisk_queue, "gendisk", "queue");
MEMBER_OFFSET_INIT(hd_struct_dev, "hd_struct", "__dev");
+ MEMBER_OFFSET_INIT(hd_struct_dkstats, "hd_struct", "dkstats");
MEMBER_OFFSET_INIT(klist_k_list, "klist", "k_list");
MEMBER_OFFSET_INIT(klist_node_n_klist, "klist_node", "n_klist");
MEMBER_OFFSET_INIT(klist_node_n_node, "klist_node", "n_node");
@@ -4476,6 +4508,7 @@ void diskio_init(void)
MEMBER_SIZE_INIT(rq_in_flight, "request_queue", "in_flight");
MEMBER_SIZE_INIT(class_private_devices, "class_private",
"class_devices");
+ MEMBER_OFFSET_INIT(disk_stats_in_flight, "disk_stats", "in_flight");
dt->flags |= DISKIO_INIT;
}
diff --git a/help.c b/help.c
index aadd2ed..1593e82 100644
--- a/help.c
+++ b/help.c
@@ -3218,7 +3218,7 @@ char *help_dev[] = {
" WRITE: I/O requests that are writes (older kernels)",
" DRV: I/O requests that are in-flight in the device driver.",
" If the device driver uses blk-mq interface, this field",
-" shows N/A(MQ).",
+" shows N/A(MQ). If not available, this column is not shown.",
" -D same as -d, but filter out disks with no in-progress I/O requests.",
"\nEXAMPLES",
" Display character and block device data:\n",
diff --git a/symbols.c b/symbols.c
index ef6f934..5f77e27 100644
--- a/symbols.c
+++ b/symbols.c
@@ -10021,6 +10021,10 @@ dump_offset_table(char *spec, ulong makestruct)
OFFSET(gendisk_queue));
fprintf(fp, " hd_struct_dev: %ld\n",
OFFSET(hd_struct_dev));
+ fprintf(fp, " hd_struct_dkstats: %ld\n",
+ OFFSET(hd_struct_dkstats));
+ fprintf(fp, " disk_stats_in_flight: %ld\n",
+ OFFSET(disk_stats_in_flight));
fprintf(fp, " klist_k_list: %ld\n",
OFFSET(klist_k_list));
fprintf(fp, " klist_node_n_klist: %ld\n",

View File

@ -1,414 +0,0 @@
commit 46d2121960d81354facf4e2558c81f82257b740e
Author: Dave Anderson <anderson@redhat.com>
Date: Tue May 29 14:04:03 2018 -0400
Fix for the "timer -r" command on Linux 4.10 and later kernels that
contain commit 2456e855354415bfaeb7badaa14e11b3e02c8466, titled
"ktime: Get rid of the union". Without the patch, the command fails
with the error message "timer: invalid structure member offset:
ktime_t_sec".
(k-hagio@ab.jp.nec.com)
diff --git a/kernel.c b/kernel.c
index b1886ce..138a47f 100644
--- a/kernel.c
+++ b/kernel.c
@@ -7740,7 +7740,7 @@ ktime_to_ns(const void *ktime)
if (VALID_MEMBER(ktime_t_tv64)) {
readmem((ulong)ktime + OFFSET(ktime_t_tv64), KVADDR, &ns,
sizeof(ns), "ktime_t tv64", QUIET|RETURN_ON_ERROR);
- } else {
+ } else if (VALID_MEMBER(ktime_t_sec) && VALID_MEMBER(ktime_t_nsec)) {
uint32_t sec, nsec;
sec = 0;
@@ -7753,6 +7753,9 @@ ktime_to_ns(const void *ktime)
sizeof(nsec), "ktime_t nsec", QUIET|RETURN_ON_ERROR);
ns = sec * 1000000000L + nsec;
+ } else {
+ readmem((ulong)ktime, KVADDR, &ns,
+ sizeof(ns), "ktime_t", QUIET|RETURN_ON_ERROR);
}
return ns;
commit a6cd8408d1d214a67ed0c4b09343fec77a8e2ae7
Author: Dave Anderson <anderson@redhat.com>
Date: Thu May 31 11:43:14 2018 -0400
Fix for the x86 and x86_64 "mach -m" option on Linux 4.12 and later
kernels to account for the structure name changes "e820map" to
"e820_table", and "e820entry" to "e820_entry", and for the symbol
name change from "e820" to "e820_table". Also updated the display
output to properly translate E820_PRAM and E820_RESERVED_KERN entries.
Without the patch on all kernels, E820_PRAM and E820_RESERVED_KERN
entries show "type 12" and "type 128" respectively. Without the
patch on Linux 4.12 and later kernels, the command fails with the
error message "mach: cannot resolve e820".
(anderson@redhat.com)
diff --git a/x86.c b/x86.c
index 47767b6..88562b6 100644
--- a/x86.c
+++ b/x86.c
@@ -1,8 +1,8 @@
/* x86.c - core analysis suite
*
* Portions Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc.
- * Copyright (C) 2002-2014,2017 David Anderson
- * Copyright (C) 2002-2014,2017 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2002-2014,2017-2018 David Anderson
+ * Copyright (C) 2002-2014,2017-2018 Red Hat, Inc. All rights reserved.
*
* 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
@@ -1967,15 +1967,27 @@ x86_init(int when)
}
MEMBER_OFFSET_INIT(thread_struct_cr3, "thread_struct", "cr3");
STRUCT_SIZE_INIT(cpuinfo_x86, "cpuinfo_x86");
- STRUCT_SIZE_INIT(e820map, "e820map");
- STRUCT_SIZE_INIT(e820entry, "e820entry");
STRUCT_SIZE_INIT(irq_ctx, "irq_ctx");
+ if (STRUCT_EXISTS("e820map")) {
+ STRUCT_SIZE_INIT(e820map, "e820map");
+ MEMBER_OFFSET_INIT(e820map_nr_map, "e820map", "nr_map");
+ } else {
+ STRUCT_SIZE_INIT(e820map, "e820_table");
+ MEMBER_OFFSET_INIT(e820map_nr_map, "e820_table", "nr_entries");
+ }
+ if (STRUCT_EXISTS("e820entry")) {
+ STRUCT_SIZE_INIT(e820entry, "e820entry");
+ MEMBER_OFFSET_INIT(e820entry_addr, "e820entry", "addr");
+ MEMBER_OFFSET_INIT(e820entry_size, "e820entry", "size");
+ MEMBER_OFFSET_INIT(e820entry_type, "e820entry", "type");
+ } else {
+ STRUCT_SIZE_INIT(e820entry, "e820_entry");
+ MEMBER_OFFSET_INIT(e820entry_addr, "e820_entry", "addr");
+ MEMBER_OFFSET_INIT(e820entry_size, "e820_entry", "size");
+ MEMBER_OFFSET_INIT(e820entry_type, "e820_entry", "type");
+ }
if (!VALID_STRUCT(irq_ctx))
STRUCT_SIZE_INIT(irq_ctx, "irq_stack");
- MEMBER_OFFSET_INIT(e820map_nr_map, "e820map", "nr_map");
- MEMBER_OFFSET_INIT(e820entry_addr, "e820entry", "addr");
- MEMBER_OFFSET_INIT(e820entry_size, "e820entry", "size");
- MEMBER_OFFSET_INIT(e820entry_type, "e820entry", "type");
if (KVMDUMP_DUMPFILE())
set_kvm_iohole(NULL);
if (symbol_exists("irq_desc"))
@@ -4415,33 +4427,54 @@ static char *e820type[] = {
static void
x86_display_memmap(void)
{
- ulong e820;
- int nr_map, i;
- char *buf, *e820entry_ptr;
- ulonglong addr, size;
- ulong type;
+ ulong e820;
+ int nr_map, i;
+ char *buf, *e820entry_ptr;
+ ulonglong addr, size;
+ uint type;
+
+ if (kernel_symbol_exists("e820")) {
+ if (get_symbol_type("e820", NULL, NULL) == TYPE_CODE_PTR)
+ get_symbol_data("e820", sizeof(void *), &e820);
+ else
+ e820 = symbol_value("e820");
+
+ } else if (kernel_symbol_exists("e820_table"))
+ get_symbol_data("e820_table", sizeof(void *), &e820);
+ else
+ error(FATAL, "neither e820 or e820_table symbols exist\n");
- e820 = symbol_value("e820");
- buf = (char *)GETBUF(SIZE(e820map));
+ if (CRASHDEBUG(1)) {
+ if (STRUCT_EXISTS("e820map"))
+ dump_struct("e820map", e820, RADIX(16));
+ else if (STRUCT_EXISTS("e820_table"))
+ dump_struct("e820_table", e820, RADIX(16));
+ }
+ buf = (char *)GETBUF(SIZE(e820map));
- readmem(e820, KVADDR, &buf[0], SIZE(e820map),
- "e820map", FAULT_ON_ERROR);
+ readmem(e820, KVADDR, &buf[0], SIZE(e820map),
+ "e820map", FAULT_ON_ERROR);
- nr_map = INT(buf + OFFSET(e820map_nr_map));
+ nr_map = INT(buf + OFFSET(e820map_nr_map));
- fprintf(fp, " PHYSICAL ADDRESS RANGE TYPE\n");
+ fprintf(fp, " PHYSICAL ADDRESS RANGE TYPE\n");
- for (i = 0; i < nr_map; i++) {
- e820entry_ptr = buf + sizeof(int) + (SIZE(e820entry) * i);
- addr = ULONGLONG(e820entry_ptr + OFFSET(e820entry_addr));
- size = ULONGLONG(e820entry_ptr + OFFSET(e820entry_size));
- type = ULONG(e820entry_ptr + OFFSET(e820entry_type));
+ for (i = 0; i < nr_map; i++) {
+ e820entry_ptr = buf + sizeof(int) + (SIZE(e820entry) * i);
+ addr = ULONGLONG(e820entry_ptr + OFFSET(e820entry_addr));
+ size = ULONGLONG(e820entry_ptr + OFFSET(e820entry_size));
+ type = UINT(e820entry_ptr + OFFSET(e820entry_type));
fprintf(fp, "%016llx - %016llx ", addr, addr+size);
- if (type >= (sizeof(e820type)/sizeof(char *)))
- fprintf(fp, "type %ld\n", type);
- else
+ if (type >= (sizeof(e820type)/sizeof(char *))) {
+ if (type == 12)
+ fprintf(fp, "E820_PRAM\n");
+ else if (type == 128)
+ fprintf(fp, "E820_RESERVED_KERN\n");
+ else
+ fprintf(fp, "type %d\n", type);
+ } else
fprintf(fp, "%s\n", e820type[type]);
- }
+ }
}
/*
diff --git a/x86_64.c b/x86_64.c
index 921552b..1d5e155 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -415,12 +415,26 @@ x86_64_init(int when)
STRUCT_SIZE_INIT(gate_struct, "gate_desc");
else
STRUCT_SIZE_INIT(gate_struct, "gate_struct");
- STRUCT_SIZE_INIT(e820map, "e820map");
- STRUCT_SIZE_INIT(e820entry, "e820entry");
- MEMBER_OFFSET_INIT(e820map_nr_map, "e820map", "nr_map");
- MEMBER_OFFSET_INIT(e820entry_addr, "e820entry", "addr");
- MEMBER_OFFSET_INIT(e820entry_size, "e820entry", "size");
- MEMBER_OFFSET_INIT(e820entry_type, "e820entry", "type");
+
+ if (STRUCT_EXISTS("e820map")) {
+ STRUCT_SIZE_INIT(e820map, "e820map");
+ MEMBER_OFFSET_INIT(e820map_nr_map, "e820map", "nr_map");
+ } else {
+ STRUCT_SIZE_INIT(e820map, "e820_table");
+ MEMBER_OFFSET_INIT(e820map_nr_map, "e820_table", "nr_entries");
+ }
+ if (STRUCT_EXISTS("e820entry")) {
+ STRUCT_SIZE_INIT(e820entry, "e820entry");
+ MEMBER_OFFSET_INIT(e820entry_addr, "e820entry", "addr");
+ MEMBER_OFFSET_INIT(e820entry_size, "e820entry", "size");
+ MEMBER_OFFSET_INIT(e820entry_type, "e820entry", "type");
+ } else {
+ STRUCT_SIZE_INIT(e820entry, "e820_entry");
+ MEMBER_OFFSET_INIT(e820entry_addr, "e820_entry", "addr");
+ MEMBER_OFFSET_INIT(e820entry_size, "e820_entry", "size");
+ MEMBER_OFFSET_INIT(e820entry_type, "e820_entry", "type");
+ }
+
if (KVMDUMP_DUMPFILE())
set_kvm_iohole(NULL);
MEMBER_OFFSET_INIT(thread_struct_rip, "thread_struct", "rip");
@@ -5643,12 +5657,23 @@ x86_64_display_memmap(void)
ulonglong addr, size;
uint type;
- if (get_symbol_type("e820", NULL, NULL) == TYPE_CODE_PTR)
- get_symbol_data("e820", sizeof(void *), &e820);
+ if (kernel_symbol_exists("e820")) {
+ if (get_symbol_type("e820", NULL, NULL) == TYPE_CODE_PTR)
+ get_symbol_data("e820", sizeof(void *), &e820);
+ else
+ e820 = symbol_value("e820");
+
+ } else if (kernel_symbol_exists("e820_table"))
+ get_symbol_data("e820_table", sizeof(void *), &e820);
else
- e820 = symbol_value("e820");
- if (CRASHDEBUG(1))
- dump_struct("e820map", e820, RADIX(16));
+ error(FATAL, "neither e820 or e820_table symbols exist\n");
+
+ if (CRASHDEBUG(1)) {
+ if (STRUCT_EXISTS("e820map"))
+ dump_struct("e820map", e820, RADIX(16));
+ else if (STRUCT_EXISTS("e820_table"))
+ dump_struct("e820_table", e820, RADIX(16));
+ }
buf = (char *)GETBUF(SIZE(e820map));
readmem(e820, KVADDR, &buf[0], SIZE(e820map),
@@ -5664,9 +5689,14 @@ x86_64_display_memmap(void)
size = ULONGLONG(e820entry_ptr + OFFSET(e820entry_size));
type = UINT(e820entry_ptr + OFFSET(e820entry_type));
fprintf(fp, "%016llx - %016llx ", addr, addr+size);
- if (type >= (sizeof(e820type)/sizeof(char *)))
- fprintf(fp, "type %d\n", type);
- else
+ if (type >= (sizeof(e820type)/sizeof(char *))) {
+ if (type == 12)
+ fprintf(fp, "E820_PRAM\n");
+ else if (type == 128)
+ fprintf(fp, "E820_RESERVED_KERN\n");
+ else
+ fprintf(fp, "type %d\n", type);
+ } else
fprintf(fp, "%s\n", e820type[type]);
}
}
commit da49e2010b3cb88b4755d69d38fe90af6ba218b2
Author: Dave Anderson <anderson@redhat.com>
Date: Fri Jun 1 10:58:00 2018 -0400
Update for the recognition of the new x86_64 CPU_ENTRY_AREA virtual
address range introduced in Linux 4.15. The memory range exists
above the vmemmap range and below the mapped kernel static text/data
region, and where all of the x86_64 exception stacks have been moved.
Without the patch, reads from the new memory region fail because the
address range is not recognized as a legitimate virtual address.
Most notable is the failure of "bt" on tasks whose backtraces
originate from any of the exception stacks, which fail with the two
error messages "bt: seek error: kernel virtual address: <address>
type: stack contents" followed by "bt: read of stack at <address>
failed".
(anderson@redhat.com)
diff --git a/defs.h b/defs.h
index 931be07..6e6f6be 100644
--- a/defs.h
+++ b/defs.h
@@ -3391,6 +3391,9 @@ struct arm64_stackframe {
#define VSYSCALL_START 0xffffffffff600000
#define VSYSCALL_END 0xffffffffff601000
+#define CPU_ENTRY_AREA_START 0xfffffe0000000000
+#define CPU_ENTRY_AREA_END 0xfffffe7fffffffff
+
#define PTOV(X) ((unsigned long)(X)+(machdep->kvbase))
#define VTOP(X) x86_64_VTOP((ulong)(X))
#define IS_VMALLOC_ADDR(X) x86_64_IS_VMALLOC_ADDR((ulong)(X))
@@ -5829,6 +5832,8 @@ struct machine_specific {
ulong kpti_entry_stack;
ulong kpti_entry_stack_size;
ulong ptrs_per_pgd;
+ ulong cpu_entry_area_start;
+ ulong cpu_entry_area_end;
};
#define KSYMS_START (0x1)
diff --git a/x86_64.c b/x86_64.c
index 1d5e155..54b6539 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -407,6 +407,11 @@ x86_64_init(int when)
machdep->machspec->modules_end = MODULES_END_2_6_31;
}
}
+ if (STRUCT_EXISTS("cpu_entry_area")) {
+ machdep->machspec->cpu_entry_area_start = CPU_ENTRY_AREA_START;
+ machdep->machspec->cpu_entry_area_end = CPU_ENTRY_AREA_END;
+ }
+
STRUCT_SIZE_INIT(cpuinfo_x86, "cpuinfo_x86");
/*
* Before 2.6.25 the structure was called gate_struct
@@ -879,20 +884,21 @@ x86_64_dump_machdep_table(ulong arg)
/* pml4 and upml is legacy for extension modules */
if (ms->pml4) {
- fprintf(fp, " pml4: %lx\n", (ulong)ms->pml4);
- fprintf(fp, " last_pml4_read: %lx\n", (ulong)ms->last_pml4_read);
+ fprintf(fp, " pml4: %lx\n", (ulong)ms->pml4);
+ fprintf(fp, " last_pml4_read: %lx\n", (ulong)ms->last_pml4_read);
} else {
- fprintf(fp, " pml4: (unused)\n");
- fprintf(fp, " last_pml4_read: (unused)\n");
+ fprintf(fp, " pml4: (unused)\n");
+ fprintf(fp, " last_pml4_read: (unused)\n");
}
if (ms->upml) {
- fprintf(fp, " upml: %lx\n", (ulong)ms->upml);
- fprintf(fp, " last_upml_read: %lx\n", (ulong)ms->last_upml_read);
+ fprintf(fp, " upml: %lx\n", (ulong)ms->upml);
+ fprintf(fp, " last_upml_read: %lx\n", (ulong)ms->last_upml_read);
} else {
- fprintf(fp, " upml: (unused)\n");
- fprintf(fp, " last_upml_read: (unused)\n");
+ fprintf(fp, " GART_end: %lx\n", ms->GART_end);
+ fprintf(fp, " upml: (unused)\n");
+ fprintf(fp, " last_upml_read: (unused)\n");
}
if (ms->p4d) {
@@ -1016,10 +1022,14 @@ x86_64_dump_machdep_table(ulong arg)
fprintf(fp, "\n ");
fprintf(fp, "%016lx ", ms->stkinfo.ibase[c]);
}
- fprintf(fp, "\n kpti_entry_stack_size: %ld", ms->kpti_entry_stack_size);
- fprintf(fp, "\n kpti_entry_stack: ");
+ fprintf(fp, "\n kpti_entry_stack_size: ");
+ if (ms->kpti_entry_stack_size)
+ fprintf(fp, "%ld", ms->kpti_entry_stack_size);
+ else
+ fprintf(fp, "(unused)");
+ fprintf(fp, "\n kpti_entry_stack: ");
if (machdep->flags & KPTI) {
- fprintf(fp, "%lx\n ", ms->kpti_entry_stack);
+ fprintf(fp, "(percpu: %lx):\n ", ms->kpti_entry_stack);
for (c = 0; c < cpus; c++) {
if (c && !(c%4))
fprintf(fp, "\n ");
@@ -1028,6 +1038,16 @@ x86_64_dump_machdep_table(ulong arg)
fprintf(fp, "\n");
} else
fprintf(fp, "(unused)\n");
+ fprintf(fp, " cpu_entry_area_start: ");
+ if (ms->cpu_entry_area_start)
+ fprintf(fp, "%016lx\n", (ulong)ms->cpu_entry_area_start);
+ else
+ fprintf(fp, "(unused)\n");
+ fprintf(fp, " cpu_entry_area_end: ");
+ if (ms->cpu_entry_area_end)
+ fprintf(fp, "%016lx\n", (ulong)ms->cpu_entry_area_end);
+ else
+ fprintf(fp, "(unused)\n");
}
/*
@@ -1586,7 +1606,10 @@ x86_64_IS_VMALLOC_ADDR(ulong vaddr)
((machdep->flags & VMEMMAP) &&
(vaddr >= VMEMMAP_VADDR && vaddr <= VMEMMAP_END)) ||
(vaddr >= MODULES_VADDR && vaddr <= MODULES_END) ||
- (vaddr >= VSYSCALL_START && vaddr < VSYSCALL_END));
+ (vaddr >= VSYSCALL_START && vaddr < VSYSCALL_END) ||
+ (machdep->machspec->cpu_entry_area_start &&
+ vaddr >= machdep->machspec->cpu_entry_area_start &&
+ vaddr <= machdep->machspec->cpu_entry_area_end));
}
static int
commit 9446958fe211825ed5524317b05d5ea020bb00d6
Author: Dave Anderson <anderson@redhat.com>
Date: Fri Jun 1 14:01:01 2018 -0400
Fix to address a "__builtin___snprintf_chk" compiler warning if bpf.c
is compiled with -D_FORTIFY_SOURCE=2.
(anderson@redhat.com)
diff --git a/bpf.c b/bpf.c
index 305d49f..ee1986f 100644
--- a/bpf.c
+++ b/bpf.c
@@ -362,7 +362,7 @@ do_bpf(ulong flags, ulong prog_id, ulong map_id, int radix)
fprintf(fp, " LOAD_TIME: ");
if (VALID_MEMBER(bpf_prog_aux_load_time)) {
load_time = ULONGLONG(bpf->bpf_prog_aux_buf + OFFSET(bpf_prog_aux_load_time));
- print_boot_time(load_time, buf5, BUFSIZE);
+ print_boot_time(load_time, buf5, BUFSIZE/2);
fprintf(fp, "%s\n", buf5);
} else
fprintf(fp, "(unknown)\n");

View File

@ -1,34 +0,0 @@
commit 64dad6d0d60514498252e6071738fa1b4c12db8c
Author: Dave Anderson <anderson@redhat.com>
Date: Thu Nov 29 14:21:19 2018 -0500
Fix for the "ps -s" option on ARM64 if the number of tasks exceeds
2000. Without the patch, the command ultimately fails with a
dump of the internal buffer allocation stats, followed by the
message "ps: cannot allocate any more memory!".
(anderson@redhat.com)
diff -up crash-7.2.3/task.c.orig crash-7.2.3/task.c
--- crash-7.2.3/task.c.orig 2018-11-29 13:54:39.108320730 -0500
+++ crash-7.2.3/task.c 2018-11-29 13:54:48.598279086 -0500
@@ -4133,6 +4133,10 @@ task_pointer_string(struct task_context
readmem(tc->task + OFFSET(task_struct_thread_ksp),
KVADDR, &bt->stkptr, sizeof(void *),
"thread_struct ksp", FAULT_ON_ERROR);
+ } else if (VALID_MEMBER(task_struct_thread_context_sp)) {
+ readmem(tc->task + OFFSET(task_struct_thread_context_sp),
+ KVADDR, &bt->stkptr, sizeof(void *),
+ "cpu_context sp", FAULT_ON_ERROR);
} else {
if ((bt->stackbase = GET_STACKBASE(tc->task))) {
bt->stacktop = GET_STACKTOP(tc->task);
@@ -4140,6 +4144,8 @@ task_pointer_string(struct task_context
bt->tc = tc;
bt->flags |= BT_KSTACKP;
back_trace(bt);
+ if (bt->stackbuf)
+ FREEBUF(bt->stackbuf);
} else
bt->stkptr = 0;
}

View File

@ -1,39 +0,0 @@
commit 6b93714b83d59ae4147b8ec3887261aca7fd6f65
Author: Dave Anderson <anderson@redhat.com>
Date: Mon Jan 7 10:44:29 2019 -0500
Prevent a SIGSEGV if a user attempts to input a command line that
exceeds the maximum length of 1500 bytes. The patch displays an
error message and ignores the command line.
(anderson@redhat.com)
diff --git a/cmdline.c b/cmdline.c
index 665f48c..796f7c5 100644
--- a/cmdline.c
+++ b/cmdline.c
@@ -1,8 +1,8 @@
/* cmdline.c - core analysis suite
*
* Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc.
- * Copyright (C) 2002-2015,2018 David Anderson
- * Copyright (C) 2002-2015,2018 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2002-2015,2019 David Anderson
+ * Copyright (C) 2002-2015,2019 Red Hat, Inc. All rights reserved.
*
* 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
@@ -121,9 +121,11 @@ process_command_line(void)
args[0] = NULL;
fprintf(fp, "\n");
return;
- }
-
- strcpy(pc->command_line, pc->readline);
+ }
+ if (strlen(pc->readline) >= BUFSIZE)
+ error(FATAL, "input line exceeds maximum of 1500 bytes\n");
+ else
+ strcpy(pc->command_line, pc->readline);
free(pc->readline);
clean_line(pc->command_line);

View File

@ -1,212 +0,0 @@
commit 8618ddd817621c40c1f44f0ab6df7c7805234416
Author: Dave Anderson <anderson@redhat.com>
Date: Fri Feb 1 15:01:29 2019 -0500
First phase of support for ARM64 kernels that are configured with
CONFIG_ARM64_USER_VA_BITS_52, which causes the PTRS_PER_PGD count
to increase from 64 to 1024. Without the patch, "WARNING: cannot
access vmalloc'd module memory" will be displayed during session
initialization, and the translation of any mapped kernel virtual
address that requires a page table walk will fail, leading to a
myriad of other errors.
(anderson@redhat.com)
diff --git a/arm64.c b/arm64.c
index 45c7313..2308612 100644
--- a/arm64.c
+++ b/arm64.c
@@ -1,8 +1,8 @@
/*
* arm64.c - core analysis suite
*
- * Copyright (C) 2012-2018 David Anderson
- * Copyright (C) 2012-2018 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2012-2019 David Anderson
+ * Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
*
* 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
@@ -209,6 +209,8 @@ arm64_init(int when)
ms->page_offset = ARM64_PAGE_OFFSET;
machdep->identity_map_base = ARM64_PAGE_OFFSET;
machdep->kvbase = ARM64_VA_START;
+ machdep->is_kvaddr = generic_is_kvaddr;
+ machdep->kvtop = arm64_kvtop;
ms->userspace_top = ARM64_USERSPACE_TOP;
if (machdep->flags & NEW_VMEMMAP) {
struct syment *sp;
@@ -262,11 +264,17 @@ arm64_init(int when)
break;
case 65536:
+ if (kernel_symbol_exists("idmap_ptrs_per_pgd") &&
+ readmem(symbol_value("idmap_ptrs_per_pgd"), KVADDR,
+ &value, sizeof(ulong), "idmap_ptrs_per_pgd", RETURN_ON_ERROR))
+ machdep->ptrs_per_pgd = value;
+
if (machdep->machspec->VA_BITS > PGDIR_SHIFT_L3_64K) {
machdep->flags |= VM_L3_64K;
- machdep->ptrs_per_pgd = PTRS_PER_PGD_L3_64K;
+ if (!machdep->ptrs_per_pgd)
+ machdep->ptrs_per_pgd = PTRS_PER_PGD_L3_64K;
if ((machdep->pgd =
- (char *)malloc(PTRS_PER_PGD_L3_64K * 8)) == NULL)
+ (char *)malloc(machdep->ptrs_per_pgd * 8)) == NULL)
error(FATAL, "cannot malloc pgd space.");
if ((machdep->pmd =
(char *)malloc(PTRS_PER_PMD_L3_64K * 8)) == NULL)
@@ -276,9 +284,10 @@ arm64_init(int when)
error(FATAL, "cannot malloc ptbl space.");
} else {
machdep->flags |= VM_L2_64K;
- machdep->ptrs_per_pgd = PTRS_PER_PGD_L2_64K;
+ if (!machdep->ptrs_per_pgd)
+ machdep->ptrs_per_pgd = PTRS_PER_PGD_L2_64K;
if ((machdep->pgd =
- (char *)malloc(PTRS_PER_PGD_L2_64K * 8)) == NULL)
+ (char *)malloc(machdep->ptrs_per_pgd * 8)) == NULL)
error(FATAL, "cannot malloc pgd space.");
if ((machdep->ptbl =
(char *)malloc(PTRS_PER_PTE_L2_64K * 8)) == NULL)
@@ -306,9 +315,11 @@ arm64_init(int when)
machdep->flags |= VMEMMAP;
machdep->uvtop = arm64_uvtop;
- machdep->kvtop = arm64_kvtop;
- machdep->is_kvaddr = generic_is_kvaddr;
machdep->is_uvaddr = arm64_is_uvaddr;
+ if (kernel_symbol_exists("vabits_user") &&
+ readmem(symbol_value("vabits_user"), KVADDR,
+ &value, sizeof(ulong), "vabits_user", RETURN_ON_ERROR))
+ machdep->machspec->vabits_user = value;
machdep->eframe_search = arm64_eframe_search;
machdep->back_trace = arm64_back_trace_cmd;
machdep->in_alternate_stack = arm64_in_alternate_stack;
@@ -350,10 +361,14 @@ arm64_init(int when)
case POST_GDB:
arm64_calc_virtual_memory_ranges();
machdep->section_size_bits = _SECTION_SIZE_BITS;
- if (THIS_KERNEL_VERSION >= LINUX(3,17,0))
- machdep->max_physmem_bits = _MAX_PHYSMEM_BITS_3_17;
- else
- machdep->max_physmem_bits = _MAX_PHYSMEM_BITS;
+ if (!machdep->max_physmem_bits) {
+ if (machdep->machspec->VA_BITS == 52) /* guess */
+ machdep->max_physmem_bits = _MAX_PHYSMEM_BITS_52;
+ else if (THIS_KERNEL_VERSION >= LINUX(3,17,0))
+ machdep->max_physmem_bits = _MAX_PHYSMEM_BITS_3_17;
+ else
+ machdep->max_physmem_bits = _MAX_PHYSMEM_BITS;
+ }
ms = machdep->machspec;
if (THIS_KERNEL_VERSION >= LINUX(4,0,0)) {
@@ -601,6 +616,11 @@ arm64_dump_machdep_table(ulong arg)
fprintf(fp, " machspec: %lx\n", (ulong)ms);
fprintf(fp, " VA_BITS: %ld\n", ms->VA_BITS);
+ fprintf(fp, " vabits_user: ");
+ if (ms->vabits_user)
+ fprintf(fp, "%ld\n", ms->vabits_user);
+ else
+ fprintf(fp, "(unused)\n");
fprintf(fp, " userspace_top: %016lx\n", ms->userspace_top);
fprintf(fp, " page_offset: %016lx\n", ms->page_offset);
fprintf(fp, " vmalloc_start_addr: %016lx\n", ms->vmalloc_start_addr);
@@ -691,6 +711,8 @@ arm64_parse_machdep_arg_l(char *argstring, char *param, ulong *value)
*value = dtol(p, flags, &err);
if (!err)
*value = MEGABYTES(*value);
+ } else if (STRNEQ(argstring, "max_physmem_bits")) {
+ *value = dtol(p, flags, &err);
} else {
*value = htol(p, flags, &err);
}
@@ -750,6 +772,12 @@ arm64_parse_cmdline_args(void)
"setting kimage_voffset to: 0x%lx\n\n",
machdep->machspec->kimage_voffset);
continue;
+ } else if (arm64_parse_machdep_arg_l(arglist[i], "max_physmem_bits",
+ &machdep->max_physmem_bits)) {
+ error(NOTE,
+ "setting max_physmem_bits to: %ld\n\n",
+ machdep->max_physmem_bits);
+ continue;
}
error(WARNING, "ignoring --machdep option: %s\n",
@@ -1065,8 +1093,8 @@ arm64_vtop_2level_64k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
fprintf(fp, "PAGE DIRECTORY: %lx\n", pgd);
pgd_base = (ulong *)pgd;
- FILL_PGD(pgd_base, KVADDR, PTRS_PER_PGD_L2_64K * sizeof(ulong));
- pgd_ptr = pgd_base + (((vaddr) >> PGDIR_SHIFT_L2_64K) & (PTRS_PER_PGD_L2_64K - 1));
+ FILL_PGD(pgd_base, KVADDR, machdep->ptrs_per_pgd * sizeof(ulong));
+ pgd_ptr = pgd_base + (((vaddr) >> PGDIR_SHIFT_L2_64K) & (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);
@@ -1129,8 +1157,8 @@ arm64_vtop_3level_64k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
fprintf(fp, "PAGE DIRECTORY: %lx\n", pgd);
pgd_base = (ulong *)pgd;
- FILL_PGD(pgd_base, KVADDR, PTRS_PER_PGD_L3_64K * sizeof(ulong));
- pgd_ptr = pgd_base + (((vaddr) >> PGDIR_SHIFT_L3_64K) & (PTRS_PER_PGD_L3_64K - 1));
+ FILL_PGD(pgd_base, KVADDR, machdep->ptrs_per_pgd * sizeof(ulong));
+ pgd_ptr = pgd_base + (((vaddr) >> PGDIR_SHIFT_L3_64K) & (machdep->ptrs_per_pgd - 1));
pgd_val = ULONG(machdep->pgd + PGDIR_OFFSET_L3_64K(pgd_ptr));
if (verbose)
fprintf(fp, " PGD: %lx => %lx\n", (ulong)pgd_ptr, pgd_val);
diff --git a/crash.8 b/crash.8
index 8c11615..f9de36d 100644
--- a/crash.8
+++ b/crash.8
@@ -278,6 +278,7 @@ ARM:
ARM64:
phys_offset=<physical-address>
kimage_voffset=<kimage_voffset-value>
+ max_physmem_bits=<value>
X86:
page_offset=<CONFIG_PAGE_OFFSET-value>
.fi
diff --git a/defs.h b/defs.h
index b473972..05f2d17 100644
--- a/defs.h
+++ b/defs.h
@@ -3049,7 +3049,7 @@ typedef signed int s32;
#define PMD_SHIFT_L3_64K (29)
#define PMD_SIZE_L3_64K (1UL << PMD_SHIFT_L3_64K)
#define PMD_MASK_L3_64K (~(PMD_SIZE_L3_64K-1))
-#define PGDIR_OFFSET_L3_64K(X) (((ulong)(X)) & ((PTRS_PER_PGD_L3_64K * 8) - 1))
+#define PGDIR_OFFSET_L3_64K(X) (((ulong)(X)) & ((machdep->ptrs_per_pgd * 8) - 1))
/*
* 2-levels / 64K pages
@@ -3136,6 +3136,7 @@ typedef signed int s32;
#define _SECTION_SIZE_BITS 30
#define _MAX_PHYSMEM_BITS 40
#define _MAX_PHYSMEM_BITS_3_17 48
+#define _MAX_PHYSMEM_BITS_52 52
typedef unsigned long long __u64;
typedef unsigned long long u64;
@@ -3215,6 +3216,7 @@ struct machine_specific {
ulong kern_eframe_offset;
ulong machine_kexec_start;
ulong machine_kexec_end;
+ ulong vabits_user;
};
struct arm64_stackframe {
diff --git a/help.c b/help.c
index ff0c80b..ba15dec 100644
--- a/help.c
+++ b/help.c
@@ -179,6 +179,7 @@ char *program_usage_info[] = {
" ARM64:",
" phys_offset=<physical-address>",
" kimage_voffset=<kimage_voffset-value>",
+ " max_physmem_bits=<value>",
" X86:",
" page_offset=<CONFIG_PAGE_OFFSET-value>",
"",

View File

@ -1,23 +0,0 @@
commit 95daa11b82dfa6aa3e68ffc92e1282abc1b2b62a
Author: Dave Anderson <anderson@redhat.com>
Date: Fri Jun 1 15:28:55 2018 -0400
Fix for the "bpf -t" option. Although highly unlikely, without the
patch, the target function name of a BPF bytecode call instruction
may fail to be resolved correctly.
(anderson@redhat.com)
diff --git a/bpf.c b/bpf.c
index ee1986f..427263d 100644
--- a/bpf.c
+++ b/bpf.c
@@ -1060,8 +1060,7 @@ static char *__func_get_name(const struct bpf_insn *insn,
return buff;
if (insn->src_reg != BPF_PSEUDO_CALL &&
- insn->imm >= 0 && insn->imm < __BPF_FUNC_MAX_ID &&
- func_id_str[insn->imm]) {
+ insn->imm >= 0 && insn->imm < __BPF_FUNC_MAX_ID) {
// return func_id_str[insn->imm];
if (!readmem(symbol_value("func_id_str") + (insn->imm * sizeof(void *)),
KVADDR, &func_id_ptr, sizeof(void *), "func_id_str pointer",

File diff suppressed because it is too large Load Diff

View File

@ -1,894 +0,0 @@
commit a10917ba3203aa8b20e2aa1b84dc12c1e17445e1
Author: Dave Anderson <anderson@redhat.com>
Date: Thu Jul 19 13:43:07 2018 -0400
Update for "ps" and "foreach" commands to display and recognize two
new process states, "ID" for the TASK_IDLE macro introduced in
Linux 4.2, and "NE" for the TASK_NEW bit introduced in Linux 4.8.
(k-hagio@ab.jp.nec.com)
diff --git a/help.c b/help.c
index 54bf9b4..83cda7c 100644
--- a/help.c
+++ b/help.c
@@ -837,7 +837,7 @@ char *help_foreach[] = {
" kernel perform the command(s) on all kernel threads.",
" active perform the command(s) on the active thread on each CPU.",
" state perform the command(s) on all tasks in the specified state, which",
-" may be one of: RU, IN, UN, ST, ZO, TR, SW, DE, WA or PA.\n",
+" may be one of: RU, IN, UN, ST, ZO, TR, SW, DE, WA, PA, ID or NE.\n",
" If none of the task-identifying arguments above are entered, the command",
" will be performed on all tasks.\n",
" command select one or more of the following commands to be run on the tasks",
@@ -1292,7 +1292,7 @@ char *help_ps[] = {
" 3. the CPU number that the task ran on last.",
" 4. the task_struct address or the kernel stack pointer of the process.",
" (see -s option below)",
-" 5. the task state (RU, IN, UN, ZO, ST, TR, DE, SW, WA, PA).",
+" 5. the task state (RU, IN, UN, ZO, ST, TR, DE, SW, WA, PA, ID, NE).",
" 6. the percentage of physical memory being used by this task.",
" 7. the virtual address size of this task in kilobytes.",
" 8. the resident set size of this task in kilobytes.",
diff --git a/task.c b/task.c
index 1b32629..39fb0de 100644
--- a/task.c
+++ b/task.c
@@ -5172,6 +5172,7 @@ static long _WAKING_ = TASK_STATE_UNINITIALIZED;
static long _NONINTERACTIVE_ = TASK_STATE_UNINITIALIZED;
static long _PARKED_ = TASK_STATE_UNINITIALIZED;
static long _NOLOAD_ = TASK_STATE_UNINITIALIZED;
+static long _NEW_ = TASK_STATE_UNINITIALIZED;
#define valid_task_state(X) ((X) != TASK_STATE_UNINITIALIZED)
@@ -5249,6 +5250,10 @@ dump_task_states(void)
if (valid_task_state(_NOLOAD_))
fprintf(fp, " NOLOAD: %3ld (0x%lx)\n",
_NOLOAD_, _NOLOAD_);
+
+ if (valid_task_state(_NEW_))
+ fprintf(fp, " NEW: %3ld (0x%lx)\n",
+ _NEW_, _NEW_);
}
@@ -5282,6 +5287,7 @@ old_defaults:
/*
* If the later version of stat_nam[] array exists that contains
* WAKING, WAKEKILL and PARKED, use it instead of task_state_array[].
+ * Available since kernel version 2.6.33 to 4.13.
*/
if (((len = get_array_length("stat_nam", NULL, 0)) > 0) &&
read_string(symbol_value("stat_nam"), buf, BUFSIZE-1) &&
@@ -5331,6 +5337,9 @@ old_defaults:
case 'N':
_NOLOAD_ = (1 << (i-1));
break;
+ case 'n':
+ _NEW_ = (1 << (i-1));
+ break;
}
}
@@ -5393,7 +5402,16 @@ old_defaults:
_NONINTERACTIVE_ = 64;
}
- if (THIS_KERNEL_VERSION >= LINUX(2,6,32)) {
+ if (THIS_KERNEL_VERSION >= LINUX(4,14,0)) {
+ if (valid_task_state(_PARKED_)) {
+ bitpos = _PARKED_;
+ _DEAD_ |= (bitpos << 1); /* TASK_DEAD */
+ _WAKEKILL_ = (bitpos << 2); /* TASK_WAKEKILL */
+ _WAKING_ = (bitpos << 3); /* TASK_WAKING */
+ _NOLOAD_ = (bitpos << 4); /* TASK_NOLOAD */
+ _NEW_ = (bitpos << 5); /* TASK_NEW */
+ }
+ } else if (THIS_KERNEL_VERSION >= LINUX(2,6,32)) {
/*
* Account for states not listed in task_state_array[]
*/
@@ -5481,6 +5499,10 @@ task_state_string_verbose(ulong task, char *buf)
sprintf(&buf[strlen(buf)], "%sTASK_NOLOAD",
count++ ? "|" : "");
+ if (valid_task_state(_NEW_) && (state & _NEW_))
+ sprintf(&buf[strlen(buf)], "%sTASK_NEW",
+ count++ ? "|" : "");
+
if (valid_task_state(_NONINTERACTIVE_) &&
(state & _NONINTERACTIVE_))
sprintf(&buf[strlen(buf)], "%sTASK_NONINTERACTIVE",
@@ -5530,7 +5552,11 @@ task_state_string(ulong task, char *buf, int verbose)
}
if (state & _UNINTERRUPTIBLE_) {
- sprintf(buf, "UN");
+ if (valid_task_state(_NOLOAD_) &&
+ (state & _NOLOAD_))
+ sprintf(buf, "ID");
+ else
+ sprintf(buf, "UN");
valid++;
set++;
}
@@ -5576,6 +5602,11 @@ task_state_string(ulong task, char *buf, int verbose)
valid++;
}
+ if (state == _NEW_) {
+ sprintf(buf, "NE");
+ valid++;
+ }
+
if (valid && exclusive)
strcat(buf, "EX");
@@ -6273,6 +6304,8 @@ cmd_foreach(void)
STREQ(args[optind], "DE") ||
STREQ(args[optind], "PA") ||
STREQ(args[optind], "WA") ||
+ STREQ(args[optind], "ID") ||
+ STREQ(args[optind], "NE") ||
STREQ(args[optind], "SW")) {
if (fd->flags & FOREACH_STATE)
@@ -6298,6 +6331,10 @@ cmd_foreach(void)
fd->state = _PARKED_;
else if (STREQ(args[optind], "WA"))
fd->state = _WAKING_;
+ else if (STREQ(args[optind], "ID"))
+ fd->state = _UNINTERRUPTIBLE_|_NOLOAD_;
+ else if (STREQ(args[optind], "NE"))
+ fd->state = _NEW_;
if (fd->state == TASK_STATE_UNINITIALIZED)
error(FATAL,
@@ -6678,6 +6715,19 @@ foreach(struct foreach_data *fd)
if (fd->state == _RUNNING_) {
if (task_state(tc->task) != _RUNNING_)
continue;
+ } else if (fd->state & _UNINTERRUPTIBLE_) {
+ if (!(task_state(tc->task) & _UNINTERRUPTIBLE_))
+ continue;
+
+ if (valid_task_state(_NOLOAD_)) {
+ if (fd->state & _NOLOAD_) {
+ if (!(task_state(tc->task) & _NOLOAD_))
+ continue;
+ } else {
+ if ((task_state(tc->task) & _NOLOAD_))
+ continue;
+ }
+ }
} else if (!(task_state(tc->task) & fd->state))
continue;
}
commit 6c39a3d39b799e1f3f26e8017bcfa458d38d3820
Author: Dave Anderson <anderson@redhat.com>
Date: Wed Aug 8 11:31:17 2018 -0400
Fix for running live on ARM64 kernels against /proc/kcore on kernels
configured with CONFIG_RANDOMIZE_BASE. Without the patch, depending
upon the hardware platform, the session may fail with the error message
"crash: vmlinux and /proc/kcore do not match!".
(anderson@redhat.com)
diff --git a/arm64.c b/arm64.c
index 150e7d7..4ee53ce 100644
--- a/arm64.c
+++ b/arm64.c
@@ -125,7 +125,8 @@ arm64_init(int when)
free(string);
}
- if (ms->kimage_voffset) {
+ if (ms->kimage_voffset ||
+ (ACTIVE() && (symbol_value_from_proc_kallsyms("kimage_voffset") != BADVAL))) {
machdep->flags |= NEW_VMEMMAP;
/*
@@ -771,6 +772,17 @@ arm64_calc_kimage_voffset(void)
char *p1;
int errflag;
FILE *iomem;
+ ulong kimage_voffset, vaddr;
+
+ if (pc->flags & PROC_KCORE) {
+ kimage_voffset = symbol_value_from_proc_kallsyms("kimage_voffset");
+ if ((kimage_voffset != BADVAL) &&
+ (READMEM(pc->mfd, &vaddr, sizeof(ulong),
+ kimage_voffset, KCORE_USE_VADDR) > 0)) {
+ ms->kimage_voffset = vaddr;
+ return;
+ }
+ }
if ((iomem = fopen("/proc/iomem", "r")) == NULL)
return;
@@ -838,16 +850,22 @@ arm64_calc_phys_offset(void)
int errflag;
FILE *iomem;
physaddr_t paddr;
+ ulong vaddr;
struct syment *sp;
if ((machdep->flags & NEW_VMEMMAP) &&
ms->kimage_voffset && (sp = kernel_symbol_search("memstart_addr"))) {
- if (pc->flags & PROC_KCORE)
+ if (pc->flags & PROC_KCORE) {
+ vaddr = symbol_value_from_proc_kallsyms("memstart_addr");
+ if (vaddr == BADVAL)
+ vaddr = sp->value;
paddr = KCORE_USE_VADDR;
- else
+ } else {
+ vaddr = sp->value;
paddr = sp->value - machdep->machspec->kimage_voffset;
+ }
if (READMEM(pc->mfd, &phys_offset, sizeof(phys_offset),
- sp->value, paddr) > 0) {
+ vaddr, paddr) > 0) {
ms->phys_offset = phys_offset;
return;
}
diff --git a/defs.h b/defs.h
index 5af82be..da2ae04 100644
--- a/defs.h
+++ b/defs.h
@@ -5067,6 +5067,7 @@ struct syment *per_cpu_symbol_search(char *);
int symbol_exists(char *s);
int kernel_symbol_exists(char *s);
struct syment *kernel_symbol_search(char *);
+ulong symbol_value_from_proc_kallsyms(char *);
int get_syment_array(char *, struct syment **, int);
void set_temporary_radix(unsigned int, unsigned int *);
void restore_current_radix(unsigned int);
diff --git a/symbols.c b/symbols.c
index 8ff1430..df84ee2 100644
--- a/symbols.c
+++ b/symbols.c
@@ -28,7 +28,6 @@ static void store_sysmap_symbols(void);
static ulong relocate(ulong, char *, int);
static int relocate_force(ulong, char *);
static void kaslr_init(void);
-static ulong symbol_value_from_proc_kallsyms(char *);
static void strip_module_symbol_end(char *s);
static int compare_syms(const void *, const void *);
static int compare_mods(const void *, const void *);
@@ -997,7 +996,7 @@ relocate_force(ulong symval, char *symname)
/*
* Get a symbol value from /proc/kallsyms.
*/
-static ulong
+ulong
symbol_value_from_proc_kallsyms(char *symname)
{
FILE *kp;
commit 455da1ae5c7f22ba870aa57e071dad340749bdcd
Author: Dave Anderson <anderson@redhat.com>
Date: Wed Aug 8 14:20:21 2018 -0400
Modify the output of the "kmem -[sS]" header and contents such that
the slab cache name string is moved from the second column to the
the last column. Since the slab cache name strings have become
increasingly longer over time, without the patch, the numerical
column contents may be skewed so far to the right that the output
becomes difficult to read.
(k-hagio@ab.jp.nec.com)
diff --git a/help.c b/help.c
index 83cda7c..a189038 100644
--- a/help.c
+++ b/help.c
@@ -6692,8 +6692,8 @@ char *help_kmem[] = {
" Find all of the combined slab/page structures that are used by",
" the kmalloc-8192 slab cache:\n",
" %s> kmem -s kmalloc-8192",
-" CACHE NAME OBJSIZE ALLOCATED TOTAL SLABS SSIZE",
-" ffff880215802e00 kmalloc-8192 8192 65 80 20 32k",
+" CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME",
+" ffff880215802e00 8192 65 80 20 32k kmalloc-8192",
" %s> kmem -m slab_cache | grep ffff880215802e00",
" ffffea0004117800 ffff880215802e00 ",
" ffffea00041ca600 ffff880215802e00 ",
@@ -6889,72 +6889,72 @@ char *help_kmem[] = {
" ",
" Display kmalloc() slab data:\n",
" %s> kmem -s",
-" CACHE NAME OBJSIZE ALLOCATED TOTAL SLABS SSIZE",
-" c02eadc0 kmem_cache 232 58 68 4 4k",
-" f79c2888 ip_vs_conn 128 0 0 0 4k",
-" f79c2970 tcp_tw_bucket 96 0 0 0 4k",
-" f79c2a58 tcp_bind_bucket 32 12 565 5 4k",
-" f79c2b40 tcp_open_request 64 0 59 1 4k",
-" f79c2c28 inet_peer_cache 64 1 59 1 4k",
-" f79c2d10 ip_fib_hash 32 11 339 3 4k",
-" f79c2df8 ip_dst_cache 160 8 120 5 4k",
-" f79c2ee0 arp_cache 128 1 30 1 4k",
-" c8402970 blkdev_requests 96 30208 37800 945 4k",
-" c8402a58 nfs_read_data 384 0 0 0 4k",
-" c8402b40 nfs_write_data 384 0 0 0 4k",
-" c8402c28 nfs_page 96 0 0 0 4k",
-" c8402d10 dnotify cache 20 0 0 0 4k",
-" c8402df8 file lock cache 92 3 336 8 4k",
-" c8402ee0 fasync cache 16 0 0 0 4k",
-" c84027a0 uid_cache 32 3 339 3 4k",
-" c84026b8 skbuff_head_cache 160 320 624 26 4k",
-" c84025d0 sock 832 32 180 20 8k",
-" c84024e8 sigqueue 132 0 203 7 4k",
-" c8402400 cdev_cache 64 19 472 8 4k",
-" c8402318 bdev_cache 64 8 236 4 4k",
-" c8402230 mnt_cache 96 11 120 3 4k",
-" c8402148 inode_cache 480 817 848 106 4k",
-" c8402060 dentry_cache 128 1352 1470 49 4k",
-" c8403ee0 filp 96 244 440 11 4k",
-" c8403df8 names_cache 4096 0 12 12 4k",
-" c8403d10 buffer_head 96 14936 16000 400 4k",
-" c8403c28 mm_struct 128 25 240 8 4k",
-" c8403b40 vm_area_struct 64 393 1298 22 4k",
-" c8403a58 fs_cache 64 30 472 8 4k",
-" c8403970 files_cache 416 30 135 15 4k",
-" c8403888 signal_act 1312 32 99 33 4k",
-" c84037a0 size-131072(DMA) 131072 0 0 0 128k",
-" c84036b8 size-131072 131072 1 1 1 128k",
-" c84035d0 size-65536(DMA) 65536 0 0 0 64k",
-" c84034e8 size-65536 65536 0 0 0 64k",
-" c8403400 size-32768(DMA) 32768 0 0 0 32k",
-" c8403318 size-32768 32768 0 1 1 32k",
-" c8403230 size-16384(DMA) 16384 0 0 0 16k",
-" c8403148 size-16384 16384 0 0 0 16k",
-" c8403060 size-8192(DMA) 8192 0 0 0 8k",
-" c8401ee0 size-8192 8192 1 2 2 8k",
-" c8401df8 size-4096(DMA) 4096 0 0 0 4k",
-" c8401d10 size-4096 4096 30 30 30 4k",
-" c8401c28 size-2048(DMA) 2048 0 0 0 4k",
-" c8401b40 size-2048 2048 37 132 66 4k",
-" c8401a58 size-1024(DMA) 1024 0 0 0 4k",
-" c8401970 size-1024 1024 301 328 82 4k",
-" c8401888 size-512(DMA) 512 0 0 0 4k",
-" c84017a0 size-512 512 141 168 21 4k",
-" c84016b8 size-256(DMA) 256 0 0 0 4k",
-" c84015d0 size-256 256 80 435 29 4k",
-" c84014e8 size-128(DMA) 128 0 0 0 4k",
-" c8401400 size-128 128 508 840 28 4k",
-" c8401318 size-64(DMA) 64 0 0 0 4k",
-" c8401230 size-64 64 978 1357 23 4k",
-" c8401148 size-32(DMA) 32 0 0 0 4k",
-" c8401060 size-32 32 1244 1808 16 4k",
+" CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME",
+" c02eadc0 232 58 68 4 4k kmem_cache",
+" f79c2888 128 0 0 0 4k ip_vs_conn",
+" f79c2970 96 0 0 0 4k tcp_tw_bucket",
+" f79c2a58 32 12 565 5 4k tcp_bind_bucket",
+" f79c2b40 64 0 59 1 4k tcp_open_request",
+" f79c2c28 64 1 59 1 4k inet_peer_cache",
+" f79c2d10 32 11 339 3 4k ip_fib_hash",
+" f79c2df8 160 8 120 5 4k ip_dst_cache",
+" f79c2ee0 128 1 30 1 4k arp_cache",
+" c8402970 96 30208 37800 945 4k blkdev_requests",
+" c8402a58 384 0 0 0 4k nfs_read_data",
+" c8402b40 384 0 0 0 4k nfs_write_data",
+" c8402c28 96 0 0 0 4k nfs_page",
+" c8402d10 20 0 0 0 4k dnotify cache",
+" c8402df8 92 3 336 8 4k file lock cache",
+" c8402ee0 16 0 0 0 4k fasync cache",
+" c84027a0 32 3 339 3 4k uid_cache",
+" c84026b8 160 320 624 26 4k skbuff_head_cache",
+" c84025d0 832 32 180 20 8k sock",
+" c84024e8 132 0 203 7 4k sigqueue",
+" c8402400 64 19 472 8 4k cdev_cache",
+" c8402318 64 8 236 4 4k bdev_cache",
+" c8402230 96 11 120 3 4k mnt_cache",
+" c8402148 480 817 848 106 4k inode_cache",
+" c8402060 128 1352 1470 49 4k dentry_cache",
+" c8403ee0 96 244 440 11 4k filp",
+" c8403df8 4096 0 12 12 4k names_cache",
+" c8403d10 96 14936 16000 400 4k buffer_head",
+" c8403c28 128 25 240 8 4k mm_struct",
+" c8403b40 64 393 1298 22 4k vm_area_struct",
+" c8403a58 64 30 472 8 4k fs_cache",
+" c8403970 416 30 135 15 4k files_cache",
+" c8403888 1312 32 99 33 4k signal_act",
+" c84037a0 131072 0 0 0 128k size-131072(DMA)",
+" c84036b8 131072 1 1 1 128k size-131072",
+" c84035d0 65536 0 0 0 64k size-65536(DMA)",
+" c84034e8 65536 0 0 0 64k size-65536",
+" c8403400 32768 0 0 0 32k size-32768(DMA)",
+" c8403318 32768 0 1 1 32k size-32768",
+" c8403230 16384 0 0 0 16k size-16384(DMA)",
+" c8403148 16384 0 0 0 16k size-16384",
+" c8403060 8192 0 0 0 8k size-8192(DMA)",
+" c8401ee0 8192 1 2 2 8k size-8192",
+" c8401df8 4096 0 0 0 4k size-4096(DMA)",
+" c8401d10 4096 30 30 30 4k size-4096",
+" c8401c28 2048 0 0 0 4k size-2048(DMA)",
+" c8401b40 2048 37 132 66 4k size-2048",
+" c8401a58 1024 0 0 0 4k size-1024(DMA)",
+" c8401970 1024 301 328 82 4k size-1024",
+" c8401888 512 0 0 0 4k size-512(DMA)",
+" c84017a0 512 141 168 21 4k size-512",
+" c84016b8 256 0 0 0 4k size-256(DMA)",
+" c84015d0 256 80 435 29 4k size-256",
+" c84014e8 128 0 0 0 4k size-128(DMA)",
+" c8401400 128 508 840 28 4k size-128",
+" c8401318 64 0 0 0 4k size-64(DMA)",
+" c8401230 64 978 1357 23 4k size-64",
+" c8401148 32 0 0 0 4k size-32(DMA)",
+" c8401060 32 1244 1808 16 4k size-32",
" ",
" Display all slab data in the \"arp_cache\" cache:\n",
" %s> kmem -S arp_cache",
-" CACHE NAME OBJSIZE ALLOCATED TOTAL SLABS SSIZE",
-" f79c2ee0 arp_cache 128 1 30 1 4k",
+" CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME",
+" f79c2ee0 128 1 30 1 4k arp_cache",
" SLAB MEMORY TOTAL ALLOCATED FREE",
" f729d000 f729d0a0 30 1 29",
" FREE / [ALLOCATED]",
@@ -6991,8 +6991,8 @@ char *help_kmem[] = {
" ",
" Search the kmalloc() slab subsystem for address c3fbdb60:\n",
" %s> kmem -s c3fbdb60",
-" CACHE NAME OBJSIZE ALLOCATED TOTAL SLABS SSIZE",
-" c8402970 blkdev_requests 96 30208 37800 945 4k",
+" CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME",
+" c8402970 96 30208 37800 945 4k blkdev_requests",
" SLAB MEMORY TOTAL ALLOCATED FREE",
" c3fbd020 c3fbd0e0 40 40 0",
" FREE / [ALLOCATED]",
@@ -7000,8 +7000,8 @@ char *help_kmem[] = {
" ",
" Make a generic search (no flags) for the same address c3fbdb60:\n",
" %s> kmem c3fbdb60 ",
-" CACHE NAME OBJSIZE ALLOCATED TOTAL SLABS SSIZE",
-" c8402970 blkdev_requests 96 30208 37800 945 4k",
+" CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME",
+" c8402970 96 30208 37800 945 4k blkdev_requests",
" SLAB MEMORY TOTAL ALLOCATED FREE",
" c3fbd020 c3fbd0e0 40 40 0 ",
" FREE / [ALLOCATED]",
diff --git a/memory.c b/memory.c
index 81ed689..5bcf09e 100644
--- a/memory.c
+++ b/memory.c
@@ -172,7 +172,6 @@ static void dump_kmem_cache(struct meminfo *);
static void dump_kmem_cache_percpu_v1(struct meminfo *);
static void dump_kmem_cache_percpu_v2(struct meminfo *);
static void dump_kmem_cache_slub(struct meminfo *);
-static void dump_kmem_cache_info_v2(struct meminfo *);
static void kmem_cache_list_common(void);
static ulong get_cpu_slab_ptr(struct meminfo *, int, ulong *);
static unsigned int oo_order(ulong);
@@ -9379,7 +9378,7 @@ kmem_cache_init(void)
if (!strlen(kmem_cache_hdr))
sprintf(kmem_cache_hdr,
- "CACHE%sNAME OBJSIZE ALLOCATED TOTAL SLABS SSIZE\n",
+ "CACHE%s OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME\n",
space(VADDR_PRLEN > 8 ? 12 : 4));
if (!strlen(free_inuse_hdr))
@@ -9964,55 +9963,36 @@ ignore_cache(struct meminfo *si, char *name)
#define KMEM_SLAB_OVERLOAD_PAGE (8)
#define KMEM_SLAB_FREELIST (9)
-#define DUMP_KMEM_CACHE_INFO_V1() \
- { \
- char b1[BUFSIZE]; \
- fprintf(fp, "%s %-18s %8ld ", \
- mkstring(b1, VADDR_PRLEN, LJUST|LONG_HEX, MKSTR(si->cache)), \
- buf, si->size); \
- fprintf(fp, "%9ld %8ld %5ld %3ldk\n", \
- vt->flags & PERCPU_KMALLOC_V1 ? \
- si->inuse - si->cpucached_cache : \
- si->inuse, si->num_slabs * si->c_num, \
- si->num_slabs, si->slabsize/1024); \
- }
-
-#define DUMP_KMEM_CACHE_INFO_V2() dump_kmem_cache_info_v2(si)
+#define DUMP_KMEM_CACHE_INFO() dump_kmem_cache_info(si)
static void
-dump_kmem_cache_info_v2(struct meminfo *si)
+dump_kmem_cache_info(struct meminfo *si)
{
char b1[BUFSIZE];
- char b2[BUFSIZE];
- int namelen, sizelen, spacelen;
-
- fprintf(fp, "%s ",
- mkstring(b1, VADDR_PRLEN, LJUST|LONG_HEX, MKSTR(si->cache)));
-
- namelen = strlen(si->curname);
- sprintf(b2, "%ld", si->size);
- sizelen = strlen(b2);
- spacelen = 0;
-
- if (namelen++ > 18) {
- spacelen = 29 - namelen - sizelen;
- fprintf(fp, "%s%s%ld ", si->curname,
- space(spacelen <= 0 ? 1 : spacelen), si->size);
- if (spacelen > 0)
- spacelen = 1;
- sprintf(b1, "%c%dld ", '%', 9 + spacelen - 1);
+ ulong objsize, allocated, total;
+
+ if (si->flags & SLAB_GATHER_FAILURE)
+ error(INFO, "%s: cannot gather relevant slab data\n", si->curname);
+
+ objsize = (vt->flags & KMALLOC_SLUB) ? si->objsize : si->size;
+
+ fprintf(fp, "%s %8ld ",
+ mkstring(b1, VADDR_PRLEN, LJUST|LONG_HEX, MKSTR(si->cache)),
+ objsize);
+
+ if (si->flags & SLAB_GATHER_FAILURE) {
+ fprintf(fp, "%9s %8s %5s ", "?", "?", "?");
} else {
- fprintf(fp, "%-18s %8ld ", si->curname, si->size);
- sprintf(b1, "%c%dld ", '%', 9);
- }
+ allocated = (vt->flags & (PERCPU_KMALLOC_V1|PERCPU_KMALLOC_V2)) ?
+ si->inuse - si->cpucached_cache : si->inuse;
+ total = (vt->flags & KMALLOC_SLUB) ?
+ si->inuse + si->free : si->num_slabs * si->c_num;
- fprintf(fp, b1, vt->flags & (PERCPU_KMALLOC_V2) ?
- si->inuse - si->cpucached_cache : si->inuse);
+ fprintf(fp, "%9ld %8ld %5ld ",
+ allocated, total, si->num_slabs);
+ }
- fprintf(fp, "%8ld %s%5ld %s%3ldk\n",
- si->num_slabs * si->c_num,
- si->num_slabs < 100000 ? " " : "", si->num_slabs,
- (si->slabsize/1024) < 1000 ? " " : "", si->slabsize/1024);
+ fprintf(fp, "%4ldk %s\n", si->slabsize/1024, si->curname);
}
#define DUMP_SLAB_INFO() \
@@ -10152,7 +10132,7 @@ dump_kmem_cache(struct meminfo *si)
do_slab_chain(SLAB_GET_COUNTS, si);
if (!(si->flags & (ADDRESS_SPECIFIED|GET_SLAB_PAGES)))
- DUMP_KMEM_CACHE_INFO_V1();
+ DUMP_KMEM_CACHE_INFO();
if (si->flags == GET_SLAB_PAGES)
si->retval += (si->num_slabs *
@@ -10166,7 +10146,7 @@ dump_kmem_cache(struct meminfo *si)
if (si->found) {
fprintf(fp, "%s", kmem_cache_hdr);
- DUMP_KMEM_CACHE_INFO_V1();
+ DUMP_KMEM_CACHE_INFO();
fprintf(fp, "%s", slab_hdr);
DUMP_SLAB_INFO();
@@ -10362,7 +10342,7 @@ dump_kmem_cache_percpu_v1(struct meminfo *si)
do_slab_chain_percpu_v1(SLAB_GET_COUNTS, si);
if (!(si->flags & (ADDRESS_SPECIFIED|GET_SLAB_PAGES))) {
- DUMP_KMEM_CACHE_INFO_V1();
+ DUMP_KMEM_CACHE_INFO();
if (CRASHDEBUG(3))
dump_struct("kmem_cache_s", si->cache, 0);
}
@@ -10382,7 +10362,7 @@ dump_kmem_cache_percpu_v1(struct meminfo *si)
if (si->found) {
fprintf(fp, "%s", kmem_cache_hdr);
- DUMP_KMEM_CACHE_INFO_V1();
+ DUMP_KMEM_CACHE_INFO();
fprintf(fp, "%s", slab_hdr);
gather_slab_cached_count(si);
DUMP_SLAB_INFO();
@@ -10617,7 +10597,7 @@ dump_kmem_cache_percpu_v2(struct meminfo *si)
do_slab_chain_percpu_v2(SLAB_GET_COUNTS, si);
if (!(si->flags & (ADDRESS_SPECIFIED|GET_SLAB_PAGES))) {
- DUMP_KMEM_CACHE_INFO_V2();
+ DUMP_KMEM_CACHE_INFO();
if (CRASHDEBUG(3))
dump_struct("kmem_cache_s", si->cache, 0);
}
@@ -10644,7 +10624,7 @@ dump_kmem_cache_percpu_v2(struct meminfo *si)
if (si->found) {
fprintf(fp, "%s", kmem_cache_hdr);
- DUMP_KMEM_CACHE_INFO_V2();
+ DUMP_KMEM_CACHE_INFO();
fprintf(fp, "%s", slab_hdr);
gather_slab_cached_count(si);
DUMP_SLAB_INFO();
@@ -18064,56 +18044,6 @@ kmem_cache_list_common(void)
FREEBUF(cache_list);
}
-#define DUMP_KMEM_CACHE_INFO_SLUB() dump_kmem_cache_info_slub(si)
-
-static void
-dump_kmem_cache_info_slub(struct meminfo *si)
-{
- char b1[BUFSIZE];
- char b2[BUFSIZE];
- int namelen, sizelen, spacelen;
-
- if (si->flags & SLAB_GATHER_FAILURE)
- error(INFO, "%s: cannot gather relevant slab data\n", si->curname);
-
- fprintf(fp, "%s ",
- mkstring(b1, VADDR_PRLEN, LJUST|LONG_HEX, MKSTR(si->cache)));
-
- namelen = strlen(si->curname);
- sprintf(b2, "%ld", si->objsize);
- sizelen = strlen(b2);
- spacelen = 0;
-
- if (namelen++ > 18) {
- spacelen = 29 - namelen - sizelen;
- fprintf(fp, "%s%s%ld ", si->curname,
- space(spacelen <= 0 ? 1 : spacelen), si->objsize);
- if (spacelen > 0)
- spacelen = 1;
- if (si->flags & SLAB_GATHER_FAILURE)
- sprintf(b1, "%c%ds ", '%', 9 + spacelen - 1);
- else
- sprintf(b1, "%c%dld ", '%', 9 + spacelen - 1);
- } else {
- fprintf(fp, "%-18s %8ld ", si->curname, si->objsize);
- if (si->flags & SLAB_GATHER_FAILURE)
- sprintf(b1, "%c%ds ", '%', 9);
- else
- sprintf(b1, "%c%dld ", '%', 9);
- }
-
- if (si->flags & SLAB_GATHER_FAILURE) {
- fprintf(fp, b1, "?");
- fprintf(fp, "%8s %5s %4ldk\n",
- "?", "?", si->slabsize/1024);
- } else {
- fprintf(fp, b1, si->inuse);
- fprintf(fp, "%8ld %5ld %4ldk\n",
- si->inuse + si->free,
- si->num_slabs, si->slabsize/1024);
- }
-}
-
static void
dump_kmem_cache_slub(struct meminfo *si)
{
@@ -18214,7 +18144,7 @@ dump_kmem_cache_slub(struct meminfo *si)
!get_kmem_cache_slub_data(GET_SLUB_OBJECTS, si))
si->flags |= SLAB_GATHER_FAILURE;
- DUMP_KMEM_CACHE_INFO_SLUB();
+ DUMP_KMEM_CACHE_INFO();
if (si->flags & SLAB_GATHER_FAILURE) {
si->flags &= ~SLAB_GATHER_FAILURE;
commit ba03b66cec24fc0033d4378be08f5f9a96cd4a91
Author: Dave Anderson <anderson@redhat.com>
Date: Thu Aug 9 10:54:46 2018 -0400
Fix for the "files" and "net -s" commands when a task has an open
files count that exceeds 1024 (FD_SETSIZE) file descriptors. Without
the patch, the commands may omit the display of open file descriptors.
(tan.hu@zte.com.cn)
diff --git a/filesys.c b/filesys.c
index 0ace8f4..47f5a24 100644
--- a/filesys.c
+++ b/filesys.c
@@ -2380,7 +2380,8 @@ open_files_dump(ulong task, int flags, struct reference *ref)
int max_fdset = 0;
int max_fds = 0;
ulong open_fds_addr;
- fd_set open_fds;
+ int open_fds_size;
+ ulong *open_fds;
ulong fd;
ulong file;
ulong value;
@@ -2583,16 +2584,25 @@ open_files_dump(ulong task, int flags, struct reference *ref)
open_fds_addr = ULONG(files_struct_buf +
OFFSET(files_struct_open_fds));
+ open_fds_size = MAX(max_fdset, max_fds) / BITS_PER_BYTE;
+ open_fds = (ulong *)GETBUF(open_fds_size);
+ if (!open_fds) {
+ if (fdtable_buf)
+ FREEBUF(fdtable_buf);
+ FREEBUF(files_struct_buf);
+ return;
+ }
+
if (open_fds_addr) {
if (VALID_MEMBER(files_struct_open_fds_init) &&
(open_fds_addr == (files_struct_addr +
OFFSET(files_struct_open_fds_init))))
BCOPY(files_struct_buf +
OFFSET(files_struct_open_fds_init),
- &open_fds, sizeof(fd_set));
+ open_fds, open_fds_size);
else
- readmem(open_fds_addr, KVADDR, &open_fds,
- sizeof(fd_set), "fdtable open_fds",
+ readmem(open_fds_addr, KVADDR, open_fds,
+ open_fds_size, "fdtable open_fds",
FAULT_ON_ERROR);
}
@@ -2607,6 +2617,7 @@ open_files_dump(ulong task, int flags, struct reference *ref)
if (fdtable_buf)
FREEBUF(fdtable_buf);
FREEBUF(files_struct_buf);
+ FREEBUF(open_fds);
return;
}
@@ -2617,11 +2628,11 @@ open_files_dump(ulong task, int flags, struct reference *ref)
j = 0;
for (;;) {
unsigned long set;
- i = j * __NFDBITS;
+ i = j * BITS_PER_LONG;
if (((max_fdset >= 0) && (i >= max_fdset)) ||
(i >= max_fds))
break;
- set = open_fds.__fds_bits[j++];
+ set = open_fds[j++];
while (set) {
if (set & 1) {
readmem(fd + i*sizeof(struct file *), KVADDR,
@@ -2665,6 +2676,7 @@ open_files_dump(ulong task, int flags, struct reference *ref)
if (fdtable_buf)
FREEBUF(fdtable_buf);
FREEBUF(files_struct_buf);
+ FREEBUF(open_fds);
}
/*
diff --git a/net.c b/net.c
index 4199091..f08f22a 100644
--- a/net.c
+++ b/net.c
@@ -1373,7 +1373,8 @@ dump_sockets_workhorse(ulong task, ulong flag, struct reference *ref)
int max_fdset = 0;
int max_fds = 0;
ulong open_fds_addr = 0;
- fd_set open_fds;
+ ulong *open_fds;
+ int open_fds_size;
ulong fd;
ulong file;
int i, j;
@@ -1446,12 +1447,18 @@ dump_sockets_workhorse(ulong task, ulong flag, struct reference *ref)
sizeof(void *), "files_struct fd addr", FAULT_ON_ERROR);
}
+ open_fds_size = MAX(max_fdset, max_fds) / BITS_PER_BYTE;
+ open_fds = (ulong *)GETBUF(open_fds_size);
+ if (!open_fds)
+ return;
+
if (open_fds_addr)
- readmem(open_fds_addr, KVADDR, &open_fds, sizeof(fd_set),
+ readmem(open_fds_addr, KVADDR, open_fds, open_fds_size,
"files_struct open_fds", FAULT_ON_ERROR);
if (!open_fds_addr || !fd) {
if (!NET_REFERENCE_CHECK(ref))
fprintf(fp, "No open sockets.\n");
+ FREEBUF(open_fds);
return;
}
@@ -1479,10 +1486,10 @@ dump_sockets_workhorse(ulong task, ulong flag, struct reference *ref)
j = 0;
for (;;) {
unsigned long set;
- i = j * __NFDBITS;
+ i = j * BITS_PER_LONG;
if (((max_fdset >= 0) && (i >= max_fdset)) || (i >= max_fds))
break;
- set = open_fds.__fds_bits[j++];
+ set = open_fds[j++];
while (set) {
if (set & 1) {
readmem(fd + i*sizeof(struct file *), KVADDR,
@@ -1505,6 +1512,8 @@ dump_sockets_workhorse(ulong task, ulong flag, struct reference *ref)
if (NET_REFERENCE_FOUND(ref))
fprintf(fp, "\n");
+
+ FREEBUF(open_fds);
}
commit e9532aea6818b347bc0740f39efd4ec844cfb9b0
Author: Dave Anderson <anderson@redhat.com>
Date: Thu Aug 9 11:20:26 2018 -0400
As an addendum to the new "kmem -[sS]" output format, align the slab
cache name string so that it is beneath the "NAME" header column when
the "kmem -I &lt;slab-cache>" option is used to ignore a slab cache,
or if the scan of the metadata of a slab cache enounters corruption.
Also remove a superfluous line from the "help kmem" description of
the "kmem -I" option.
(k-hagio@ab.jp.nec.com, anderson@redhat.com)
diff --git a/help.c b/help.c
index a189038..aeeb056 100644
--- a/help.c
+++ b/help.c
@@ -6495,7 +6495,6 @@ char *help_kmem[] = {
" all slab cache names and addresses are listed.",
" -I slab when used with -s or -S, one or more slab cache names in a",
" comma-separated list may be specified as slab caches to ignore.",
-" their hugepage size, total and free counts, and name.",
" -g displays the enumerator value of all bits in the page structure's",
" \"flags\" field.",
" flags when used with -g, translates all bits in this hexadecimal page",
diff --git a/memory.c b/memory.c
index 5bcf09e..4790cf6 100644
--- a/memory.c
+++ b/memory.c
@@ -9963,6 +9963,9 @@ ignore_cache(struct meminfo *si, char *name)
#define KMEM_SLAB_OVERLOAD_PAGE (8)
#define KMEM_SLAB_FREELIST (9)
+#define DUMP_KMEM_CACHE_TAG(addr, name, tag) \
+ fprintf(fp, "%lx %-43s %s\n", addr, tag, name)
+
#define DUMP_KMEM_CACHE_INFO() dump_kmem_cache_info(si)
static void
@@ -10094,7 +10097,7 @@ dump_kmem_cache(struct meminfo *si)
goto next_cache;
if (ignore_cache(si, buf)) {
- fprintf(fp, "%lx %-18s [IGNORED]\n", si->cache, buf);
+ DUMP_KMEM_CACHE_TAG(si->cache, buf, "[IGNORED]");
goto next_cache;
}
@@ -10303,7 +10306,7 @@ dump_kmem_cache_percpu_v1(struct meminfo *si)
goto next_cache;
if (ignore_cache(si, buf)) {
- fprintf(fp, "%lx %-18s [IGNORED]\n", si->cache, buf);
+ DUMP_KMEM_CACHE_TAG(si->cache, buf, "[IGNORED]");
goto next_cache;
}
@@ -10547,12 +10550,12 @@ dump_kmem_cache_percpu_v2(struct meminfo *si)
goto next_cache;
if (ignore_cache(si, buf)) {
- fprintf(fp, "%lx %-18s [IGNORED]\n", si->cache, buf);
+ DUMP_KMEM_CACHE_TAG(si->cache, buf, "[IGNORED]");
goto next_cache;
}
if (bad_slab_cache(si->cache)) {
- fprintf(fp, "%lx %-18s [INVALID/CORRUPTED]\n", si->cache, buf);
+ DUMP_KMEM_CACHE_TAG(si->cache, buf, "[INVALID/CORRUPTED]");
goto next_cache;
}
@@ -18109,8 +18112,7 @@ dump_kmem_cache_slub(struct meminfo *si)
fprintf(fp, "%s", kmem_cache_hdr);
}
if (ignore_cache(si, buf)) {
- fprintf(fp, "%lx %-18s [IGNORED]\n",
- si->cache_list[i], buf);
+ DUMP_KMEM_CACHE_TAG(si->cache_list[i], buf, "[IGNORED]");
goto next_cache;
}

View File

@ -1,193 +0,0 @@
commit a89ec821cb5dbb106cb58e8740f84c7e382c0140
Author: Dave Anderson <anderson@redhat.com>
Date: Fri Feb 8 11:12:23 2019 -0500
For live system analysis where there is no vmcoreinfo ELF note
attached to /proc/kcore, or for dumpfile analysis where there is no
vmcoreinfo ELF note attached to the dumpfile, this patch sets the
internal pc->read_vmcoreinfo() function to a new plugin function
that reads the data directly from the live kernel or dumpfile.
Because the function is set much later during initialization than
if the ELF note is attached to /proc/kcore or the dumpfile, it may
not be available during very early session initialization.
(anderson@redhat.com)
diff --git a/defs.h b/defs.h
index 05f2d17..5841b1f 100644
--- a/defs.h
+++ b/defs.h
@@ -4872,6 +4872,7 @@ int clean_exit(int);
int untrusted_file(FILE *, char *);
char *readmem_function_name(void);
char *writemem_function_name(void);
+char *no_vmcoreinfo(const char *);
/*
* cmdline.c
diff --git a/kernel.c b/kernel.c
index e512da5..9f5ba89 100644
--- a/kernel.c
+++ b/kernel.c
@@ -93,6 +93,8 @@ static void source_tree_init(void);
static ulong dump_audit_skb_queue(ulong);
static ulong __dump_audit(char *);
static void dump_audit(void);
+static char *vmcoreinfo_read_string(const char *);
+static void check_vmcoreinfo(void);
/*
@@ -127,6 +129,8 @@ kernel_init()
kt->end = highest_bss_symbol();
if ((sp1 = kernel_symbol_search("_end")) && (sp1->value > kt->end))
kt->end = sp1->value;
+
+ check_vmcoreinfo();
/*
* For the traditional (non-pv_ops) Xen architecture, default to writable
@@ -11117,3 +11121,84 @@ dump_audit(void)
if (!qlen)
error(INFO, "kernel audit log is empty\n");
}
+
+/*
+ * Reads a string value from the VMCOREINFO data stored in (live) memory.
+ *
+ * Returns a string (that has to be freed by the caller) that contains the
+ * value for key or NULL if the key has not been found.
+ */
+static char *
+vmcoreinfo_read_string(const char *key)
+{
+ char *buf, *value_string, *p1, *p2;
+ size_t value_length;
+ size_t vmcoreinfo_size;
+ ulong vmcoreinfo_data;
+ char keybuf[BUFSIZE];
+
+ buf = value_string = NULL;
+
+ switch (get_symbol_type("vmcoreinfo_data", NULL, NULL))
+ {
+ case TYPE_CODE_PTR:
+ get_symbol_data("vmcoreinfo_data", sizeof(vmcoreinfo_data), &vmcoreinfo_data);
+ break;
+ case TYPE_CODE_ARRAY:
+ vmcoreinfo_data = symbol_value("vmcoreinfo_data");
+ break;
+ default:
+ return NULL;
+ }
+
+ get_symbol_data("vmcoreinfo_size", sizeof(vmcoreinfo_size), &vmcoreinfo_size);
+
+ sprintf(keybuf, "%s=", key);
+
+ if ((buf = malloc(vmcoreinfo_size+1)) == NULL) {
+ error(INFO, "cannot malloc vmcoreinfo buffer\n");
+ goto err;
+ }
+
+ if (!readmem(vmcoreinfo_data, KVADDR, buf, vmcoreinfo_size,
+ "vmcoreinfo_data", RETURN_ON_ERROR|QUIET)) {
+ error(INFO, "cannot read vmcoreinfo_data\n");
+ goto err;
+ }
+
+ buf[vmcoreinfo_size] = '\n';
+
+ if ((p1 = strstr(buf, keybuf))) {
+ p2 = p1 + strlen(keybuf);
+ p1 = strstr(p2, "\n");
+ value_length = p1-p2;
+ value_string = calloc(value_length+1, sizeof(char));
+ strncpy(value_string, p2, value_length);
+ value_string[value_length] = NULLCHAR;
+ }
+err:
+ if (buf)
+ free(buf);
+
+ return value_string;
+}
+
+static void
+check_vmcoreinfo(void)
+{
+ if (!kernel_symbol_exists("vmcoreinfo_data") ||
+ !kernel_symbol_exists("vmcoreinfo_size"))
+ return;
+
+ if (pc->read_vmcoreinfo == no_vmcoreinfo) {
+ switch (get_symbol_type("vmcoreinfo_data", NULL, NULL))
+ {
+ case TYPE_CODE_PTR:
+ pc->read_vmcoreinfo = vmcoreinfo_read_string;
+ break;
+ case TYPE_CODE_ARRAY:
+ pc->read_vmcoreinfo = vmcoreinfo_read_string;
+ break;
+ }
+ }
+}
diff --git a/main.c b/main.c
index 7248810..cd282cd 100644
--- a/main.c
+++ b/main.c
@@ -1,8 +1,8 @@
/* main.c - core analysis suite
*
* Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc.
- * Copyright (C) 2002-2018 David Anderson
- * Copyright (C) 2002-2018 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2002-2019 David Anderson
+ * Copyright (C) 2002-2019 Red Hat, Inc. All rights reserved.
*
* 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
@@ -29,7 +29,6 @@ static void check_xen_hyper(void);
static void show_untrusted_files(void);
static void get_osrelease(char *);
static void get_log(char *);
-static char *no_vmcoreinfo(const char *);
static struct option long_options[] = {
{"memory_module", required_argument, 0, 0},
@@ -1950,7 +1949,7 @@ get_log(char *dumpfile)
}
-static char *
+char *
no_vmcoreinfo(const char *unused)
{
return NULL;
diff --git a/netdump.c b/netdump.c
index d0179e0..5aeea6f 100644
--- a/netdump.c
+++ b/netdump.c
@@ -1,7 +1,7 @@
/* netdump.c
*
- * Copyright (C) 2002-2018 David Anderson
- * Copyright (C) 2002-2018 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2002-2019 David Anderson
+ * Copyright (C) 2002-2019 Red Hat, Inc. All rights reserved.
*
* 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
@@ -1786,11 +1786,13 @@ vmcoreinfo_read_string(const char *key)
if (STREQ(key, "NUMBER(kimage_voffset)") && nd->arch_data) {
value = calloc(VADDR_PRLEN+1, sizeof(char));
sprintf(value, "%lx", nd->arch_data);
+ pc->read_vmcoreinfo = no_vmcoreinfo;
return value;
}
if (STREQ(key, "relocate") && nd->arch_data) {
value = calloc(VADDR_PRLEN+1, sizeof(char));
sprintf(value, "%lx", nd->arch_data);
+ pc->read_vmcoreinfo = no_vmcoreinfo;
return value;
}
}

View File

@ -1,29 +0,0 @@
commit ac5a7889d31bb37aa0687110ecea08837f8a66a8
Author: Dave Anderson <anderson@redhat.com>
Date: Fri Feb 8 10:48:30 2019 -0500
Support for configurable CONFIG_ARM64_PA_BITS values introduced
in kernel commit 982aa7c5f0861bf56b2412ca341a13f44c238ba4, titled
"arm64: add kconfig symbol to configure physical address size".
Without the patch, it is impossible to determine the value of
CONFIG_ARM64_PA_BITS, and will require a new MAX_PHYSMEM_BITS
vmcoreinfo entry to be exported. This patch reads that entry
during intitialization.
(anderson@redhat.com)
diff --git a/arm64.c b/arm64.c
index 2308612..b4d9b13 100644
--- a/arm64.c
+++ b/arm64.c
@@ -362,7 +362,10 @@ arm64_init(int when)
arm64_calc_virtual_memory_ranges();
machdep->section_size_bits = _SECTION_SIZE_BITS;
if (!machdep->max_physmem_bits) {
- if (machdep->machspec->VA_BITS == 52) /* guess */
+ if ((string = pc->read_vmcoreinfo("NUMBER(MAX_PHYSMEM_BITS)"))) {
+ machdep->max_physmem_bits = atol(string);
+ free(string);
+ } else if (machdep->machspec->VA_BITS == 52) /* guess */
machdep->max_physmem_bits = _MAX_PHYSMEM_BITS_52;
else if (THIS_KERNEL_VERSION >= LINUX(3,17,0))
machdep->max_physmem_bits = _MAX_PHYSMEM_BITS_3_17;

View File

@ -0,0 +1,28 @@
commit b1a6e13a93661dfae7df15fe32862bddf4026c80
Author: Dave Anderson <anderson@redhat.com>
Date: Tue May 21 14:09:13 2019 -0400
Fix for a crash-7.2.6 regression to the "p" command. Without the
patch, a gdb pass-through command construct such as:
p ((struct zone *)0xffff901e3ffda000)->min_slab_pages
gets parsed incorrectly, and the "-" is mistaken for an argument
option, and each of the subsequent characters are marked as an
"invalid option".
(dwysocha@redhat.com)
diff --git a/tools.c b/tools.c
index eceea90..2d95c3a 100644
--- a/tools.c
+++ b/tools.c
@@ -246,8 +246,10 @@ next:
break;
}
}
- if (expression == 0)
+ if (expression == 0) {
i++;
+ continue;
+ }
}
if (str[i] != NULLCHAR && str[i] != '\n') {

View File

@ -1,149 +0,0 @@
commit b9d76838372d1b4087bb506ce6da425afad68876
Author: Dave Anderson <anderson@redhat.com>
Date: Thu Jun 7 13:20:16 2018 -0400
If /proc/kcore gets selected for the live memory source because
/dev/mem was configured with CONFIG_STRICT_DEVMEM, its ELF header
contents are not displayed by "help -[dD]", and are not displayed
when the crash session is invoked with -d<number>". Without the
patch, the ELF contents are only displayed in those two situations
if "/proc/kcore" is explicitly entered on the crash command line.
(anderson@redhat.com)
diff --git a/netdump.c b/netdump.c
index 25683eb..1f3e26c 100644
--- a/netdump.c
+++ b/netdump.c
@@ -4334,11 +4334,8 @@ kcore_memory_dump(FILE *ofp)
Elf32_Phdr *lp32;
Elf64_Phdr *lp64;
- if (!(pkd->flags & KCORE_LOCAL))
- return FALSE;
-
fprintf(ofp, "proc_kcore_data:\n");
- fprintf(ofp, " flags: %lx (", nd->flags);
+ fprintf(ofp, " flags: %x (", pkd->flags);
others = 0;
if (pkd->flags & KCORE_LOCAL)
fprintf(ofp, "%sKCORE_LOCAL", others++ ? "|" : "");
commit c79a11fa10da94b71ddf341ec996c522fbd75237
Author: Dave Anderson <anderson@redhat.com>
Date: Fri Jun 8 14:31:08 2018 -0400
If the default live memory source /dev/mem is determined to be
unusable because the kernel was configured with CONFIG_STRICT_DEVMEM,
the first memory read during session initialization will fail. The
current behavior results in a readmem() error message, followed by two
notification messages that indicate that /dev/mem is restricted and
a switch to using /proc/kcore will be attempted; the readmem is
reattempted from /proc/kcore, and if successful, the session will
continue initialization. With this patch, the behavior will change
such that if the switch to /proc/kcore and the reattempted readmem()
are successful, no messages will be displayed unless the crash
session is invoked with "crash -d&lt;number>".
(anderson@redhat.com)
diff --git a/kernel.c b/kernel.c
index 138a47f..3cd5bf1 100644
--- a/kernel.c
+++ b/kernel.c
@@ -882,7 +882,7 @@ cpu_maps_init(void)
{
int i, c, m, cpu, len;
char *buf;
- ulong *maskptr, addr;
+ ulong *maskptr, addr, error_handle;
struct mapinfo {
ulong cpu_flag;
char *name;
@@ -902,8 +902,9 @@ cpu_maps_init(void)
if (!(addr = cpu_map_addr(mapinfo[m].name)))
continue;
+ error_handle = pc->flags & DEVMEM ? RETURN_ON_ERROR|QUIET : RETURN_ON_ERROR;
if (!readmem(addr, KVADDR, buf, len,
- mapinfo[m].name, RETURN_ON_ERROR)) {
+ mapinfo[m].name, error_handle)) {
error(WARNING, "cannot read cpu_%s_map\n",
mapinfo[m].name);
continue;
diff --git a/memory.c b/memory.c
index 82f9cbf..2f568d5 100644
--- a/memory.c
+++ b/memory.c
@@ -2243,9 +2243,11 @@ readmem(ulonglong addr, int memtype, void *buffer, long size,
error(INFO, READ_ERRMSG, memtype_string(memtype, 0), addr, type);
if ((pc->flags & DEVMEM) && (kt->flags & PRE_KERNEL_INIT) &&
!(error_handle & NO_DEVMEM_SWITCH) && devmem_is_restricted() &&
- switch_to_proc_kcore())
+ switch_to_proc_kcore()) {
+ error_handle &= ~QUIET;
return(readmem(addr, memtype, bufptr, size,
type, error_handle));
+ }
goto readmem_error;
case PAGE_EXCLUDED:
@@ -2457,7 +2459,7 @@ devmem_is_restricted(void)
QUIET|RETURN_ON_ERROR|NO_DEVMEM_SWITCH))
restricted = TRUE;
- if (restricted)
+ if (restricted && CRASHDEBUG(1))
error(INFO,
"this kernel may be configured with CONFIG_STRICT_DEVMEM,"
" which\n renders /dev/mem unusable as a live memory "
@@ -2472,9 +2474,10 @@ switch_to_proc_kcore(void)
{
close(pc->mfd);
- if (file_exists("/proc/kcore", NULL))
- error(INFO, "trying /proc/kcore as an alternative to /dev/mem\n\n");
- else
+ if (file_exists("/proc/kcore", NULL)) {
+ if (CRASHDEBUG(1))
+ error(INFO, "trying /proc/kcore as an alternative to /dev/mem\n\n");
+ } else
return FALSE;
if ((pc->mfd = open("/proc/kcore", O_RDONLY)) < 0) {
diff --git a/ppc64.c b/ppc64.c
index 0b04187..0dd8a2a 100644
--- a/ppc64.c
+++ b/ppc64.c
@@ -1,7 +1,7 @@
/* ppc64.c -- core analysis suite
*
- * Copyright (C) 2004-2015,2017 David Anderson
- * Copyright (C) 2004-2015,2017 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004-2015,2018 David Anderson
+ * Copyright (C) 2004-2015,2018 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004, 2006 Haren Myneni, IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
@@ -343,8 +343,9 @@ ppc64_init(int when)
if (symbol_exists("vmemmap_populate")) {
if (symbol_exists("vmemmap")) {
- get_symbol_data("vmemmap", sizeof(void *),
- &machdep->machspec->vmemmap_base);
+ readmem(symbol_value("vmemmap"), KVADDR,
+ &machdep->machspec->vmemmap_base,
+ sizeof(void *), "vmemmap", QUIET|FAULT_ON_ERROR);
} else
machdep->machspec->vmemmap_base =
VMEMMAP_REGION_ID << REGION_SHIFT;
diff --git a/x86_64.c b/x86_64.c
index 54b6539..e01082b 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -356,7 +356,7 @@ x86_64_init(int when)
machdep->flags |= RANDOMIZED;
readmem(symbol_value("page_offset_base"), KVADDR,
&machdep->machspec->page_offset, sizeof(ulong),
- "page_offset_base", FAULT_ON_ERROR);
+ "page_offset_base", QUIET|FAULT_ON_ERROR);
machdep->kvbase = machdep->machspec->page_offset;
machdep->identity_map_base = machdep->machspec->page_offset;
}

View File

@ -0,0 +1,26 @@
commit bf48dd4e9926515345cad06c1bfce49d7a057a26
Author: Dave Anderson <anderson@redhat.com>
Date: Mon Jun 10 14:12:52 2019 -0400
Fix for Linux 4.16 and later ARM64 kernels that contain kernel commit
fa2a8445b1d3810c52f2a6b3a006456bd1aacb7e, titled "arm64: allow ID map
to be extended to 52 bits", and which have been configured with both
CONFIG_DEVMEM=y and CONFIG_STRICT_DEVMEM=y. Without the patch, an
inconsequential error message indicating "crash: read error: kernel
virtual address: <address> type: idmap_ptrs_per_pgd" is displayed
during initialization.
(anderson@redhat.com)
diff --git a/arm64.c b/arm64.c
index 5b82263..6b34b5f 100644
--- a/arm64.c
+++ b/arm64.c
@@ -283,7 +283,7 @@ arm64_init(int when)
case 65536:
if (kernel_symbol_exists("idmap_ptrs_per_pgd") &&
readmem(symbol_value("idmap_ptrs_per_pgd"), KVADDR,
- &value, sizeof(ulong), "idmap_ptrs_per_pgd", RETURN_ON_ERROR))
+ &value, sizeof(ulong), "idmap_ptrs_per_pgd", QUIET|RETURN_ON_ERROR))
machdep->ptrs_per_pgd = value;
if (machdep->machspec->VA_BITS > PGDIR_SHIFT_L3_64K) {

View File

@ -1,239 +0,0 @@
commit c5f45d6cdbe7f01314857a75b2feef25b22adaaa
Author: Dave Anderson <anderson@redhat.com>
Date: Thu Oct 11 13:28:39 2018 -0400
Address several Coverity Scan "RESOURCE_LEAK" issues in the following
top-level source files: cmdline.c, kvmdump.c, lkcd_v8.c, xendump.c,
symbols.c, unwind_x86_32_64.c, va_server.c and va_server_v1.c.
(anderson@redhat.com)
diff --git a/cmdline.c b/cmdline.c
index c0a9f4f..cf3e150 100644
--- a/cmdline.c
+++ b/cmdline.c
@@ -1318,8 +1318,10 @@ is_shell_script(char *s)
if ((fd = open(s, O_RDONLY)) < 0)
return FALSE;
- if (isatty(fd))
+ if (isatty(fd)) {
+ close(fd);
return FALSE;
+ }
if (read(fd, interp, 2) != 2) {
close(fd);
diff --git a/kvmdump.c b/kvmdump.c
index 622619c..4db96bd 100644
--- a/kvmdump.c
+++ b/kvmdump.c
@@ -846,8 +846,10 @@ kvmdump_mapfile_exists(void)
sprintf(filename, "%s.map", pc->dumpfile);
- if (!file_exists(filename, &stat) || !S_ISREG(stat.st_mode))
+ if (!file_exists(filename, &stat) || !S_ISREG(stat.st_mode)) {
+ free(filename);
return FALSE;
+ }
if (is_kvmdump_mapfile(filename)) {
pc->kvmdump_mapfile = filename;
diff --git a/lkcd_v8.c b/lkcd_v8.c
index 1322250..3b355e0 100644
--- a/lkcd_v8.c
+++ b/lkcd_v8.c
@@ -184,6 +184,7 @@ lkcd_dump_init_v8_arch(dump_header_t *dh)
memcpy(&dump_header_asm_v8, &arch_hdr, sizeof(dump_header_asm_t));
+ free(hdr_buf);
return 0;
err:
diff --git a/symbols.c b/symbols.c
index b54b8c0..fb9cd1b 100644
--- a/symbols.c
+++ b/symbols.c
@@ -3862,12 +3862,10 @@ is_bfd_format(char *filename)
#else
struct bfd *bfd;
#endif
- char **matching;
-
if ((bfd = bfd_openr(filename, NULL)) == NULL)
return FALSE;
- if (!bfd_check_format_matches(bfd, bfd_object, &matching)) {
+ if (!bfd_check_format_matches(bfd, bfd_object, NULL)) {
bfd_close(bfd);
return FALSE;
}
diff --git a/unwind_x86_32_64.c b/unwind_x86_32_64.c
index c62f92f..c7c30d6 100644
--- a/unwind_x86_32_64.c
+++ b/unwind_x86_32_64.c
@@ -819,6 +819,7 @@ try_eh_frame:
error(WARNING, "cannot read %s data from %s\n",
is_ehframe ? ".eh_frame" : ".debug_frame", pc->namelist);
free(unwind_table);
+ close(fd);
return;
}
diff --git a/va_server.c b/va_server.c
index d96287a..96c2b5c 100644
--- a/va_server.c
+++ b/va_server.c
@@ -313,20 +313,27 @@ int read_map(char *crash_file)
ret = fseek(vas_file_p, (long)0, SEEK_SET);
if(ret == -1) {
printf("va_server: unable to fseek, err = %d\n", ferror(vas_file_p));
+ free(hdr);
free(disk_hdr);
return -1;
}
items = fread((void *)disk_hdr, 1, Page_Size, vas_file_p);
if(items != Page_Size) {
+ free(hdr);
+ free(disk_hdr);
return -1;
}
if(disk_hdr->magic[0] != CRASH_MAGIC) {
+ free(hdr);
+ free(disk_hdr);
return -1;
}
ret = fseek(vas_file_p, (long)((disk_hdr->map_block) * disk_hdr->blk_size), SEEK_SET);
if(ret == -1) {
printf("va_server: unable to fseek, err = %d\n", ferror(vas_file_p));
+ free(hdr);
+ free(disk_hdr);
return -1;
}
@@ -338,10 +345,13 @@ int read_map(char *crash_file)
vas_file_p);
if(items != disk_hdr->map_blocks) {
printf("unable to read map entries, err = %d\n", errno);
+ free(hdr);
+ free(disk_hdr);
return -1;
}
vas_map_base = hdr;
+ free(disk_hdr);
return 0;
}
diff --git a/va_server_v1.c b/va_server_v1.c
index 1924946..88a2a5a 100644
--- a/va_server_v1.c
+++ b/va_server_v1.c
@@ -253,7 +253,7 @@ u_long vas_find_end_v1(void)
}
int read_maps_v1(char *crash_file)
{
- int *cur_entry_p;
+ int *cur_entry_p, *cp;
int ret, items, blk_pos;
cur_entry_p = (int *)malloc(Page_Size);
@@ -266,25 +266,32 @@ int read_maps_v1(char *crash_file)
vas_file_p = fopen(crash_file, "r");
if(vas_file_p == (FILE *)0) {
printf("read_maps: bad ret from fopen for %s: %s\n", crash_file, strerror(errno));
+ free(cur_entry_p);
return -1;
}
ret = fseek(vas_file_p, (long)0, SEEK_SET);
if(ret == -1) {
printf("read_maps: unable to fseek in %s, errno = %d\n", crash_file, ferror(vas_file_p));
+ free(cur_entry_p);
return -1;
}
items = fread((void *)cur_entry_p, 1, Page_Size, vas_file_p);
if(items != Page_Size) {
printf("read_maps: unable to read header from %s, errno = %d\n", crash_file, ferror(vas_file_p));
+ free(cur_entry_p);
return -1;
}
ret = -1;
- while ((blk_pos = *cur_entry_p++)) {
- if (read_map_v1(blk_pos))
+ cp = cur_entry_p;
+ while ((blk_pos = *cp++)) {
+ if (read_map_v1(blk_pos)) {
+ free(cur_entry_p);
return -1;
+ }
ret = 0;
}
+ free(cur_entry_p);
return ret;
}
@@ -308,21 +315,28 @@ int read_map_v1(int blk_pos)
ret = fseek(vas_file_p, (long)(blk_pos*Page_Size), SEEK_SET);
if(ret == -1) {
console("va_server: unable to fseek, err = %d\n", ferror(vas_file_p));
+ free(hdr);
free(disk_hdr);
return -1;
}
items = fread((void *)disk_hdr, 1, Page_Size, vas_file_p);
if(items != Page_Size) {
+ free(hdr);
+ free(disk_hdr);
return -1;
}
if(disk_hdr->magic[0] != CRASH_MAGIC) {
console("va_server: bad magic 0x%lx\n", disk_hdr->magic[0]);
+ free(hdr);
+ free(disk_hdr);
return -1;
}
ret = fseek(vas_file_p, (long)((blk_pos + disk_hdr->map_block) * disk_hdr->blk_size), SEEK_SET);
if(ret == -1) {
printf("va_server: unable to fseek, err = %d\n", ferror(vas_file_p));
+ free(hdr);
+ free(disk_hdr);
return -1;
}
@@ -338,6 +352,8 @@ int read_map_v1(int blk_pos)
vas_file_p);
if(items != hdr->map_entries) {
printf("unable to read map entries, err = %d\n", errno);
+ free(hdr);
+ free(disk_hdr);
return -1;
}
diff --git a/xendump.c b/xendump.c
index 4bd59b5..70cf261 100644
--- a/xendump.c
+++ b/xendump.c
@@ -2775,8 +2775,10 @@ xc_core_dump_elfnote(off_t sh_offset, size_t sh_size, int store)
index += sizeof(struct elfnote) + elfnote->descsz;
}
- if (!store)
+ if (!store) {
+ free(notes_buffer);
return;
+ }
if (elfnote_header) {
xd->xc_core.header.xch_magic = elfnote_header->xch_magic;
@@ -2798,6 +2800,7 @@ xc_core_dump_elfnote(off_t sh_offset, size_t sh_size, int store)
xd->xc_core.format_version = format_version->version;
}
+ free(notes_buffer);
}
/*

View File

@ -1,41 +0,0 @@
commit ced5255233447cc0810965b683657409f798c4a2
Author: Dave Anderson <anderson@redhat.com>
Date: Tue Oct 2 11:18:09 2018 -0400
As an addendum to the "dev -p" patch above, add the new structure
member offsets for display by the "help -o" option.
(anderson@redhat.com)
diff --git a/symbols.c b/symbols.c
index cb2174b..bb8a8f4 100644
--- a/symbols.c
+++ b/symbols.c
@@ -9692,6 +9692,28 @@ dump_offset_table(char *spec, ulong makestruct)
fprintf(fp, " pci_bus_number: %ld\n",
OFFSET(pci_bus_number));
+ fprintf(fp, " pci_dev_dev: %ld\n",
+ OFFSET(pci_dev_dev));
+ fprintf(fp, " pci_dev_hdr_type: %ld\n",
+ OFFSET(pci_dev_hdr_type));
+ fprintf(fp, " pci_dev_pcie_flags_reg: %ld\n",
+ OFFSET(pci_dev_pcie_flags_reg));
+ fprintf(fp, " pci_bus_node: %ld\n",
+ OFFSET(pci_bus_node));
+ fprintf(fp, " pci_bus_devices: %ld\n",
+ OFFSET(pci_bus_devices));
+ fprintf(fp, " pci_bus_dev: %ld\n",
+ OFFSET(pci_bus_dev));
+ fprintf(fp, " pci_bus_children: %ld\n",
+ OFFSET(pci_bus_children));
+ fprintf(fp, " pci_bus_parent: %ld\n",
+ OFFSET(pci_bus_parent));
+ fprintf(fp, " pci_bus_self: %ld\n",
+ OFFSET(pci_bus_self));
+ fprintf(fp, " device_kobj: %ld\n",
+ OFFSET(device_kobj));
+ fprintf(fp, " kobject_name: %ld\n",
+ OFFSET(kobject_name));
fprintf(fp, " resource_entry_t_from: %ld\n",
OFFSET(resource_entry_t_from));

View File

@ -1,89 +0,0 @@
commit f3a5305947077a65aea8091b05cdb542cea0d61a
Author: Dave Anderson <anderson@redhat.com>
Date: Wed Oct 24 16:25:43 2018 -0400
Modify the x86_64 "bt" behavior when a legitimate exception RIP value
cannot be referenced symbolically, such as when the exception occurs
while running in seccomp BPF filter code. Without the patch, the
exception frame register dump is preceded by "[exception RIP: unknown
or invalid address]", and then followed by "bt: WARNING: possibly
bogus exception frame". With the patch applied, the translation of
the exception RIP will show "[exception RIP: no symbolic reference]",
and there will be no warning message.
(anderson@redhat.com)
diff --git a/x86_64.c b/x86_64.c
index 345122c..d145f96 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -3259,6 +3259,18 @@ x86_64_in_alternate_stack(int cpu, ulong
return FALSE;
}
+static char *
+x86_64_exception_RIP_message(struct bt_info *bt, ulong rip)
+{
+ physaddr_t phys;
+
+ if (IS_VMALLOC_ADDR(rip) &&
+ machdep->kvtop(bt->tc, rip, &phys, 0))
+ return ("no symbolic reference");
+
+ return ("unknown or invalid address");
+}
+
#define STACK_TRANSITION_ERRMSG_E_I_P \
"cannot transition from exception stack to IRQ stack to current process stack:\n exception stack pointer: %lx\n IRQ stack pointer: %lx\n process stack pointer: %lx\n current stack base: %lx\n"
#define STACK_TRANSITION_ERRMSG_E_P \
@@ -3370,7 +3382,7 @@ x86_64_low_budget_back_trace_cmd(struct
fprintf(ofp, (*gdb_output_radix == 16) ?
"+0x%lx" : "+%ld", offset);
} else
- fprintf(ofp, "unknown or invalid address");
+ fprintf(ofp, "%s", x86_64_exception_RIP_message(bt, bt->instptr));
fprintf(ofp, "]\n");
if (KVMDUMP_DUMPFILE())
kvmdump_display_regs(bt->tc->processor, ofp);
@@ -4458,9 +4470,9 @@ x86_64_exception_frame(ulong flags, ulon
(*gdb_output_radix == 16) ?
"+0x%lx" : "+%ld",
offset);
- } else
- fprintf(ofp,
- "unknown or invalid address");
+ } else
+ fprintf(ofp, "%s",
+ x86_64_exception_RIP_message(bt, rip));
fprintf(ofp, "]\n");
}
} else if (!(cs & 3)) {
@@ -4472,7 +4484,7 @@ x86_64_exception_frame(ulong flags, ulon
"+0x%lx" : "+%ld", offset);
bt->eframe_ip = rip;
} else
- fprintf(ofp, "unknown or invalid address");
+ fprintf(ofp, "%s", x86_64_exception_RIP_message(bt, rip));
fprintf(ofp, "]\n");
}
fprintf(ofp, " RIP: %016lx RSP: %016lx RFLAGS: %08lx\n",
@@ -4616,6 +4628,7 @@ x86_64_eframe_verify(struct bt_info *bt,
int estack;
struct syment *sp;
ulong offset, exception;
+ physaddr_t phys;
if ((rflags & RAZ_MASK) || !(rflags & 0x2))
return FALSE;
@@ -4682,6 +4695,12 @@ x86_64_eframe_verify(struct bt_info *bt,
return TRUE;
}
+ if ((cs == 0x10) && kvaddr) {
+ if (IS_KVADDR(rsp) && IS_VMALLOC_ADDR(rip) &&
+ machdep->kvtop(bt->tc, rip, &phys, 0))
+ return TRUE;
+ }
+
if ((cs == 0x33) && (ss == 0x2b)) {
if (IS_UVADDR(rip, bt->tc) && IS_UVADDR(rsp, bt->tc))
return TRUE;

View File

@ -1,499 +0,0 @@
commit 5fe78861ea1589084f6a2956a6ff63677c9269e1
Author: Dave Anderson <anderson@redhat.com>
Date: Fri Sep 7 16:05:52 2018 -0400
Commit 3db3d3992d781c1e42587d2d2bf81e785408e0c2 in crash-7.1.8 was
aimed at making the PPC64 "bt" command work for dumpfiles saved
with the FADUMP facility, but it introduced a bit of unwarranted
complexity in "bt" command processing. Reworked the "bt" command
processing for PPC64 arch to make it a little less compilated and
also to print symbols for NIP and LR registers in exception frames.
Without the patch, "bt" on non-panic active tasks may fail with
the message "bt: invalid kernel virtual address: <address>
type: Regs NIP value".
(hbathini@linux.ibm.com)
diff --git a/ppc64.c b/ppc64.c
index f5d0dac..03fecd3 100644
--- a/ppc64.c
+++ b/ppc64.c
@@ -2093,15 +2093,10 @@ ppc64_print_stack_entry(int frame,
lr);
return;
}
- if (req->pc != lr) {
- fprintf(fp, "\n%s[Link Register] ",
- frame < 10 ? " " : "");
- fprintf(fp, "[%lx] %s at %lx",
- req->sp, lrname, lr);
- }
req->ra = lr;
}
- if (!req->name || STREQ(req->name,lrname))
+ if (!req->name || STREQ(req->name, lrname) ||
+ !is_kernel_text(req->pc))
fprintf(fp, " (unreliable)");
fprintf(fp, "\n");
@@ -2219,6 +2214,22 @@ ppc64_print_regs(struct ppc64_pt_regs *regs)
fprintf(fp, " Syscall Result: %016lx\n", regs->result);
}
+static void ppc64_print_nip_lr(struct ppc64_pt_regs *regs, int print_lr)
+{
+ char buf[BUFSIZE];
+ char *sym_buf;
+
+ sym_buf = value_to_symstr(regs->nip, buf, 0);
+ if (sym_buf[0] != NULLCHAR)
+ fprintf(fp, " [NIP : %s]\n", sym_buf);
+
+ if (print_lr) {
+ sym_buf = value_to_symstr(regs->link, buf, 0);
+ if (sym_buf[0] != NULLCHAR)
+ fprintf(fp, " [LR : %s]\n", sym_buf);
+ }
+}
+
/*
* Print the exception frame information
*/
@@ -2231,6 +2242,59 @@ ppc64_print_eframe(char *efrm_str, struct ppc64_pt_regs *regs,
fprintf(fp, " %s [%lx] exception frame:\n", efrm_str, regs->trap);
ppc64_print_regs(regs);
+ ppc64_print_nip_lr(regs, 1);
+}
+
+/*
+ * For vmcore typically saved with KDump or FADump, get SP and IP values
+ * from the saved ptregs.
+ */
+static int
+ppc64_vmcore_stack_frame(struct bt_info *bt_in, ulong *nip, ulong *ksp)
+{
+ struct ppc64_pt_regs *pt_regs;
+ unsigned long unip;
+
+ pt_regs = (struct ppc64_pt_regs *)bt_in->machdep;
+ if (!pt_regs || !pt_regs->gpr[1]) {
+ /*
+ * Not collected regs. May be the corresponding CPU not
+ * responded to an IPI in case of KDump OR f/w has not
+ * not provided the register info in case of FADump.
+ */
+ fprintf(fp, "%0lx: GPR1 register value (SP) was not saved\n",
+ bt_in->task);
+ return FALSE;
+ }
+ *ksp = pt_regs->gpr[1];
+ if (IS_KVADDR(*ksp)) {
+ readmem(*ksp+16, KVADDR, &unip, sizeof(ulong), "Regs NIP value",
+ FAULT_ON_ERROR);
+ *nip = unip;
+ } else {
+ if (IN_TASK_VMA(bt_in->task, *ksp))
+ fprintf(fp, "%0lx: Task is running in user space\n",
+ bt_in->task);
+ else
+ fprintf(fp, "%0lx: Invalid Stack Pointer %0lx\n",
+ bt_in->task, *ksp);
+ *nip = pt_regs->nip;
+ }
+
+ if (bt_in->flags &&
+ ((BT_TEXT_SYMBOLS|BT_TEXT_SYMBOLS_PRINT|BT_TEXT_SYMBOLS_NOPRINT)))
+ return TRUE;
+
+ /*
+ * Print the collected regs for the active task
+ */
+ ppc64_print_regs(pt_regs);
+ if (!IS_KVADDR(*ksp))
+ return FALSE;
+
+ ppc64_print_nip_lr(pt_regs, (unip != pt_regs->link) ? 1 : 0);
+
+ return TRUE;
}
/*
@@ -2239,7 +2303,7 @@ ppc64_print_eframe(char *efrm_str, struct ppc64_pt_regs *regs,
static int
ppc64_get_dumpfile_stack_frame(struct bt_info *bt_in, ulong *nip, ulong *ksp)
{
- int i;
+ int i, ret, panic_task;
char *sym;
ulong *up;
struct bt_info bt_local, *bt;
@@ -2251,11 +2315,29 @@ ppc64_get_dumpfile_stack_frame(struct bt_info *bt_in, ulong *nip, ulong *ksp)
struct ppc64_pt_regs *pt_regs;
struct syment *sp;
- bt = &bt_local;
- BCOPY(bt_in, bt, sizeof(struct bt_info));
- ms = machdep->machspec;
+ bt = &bt_local;
+ BCOPY(bt_in, bt, sizeof(struct bt_info));
+ ms = machdep->machspec;
+ ur_nip = ur_ksp = 0;
+
+ panic_task = tt->panic_task == bt->task ? TRUE : FALSE;
check_hardirq = check_softirq = tt->flags & IRQSTACKS ? TRUE : FALSE;
+ if (panic_task && bt->machdep) {
+ pt_regs = (struct ppc64_pt_regs *)bt->machdep;
+ ur_nip = pt_regs->nip;
+ ur_ksp = pt_regs->gpr[1];
+ } else if ((pc->flags & KDUMP) ||
+ ((pc->flags & DISKDUMP) &&
+ (*diskdump_flags & KDUMP_CMPRS_LOCAL))) {
+ /*
+ * For the KDump or FADump vmcore, use SP and IP values
+ * that are saved in ptregs.
+ */
+ ret = ppc64_vmcore_stack_frame(bt_in, nip, ksp);
+ if (ret)
+ return TRUE;
+ }
if (bt->task != tt->panic_task) {
char cpu_frozen = FALSE;
@@ -2385,38 +2467,14 @@ retry:
check_intrstack = FALSE;
goto retry;
}
-
/*
- * We didn't find what we were looking for, so try to use
- * the SP and IP values saved in ptregs.
+ * We didn't find what we were looking for, so just use what was
+ * passed in the ELF header.
*/
- pt_regs = (struct ppc64_pt_regs *)bt_in->machdep;
- if (!pt_regs || !pt_regs->gpr[1]) {
- /*
- * Not collected regs. May be the corresponding CPU did not
- * respond to an IPI.
- */
- if (CRASHDEBUG(1))
- fprintf(fp, "%0lx: GPR1(SP) register value not saved\n",
- bt_in->task);
- } else {
- *ksp = pt_regs->gpr[1];
- if (IS_KVADDR(*ksp)) {
- readmem(*ksp+16, KVADDR, nip, sizeof(ulong),
- "Regs NIP value", FAULT_ON_ERROR);
- ppc64_print_regs(pt_regs);
- return TRUE;
- } else {
- if (IN_TASK_VMA(bt_in->task, *ksp))
- fprintf(fp, "%0lx: Task is running in user space\n",
- bt_in->task);
- else
- fprintf(fp, "%0lx: Invalid Stack Pointer %0lx\n",
- bt_in->task, *ksp);
- *nip = pt_regs->nip;
- ppc64_print_regs(pt_regs);
- return FALSE;
- }
+ if (ur_nip && ur_ksp) {
+ *nip = ur_nip;
+ *ksp = ur_ksp;
+ return TRUE;
}
console("ppc64_get_dumpfile_stack_frame: cannot find SP for panic task\n");
commit 7e3936895386ea6e85a6dc01bc5027f8133d12bb
Author: Dave Anderson <anderson@redhat.com>
Date: Mon Sep 17 14:33:08 2018 -0400
An addendum to crash commit 5fe78861ea1589084f6a2956a6ff63677c9269e1,
this patch for the PPC64 "bt" command prevents an invalid error
message from being displayed when an active non-panic task is
interrupted while running in user space. Without the patch, the
command correctly indicates "Task is running in user space", dumps
the user-space exception frame, but then prints the invalid error
message "bt: invalid kernel virtual address: ffffffffffffff90 type:
Regs NIP value".
(anderson@redhat.com)
diff --git a/ppc64.c b/ppc64.c
index 03fecd3..8badcde 100644
--- a/ppc64.c
+++ b/ppc64.c
@@ -2254,6 +2254,7 @@ ppc64_vmcore_stack_frame(struct bt_info *bt_in, ulong *nip, ulong *ksp)
{
struct ppc64_pt_regs *pt_regs;
unsigned long unip;
+ int in_user_space = FALSE;
pt_regs = (struct ppc64_pt_regs *)bt_in->machdep;
if (!pt_regs || !pt_regs->gpr[1]) {
@@ -2272,10 +2273,11 @@ ppc64_vmcore_stack_frame(struct bt_info *bt_in, ulong *nip, ulong *ksp)
FAULT_ON_ERROR);
*nip = unip;
} else {
- if (IN_TASK_VMA(bt_in->task, *ksp))
+ if (IN_TASK_VMA(bt_in->task, *ksp)) {
fprintf(fp, "%0lx: Task is running in user space\n",
bt_in->task);
- else
+ in_user_space = TRUE;
+ } else
fprintf(fp, "%0lx: Invalid Stack Pointer %0lx\n",
bt_in->task, *ksp);
*nip = pt_regs->nip;
@@ -2289,6 +2291,8 @@ ppc64_vmcore_stack_frame(struct bt_info *bt_in, ulong *nip, ulong *ksp)
* Print the collected regs for the active task
*/
ppc64_print_regs(pt_regs);
+ if (in_user_space)
+ return TRUE;
if (!IS_KVADDR(*ksp))
return FALSE;
commit 599a6579aa916df7800f8e889d68e4287e4520dd
Author: Dave Anderson <anderson@redhat.com>
Date: Thu Sep 27 14:14:31 2018 -0400
With Linux 4.19-rc1 commit 7d4340bb92a9df78e6e28152f3dd89d9bd82146b,
titled "powerpc/mm: Increase MAX_PHYSMEM_BITS to 128TB with
SPARSEMEM_VMEMMAP config", the PPC64 MAX_PHYSMEM_BITS value has
been bumped up to 47. The appropriate update has been made in
this patch.
(hbathini@linux.ibm.com)
diff --git a/defs.h b/defs.h
index 80c61ef..5b64bb7 100644
--- a/defs.h
+++ b/defs.h
@@ -4054,6 +4054,7 @@ struct efi_memory_desc_t {
#define _SECTION_SIZE_BITS 24
#define _MAX_PHYSMEM_BITS 44
#define _MAX_PHYSMEM_BITS_3_7 46
+#define _MAX_PHYSMEM_BITS_4_19 47
#endif /* PPC64 */
diff --git a/ppc64.c b/ppc64.c
index 8badcde..ee2f76f 100644
--- a/ppc64.c
+++ b/ppc64.c
@@ -554,7 +554,10 @@ ppc64_init(int when)
ppc64_vmemmap_init();
machdep->section_size_bits = _SECTION_SIZE_BITS;
- if (THIS_KERNEL_VERSION >= LINUX(3,7,0))
+ if ((machdep->flags & VMEMMAP) &&
+ (THIS_KERNEL_VERSION >= LINUX(4,19,0)))
+ machdep->max_physmem_bits = _MAX_PHYSMEM_BITS_4_19;
+ else if (THIS_KERNEL_VERSION >= LINUX(3,7,0))
machdep->max_physmem_bits = _MAX_PHYSMEM_BITS_3_7;
else
machdep->max_physmem_bits = _MAX_PHYSMEM_BITS;
commit 72cc0cba8a6cab14ca0961dff062d0384d307ce5
Author: Dave Anderson <anderson@redhat.com>
Date: Tue Oct 2 10:56:28 2018 -0400
Fix for the PPC64 "bt" command to recognize when a thread is running
in OPAL firmware. Without the patch, the "bt" command indicates
<task-address>: Invalid Stack Pointer <OPAL-firmware-address>"
(hbathini@linux.ibm.com)
--- a/defs.h
+++ b/defs.h
@@ -5934,6 +5934,12 @@ struct ppc64_elf_prstatus {
#ifdef PPC64
+struct ppc64_opal {
+ uint64_t base;
+ uint64_t entry;
+ uint64_t size;
+};
+
struct ppc64_vmemmap {
unsigned long phys;
unsigned long virt;
@@ -5984,6 +5990,7 @@ struct machine_specific {
ulong _page_accessed;
int (*is_kvaddr)(ulong);
int (*is_vmaddr)(ulong);
+ struct ppc64_opal opal;
};
void ppc64_init(int);
@@ -6001,6 +6008,7 @@ void ppc64_dump_machdep_table(ulong);
* in the kernel is also 0x40.
*/
#define RADIX_MMU (0x40)
+#define OPAL_FW (0x80)
#define REGION_SHIFT (60UL)
#define REGION_ID(addr) (((unsigned long)(addr)) >> REGION_SHIFT)
--- a/ppc64.c
+++ b/ppc64.c
@@ -65,8 +65,26 @@ static ulong hugepage_dir(ulong pte);
static ulong pgd_page_vaddr_l4(ulong pgd);
static ulong pud_page_vaddr_l4(ulong pud);
static ulong pmd_page_vaddr_l4(ulong pmd);
+static int is_opal_context(ulong sp, ulong nip);
void opalmsg(void);
+static int is_opal_context(ulong sp, ulong nip)
+{
+ uint64_t opal_start, opal_end;
+
+ if (!(machdep->flags & OPAL_FW))
+ return FALSE;
+
+ opal_start = machdep->machspec->opal.base;
+ opal_end = opal_start + machdep->machspec->opal.size;
+
+ if (((sp >= opal_start) && (sp < opal_end)) ||
+ ((nip >= opal_start) && (nip < opal_end)))
+ return TRUE;
+
+ return FALSE;
+}
+
static inline int is_hugepage(ulong pte)
{
if ((machdep->flags & BOOK3E) ||
@@ -241,6 +259,7 @@ struct machine_specific book3e_machine_s
.is_vmaddr = book3e_is_vmaddr,
};
+#define SKIBOOT_BASE 0x30000000
/*
* Do all necessary machine-specific setup here. This is called several
@@ -362,6 +381,16 @@ ppc64_init(int when)
struct machine_specific *m = machdep->machspec;
/*
+ * To determine if the kernel was running on OPAL based platform,
+ * use struct opal, which is populated with relevant values.
+ */
+ if (symbol_exists("opal")) {
+ get_symbol_data("opal", sizeof(struct ppc64_opal), &(m->opal));
+ if (m->opal.base == SKIBOOT_BASE)
+ machdep->flags |= OPAL_FW;
+ }
+
+ /*
* On Power ISA 3.0 based server processors, a kernel can
* run with radix MMU or standard MMU. Set the flag,
* if it is radix MMU.
@@ -712,6 +741,8 @@ ppc64_dump_machdep_table(ulong arg)
fprintf(fp, "%sSWAP_ENTRY_L4", others++ ? "|" : "");
if (machdep->flags & RADIX_MMU)
fprintf(fp, "%sRADIX_MMU", others++ ? "|" : "");
+ if (machdep->flags & OPAL_FW)
+ fprintf(fp, "%sOPAL_FW", others++ ? "|" : "");
fprintf(fp, ")\n");
fprintf(fp, " kvbase: %lx\n", machdep->kvbase);
@@ -2257,7 +2288,11 @@ ppc64_vmcore_stack_frame(struct bt_info
{
struct ppc64_pt_regs *pt_regs;
unsigned long unip;
- int in_user_space = FALSE;
+ /*
+ * TRUE: task is running in a different context (userspace, OPAL..)
+ * FALSE: task is probably running in kernel space.
+ */
+ int out_of_context = FALSE;
pt_regs = (struct ppc64_pt_regs *)bt_in->machdep;
if (!pt_regs || !pt_regs->gpr[1]) {
@@ -2270,20 +2305,25 @@ ppc64_vmcore_stack_frame(struct bt_info
bt_in->task);
return FALSE;
}
+
*ksp = pt_regs->gpr[1];
if (IS_KVADDR(*ksp)) {
readmem(*ksp+16, KVADDR, &unip, sizeof(ulong), "Regs NIP value",
FAULT_ON_ERROR);
*nip = unip;
} else {
+ *nip = pt_regs->nip;
if (IN_TASK_VMA(bt_in->task, *ksp)) {
fprintf(fp, "%0lx: Task is running in user space\n",
bt_in->task);
- in_user_space = TRUE;
+ out_of_context = TRUE;
+ } else if (is_opal_context(*ksp, *nip)) {
+ fprintf(fp, "%0lx: Task is running in OPAL (firmware) context\n",
+ bt_in->task);
+ out_of_context = TRUE;
} else
fprintf(fp, "%0lx: Invalid Stack Pointer %0lx\n",
bt_in->task, *ksp);
- *nip = pt_regs->nip;
}
if (bt_in->flags &&
@@ -2294,7 +2334,8 @@ ppc64_vmcore_stack_frame(struct bt_info
* Print the collected regs for the active task
*/
ppc64_print_regs(pt_regs);
- if (in_user_space)
+
+ if (out_of_context)
return TRUE;
if (!IS_KVADDR(*ksp))
return FALSE;
@@ -2828,7 +2869,6 @@ ppc64_get_smp_cpus(void)
*/
#define SKIBOOT_CONSOLE_DUMP_START 0x31000000
#define SKIBOOT_CONSOLE_DUMP_SIZE 0x100000
-#define SKIBOOT_BASE 0x30000000
#define ASCII_UNLIMITED ((ulong)(-1) >> 1)
void
@@ -2841,10 +2881,6 @@ opalmsg(void)
uint64_t u64;
uint64_t limit64;
};
- struct opal {
- unsigned long long base;
- unsigned long long entry;
- } opal;
int i, a;
size_t typesz;
void *location;
@@ -2856,25 +2892,13 @@ opalmsg(void)
long count = SKIBOOT_CONSOLE_DUMP_SIZE;
ulonglong addr = SKIBOOT_CONSOLE_DUMP_START;
+ if (!(machdep->flags & OPAL_FW))
+ error(FATAL, "dump was not captured on OPAL based system");
+
if (CRASHDEBUG(4))
fprintf(fp, "<addr: %llx count: %ld (%s)>\n",
addr, count, "PHYSADDR");
- /*
- * OPAL based platform check
- * struct opal of BSS section and hence default value will be ZERO(0)
- * opal_init() in the kernel initializes this structure based on
- * the platform. Use it as a key to determine whether the dump
- * was taken on an OPAL based system or not.
- */
- if (symbol_exists("opal")) {
- get_symbol_data("opal", sizeof(struct opal), &opal);
- if (opal.base != SKIBOOT_BASE)
- error(FATAL, "dump was captured on non-PowerNV machine");
- } else {
- error(FATAL, "dump was captured on non-PowerNV machine");
- }
-
BZERO(&mem, sizeof(struct memloc));
lost = typesz = per_line = 0;
location = NULL;

View File

@ -1,15 +0,0 @@
--- crash-7.2.3/ppc64.c.orig
+++ crash-7.2.3/ppc64.c
@@ -583,8 +583,11 @@ ppc64_init(int when)
ppc64_vmemmap_init();
machdep->section_size_bits = _SECTION_SIZE_BITS;
+
+#define is_RHEL8() (strstr(kt->proc_version, ".el8."))
+
if ((machdep->flags & VMEMMAP) &&
- (THIS_KERNEL_VERSION >= LINUX(4,19,0)))
+ ((THIS_KERNEL_VERSION >= LINUX(4,19,0)) || is_RHEL8()))
machdep->max_physmem_bits = _MAX_PHYSMEM_BITS_4_19;
else if (THIS_KERNEL_VERSION >= LINUX(3,7,0))
machdep->max_physmem_bits = _MAX_PHYSMEM_BITS_3_7;

View File

@ -3,8 +3,8 @@
# #
Summary: Kernel analysis utility for live systems, netdump, diskdump, kdump, LKCD or mcore dumpfiles Summary: Kernel analysis utility for live systems, netdump, diskdump, kdump, LKCD or mcore dumpfiles
Name: crash Name: crash
Version: 7.2.3 Version: 7.2.6
Release: 18%{?dist} Release: 2%{?dist}
License: GPLv3 License: GPLv3
Group: Development/Debuggers Group: Development/Debuggers
Source: http://people.redhat.com/anderson/crash-%{version}.tar.gz Source: http://people.redhat.com/anderson/crash-%{version}.tar.gz
@ -15,29 +15,9 @@ Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot-%(%{__id_u} -n)
BuildRequires: ncurses-devel zlib-devel lzo-devel bison snappy-devel BuildRequires: ncurses-devel zlib-devel lzo-devel bison snappy-devel
Requires: binutils Requires: binutils
Patch0: lzo_snappy.patch Patch0: lzo_snappy.patch
Patch1: github_46d21219_to_9446958f.patch Patch1: rhel8_build.patch
Patch2: github_95daa11b.patch Patch2: github_bf48dd4e_arm64_devmem_read_error.patch
Patch3: github_b9d76838_c79a11fa_proc_kcore.patch Patch3: github_b1a6e13a_p_regression.patch
Patch4: github_1926150e_ppc64_stacksize.patch
Patch5: github_28fa7bd0_to_02efd083.patch
Patch6: github_9b494b70_to_eb823b79.patch
Patch7: github_a10917ba_to_e9532aea.patch
Patch8: rhel8_build.patch
Patch9: github_ppc64_5fe78861_7e393689_599a6579_72cc0cba.patch
Patch10: github_3141bba9.patch
Patch11: github_c5f45d6c.patch
Patch12: github_f3a53059.patch
Patch13: github_64dad6d0.patch
Patch14: rhel8_ppc64_max_physmem_bits.patch
Patch15: github_27a6ebd0_dev-p.patch
Patch16: github_ced52552_dev-p_offsets.patch
Patch17: github_361f050e_dev-d.patch
Patch18: github_0f65ae0c_readline.patch
Patch19: github_6b93714b_cmdline.patch
Patch20: github_8618ddd8_CONFIG_ARM64_USER_VA_BITS_52
Patch21: github_ac5a7889_CONFIG_ARM64_PA_BITS.patch
Patch22: github_a89ec821_vmcoreinfo_plugin.patch
Patch23: github_2f57a96c_files-c-p.patch
%description %description
The core analysis suite is a self-contained tool that can be used to The core analysis suite is a self-contained tool that can be used to
@ -59,29 +39,9 @@ offered by Mission Critical Linux, or the LKCD kernel patch.
%prep %prep
%setup -n %{name}-%{version} -q %setup -n %{name}-%{version} -q
%patch0 -p1 -b lzo_snappy.patch %patch0 -p1 -b lzo_snappy.patch
%patch1 -p1 -b github_46d21219_to_9446958f.patch %patch1 -p1 -b rhel8_build.patch
%patch2 -p1 -b github_95daa11b.patch %patch2 -p1 -b github_bf48dd4e_arm64_devmem_read_error.patch
%patch3 -p1 -b github_b9d76838_c79a11fa_proc_kcore.patch %patch3 -p1 -b github_b1a6e13a_p_regression.patch
%patch4 -p1 -b github_1926150e_ppc64_stacksize.patch
%patch5 -p1 -b github_28fa7bd0_to_02efd083.patch
%patch6 -p1 -b github_9b494b70_to_eb823b79.patch
%patch7 -p1 -b github_a10917ba_to_e9532aea.patch
%patch8 -p1 -b rhel8_build.patch
%patch9 -p1 -b github_ppc64_5fe78861_7e393689_599a6579_72cc0cba.patch
%patch10 -p1 -b github_3141bba9.patch
%patch11 -p1 -b github_c5f45d6c.patch
%patch12 -p1 -b github_f3a53059.patch
%patch13 -p1 -b github_64dad6d0.patch
%patch14 -p1 -b rhel8_ppc64_max_physmem_bits.patch
%patch15 -p1 -b github_27a6ebd0_dev-p.patch
%patch16 -p1 -b github_ced52552_dev-p_offsets.patch
%patch17 -p1 -b github_361f050e_dev-d.patch
%patch18 -p1 -b github_0f65ae0c_readline.patch
%patch19 -p1 -b github_6b93714b_cmdline.patch
%patch20 -p1 -b github_8618ddd8_CONFIG_ARM64_USER_VA_BITS_52
%patch21 -p1 -b github_ac5a7889_CONFIG_ARM64_PA_BITS.patch
%patch22 -p1 -b github_a89ec821_vmcoreinfo_plugin.patch
%patch23 -p1 -b github_2f57a96c_files-c-p.patch
%build %build
make RPMPKG="%{version}-%{release}" CFLAGS="%{optflags}" make RPMPKG="%{version}-%{release}" CFLAGS="%{optflags}"
@ -110,6 +70,20 @@ rm -rf %{buildroot}
%{_includedir}/* %{_includedir}/*
%changelog %changelog
* Mon Jun 10 2019 Dave Anderson <anderson@redhat.com> - 7.2.6-2
- Fix "p" command regression
Resolves: rhbz#1718417
- Fix arm64 debug kernel read error message during initialization
Resolves: rhbz#1718736
* Mon May 6 2019 Dave Anderson <anderson@redhat.com> - 7.2.6-1
- Rebase to latest upstream sources
Resolves: rhbz#1686560
- Utilize the VMCOREINFO PT_NOTE in /proc/kcore header
Resolves: rhbz#1627528
- Support extraction of CONFIG_PROC_VMCORE_DEVICE_DUMP data from dumpfile header
Resolves: rhbz#1702535
* Thu Feb 14 2019 Dave Anderson <anderson@redhat.com> - 7.2.3-18 * Thu Feb 14 2019 Dave Anderson <anderson@redhat.com> - 7.2.3-18
- Fix "files -c" and "files -p" options - Fix "files -c" and "files -p" options
Resolves: rhbz#1673285 Resolves: rhbz#1673285