Accepting request 590461 from Kernel:kdump
OBS-URL: https://build.opensuse.org/request/show/590461 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/crash?expand=0&rev=148
This commit is contained in:
@@ -1,3 +1,22 @@
|
||||
-------------------------------------------------------------------
|
||||
Mon Mar 19 20:42:50 UTC 2018 - dmair@suse.com
|
||||
|
||||
- Upgraded to 7.2.1 because it includes the fixes to support
|
||||
several core cases that recently were caused tofail to open.
|
||||
As a result, removed patches that were already superceded by
|
||||
7.2.1 source.
|
||||
|
||||
Removed:
|
||||
crash-ppc64-book3s-update-hash-page-table-geometry.patch
|
||||
crash-x86_64_kvtop-usable-symtab_init.patch
|
||||
crash-ppc64-ensure-chosen-stack-symbol-relates-to-an-actual-backtrace.patch
|
||||
crash-fix-error-cannot-resolve-schedulers-0001.patch
|
||||
crash-fix-error-cannot-resolve-schedulers-0002.patch
|
||||
crash-extend-direct-mapping-to-5TB.patch
|
||||
|
||||
Modified:
|
||||
crash-allow-use-of-sadump-captured-KASLR-kernel.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Mon Feb 5 18:56:04 UTC 2018 - dmair@suse.com
|
||||
|
||||
|
||||
+9
-21
@@ -54,9 +54,9 @@ Name: crash
|
||||
%endif
|
||||
Url: http://people.redhat.com/anderson/
|
||||
Summary: Crash utility for live systems; netdump, diskdump, LKCD or mcore dumpfiles
|
||||
License: GPL-3.0+ and GFDL-1.2
|
||||
License: GPL-3.0-or-later AND GFDL-1.2-only
|
||||
Group: Development/Tools/Debuggers
|
||||
Version: 7.2.0
|
||||
Version: 7.2.1
|
||||
Release: 0
|
||||
Source: %{name}-%{version}.tar.gz
|
||||
Source2: crash_whitepaper-%{whitepaper_version}.tar.bz2
|
||||
@@ -83,13 +83,7 @@ Patch13: %{name}-patch-gdb.patch
|
||||
Patch15: %{name}_enable_snappy_support.patch
|
||||
Patch16: eppic-support-arm64.patch
|
||||
Patch18: %{name}-stop_read_error_when_intent_is_retry.patch
|
||||
Patch19: %{name}-ppc64-book3s-update-hash-page-table-geometry.patch
|
||||
Patch20: %{name}-x86_64_kvtop-usable-symtab_init.patch
|
||||
Patch21: %{name}-allow-use-of-sadump-captured-KASLR-kernel.patch
|
||||
Patch22: %{name}-ppc64-ensure-chosen-stack-symbol-relates-to-an-actual-backtrace.patch
|
||||
Patch23: %{name}-fix-error-cannot-resolve-schedulers-0001.patch
|
||||
Patch24: %{name}-fix-error-cannot-resolve-schedulers-0002.patch
|
||||
Patch25: %{name}-extend-direct-mapping-to-5TB.patch
|
||||
Patch90: %{name}-sial-ps-2.6.29.diff
|
||||
BuildRequires: bison
|
||||
BuildRequires: flex
|
||||
@@ -110,7 +104,7 @@ ExcludeArch: ppc
|
||||
BuildRequires: kernel-syms
|
||||
BuildRequires: module-init-tools
|
||||
%if 0%{?buildrt}
|
||||
%if ! 0%{?build_crash_on_obs}
|
||||
%if ! 0%{?build_crash_on_obs}
|
||||
BuildRequires: kernel-syms-rt
|
||||
%endif
|
||||
%endif
|
||||
@@ -148,7 +142,7 @@ Authors:
|
||||
%package doc
|
||||
Requires: %{name} = %{version}
|
||||
Summary: Documentation for Crash
|
||||
License: GFDL-1.2
|
||||
License: GFDL-1.2-only
|
||||
Group: Development/Tools/Debuggers
|
||||
|
||||
%description doc
|
||||
@@ -163,7 +157,7 @@ Authors:
|
||||
%package devel
|
||||
Requires: %{name} = %{version}
|
||||
Summary: Development files for crash
|
||||
License: GPL-2.0+
|
||||
License: GPL-2.0-or-later
|
||||
Group: Development/Tools/Debuggers
|
||||
|
||||
%description devel
|
||||
@@ -190,7 +184,7 @@ Provides: %{name}-sial = %{version}
|
||||
Obsoletes: %{name}-sial < %{version}
|
||||
%endif
|
||||
Summary: Embeddable Pre-Processor and Interpreter for C extension for crash
|
||||
License: GPL-2.0+
|
||||
License: GPL-2.0-or-later
|
||||
Group: Development/Tools/Debuggers
|
||||
|
||||
%description eppic
|
||||
@@ -212,7 +206,7 @@ Authors:
|
||||
%package sial
|
||||
Requires: %{name} = %{version}
|
||||
Summary: SIAL extension for crash
|
||||
License: GPL-2.0+
|
||||
License: GPL-2.0-or-later
|
||||
Group: Development/Tools/Debuggers
|
||||
|
||||
%description sial
|
||||
@@ -235,7 +229,7 @@ Authors:
|
||||
%package gcore
|
||||
Requires: %{name} = %{version}
|
||||
Summary: Gcore extension for crash
|
||||
License: GPL-2.0+
|
||||
License: GPL-2.0-or-later
|
||||
Group: Development/Tools/Debuggers
|
||||
|
||||
%description gcore
|
||||
@@ -254,7 +248,7 @@ Authors:
|
||||
|
||||
%package %kmp_pkg
|
||||
Summary: Memory driver for the crash utility
|
||||
License: GPL-2.0
|
||||
License: GPL-2.0-only
|
||||
Group: System/Kernel
|
||||
%if 0%{?suse_version} < 920
|
||||
Version: %{version}_%{kver_}
|
||||
@@ -285,13 +279,7 @@ Authors:
|
||||
%patch11 -p1
|
||||
%patch13 -p1
|
||||
%patch18 -p1
|
||||
%patch19 -p1
|
||||
%patch20 -p1
|
||||
%patch21 -p1
|
||||
%patch22 -p1
|
||||
%patch23 -p1
|
||||
%patch24 -p1
|
||||
%patch25 -p1
|
||||
%if %{have_snappy}
|
||||
%patch15 -p1
|
||||
%endif
|
||||
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -19,537 +19,13 @@ calculate kaslr_offset/phys_base using them.
|
||||
|
||||
Signed-off-by: Takao Indoh <indou.takao@jp.fujitsu.com>
|
||||
---
|
||||
defs.h | 4 +
|
||||
sadump.c | 465 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
sadump.h | 1 +
|
||||
symbols.c | 34 +++++
|
||||
4 files changed, 503 insertions(+), 1 deletion(-)
|
||||
symbols.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/defs.h b/defs.h
|
||||
index 7768895..fd181ea 100644
|
||||
--- a/defs.h
|
||||
+++ b/defs.h
|
||||
@@ -2590,6 +2590,9 @@ struct symbol_table_data {
|
||||
ulong first_section_start;
|
||||
ulong last_section_end;
|
||||
ulong _stext_vmlinux;
|
||||
+ ulong divide_error_vmlinux;
|
||||
+ ulong idt_table_vmlinux;
|
||||
+ ulong saved_command_line_vmlinux;
|
||||
struct downsized downsized;
|
||||
};
|
||||
|
||||
@@ -6309,6 +6312,7 @@ void sadump_set_zero_excluded(void);
|
||||
void sadump_unset_zero_excluded(void);
|
||||
struct sadump_data;
|
||||
struct sadump_data *get_sadump_data(void);
|
||||
+int sadump_calc_kaslr_offset(ulong *kaslr_offset);
|
||||
|
||||
/*
|
||||
* qemu.c
|
||||
diff --git a/sadump.c b/sadump.c
|
||||
index a96ba9c..8d9b342 100644
|
||||
--- a/sadump.c
|
||||
+++ b/sadump.c
|
||||
@@ -1558,12 +1558,17 @@ sadump_display_regs(int cpu, FILE *ofp)
|
||||
*/
|
||||
int sadump_phys_base(ulong *phys_base)
|
||||
{
|
||||
- if (SADUMP_VALID()) {
|
||||
+ if (SADUMP_VALID() && !sd->phys_base) {
|
||||
if (CRASHDEBUG(1))
|
||||
error(NOTE, "sadump: does not save phys_base.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
+ if (sd->phys_base) {
|
||||
+ *phys_base = sd->phys_base;
|
||||
+ return TRUE;
|
||||
+ }
|
||||
+
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1649,3 +1654,461 @@ get_sadump_data(void)
|
||||
{
|
||||
return sd;
|
||||
}
|
||||
+
|
||||
+#ifdef X86_64
|
||||
+static int
|
||||
+get_sadump_smram_cpu_state_any(struct sadump_smram_cpu_state *smram)
|
||||
+{
|
||||
+ ulong offset;
|
||||
+ struct sadump_header *sh = sd->dump_header;
|
||||
+ int apicid;
|
||||
+ struct sadump_smram_cpu_state scs, zero;
|
||||
+
|
||||
+ offset = sd->sub_hdr_offset + sizeof(uint32_t) +
|
||||
+ sd->dump_header->nr_cpus * sizeof(struct sadump_apic_state);
|
||||
+
|
||||
+ memset(&zero, 0, sizeof(zero));
|
||||
+
|
||||
+ for (apicid = 0; apicid < sh->nr_cpus; ++apicid) {
|
||||
+ if (!read_device(&scs, sizeof(scs), &offset)) {
|
||||
+ error(INFO, "sadump: cannot read sub header "
|
||||
+ "cpu_state\n");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ if (memcmp(&scs, &zero, sizeof(scs)) != 0) {
|
||||
+ *smram = scs;
|
||||
+ return TRUE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return FALSE;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Get address of vector0 interrupt handler (Devide Error) from Interrupt
|
||||
+ * Descriptor Table.
|
||||
+ */
|
||||
+static ulong
|
||||
+get_vec0_addr(ulong idtr)
|
||||
+{
|
||||
+ struct gate_struct64 {
|
||||
+ uint16_t offset_low;
|
||||
+ uint16_t segment;
|
||||
+ uint32_t ist : 3, zero0 : 5, type : 5, dpl : 2, p : 1;
|
||||
+ uint16_t offset_middle;
|
||||
+ uint32_t offset_high;
|
||||
+ uint32_t zero1;
|
||||
+ } __attribute__((packed)) gate;
|
||||
+
|
||||
+ readmem(idtr, PHYSADDR, &gate, sizeof(gate), "idt_table", FAULT_ON_ERROR);
|
||||
+
|
||||
+ return ((ulong)gate.offset_high << 32)
|
||||
+ + ((ulong)gate.offset_middle << 16)
|
||||
+ + gate.offset_low;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Parse a string of [size[KMG]@]offset[KMG]
|
||||
+ * Import from Linux kernel(lib/cmdline.c)
|
||||
+ */
|
||||
+static ulong memparse(char *ptr, char **retptr)
|
||||
+{
|
||||
+ char *endptr;
|
||||
+
|
||||
+ unsigned long long ret = strtoull(ptr, &endptr, 0);
|
||||
+
|
||||
+ switch (*endptr) {
|
||||
+ case 'E':
|
||||
+ case 'e':
|
||||
+ ret <<= 10;
|
||||
+ case 'P':
|
||||
+ case 'p':
|
||||
+ ret <<= 10;
|
||||
+ case 'T':
|
||||
+ case 't':
|
||||
+ ret <<= 10;
|
||||
+ case 'G':
|
||||
+ case 'g':
|
||||
+ ret <<= 10;
|
||||
+ case 'M':
|
||||
+ case 'm':
|
||||
+ ret <<= 10;
|
||||
+ case 'K':
|
||||
+ case 'k':
|
||||
+ ret <<= 10;
|
||||
+ endptr++;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (retptr)
|
||||
+ *retptr = endptr;
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Find "elfcorehdr=" in the boot parameter of kernel and return the address
|
||||
+ * of elfcorehdr.
|
||||
+ */
|
||||
+static ulong
|
||||
+get_elfcorehdr(ulong cr3, ulong kaslr_offset)
|
||||
+{
|
||||
+ char cmdline[BUFSIZE], *ptr;
|
||||
+ ulong cmdline_vaddr;
|
||||
+ ulong cmdline_paddr;
|
||||
+ ulong buf_vaddr, buf_paddr;
|
||||
+ char *end;
|
||||
+ ulong elfcorehdr_addr = 0, elfcorehdr_size = 0;
|
||||
+ int verbose = CRASHDEBUG(1)? 1: 0;
|
||||
+
|
||||
+ cmdline_vaddr = st->saved_command_line_vmlinux + kaslr_offset;
|
||||
+ if (!kvtop(NULL, cmdline_vaddr, &cmdline_paddr, verbose))
|
||||
+ return 0;
|
||||
+
|
||||
+ if (CRASHDEBUG(1)) {
|
||||
+ fprintf(fp, "cmdline vaddr=%lx\n", cmdline_vaddr);
|
||||
+ fprintf(fp, "cmdline paddr=%lx\n", cmdline_paddr);
|
||||
+ }
|
||||
+
|
||||
+ if (!readmem(cmdline_paddr, PHYSADDR, &buf_vaddr, sizeof(ulong),
|
||||
+ "saved_command_line", RETURN_ON_ERROR))
|
||||
+ return 0;
|
||||
+
|
||||
+ if (!kvtop(NULL, buf_vaddr, &buf_paddr, verbose))
|
||||
+ return 0;
|
||||
+
|
||||
+ if (CRASHDEBUG(1)) {
|
||||
+ fprintf(fp, "cmdline buffer vaddr=%lx\n", buf_vaddr);
|
||||
+ fprintf(fp, "cmdline buffer paddr=%lx\n", buf_paddr);
|
||||
+ }
|
||||
+
|
||||
+ memset(cmdline, 0, BUFSIZE);
|
||||
+ if (!readmem(buf_paddr, PHYSADDR, cmdline, BUFSIZE,
|
||||
+ "saved_command_line", RETURN_ON_ERROR))
|
||||
+ return 0;
|
||||
+
|
||||
+ ptr = strstr(cmdline, "elfcorehdr=");
|
||||
+ if (!ptr)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (CRASHDEBUG(1))
|
||||
+ fprintf(fp, "2nd kernel detected\n");
|
||||
+
|
||||
+ ptr += strlen("elfcorehdr=");
|
||||
+ elfcorehdr_addr = memparse(ptr, &end);
|
||||
+ if (*end == '@') {
|
||||
+ elfcorehdr_size = elfcorehdr_addr;
|
||||
+ elfcorehdr_addr = memparse(end + 1, &end);
|
||||
+ }
|
||||
+
|
||||
+ if (CRASHDEBUG(1)) {
|
||||
+ fprintf(fp, "elfcorehdr_addr=%lx\n", elfcorehdr_addr);
|
||||
+ fprintf(fp, "elfcorehdr_size=%lx\n", elfcorehdr_size);
|
||||
+ }
|
||||
+
|
||||
+ return elfcorehdr_addr;
|
||||
+}
|
||||
+
|
||||
+ /*
|
||||
+ * Get vmcoreinfo from elfcorehdr.
|
||||
+ * Some codes are imported from Linux kernel(fs/proc/vmcore.c)
|
||||
+ */
|
||||
+static int
|
||||
+get_vmcoreinfo(ulong elfcorehdr, ulong *addr, int *len)
|
||||
+{
|
||||
+ unsigned char e_ident[EI_NIDENT];
|
||||
+ Elf64_Ehdr ehdr;
|
||||
+ Elf64_Phdr phdr;
|
||||
+ Elf64_Nhdr nhdr;
|
||||
+ ulong ptr;
|
||||
+ ulong nhdr_offset = 0;
|
||||
+ int i;
|
||||
+
|
||||
+ if (!readmem(elfcorehdr, PHYSADDR, e_ident, EI_NIDENT,
|
||||
+ "EI_NIDENT", RETURN_ON_ERROR))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ if (e_ident[EI_CLASS] != ELFCLASS64) {
|
||||
+ error(INFO, "Only ELFCLASS64 is supportd\n");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ if (!readmem(elfcorehdr, PHYSADDR, &ehdr, sizeof(ehdr),
|
||||
+ "Elf64_Ehdr", RETURN_ON_ERROR))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ /* Sanity Check */
|
||||
+ if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0 ||
|
||||
+ (ehdr.e_type != ET_CORE) ||
|
||||
+ ehdr.e_ident[EI_CLASS] != ELFCLASS64 ||
|
||||
+ ehdr.e_ident[EI_VERSION] != EV_CURRENT ||
|
||||
+ ehdr.e_version != EV_CURRENT ||
|
||||
+ ehdr.e_ehsize != sizeof(Elf64_Ehdr) ||
|
||||
+ ehdr.e_phentsize != sizeof(Elf64_Phdr) ||
|
||||
+ ehdr.e_phnum == 0) {
|
||||
+ error(INFO, "Invalid elf header\n");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ ptr = elfcorehdr + ehdr.e_phoff;
|
||||
+ for (i = 0; i < ehdr.e_phnum; i++) {
|
||||
+ ulong offset;
|
||||
+ char name[16];
|
||||
+
|
||||
+ if (!readmem(ptr, PHYSADDR, &phdr, sizeof(phdr),
|
||||
+ "Elf64_Phdr", RETURN_ON_ERROR))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ ptr += sizeof(phdr);
|
||||
+ if (phdr.p_type != PT_NOTE)
|
||||
+ continue;
|
||||
+
|
||||
+ offset = phdr.p_offset;
|
||||
+ if (!readmem(offset, PHYSADDR, &nhdr, sizeof(nhdr),
|
||||
+ "Elf64_Nhdr", RETURN_ON_ERROR))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ offset += DIV_ROUND_UP(sizeof(Elf64_Nhdr), sizeof(Elf64_Word))*
|
||||
+ sizeof(Elf64_Word);
|
||||
+ memset(name, 0, sizeof(name));
|
||||
+ if (!readmem(offset, PHYSADDR, name, sizeof(name),
|
||||
+ "Elf64_Nhdr name", RETURN_ON_ERROR))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ if(!strcmp(name, "VMCOREINFO")) {
|
||||
+ nhdr_offset = offset;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!nhdr_offset)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ *addr = nhdr_offset +
|
||||
+ DIV_ROUND_UP(nhdr.n_namesz, sizeof(Elf64_Word))*
|
||||
+ sizeof(Elf64_Word);
|
||||
+ *len = nhdr.n_descsz;
|
||||
+
|
||||
+ if (CRASHDEBUG(1)) {
|
||||
+ fprintf(fp, "vmcoreinfo addr=%lx\n", *addr);
|
||||
+ fprintf(fp, "vmcoreinfo len=%d\n", *len);
|
||||
+ }
|
||||
+
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Check if current kaslr_offset/phys_base is for 1st kernel or 2nd kernel.
|
||||
+ * If we are in 2nd kernel, get kaslr_offset/phys_base from vmcoreinfo.
|
||||
+ *
|
||||
+ * 1. Get command line and try to retrieve "elfcorehdr=" boot parameter
|
||||
+ * 2. If "elfcorehdr=" is not found in command line, we are in 1st kernel.
|
||||
+ * There is nothing to do.
|
||||
+ * 3. If "elfcorehdr=" is found, we are in 2nd kernel. Find vmcoreinfo
|
||||
+ * using "elfcorehdr=" and retrieve kaslr_offset/phys_base from vmcoreinfo.
|
||||
+ */
|
||||
+static int
|
||||
+get_kaslr_offset_from_vmcoreinfo(ulong cr3, ulong orig_kaslr_offset,
|
||||
+ ulong *kaslr_offset, ulong *phys_base)
|
||||
+{
|
||||
+ ulong elfcorehdr_addr = 0;
|
||||
+ ulong vmcoreinfo_addr;
|
||||
+ int vmcoreinfo_len;
|
||||
+ char *buf, *pos;
|
||||
+ int ret = FALSE;
|
||||
+
|
||||
+ /* Find "elfcorehdr=" in the kernel boot parameter */
|
||||
+ elfcorehdr_addr = get_elfcorehdr(cr3, orig_kaslr_offset);
|
||||
+ if (!elfcorehdr_addr)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ /* Get vmcoreinfo from the address of "elfcorehdr=" */
|
||||
+ if (!get_vmcoreinfo(elfcorehdr_addr, &vmcoreinfo_addr, &vmcoreinfo_len))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ if (!vmcoreinfo_len)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ if (CRASHDEBUG(1))
|
||||
+ fprintf(fp, "Find vmcoreinfo in kdump memory\n");
|
||||
+
|
||||
+ buf = GETBUF(vmcoreinfo_len);
|
||||
+ if (!readmem(vmcoreinfo_addr, PHYSADDR, buf, vmcoreinfo_len,
|
||||
+ "vmcoreinfo", RETURN_ON_ERROR))
|
||||
+ goto quit;
|
||||
+
|
||||
+ /* Get phys_base form vmcoreinfo */
|
||||
+ pos = strstr(buf, "NUMBER(phys_base)=");
|
||||
+ if (!pos)
|
||||
+ goto quit;
|
||||
+ *phys_base = strtoull(pos + strlen("NUMBER(phys_base)="), NULL, 0);
|
||||
+
|
||||
+ /* Get kaslr_offset form vmcoreinfo */
|
||||
+ pos = strstr(buf, "KERNELOFFSET=");
|
||||
+ if (!pos)
|
||||
+ goto quit;
|
||||
+ *kaslr_offset = strtoull(pos + strlen("KERNELOFFSET="), NULL, 16);
|
||||
+
|
||||
+ ret = TRUE;
|
||||
+
|
||||
+quit:
|
||||
+ FREEBUF(buf);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Calculate kaslr_offset and phys_base
|
||||
+ *
|
||||
+ * kaslr_offset:
|
||||
+ * The difference between original address in System.map or vmlinux and
|
||||
+ * actual address placed randomly by kaslr feature. To be more accurate,
|
||||
+ * kaslr_offset = actual address - original address
|
||||
+ *
|
||||
+ * phys_base:
|
||||
+ * Physical address where the kerenel is placed. In other words, it's a
|
||||
+ * physical address of __START_KERNEL_map. This is also decided randomly by
|
||||
+ * kaslr.
|
||||
+ *
|
||||
+ * kaslr offset and phys_base are calculated as follows:
|
||||
+ *
|
||||
+ * kaslr_offset:
|
||||
+ * 1) Get IDTR and CR3 value from the dump header.
|
||||
+ * 2) Get a virtual address of IDT from IDTR value
|
||||
+ * --- (A)
|
||||
+ * 3) Translate (A) to physical address using CR3, which points a top of
|
||||
+ * page table.
|
||||
+ * --- (B)
|
||||
+ * 4) Get an address of vector0 (Devide Error) interrupt handler from
|
||||
+ * IDT, which are pointed by (B).
|
||||
+ * --- (C)
|
||||
+ * 5) Get an address of symbol "divide_error" form vmlinux
|
||||
+ * --- (D)
|
||||
+ *
|
||||
+ * Now we have two addresses:
|
||||
+ * (C)-> Actual address of "divide_error"
|
||||
+ * (D)-> Original address of "divide_error" in the vmlinux
|
||||
+ *
|
||||
+ * kaslr_offset can be calculated by the difference between these two
|
||||
+ * value.
|
||||
+ *
|
||||
+ * phys_base;
|
||||
+ * 1) Get IDT virtual address from vmlinux
|
||||
+ * --- (E)
|
||||
+ *
|
||||
+ * So phys_base can be calculated using relationship of directly mapped
|
||||
+ * address.
|
||||
+ *
|
||||
+ * phys_base =
|
||||
+ * Physical address(B) -
|
||||
+ * (Virtual address(E) + kaslr_offset - __START_KERNEL_map)
|
||||
+ *
|
||||
+ * Note that the address (A) cannot be used instead of (E) because (A) is
|
||||
+ * not direct map address, it's a fixed map address.
|
||||
+ *
|
||||
+ * This solution works in most every case, but does not work in the
|
||||
+ * following case.
|
||||
+ *
|
||||
+ * 1) If the dump is captured on early stage of kernel boot, IDTR points
|
||||
+ * early IDT table(early_idts) instead of normal IDT(idt_table).
|
||||
+ * 2) If the dump is captured whle kdump is working, IDTR points
|
||||
+ * IDT table of 2nd kernel, not 1st kernel.
|
||||
+ *
|
||||
+ * Current implementation does not support the case 1), need
|
||||
+ * enhancement in the future. For the case 2), get kaslr_offset and
|
||||
+ * phys_base as follows.
|
||||
+ *
|
||||
+ * 1) Get kaslr_offset and phys_base using the above solution.
|
||||
+ * 2) Get kernel boot parameter from "saved_command_line"
|
||||
+ * 3) If "elfcorehdr=" is not included in boot parameter, we are in the
|
||||
+ * first kernel, nothing to do any more.
|
||||
+ * 4) If "elfcorehdr=" is included in boot parameter, we are in the 2nd
|
||||
+ * kernel. Retrieve vmcoreinfo from address of "elfcorehdr=" and
|
||||
+ * get kaslr_offset and phys_base from vmcoreinfo.
|
||||
+ */
|
||||
+int
|
||||
+sadump_calc_kaslr_offset(ulong *kaslr_offset)
|
||||
+{
|
||||
+ ulong phys_base = 0;
|
||||
+ struct sadump_smram_cpu_state scs;
|
||||
+ uint64_t idtr = 0, cr3 = 0, idtr_paddr;
|
||||
+ ulong divide_error_vmcore;
|
||||
+ ulong kaslr_offset_kdump, phys_base_kdump;
|
||||
+ int ret = FALSE;
|
||||
+ int verbose = CRASHDEBUG(1)? 1: 0;
|
||||
+
|
||||
+ if (!machine_type("X86_64"))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ memset(&scs, 0, sizeof(scs));
|
||||
+ get_sadump_smram_cpu_state_any(&scs);
|
||||
+ cr3 = scs.Cr3;
|
||||
+ idtr = ((uint64_t)scs.IdtUpper)<<32 | (uint64_t)scs.IdtLower;
|
||||
+
|
||||
+ /*
|
||||
+ * Set up for kvtop.
|
||||
+ *
|
||||
+ * calc_kaslr_offset() is called before machdep_init(PRE_GDB), so some
|
||||
+ * variables are not initialized yet. Set up them here to call kvtop().
|
||||
+ *
|
||||
+ * TODO: XEN and 5-level is not supported
|
||||
+ */
|
||||
+ vt->kernel_pgd[0] = cr3;
|
||||
+ machdep->machspec->last_pml4_read = vt->kernel_pgd[0];
|
||||
+ machdep->machspec->physical_mask_shift = __PHYSICAL_MASK_SHIFT_2_6;
|
||||
+ machdep->machspec->pgdir_shift = PGDIR_SHIFT;
|
||||
+ if (!readmem(cr3, PHYSADDR, machdep->machspec->pml4, PAGESIZE(),
|
||||
+ "cr3", RETURN_ON_ERROR))
|
||||
+ goto quit;
|
||||
+
|
||||
+ /* Convert virtual address of IDT table to physical address */
|
||||
+ if (!kvtop(NULL, idtr, &idtr_paddr, verbose))
|
||||
+ goto quit;
|
||||
+
|
||||
+ /* Now we can calculate kaslr_offset and phys_base */
|
||||
+ divide_error_vmcore = get_vec0_addr(idtr_paddr);
|
||||
+ *kaslr_offset = divide_error_vmcore - st->divide_error_vmlinux;
|
||||
+ phys_base = idtr_paddr -
|
||||
+ (st->idt_table_vmlinux + *kaslr_offset - __START_KERNEL_map);
|
||||
+
|
||||
+ if (CRASHDEBUG(1)) {
|
||||
+ fprintf(fp, "calc_kaslr_offset: idtr=%lx\n", idtr);
|
||||
+ fprintf(fp, "calc_kaslr_offset: cr3=%lx\n", cr3);
|
||||
+ fprintf(fp, "calc_kaslr_offset: idtr(phys)=%lx\n", idtr_paddr);
|
||||
+ fprintf(fp, "calc_kaslr_offset: divide_error(vmlinux): %lx\n",
|
||||
+ st->divide_error_vmlinux);
|
||||
+ fprintf(fp, "calc_kaslr_offset: divide_error(vmcore): %lx\n",
|
||||
+ divide_error_vmcore);
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Check if current kaslr_offset/phys_base is for 1st kernel or 2nd
|
||||
+ * kernel. If we are in 2nd kernel, get kaslr_offset/phys_base
|
||||
+ * from vmcoreinfo
|
||||
+ */
|
||||
+ if (get_kaslr_offset_from_vmcoreinfo(
|
||||
+ cr3, *kaslr_offset, &kaslr_offset_kdump, &phys_base_kdump)) {
|
||||
+ *kaslr_offset = kaslr_offset_kdump;
|
||||
+ phys_base = phys_base_kdump;
|
||||
+ }
|
||||
+
|
||||
+ if (CRASHDEBUG(1)) {
|
||||
+ fprintf(fp, "calc_kaslr_offset: kaslr_offset=%lx\n",
|
||||
+ *kaslr_offset);
|
||||
+ fprintf(fp, "calc_kaslr_offset: phys_base=%lx\n", phys_base);
|
||||
+ }
|
||||
+
|
||||
+ sd->phys_base = phys_base;
|
||||
+ ret = TRUE;
|
||||
+quit:
|
||||
+ vt->kernel_pgd[0] = 0;
|
||||
+ machdep->machspec->last_pml4_read = 0;
|
||||
+ return ret;
|
||||
+}
|
||||
+#else
|
||||
+int
|
||||
+sadump_calc_kaslr_offset(ulong *kaslr_offset)
|
||||
+{
|
||||
+ return FALSE;
|
||||
+}
|
||||
+#endif /* X86_64 */
|
||||
diff --git a/sadump.h b/sadump.h
|
||||
index 7f8e384..681f5e4 100644
|
||||
--- a/sadump.h
|
||||
+++ b/sadump.h
|
||||
@@ -219,6 +219,7 @@ struct sadump_data {
|
||||
ulonglong backup_offset;
|
||||
|
||||
uint64_t max_mapnr;
|
||||
+ ulong phys_base;
|
||||
};
|
||||
|
||||
struct sadump_data *sadump_get_sadump_data(void);
|
||||
diff --git a/symbols.c b/symbols.c
|
||||
index 02cb34e..e7eaac2 100644
|
||||
--- a/symbols.c
|
||||
+++ b/symbols.c
|
||||
@@ -624,6 +624,9 @@ kaslr_init(void)
|
||||
st->_stext_vmlinux = UNINITIALIZED;
|
||||
@@ -1133,6 +1133,9 @@ symname_hash_install(struct syment *spn)
|
||||
}
|
||||
}
|
||||
}
|
||||
+
|
||||
@@ -558,48 +34,3 @@ index 02cb34e..e7eaac2 100644
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -637,6 +640,19 @@ derive_kaslr_offset(bfd *abfd, int dynamic, bfd_byte *start, bfd_byte *end,
|
||||
unsigned long relocate;
|
||||
ulong _stext_relocated;
|
||||
|
||||
+ if (SADUMP_DUMPFILE()) {
|
||||
+ ulong kaslr_offset = 0;
|
||||
+
|
||||
+ sadump_calc_kaslr_offset(&kaslr_offset);
|
||||
+
|
||||
+ if (kaslr_offset) {
|
||||
+ kt->relocate = kaslr_offset * -1;
|
||||
+ kt->flags |= RELOC_SET;
|
||||
+ }
|
||||
+
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
if (ACTIVE()) {
|
||||
_stext_relocated = symbol_value_from_proc_kallsyms("_stext");
|
||||
if (_stext_relocated == BADVAL)
|
||||
@@ -12246,6 +12262,24 @@ numeric_forward(const void *P_x, const void *P_y)
|
||||
}
|
||||
}
|
||||
|
||||
+ if (SADUMP_DUMPFILE()) {
|
||||
+ /* Need for kaslr_offset and phys_base */
|
||||
+ if (STREQ(x->name, "divide_error"))
|
||||
+ st->divide_error_vmlinux = valueof(x);
|
||||
+ else if (STREQ(y->name, "divide_error"))
|
||||
+ st->divide_error_vmlinux = valueof(y);
|
||||
+
|
||||
+ if (STREQ(x->name, "idt_table"))
|
||||
+ st->idt_table_vmlinux = valueof(x);
|
||||
+ else if (STREQ(y->name, "idt_table"))
|
||||
+ st->idt_table_vmlinux = valueof(y);
|
||||
+
|
||||
+ if (STREQ(x->name, "saved_command_line"))
|
||||
+ st->saved_command_line_vmlinux = valueof(x);
|
||||
+ else if (STREQ(y->name, "saved_command_line"))
|
||||
+ st->saved_command_line_vmlinux = valueof(y);
|
||||
+ }
|
||||
+
|
||||
xs = bfd_get_section(x);
|
||||
ys = bfd_get_section(y);
|
||||
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
From: Petr Tesarik <ptesarik@suse.com>
|
||||
Subject: Extend Xen hypervisor direct mapping on x86_64
|
||||
References: bsc#1073993
|
||||
Upstream: merged
|
||||
Git-commit: e9ae5eb9749a62060610dc29d1b2829999bc79d3
|
||||
|
||||
Xen commit 615588563e99a23aaf37037c3fee0c413b051f4d (Xen 4.0.0.)
|
||||
extended the direct mapping to 5 TB. This area was previously
|
||||
reserved for future use, so it is OK to simply change the upper
|
||||
bound unconditionally.
|
||||
|
||||
Signed-off-by: Petr Tesarik <ptesarik@suse.com>
|
||||
---
|
||||
xen_hyper_defs.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/xen_hyper_defs.h b/xen_hyper_defs.h
|
||||
index 6d5d256..b871bdd 100644
|
||||
--- a/xen_hyper_defs.h
|
||||
+++ b/xen_hyper_defs.h
|
||||
@@ -63,7 +63,7 @@
|
||||
#define HYPERVISOR_VIRT_START (0xffff800000000000)
|
||||
#define HYPERVISOR_VIRT_END (0xffff880000000000)
|
||||
#define DIRECTMAP_VIRT_START (0xffff830000000000)
|
||||
-#define DIRECTMAP_VIRT_END (0xffff840000000000)
|
||||
+#define DIRECTMAP_VIRT_END (0xffff880000000000)
|
||||
#define PAGE_OFFSET_XEN_HYPER DIRECTMAP_VIRT_START
|
||||
#define XEN_VIRT_START (xht->xen_virt_start)
|
||||
#define XEN_VIRT_ADDR(vaddr) \
|
||||
@@ -1,80 +0,0 @@
|
||||
From: Nikola Pajkovsky <npajkovsky@suse.cz>
|
||||
Subject: dynamically allocate schedulers_buf
|
||||
References: bsc#1073993
|
||||
Upstream: merged
|
||||
Git-commit: e4499a9de664826b0db2f650684959c2f3f9998c
|
||||
|
||||
crash can simply determinate length of xen schedulers struct.
|
||||
|
||||
static const struct scheduler *schedulers[] = {
|
||||
...
|
||||
};
|
||||
|
||||
Signed-off-by: Nikola Pajkovsky <npajkovsky@suse.cz>
|
||||
---
|
||||
xen_hyper.c | 15 +++++++++------
|
||||
1 file changed, 9 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/xen_hyper.c b/xen_hyper.c
|
||||
index 27e44c6e733d..479aa1acfd43 100644
|
||||
--- a/xen_hyper.c
|
||||
+++ b/xen_hyper.c
|
||||
@@ -435,7 +435,6 @@ xen_hyper_misc_init(void)
|
||||
/*
|
||||
* Do initialization for scheduler of Xen Hyper system here.
|
||||
*/
|
||||
-#define XEN_HYPER_SCHEDULERS_ARRAY_CNT 10
|
||||
#define XEN_HYPER_SCHEDULER_NAME 1024
|
||||
|
||||
static void
|
||||
@@ -443,7 +442,8 @@ xen_hyper_schedule_init(void)
|
||||
{
|
||||
ulong addr, opt_sched, schedulers, opt_name;
|
||||
long scheduler_opt_name;
|
||||
- long schedulers_buf[XEN_HYPER_SCHEDULERS_ARRAY_CNT];
|
||||
+ long *schedulers_buf;
|
||||
+ int nr_schedulers;
|
||||
struct xen_hyper_sched_context *schc;
|
||||
char *buf;
|
||||
char opt_name_buf[XEN_HYPER_OPT_SCHED_SIZE];
|
||||
@@ -469,15 +469,17 @@ xen_hyper_schedule_init(void)
|
||||
XEN_HYPER_OPT_SCHED_SIZE, "opt_sched,", RETURN_ON_ERROR)) {
|
||||
error(FATAL, "cannot read opt_sched,.\n");
|
||||
}
|
||||
+ nr_schedulers = get_array_length("schedulers", 0, 0);
|
||||
+ schedulers_buf = (long *)GETBUF(nr_schedulers * sizeof(long));
|
||||
schedulers = symbol_value("schedulers");
|
||||
addr = schedulers;
|
||||
while (xhscht->name == NULL) {
|
||||
if (!readmem(addr, KVADDR, schedulers_buf,
|
||||
- sizeof(long) * XEN_HYPER_SCHEDULERS_ARRAY_CNT,
|
||||
- "schedulers", RETURN_ON_ERROR)) {
|
||||
+ sizeof(long) * nr_schedulers,
|
||||
+ "schedulers", RETURN_ON_ERROR)) {
|
||||
error(FATAL, "cannot read schedulers.\n");
|
||||
}
|
||||
- for (i = 0; i < XEN_HYPER_SCHEDULERS_ARRAY_CNT; i++) {
|
||||
+ for (i = 0; i < nr_schedulers; i++) {
|
||||
if (schedulers_buf[i] == 0) {
|
||||
error(FATAL, "schedule data not found.\n");
|
||||
}
|
||||
@@ -514,9 +516,10 @@ xen_hyper_schedule_init(void)
|
||||
strncpy(xhscht->name, buf, strlen(buf));
|
||||
break;
|
||||
}
|
||||
- addr += sizeof(long) * XEN_HYPER_SCHEDULERS_ARRAY_CNT;
|
||||
+ addr += sizeof(long) * nr_schedulers;
|
||||
}
|
||||
FREEBUF(buf);
|
||||
+ FREEBUF(schedulers_buf);
|
||||
|
||||
/* get schedule_data information */
|
||||
if((xhscht->sched_context_array =
|
||||
--
|
||||
2.13.6
|
||||
|
||||
--
|
||||
Crash-utility mailing list
|
||||
Crash-utility@redhat.com
|
||||
https://www.redhat.com/mailman/listinfo/crash-utility
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
From: Nikola Pajkovsky <npajkovsky@suse.cz>
|
||||
Subject: fix error crash: cannot resolve "schedulers"
|
||||
References: bsc#1073993
|
||||
Upstream: merged
|
||||
Git-commit: e4499a9de664826b0db2f650684959c2f3f9998c
|
||||
|
||||
Since Xen commit 666aca08175b ("sched: use the auto-generated list of
|
||||
schedulers") crash cannot open Xen vmcores, because symbol 'schedulers'
|
||||
does not exist. Xen 4.7 implemented schedulers as its own section.
|
||||
|
||||
xen/arch/x86/xen.lds.S
|
||||
__start_schedulers_array = .;
|
||||
*(.data.schedulers)
|
||||
__end_schedulers_array = .;
|
||||
|
||||
Crash must not look up for "schedulers" symbol and fails, if symbol is
|
||||
not found. It must check if __start_schedulers_array exits, and if it
|
||||
does, use it and get size of the section. Otherwise, crash fallback to
|
||||
looking up "schedulers" symbol. That way, crash can open vmcore before
|
||||
and after Xen 4.7.
|
||||
|
||||
Signed-off-by: Nikola Pajkovsky <npajkovsky@suse.cz>
|
||||
---
|
||||
xen_hyper.c | 25 +++++++++++++++++++++++--
|
||||
1 file changed, 23 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/xen_hyper.c b/xen_hyper.c
|
||||
index 479aa1acfd43..2a42e44b1f70 100644
|
||||
--- a/xen_hyper.c
|
||||
+++ b/xen_hyper.c
|
||||
@@ -437,6 +437,16 @@ xen_hyper_misc_init(void)
|
||||
*/
|
||||
#define XEN_HYPER_SCHEDULER_NAME 1024
|
||||
|
||||
+static int section_size(char *start_section, char *end_section)
|
||||
+{
|
||||
+ ulong sp_start, sp_end;
|
||||
+
|
||||
+ sp_start = symbol_value(start_section);
|
||||
+ sp_end = symbol_value(end_section);
|
||||
+
|
||||
+ return (sp_end - sp_start) / sizeof(long);
|
||||
+}
|
||||
+
|
||||
static void
|
||||
xen_hyper_schedule_init(void)
|
||||
{
|
||||
@@ -448,6 +458,7 @@ xen_hyper_schedule_init(void)
|
||||
char *buf;
|
||||
char opt_name_buf[XEN_HYPER_OPT_SCHED_SIZE];
|
||||
int i, cpuid, flag;
|
||||
+ char *sp_name;
|
||||
|
||||
/* get scheduler information */
|
||||
if((xhscht->scheduler_struct =
|
||||
@@ -469,9 +480,19 @@ xen_hyper_schedule_init(void)
|
||||
XEN_HYPER_OPT_SCHED_SIZE, "opt_sched,", RETURN_ON_ERROR)) {
|
||||
error(FATAL, "cannot read opt_sched,.\n");
|
||||
}
|
||||
- nr_schedulers = get_array_length("schedulers", 0, 0);
|
||||
+
|
||||
+ /* symbol exists since Xen 4.7 */
|
||||
+ if (symbol_exists("__start_schedulers_array")) {
|
||||
+ sp_name = "__start_schedulers_array";
|
||||
+ nr_schedulers = section_size("__start_schedulers_array",
|
||||
+ "__end_schedulers_array");
|
||||
+ } else {
|
||||
+ sp_name = "schedulers";
|
||||
+ nr_schedulers = get_array_length("schedulers", 0, 0);
|
||||
+ }
|
||||
+
|
||||
schedulers_buf = (long *)GETBUF(nr_schedulers * sizeof(long));
|
||||
- schedulers = symbol_value("schedulers");
|
||||
+ schedulers = symbol_value(sp_name);
|
||||
addr = schedulers;
|
||||
while (xhscht->name == NULL) {
|
||||
if (!readmem(addr, KVADDR, schedulers_buf,
|
||||
--
|
||||
2.13.6
|
||||
|
||||
--
|
||||
Crash-utility mailing list
|
||||
Crash-utility@redhat.com
|
||||
https://www.redhat.com/mailman/listinfo/crash-utility
|
||||
@@ -1,52 +0,0 @@
|
||||
Update for support of Linux 4.14 and later PPC64 kernels where the
|
||||
|
||||
From: Dave Anderson <anderson@redhat.com>
|
||||
|
||||
hash page table geometry accomodates a larger virtual address range.
|
||||
Without the patch, the virtual-to-physical translation of user space
|
||||
virtual addresses by "vm -p", "vtop", and "rd -u" may generate an
|
||||
invalid translation or otherwise fail.
|
||||
(hbathini@linux.vnet.ibm.com)
|
||||
---
|
||||
defs.h | 3 +++
|
||||
ppc64.c | 12 +++++++++---
|
||||
2 files changed, 12 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/defs.h b/defs.h
|
||||
index 154a5b9..f2c3f50 100644
|
||||
--- a/defs.h
|
||||
+++ b/defs.h
|
||||
@@ -3857,6 +3857,9 @@ struct efi_memory_desc_t {
|
||||
#define PGD_INDEX_SIZE_L4_64K_3_10 12
|
||||
#define PMD_INDEX_SIZE_L4_64K_4_6 5
|
||||
#define PUD_INDEX_SIZE_L4_64K_4_6 5
|
||||
+#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 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 edf46dc..77ac09f 100644
|
||||
--- a/ppc64.c
|
||||
+++ b/ppc64.c
|
||||
@@ -447,10 +447,16 @@ ppc64_init(int when)
|
||||
} else if (!(machdep->flags & BOOK3E) &&
|
||||
(THIS_KERNEL_VERSION >= LINUX(4,6,0))) {
|
||||
m->l1_index_size = PTE_INDEX_SIZE_L4_64K_3_10;
|
||||
- m->l2_index_size = PMD_INDEX_SIZE_L4_64K_4_6;
|
||||
- m->l3_index_size = PUD_INDEX_SIZE_L4_64K_4_6;
|
||||
- m->l4_index_size = PGD_INDEX_SIZE_L4_64K_3_10;
|
||||
|
||||
+ 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;
|
||||
+ m->l4_index_size = PGD_INDEX_SIZE_L4_64K_4_12;
|
||||
+ } else {
|
||||
+ m->l2_index_size = PMD_INDEX_SIZE_L4_64K_4_6;
|
||||
+ m->l3_index_size = PUD_INDEX_SIZE_L4_64K_4_6;
|
||||
+ m->l4_index_size = PGD_INDEX_SIZE_L4_64K_3_10;
|
||||
+ }
|
||||
} else if (THIS_KERNEL_VERSION >= LINUX(3,10,0)) {
|
||||
m->l1_index_size = PTE_INDEX_SIZE_L4_64K_3_10;
|
||||
m->l2_index_size = PMD_INDEX_SIZE_L4_64K_3_10;
|
||||
@@ -1,33 +0,0 @@
|
||||
From: Hari Bathini <hbathini@linux.vnet.ibm.com>
|
||||
Subject: ppc64: fix bt for secondary threads for NMI IPIs
|
||||
References: bsc#1072718
|
||||
Upstream: merged
|
||||
Git-commit: ed2abb47be9846be7a47d769c420ee3992cc0196
|
||||
|
||||
With latest NMI IPI changes, crash_ipi_callback is found multiple times
|
||||
on the stack. Ensure the chosen symbol relates to an actual backtrace.
|
||||
|
||||
Signed-off-by: Hari Bathini <hbathini@linux.vnet.ibm.com>
|
||||
---
|
||||
ppc64.c | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/ppc64.c b/ppc64.c
|
||||
index 672ee60..0b04187 100644
|
||||
--- a/ppc64.c
|
||||
+++ b/ppc64.c
|
||||
@@ -2337,6 +2337,14 @@ retry:
|
||||
*nip = *up;
|
||||
*ksp = bt->stackbase +
|
||||
((char *)(up) - 16 - bt->stackbuf);
|
||||
+ /*
|
||||
+ * Check whether this symbol relates to a
|
||||
+ * backtrace or not
|
||||
+ */
|
||||
+ ur_ksp = *(ulong *)&bt->stackbuf[(*ksp) - bt->stackbase];
|
||||
+ if (!INSTACK(ur_ksp, bt))
|
||||
+ continue;
|
||||
+
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
This patch changes x86_64_kvtop() so that it can be called during
|
||||
symtab_init().
|
||||
|
||||
To solve kaslr problem of sadump, kaslr offset and phys_base need to be
|
||||
calculated before symbol data is loaded. This calculation needs
|
||||
translation of kernel virtual address to physical address. Current
|
||||
x86_64_kvtop() implementation tries to use x86_64_VTOP for translation
|
||||
at first, but this does not work for this purpose because x86_64_VTOP
|
||||
uses phys_base. x86_64_kvtop() need to be changed to skip x86_64_VTOP()
|
||||
during sadump initialization.
|
||||
|
||||
Signed-off-by: Takao Indoh <indou.takao@jp.fujitsu.com>
|
||||
---
|
||||
x86_64.c | 21 +++++++++++++++++++++
|
||||
1 file changed, 21 insertions(+)
|
||||
|
||||
diff --git a/x86_64.c b/x86_64.c
|
||||
index 6e60dda..2f9e6db 100644
|
||||
--- a/x86_64.c
|
||||
+++ b/x86_64.c
|
||||
@@ -194,6 +194,9 @@ x86_64_init(int when)
|
||||
machdep->machspec->kernel_image_size = dtol(string, QUIET, NULL);
|
||||
free(string);
|
||||
}
|
||||
+ if (SADUMP_DUMPFILE())
|
||||
+ /* Need for calculation of kaslr_offset and phys_base */
|
||||
+ machdep->kvtop = x86_64_kvtop;
|
||||
break;
|
||||
|
||||
case PRE_GDB:
|
||||
@@ -2019,6 +2022,22 @@ x86_64_kvtop(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbo
|
||||
ulong pte;
|
||||
physaddr_t physpage;
|
||||
|
||||
+ if (SADUMP_DUMPFILE() && !(machdep->flags & KSYMS_START)) {
|
||||
+ /*
|
||||
+ * In the case of sadump, to calculate kaslr_offset and
|
||||
+ * phys_base, kvtop is called during symtab_init(). In this
|
||||
+ * stage phys_base is not initialized yet and x86_64_VTOP()
|
||||
+ * does not work. Jump to the code of pagetable translation.
|
||||
+ */
|
||||
+ FILL_PML4();
|
||||
+ pml4 = ((ulong *)machdep->machspec->pml4) + pml4_index(kvaddr);
|
||||
+ if (verbose) {
|
||||
+ fprintf(fp, "PML4 DIRECTORY: %lx\n", vt->kernel_pgd[0]);
|
||||
+ fprintf(fp, "PAGE DIRECTORY: %lx\n", *pml4);
|
||||
+ }
|
||||
+ goto start_vtop_with_pagetable;
|
||||
+ }
|
||||
+
|
||||
if (!IS_KVADDR(kvaddr))
|
||||
return FALSE;
|
||||
|
||||
@@ -2065,6 +2084,8 @@ x86_64_kvtop(struct task_context *tc, ulong kvaddr, physaddr_t *paddr, int verbo
|
||||
fprintf(fp, "PAGE DIRECTORY: %lx\n", *pml4);
|
||||
}
|
||||
}
|
||||
+
|
||||
+start_vtop_with_pagetable:
|
||||
if (!(*pml4) & _PAGE_PRESENT)
|
||||
goto no_kpage;
|
||||
pgd_paddr = (*pml4) & PHYSICAL_PAGE_MASK;
|
||||
Reference in New Issue
Block a user