diff --git a/.crash.metadata b/.crash.metadata index d966af7..d8e3943 100644 --- a/.crash.metadata +++ b/.crash.metadata @@ -1 +1 @@ -1a9fa8cd6869da42314ec47df6a750e053f4bece SOURCES/crash-7.2.3.tar.gz +c972d50634ae15fac036bd1f8f9f84d87a54acba SOURCES/crash-7.2.6.tar.gz diff --git a/.gitignore b/.gitignore index 32212ef..ee5c871 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/crash-7.2.3.tar.gz +SOURCES/crash-7.2.6.tar.gz diff --git a/SOURCES/github_0f65ae0c_readline.patch b/SOURCES/github_0f65ae0c_readline.patch deleted file mode 100644 index 73d317a..0000000 --- a/SOURCES/github_0f65ae0c_readline.patch +++ /dev/null @@ -1,154 +0,0 @@ -commit 0f65ae0c36bf04e22219f28c32c3ae0cdee5acfe -Author: Dave Anderson -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; -+} diff --git a/SOURCES/github_1926150e_ppc64_stacksize.patch b/SOURCES/github_1926150e_ppc64_stacksize.patch deleted file mode 100644 index 5da09da..0000000 --- a/SOURCES/github_1926150e_ppc64_stacksize.patch +++ /dev/null @@ -1,27 +0,0 @@ -commit 1926150ee350e17fee2aeabb8ef781222d94366e -Author: Dave Anderson -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:
type: stack - contents" and "bt: read of stack at
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"); diff --git a/SOURCES/github_27a6ebd0_dev-p.patch b/SOURCES/github_27a6ebd0_dev-p.patch deleted file mode 100644 index 0cbafcc..0000000 --- a/SOURCES/github_27a6ebd0_dev-p.patch +++ /dev/null @@ -1,412 +0,0 @@ -commit 27a6ebd0cda386b1dfb7b0fffb4d8b489b391ccf -Author: Dave Anderson -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)) { diff --git a/SOURCES/github_28fa7bd0_to_02efd083.patch b/SOURCES/github_28fa7bd0_to_02efd083.patch deleted file mode 100644 index 177c106..0000000 --- a/SOURCES/github_28fa7bd0_to_02efd083.patch +++ /dev/null @@ -1,174 +0,0 @@ -commit 28fa7bd09013455b5ddc020dea4706278cda0d65 -Author: Dave Anderson -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:
- type: kmem_cache_cpu.freelist" and "kmem: invalid kernel virtual - 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 -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 -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 -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 ... - Without the patch, the kmem command may fail with the error message - "". 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"); diff --git a/SOURCES/github_2f57a96c_files-c-p.patch b/SOURCES/github_2f57a96c_files-c-p.patch deleted file mode 100644 index 18c9255..0000000 --- a/SOURCES/github_2f57a96c_files-c-p.patch +++ /dev/null @@ -1,58 +0,0 @@ -commit 2f57a96ce27d8b121c2822de2a66c71b83bdad21 -Author: Dave Anderson -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 <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"); diff --git a/SOURCES/github_3141bba9.patch b/SOURCES/github_3141bba9.patch deleted file mode 100644 index 4629517..0000000 --- a/SOURCES/github_3141bba9.patch +++ /dev/null @@ -1,45 +0,0 @@ -commit 3141bba98af302e2a7c5e2a19203bb8a40b6aa63 -Author: Dave Anderson -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: - type: " - (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 diff --git a/SOURCES/github_361f050e_dev-d.patch b/SOURCES/github_361f050e_dev-d.patch deleted file mode 100644 index 0091f96..0000000 --- a/SOURCES/github_361f050e_dev-d.patch +++ /dev/null @@ -1,196 +0,0 @@ -commit 361f050e3148c6188afb45942e06d4a509852b86 -Author: Dave Anderson -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", diff --git a/SOURCES/github_46d21219_to_9446958f.patch b/SOURCES/github_46d21219_to_9446958f.patch deleted file mode 100644 index c871403..0000000 --- a/SOURCES/github_46d21219_to_9446958f.patch +++ /dev/null @@ -1,414 +0,0 @@ -commit 46d2121960d81354facf4e2558c81f82257b740e -Author: Dave Anderson -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 -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 -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:
- type: stack contents" followed by "bt: read of stack at
- 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 -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"); diff --git a/SOURCES/github_64dad6d0.patch b/SOURCES/github_64dad6d0.patch deleted file mode 100644 index 7f41a57..0000000 --- a/SOURCES/github_64dad6d0.patch +++ /dev/null @@ -1,34 +0,0 @@ - -commit 64dad6d0d60514498252e6071738fa1b4c12db8c -Author: Dave Anderson -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; - } diff --git a/SOURCES/github_6b93714b_cmdline.patch b/SOURCES/github_6b93714b_cmdline.patch deleted file mode 100644 index 0fe9a66..0000000 --- a/SOURCES/github_6b93714b_cmdline.patch +++ /dev/null @@ -1,39 +0,0 @@ -commit 6b93714b83d59ae4147b8ec3887261aca7fd6f65 -Author: Dave Anderson -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); diff --git a/SOURCES/github_8618ddd8_CONFIG_ARM64_USER_VA_BITS_52 b/SOURCES/github_8618ddd8_CONFIG_ARM64_USER_VA_BITS_52 deleted file mode 100644 index c15eddc..0000000 --- a/SOURCES/github_8618ddd8_CONFIG_ARM64_USER_VA_BITS_52 +++ /dev/null @@ -1,212 +0,0 @@ -commit 8618ddd817621c40c1f44f0ab6df7c7805234416 -Author: Dave Anderson -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= - kimage_voffset= -+ max_physmem_bits= - X86: - page_offset= - .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=", - " kimage_voffset=", -+ " max_physmem_bits=", - " X86:", - " page_offset=", - "", diff --git a/SOURCES/github_95daa11b.patch b/SOURCES/github_95daa11b.patch deleted file mode 100644 index b36d5ab..0000000 --- a/SOURCES/github_95daa11b.patch +++ /dev/null @@ -1,23 +0,0 @@ -commit 95daa11b82dfa6aa3e68ffc92e1282abc1b2b62a -Author: Dave Anderson -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", diff --git a/SOURCES/github_9b494b70_to_eb823b79.patch b/SOURCES/github_9b494b70_to_eb823b79.patch deleted file mode 100644 index 5723118..0000000 --- a/SOURCES/github_9b494b70_to_eb823b79.patch +++ /dev/null @@ -1,1233 +0,0 @@ - -commit 9b494b7006bcc7f3f0bf3be9e3c6d3a5e703a728 -Author: Dave Anderson -Date: Tue Jun 26 16:00:28 2018 -0400 - - Update for the "kmem -V" option to also dump the global entries that - are contained in the "vm_numa_stat" array that was introduced in - Linux 4.14. Also, the command output separates the "vm_zone_stat", - "vm_node_stat" and "vm_numa_stat" entries into separate sections with - "VM_ZONE_STAT", "VM_NODE_STAT" and "VM_NUMA_STAT" headers. Without - the patch, the "vm_zone_stat" and "vm_node_stat" entries are listed - together under a "VM_STAT" header. - (anderson@redhat.com) - -diff --git a/help.c b/help.c -index 5a52650..638c6ec 100644 ---- a/help.c -+++ b/help.c -@@ -6451,9 +6451,10 @@ char *help_kmem[] = { - " -C same as -c, but also dumps all pages in the page_hash_table.", - " -i displays general memory usage information", - " -v displays the mapped virtual memory regions allocated by vmalloc().", --" -V displays the kernel vm_stat table if it exists, the cumulative", --" page_states counter values if they exist, and/or the cumulative", --" vm_event_states counter values if they exist.", -+" -V displays the kernel vm_stat table if it exists, or in more recent", -+" kernels, the vm_zone_stat, vm_node_stat and vm_numa_stat tables,", -+" the cumulative page_states counter values if they exist, and/or ", -+" the cumulative, vm_event_states counter values if they exist.", - " -n display memory node data (if supported).", - " -z displays per-zone memory statistics.", - " -o displays each cpu's offset value that is added to per-cpu symbol", -@@ -6761,24 +6762,69 @@ char *help_kmem[] = { - " f63d5cc0 f6287b80 f83c2000 - f84c3000 1052672", - " ...", - " ", --" Dump the vm_table contents:\n", -+" Dump the virtual memory statistics:\n", - " %s> kmem -V", --" NR_ANON_PAGES: 38989", --" NR_FILE_MAPPED: 3106", --" NR_FILE_PAGES: 169570", --" NR_SLAB: 32439", --" NR_PAGETABLE: 1181", --" NR_FILE_DIRTY: 4633", --" NR_WRITEBACK: 0", --" NR_UNSTABLE_NFS: 0", --" NR_BOUNCE: 0", --" NUMA_HIT: 63545992", --" NUMA_MISS: 0", --" NUMA_FOREIGN: 0", --" NUMA_INTERLEAVE_HIT: 24002", --" NUMA_LOCAL: 63545992", --" NUMA_OTHER: 0", --" ", -+" VM_ZONE_STAT:", -+" NR_FREE_PAGES: 30085", -+" NR_ZONE_INACTIVE_ANON: 1985", -+" NR_ZONE_ACTIVE_ANON: 338275", -+" NR_ZONE_INACTIVE_FILE: 19760", -+" NR_ZONE_ACTIVE_FILE: 12018", -+" NR_ZONE_UNEVICTABLE: 0", -+" NR_ZONE_WRITE_PENDING: 4", -+" NR_MLOCK: 0", -+" NR_PAGETABLE: 1562", -+" NR_KERNEL_STACK_KB: 1728", -+" NR_BOUNCE: 0", -+" NR_FREE_CMA_PAGES: 0", -+" ", -+" VM_NODE_STAT:", -+" NR_INACTIVE_ANON: 1985", -+" NR_ACTIVE_ANON: 338275", -+" NR_INACTIVE_FILE: 19760", -+" NR_ACTIVE_FILE: 12018", -+" NR_UNEVICTABLE: 0", -+" NR_SLAB_RECLAIMABLE: 3111", -+" NR_SLAB_UNRECLAIMABLE: 3039", -+" NR_ISOLATED_ANON: 0", -+" NR_ISOLATED_FILE: 0", -+" WORKINGSET_REFAULT: 0", -+" WORKINGSET_ACTIVATE: 0", -+" WORKINGSET_NODERECLAIM: 0", -+" NR_ANON_MAPPED: 338089", -+" NR_FILE_MAPPED: 8102", -+" NR_FILE_PAGES: 33949", -+" NR_FILE_DIRTY: 4", -+" NR_WRITEBACK: 0", -+" NR_WRITEBACK_TEMP: 0", -+" NR_SHMEM: 2171", -+" NR_SHMEM_THPS: 0", -+" NR_SHMEM_PMDMAPPED: 0", -+" NR_ANON_THPS: 86", -+" NR_UNSTABLE_NFS: 0", -+" NR_VMSCAN_WRITE: 0", -+" NR_VMSCAN_IMMEDIATE: 0", -+" NR_DIRTIED: 155", -+" NR_WRITTEN: 75", -+" ", -+" VM_NUMA_STAT:", -+" NUMA_HIT: 575409", -+" NUMA_MISS: 0", -+" NUMA_FOREIGN: 0", -+" NUMA_INTERLEAVE_HIT: 12930", -+" NUMA_LOCAL: 575409", -+" NUMA_OTHER: 0", -+" ", -+" VM_EVENT_STATES:", -+" PGPGIN: 282492", -+" PGPGOUT: 6773", -+" PSWPIN: 0", -+" PSWPOUT: 0", -+" PGALLOC_DMA: 0", -+" PGALLOC_DMA32: 693092", -+" PGALLOC_NORMAL: 0", -+" ...", -+" ", - " Display hugepage hstate information: \n", - " %s> kmem -h", - " HSTATE SIZE FREE TOTAL NAME", -diff --git a/memory.c b/memory.c -index 5c0a853..81ed689 100644 ---- a/memory.c -+++ b/memory.c -@@ -17422,7 +17422,7 @@ vm_stat_init(void) - int c ATTRIBUTE_UNUSED; - struct gnu_request *req; - char *start; -- long enum_value, zc = -1; -+ long enum_value, zone_cnt = -1, node_cnt = -1; - int split_vmstat = 0, ni = 0; - - if (vt->flags & VM_STAT) -@@ -17451,11 +17451,21 @@ vm_stat_init(void) - } else if (symbol_exists("vm_zone_stat") && - get_symbol_type("vm_zone_stat", - NULL, NULL) == TYPE_CODE_ARRAY) { -- vt->nr_vm_stat_items = -- get_array_length("vm_zone_stat", NULL, 0) -- + get_array_length("vm_node_stat", NULL, 0); -- split_vmstat = 1; -- enumerator_value("NR_VM_ZONE_STAT_ITEMS", &zc); -+ if (symbol_exists("vm_numa_stat")) { -+ vt->nr_vm_stat_items = -+ get_array_length("vm_zone_stat", NULL, 0) -+ + get_array_length("vm_node_stat", NULL, 0) -+ + get_array_length("vm_numa_stat", NULL, 0); -+ split_vmstat = 2; -+ enumerator_value("NR_VM_ZONE_STAT_ITEMS", &zone_cnt); -+ enumerator_value("NR_VM_NODE_STAT_ITEMS", &node_cnt); -+ } else { -+ vt->nr_vm_stat_items = -+ get_array_length("vm_zone_stat", NULL, 0) -+ + get_array_length("vm_node_stat", NULL, 0); -+ split_vmstat = 1; -+ enumerator_value("NR_VM_ZONE_STAT_ITEMS", &zone_cnt); -+ } - } else { - goto bailout; - } -@@ -17468,13 +17478,20 @@ vm_stat_init(void) - req->flags = GNU_PRINT_ENUMERATORS; - gdb_interface(req); - -- if (split_vmstat) { -+ if (split_vmstat >= 1) { - req->command = GNU_GET_DATATYPE; - req->name = "node_stat_item"; - req->flags = GNU_PRINT_ENUMERATORS; - gdb_interface(req); - } - -+ if (split_vmstat == 2) { -+ req->command = GNU_GET_DATATYPE; -+ req->name = "numa_stat_item"; -+ req->flags = GNU_PRINT_ENUMERATORS; -+ gdb_interface(req); -+ } -+ - FREEBUF(req); - - stringlen = 1; -@@ -17488,15 +17505,20 @@ vm_stat_init(void) - c = parse_line(buf, arglist); - if ((!split_vmstat && - STREQ(arglist[0], "NR_VM_ZONE_STAT_ITEMS")) || -- (split_vmstat && -- STREQ(arglist[0], "NR_VM_NODE_STAT_ITEMS"))) { -+ ((split_vmstat == 1) && -+ STREQ(arglist[0], "NR_VM_NODE_STAT_ITEMS")) || -+ ((split_vmstat == 2) && -+ STREQ(arglist[0], "NR_VM_NUMA_STAT_ITEMS"))) { - if (LKCD_KERNTYPES()) - vt->nr_vm_stat_items = - MAX(atoi(arglist[2]), count); - break; -- } else if (split_vmstat && -+ } else if ((split_vmstat == 1) && - STREQ(arglist[0], "NR_VM_ZONE_STAT_ITEMS")) { - continue; -+ } else if ((split_vmstat == 2) && -+ STREQ(arglist[0], "NR_VM_NODE_STAT_ITEMS")) { -+ continue; - } else { - stringlen += strlen(arglist[0]) + 1; - count++; -@@ -17523,8 +17545,11 @@ vm_stat_init(void) - } - - i = ni + enum_value; -- if (!ni && (enum_value == zc)) { -- ni = zc; -+ if (!ni && (enum_value == zone_cnt)) { -+ ni = zone_cnt; -+ continue; -+ } else if ((ni == zone_cnt) && (enum_value == node_cnt)) { -+ ni += node_cnt; - continue; - } - -@@ -17556,8 +17581,8 @@ dump_vm_stat(char *item, long *retval, ulong zone) - char *buf; - ulong *vp; - ulong location; -- int i, maxlen, len; -- long tc, zc = 0, nc = 0; -+ int i, maxlen, len, node_start = -1, numa_start = 1; -+ long total_cnt, zone_cnt = 0, node_cnt = 0, numa_cnt = 0; - int split_vmstat = 0; - - if (!vm_stat_init()) { -@@ -17570,48 +17595,86 @@ dump_vm_stat(char *item, long *retval, ulong zone) - - buf = GETBUF(sizeof(ulong) * vt->nr_vm_stat_items); - -- if (symbol_exists("vm_node_stat") && symbol_exists("vm_zone_stat")) -+ if (symbol_exists("vm_node_stat") && symbol_exists("vm_zone_stat") && -+ symbol_exists("vm_numa_stat")) -+ split_vmstat = 2; -+ else if (symbol_exists("vm_node_stat") && symbol_exists("vm_zone_stat")) - split_vmstat = 1; - else - location = zone ? zone : symbol_value("vm_stat"); - -- if (split_vmstat) { -- enumerator_value("NR_VM_ZONE_STAT_ITEMS", &zc); -+ if (split_vmstat == 1) { -+ enumerator_value("NR_VM_ZONE_STAT_ITEMS", &zone_cnt); - location = zone ? zone : symbol_value("vm_zone_stat"); - readmem(location, KVADDR, buf, -- sizeof(ulong) * zc, -+ sizeof(ulong) * zone_cnt, - "vm_zone_stat", FAULT_ON_ERROR); - if (!zone) { - location = symbol_value("vm_node_stat"); -- enumerator_value("NR_VM_NODE_STAT_ITEMS", &nc); -- readmem(location, KVADDR, buf + (sizeof(ulong) * zc), -- sizeof(ulong) * nc, -+ enumerator_value("NR_VM_NODE_STAT_ITEMS", &node_cnt); -+ readmem(location, KVADDR, buf + (sizeof(ulong) * zone_cnt), -+ sizeof(ulong) * node_cnt, - "vm_node_stat", FAULT_ON_ERROR); - } -- tc = zc + nc; -+ node_start = zone_cnt; -+ total_cnt = zone_cnt + node_cnt; -+ } else if (split_vmstat == 2) { -+ enumerator_value("NR_VM_ZONE_STAT_ITEMS", &zone_cnt); -+ location = zone ? zone : symbol_value("vm_zone_stat"); -+ readmem(location, KVADDR, buf, -+ sizeof(ulong) * zone_cnt, -+ "vm_zone_stat", FAULT_ON_ERROR); -+ if (!zone) { -+ location = symbol_value("vm_node_stat"); -+ enumerator_value("NR_VM_NODE_STAT_ITEMS", &node_cnt); -+ readmem(location, KVADDR, buf + (sizeof(ulong) * zone_cnt), -+ sizeof(ulong) * node_cnt, -+ "vm_node_stat", FAULT_ON_ERROR); -+ } -+ node_start = zone_cnt; -+ if (!zone) { -+ location = symbol_value("vm_numa_stat"); -+ enumerator_value("NR_VM_NUMA_STAT_ITEMS", &numa_cnt); -+ readmem(location, KVADDR, buf + (sizeof(ulong) * (zone_cnt+node_cnt)), -+ sizeof(ulong) * numa_cnt, -+ "vm_numa_stat", FAULT_ON_ERROR); -+ } -+ numa_start = zone_cnt+node_cnt; -+ total_cnt = zone_cnt + node_cnt + numa_cnt; - } else { - readmem(location, KVADDR, buf, - sizeof(ulong) * vt->nr_vm_stat_items, - "vm_stat", FAULT_ON_ERROR); -- tc = vt->nr_vm_stat_items; -+ total_cnt = vt->nr_vm_stat_items; - } - - if (!item) { -- if (!zone) -- fprintf(fp, " VM_STAT:\n"); -- for (i = maxlen = 0; i < tc; i++) -+ if (!zone) { -+ if (symbol_exists("vm_zone_stat")) -+ fprintf(fp, " VM_ZONE_STAT:\n"); -+ else -+ fprintf(fp, " VM_STAT:\n"); -+ } -+ for (i = maxlen = 0; i < total_cnt; i++) - if ((len = strlen(vt->vm_stat_items[i])) > maxlen) - maxlen = len; - vp = (ulong *)buf; -- for (i = 0; i < tc; i++) -+ for (i = 0; i < total_cnt; i++) { -+ if (!zone) { -+ if ((i == node_start) && symbol_exists("vm_node_stat")) -+ fprintf(fp, "\n VM_NODE_STAT:\n"); -+ if ((i == numa_start) && symbol_exists("vm_numa_stat")) -+ fprintf(fp, "\n VM_NUMA_STAT:\n"); -+ } - fprintf(fp, "%s%s: %ld\n", - space(maxlen - strlen(vt->vm_stat_items[i])), - vt->vm_stat_items[i], vp[i]); -+ } - return TRUE; - } - - vp = (ulong *)buf; -- for (i = 0; i < tc; i++) { -+ for (i = 0; i < total_cnt; i++) { - if (STREQ(vt->vm_stat_items[i], item)) { - *retval = vp[i]; - return TRUE; - -commit f294197b5511537e6b14d5e1db324f4fc4fdd3f8 -Author: Dave Anderson -Date: Fri Jul 6 10:57:50 2018 -0400 - - Support for the "bpf" command on RHEL 3.10.0-913.el7 and later - 3.10-based RHEL7 kernels, which contain a backport of the upstream - eBPF code, but still use the older, pre-4.11, IDR facility that does - not use radix trees for linking the active bpf_prog and bpf_map - structures. Without the patch, the command indicates "bpf: command - not supported or applicable on this architecture or kernel". - (anderson@redhat.com) - -diff --git a/bpf.c b/bpf.c -index 427263d..8871b76 100644 ---- a/bpf.c -+++ b/bpf.c -@@ -45,6 +45,10 @@ static void bpf_prog_gpl_compatible(char *, ulong); - static void dump_xlated_plain(void *, unsigned int, int); - static void print_boot_time(unsigned long long, char *, unsigned int); - -+static int do_old_idr(int, ulong, struct radix_tree_pair *); -+#define OLD_IDR_INIT (1) -+#define OLD_IDR_COUNT (2) -+#define OLD_IDR_GATHER (3) - - #define PROG_ID (0x1) - #define MAP_ID (0x2) -@@ -167,7 +171,6 @@ bpf_init(struct bpf_info *bpf) - !VALID_STRUCT(bpf_map) || - !VALID_STRUCT(bpf_insn) || - INVALID_MEMBER(bpf_prog_aux) || -- INVALID_MEMBER(idr_idr_rt) || - INVALID_MEMBER(bpf_prog_type) || - INVALID_MEMBER(bpf_prog_tag) || - INVALID_MEMBER(bpf_prog_jited_len) || -@@ -210,6 +213,9 @@ bpf_init(struct bpf_info *bpf) - mkstring(buf2, VADDR_PRLEN, CENTER|LJUST, "BPF_MAP"), - mkstring(buf3, bpf->bpf_map_map_type_size, CENTER|LJUST, "BPF_MAP_TYPE")); - -+ if (INVALID_MEMBER(idr_idr_rt)) -+ do_old_idr(OLD_IDR_INIT, 0, NULL); -+ - bpf->status = TRUE; - break; - -@@ -220,24 +226,38 @@ bpf_init(struct bpf_info *bpf) - command_not_supported(); - } - -- bpf->progs = do_radix_tree(symbol_value("prog_idr") + OFFSET(idr_idr_rt), -- RADIX_TREE_COUNT, NULL); -+ if (VALID_MEMBER(idr_idr_rt)) -+ bpf->progs = do_radix_tree(symbol_value("prog_idr") + OFFSET(idr_idr_rt), -+ RADIX_TREE_COUNT, NULL); -+ else -+ bpf->progs = do_old_idr(OLD_IDR_COUNT, symbol_value("prog_idr"), NULL); -+ - if (bpf->progs) { - len = sizeof(struct radix_tree_pair) * (bpf->progs+1); - bpf->proglist = (struct radix_tree_pair *)GETBUF(len); - bpf->proglist[0].index = bpf->progs; -- bpf->progs = do_radix_tree(symbol_value("prog_idr") + OFFSET(idr_idr_rt), -- RADIX_TREE_GATHER, bpf->proglist); -+ if (VALID_MEMBER(idr_idr_rt)) -+ bpf->progs = do_radix_tree(symbol_value("prog_idr") + OFFSET(idr_idr_rt), -+ RADIX_TREE_GATHER, bpf->proglist); -+ else -+ bpf->progs = do_old_idr(OLD_IDR_GATHER, symbol_value("prog_idr"), bpf->proglist); - } - -- bpf->maps = do_radix_tree(symbol_value("map_idr") + OFFSET(idr_idr_rt), -- RADIX_TREE_COUNT, NULL); -+ if (VALID_MEMBER(idr_idr_rt)) -+ bpf->maps = do_radix_tree(symbol_value("map_idr") + OFFSET(idr_idr_rt), -+ RADIX_TREE_COUNT, NULL); -+ else -+ bpf->maps = do_old_idr(OLD_IDR_COUNT, symbol_value("map_idr"), NULL); -+ - if (bpf->maps) { - len = sizeof(struct radix_tree_pair) * (bpf->maps+1); - bpf->maplist = (struct radix_tree_pair *)GETBUF(len); - bpf->maplist[0].index = bpf->maps; -- bpf->maps = do_radix_tree(symbol_value("map_idr") + OFFSET(idr_idr_rt), -- RADIX_TREE_GATHER, bpf->maplist); -+ if (VALID_MEMBER(idr_idr_rt)) -+ bpf->maps = do_radix_tree(symbol_value("map_idr") + OFFSET(idr_idr_rt), -+ RADIX_TREE_GATHER, bpf->maplist); -+ else -+ bpf->maps = do_old_idr(OLD_IDR_GATHER, symbol_value("map_idr"), bpf->maplist); - } - - bpf->bpf_prog_buf = GETBUF(SIZE(bpf_prog)); -@@ -538,8 +558,10 @@ do_map_only: - } - - bailout: -- FREEBUF(bpf->proglist); -- FREEBUF(bpf->maplist); -+ if (bpf->proglist) -+ FREEBUF(bpf->proglist); -+ if (bpf->maplist) -+ FREEBUF(bpf->maplist); - FREEBUF(bpf->bpf_prog_buf); - FREEBUF(bpf->bpf_prog_aux_buf); - FREEBUF(bpf->bpf_map_buf); -@@ -1255,3 +1277,50 @@ print_boot_time(unsigned long long nsecs, char *buf, unsigned int size) - sprintf(buf, "(unknown)"); - #endif - } -+ -+/* -+ * Borrow the old (pre-radix_tree) IDR facility code used by -+ * the ipcs command. -+ */ -+static int -+do_old_idr(int cmd, ulong idr, struct radix_tree_pair *rtp) -+{ -+ int i, max, cur, next_id, total = 0; -+ ulong entry; -+ -+ switch (cmd) -+ { -+ case OLD_IDR_INIT: -+ ipcs_init(); -+ break; -+ -+ case OLD_IDR_COUNT: -+ readmem(idr + OFFSET(idr_cur), KVADDR, &cur, -+ sizeof(int), "idr.cur", FAULT_ON_ERROR); -+ for (total = next_id = 0; next_id < cur; next_id++) { -+ entry = idr_find(idr, next_id); -+ if (entry == 0) -+ continue; -+ total++; -+ } -+ break; -+ -+ case OLD_IDR_GATHER: -+ max = rtp[0].index; -+ readmem(idr + OFFSET(idr_cur), KVADDR, &cur, -+ sizeof(int), "idr.cur", FAULT_ON_ERROR); -+ for (i = total = next_id = 0; next_id < cur; next_id++) { -+ entry = idr_find(idr, next_id); -+ if (entry == 0) -+ continue; -+ total++; -+ rtp[i].index = next_id; -+ rtp[i].value = (void *)entry; -+ if (++i == max) -+ break; -+ } -+ break; -+ } -+ -+ return total; -+} -diff --git a/defs.h b/defs.h -index e6e3850..b05aecc 100644 ---- a/defs.h -+++ b/defs.h -@@ -2031,6 +2031,7 @@ struct offset_table { /* stash of commonly-used offsets */ - long bpf_prog_aux_load_time; - long bpf_prog_aux_user; - long user_struct_uid; -+ long idr_cur; - }; - - struct size_table { /* stash of commonly-used sizes */ -@@ -5591,6 +5592,12 @@ enum { - void dev_init(void); - void dump_dev_table(void); - -+/* -+ * ipcs.c -+ */ -+void ipcs_init(void); -+ulong idr_find(ulong, int); -+ - #ifdef ARM - void arm_init(int); - void arm_dump_machdep_table(ulong); -diff --git a/ipcs.c b/ipcs.c -index ef51fdd..80f78e4 100644 ---- a/ipcs.c -+++ b/ipcs.c -@@ -79,13 +79,11 @@ struct ipcs_table { - * function declaration - */ - --static void ipcs_init(void); - static int dump_shared_memory(int, ulong, int, ulong); - static int dump_semaphore_arrays(int, ulong, int, ulong); - static int dump_message_queues(int, ulong, int, ulong); - static int ipc_search_idr(ulong, int, ulong, int (*)(ulong, int, ulong, int, int), int); - static int ipc_search_array(ulong, int, ulong, int (*)(ulong, int, ulong, int, int), int); --static ulong idr_find(ulong, int); - static int dump_shm_info(ulong, int, ulong, int, int); - static int dump_sem_info(ulong, int, ulong, int, int); - static int dump_msg_info(ulong, int, ulong, int, int); -@@ -101,7 +99,7 @@ static void gather_radix_tree_entries(ulong); - */ - static struct ipcs_table ipcs_table = { 0 }; - --static void -+void - ipcs_init(void) - { - if (ipcs_table.init_flags & IPCS_INIT) { -@@ -119,6 +117,7 @@ ipcs_init(void) - MEMBER_OFFSET_INIT(idr_layer_layer, "idr_layer", "layer"); - MEMBER_OFFSET_INIT(idr_layer_ary, "idr_layer", "ary"); - MEMBER_OFFSET_INIT(idr_top, "idr", "top"); -+ MEMBER_OFFSET_INIT(idr_cur, "idr", "cur"); - MEMBER_OFFSET_INIT(ipc_id_ary_p, "ipc_id_ary", "p"); - MEMBER_OFFSET_INIT(ipc_ids_entries, "ipc_ids", "entries"); - MEMBER_OFFSET_INIT(ipc_ids_max_id, "ipc_ids", "max_id"); -@@ -188,7 +187,10 @@ ipcs_init(void) - ipcs_table.shm_f_op_huge_addr = -1; - } - -- if (BITS32()) -+ if (VALID_MEMBER(idr_layer_ary) && -+ get_array_length("idr_layer.ary", NULL, 0) > 64) -+ ipcs_table.idr_bits = 8; -+ else if (BITS32()) - ipcs_table.idr_bits = 5; - else if (BITS64()) - ipcs_table.idr_bits = 6; -@@ -635,7 +637,7 @@ ipc_search_idr(ulong ipc_ids_p, int specified, ulong specified_value, int (*fn)( - /* - * search every idr_layer - */ --static ulong -+ulong - idr_find(ulong idp, int id) - { - ulong idr_layer_p; -diff --git a/symbols.c b/symbols.c -index bf55319..8ff1430 100644 ---- a/symbols.c -+++ b/symbols.c -@@ -10055,6 +10055,8 @@ dump_offset_table(char *spec, ulong makestruct) - OFFSET(idr_layers)); - fprintf(fp, " idr_top: %ld\n", - OFFSET(idr_top)); -+ fprintf(fp, " idr_cur: %ld\n", -+ OFFSET(idr_cur)); - fprintf(fp, " ipc_id_ary_p: %ld\n", - OFFSET(ipc_id_ary_p)); - fprintf(fp, " ipc_ids_entries: %ld\n", - -commit b21633026a725a10b9394aabc65d8c57d5bbe33a -Author: Dave Anderson -Date: Tue Jul 10 15:24:38 2018 -0400 - - Third phase of support for x86_64 5-level page tables in Linux 4.17 - and later kernels. With this patch, the usage of 5-level page tables - is automatically detected on live systems and when running against - vmcores that contain the new "NUMBER(pgtable_l5_enabled)" VMCOREINFO - entry. Without the patch, the "--machdep vm=5level" command line - option is required. - (douly.fnst@cn.fujitsu.com, anderson@redhat.com) - -diff --git a/x86_64.c b/x86_64.c -index 6d1ae2f..b07d6f2 100644 ---- a/x86_64.c -+++ b/x86_64.c -@@ -294,25 +294,6 @@ x86_64_init(int when) - machdep->machspec->pgdir_shift = PGDIR_SHIFT; - machdep->machspec->ptrs_per_pgd = PTRS_PER_PGD; - break; -- -- case VM_5LEVEL: -- machdep->machspec->userspace_top = USERSPACE_TOP_5LEVEL; -- machdep->machspec->page_offset = PAGE_OFFSET_5LEVEL; -- machdep->machspec->vmalloc_start_addr = VMALLOC_START_ADDR_5LEVEL; -- machdep->machspec->vmalloc_end = VMALLOC_END_5LEVEL; -- machdep->machspec->modules_vaddr = MODULES_VADDR_5LEVEL; -- machdep->machspec->modules_end = MODULES_END_5LEVEL; -- machdep->machspec->vmemmap_vaddr = VMEMMAP_VADDR_5LEVEL; -- machdep->machspec->vmemmap_end = VMEMMAP_END_5LEVEL; -- if (symbol_exists("vmemmap_populate")) -- machdep->flags |= VMEMMAP; -- machdep->machspec->physical_mask_shift = __PHYSICAL_MASK_SHIFT_5LEVEL; -- machdep->machspec->pgdir_shift = PGDIR_SHIFT_5LEVEL; -- machdep->machspec->ptrs_per_pgd = PTRS_PER_PGD_5LEVEL; -- if ((machdep->machspec->p4d = (char *)malloc(PAGESIZE())) == NULL) -- error(FATAL, "cannot malloc p4d space."); -- machdep->machspec->last_p4d_read = 0; -- machdep->uvtop = x86_64_uvtop_level4; /* 5-level is optional per-task */ - } - machdep->kvbase = (ulong)PAGE_OFFSET; - machdep->identity_map_base = (ulong)PAGE_OFFSET; -@@ -346,6 +327,43 @@ x86_64_init(int when) - break; - - case POST_RELOC: -+ /* Check for 5-level paging */ -+ if (!(machdep->flags & VM_5LEVEL)) { -+ int l5_enabled = 0; -+ if ((string = pc->read_vmcoreinfo("NUMBER(pgtable_l5_enabled)"))) { -+ l5_enabled = atoi(string); -+ free(string); -+ } else if (kernel_symbol_exists("__pgtable_l5_enabled")) -+ readmem(symbol_value("__pgtable_l5_enabled"), KVADDR, -+ &l5_enabled, sizeof(int), "__pgtable_l5_enabled", -+ FAULT_ON_ERROR); -+ -+ if (l5_enabled) -+ machdep->flags |= VM_5LEVEL; -+ } -+ if (machdep->flags & VM_5LEVEL) { -+ machdep->machspec->userspace_top = USERSPACE_TOP_5LEVEL; -+ machdep->machspec->page_offset = PAGE_OFFSET_5LEVEL; -+ machdep->machspec->vmalloc_start_addr = VMALLOC_START_ADDR_5LEVEL; -+ machdep->machspec->vmalloc_end = VMALLOC_END_5LEVEL; -+ machdep->machspec->modules_vaddr = MODULES_VADDR_5LEVEL; -+ machdep->machspec->modules_end = MODULES_END_5LEVEL; -+ machdep->machspec->vmemmap_vaddr = VMEMMAP_VADDR_5LEVEL; -+ machdep->machspec->vmemmap_end = VMEMMAP_END_5LEVEL; -+ if (symbol_exists("vmemmap_populate")) -+ machdep->flags |= VMEMMAP; -+ machdep->machspec->physical_mask_shift = __PHYSICAL_MASK_SHIFT_5LEVEL; -+ machdep->machspec->pgdir_shift = PGDIR_SHIFT_5LEVEL; -+ machdep->machspec->ptrs_per_pgd = PTRS_PER_PGD_5LEVEL; -+ if ((machdep->machspec->p4d = (char *)malloc(PAGESIZE())) == NULL) -+ error(FATAL, "cannot malloc p4d space."); -+ machdep->machspec->last_p4d_read = 0; -+ machdep->uvtop = x86_64_uvtop_level4; /* 5-level is optional per-task */ -+ machdep->kvbase = (ulong)PAGE_OFFSET; -+ machdep->identity_map_base = (ulong)PAGE_OFFSET; -+ -+ } -+ - /* - * Check for CONFIG_RANDOMIZE_MEMORY, and set page_offset here. - * The remainder of the virtual address range setups will get - -commit 6596f1121b89162f96d1e1825c2905b83b59bec1 -Author: Dave Anderson -Date: Wed Jul 11 16:25:59 2018 -0400 - - The existing "list" command uses a hash table to detect duplicate - items as it traverses the list. The hash table approach has worked - well for many years. However, with increasing memory sizes and list - sizes, the overhead of the hash table can be substantial, often - leading to commands running for a very long time. For large lists, - we have found that the existing hash based approach may slow the - system to a crawl and possibly never complete. You can turn off - the hash with "set hash off" but then there is no loop detection; in - that case, loop detection must be done manually after dumping the - list to disk or some other method. This patch is an implementation - of the cycle detection algorithm from R. P. Brent as an alternative - algorithm for the "list" command. The algorithm both avoids the - overhead of the hash table and yet is able to detect a loop. In - addition, further loop characteristics are printed, such as the - distance to the start of the loop as well as the loop length. - An excellent description of the algorithm can be found here on - the crash-utility mailing list: - - https://www.redhat.com/archives/crash-utility/2018-July/msg00019.html - - A new "list -B" option has been added to the "list" command to - invoke this new algorithm rather than using the hash table. In - addition to low memory usage, the output of the list command is - slightly different when a loop is detected. In addition to printing - the first duplicate entry, the length of the loop, and the distance - to the loop is output. - (dwysocha@redhat.com) - -diff --git a/defs.h b/defs.h -index b05aecc..5af82be 100644 ---- a/defs.h -+++ b/defs.h -@@ -2491,6 +2491,7 @@ struct list_data { /* generic structure used by do_list() to walk */ - #define CALLBACK_RETURN (VERBOSE << 12) - #define LIST_PARSE_MEMBER (VERBOSE << 13) - #define LIST_READ_MEMBER (VERBOSE << 14) -+#define LIST_BRENT_ALGO (VERBOSE << 15) - - struct tree_data { - ulong flags; -@@ -4944,6 +4945,7 @@ char *shift_string_right(char *, int); - int bracketed(char *, char *, int); - void backspace(int); - int do_list(struct list_data *); -+int do_list_no_hash(struct list_data *); - struct radix_tree_ops { - void (*entry)(ulong node, ulong slot, const char *path, - ulong index, void *private); -diff --git a/help.c b/help.c -index 638c6ec..54bf9b4 100644 ---- a/help.c -+++ b/help.c -@@ -5724,7 +5724,7 @@ char *help__list[] = { - "list", - "linked list", - "[[-o] offset][-e end][-[s|S] struct[.member[,member] [-l offset]] -[x|d]]" --"\n [-r|-h|-H] start", -+"\n [-r|-B] [-h|-H] start", - " ", - " This command dumps the contents of a linked list. The entries in a linked", - " list are typically data structures that are tied together in one of two", -@@ -5822,6 +5822,12 @@ char *help__list[] = { - " -r For a list linked with list_head structures, traverse the list", - " in the reverse order by using the \"prev\" pointer instead", - " of \"next\".", -+" -B Use the algorithm from R. P. Brent to detect loops instead of", -+" using a hash table. This algorithm uses a tiny fixed amount of", -+" memory and so is especially helpful for longer lists. The output", -+" is slightly different than the normal list output as it will", -+" print the length of the loop, the start of the loop, and the", -+" first duplicate in the list.", - " ", - " The meaning of the \"start\" argument, which can be expressed symbolically,", - " in hexadecimal format, or an expression evaluating to an address, depends", -diff --git a/tools.c b/tools.c -index 1a83643..634aec6 100644 ---- a/tools.c -+++ b/tools.c -@@ -3266,9 +3266,12 @@ cmd_list(void) - BZERO(ld, sizeof(struct list_data)); - struct_list_offset = 0; - -- while ((c = getopt(argcnt, args, "Hhrs:S:e:o:xdl:")) != EOF) { -+ while ((c = getopt(argcnt, args, "BHhrs:S:e:o:xdl:")) != EOF) { - switch(c) - { -+ case 'B': -+ ld->flags |= LIST_BRENT_ALGO; -+ break; - case 'H': - ld->flags |= LIST_HEAD_FORMAT; - ld->flags |= LIST_HEAD_POINTER; -@@ -3516,9 +3519,13 @@ next_arg: - ld->flags &= ~(LIST_OFFSET_ENTERED|LIST_START_ENTERED); - ld->flags |= VERBOSE; - -- hq_open(); -- c = do_list(ld); -- hq_close(); -+ if (ld->flags & LIST_BRENT_ALGO) -+ c = do_list_no_hash(ld); -+ else { -+ hq_open(); -+ c = do_list(ld); -+ hq_close(); -+ } - - if (ld->structname_args) - FREEBUF(ld->structname); -@@ -3862,6 +3869,283 @@ do_list(struct list_data *ld) - return count; - } - -+static void -+do_list_debug_entry(struct list_data *ld) -+{ -+ int i, others; -+ -+ if (CRASHDEBUG(1)) { -+ others = 0; -+ console(" flags: %lx (", ld->flags); -+ if (ld->flags & VERBOSE) -+ console("%sVERBOSE", others++ ? "|" : ""); -+ if (ld->flags & LIST_OFFSET_ENTERED) -+ console("%sLIST_OFFSET_ENTERED", others++ ? "|" : ""); -+ if (ld->flags & LIST_START_ENTERED) -+ console("%sLIST_START_ENTERED", others++ ? "|" : ""); -+ if (ld->flags & LIST_HEAD_FORMAT) -+ console("%sLIST_HEAD_FORMAT", others++ ? "|" : ""); -+ if (ld->flags & LIST_HEAD_POINTER) -+ console("%sLIST_HEAD_POINTER", others++ ? "|" : ""); -+ if (ld->flags & RETURN_ON_DUPLICATE) -+ console("%sRETURN_ON_DUPLICATE", others++ ? "|" : ""); -+ if (ld->flags & RETURN_ON_LIST_ERROR) -+ console("%sRETURN_ON_LIST_ERROR", others++ ? "|" : ""); -+ if (ld->flags & RETURN_ON_LIST_ERROR) -+ console("%sRETURN_ON_LIST_ERROR", others++ ? "|" : ""); -+ if (ld->flags & LIST_STRUCT_RADIX_10) -+ console("%sLIST_STRUCT_RADIX_10", others++ ? "|" : ""); -+ if (ld->flags & LIST_STRUCT_RADIX_16) -+ console("%sLIST_STRUCT_RADIX_16", others++ ? "|" : ""); -+ if (ld->flags & LIST_ALLOCATE) -+ console("%sLIST_ALLOCATE", others++ ? "|" : ""); -+ if (ld->flags & LIST_CALLBACK) -+ console("%sLIST_CALLBACK", others++ ? "|" : ""); -+ if (ld->flags & CALLBACK_RETURN) -+ console("%sCALLBACK_RETURN", others++ ? "|" : ""); -+ console(")\n"); -+ console(" start: %lx\n", ld->start); -+ console(" member_offset: %ld\n", ld->member_offset); -+ console(" list_head_offset: %ld\n", ld->list_head_offset); -+ console(" end: %lx\n", ld->end); -+ console(" searchfor: %lx\n", ld->searchfor); -+ console(" structname_args: %lx\n", ld->structname_args); -+ if (!ld->structname_args) -+ console(" structname: (unused)\n"); -+ for (i = 0; i < ld->structname_args; i++) -+ console(" structname[%d]: %s\n", i, ld->structname[i]); -+ console(" header: %s\n", ld->header); -+ console(" list_ptr: %lx\n", (ulong)ld->list_ptr); -+ console(" callback_func: %lx\n", (ulong)ld->callback_func); -+ console(" callback_data: %lx\n", (ulong)ld->callback_data); -+ console("struct_list_offset: %lx\n", ld->struct_list_offset); -+ } -+} -+ -+ -+static void -+do_list_output_struct(struct list_data *ld, ulong next, ulong offset, -+ unsigned int radix, struct req_entry **e) -+{ -+ int i; -+ -+ for (i = 0; i < ld->structname_args; i++) { -+ switch (count_chars(ld->structname[i], '.')) -+ { -+ case 0: -+ dump_struct(ld->structname[i], -+ next - offset, radix); -+ break; -+ default: -+ if (ld->flags & LIST_PARSE_MEMBER) -+ dump_struct_members(ld, i, next); -+ else if (ld->flags & LIST_READ_MEMBER) -+ dump_struct_members_fast(e[i], -+ radix, next - offset); -+ break; -+ } -+ } -+} -+ -+static int -+do_list_no_hash_readmem(struct list_data *ld, ulong *next_ptr, -+ ulong readflag) -+{ -+ if (!readmem(*next_ptr + ld->member_offset, KVADDR, next_ptr, -+ sizeof(void *), "list entry", readflag)) { -+ error(INFO, "\ninvalid list entry: %lx\n", *next_ptr); -+ return -1; -+ } -+ return 0; -+} -+ -+static ulong brent_x; /* tortoise */ -+static ulong brent_y; /* hare */ -+static ulong brent_r; /* power */ -+static ulong brent_lambda; /* loop length */ -+static ulong brent_mu; /* distance to start of loop */ -+static ulong brent_loop_detect; -+static ulong brent_loop_exit; -+/* -+ * 'ptr': representative of x or y; modified on return -+ */ -+static int -+brent_f(ulong *ptr, struct list_data *ld, ulong readflag) -+{ -+ return do_list_no_hash_readmem(ld, ptr, readflag); -+} -+ -+/* -+ * Similar to do_list() but without the hash_table or LIST_ALLOCATE. -+ * Useful for the 'list' command and other callers needing faster list -+ * enumeration. -+ */ -+int -+do_list_no_hash(struct list_data *ld) -+{ -+ ulong next, last, first, offset; -+ ulong searchfor, readflag; -+ int i, count, ret; -+ unsigned int radix; -+ struct req_entry **e = NULL; -+ -+ do_list_debug_entry(ld); -+ -+ count = 0; -+ searchfor = ld->searchfor; -+ ld->searchfor = 0; -+ if (ld->flags & LIST_STRUCT_RADIX_10) -+ radix = 10; -+ else if (ld->flags & LIST_STRUCT_RADIX_16) -+ radix = 16; -+ else -+ radix = 0; -+ next = ld->start; -+ -+ readflag = ld->flags & RETURN_ON_LIST_ERROR ? -+ (RETURN_ON_ERROR|QUIET) : FAULT_ON_ERROR; -+ -+ if (!readmem(next + ld->member_offset, KVADDR, &first, sizeof(void *), -+ "first list entry", readflag)) { -+ error(INFO, "\ninvalid list entry: %lx\n", next); -+ return -1; -+ } -+ -+ if (ld->header) -+ fprintf(fp, "%s", ld->header); -+ -+ offset = ld->list_head_offset + ld->struct_list_offset; -+ -+ if (ld->structname && (ld->flags & LIST_READ_MEMBER)) { -+ e = (struct req_entry **)GETBUF(sizeof(*e) * ld->structname_args); -+ for (i = 0; i < ld->structname_args; i++) -+ e[i] = fill_member_offsets(ld->structname[i]); -+ } -+ -+ brent_loop_detect = brent_loop_exit = 0; -+ brent_lambda = 0; -+ brent_r = 2; -+ brent_x = brent_y = next; -+ ret = brent_f(&brent_y, ld, readflag); -+ if (ret == -1) -+ return -1; -+ while (1) { -+ if (!brent_loop_detect && ld->flags & VERBOSE) { -+ fprintf(fp, "%lx\n", next - ld->list_head_offset); -+ if (ld->structname) { -+ do_list_output_struct(ld, next, offset, radix, e); -+ } -+ } -+ -+ if (next && brent_loop_exit) { -+ if (ld->flags & -+ (RETURN_ON_DUPLICATE|RETURN_ON_LIST_ERROR)) { -+ error(INFO, "\nduplicate list entry: %lx\n", -+ brent_x); -+ return -1; -+ } -+ error(FATAL, "\nduplicate list entry: %lx\n", brent_x); -+ } -+ -+ if ((searchfor == next) || -+ (searchfor == (next - ld->list_head_offset))) -+ ld->searchfor = searchfor; -+ -+ count++; -+ last = next; -+ -+ if ((ld->flags & LIST_CALLBACK) && -+ ld->callback_func((void *)(next - ld->list_head_offset), -+ ld->callback_data) && (ld->flags & CALLBACK_RETURN)) -+ break; -+ -+ ret = do_list_no_hash_readmem(ld, &next, readflag); -+ if (ret == -1) -+ return -1; -+ -+ if (!brent_loop_detect) { -+ if (brent_x == brent_y) { -+ brent_loop_detect = 1; -+ error(INFO, "loop detected, loop length: %lx\n", brent_lambda); -+ /* reset x and y to start; advance y loop length */ -+ brent_mu = 0; -+ brent_x = brent_y = ld->start; -+ while (brent_lambda--) { -+ ret = brent_f(&brent_y, ld, readflag); -+ if (ret == -1) -+ return -1; -+ } -+ } else { -+ if (brent_r == brent_lambda) { -+ brent_x = brent_y; -+ brent_r *= 2; -+ brent_lambda = 0; -+ } -+ brent_y = next; -+ brent_lambda++; -+ } -+ } else { -+ if (!brent_loop_exit && brent_x == brent_y) { -+ brent_loop_exit = 1; -+ error(INFO, "length from start to loop: %lx", -+ brent_mu); -+ } else { -+ ret = brent_f(&brent_x, ld, readflag); -+ if (ret == -1) -+ return -1; -+ ret = brent_f(&brent_y, ld, readflag); -+ if (ret == -1) -+ return -1; -+ brent_mu++; -+ } -+ } -+ -+ if (next == 0) { -+ if (ld->flags & LIST_HEAD_FORMAT) { -+ error(INFO, "\ninvalid list entry: 0\n"); -+ return -1; -+ } -+ if (CRASHDEBUG(1)) -+ console("do_list end: next:%lx\n", next); -+ -+ break; -+ } -+ -+ if (next == ld->end) { -+ if (CRASHDEBUG(1)) -+ console("do_list end: next:%lx == end:%lx\n", -+ next, ld->end); -+ break; -+ } -+ -+ if (next == ld->start) { -+ if (CRASHDEBUG(1)) -+ console("do_list end: next:%lx == start:%lx\n", -+ next, ld->start); -+ break; -+ } -+ -+ if (next == last) { -+ if (CRASHDEBUG(1)) -+ console("do_list end: next:%lx == last:%lx\n", -+ next, last); -+ break; -+ } -+ -+ if ((next == first) && (count != 1)) { -+ if (CRASHDEBUG(1)) -+ console("do_list end: next:%lx == first:%lx (count %d)\n", -+ next, last, count); -+ break; -+ } -+ } -+ -+ if (CRASHDEBUG(1)) -+ console("do_list count: %d\n", count); -+ -+ return count; -+} -+ - /* - * Issue a dump_struct_member() call for one or more structure - * members. Multiple members are passed in a comma-separated - -commit 582f8b1ea4bb843f996d5285288e7a12b519ee73 -Author: Dave Anderson -Date: Thu Jul 12 14:06:22 2018 -0400 - - Fix for x86_64 "bt" command to prevent an in-kernel exception frame - from not being displayed. Without the patch, if the RIP in a pt_regs - structure on the stack is not a kernel text address, such as a NULL - pointer, it is not recognized as an exception frame and the register - set is not displayed. - (anderson@redhat.com) - -diff --git a/x86_64.c b/x86_64.c -index b07d6f2..15800fb 100644 ---- a/x86_64.c -+++ b/x86_64.c -@@ -4662,6 +4662,8 @@ x86_64_eframe_verify(struct bt_info *bt, long kvaddr, long cs, long ss, - STREQ(sp->name, "page_fault")) - return TRUE; - -+ if ((kvaddr + SIZE(pt_regs)) == rsp) -+ return TRUE; - } - - if ((cs == 0x10) && kvaddr) { -@@ -8393,7 +8395,7 @@ x86_64_get_framesize(struct bt_info *bt, ulong textaddr, ulong rsp) - *p1 = NULLCHAR; - p2 = arglist[arg]; - reterror = 0; -- offset = htol(p2+1, RETURN_ON_ERROR, &reterror); -+ offset = htol(p2+1, RETURN_ON_ERROR|QUIET, &reterror); - if (reterror) - continue; - framesize += offset; - -commit 528849c15a02d9162c2dd17f4551390763711ad5 -Author: Dave Anderson -Date: Fri Jul 13 13:50:44 2018 -0400 - - Fix for the "repeat" command when the argument consists of an input - file construct, for example, "repeat -1 < input_file". Without the - patch, only the first command line in the input file is executed - each time. - (anderson@redhat.com) - -diff --git a/cmdline.c b/cmdline.c -index aab37ce..ee08f06 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,2017 David Anderson -- * Copyright (C) 2002-2015,2017 Red Hat, Inc. All rights reserved. -+ * Copyright (C) 2002-2015,2018 David Anderson -+ * Copyright (C) 2002-2015,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 -@@ -2324,6 +2324,9 @@ is_args_input_file(struct command_table_entry *ct, struct args_input_file *aif) - if (pc->curcmd_flags & NO_MODIFY) - return FALSE; - -+ if (STREQ(ct->name, "repeat")) -+ return FALSE; -+ - BZERO(aif, sizeof(struct args_input_file)); - retval = FALSE; - - -commit 61fcad549faa479e6831d5283387f8f2e4ec9202 -Author: Dave Anderson -Date: Mon Jul 16 09:32:57 2018 -0400 - - Fourth phase of support for x86_64 5-level page tables in Linux 4.17 - and later kernels. This patch adds support for user virtual address - translation when the kernel is configured with CONFIG_X86_5LEVEL. - (douly.fnst@cn.fujitsu.com) - -diff --git a/x86_64.c b/x86_64.c -index 15800fb..4073acb 100644 ---- a/x86_64.c -+++ b/x86_64.c -@@ -24,7 +24,6 @@ static int x86_64_uvtop(struct task_context *, ulong, physaddr_t *, int); - static int x86_64_uvtop_level4(struct task_context *, ulong, physaddr_t *, int); - static int x86_64_uvtop_level4_xen_wpt(struct task_context *, ulong, physaddr_t *, int); - static int x86_64_uvtop_level4_rhel4_xen_wpt(struct task_context *, ulong, physaddr_t *, int); --static int x86_64_task_uses_5level(struct task_context *); - static ulong x86_64_vmalloc_start(void); - static int x86_64_is_task_addr(ulong); - static int x86_64_verify_symbol(const char *, ulong, char); -@@ -341,6 +340,7 @@ x86_64_init(int when) - if (l5_enabled) - machdep->flags |= VM_5LEVEL; - } -+ - if (machdep->flags & VM_5LEVEL) { - machdep->machspec->userspace_top = USERSPACE_TOP_5LEVEL; - machdep->machspec->page_offset = PAGE_OFFSET_5LEVEL; -@@ -361,7 +361,6 @@ x86_64_init(int when) - machdep->uvtop = x86_64_uvtop_level4; /* 5-level is optional per-task */ - machdep->kvbase = (ulong)PAGE_OFFSET; - machdep->identity_map_base = (ulong)PAGE_OFFSET; -- - } - - /* -@@ -812,7 +811,7 @@ x86_64_dump_machdep_table(ulong arg) - else if (machdep->uvtop == x86_64_uvtop_level4) { - fprintf(fp, " uvtop: x86_64_uvtop_level4()"); - if (machdep->flags & VM_5LEVEL) -- fprintf(fp, " or x86_64_uvtop_5level()"); -+ fprintf(fp, " (uses 5-level page tables)"); - fprintf(fp, "\n"); - } else if (machdep->uvtop == x86_64_uvtop_level4_xen_wpt) - fprintf(fp, " uvtop: x86_64_uvtop_level4_xen_wpt()\n"); -@@ -1915,7 +1914,7 @@ x86_64_uvtop_level4(struct task_context *tc, ulong uvaddr, physaddr_t *paddr, in - goto no_upage; - - /* If the VM is in 5-level page table */ -- if (machdep->flags & VM_5LEVEL && x86_64_task_uses_5level(tc)) { -+ if (machdep->flags & VM_5LEVEL) { - ulong p4d_pte; - /* - * p4d = p4d_offset(pgd, address); -@@ -1987,12 +1986,6 @@ no_upage: - } - - static int --x86_64_task_uses_5level(struct task_context *tc) --{ -- return FALSE; --} -- --static int - x86_64_uvtop_level4_xen_wpt(struct task_context *tc, ulong uvaddr, physaddr_t *paddr, int verbose) - { - ulong pgd_pte; - -commit eb823b79385f61be97411a06dd57b6fc0973d280 -Author: Dave Anderson -Date: Mon Jul 16 10:50:19 2018 -0400 - - Fix to prevent an unnecessary "read error" message during session - initialization on live systems running a kernel that is configured - with CONFIG_X86_5LEVEL. Without the patch, a message indicating - "crash: read error: kernel virtual address: <address> type: - __pgtable_l5_enabled" will be displayed if /proc/kcore gets - selected as the live memory source after /dev/mem is determined - to be unusable. - (anderson@redhat.com) - -diff --git a/x86_64.c b/x86_64.c -index 4073acb..0574041 100644 ---- a/x86_64.c -+++ b/x86_64.c -@@ -335,7 +335,7 @@ x86_64_init(int when) - } else if (kernel_symbol_exists("__pgtable_l5_enabled")) - readmem(symbol_value("__pgtable_l5_enabled"), KVADDR, - &l5_enabled, sizeof(int), "__pgtable_l5_enabled", -- FAULT_ON_ERROR); -+ QUIET|FAULT_ON_ERROR); - - if (l5_enabled) - machdep->flags |= VM_5LEVEL; diff --git a/SOURCES/github_a10917ba_to_e9532aea.patch b/SOURCES/github_a10917ba_to_e9532aea.patch deleted file mode 100644 index 0a858bd..0000000 --- a/SOURCES/github_a10917ba_to_e9532aea.patch +++ /dev/null @@ -1,894 +0,0 @@ -commit a10917ba3203aa8b20e2aa1b84dc12c1e17445e1 -Author: Dave Anderson -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 -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 -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 -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 -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 <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; - } - diff --git a/SOURCES/github_a89ec821_vmcoreinfo_plugin.patch b/SOURCES/github_a89ec821_vmcoreinfo_plugin.patch deleted file mode 100644 index 0c79a31..0000000 --- a/SOURCES/github_a89ec821_vmcoreinfo_plugin.patch +++ /dev/null @@ -1,193 +0,0 @@ -commit a89ec821cb5dbb106cb58e8740f84c7e382c0140 -Author: Dave Anderson -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; - } - } diff --git a/SOURCES/github_ac5a7889_CONFIG_ARM64_PA_BITS.patch b/SOURCES/github_ac5a7889_CONFIG_ARM64_PA_BITS.patch deleted file mode 100644 index 2122183..0000000 --- a/SOURCES/github_ac5a7889_CONFIG_ARM64_PA_BITS.patch +++ /dev/null @@ -1,29 +0,0 @@ -commit ac5a7889d31bb37aa0687110ecea08837f8a66a8 -Author: Dave Anderson -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; diff --git a/SOURCES/github_b1a6e13a_p_regression.patch b/SOURCES/github_b1a6e13a_p_regression.patch new file mode 100644 index 0000000..be51417 --- /dev/null +++ b/SOURCES/github_b1a6e13a_p_regression.patch @@ -0,0 +1,28 @@ +commit b1a6e13a93661dfae7df15fe32862bddf4026c80 +Author: Dave Anderson +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') { diff --git a/SOURCES/github_b9d76838_c79a11fa_proc_kcore.patch b/SOURCES/github_b9d76838_c79a11fa_proc_kcore.patch deleted file mode 100644 index 0d84189..0000000 --- a/SOURCES/github_b9d76838_c79a11fa_proc_kcore.patch +++ /dev/null @@ -1,149 +0,0 @@ -commit b9d76838372d1b4087bb506ce6da425afad68876 -Author: Dave Anderson -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". 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 -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<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; - } diff --git a/SOURCES/github_bf48dd4e_arm64_devmem_read_error.patch b/SOURCES/github_bf48dd4e_arm64_devmem_read_error.patch new file mode 100644 index 0000000..d3982cd --- /dev/null +++ b/SOURCES/github_bf48dd4e_arm64_devmem_read_error.patch @@ -0,0 +1,26 @@ +commit bf48dd4e9926515345cad06c1bfce49d7a057a26 +Author: Dave Anderson +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:
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) { diff --git a/SOURCES/github_c5f45d6c.patch b/SOURCES/github_c5f45d6c.patch deleted file mode 100644 index c242be1..0000000 --- a/SOURCES/github_c5f45d6c.patch +++ /dev/null @@ -1,239 +0,0 @@ -commit c5f45d6cdbe7f01314857a75b2feef25b22adaaa -Author: Dave Anderson -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); - } - - /* diff --git a/SOURCES/github_ced52552_dev-p_offsets.patch b/SOURCES/github_ced52552_dev-p_offsets.patch deleted file mode 100644 index f8ba626..0000000 --- a/SOURCES/github_ced52552_dev-p_offsets.patch +++ /dev/null @@ -1,41 +0,0 @@ -commit ced5255233447cc0810965b683657409f798c4a2 -Author: Dave Anderson -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)); diff --git a/SOURCES/github_f3a53059.patch b/SOURCES/github_f3a53059.patch deleted file mode 100644 index f28387c..0000000 --- a/SOURCES/github_f3a53059.patch +++ /dev/null @@ -1,89 +0,0 @@ -commit f3a5305947077a65aea8091b05cdb542cea0d61a -Author: Dave Anderson -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; diff --git a/SOURCES/github_ppc64_5fe78861_7e393689_599a6579_72cc0cba.patch b/SOURCES/github_ppc64_5fe78861_7e393689_599a6579_72cc0cba.patch deleted file mode 100644 index 2b3d324..0000000 --- a/SOURCES/github_ppc64_5fe78861_7e393689_599a6579_72cc0cba.patch +++ /dev/null @@ -1,499 +0,0 @@ -commit 5fe78861ea1589084f6a2956a6ff63677c9269e1 -Author: Dave Anderson -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:
- 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 -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 -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 -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 - : Invalid Stack Pointer " - (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, "\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; diff --git a/SOURCES/rhel8_ppc64_max_physmem_bits.patch b/SOURCES/rhel8_ppc64_max_physmem_bits.patch deleted file mode 100644 index 28cd4cf..0000000 --- a/SOURCES/rhel8_ppc64_max_physmem_bits.patch +++ /dev/null @@ -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; diff --git a/SPECS/crash.spec b/SPECS/crash.spec index 8a25125..b38e9f6 100644 --- a/SPECS/crash.spec +++ b/SPECS/crash.spec @@ -3,8 +3,8 @@ # Summary: Kernel analysis utility for live systems, netdump, diskdump, kdump, LKCD or mcore dumpfiles Name: crash -Version: 7.2.3 -Release: 18%{?dist} +Version: 7.2.6 +Release: 2%{?dist} License: GPLv3 Group: Development/Debuggers 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 Requires: binutils Patch0: lzo_snappy.patch -Patch1: github_46d21219_to_9446958f.patch -Patch2: github_95daa11b.patch -Patch3: github_b9d76838_c79a11fa_proc_kcore.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 +Patch1: rhel8_build.patch +Patch2: github_bf48dd4e_arm64_devmem_read_error.patch +Patch3: github_b1a6e13a_p_regression.patch %description 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 %setup -n %{name}-%{version} -q %patch0 -p1 -b lzo_snappy.patch -%patch1 -p1 -b github_46d21219_to_9446958f.patch -%patch2 -p1 -b github_95daa11b.patch -%patch3 -p1 -b github_b9d76838_c79a11fa_proc_kcore.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 +%patch1 -p1 -b rhel8_build.patch +%patch2 -p1 -b github_bf48dd4e_arm64_devmem_read_error.patch +%patch3 -p1 -b github_b1a6e13a_p_regression.patch %build make RPMPKG="%{version}-%{release}" CFLAGS="%{optflags}" @@ -110,6 +70,20 @@ rm -rf %{buildroot} %{_includedir}/* %changelog +* Mon Jun 10 2019 Dave Anderson - 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 - 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 - 7.2.3-18 - Fix "files -c" and "files -p" options Resolves: rhbz#1673285