update to version 2.0.23
This commit is contained in:
parent
6ae67c6fff
commit
6db177884b
@ -1,25 +0,0 @@
|
||||
From 4c95454cd8f8ebdaf065b99ec89c7b0da743df37 Mon Sep 17 00:00:00 2001
|
||||
From: zwx1052249 <zhouwenpei1@Huawei.com>
|
||||
Date: Tue, 27 Jul 2021 10:15:46 +0800
|
||||
Subject: [PATCH] fix build fail caused by file format not recognized
|
||||
|
||||
---
|
||||
.../libeppic/Makefile | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/eppic-d84c3541035d95077aa8571f5d5c3e07c6ef510b/libeppic/Makefile b/eppic-d84c3541035d95077aa8571f5d5c3e07c6ef510b/libeppic/Makefile
|
||||
index 8b97c87..1debebe 100644
|
||||
--- a/eppic-d84c3541035d95077aa8571f5d5c3e07c6ef510b/libeppic/Makefile
|
||||
+++ b/eppic-d84c3541035d95077aa8571f5d5c3e07c6ef510b/libeppic/Makefile
|
||||
@@ -104,7 +104,7 @@ default: $(TARGETS)
|
||||
$(CFILES): $(HFILES) eppic.tab.h
|
||||
|
||||
$(TARGETS): $(OFILES)
|
||||
- $(AR) ccurl $(TARGETS) $(OFILES)
|
||||
+ $(AR) rs $(TARGETS) $(OFILES)
|
||||
|
||||
clean:
|
||||
-/bin/rm -f *.o $(TARGETS) $(LDIRT)
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -1,176 +0,0 @@
|
||||
From a7c4cb8e998571cb3dd62e907935a1e052b15d6c Mon Sep 17 00:00:00 2001
|
||||
From: Lianbo Jiang <lijiang@redhat.com>
|
||||
Date: Fri, 23 Aug 2019 20:05:38 +0800
|
||||
Subject: [PATCH] Cleanup: move it back from util_lib/elf_info.c
|
||||
|
||||
Some code related to vmcore-dmesg.c is put into the util_lib, which
|
||||
is not very reasonable, so lets move it back and tidy up those code.
|
||||
|
||||
In addition, that will also help to limit the size of vmcore-dmesg.txt
|
||||
in vmcore-dmesg.c instead of elf_info.c.
|
||||
|
||||
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||
Signed-off-by: Simon Horman <horms@verge.net.au>
|
||||
|
||||
diff --git a/util_lib/elf_info.c b/util_lib/elf_info.c
|
||||
index 5d0efaa..2bce5cb 100644
|
||||
--- a/util_lib/elf_info.c
|
||||
+++ b/util_lib/elf_info.c
|
||||
@@ -531,19 +531,7 @@ static int32_t read_file_s32(int fd, uint64_t addr)
|
||||
return read_file_u32(fd, addr);
|
||||
}
|
||||
|
||||
-static void write_to_stdout(char *buf, unsigned int nr)
|
||||
-{
|
||||
- ssize_t ret;
|
||||
-
|
||||
- ret = write(STDOUT_FILENO, buf, nr);
|
||||
- if (ret != nr) {
|
||||
- fprintf(stderr, "Failed to write out the dmesg log buffer!:"
|
||||
- " %s\n", strerror(errno));
|
||||
- exit(54);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-static void dump_dmesg_legacy(int fd)
|
||||
+static void dump_dmesg_legacy(int fd, void (*handler)(char*, unsigned int))
|
||||
{
|
||||
uint64_t log_buf, log_buf_offset;
|
||||
unsigned log_end, logged_chars, log_end_wrapped;
|
||||
@@ -604,7 +592,8 @@ static void dump_dmesg_legacy(int fd)
|
||||
*/
|
||||
logged_chars = log_end < log_buf_len ? log_end : log_buf_len;
|
||||
|
||||
- write_to_stdout(buf + (log_buf_len - logged_chars), logged_chars);
|
||||
+ if (handler)
|
||||
+ handler(buf + (log_buf_len - logged_chars), logged_chars);
|
||||
}
|
||||
|
||||
static inline uint16_t struct_val_u16(char *ptr, unsigned int offset)
|
||||
@@ -623,7 +612,7 @@ static inline uint64_t struct_val_u64(char *ptr, unsigned int offset)
|
||||
}
|
||||
|
||||
/* Read headers of log records and dump accordingly */
|
||||
-static void dump_dmesg_structured(int fd)
|
||||
+static void dump_dmesg_structured(int fd, void (*handler)(char*, unsigned int))
|
||||
{
|
||||
#define OUT_BUF_SIZE 4096
|
||||
uint64_t log_buf, log_buf_offset, ts_nsec;
|
||||
@@ -733,7 +722,8 @@ static void dump_dmesg_structured(int fd)
|
||||
out_buf[len++] = c;
|
||||
|
||||
if (len >= OUT_BUF_SIZE - 64) {
|
||||
- write_to_stdout(out_buf, len);
|
||||
+ if (handler)
|
||||
+ handler(out_buf, len);
|
||||
len = 0;
|
||||
}
|
||||
}
|
||||
@@ -752,16 +742,16 @@ static void dump_dmesg_structured(int fd)
|
||||
current_idx += loglen;
|
||||
}
|
||||
free(buf);
|
||||
- if (len)
|
||||
- write_to_stdout(out_buf, len);
|
||||
+ if (len && handler)
|
||||
+ handler(out_buf, len);
|
||||
}
|
||||
|
||||
-static void dump_dmesg(int fd)
|
||||
+void dump_dmesg(int fd, void (*handler)(char*, unsigned int))
|
||||
{
|
||||
if (log_first_idx_vaddr)
|
||||
- dump_dmesg_structured(fd);
|
||||
+ dump_dmesg_structured(fd, handler);
|
||||
else
|
||||
- dump_dmesg_legacy(fd);
|
||||
+ dump_dmesg_legacy(fd, handler);
|
||||
}
|
||||
|
||||
int read_elf(int fd)
|
||||
@@ -808,22 +798,6 @@ int read_elf(int fd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-int read_elf_vmcore(int fd)
|
||||
-{
|
||||
- int ret;
|
||||
-
|
||||
- ret = read_elf(fd);
|
||||
- if (ret > 0) {
|
||||
- fprintf(stderr, "Unable to read ELF information"
|
||||
- " from vmcore\n");
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
- dump_dmesg(fd);
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
int read_phys_offset_elf_kcore(int fd, unsigned long *phys_off)
|
||||
{
|
||||
int ret;
|
||||
diff --git a/util_lib/include/elf_info.h b/util_lib/include/elf_info.h
|
||||
index c328a1b..4bc9279 100644
|
||||
--- a/util_lib/include/elf_info.h
|
||||
+++ b/util_lib/include/elf_info.h
|
||||
@@ -30,6 +30,6 @@ int get_pt_load(int idx,
|
||||
unsigned long long *virt_end);
|
||||
int read_phys_offset_elf_kcore(int fd, unsigned long *phys_off);
|
||||
int read_elf(int fd);
|
||||
-int read_elf_vmcore(int fd);
|
||||
+void dump_dmesg(int fd, void (*handler)(char*, unsigned int));
|
||||
|
||||
#endif /* ELF_INFO_H */
|
||||
diff --git a/vmcore-dmesg/vmcore-dmesg.c b/vmcore-dmesg/vmcore-dmesg.c
|
||||
index bebc348..fe7df8e 100644
|
||||
--- a/vmcore-dmesg/vmcore-dmesg.c
|
||||
+++ b/vmcore-dmesg/vmcore-dmesg.c
|
||||
@@ -5,6 +5,34 @@ typedef Elf32_Nhdr Elf_Nhdr;
|
||||
|
||||
extern const char *fname;
|
||||
|
||||
+static void write_to_stdout(char *buf, unsigned int nr)
|
||||
+{
|
||||
+ ssize_t ret;
|
||||
+
|
||||
+ ret = write(STDOUT_FILENO, buf, nr);
|
||||
+ if (ret != nr) {
|
||||
+ fprintf(stderr, "Failed to write out the dmesg log buffer!:"
|
||||
+ " %s\n", strerror(errno));
|
||||
+ exit(54);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int read_vmcore_dmesg(int fd, void (*handler)(char*, unsigned int))
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = read_elf(fd);
|
||||
+ if (ret > 0) {
|
||||
+ fprintf(stderr, "Unable to read ELF information"
|
||||
+ " from vmcore\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ dump_dmesg(fd, handler);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
ssize_t ret;
|
||||
@@ -23,7 +51,7 @@ int main(int argc, char **argv)
|
||||
return 2;
|
||||
}
|
||||
|
||||
- ret = read_elf_vmcore(fd);
|
||||
+ ret = read_vmcore_dmesg(fd, write_to_stdout);
|
||||
|
||||
close(fd);
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,79 +0,0 @@
|
||||
From 545c811050a375f79e0fa0e107cb35b9ae3a1599 Mon Sep 17 00:00:00 2001
|
||||
From: Lianbo Jiang <lijiang@redhat.com>
|
||||
Date: Fri, 23 Aug 2019 20:05:36 +0800
|
||||
Subject: [PATCH] Cleanup: remove the read_elf_kcore()
|
||||
|
||||
Here, no need to wrap the read_elf() again, lets invoke it directly.
|
||||
So remove the read_elf_kcore() and clean up redundant code.
|
||||
|
||||
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||
Signed-off-by: Simon Horman <horms@verge.net.au>
|
||||
|
||||
diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
|
||||
index eb3a3a3..6ad3b0a 100644
|
||||
--- a/kexec/arch/arm64/kexec-arm64.c
|
||||
+++ b/kexec/arch/arm64/kexec-arm64.c
|
||||
@@ -889,7 +889,7 @@ int get_phys_base_from_pt_load(unsigned long *phys_offset)
|
||||
return EFAILED;
|
||||
}
|
||||
|
||||
- read_elf_kcore(fd);
|
||||
+ read_elf(fd);
|
||||
|
||||
for (i = 0; get_pt_load(i,
|
||||
&phys_start, NULL, &virt_start, NULL);
|
||||
diff --git a/util_lib/elf_info.c b/util_lib/elf_info.c
|
||||
index 90a3b21..d9397ec 100644
|
||||
--- a/util_lib/elf_info.c
|
||||
+++ b/util_lib/elf_info.c
|
||||
@@ -764,7 +764,7 @@ static void dump_dmesg(int fd)
|
||||
dump_dmesg_legacy(fd);
|
||||
}
|
||||
|
||||
-static int read_elf(int fd)
|
||||
+int read_elf(int fd)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -824,24 +824,13 @@ int read_elf_vmcore(int fd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-int read_elf_kcore(int fd)
|
||||
-{
|
||||
- int ret;
|
||||
-
|
||||
- ret = read_elf(fd);
|
||||
- if (ret != 0)
|
||||
- return ret;
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
int read_phys_offset_elf_kcore(int fd, unsigned long *phys_off)
|
||||
{
|
||||
int ret;
|
||||
|
||||
*phys_off = UINT64_MAX;
|
||||
|
||||
- ret = read_elf_kcore(fd);
|
||||
+ ret = read_elf(fd);
|
||||
if (!ret) {
|
||||
/* If we have a valid 'PHYS_OFFSET' by now,
|
||||
* return it to the caller now.
|
||||
diff --git a/util_lib/include/elf_info.h b/util_lib/include/elf_info.h
|
||||
index 1a4debd..c328a1b 100644
|
||||
--- a/util_lib/include/elf_info.h
|
||||
+++ b/util_lib/include/elf_info.h
|
||||
@@ -29,7 +29,7 @@ int get_pt_load(int idx,
|
||||
unsigned long long *virt_start,
|
||||
unsigned long long *virt_end);
|
||||
int read_phys_offset_elf_kcore(int fd, unsigned long *phys_off);
|
||||
-int read_elf_kcore(int fd);
|
||||
+int read_elf(int fd);
|
||||
int read_elf_vmcore(int fd);
|
||||
|
||||
#endif /* ELF_INFO_H */
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,43 +0,0 @@
|
||||
From 14ad054e7baa788a6629385ffe5e0f1996b7de02 Mon Sep 17 00:00:00 2001
|
||||
From: Lianbo Jiang <lijiang@redhat.com>
|
||||
Date: Fri, 23 Aug 2019 20:05:37 +0800
|
||||
Subject: [PATCH] Fix an error definition about the variable 'fname'
|
||||
|
||||
The variable 'fname' is mistakenly defined two twice, the first definition
|
||||
is in the vmcore-dmesg.c, and the second definition is in the elf_info.c.
|
||||
That is confused and incorrect although it's a static type, because the
|
||||
value of variable 'fname' is not assigned(set) in elf_info.c. Anyway, its
|
||||
value will be always 'null' when printing an error information.
|
||||
|
||||
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||
Signed-off-by: Simon Horman <horms@verge.net.au>
|
||||
|
||||
diff --git a/util_lib/elf_info.c b/util_lib/elf_info.c
|
||||
index d9397ec..5d0efaa 100644
|
||||
--- a/util_lib/elf_info.c
|
||||
+++ b/util_lib/elf_info.c
|
||||
@@ -20,7 +20,7 @@
|
||||
/* The 32bit and 64bit note headers make it clear we don't care */
|
||||
typedef Elf32_Nhdr Elf_Nhdr;
|
||||
|
||||
-static const char *fname;
|
||||
+const char *fname;
|
||||
static Elf64_Ehdr ehdr;
|
||||
static Elf64_Phdr *phdr;
|
||||
static int num_pt_loads;
|
||||
diff --git a/vmcore-dmesg/vmcore-dmesg.c b/vmcore-dmesg/vmcore-dmesg.c
|
||||
index 7a386b3..bebc348 100644
|
||||
--- a/vmcore-dmesg/vmcore-dmesg.c
|
||||
+++ b/vmcore-dmesg/vmcore-dmesg.c
|
||||
@@ -3,7 +3,7 @@
|
||||
/* The 32bit and 64bit note headers make it clear we don't care */
|
||||
typedef Elf32_Nhdr Elf_Nhdr;
|
||||
|
||||
-static const char *fname;
|
||||
+extern const char *fname;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,52 +0,0 @@
|
||||
From fa3f0ed47f3e6dbee485722d13713ad495571b7e Mon Sep 17 00:00:00 2001
|
||||
From: Lianbo Jiang <lijiang@redhat.com>
|
||||
Date: Fri, 23 Aug 2019 20:05:39 +0800
|
||||
Subject: [PATCH] Limit the size of vmcore-dmesg.txt to 2G
|
||||
|
||||
With some corrupted vmcore files, the vmcore-dmesg.txt file may grow
|
||||
forever till the kdump disk becomes full, and also probably causes
|
||||
the disk error messages as follow:
|
||||
...
|
||||
sd 0:0:0:0: [sda] tag#6 FAILED Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK
|
||||
sd 0:0:0:0: [sda] tag#6 CDB: Read(10) 28 00 08 06 4c 98 00 00 08 00
|
||||
blk_update_request: I/O error, dev sda, sector 134630552
|
||||
sd 0:0:0:0: [sda] tag#7 FAILED Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK
|
||||
sd 0:0:0:0: [sda] tag#7 CDB: Read(10) 28 00 08 06 4c 98 00 00 08 00
|
||||
blk_update_request: I/O error, dev sda, sector 134630552
|
||||
...
|
||||
|
||||
If vmcore-dmesg.txt occupies the whole disk, the vmcore can not be
|
||||
saved, this is also a problem.
|
||||
|
||||
Lets limit the size of vmcore-dmesg.txt to avoid such problems.
|
||||
|
||||
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||
Signed-off-by: Simon Horman <horms@verge.net.au>
|
||||
|
||||
diff --git a/vmcore-dmesg/vmcore-dmesg.c b/vmcore-dmesg/vmcore-dmesg.c
|
||||
index fe7df8e..81c2a58 100644
|
||||
--- a/vmcore-dmesg/vmcore-dmesg.c
|
||||
+++ b/vmcore-dmesg/vmcore-dmesg.c
|
||||
@@ -5,9 +5,19 @@ typedef Elf32_Nhdr Elf_Nhdr;
|
||||
|
||||
extern const char *fname;
|
||||
|
||||
+/* stole this macro from kernel printk.c */
|
||||
+#define LOG_BUF_LEN_MAX (uint32_t)(1 << 31)
|
||||
+
|
||||
static void write_to_stdout(char *buf, unsigned int nr)
|
||||
{
|
||||
ssize_t ret;
|
||||
+ static uint32_t n_bytes = 0;
|
||||
+
|
||||
+ n_bytes += nr;
|
||||
+ if (n_bytes > LOG_BUF_LEN_MAX) {
|
||||
+ fprintf(stderr, "The vmcore-dmesg.txt over 2G in size is not supported.\n");
|
||||
+ exit(53);
|
||||
+ }
|
||||
|
||||
ret = write(STDOUT_FILENO, buf, nr);
|
||||
if (ret != nr) {
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -12,8 +12,8 @@ Signed-off-by: pengyeqing <pengyeqing@huawei.com>
|
||||
|
||||
diff --git a/makedumpfile-1.6.7/Makefile b/makedumpfile-1.6.7/Makefile
|
||||
index 612b9d0..180a64f 100644
|
||||
--- a/makedumpfile-1.6.7/Makefile
|
||||
+++ b/makedumpfile-1.6.7/Makefile
|
||||
--- a/makedumpfile-1.7.0/Makefile
|
||||
+++ b/makedumpfile-1.7.0/Makefile
|
||||
@@ -10,9 +10,10 @@ endif
|
||||
|
||||
CFLAGS_BASE := $(CFLAGS) -g -O2 -Wall -D_FILE_OFFSET_BITS=64 \
|
||||
|
||||
@ -1,79 +0,0 @@
|
||||
From 2572b8d702e452624bdb8d7b7c39f458e7dcf2ce Mon Sep 17 00:00:00 2001
|
||||
From: AKASHI Takahiro <takahiro.akashi@linaro.org>
|
||||
Date: Wed, 18 Dec 2019 11:42:32 -0500
|
||||
Subject: [PATCH] arm64: kdump: deal with a lot of resource entries in
|
||||
/proc/iomem
|
||||
|
||||
As described in the commit ("arm64: kexec: allocate memory space avoiding
|
||||
reserved regions"), /proc/iomem now has a lot of "reserved" entries, and
|
||||
it's not just enough to have a fixed size of memory range array.
|
||||
|
||||
With this patch, kdump is allowed to handle arbitrary number of memory
|
||||
ranges, using mem_regions_alloc_and_xxx() functions.
|
||||
|
||||
Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
|
||||
Tested-by: Bhupesh Sharma <bhsharma@redhat.com>
|
||||
Tested-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
|
||||
Signed-off-by: Simon Horman <horms@verge.net.au>
|
||||
|
||||
diff --git a/kexec/arch/arm64/crashdump-arm64.c b/kexec/arch/arm64/crashdump-arm64.c
|
||||
index 4fd7aa8..38d1a0f 100644
|
||||
--- a/kexec/arch/arm64/crashdump-arm64.c
|
||||
+++ b/kexec/arch/arm64/crashdump-arm64.c
|
||||
@@ -23,13 +23,8 @@
|
||||
#include "kexec-elf.h"
|
||||
#include "mem_regions.h"
|
||||
|
||||
-/* memory ranges on crashed kernel */
|
||||
-static struct memory_range system_memory_ranges[CRASH_MAX_MEMORY_RANGES];
|
||||
-static struct memory_ranges system_memory_rgns = {
|
||||
- .size = 0,
|
||||
- .max_size = CRASH_MAX_MEMORY_RANGES,
|
||||
- .ranges = system_memory_ranges,
|
||||
-};
|
||||
+/* memory ranges of crashed kernel */
|
||||
+static struct memory_ranges system_memory_rgns;
|
||||
|
||||
/* memory range reserved for crashkernel */
|
||||
struct memory_range crash_reserved_mem;
|
||||
@@ -82,7 +77,7 @@ static uint64_t get_kernel_page_offset(void)
|
||||
*
|
||||
* This function is called once for each memory region found in /proc/iomem.
|
||||
* It locates system RAM and crashkernel reserved memory and places these to
|
||||
- * variables, respectively, system_memory_ranges and crash_reserved_mem.
|
||||
+ * variables, respectively, system_memory_rgns and usablemem_rgns.
|
||||
*/
|
||||
|
||||
static int iomem_range_callback(void *UNUSED(data), int UNUSED(nr),
|
||||
@@ -90,11 +85,11 @@ static int iomem_range_callback(void *UNUSED(data), int UNUSED(nr),
|
||||
unsigned long long length)
|
||||
{
|
||||
if (strncmp(str, CRASH_KERNEL, strlen(CRASH_KERNEL)) == 0)
|
||||
- return mem_regions_add(&usablemem_rgns,
|
||||
- base, length, RANGE_RAM);
|
||||
+ return mem_regions_alloc_and_add(&usablemem_rgns,
|
||||
+ base, length, RANGE_RAM);
|
||||
else if (strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)) == 0)
|
||||
- return mem_regions_add(&system_memory_rgns,
|
||||
- base, length, RANGE_RAM);
|
||||
+ return mem_regions_alloc_and_add(&system_memory_rgns,
|
||||
+ base, length, RANGE_RAM);
|
||||
else if (strncmp(str, KERNEL_CODE, strlen(KERNEL_CODE)) == 0)
|
||||
elf_info.kern_paddr_start = base;
|
||||
else if (strncmp(str, KERNEL_DATA, strlen(KERNEL_DATA)) == 0)
|
||||
@@ -135,9 +130,9 @@ static int crash_get_memory_ranges(void)
|
||||
|
||||
dbgprint_mem_range("Reserved memory range", &crash_reserved_mem, 1);
|
||||
|
||||
- if (mem_regions_exclude(&system_memory_rgns, &crash_reserved_mem)) {
|
||||
- fprintf(stderr,
|
||||
- "Error: Number of crash memory ranges excedeed the max limit\n");
|
||||
+ if (mem_regions_alloc_and_exclude(&system_memory_rgns,
|
||||
+ &crash_reserved_mem)) {
|
||||
+ fprintf(stderr, "Cannot allocate memory for ranges\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,244 +0,0 @@
|
||||
From f736104f533290b4ce6fbfbca74abde9ffd3888c Mon Sep 17 00:00:00 2001
|
||||
From: AKASHI Takahiro <takahiro.akashi@linaro.org>
|
||||
Date: Wed, 18 Dec 2019 11:42:31 -0500
|
||||
Subject: [PATCH] arm64: kexec: allocate memory space avoiding reserved regions
|
||||
|
||||
On UEFI/ACPI-only system, some memory regions, including but not limited
|
||||
to UEFI memory map and ACPI tables, must be preserved across kexec'ing.
|
||||
Otherwise, they can be corrupted and result in early failure in booting
|
||||
a new kernel.
|
||||
|
||||
In recent kernels, /proc/iomem now has an extended file format like:
|
||||
|
||||
40000000-5871ffff : System RAM
|
||||
41800000-426affff : Kernel code
|
||||
426b0000-42aaffff : reserved
|
||||
42ab0000-42c64fff : Kernel data
|
||||
54400000-583fffff : Crash kernel
|
||||
58590000-585effff : reserved
|
||||
58700000-5871ffff : reserved
|
||||
58720000-58b5ffff : reserved
|
||||
58b60000-5be3ffff : System RAM
|
||||
58b61000-58b61fff : reserved
|
||||
|
||||
where the "reserved" entries at the top level or under System RAM (and
|
||||
its descendant resources) are ones of such kind and should not be regarded
|
||||
as usable memory ranges where several free spaces for loading kexec data
|
||||
will be allocated.
|
||||
|
||||
With this patch, get_memory_ranges() will handle this format of file
|
||||
correctly. Note that, for safety, unknown regions, in addition to
|
||||
"reserved" ones, will also be excluded.
|
||||
|
||||
Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
|
||||
Tested-by: Bhupesh Sharma <bhsharma@redhat.com>
|
||||
Tested-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
|
||||
Signed-off-by: Simon Horman <horms@verge.net.au>
|
||||
---
|
||||
kexec/arch/arm64/kexec-arm64.c | 153 ++++++++++++++++++++-------------
|
||||
1 file changed, 94 insertions(+), 59 deletions(-)
|
||||
|
||||
diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
|
||||
index 6ad3b0a..45ebc54 100644
|
||||
--- a/kexec/arch/arm64/kexec-arm64.c
|
||||
+++ b/kexec/arch/arm64/kexec-arm64.c
|
||||
@@ -10,7 +10,9 @@
|
||||
#include <inttypes.h>
|
||||
#include <libfdt.h>
|
||||
#include <limits.h>
|
||||
+#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <linux/elf-em.h>
|
||||
#include <elf.h>
|
||||
@@ -29,6 +31,7 @@
|
||||
#include "fs2dt.h"
|
||||
#include "iomem.h"
|
||||
#include "kexec-syscall.h"
|
||||
+#include "mem_regions.h"
|
||||
#include "arch/options.h"
|
||||
|
||||
#define ROOT_NODE_ADDR_CELLS_DEFAULT 1
|
||||
@@ -905,19 +908,33 @@ int get_phys_base_from_pt_load(unsigned long *phys_offset)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static bool to_be_excluded(char *str)
|
||||
+{
|
||||
+ if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)) ||
|
||||
+ !strncmp(str, KERNEL_CODE, strlen(KERNEL_CODE)) ||
|
||||
+ !strncmp(str, KERNEL_DATA, strlen(KERNEL_DATA)) ||
|
||||
+ !strncmp(str, CRASH_KERNEL, strlen(CRASH_KERNEL)))
|
||||
+ return false;
|
||||
+ else
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
- * get_memory_ranges_iomem_cb - Helper for get_memory_ranges_iomem.
|
||||
+ * get_memory_ranges - Try to get the memory ranges from
|
||||
+ * /proc/iomem.
|
||||
*/
|
||||
-
|
||||
-static int get_memory_ranges_iomem_cb(void *data, int nr, char *str,
|
||||
- unsigned long long base, unsigned long long length)
|
||||
+int get_memory_ranges(struct memory_range **range, int *ranges,
|
||||
+ unsigned long kexec_flags)
|
||||
{
|
||||
- int ret;
|
||||
unsigned long phys_offset = UINT64_MAX;
|
||||
- struct memory_range *r;
|
||||
-
|
||||
- if (nr >= KEXEC_SEGMENT_MAX)
|
||||
- return -1;
|
||||
+ FILE *fp;
|
||||
+ const char *iomem = proc_iomem();
|
||||
+ char line[MAX_LINE], *str;
|
||||
+ unsigned long long start, end;
|
||||
+ int n, consumed;
|
||||
+ struct memory_ranges memranges;
|
||||
+ struct memory_range *last, excl_range;
|
||||
+ int ret;
|
||||
|
||||
if (!try_read_phys_offset_from_kcore) {
|
||||
/* Since kernel version 4.19, 'kcore' contains
|
||||
@@ -951,17 +968,72 @@ static int get_memory_ranges_iomem_cb(void *data, int nr, char *str,
|
||||
try_read_phys_offset_from_kcore = true;
|
||||
}
|
||||
|
||||
- r = (struct memory_range *)data + nr;
|
||||
+ fp = fopen(iomem, "r");
|
||||
+ if (!fp)
|
||||
+ die("Cannot open %s\n", iomem);
|
||||
+
|
||||
+ memranges.ranges = NULL;
|
||||
+ memranges.size = memranges.max_size = 0;
|
||||
+
|
||||
+ while (fgets(line, sizeof(line), fp) != 0) {
|
||||
+ n = sscanf(line, "%llx-%llx : %n", &start, &end, &consumed);
|
||||
+ if (n != 2)
|
||||
+ continue;
|
||||
+ str = line + consumed;
|
||||
+
|
||||
+ if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM))) {
|
||||
+ ret = mem_regions_alloc_and_add(&memranges,
|
||||
+ start, end - start + 1, RANGE_RAM);
|
||||
+ if (ret) {
|
||||
+ fprintf(stderr,
|
||||
+ "Cannot allocate memory for ranges\n");
|
||||
+ fclose(fp);
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
|
||||
- if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)))
|
||||
- r->type = RANGE_RAM;
|
||||
- else if (!strncmp(str, IOMEM_RESERVED, strlen(IOMEM_RESERVED)))
|
||||
- r->type = RANGE_RESERVED;
|
||||
- else
|
||||
- return 1;
|
||||
+ dbgprintf("%s:+[%d] %016llx - %016llx\n", __func__,
|
||||
+ memranges.size - 1,
|
||||
+ memranges.ranges[memranges.size - 1].start,
|
||||
+ memranges.ranges[memranges.size - 1].end);
|
||||
+ } else if (to_be_excluded(str)) {
|
||||
+ if (!memranges.size)
|
||||
+ continue;
|
||||
+
|
||||
+ /*
|
||||
+ * Note: mem_regions_exclude() doesn't guarantee
|
||||
+ * that the ranges are sorted out, but as long as
|
||||
+ * we cope with /proc/iomem, we only operate on
|
||||
+ * the last entry and so it is safe.
|
||||
+ */
|
||||
|
||||
- r->start = base;
|
||||
- r->end = base + length - 1;
|
||||
+ /* The last System RAM range */
|
||||
+ last = &memranges.ranges[memranges.size - 1];
|
||||
+
|
||||
+ if (last->end < start)
|
||||
+ /* New resource outside of System RAM */
|
||||
+ continue;
|
||||
+ if (end < last->start)
|
||||
+ /* Already excluded by parent resource */
|
||||
+ continue;
|
||||
+
|
||||
+ excl_range.start = start;
|
||||
+ excl_range.end = end;
|
||||
+ ret = mem_regions_alloc_and_exclude(&memranges, &excl_range);
|
||||
+ if (ret) {
|
||||
+ fprintf(stderr,
|
||||
+ "Cannot allocate memory for ranges (exclude)\n");
|
||||
+ fclose(fp);
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+ dbgprintf("%s:- %016llx - %016llx\n",
|
||||
+ __func__, start, end);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ fclose(fp);
|
||||
+
|
||||
+ *range = memranges.ranges;
|
||||
+ *ranges = memranges.size;
|
||||
|
||||
/* As a fallback option, we can try determining the PHYS_OFFSET
|
||||
* value from the '/proc/iomem' entries as well.
|
||||
@@ -982,52 +1054,15 @@ static int get_memory_ranges_iomem_cb(void *data, int nr, char *str,
|
||||
* between the user-space and kernel space 'PHYS_OFFSET'
|
||||
* value.
|
||||
*/
|
||||
- set_phys_offset(r->start, "iomem");
|
||||
-
|
||||
- dbgprintf("%s: %016llx - %016llx : %s", __func__, r->start,
|
||||
- r->end, str);
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-/**
|
||||
- * get_memory_ranges_iomem - Try to get the memory ranges from
|
||||
- * /proc/iomem.
|
||||
- */
|
||||
+ if (memranges.size)
|
||||
+ set_phys_offset(memranges.ranges[0].start, "iomem");
|
||||
|
||||
-static int get_memory_ranges_iomem(struct memory_range *array,
|
||||
- unsigned int *count)
|
||||
-{
|
||||
- *count = kexec_iomem_for_each_line(NULL,
|
||||
- get_memory_ranges_iomem_cb, array);
|
||||
-
|
||||
- if (!*count) {
|
||||
- dbgprintf("%s: failed: No RAM found.\n", __func__);
|
||||
- return EFAILED;
|
||||
- }
|
||||
+ dbgprint_mem_range("System RAM ranges;",
|
||||
+ memranges.ranges, memranges.size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
-/**
|
||||
- * get_memory_ranges - Try to get the memory ranges some how.
|
||||
- */
|
||||
-
|
||||
-int get_memory_ranges(struct memory_range **range, int *ranges,
|
||||
- unsigned long kexec_flags)
|
||||
-{
|
||||
- static struct memory_range array[KEXEC_SEGMENT_MAX];
|
||||
- unsigned int count;
|
||||
- int result;
|
||||
-
|
||||
- result = get_memory_ranges_iomem(array, &count);
|
||||
-
|
||||
- *range = result ? NULL : array;
|
||||
- *ranges = result ? 0 : count;
|
||||
-
|
||||
- return result;
|
||||
-}
|
||||
-
|
||||
int arch_compat_trampoline(struct kexec_info *info)
|
||||
{
|
||||
return 0;
|
||||
@ -1,143 +0,0 @@
|
||||
From d8b701796f0491f2ac4b06c7a5b795c29399efab Mon Sep 17 00:00:00 2001
|
||||
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
Date: Fri, 29 Jan 2021 11:40:23 +0900
|
||||
Subject: [PATCH] [PATCH 1/3] Use vmcoreinfo note in /proc/kcore for
|
||||
--mem-usage option
|
||||
|
||||
kernel commit 23c85094fe18 added vmcoreinfo note to /proc/kcore.
|
||||
Use the vmcoreinfo note to get necessary information, especially
|
||||
page_offset and phys_base on arm64, for the --mem-usage option.
|
||||
|
||||
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
---
|
||||
elf_info.c | 49 -------------------------------------------------
|
||||
elf_info.h | 1 -
|
||||
makedumpfile.c | 26 +++++++++++++++++++++-----
|
||||
3 files changed, 21 insertions(+), 55 deletions(-)
|
||||
|
||||
diff --git a/elf_info.c b/elf_info.c
|
||||
index a6624b5..e8affb7 100644
|
||||
--- a/makedumpfile-1.6.7/elf_info.c
|
||||
+++ b/makedumpfile-1.6.7/elf_info.c
|
||||
@@ -698,55 +698,6 @@ get_elf32_ehdr(int fd, char *filename, Elf32_Ehdr *ehdr)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
-int
|
||||
-get_elf_loads(int fd, char *filename)
|
||||
-{
|
||||
- int i, j, phnum, elf_format;
|
||||
- Elf64_Phdr phdr;
|
||||
-
|
||||
- /*
|
||||
- * Check ELF64 or ELF32.
|
||||
- */
|
||||
- elf_format = check_elf_format(fd, filename, &phnum, &num_pt_loads);
|
||||
- if (elf_format == ELF64)
|
||||
- flags_memory |= MEMORY_ELF64;
|
||||
- else if (elf_format != ELF32)
|
||||
- return FALSE;
|
||||
-
|
||||
- if (!num_pt_loads) {
|
||||
- ERRMSG("Can't get the number of PT_LOAD.\n");
|
||||
- return FALSE;
|
||||
- }
|
||||
-
|
||||
- /*
|
||||
- * The below file information will be used as /proc/vmcore.
|
||||
- */
|
||||
- fd_memory = fd;
|
||||
- name_memory = filename;
|
||||
-
|
||||
- pt_loads = calloc(sizeof(struct pt_load_segment), num_pt_loads);
|
||||
- if (pt_loads == NULL) {
|
||||
- ERRMSG("Can't allocate memory for the PT_LOAD. %s\n",
|
||||
- strerror(errno));
|
||||
- return FALSE;
|
||||
- }
|
||||
- for (i = 0, j = 0; i < phnum; i++) {
|
||||
- if (!get_phdr_memory(i, &phdr))
|
||||
- return FALSE;
|
||||
-
|
||||
- if (phdr.p_type != PT_LOAD)
|
||||
- continue;
|
||||
-
|
||||
- if (j >= num_pt_loads)
|
||||
- return FALSE;
|
||||
- if (!dump_Elf_load(&phdr, j))
|
||||
- return FALSE;
|
||||
- j++;
|
||||
- }
|
||||
-
|
||||
- return TRUE;
|
||||
-}
|
||||
-
|
||||
static int exclude_segment(struct pt_load_segment **pt_loads,
|
||||
unsigned int *num_pt_loads, uint64_t start, uint64_t end)
|
||||
{
|
||||
diff --git a/elf_info.h b/elf_info.h
|
||||
index d9b5d05..d5416b3 100644
|
||||
--- a/makedumpfile-1.6.7/elf_info.h
|
||||
+++ b/makedumpfile-1.6.7/elf_info.h
|
||||
@@ -44,7 +44,6 @@ int get_elf64_ehdr(int fd, char *filename, Elf64_Ehdr *ehdr);
|
||||
int get_elf32_ehdr(int fd, char *filename, Elf32_Ehdr *ehdr);
|
||||
int get_elf_info(int fd, char *filename);
|
||||
void free_elf_info(void);
|
||||
-int get_elf_loads(int fd, char *filename);
|
||||
int set_kcore_vmcoreinfo(uint64_t vmcoreinfo_addr, uint64_t vmcoreinfo_len);
|
||||
int get_kcore_dump_loads(void);
|
||||
|
||||
diff --git a/makedumpfile.c b/makedumpfile.c
|
||||
index ba0003a..768eda4 100644
|
||||
--- a/makedumpfile-1.6.7/makedumpfile.c
|
||||
+++ b/makedumpfile-1.6.7/makedumpfile.c
|
||||
@@ -11445,6 +11445,7 @@ int show_mem_usage(void)
|
||||
{
|
||||
uint64_t vmcoreinfo_addr, vmcoreinfo_len;
|
||||
struct cycle cycle = {0};
|
||||
+ int vmcoreinfo = FALSE;
|
||||
|
||||
if (!is_crashkernel_mem_reserved()) {
|
||||
ERRMSG("No memory is reserved for crashkernel!\n");
|
||||
@@ -11456,9 +11457,22 @@ int show_mem_usage(void)
|
||||
if (!open_files_for_creating_dumpfile())
|
||||
return FALSE;
|
||||
|
||||
- if (!get_elf_loads(info->fd_memory, info->name_memory))
|
||||
+ if (!get_elf_info(info->fd_memory, info->name_memory))
|
||||
return FALSE;
|
||||
|
||||
+ /*
|
||||
+ * /proc/kcore on Linux 4.19 and later kernels have vmcoreinfo note in
|
||||
+ * NOTE segment. See commit 23c85094fe18.
|
||||
+ */
|
||||
+ if (has_vmcoreinfo()) {
|
||||
+ off_t offset;
|
||||
+ unsigned long size;
|
||||
+
|
||||
+ get_vmcoreinfo(&offset, &size);
|
||||
+ vmcoreinfo = read_vmcoreinfo_from_vmcore(offset, size, FALSE);
|
||||
+ DEBUG_MSG("Read vmcoreinfo from NOTE segment: %d\n", vmcoreinfo);
|
||||
+ }
|
||||
+
|
||||
if (!get_page_offset())
|
||||
return FALSE;
|
||||
|
||||
@@ -11466,11 +11480,13 @@ int show_mem_usage(void)
|
||||
if (!get_phys_base())
|
||||
return FALSE;
|
||||
|
||||
- if (!get_sys_kernel_vmcoreinfo(&vmcoreinfo_addr, &vmcoreinfo_len))
|
||||
- return FALSE;
|
||||
+ if (!vmcoreinfo) {
|
||||
+ if (!get_sys_kernel_vmcoreinfo(&vmcoreinfo_addr, &vmcoreinfo_len))
|
||||
+ return FALSE;
|
||||
|
||||
- if (!set_kcore_vmcoreinfo(vmcoreinfo_addr, vmcoreinfo_len))
|
||||
- return FALSE;
|
||||
+ if (!set_kcore_vmcoreinfo(vmcoreinfo_addr, vmcoreinfo_len))
|
||||
+ return FALSE;
|
||||
+ }
|
||||
|
||||
if (!initial())
|
||||
return FALSE;
|
||||
@ -1,97 +0,0 @@
|
||||
From 67d0e1d68f28c567a704fd6b9b8fd696ad3df183 Mon Sep 17 00:00:00 2001
|
||||
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
Date: Fri, 29 Jan 2021 11:40:24 +0900
|
||||
Subject: [PATCH] [PATCH 2/3] arm64: Make use of NUMBER(VA_BITS) in vmcoreinfo
|
||||
|
||||
Make use of the NUMBER(VA_BITS) in vmcoreinfo, which was added by
|
||||
kernel commit 20a166243328 (Linux 4.12 and later kernels), as the
|
||||
current way of guessing VA_BITS does not work on Linux 5.4 and
|
||||
later kernels.
|
||||
|
||||
Signed-off-by: Bhupesh Sharma <bhsharma@redhat.com>
|
||||
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
---
|
||||
arch/arm64.c | 63 ++++++++++++++++++++++++++++++++++------------------
|
||||
1 file changed, 42 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/arch/arm64.c b/arch/arm64.c
|
||||
index 3d7b416..2916b4f 100644
|
||||
--- a/makedumpfile-1.6.7/arch/arm64.c
|
||||
+++ b/makedumpfile-1.6.7/arch/arm64.c
|
||||
@@ -345,6 +345,43 @@ get_stext_symbol(void)
|
||||
return(found ? kallsym : FALSE);
|
||||
}
|
||||
|
||||
+static int
|
||||
+get_va_bits_from_stext_arm64(void)
|
||||
+{
|
||||
+ ulong _stext;
|
||||
+
|
||||
+ _stext = get_stext_symbol();
|
||||
+ if (!_stext) {
|
||||
+ ERRMSG("Can't get the symbol of _stext.\n");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Derive va_bits as per arch/arm64/Kconfig. Note that this is a
|
||||
+ * best case approximation at the moment, as there can be
|
||||
+ * inconsistencies in this calculation (for e.g., for 52-bit
|
||||
+ * kernel VA case, the 48th bit is set in * the _stext symbol).
|
||||
+ */
|
||||
+ if ((_stext & PAGE_OFFSET_48) == PAGE_OFFSET_48) {
|
||||
+ va_bits = 48;
|
||||
+ } else if ((_stext & PAGE_OFFSET_47) == PAGE_OFFSET_47) {
|
||||
+ va_bits = 47;
|
||||
+ } else if ((_stext & PAGE_OFFSET_42) == PAGE_OFFSET_42) {
|
||||
+ va_bits = 42;
|
||||
+ } else if ((_stext & PAGE_OFFSET_39) == PAGE_OFFSET_39) {
|
||||
+ va_bits = 39;
|
||||
+ } else if ((_stext & PAGE_OFFSET_36) == PAGE_OFFSET_36) {
|
||||
+ va_bits = 36;
|
||||
+ } else {
|
||||
+ ERRMSG("Cannot find a proper _stext for calculating VA_BITS\n");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ DEBUG_MSG("va_bits : %d (guess from _stext)\n", va_bits);
|
||||
+
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
int
|
||||
get_machdep_info_arm64(void)
|
||||
{
|
||||
@@ -398,27 +435,11 @@ get_xen_info_arm64(void)
|
||||
int
|
||||
get_versiondep_info_arm64(void)
|
||||
{
|
||||
- ulong _stext;
|
||||
-
|
||||
- _stext = get_stext_symbol();
|
||||
- if (!_stext) {
|
||||
- ERRMSG("Can't get the symbol of _stext.\n");
|
||||
- return FALSE;
|
||||
- }
|
||||
-
|
||||
- /* Derive va_bits as per arch/arm64/Kconfig */
|
||||
- if ((_stext & PAGE_OFFSET_36) == PAGE_OFFSET_36) {
|
||||
- va_bits = 36;
|
||||
- } else if ((_stext & PAGE_OFFSET_39) == PAGE_OFFSET_39) {
|
||||
- va_bits = 39;
|
||||
- } else if ((_stext & PAGE_OFFSET_42) == PAGE_OFFSET_42) {
|
||||
- va_bits = 42;
|
||||
- } else if ((_stext & PAGE_OFFSET_47) == PAGE_OFFSET_47) {
|
||||
- va_bits = 47;
|
||||
- } else if ((_stext & PAGE_OFFSET_48) == PAGE_OFFSET_48) {
|
||||
- va_bits = 48;
|
||||
- } else {
|
||||
- ERRMSG("Cannot find a proper _stext for calculating VA_BITS\n");
|
||||
+ if (NUMBER(VA_BITS) != NOT_FOUND_NUMBER) {
|
||||
+ va_bits = NUMBER(VA_BITS);
|
||||
+ DEBUG_MSG("va_bits : %d (vmcoreinfo)\n", va_bits);
|
||||
+ } else if (get_va_bits_from_stext_arm64() == FALSE) {
|
||||
+ ERRMSG("Can't determine va_bits.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -1,241 +0,0 @@
|
||||
From a0216b678a95f099a16172cc4a67ad5aa6a89583 Mon Sep 17 00:00:00 2001
|
||||
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
Date: Fri, 29 Jan 2021 11:40:25 +0900
|
||||
Subject: [PATCH] [PATCH 3/3] arm64: support flipped VA and 52-bit kernel VA
|
||||
|
||||
Linux 5.4 and later kernels for arm64 changed the kernel VA space
|
||||
arrangement and introduced 52-bit kernel VAs by merging branch
|
||||
commit b333b0ba2346. Support 5.9+ kernels with vmcoreinfo entries
|
||||
and 5.4+ kernels with best guessing.
|
||||
|
||||
However, the following conditions are not supported for now due to
|
||||
no necessary information provided from kernel:
|
||||
(1) 5.4 <= kernels <= 5.8 and
|
||||
- if PA_BITS=52 && VA_BITS!=52
|
||||
- with -x option if vabits_actual=52
|
||||
(2) kernels < 5.4 with CONFIG_ARM64_USER_VA_BITS_52=y
|
||||
|
||||
(1) should be supported with kernel commit bbdbc11804ff and
|
||||
1d50e5d0c5052 adding necessary information to vmcoreinfo.
|
||||
|
||||
Signed-off-by: Bhupesh Sharma <bhsharma@redhat.com>
|
||||
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
Reviewed-by: Pingfan Liu <piliu@redhat.com>
|
||||
---
|
||||
arch/arm64.c | 100 +++++++++++++++++++++++++++++++++++++++++--------
|
||||
makedumpfile.c | 2 +
|
||||
makedumpfile.h | 1 +
|
||||
3 files changed, 88 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/arch/arm64.c b/arch/arm64.c
|
||||
index 2916b4f..1072178 100644
|
||||
--- a/makedumpfile-1.6.7/arch/arm64.c
|
||||
+++ b/makedumpfile-1.6.7/arch/arm64.c
|
||||
@@ -47,6 +47,8 @@ typedef struct {
|
||||
static int lpa_52_bit_support_available;
|
||||
static int pgtable_level;
|
||||
static int va_bits;
|
||||
+static int vabits_actual;
|
||||
+static int flipped_va;
|
||||
static unsigned long kimage_voffset;
|
||||
|
||||
#define SZ_4K 4096
|
||||
@@ -58,7 +60,6 @@ static unsigned long kimage_voffset;
|
||||
#define PAGE_OFFSET_42 ((0xffffffffffffffffUL) << 42)
|
||||
#define PAGE_OFFSET_47 ((0xffffffffffffffffUL) << 47)
|
||||
#define PAGE_OFFSET_48 ((0xffffffffffffffffUL) << 48)
|
||||
-#define PAGE_OFFSET_52 ((0xffffffffffffffffUL) << 52)
|
||||
|
||||
#define pgd_val(x) ((x).pgd)
|
||||
#define pud_val(x) (pgd_val((x).pgd))
|
||||
@@ -218,12 +219,20 @@ pmd_page_paddr(pmd_t pmd)
|
||||
#define pte_index(vaddr) (((vaddr) >> PAGESHIFT()) & (PTRS_PER_PTE - 1))
|
||||
#define pte_offset(dir, vaddr) (pmd_page_paddr((*dir)) + pte_index(vaddr) * sizeof(pte_t))
|
||||
|
||||
+/*
|
||||
+ * The linear kernel range starts at the bottom of the virtual address
|
||||
+ * space. Testing the top bit for the start of the region is a
|
||||
+ * sufficient check and avoids having to worry about the tag.
|
||||
+ */
|
||||
+#define is_linear_addr(addr) (flipped_va ? \
|
||||
+ (!((unsigned long)(addr) & (1UL << (vabits_actual - 1)))) : \
|
||||
+ (!!((unsigned long)(addr) & (1UL << (vabits_actual - 1)))))
|
||||
+
|
||||
static unsigned long long
|
||||
__pa(unsigned long vaddr)
|
||||
{
|
||||
- if (kimage_voffset == NOT_FOUND_NUMBER ||
|
||||
- (vaddr >= PAGE_OFFSET))
|
||||
- return (vaddr - PAGE_OFFSET + info->phys_base);
|
||||
+ if (kimage_voffset == NOT_FOUND_NUMBER || is_linear_addr(vaddr))
|
||||
+ return ((vaddr & ~PAGE_OFFSET) + info->phys_base);
|
||||
else
|
||||
return (vaddr - kimage_voffset);
|
||||
}
|
||||
@@ -253,6 +262,7 @@ static int calculate_plat_config(void)
|
||||
(PAGESIZE() == SZ_64K && va_bits == 42)) {
|
||||
pgtable_level = 2;
|
||||
} else if ((PAGESIZE() == SZ_64K && va_bits == 48) ||
|
||||
+ (PAGESIZE() == SZ_64K && va_bits == 52) ||
|
||||
(PAGESIZE() == SZ_4K && va_bits == 39) ||
|
||||
(PAGESIZE() == SZ_16K && va_bits == 47)) {
|
||||
pgtable_level = 3;
|
||||
@@ -263,6 +273,7 @@ static int calculate_plat_config(void)
|
||||
PAGESIZE(), va_bits);
|
||||
return FALSE;
|
||||
}
|
||||
+ DEBUG_MSG("pgtable_level: %d\n", pgtable_level);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -270,6 +281,9 @@ static int calculate_plat_config(void)
|
||||
unsigned long
|
||||
get_kvbase_arm64(void)
|
||||
{
|
||||
+ if (flipped_va)
|
||||
+ return PAGE_OFFSET;
|
||||
+
|
||||
return (0xffffffffffffffffUL << va_bits);
|
||||
}
|
||||
|
||||
@@ -382,22 +396,54 @@ get_va_bits_from_stext_arm64(void)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+static void
|
||||
+get_page_offset_arm64(void)
|
||||
+{
|
||||
+ ulong page_end;
|
||||
+ int vabits_min;
|
||||
+
|
||||
+ /*
|
||||
+ * See arch/arm64/include/asm/memory.h for more details of
|
||||
+ * the PAGE_OFFSET calculation.
|
||||
+ */
|
||||
+ vabits_min = (va_bits > 48) ? 48 : va_bits;
|
||||
+ page_end = -(1UL << (vabits_min - 1));
|
||||
+
|
||||
+ if (SYMBOL(_stext) > page_end) {
|
||||
+ flipped_va = TRUE;
|
||||
+ info->page_offset = -(1UL << vabits_actual);
|
||||
+ } else {
|
||||
+ flipped_va = FALSE;
|
||||
+ info->page_offset = -(1UL << (vabits_actual - 1));
|
||||
+ }
|
||||
+
|
||||
+ DEBUG_MSG("page_offset : %lx (from page_end check)\n",
|
||||
+ info->page_offset);
|
||||
+}
|
||||
+
|
||||
int
|
||||
get_machdep_info_arm64(void)
|
||||
{
|
||||
+ /* Check if va_bits is still not initialized. If still 0, call
|
||||
+ * get_versiondep_info() to initialize the same.
|
||||
+ */
|
||||
+ if (!va_bits)
|
||||
+ get_versiondep_info_arm64();
|
||||
+
|
||||
/* Determine if the PA address range is 52-bits: ARMv8.2-LPA */
|
||||
if (NUMBER(MAX_PHYSMEM_BITS) != NOT_FOUND_NUMBER) {
|
||||
info->max_physmem_bits = NUMBER(MAX_PHYSMEM_BITS);
|
||||
+ DEBUG_MSG("max_physmem_bits : %ld (vmcoreinfo)\n", info->max_physmem_bits);
|
||||
if (info->max_physmem_bits == 52)
|
||||
lpa_52_bit_support_available = 1;
|
||||
- } else
|
||||
- info->max_physmem_bits = 48;
|
||||
+ } else {
|
||||
+ if (va_bits == 52)
|
||||
+ info->max_physmem_bits = 52; /* just guess */
|
||||
+ else
|
||||
+ info->max_physmem_bits = 48;
|
||||
|
||||
- /* Check if va_bits is still not initialized. If still 0, call
|
||||
- * get_versiondep_info() to initialize the same.
|
||||
- */
|
||||
- if (!va_bits)
|
||||
- get_versiondep_info_arm64();
|
||||
+ DEBUG_MSG("max_physmem_bits : %ld (guess)\n", info->max_physmem_bits);
|
||||
+ }
|
||||
|
||||
if (!calculate_plat_config()) {
|
||||
ERRMSG("Can't determine platform config values\n");
|
||||
@@ -408,7 +454,6 @@ get_machdep_info_arm64(void)
|
||||
info->section_size_bits = SECTIONS_SIZE_BITS;
|
||||
|
||||
DEBUG_MSG("kimage_voffset : %lx\n", kimage_voffset);
|
||||
- DEBUG_MSG("max_physmem_bits : %ld\n", info->max_physmem_bits);
|
||||
DEBUG_MSG("section_size_bits: %ld\n", info->section_size_bits);
|
||||
|
||||
return TRUE;
|
||||
@@ -443,10 +488,35 @@ get_versiondep_info_arm64(void)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
- info->page_offset = (0xffffffffffffffffUL) << (va_bits - 1);
|
||||
+ /*
|
||||
+ * See TCR_EL1, Translation Control Register (EL1) register
|
||||
+ * description in the ARMv8 Architecture Reference Manual.
|
||||
+ * Basically, we can use the TCR_EL1.T1SZ value to determine
|
||||
+ * the virtual addressing range supported in the kernel-space
|
||||
+ * (i.e. vabits_actual) since Linux 5.9.
|
||||
+ */
|
||||
+ if (NUMBER(TCR_EL1_T1SZ) != NOT_FOUND_NUMBER) {
|
||||
+ vabits_actual = 64 - NUMBER(TCR_EL1_T1SZ);
|
||||
+ DEBUG_MSG("vabits_actual : %d (vmcoreinfo)\n", vabits_actual);
|
||||
+ } else if ((va_bits == 52) && (SYMBOL(mem_section) != NOT_FOUND_SYMBOL)) {
|
||||
+ /*
|
||||
+ * Linux 5.4 through 5.10 have the following linear space:
|
||||
+ * 48-bit: 0xffff000000000000 - 0xffff7fffffffffff
|
||||
+ * 52-bit: 0xfff0000000000000 - 0xfff7ffffffffffff
|
||||
+ * and SYMBOL(mem_section) should be in linear space if
|
||||
+ * the kernel is configured with COMFIG_SPARSEMEM_EXTREME=y.
|
||||
+ */
|
||||
+ if (SYMBOL(mem_section) & (1UL << (va_bits - 1)))
|
||||
+ vabits_actual = 48;
|
||||
+ else
|
||||
+ vabits_actual = 52;
|
||||
+ DEBUG_MSG("vabits_actual : %d (guess from mem_section)\n", vabits_actual);
|
||||
+ } else {
|
||||
+ vabits_actual = va_bits;
|
||||
+ DEBUG_MSG("vabits_actual : %d (same as va_bits)\n", vabits_actual);
|
||||
+ }
|
||||
|
||||
- DEBUG_MSG("va_bits : %d\n", va_bits);
|
||||
- DEBUG_MSG("page_offset : %lx\n", info->page_offset);
|
||||
+ get_page_offset_arm64();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
diff --git a/makedumpfile.c b/makedumpfile.c
|
||||
index 768eda4..fcd766b 100644
|
||||
--- a/makedumpfile-1.6.7/makedumpfile.c
|
||||
+++ b/makedumpfile-1.6.7/makedumpfile.c
|
||||
@@ -2397,6 +2397,7 @@ write_vmcoreinfo_data(void)
|
||||
WRITE_NUMBER("HUGETLB_PAGE_DTOR", HUGETLB_PAGE_DTOR);
|
||||
#ifdef __aarch64__
|
||||
WRITE_NUMBER("VA_BITS", VA_BITS);
|
||||
+ /* WRITE_NUMBER("TCR_EL1_T1SZ", TCR_EL1_T1SZ); should not exists */
|
||||
WRITE_NUMBER_UNSIGNED("PHYS_OFFSET", PHYS_OFFSET);
|
||||
WRITE_NUMBER_UNSIGNED("kimage_voffset", kimage_voffset);
|
||||
#endif
|
||||
@@ -2836,6 +2837,7 @@ read_vmcoreinfo(void)
|
||||
READ_NUMBER("KERNEL_IMAGE_SIZE", KERNEL_IMAGE_SIZE);
|
||||
#ifdef __aarch64__
|
||||
READ_NUMBER("VA_BITS", VA_BITS);
|
||||
+ READ_NUMBER("TCR_EL1_T1SZ", TCR_EL1_T1SZ);
|
||||
READ_NUMBER_UNSIGNED("PHYS_OFFSET", PHYS_OFFSET);
|
||||
READ_NUMBER_UNSIGNED("kimage_voffset", kimage_voffset);
|
||||
#endif
|
||||
diff --git a/makedumpfile.h b/makedumpfile.h
|
||||
index 0ed6417..97a5554 100644
|
||||
--- a/makedumpfile-1.6.7/makedumpfile.h
|
||||
+++ b/makedumpfile-1.6.7makedumpfile.h
|
||||
@@ -2049,6 +2049,7 @@ struct number_table {
|
||||
long KERNEL_IMAGE_SIZE;
|
||||
#ifdef __aarch64__
|
||||
long VA_BITS;
|
||||
+ long TCR_EL1_T1SZ;
|
||||
unsigned long PHYS_OFFSET;
|
||||
unsigned long kimage_voffset;
|
||||
#endif
|
||||
@ -1,33 +0,0 @@
|
||||
From 7242ae4cb5288df626f464ced0a8b60fd669100b Mon Sep 17 00:00:00 2001
|
||||
From: Michal Suchanek <msuchanek@suse.de>
|
||||
Date: Mon, 16 Mar 2020 19:39:58 +0100
|
||||
Subject: [PATCH] [PATCH] Align PMD_SECTION_MASK with PHYS_MASK
|
||||
|
||||
Reportedly on some arm64 systems makedumpfile loops forever exhausting
|
||||
all memory when filtering kernel core. It turns out the reason is it
|
||||
cannot resolve some addresses because the PMD mask is wrong. When
|
||||
physical address mask allows up to 48bits pmd mask should allow the
|
||||
same.
|
||||
I suppose you would need a system that needs physical addresses over 1TB
|
||||
to be able to reproduce this. This may be either because you have a lot
|
||||
of memory or because the firmware mapped some memory above 1TB for some
|
||||
reason.
|
||||
|
||||
Signed-off-by: Michal Suchanek <msuchanek@suse.de>
|
||||
---
|
||||
arch/arm64.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/arch/arm64.c b/arch/arm64.c
|
||||
index 43164cc..54d60b4 100644
|
||||
--- a/makedumpfile-1.6.7/arch/arm64.c
|
||||
+++ b/makedumpfile-1.6.7/arch/arm64.c
|
||||
@@ -81,7 +81,7 @@ static unsigned long kimage_voffset;
|
||||
* Remove the highest order bits that are not a part of the
|
||||
* physical address in a section
|
||||
*/
|
||||
-#define PMD_SECTION_MASK ((1UL << 40) - 1)
|
||||
+#define PMD_SECTION_MASK ((1UL << PHYS_MASK_SHIFT) - 1)
|
||||
|
||||
#define PMD_TYPE_MASK 3
|
||||
#define PMD_TYPE_SECT 1
|
||||
@ -1,413 +0,0 @@
|
||||
From da0d25ffa585c9a1adb94562c815daa393b1ee5e Mon Sep 17 00:00:00 2001
|
||||
From: Bhupesh Sharma <bhsharma@redhat.com>
|
||||
Date: Thu, 10 Sep 2020 11:03:04 +0530
|
||||
Subject: [PATCH] [PATCH] arm64: Add support for ARMv8.2-LPA (52-bit PA
|
||||
support)
|
||||
|
||||
ARMv8.2-LPA architecture extension (if available on underlying hardware)
|
||||
can support 52-bit physical addresses, while the kernel virtual
|
||||
addresses remain 48-bit.
|
||||
|
||||
Make sure that we read the 52-bit PA address capability from
|
||||
'MAX_PHYSMEM_BITS' variable (if available in vmcoreinfo) and
|
||||
accordingly change the pte_to_phy() mask values and also traverse
|
||||
the page-table walk accordingly.
|
||||
|
||||
Also make sure that it works well for the existing 48-bit PA address
|
||||
platforms and also on environments which use newer kernels with 52-bit
|
||||
PA support but hardware which is not ARM8.2-LPA compliant.
|
||||
|
||||
Kernel commit 1d50e5d0c505 ("crash_core, vmcoreinfo: Append
|
||||
'MAX_PHYSMEM_BITS' to vmcoreinfo") already supports adding
|
||||
'MAX_PHYSMEM_BITS' variable to vmcoreinfo.
|
||||
|
||||
This patch is in accordance with ARMv8 Architecture Reference Manual
|
||||
|
||||
Signed-off-by: Bhupesh Sharma <bhsharma@redhat.com>
|
||||
---
|
||||
arch/arm64.c | 294 +++++++++++++++++++++++++++++++++++----------------
|
||||
1 file changed, 205 insertions(+), 89 deletions(-)
|
||||
|
||||
diff --git a/arch/arm64.c b/arch/arm64.c
|
||||
index 54d60b4..3d7b416 100644
|
||||
--- a/makedumpfile-1.6.7/arch/arm64.c
|
||||
+++ b/makedumpfile-1.6.7/arch/arm64.c
|
||||
@@ -39,72 +39,184 @@ typedef struct {
|
||||
unsigned long pte;
|
||||
} pte_t;
|
||||
|
||||
+#define __pte(x) ((pte_t) { (x) } )
|
||||
+#define __pmd(x) ((pmd_t) { (x) } )
|
||||
+#define __pud(x) ((pud_t) { (x) } )
|
||||
+#define __pgd(x) ((pgd_t) { (x) } )
|
||||
+
|
||||
+static int lpa_52_bit_support_available;
|
||||
static int pgtable_level;
|
||||
static int va_bits;
|
||||
static unsigned long kimage_voffset;
|
||||
|
||||
-#define SZ_4K (4 * 1024)
|
||||
-#define SZ_16K (16 * 1024)
|
||||
-#define SZ_64K (64 * 1024)
|
||||
-#define SZ_128M (128 * 1024 * 1024)
|
||||
+#define SZ_4K 4096
|
||||
+#define SZ_16K 16384
|
||||
+#define SZ_64K 65536
|
||||
|
||||
-#define PAGE_OFFSET_36 ((0xffffffffffffffffUL) << 36)
|
||||
-#define PAGE_OFFSET_39 ((0xffffffffffffffffUL) << 39)
|
||||
-#define PAGE_OFFSET_42 ((0xffffffffffffffffUL) << 42)
|
||||
-#define PAGE_OFFSET_47 ((0xffffffffffffffffUL) << 47)
|
||||
-#define PAGE_OFFSET_48 ((0xffffffffffffffffUL) << 48)
|
||||
+#define PAGE_OFFSET_36 ((0xffffffffffffffffUL) << 36)
|
||||
+#define PAGE_OFFSET_39 ((0xffffffffffffffffUL) << 39)
|
||||
+#define PAGE_OFFSET_42 ((0xffffffffffffffffUL) << 42)
|
||||
+#define PAGE_OFFSET_47 ((0xffffffffffffffffUL) << 47)
|
||||
+#define PAGE_OFFSET_48 ((0xffffffffffffffffUL) << 48)
|
||||
+#define PAGE_OFFSET_52 ((0xffffffffffffffffUL) << 52)
|
||||
|
||||
#define pgd_val(x) ((x).pgd)
|
||||
#define pud_val(x) (pgd_val((x).pgd))
|
||||
#define pmd_val(x) (pud_val((x).pud))
|
||||
#define pte_val(x) ((x).pte)
|
||||
|
||||
-#define PAGE_MASK (~(PAGESIZE() - 1))
|
||||
-#define PGDIR_SHIFT ((PAGESHIFT() - 3) * pgtable_level + 3)
|
||||
-#define PTRS_PER_PGD (1 << (va_bits - PGDIR_SHIFT))
|
||||
-#define PUD_SHIFT get_pud_shift_arm64()
|
||||
-#define PUD_SIZE (1UL << PUD_SHIFT)
|
||||
-#define PUD_MASK (~(PUD_SIZE - 1))
|
||||
-#define PTRS_PER_PTE (1 << (PAGESHIFT() - 3))
|
||||
-#define PTRS_PER_PUD PTRS_PER_PTE
|
||||
-#define PMD_SHIFT ((PAGESHIFT() - 3) * 2 + 3)
|
||||
-#define PMD_SIZE (1UL << PMD_SHIFT)
|
||||
-#define PMD_MASK (~(PMD_SIZE - 1))
|
||||
+/* See 'include/uapi/linux/const.h' for definitions below */
|
||||
+#define __AC(X,Y) (X##Y)
|
||||
+#define _AC(X,Y) __AC(X,Y)
|
||||
+#define _AT(T,X) ((T)(X))
|
||||
+
|
||||
+/* See 'include/asm/pgtable-types.h' for definitions below */
|
||||
+typedef unsigned long pteval_t;
|
||||
+typedef unsigned long pmdval_t;
|
||||
+typedef unsigned long pudval_t;
|
||||
+typedef unsigned long pgdval_t;
|
||||
+
|
||||
+#define PAGE_SHIFT PAGESHIFT()
|
||||
+
|
||||
+/* See 'arch/arm64/include/asm/pgtable-hwdef.h' for definitions below */
|
||||
+
|
||||
+#define ARM64_HW_PGTABLE_LEVEL_SHIFT(n) ((PAGE_SHIFT - 3) * (4 - (n)) + 3)
|
||||
+
|
||||
+#define PTRS_PER_PTE (1 << (PAGE_SHIFT - 3))
|
||||
+
|
||||
+/*
|
||||
+ * PMD_SHIFT determines the size a level 2 page table entry can map.
|
||||
+ */
|
||||
+#define PMD_SHIFT ARM64_HW_PGTABLE_LEVEL_SHIFT(2)
|
||||
+#define PMD_SIZE (_AC(1, UL) << PMD_SHIFT)
|
||||
+#define PMD_MASK (~(PMD_SIZE-1))
|
||||
#define PTRS_PER_PMD PTRS_PER_PTE
|
||||
|
||||
-#define PAGE_PRESENT (1 << 0)
|
||||
+/*
|
||||
+ * PUD_SHIFT determines the size a level 1 page table entry can map.
|
||||
+ */
|
||||
+#define PUD_SHIFT ARM64_HW_PGTABLE_LEVEL_SHIFT(1)
|
||||
+#define PUD_SIZE (_AC(1, UL) << PUD_SHIFT)
|
||||
+#define PUD_MASK (~(PUD_SIZE-1))
|
||||
+#define PTRS_PER_PUD PTRS_PER_PTE
|
||||
+
|
||||
+/*
|
||||
+ * PGDIR_SHIFT determines the size a top-level page table entry can map
|
||||
+ * (depending on the configuration, this level can be 0, 1 or 2).
|
||||
+ */
|
||||
+#define PGDIR_SHIFT ARM64_HW_PGTABLE_LEVEL_SHIFT(4 - (pgtable_level))
|
||||
+#define PGDIR_SIZE (_AC(1, UL) << PGDIR_SHIFT)
|
||||
+#define PGDIR_MASK (~(PGDIR_SIZE-1))
|
||||
+#define PTRS_PER_PGD (1 << ((va_bits) - PGDIR_SHIFT))
|
||||
+
|
||||
+/*
|
||||
+ * Section address mask and size definitions.
|
||||
+ */
|
||||
#define SECTIONS_SIZE_BITS 30
|
||||
-/* Highest possible physical address supported */
|
||||
-#define PHYS_MASK_SHIFT 48
|
||||
-#define PHYS_MASK ((1UL << PHYS_MASK_SHIFT) - 1)
|
||||
+
|
||||
+/*
|
||||
+ * Hardware page table definitions.
|
||||
+ *
|
||||
+ * Level 1 descriptor (PUD).
|
||||
+ */
|
||||
+#define PUD_TYPE_TABLE (_AT(pudval_t, 3) << 0)
|
||||
+#define PUD_TABLE_BIT (_AT(pudval_t, 1) << 1)
|
||||
+#define PUD_TYPE_MASK (_AT(pudval_t, 3) << 0)
|
||||
+#define PUD_TYPE_SECT (_AT(pudval_t, 1) << 0)
|
||||
+
|
||||
/*
|
||||
- * Remove the highest order bits that are not a part of the
|
||||
- * physical address in a section
|
||||
+ * Level 2 descriptor (PMD).
|
||||
*/
|
||||
-#define PMD_SECTION_MASK ((1UL << PHYS_MASK_SHIFT) - 1)
|
||||
+#define PMD_TYPE_MASK (_AT(pmdval_t, 3) << 0)
|
||||
+#define PMD_TYPE_FAULT (_AT(pmdval_t, 0) << 0)
|
||||
+#define PMD_TYPE_TABLE (_AT(pmdval_t, 3) << 0)
|
||||
+#define PMD_TYPE_SECT (_AT(pmdval_t, 1) << 0)
|
||||
+#define PMD_TABLE_BIT (_AT(pmdval_t, 1) << 1)
|
||||
|
||||
-#define PMD_TYPE_MASK 3
|
||||
-#define PMD_TYPE_SECT 1
|
||||
-#define PMD_TYPE_TABLE 3
|
||||
+/*
|
||||
+ * Level 3 descriptor (PTE).
|
||||
+ */
|
||||
+#define PTE_ADDR_LOW (((_AT(pteval_t, 1) << (48 - PAGE_SHIFT)) - 1) << PAGE_SHIFT)
|
||||
+#define PTE_ADDR_HIGH (_AT(pteval_t, 0xf) << 12)
|
||||
|
||||
-#define PUD_TYPE_MASK 3
|
||||
-#define PUD_TYPE_SECT 1
|
||||
-#define PUD_TYPE_TABLE 3
|
||||
+static inline unsigned long
|
||||
+get_pte_addr_mask_arm64(void)
|
||||
+{
|
||||
+ if (lpa_52_bit_support_available)
|
||||
+ return (PTE_ADDR_LOW | PTE_ADDR_HIGH);
|
||||
+ else
|
||||
+ return PTE_ADDR_LOW;
|
||||
+}
|
||||
|
||||
-#define pgd_index(vaddr) (((vaddr) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
|
||||
-#define pgd_offset(pgdir, vaddr) ((pgd_t *)(pgdir) + pgd_index(vaddr))
|
||||
+#define PTE_ADDR_MASK get_pte_addr_mask_arm64()
|
||||
|
||||
-#define pte_index(vaddr) (((vaddr) >> PAGESHIFT()) & (PTRS_PER_PTE - 1))
|
||||
-#define pmd_page_paddr(pmd) (pmd_val(pmd) & PHYS_MASK & (int32_t)PAGE_MASK)
|
||||
-#define pte_offset(dir, vaddr) ((pte_t*)pmd_page_paddr((*dir)) + pte_index(vaddr))
|
||||
+#define PAGE_MASK (~(PAGESIZE() - 1))
|
||||
+#define PAGE_PRESENT (1 << 0)
|
||||
|
||||
-#define pmd_index(vaddr) (((vaddr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
|
||||
-#define pud_page_paddr(pud) (pud_val(pud) & PHYS_MASK & (int32_t)PAGE_MASK)
|
||||
-#define pmd_offset_pgtbl_lvl_2(pud, vaddr) ((pmd_t *)pud)
|
||||
-#define pmd_offset_pgtbl_lvl_3(pud, vaddr) ((pmd_t *)pud_page_paddr((*pud)) + pmd_index(vaddr))
|
||||
+/* Helper API to convert between a physical address and its placement
|
||||
+ * in a page table entry, taking care of 52-bit addresses.
|
||||
+ */
|
||||
+static inline unsigned long
|
||||
+__pte_to_phys(pte_t pte)
|
||||
+{
|
||||
+ if (lpa_52_bit_support_available)
|
||||
+ return ((pte_val(pte) & PTE_ADDR_LOW) | ((pte_val(pte) & PTE_ADDR_HIGH) << 36));
|
||||
+ else
|
||||
+ return (pte_val(pte) & PTE_ADDR_MASK);
|
||||
+}
|
||||
+
|
||||
+/* Find an entry in a page-table-directory */
|
||||
+#define pgd_index(vaddr) (((vaddr) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
|
||||
+
|
||||
+static inline pte_t
|
||||
+pgd_pte(pgd_t pgd)
|
||||
+{
|
||||
+ return __pte(pgd_val(pgd));
|
||||
+}
|
||||
+
|
||||
+#define __pgd_to_phys(pgd) __pte_to_phys(pgd_pte(pgd))
|
||||
+#define pgd_offset(pgd, vaddr) ((pgd_t *)(pgd) + pgd_index(vaddr))
|
||||
+
|
||||
+static inline pte_t pud_pte(pud_t pud)
|
||||
+{
|
||||
+ return __pte(pud_val(pud));
|
||||
+}
|
||||
|
||||
+static inline unsigned long
|
||||
+pgd_page_paddr(pgd_t pgd)
|
||||
+{
|
||||
+ return __pgd_to_phys(pgd);
|
||||
+}
|
||||
+
|
||||
+/* Find an entry in the first-level page table. */
|
||||
#define pud_index(vaddr) (((vaddr) >> PUD_SHIFT) & (PTRS_PER_PUD - 1))
|
||||
-#define pgd_page_paddr(pgd) (pgd_val(pgd) & PHYS_MASK & (int32_t)PAGE_MASK)
|
||||
+#define __pud_to_phys(pud) __pte_to_phys(pud_pte(pud))
|
||||
+
|
||||
+static inline unsigned long
|
||||
+pud_page_paddr(pud_t pud)
|
||||
+{
|
||||
+ return __pud_to_phys(pud);
|
||||
+}
|
||||
+
|
||||
+/* Find an entry in the second-level page table. */
|
||||
+#define pmd_index(vaddr) (((vaddr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
|
||||
+
|
||||
+static inline pte_t pmd_pte(pmd_t pmd)
|
||||
+{
|
||||
+ return __pte(pmd_val(pmd));
|
||||
+}
|
||||
+
|
||||
+#define __pmd_to_phys(pmd) __pte_to_phys(pmd_pte(pmd))
|
||||
+
|
||||
+static inline unsigned long
|
||||
+pmd_page_paddr(pmd_t pmd)
|
||||
+{
|
||||
+ return __pmd_to_phys(pmd);
|
||||
+}
|
||||
+
|
||||
+/* Find an entry in the third-level page table. */
|
||||
+#define pte_index(vaddr) (((vaddr) >> PAGESHIFT()) & (PTRS_PER_PTE - 1))
|
||||
+#define pte_offset(dir, vaddr) (pmd_page_paddr((*dir)) + pte_index(vaddr) * sizeof(pte_t))
|
||||
|
||||
static unsigned long long
|
||||
__pa(unsigned long vaddr)
|
||||
@@ -116,32 +228,22 @@ __pa(unsigned long vaddr)
|
||||
return (vaddr - kimage_voffset);
|
||||
}
|
||||
|
||||
-static int
|
||||
-get_pud_shift_arm64(void)
|
||||
+static pud_t *
|
||||
+pud_offset(pgd_t *pgda, pgd_t *pgdv, unsigned long vaddr)
|
||||
{
|
||||
- if (pgtable_level == 4)
|
||||
- return ((PAGESHIFT() - 3) * 3 + 3);
|
||||
+ if (pgtable_level > 3)
|
||||
+ return (pud_t *)(pgd_page_paddr(*pgdv) + pud_index(vaddr) * sizeof(pud_t));
|
||||
else
|
||||
- return PGDIR_SHIFT;
|
||||
+ return (pud_t *)(pgda);
|
||||
}
|
||||
|
||||
static pmd_t *
|
||||
pmd_offset(pud_t *puda, pud_t *pudv, unsigned long vaddr)
|
||||
{
|
||||
- if (pgtable_level == 2) {
|
||||
- return pmd_offset_pgtbl_lvl_2(puda, vaddr);
|
||||
- } else {
|
||||
- return pmd_offset_pgtbl_lvl_3(pudv, vaddr);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-static pud_t *
|
||||
-pud_offset(pgd_t *pgda, pgd_t *pgdv, unsigned long vaddr)
|
||||
-{
|
||||
- if (pgtable_level == 4)
|
||||
- return ((pud_t *)pgd_page_paddr((*pgdv)) + pud_index(vaddr));
|
||||
+ if (pgtable_level > 2)
|
||||
+ return (pmd_t *)(pud_page_paddr(*pudv) + pmd_index(vaddr) * sizeof(pmd_t));
|
||||
else
|
||||
- return (pud_t *)(pgda);
|
||||
+ return (pmd_t *)(puda);
|
||||
}
|
||||
|
||||
static int calculate_plat_config(void)
|
||||
@@ -246,6 +348,14 @@ get_stext_symbol(void)
|
||||
int
|
||||
get_machdep_info_arm64(void)
|
||||
{
|
||||
+ /* Determine if the PA address range is 52-bits: ARMv8.2-LPA */
|
||||
+ if (NUMBER(MAX_PHYSMEM_BITS) != NOT_FOUND_NUMBER) {
|
||||
+ info->max_physmem_bits = NUMBER(MAX_PHYSMEM_BITS);
|
||||
+ if (info->max_physmem_bits == 52)
|
||||
+ lpa_52_bit_support_available = 1;
|
||||
+ } else
|
||||
+ info->max_physmem_bits = 48;
|
||||
+
|
||||
/* Check if va_bits is still not initialized. If still 0, call
|
||||
* get_versiondep_info() to initialize the same.
|
||||
*/
|
||||
@@ -258,12 +368,11 @@ get_machdep_info_arm64(void)
|
||||
}
|
||||
|
||||
kimage_voffset = NUMBER(kimage_voffset);
|
||||
- info->max_physmem_bits = PHYS_MASK_SHIFT;
|
||||
info->section_size_bits = SECTIONS_SIZE_BITS;
|
||||
|
||||
DEBUG_MSG("kimage_voffset : %lx\n", kimage_voffset);
|
||||
- DEBUG_MSG("max_physmem_bits : %lx\n", info->max_physmem_bits);
|
||||
- DEBUG_MSG("section_size_bits: %lx\n", info->section_size_bits);
|
||||
+ DEBUG_MSG("max_physmem_bits : %ld\n", info->max_physmem_bits);
|
||||
+ DEBUG_MSG("section_size_bits: %ld\n", info->section_size_bits);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -321,6 +430,19 @@ get_versiondep_info_arm64(void)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+/* 1GB section for Page Table level = 4 and Page Size = 4KB */
|
||||
+static int
|
||||
+is_pud_sect(pud_t pud)
|
||||
+{
|
||||
+ return ((pud_val(pud) & PUD_TYPE_MASK) == PUD_TYPE_SECT);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+is_pmd_sect(pmd_t pmd)
|
||||
+{
|
||||
+ return ((pmd_val(pmd) & PMD_TYPE_MASK) == PMD_TYPE_SECT);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* vaddr_to_paddr_arm64() - translate arbitrary virtual address to physical
|
||||
* @vaddr: virtual address to translate
|
||||
@@ -358,10 +480,9 @@ vaddr_to_paddr_arm64(unsigned long vaddr)
|
||||
return NOT_PADDR;
|
||||
}
|
||||
|
||||
- if ((pud_val(pudv) & PUD_TYPE_MASK) == PUD_TYPE_SECT) {
|
||||
- /* 1GB section for Page Table level = 4 and Page Size = 4KB */
|
||||
- paddr = (pud_val(pudv) & (PUD_MASK & PMD_SECTION_MASK))
|
||||
- + (vaddr & (PUD_SIZE - 1));
|
||||
+ if (is_pud_sect(pudv)) {
|
||||
+ paddr = (pud_page_paddr(pudv) & PUD_MASK) +
|
||||
+ (vaddr & (PUD_SIZE - 1));
|
||||
return paddr;
|
||||
}
|
||||
|
||||
@@ -371,29 +492,24 @@ vaddr_to_paddr_arm64(unsigned long vaddr)
|
||||
return NOT_PADDR;
|
||||
}
|
||||
|
||||
- switch (pmd_val(pmdv) & PMD_TYPE_MASK) {
|
||||
- case PMD_TYPE_TABLE:
|
||||
- ptea = pte_offset(&pmdv, vaddr);
|
||||
- /* 64k page */
|
||||
- if (!readmem(PADDR, (unsigned long long)ptea, &ptev, sizeof(ptev))) {
|
||||
- ERRMSG("Can't read pte\n");
|
||||
- return NOT_PADDR;
|
||||
- }
|
||||
+ if (is_pmd_sect(pmdv)) {
|
||||
+ paddr = (pmd_page_paddr(pmdv) & PMD_MASK) +
|
||||
+ (vaddr & (PMD_SIZE - 1));
|
||||
+ return paddr;
|
||||
+ }
|
||||
|
||||
- if (!(pte_val(ptev) & PAGE_PRESENT)) {
|
||||
- ERRMSG("Can't get a valid pte.\n");
|
||||
- return NOT_PADDR;
|
||||
- } else {
|
||||
+ ptea = (pte_t *)pte_offset(&pmdv, vaddr);
|
||||
+ if (!readmem(PADDR, (unsigned long long)ptea, &ptev, sizeof(ptev))) {
|
||||
+ ERRMSG("Can't read pte\n");
|
||||
+ return NOT_PADDR;
|
||||
+ }
|
||||
|
||||
- paddr = (PAGEBASE(pte_val(ptev)) & PHYS_MASK)
|
||||
- + (vaddr & (PAGESIZE() - 1));
|
||||
- }
|
||||
- break;
|
||||
- case PMD_TYPE_SECT:
|
||||
- /* 512MB section for Page Table level = 3 and Page Size = 64KB*/
|
||||
- paddr = (pmd_val(pmdv) & (PMD_MASK & PMD_SECTION_MASK))
|
||||
- + (vaddr & (PMD_SIZE - 1));
|
||||
- break;
|
||||
+ if (!(pte_val(ptev) & PAGE_PRESENT)) {
|
||||
+ ERRMSG("Can't get a valid pte.\n");
|
||||
+ return NOT_PADDR;
|
||||
+ } else {
|
||||
+ paddr = __pte_to_phys(ptev) +
|
||||
+ (vaddr & (PAGESIZE() - 1));
|
||||
}
|
||||
|
||||
return paddr;
|
||||
@ -1,492 +0,0 @@
|
||||
From 4149df9005f2cdd2ecf70058dfe7d72f48c3a68c Mon Sep 17 00:00:00 2001
|
||||
From: John Ogness <john.ogness@linutronix.de>
|
||||
Date: Wed, 25 Nov 2020 23:26:59 +0106
|
||||
Subject: printk: add support for lockless ringbuffer
|
||||
|
||||
Linux 5.10 moved to a new lockless ringbuffer. The new ringbuffer
|
||||
is structured completely different to the previous iterations.
|
||||
Add support for retrieving the ringbuffer using vmcoreinfo. The
|
||||
new ringbuffer is detected based on the availability of the
|
||||
"prb" symbol.
|
||||
|
||||
Signed-off-by: John Ogness <john.ogness@linutronix.de>
|
||||
Signed-off-by: Simon Horman <horms@verge.net.au>
|
||||
---
|
||||
util_lib/elf_info.c | 438 +++++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 437 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/util_lib/elf_info.c b/util_lib/elf_info.c
|
||||
index 7803a94..2f23a44 100644
|
||||
--- a/util_lib/elf_info.c
|
||||
+++ b/util_lib/elf_info.c
|
||||
@@ -27,6 +27,32 @@ static int num_pt_loads;
|
||||
|
||||
static char osrelease[4096];
|
||||
|
||||
+/* VMCOREINFO symbols for lockless printk ringbuffer */
|
||||
+static loff_t prb_vaddr;
|
||||
+static size_t printk_ringbuffer_sz;
|
||||
+static size_t prb_desc_sz;
|
||||
+static size_t printk_info_sz;
|
||||
+static uint64_t printk_ringbuffer_desc_ring_offset;
|
||||
+static uint64_t printk_ringbuffer_text_data_ring_offset;
|
||||
+static uint64_t prb_desc_ring_count_bits_offset;
|
||||
+static uint64_t prb_desc_ring_descs_offset;
|
||||
+static uint64_t prb_desc_ring_infos_offset;
|
||||
+static uint64_t prb_data_ring_size_bits_offset;
|
||||
+static uint64_t prb_data_ring_data_offset;
|
||||
+static uint64_t prb_desc_ring_head_id_offset;
|
||||
+static uint64_t prb_desc_ring_tail_id_offset;
|
||||
+static uint64_t atomic_long_t_counter_offset;
|
||||
+static uint64_t prb_desc_state_var_offset;
|
||||
+static uint64_t prb_desc_info_offset;
|
||||
+static uint64_t prb_desc_text_blk_lpos_offset;
|
||||
+static uint64_t prb_data_blk_lpos_begin_offset;
|
||||
+static uint64_t prb_data_blk_lpos_next_offset;
|
||||
+static uint64_t printk_info_seq_offset;
|
||||
+static uint64_t printk_info_caller_id_offset;
|
||||
+static uint64_t printk_info_ts_nsec_offset;
|
||||
+static uint64_t printk_info_level_offset;
|
||||
+static uint64_t printk_info_text_len_offset;
|
||||
+
|
||||
static loff_t log_buf_vaddr;
|
||||
static loff_t log_end_vaddr;
|
||||
static loff_t log_buf_len_vaddr;
|
||||
@@ -304,6 +330,7 @@ void scan_vmcoreinfo(char *start, size_t size)
|
||||
size_t len;
|
||||
loff_t *vaddr;
|
||||
} symbol[] = {
|
||||
+ SYMBOL(prb),
|
||||
SYMBOL(log_buf),
|
||||
SYMBOL(log_end),
|
||||
SYMBOL(log_buf_len),
|
||||
@@ -361,6 +388,119 @@ void scan_vmcoreinfo(char *start, size_t size)
|
||||
*symbol[i].vaddr = vaddr;
|
||||
}
|
||||
|
||||
+ str = "SIZE(printk_ringbuffer)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ printk_ringbuffer_sz = strtoull(pos + strlen(str),
|
||||
+ NULL, 10);
|
||||
+
|
||||
+ str = "SIZE(prb_desc)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ prb_desc_sz = strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "SIZE(printk_info)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ printk_info_sz = strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(printk_ringbuffer.desc_ring)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ printk_ringbuffer_desc_ring_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(printk_ringbuffer.text_data_ring)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ printk_ringbuffer_text_data_ring_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(prb_desc_ring.count_bits)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ prb_desc_ring_count_bits_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(prb_desc_ring.descs)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ prb_desc_ring_descs_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(prb_desc_ring.infos)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ prb_desc_ring_infos_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(prb_data_ring.size_bits)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ prb_data_ring_size_bits_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(prb_data_ring.data)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ prb_data_ring_data_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(prb_desc_ring.head_id)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ prb_desc_ring_head_id_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(prb_desc_ring.tail_id)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ prb_desc_ring_tail_id_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(atomic_long_t.counter)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ atomic_long_t_counter_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(prb_desc.state_var)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ prb_desc_state_var_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(prb_desc.info)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ prb_desc_info_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(prb_desc.text_blk_lpos)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ prb_desc_text_blk_lpos_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(prb_data_blk_lpos.begin)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ prb_data_blk_lpos_begin_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(prb_data_blk_lpos.next)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ prb_data_blk_lpos_next_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(printk_info.seq)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ printk_info_seq_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(printk_info.caller_id)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ printk_info_caller_id_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(printk_info.ts_nsec)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ printk_info_ts_nsec_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(printk_info.level)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ printk_info_level_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
+ str = "OFFSET(printk_info.text_len)=";
|
||||
+ if (memcmp(str, pos, strlen(str)) == 0)
|
||||
+ printk_info_text_len_offset =
|
||||
+ strtoull(pos + strlen(str), NULL, 10);
|
||||
+
|
||||
/* Check for "SIZE(printk_log)" or older "SIZE(log)=" */
|
||||
str = "SIZE(log)=";
|
||||
if (memcmp(str, pos, strlen(str)) == 0)
|
||||
@@ -746,9 +886,305 @@ static void dump_dmesg_structured(int fd, void (*handler)(char*, unsigned int))
|
||||
handler(out_buf, len);
|
||||
}
|
||||
|
||||
+/* convenience struct for passing many values to helper functions */
|
||||
+struct prb_map {
|
||||
+ char *prb;
|
||||
+
|
||||
+ char *desc_ring;
|
||||
+ unsigned long desc_ring_count;
|
||||
+ char *descs;
|
||||
+
|
||||
+ char *infos;
|
||||
+
|
||||
+ char *text_data_ring;
|
||||
+ unsigned long text_data_ring_size;
|
||||
+ char *text_data;
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * desc_state and DESC_* definitions taken from kernel source:
|
||||
+ *
|
||||
+ * kernel/printk/printk_ringbuffer.h
|
||||
+ *
|
||||
+ * DESC_* definitions modified to provide 32-bit and 64-bit variants.
|
||||
+ */
|
||||
+
|
||||
+/* The possible responses of a descriptor state-query. */
|
||||
+enum desc_state {
|
||||
+ desc_miss = -1, /* ID mismatch (pseudo state) */
|
||||
+ desc_reserved = 0x0, /* reserved, in use by writer */
|
||||
+ desc_committed = 0x1, /* committed by writer, could get reopened */
|
||||
+ desc_finalized = 0x2, /* committed, no further modification allowed */
|
||||
+ desc_reusable = 0x3, /* free, not yet used by any writer */
|
||||
+};
|
||||
+
|
||||
+#define DESC_SV_BITS (sizeof(uint64_t) * 8)
|
||||
+#define DESC_FLAGS_SHIFT (DESC_SV_BITS - 2)
|
||||
+#define DESC_FLAGS_MASK (3UL << DESC_FLAGS_SHIFT)
|
||||
+#define DESC_STATE(sv) (3UL & (sv >> DESC_FLAGS_SHIFT))
|
||||
+#define DESC_ID_MASK (~DESC_FLAGS_MASK)
|
||||
+#define DESC_ID(sv) ((sv) & DESC_ID_MASK)
|
||||
+
|
||||
+#define DESC32_SV_BITS (sizeof(uint32_t) * 8)
|
||||
+#define DESC32_FLAGS_SHIFT (DESC32_SV_BITS - 2)
|
||||
+#define DESC32_FLAGS_MASK (3UL << DESC32_FLAGS_SHIFT)
|
||||
+#define DESC32_STATE(sv) (3UL & (sv >> DESC32_FLAGS_SHIFT))
|
||||
+#define DESC32_ID_MASK (~DESC32_FLAGS_MASK)
|
||||
+#define DESC32_ID(sv) ((sv) & DESC32_ID_MASK)
|
||||
+
|
||||
+/*
|
||||
+ * get_desc_state() taken from kernel source:
|
||||
+ *
|
||||
+ * kernel/printk/printk_ringbuffer.c
|
||||
+ *
|
||||
+ * get_desc32_state() added as 32-bit variant.
|
||||
+ */
|
||||
+
|
||||
+/* Query the state of a descriptor. */
|
||||
+static enum desc_state get_desc_state(unsigned long id,
|
||||
+ uint64_t state_val)
|
||||
+{
|
||||
+ if (id != DESC_ID(state_val))
|
||||
+ return desc_miss;
|
||||
+
|
||||
+ return DESC_STATE(state_val);
|
||||
+}
|
||||
+
|
||||
+static enum desc_state get_desc32_state(unsigned long id,
|
||||
+ uint64_t state_val)
|
||||
+{
|
||||
+ if (id != DESC32_ID(state_val))
|
||||
+ return desc_miss;
|
||||
+
|
||||
+ return DESC32_STATE(state_val);
|
||||
+}
|
||||
+
|
||||
+static bool record_committed(unsigned long id, uint64_t state_var)
|
||||
+{
|
||||
+ enum desc_state state;
|
||||
+
|
||||
+ if (machine_pointer_bits() == 32)
|
||||
+ state = get_desc32_state(id, state_var);
|
||||
+ else
|
||||
+ state = get_desc_state(id, state_var);
|
||||
+
|
||||
+ return (state == desc_committed || state == desc_finalized);
|
||||
+}
|
||||
+
|
||||
+static uint64_t id_inc(uint64_t id)
|
||||
+{
|
||||
+ id++;
|
||||
+
|
||||
+ if (machine_pointer_bits() == 32)
|
||||
+ return (id & DESC32_ID_MASK);
|
||||
+
|
||||
+ return (id & DESC_ID_MASK);
|
||||
+}
|
||||
+
|
||||
+static uint64_t get_ulong(char *addr)
|
||||
+{
|
||||
+ if (machine_pointer_bits() == 32)
|
||||
+ return struct_val_u32(addr, 0);
|
||||
+ return struct_val_u64(addr, 0);
|
||||
+}
|
||||
+
|
||||
+static uint64_t sizeof_ulong(void)
|
||||
+{
|
||||
+ return (machine_pointer_bits() >> 3);
|
||||
+}
|
||||
+
|
||||
+static void dump_record(struct prb_map *m, unsigned long id,
|
||||
+ void (*handler)(char*, unsigned int))
|
||||
+{
|
||||
+#define OUT_BUF_SIZE 4096
|
||||
+ char out_buf[OUT_BUF_SIZE];
|
||||
+ imaxdiv_t imaxdiv_usec;
|
||||
+ imaxdiv_t imaxdiv_sec;
|
||||
+ uint32_t offset = 0;
|
||||
+ unsigned short len;
|
||||
+ uint64_t state_var;
|
||||
+ uint64_t ts_nsec;
|
||||
+ uint64_t begin;
|
||||
+ uint64_t next;
|
||||
+ char *info;
|
||||
+ char *text;
|
||||
+ char *desc;
|
||||
+ int i;
|
||||
+
|
||||
+ desc = m->descs + ((id % m->desc_ring_count) * prb_desc_sz);
|
||||
+ info = m->infos + ((id % m->desc_ring_count) * printk_info_sz);
|
||||
+
|
||||
+ /* skip non-committed record */
|
||||
+ state_var = get_ulong(desc + prb_desc_state_var_offset +
|
||||
+ atomic_long_t_counter_offset);
|
||||
+ if (!record_committed(id, state_var))
|
||||
+ return;
|
||||
+
|
||||
+ begin = get_ulong(desc + prb_desc_text_blk_lpos_offset +
|
||||
+ prb_data_blk_lpos_begin_offset) %
|
||||
+ m->text_data_ring_size;
|
||||
+ next = get_ulong(desc + prb_desc_text_blk_lpos_offset +
|
||||
+ prb_data_blk_lpos_next_offset) %
|
||||
+ m->text_data_ring_size;
|
||||
+
|
||||
+ ts_nsec = struct_val_u64(info, printk_info_ts_nsec_offset);
|
||||
+ imaxdiv_sec = imaxdiv(ts_nsec, 1000000000);
|
||||
+ imaxdiv_usec = imaxdiv(imaxdiv_sec.rem, 1000);
|
||||
+
|
||||
+ offset += sprintf(out_buf + offset, "[%5llu.%06llu] ",
|
||||
+ (long long unsigned int)imaxdiv_sec.quot,
|
||||
+ (long long unsigned int)imaxdiv_usec.quot);
|
||||
+
|
||||
+ /* skip data-less text blocks */
|
||||
+ if (begin == next)
|
||||
+ goto out;
|
||||
+
|
||||
+ len = struct_val_u16(info, printk_info_text_len_offset);
|
||||
+
|
||||
+ /* handle wrapping data block */
|
||||
+ if (begin > next)
|
||||
+ begin = 0;
|
||||
+
|
||||
+ /* skip over descriptor ID */
|
||||
+ begin += sizeof_ulong();
|
||||
+
|
||||
+ /* handle truncated messages */
|
||||
+ if (next - begin < len)
|
||||
+ len = next - begin;
|
||||
+
|
||||
+ text = m->text_data + begin;
|
||||
+
|
||||
+ /* escape non-printable characters */
|
||||
+ for (i = 0; i < len; i++) {
|
||||
+ unsigned char c = text[i];
|
||||
+
|
||||
+ if (!isprint(c) && !isspace(c))
|
||||
+ offset += sprintf(out_buf + offset, "\\x%02x", c);
|
||||
+ else
|
||||
+ out_buf[offset++] = c;
|
||||
+
|
||||
+ if (offset >= OUT_BUF_SIZE - 64) {
|
||||
+ if (handler)
|
||||
+ handler(out_buf, offset);
|
||||
+ offset = 0;
|
||||
+ }
|
||||
+ }
|
||||
+out:
|
||||
+ out_buf[offset++] = '\n';
|
||||
+
|
||||
+ if (offset && handler)
|
||||
+ handler(out_buf, offset);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Handle the lockless printk_ringbuffer.
|
||||
+ */
|
||||
+static void dump_dmesg_lockless(int fd, void (*handler)(char*, unsigned int))
|
||||
+{
|
||||
+ struct prb_map m;
|
||||
+ uint64_t head_id;
|
||||
+ uint64_t tail_id;
|
||||
+ uint64_t kaddr;
|
||||
+ uint64_t id;
|
||||
+ int ret;
|
||||
+
|
||||
+ /* setup printk_ringbuffer */
|
||||
+ kaddr = read_file_pointer(fd, vaddr_to_offset(prb_vaddr));
|
||||
+ m.prb = calloc(1, printk_ringbuffer_sz);
|
||||
+ if (!m.prb) {
|
||||
+ fprintf(stderr, "Failed to malloc %lu bytes for prb: %s\n",
|
||||
+ printk_ringbuffer_sz, strerror(errno));
|
||||
+ exit(64);
|
||||
+ }
|
||||
+ ret = pread(fd, m.prb, printk_ringbuffer_sz, vaddr_to_offset(kaddr));
|
||||
+ if (ret != printk_ringbuffer_sz) {
|
||||
+ fprintf(stderr, "Failed to read prb of size %lu bytes: %s\n",
|
||||
+ printk_ringbuffer_sz, strerror(errno));
|
||||
+ exit(65);
|
||||
+ }
|
||||
+
|
||||
+ /* setup descriptor ring */
|
||||
+ m.desc_ring = m.prb + printk_ringbuffer_desc_ring_offset;
|
||||
+ m.desc_ring_count = 1 << struct_val_u32(m.desc_ring,
|
||||
+ prb_desc_ring_count_bits_offset);
|
||||
+ kaddr = get_ulong(m.desc_ring + prb_desc_ring_descs_offset);
|
||||
+ m.descs = calloc(1, prb_desc_sz * m.desc_ring_count);
|
||||
+ if (!m.descs) {
|
||||
+ fprintf(stderr, "Failed to malloc %lu bytes for descs: %s\n",
|
||||
+ prb_desc_sz * m.desc_ring_count, strerror(errno));
|
||||
+ exit(64);
|
||||
+ }
|
||||
+ ret = pread(fd, m.descs, prb_desc_sz * m.desc_ring_count,
|
||||
+ vaddr_to_offset(kaddr));
|
||||
+ if (ret != prb_desc_sz * m.desc_ring_count) {
|
||||
+ fprintf(stderr,
|
||||
+ "Failed to read descs of size %lu bytes: %s\n",
|
||||
+ prb_desc_sz * m.desc_ring_count, strerror(errno));
|
||||
+ exit(65);
|
||||
+ }
|
||||
+
|
||||
+ /* setup info ring */
|
||||
+ kaddr = get_ulong(m.prb + prb_desc_ring_infos_offset);
|
||||
+ m.infos = calloc(1, printk_info_sz * m.desc_ring_count);
|
||||
+ if (!m.infos) {
|
||||
+ fprintf(stderr, "Failed to malloc %lu bytes for infos: %s\n",
|
||||
+ printk_info_sz * m.desc_ring_count, strerror(errno));
|
||||
+ exit(64);
|
||||
+ }
|
||||
+ ret = pread(fd, m.infos, printk_info_sz * m.desc_ring_count,
|
||||
+ vaddr_to_offset(kaddr));
|
||||
+ if (ret != printk_info_sz * m.desc_ring_count) {
|
||||
+ fprintf(stderr,
|
||||
+ "Failed to read infos of size %lu bytes: %s\n",
|
||||
+ printk_info_sz * m.desc_ring_count, strerror(errno));
|
||||
+ exit(65);
|
||||
+ }
|
||||
+
|
||||
+ /* setup text data ring */
|
||||
+ m.text_data_ring = m.prb + printk_ringbuffer_text_data_ring_offset;
|
||||
+ m.text_data_ring_size = 1 << struct_val_u32(m.text_data_ring,
|
||||
+ prb_data_ring_size_bits_offset);
|
||||
+ kaddr = get_ulong(m.text_data_ring + prb_data_ring_data_offset);
|
||||
+ m.text_data = calloc(1, m.text_data_ring_size);
|
||||
+ if (!m.text_data) {
|
||||
+ fprintf(stderr,
|
||||
+ "Failed to malloc %lu bytes for text_data: %s\n",
|
||||
+ m.text_data_ring_size, strerror(errno));
|
||||
+ exit(64);
|
||||
+ }
|
||||
+ ret = pread(fd, m.text_data, m.text_data_ring_size,
|
||||
+ vaddr_to_offset(kaddr));
|
||||
+ if (ret != m.text_data_ring_size) {
|
||||
+ fprintf(stderr,
|
||||
+ "Failed to read text_data of size %lu bytes: %s\n",
|
||||
+ m.text_data_ring_size, strerror(errno));
|
||||
+ exit(65);
|
||||
+ }
|
||||
+
|
||||
+ /* ready to go */
|
||||
+
|
||||
+ tail_id = get_ulong(m.desc_ring + prb_desc_ring_tail_id_offset +
|
||||
+ atomic_long_t_counter_offset);
|
||||
+ head_id = get_ulong(m.desc_ring + prb_desc_ring_head_id_offset +
|
||||
+ atomic_long_t_counter_offset);
|
||||
+
|
||||
+ for (id = tail_id; id != head_id; id = id_inc(id))
|
||||
+ dump_record(&m, id, handler);
|
||||
+
|
||||
+ /* dump head record */
|
||||
+ dump_record(&m, id, handler);
|
||||
+
|
||||
+ free(m.text_data);
|
||||
+ free(m.infos);
|
||||
+ free(m.descs);
|
||||
+ free(m.prb);
|
||||
+}
|
||||
+
|
||||
void dump_dmesg(int fd, void (*handler)(char*, unsigned int))
|
||||
{
|
||||
- if (log_first_idx_vaddr)
|
||||
+ if (prb_vaddr)
|
||||
+ dump_dmesg_lockless(fd, handler);
|
||||
+ else if (log_first_idx_vaddr)
|
||||
dump_dmesg_structured(fd, handler);
|
||||
else
|
||||
dump_dmesg_legacy(fd, handler);
|
||||
--
|
||||
cgit 1.2.3-1.el7
|
||||
|
||||
Binary file not shown.
BIN
eppic-e8844d3.tar.gz
Normal file
BIN
eppic-e8844d3.tar.gz
Normal file
Binary file not shown.
@ -1,37 +0,0 @@
|
||||
From bde6d1f1d3f9551fa4ca65247e210c8ac7814168 Mon Sep 17 00:00:00 2001
|
||||
From: Jialong Chen <chenjialong@huawei.com>
|
||||
Date: Tue, 3 Dec 2019 20:26:55 +0000
|
||||
Subject: [PATCH] fix header offset overflow when large pfn
|
||||
|
||||
info->len_bitmap=0x182000000
|
||||
dh->bitmap_blocks * dh->block_size = info->len_bitmap=0x182000000 > int range
|
||||
so:
|
||||
cd_header->offset = (DISKDUMP_HEADER_BLOCKS + dh->sub_hdr_size + dh->bitmap_blocks) * dh->block_size;
|
||||
get cd_header->offset = 0x82015000, but correct size is 0x182015000
|
||||
so we set DISKDUMP_HEADER_BLOCKS to 1UL.
|
||||
|
||||
when cd_header->offset overflow, and cd_page->offset get an error offset.
|
||||
cd_page->offset = cd_header->offset + sizeof(page_desc_t)*info->num_dumpable
|
||||
later write page data will cover bitmap2.
|
||||
|
||||
Signed-off-by: Jialong Chen <chenjialong@huawei.com>
|
||||
---
|
||||
makedumpfile-1.6.4/diskdump_mod.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/makedumpfile-1.6.7/diskdump_mod.h b/makedumpfile-1.6.7/diskdump_mod.h
|
||||
index 2676817..3733953 100644
|
||||
--- a/makedumpfile-1.6.7/diskdump_mod.h
|
||||
+++ b/makedumpfile-1.6.7/diskdump_mod.h
|
||||
@@ -22,7 +22,7 @@
|
||||
#define DISK_DUMP_SIGNATURE "DISKDUMP"
|
||||
#define KDUMP_SIGNATURE "KDUMP "
|
||||
#define SIG_LEN (sizeof(DUMP_PARTITION_SIGNATURE) - 1)
|
||||
-#define DISKDUMP_HEADER_BLOCKS (1)
|
||||
+#define DISKDUMP_HEADER_BLOCKS (1UL)
|
||||
|
||||
/*
|
||||
* These are all remnants of the old "diskdump" facility,
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,19 +1,8 @@
|
||||
From c4fa8f8344a5f7a3147c8bee34d37b6af35d02e7 Mon Sep 17 00:00:00 2001
|
||||
From: snoweay <snoweay@163.com>
|
||||
Date: Wed, 12 Aug 2020 07:53:13 -0400
|
||||
Subject: [PATCH] kexec: Add quick kexec support
|
||||
From e841cb419d74adbda7116a6b11b5fcaeba0dc274 Mon Sep 17 00:00:00 2001
|
||||
From: root <root@localhost.localdomain>
|
||||
Date: Sat, 25 Dec 2021 17:42:47 +0800
|
||||
Subject: [PATCH] fix
|
||||
|
||||
Add quick kexec option -q and flags.
|
||||
|
||||
In normal kexec, relocating kernel may cost 5 ~ 10 seconds, to
|
||||
copy all segments from vmalloced memory to kernel boot memory,
|
||||
because of disabled mmu.
|
||||
|
||||
We introduce quick kexec to save time of copying memory as above,
|
||||
just like kdump(kexec on crash), by using reserved memory.
|
||||
|
||||
We also add this support in syscall kexec_load of linux kernel
|
||||
through flags of KEXEC_QUICK.
|
||||
---
|
||||
kexec/kexec-syscall.h | 1 +
|
||||
kexec/kexec.c | 10 ++++++++++
|
||||
@ -21,10 +10,10 @@ through flags of KEXEC_QUICK.
|
||||
3 files changed, 14 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/kexec/kexec-syscall.h b/kexec/kexec-syscall.h
|
||||
index dac1c1f..b146b6a 100644
|
||||
index bea29d4..6eea272 100644
|
||||
--- a/kexec/kexec-syscall.h
|
||||
+++ b/kexec/kexec-syscall.h
|
||||
@@ -102,6 +102,7 @@ static inline long kexec_file_load(int kernel_fd, int initrd_fd,
|
||||
@@ -109,6 +109,7 @@ static inline long kexec_file_load(int kernel_fd, int initrd_fd,
|
||||
|
||||
#define KEXEC_ON_CRASH 0x00000001
|
||||
#define KEXEC_PRESERVE_CONTEXT 0x00000002
|
||||
@ -33,10 +22,10 @@ index dac1c1f..b146b6a 100644
|
||||
|
||||
/* Flags for kexec file based system call */
|
||||
diff --git a/kexec/kexec.c b/kexec/kexec.c
|
||||
index bc6ab3d..48825af 100644
|
||||
index f63b36b..5b8beca 100644
|
||||
--- a/kexec/kexec.c
|
||||
+++ b/kexec/kexec.c
|
||||
@@ -997,6 +997,7 @@ void usage(void)
|
||||
@@ -1009,6 +1009,7 @@ void usage(void)
|
||||
" -l, --load Load the new kernel into the\n"
|
||||
" current kernel.\n"
|
||||
" -p, --load-panic Load the new kernel for use on panic.\n"
|
||||
@ -44,15 +33,15 @@ index bc6ab3d..48825af 100644
|
||||
" -u, --unload Unload the current kexec target kernel.\n"
|
||||
" If capture kernel is being unloaded\n"
|
||||
" specify -p with -u.\n"
|
||||
@@ -1268,6 +1269,7 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
@@ -1340,6 +1341,7 @@ int main(int argc, char *argv[])
|
||||
int has_opt_load = 0;
|
||||
int do_load = 1;
|
||||
int do_exec = 0;
|
||||
+ int do_quick = 0;
|
||||
int do_load_jump_back_helper = 0;
|
||||
int do_shutdown = 1;
|
||||
int do_sync = 1, skip_sync = 0;
|
||||
@@ -1377,6 +1379,14 @@ int main(int argc, char *argv[])
|
||||
@@ -1460,6 +1462,14 @@ int main(int argc, char *argv[])
|
||||
kexec_file_flags |= KEXEC_FILE_ON_CRASH;
|
||||
kexec_flags = KEXEC_ON_CRASH;
|
||||
break;
|
||||
@ -68,10 +57,10 @@ index bc6ab3d..48825af 100644
|
||||
mem_min = strtoul(optarg, &endptr, 0);
|
||||
if (*endptr) {
|
||||
diff --git a/kexec/kexec.h b/kexec/kexec.h
|
||||
index a97b9ce..e31e4d2 100644
|
||||
index 595dd68..9cbc77f 100644
|
||||
--- a/kexec/kexec.h
|
||||
+++ b/kexec/kexec.h
|
||||
@@ -221,6 +221,7 @@ extern int file_types;
|
||||
@@ -218,6 +218,7 @@ extern int file_types;
|
||||
#define OPT_UNLOAD 'u'
|
||||
#define OPT_TYPE 't'
|
||||
#define OPT_PANIC 'p'
|
||||
@ -79,7 +68,7 @@ index a97b9ce..e31e4d2 100644
|
||||
#define OPT_KEXEC_FILE_SYSCALL 's'
|
||||
#define OPT_KEXEC_SYSCALL 'c'
|
||||
#define OPT_KEXEC_SYSCALL_AUTO 'a'
|
||||
@@ -248,6 +249,7 @@ extern int file_types;
|
||||
@@ -249,6 +250,7 @@ extern int file_types;
|
||||
{ "entry", 1, 0, OPT_ENTRY }, \
|
||||
{ "type", 1, 0, OPT_TYPE }, \
|
||||
{ "load-panic", 0, 0, OPT_PANIC }, \
|
||||
@ -87,7 +76,7 @@ index a97b9ce..e31e4d2 100644
|
||||
{ "mem-min", 1, 0, OPT_MEM_MIN }, \
|
||||
{ "mem-max", 1, 0, OPT_MEM_MAX }, \
|
||||
{ "reuseinitrd", 0, 0, OPT_REUSE_INITRD }, \
|
||||
@@ -258,7 +260,7 @@ extern int file_types;
|
||||
@@ -259,7 +261,7 @@ extern int file_types;
|
||||
{ "status", 0, 0, OPT_STATUS }, \
|
||||
{ "print-ckr-size", 0, 0, OPT_PRINT_CKR_SIZE }, \
|
||||
|
||||
@ -97,5 +86,5 @@ index a97b9ce..e31e4d2 100644
|
||||
extern void dbgprint_mem_range(const char *prefix, struct memory_range *mr, int nr_mr);
|
||||
extern void die(const char *fmt, ...)
|
||||
--
|
||||
2.19.1
|
||||
2.30.0
|
||||
|
||||
|
||||
@ -1,86 +0,0 @@
|
||||
From cf977b1af9ec67fabcc6a625589c49c52d07b11d Mon Sep 17 00:00:00 2001
|
||||
From: AKASHI Takahiro <takahiro.akashi@linaro.org>
|
||||
Date: Wed, 18 Dec 2019 11:42:30 -0500
|
||||
Subject: [PATCH] kexec: add variant helper functions for handling memory
|
||||
regions
|
||||
|
||||
mem_regions_alloc_and_add() and mem_regions_alloc_and_exclude() are
|
||||
functionally equivalent to, respectively, mem_regions_add() and
|
||||
mem_regions_exclude() except the formers will re-allocate memory
|
||||
dynamically when no more entries are available in 'ranges' array.
|
||||
|
||||
Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
|
||||
Tested-by: Bhupesh Sharma <bhsharma@redhat.com>
|
||||
Tested-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
|
||||
Signed-off-by: Simon Horman <horms@verge.net.au>
|
||||
---
|
||||
kexec/mem_regions.c | 42 ++++++++++++++++++++++++++++++++++++++++++
|
||||
kexec/mem_regions.h | 7 +++++++
|
||||
2 files changed, 49 insertions(+)
|
||||
|
||||
diff --git a/kexec/mem_regions.c b/kexec/mem_regions.c
|
||||
index 50c8abc..ad7d3f1 100644
|
||||
--- a/kexec/mem_regions.c
|
||||
+++ b/kexec/mem_regions.c
|
||||
@@ -125,3 +125,45 @@ int mem_regions_exclude(struct memory_ranges *ranges,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
+
|
||||
+#define KEXEC_MEMORY_RANGES 16
|
||||
+
|
||||
+int mem_regions_alloc_and_add(struct memory_ranges *ranges,
|
||||
+ unsigned long long base,
|
||||
+ unsigned long long length, int type)
|
||||
+{
|
||||
+ void *new_ranges;
|
||||
+
|
||||
+ if (ranges->size >= ranges->max_size) {
|
||||
+ new_ranges = realloc(ranges->ranges,
|
||||
+ sizeof(struct memory_range) *
|
||||
+ (ranges->max_size + KEXEC_MEMORY_RANGES));
|
||||
+ if (!new_ranges)
|
||||
+ return -1;
|
||||
+
|
||||
+ ranges->ranges = new_ranges;
|
||||
+ ranges->max_size += KEXEC_MEMORY_RANGES;
|
||||
+ }
|
||||
+
|
||||
+ return mem_regions_add(ranges, base, length, type);
|
||||
+}
|
||||
+
|
||||
+int mem_regions_alloc_and_exclude(struct memory_ranges *ranges,
|
||||
+ const struct memory_range *range)
|
||||
+{
|
||||
+ void *new_ranges;
|
||||
+
|
||||
+ /* for safety, we should have at least one free entry in ranges */
|
||||
+ if (ranges->size >= ranges->max_size) {
|
||||
+ new_ranges = realloc(ranges->ranges,
|
||||
+ sizeof(struct memory_range) *
|
||||
+ (ranges->max_size + KEXEC_MEMORY_RANGES));
|
||||
+ if (!new_ranges)
|
||||
+ return -1;
|
||||
+
|
||||
+ ranges->ranges = new_ranges;
|
||||
+ ranges->max_size += KEXEC_MEMORY_RANGES;
|
||||
+ }
|
||||
+
|
||||
+ return mem_regions_exclude(ranges, range);
|
||||
+}
|
||||
diff --git a/kexec/mem_regions.h b/kexec/mem_regions.h
|
||||
index ae9e972..e306d67 100644
|
||||
--- a/kexec/mem_regions.h
|
||||
+++ b/kexec/mem_regions.h
|
||||
@@ -12,4 +12,11 @@ int mem_regions_exclude(struct memory_ranges *ranges,
|
||||
int mem_regions_add(struct memory_ranges *ranges, unsigned long long base,
|
||||
unsigned long long length, int type);
|
||||
|
||||
+int mem_regions_alloc_and_exclude(struct memory_ranges *ranges,
|
||||
+ const struct memory_range *range);
|
||||
+
|
||||
+int mem_regions_alloc_and_add(struct memory_ranges *ranges,
|
||||
+ unsigned long long base,
|
||||
+ unsigned long long length, int type);
|
||||
+
|
||||
#endif
|
||||
@ -1,44 +0,0 @@
|
||||
From 618799e90566e22554584644e496ff95f425ac48 Mon Sep 17 00:00:00 2001
|
||||
From: Lianbo Jiang <lijiang@redhat.com>
|
||||
Date: Mon, 24 Feb 2020 14:36:55 +0800
|
||||
Subject: [PATCH] kexec: support parsing the string "Reserved" to get the
|
||||
correct e820 reserved region
|
||||
|
||||
When loading kernel and initramfs for kexec, kexec-tools could get the
|
||||
e820 reserved region from "/proc/iomem" in order to rebuild the e820
|
||||
ranges for kexec kernel, but there may be the string "Reserved" in the
|
||||
"/proc/iomem", which caused the failure of parsing. For example:
|
||||
|
||||
#cat /proc/iomem|grep -i reserved
|
||||
00000000-00000fff : Reserved
|
||||
7f338000-7f34dfff : Reserved
|
||||
7f3cd000-8fffffff : Reserved
|
||||
f17f0000-f17f1fff : Reserved
|
||||
fe000000-ffffffff : Reserved
|
||||
|
||||
Currently, kexec-tools can not handle the above case because the memcmp()
|
||||
is case sensitive when comparing the string.
|
||||
|
||||
So, let's fix this corner and make sure that the string "reserved" and
|
||||
"Reserved" in the "/proc/iomem" are both parsed appropriately.
|
||||
|
||||
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||
Acked-by: Bhupesh Sharma <bhsharma@redhat.com>
|
||||
Signed-off-by: Simon Horman <horms@verge.net.au>
|
||||
|
||||
diff --git a/kexec/arch/i386/kexec-x86-common.c b/kexec/arch/i386/kexec-x86-common.c
|
||||
index 61ea193..9303704 100644
|
||||
--- a/kexec/arch/i386/kexec-x86-common.c
|
||||
+++ b/kexec/arch/i386/kexec-x86-common.c
|
||||
@@ -90,7 +90,7 @@ static int get_memory_ranges_proc_iomem(struct memory_range **range, int *ranges
|
||||
if (memcmp(str, "System RAM\n", 11) == 0) {
|
||||
type = RANGE_RAM;
|
||||
}
|
||||
- else if (memcmp(str, "reserved\n", 9) == 0) {
|
||||
+ else if (strncasecmp(str, "reserved\n", 9) == 0) {
|
||||
type = RANGE_RESERVED;
|
||||
}
|
||||
else if (memcmp(str, "ACPI Tables\n", 12) == 0) {
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,98 +0,0 @@
|
||||
From 23daba8bb97ff4291447e54859ed759cfe07975e Mon Sep 17 00:00:00 2001
|
||||
From: Kairui Song <kasong@redhat.com>
|
||||
Date: Wed, 29 Jan 2020 10:48:27 +0800
|
||||
Subject: [PATCH] kexec-tools: Remove duplicated variable declarations
|
||||
|
||||
When building kexec-tools for Fedora 32, following error is observed:
|
||||
|
||||
/usr/bin/ld: kexec/arch/x86_64/kexec-bzImage64.o:(.bss+0x0): multiple definition of `bzImage_support_efi_boot';
|
||||
kexec/arch/i386/kexec-bzImage.o:(.bss+0x0): first defined here
|
||||
|
||||
/builddir/build/BUILD/kexec-tools-2.0.20/kexec/arch/arm/../../fs2dt.h:33: multiple definition of `my_debug';
|
||||
kexec/fs2dt.o:/builddir/build/BUILD/kexec-tools-2.0.20/kexec/fs2dt.h:33: first defined here
|
||||
|
||||
/builddir/build/BUILD/kexec-tools-2.0.20/kexec/arch/arm64/kexec-arm64.h:68: multiple definition of `arm64_mem';
|
||||
kexec/fs2dt.o:/builddir/build/BUILD/kexec-tools-2.0.20/././kexec/arch/arm64/kexec-arm64.h:68: first defined here
|
||||
|
||||
/builddir/build/BUILD/kexec-tools-2.0.20/kexec/arch/arm64/kexec-arm64.h:54: multiple definition of `initrd_size';
|
||||
kexec/fs2dt.o:/builddir/build/BUILD/kexec-tools-2.0.20/././kexec/arch/arm64/kexec-arm64.h:54: first defined here
|
||||
|
||||
/builddir/build/BUILD/kexec-tools-2.0.20/kexec/arch/arm64/kexec-arm64.h:53: multiple definition of `initrd_base';
|
||||
kexec/fs2dt.o:/builddir/build/BUILD/kexec-tools-2.0.20/././kexec/arch/arm64/kexec-arm64.h:53: first defined here
|
||||
|
||||
And apparently, these variables are wrongly declared multiple times. So
|
||||
remove duplicated declaration.
|
||||
|
||||
Signed-off-by: Kairui Song <kasong@redhat.com>
|
||||
---
|
||||
kexec/arch/arm64/kexec-arm64.h | 6 +++---
|
||||
kexec/arch/ppc64/kexec-elf-ppc64.c | 2 --
|
||||
kexec/arch/x86_64/kexec-bzImage64.c | 1 -
|
||||
kexec/fs2dt.h | 2 +-
|
||||
4 files changed, 4 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/kexec/arch/arm64/kexec-arm64.h b/kexec/arch/arm64/kexec-arm64.h
|
||||
index 628de79..ed447ac 100644
|
||||
--- a/kexec/arch/arm64/kexec-arm64.h
|
||||
+++ b/kexec/arch/arm64/kexec-arm64.h
|
||||
@@ -50,8 +50,8 @@ int zImage_arm64_load(int argc, char **argv, const char *kernel_buf,
|
||||
void zImage_arm64_usage(void);
|
||||
|
||||
|
||||
-off_t initrd_base;
|
||||
-off_t initrd_size;
|
||||
+extern off_t initrd_base;
|
||||
+extern off_t initrd_size;
|
||||
|
||||
/**
|
||||
* struct arm64_mem - Memory layout info.
|
||||
@@ -65,7 +65,7 @@ struct arm64_mem {
|
||||
};
|
||||
|
||||
#define arm64_mem_ngv UINT64_MAX
|
||||
-struct arm64_mem arm64_mem;
|
||||
+extern struct arm64_mem arm64_mem;
|
||||
|
||||
uint64_t get_phys_offset(void);
|
||||
uint64_t get_vp_offset(void);
|
||||
diff --git a/kexec/arch/ppc64/kexec-elf-ppc64.c b/kexec/arch/ppc64/kexec-elf-ppc64.c
|
||||
index 3510b70..695b8b0 100644
|
||||
--- a/kexec/arch/ppc64/kexec-elf-ppc64.c
|
||||
+++ b/kexec/arch/ppc64/kexec-elf-ppc64.c
|
||||
@@ -44,8 +44,6 @@
|
||||
uint64_t initrd_base, initrd_size;
|
||||
unsigned char reuse_initrd = 0;
|
||||
const char *ramdisk;
|
||||
-/* Used for enabling printing message from purgatory code */
|
||||
-int my_debug = 0;
|
||||
|
||||
int elf_ppc64_probe(const char *buf, off_t len)
|
||||
{
|
||||
diff --git a/kexec/arch/x86_64/kexec-bzImage64.c b/kexec/arch/x86_64/kexec-bzImage64.c
|
||||
index 8edb3e4..ba8dc48 100644
|
||||
--- a/kexec/arch/x86_64/kexec-bzImage64.c
|
||||
+++ b/kexec/arch/x86_64/kexec-bzImage64.c
|
||||
@@ -42,7 +42,6 @@
|
||||
#include <arch/options.h>
|
||||
|
||||
static const int probe_debug = 0;
|
||||
-int bzImage_support_efi_boot;
|
||||
|
||||
int bzImage64_probe(const char *buf, off_t len)
|
||||
{
|
||||
diff --git a/kexec/fs2dt.h b/kexec/fs2dt.h
|
||||
index 7633273..fe24931 100644
|
||||
--- a/kexec/fs2dt.h
|
||||
+++ b/kexec/fs2dt.h
|
||||
@@ -30,7 +30,7 @@ extern struct bootblock bb[1];
|
||||
|
||||
/* Used for enabling printing message from purgatory code
|
||||
* Only has implemented for PPC64 */
|
||||
-int my_debug;
|
||||
+extern int my_debug;
|
||||
extern int dt_no_old_root;
|
||||
|
||||
void reserve(unsigned long long where, unsigned long long length);
|
||||
--
|
||||
2.24.1
|
||||
|
||||
@ -1,36 +0,0 @@
|
||||
From 2837fb1f5f8362976c188b30ebe50dc8b0377f64 Mon Sep 17 00:00:00 2001
|
||||
From: Kairui Song <kasong@redhat.com>
|
||||
Date: Wed, 29 Jan 2020 11:33:18 +0800
|
||||
Subject: [PATCH] Remove duplicated variable declaration
|
||||
|
||||
When building on Fedora 32, following error is observed:
|
||||
|
||||
...
|
||||
/usr/bin/ld: ../eppic/libeppic/libeppic.a(eppic_stat.o):/builddir/build/BUILD/kexec-tools-2.0.20/eppic/libeppic/eppic.h:474: multiple definition of `lastv';
|
||||
../eppic/libeppic/libeppic.a(eppic_func.o):/builddir/build/BUILD/kexec-tools-2.0.20/eppic/libeppic/eppic.h:474: first defined here
|
||||
...
|
||||
|
||||
And apparently, the variable is wrongly declared multiple times. So
|
||||
remove duplicated declaration.
|
||||
|
||||
Signed-off-by: Kairui Song <kasong@redhat.com>
|
||||
---
|
||||
libeppic/eppic.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libeppic/eppic.h b/libeppic/eppic.h
|
||||
index 5664583..836b475 100644
|
||||
--- a/eppic-d84c3541035d95077aa8571f5d5c3e07c6ef510b/libeppic/eppic.h
|
||||
+++ b/eppic-d84c3541035d95077aa8571f5d5c3e07c6ef510b/libeppic/eppic.h
|
||||
@@ -471,7 +471,7 @@ type_t *eppic_addstorage(type_t *t1, type_t *t2);
|
||||
type_t *eppic_getvoidstruct(int ctype);
|
||||
|
||||
extern int lineno, needvar, instruct, nomacs, eppic_legacy;
|
||||
-node_t *lastv;
|
||||
+extern node_t *lastv;
|
||||
|
||||
#define NULLNODE ((node_t*)0)
|
||||
|
||||
--
|
||||
2.24.1
|
||||
|
||||
@ -1,88 +0,0 @@
|
||||
From 940c3a1e1a304fbecc850c593a272215b0f52eab Mon Sep 17 00:00:00 2001
|
||||
From: Kairui Song <kasong@redhat.com>
|
||||
Date: Wed, 31 Jul 2019 16:30:47 +0800
|
||||
Subject: [PATCH] x86: Fix broken multiboot2 buliding for i386
|
||||
|
||||
When building for i386, an error occured:
|
||||
|
||||
kexec/arch/i386/kexec-x86.c:39:22: error: 'multiboot2_x86_probe'
|
||||
undeclared here (not in a function); did you mean 'multiboot_x86_probe'?
|
||||
39 | { "multiboot2-x86", multiboot2_x86_probe, multiboot2_x86_load,
|
||||
| ^~~~~~~~~~~~~~~~~~~~
|
||||
| multiboot_x86_probe
|
||||
|
||||
kexec/arch/i386/kexec-x86.c:39:44: error: 'multiboot2_x86_load'
|
||||
undeclared here (not in a function); did you mean 'multiboot_x86_load'?
|
||||
39 | { "multiboot2-x86", multiboot2_x86_probe, multiboot2_x86_load,
|
||||
| ^~~~~~~~~~~~~~~~~~~
|
||||
| multiboot_x86_load
|
||||
kexec/arch/i386/kexec-x86.c:40:4: error: 'multiboot2_x86_usage'
|
||||
undeclared here (not in a function); did you mean 'multiboot_x86_usage'?
|
||||
40 | multiboot2_x86_usage },
|
||||
| ^~~~~~~~~~~~~~~~~~~~
|
||||
| multiboot_x86_usage
|
||||
|
||||
Fix this issue by putting the definition in the right header, also tidy
|
||||
up Makefile.
|
||||
|
||||
Fixes: 22a2ed55132e ("x86: Support multiboot2 images")
|
||||
Signed-off-by: Kairui Song <kasong@redhat.com>
|
||||
---
|
||||
kexec/arch/i386/Makefile | 2 +-
|
||||
kexec/arch/i386/kexec-x86.h | 5 +++++
|
||||
kexec/arch/x86_64/kexec-x86_64.h | 5 -----
|
||||
3 files changed, 6 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/kexec/arch/i386/Makefile b/kexec/arch/i386/Makefile
|
||||
index 105cefd..f486103 100644
|
||||
--- a/kexec/arch/i386/Makefile
|
||||
+++ b/kexec/arch/i386/Makefile
|
||||
@@ -7,6 +7,7 @@ i386_KEXEC_SRCS += kexec/arch/i386/kexec-elf-x86.c
|
||||
i386_KEXEC_SRCS += kexec/arch/i386/kexec-elf-rel-x86.c
|
||||
i386_KEXEC_SRCS += kexec/arch/i386/kexec-bzImage.c
|
||||
i386_KEXEC_SRCS += kexec/arch/i386/kexec-multiboot-x86.c
|
||||
+i386_KEXEC_SRCS += kexec/arch/i386/kexec-mb2-x86.c
|
||||
i386_KEXEC_SRCS += kexec/arch/i386/kexec-beoboot-x86.c
|
||||
i386_KEXEC_SRCS += kexec/arch/i386/kexec-nbi.c
|
||||
i386_KEXEC_SRCS += kexec/arch/i386/x86-linux-setup.c
|
||||
@@ -14,7 +15,6 @@ i386_KEXEC_SRCS += kexec/arch/i386/crashdump-x86.c
|
||||
|
||||
dist += kexec/arch/i386/Makefile $(i386_KEXEC_SRCS) \
|
||||
kexec/arch/i386/crashdump-x86.h \
|
||||
- kexec/arch/i386/kexec-mb2-x86.c \
|
||||
kexec/arch/i386/kexec-x86.h \
|
||||
kexec/arch/i386/x86-linux-setup.h \
|
||||
kexec/arch/i386/include/arch/options.h
|
||||
diff --git a/kexec/arch/i386/kexec-x86.h b/kexec/arch/i386/kexec-x86.h
|
||||
index 1b58c3b..16d0f6c 100644
|
||||
--- a/kexec/arch/i386/kexec-x86.h
|
||||
+++ b/kexec/arch/i386/kexec-x86.h
|
||||
@@ -60,6 +60,11 @@ int multiboot_x86_load(int argc, char **argv, const char *buf, off_t len,
|
||||
struct kexec_info *info);
|
||||
void multiboot_x86_usage(void);
|
||||
|
||||
+int multiboot2_x86_load(int argc, char **argv, const char *buf, off_t len,
|
||||
+ struct kexec_info *info);
|
||||
+void multiboot2_x86_usage(void);
|
||||
+int multiboot2_x86_probe(const char *buf, off_t buf_len);
|
||||
+
|
||||
int elf_x86_probe(const char *buf, off_t len);
|
||||
int elf_x86_load(int argc, char **argv, const char *buf, off_t len,
|
||||
struct kexec_info *info);
|
||||
diff --git a/kexec/arch/x86_64/kexec-x86_64.h b/kexec/arch/x86_64/kexec-x86_64.h
|
||||
index 21c3a73..4cdeffb 100644
|
||||
--- a/kexec/arch/x86_64/kexec-x86_64.h
|
||||
+++ b/kexec/arch/x86_64/kexec-x86_64.h
|
||||
@@ -33,9 +33,4 @@ int bzImage64_load(int argc, char **argv, const char *buf, off_t len,
|
||||
struct kexec_info *info);
|
||||
void bzImage64_usage(void);
|
||||
|
||||
-int multiboot2_x86_load(int argc, char **argv, const char *buf, off_t len,
|
||||
- struct kexec_info *info);
|
||||
-void multiboot2_x86_usage(void);
|
||||
-int multiboot2_x86_probe(const char *buf, off_t buf_len);
|
||||
-
|
||||
#endif /* KEXEC_X86_64_H */
|
||||
--
|
||||
2.21.0
|
||||
|
||||
@ -1,255 +0,0 @@
|
||||
From 989152e113bfcb4fbfbad6f3aed6f43be4455919 Mon Sep 17 00:00:00 2001
|
||||
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
Date: Tue, 25 Feb 2020 16:04:55 -0500
|
||||
Subject: [PATCH] Introduce --check-params option
|
||||
|
||||
Currently it's difficult to check whether a makedumpfile command-line
|
||||
is valid or not without an actual panic. This is inefficient and if
|
||||
a wrong configuration is not tested, you will miss the vmcore when an
|
||||
actual panic occurs.
|
||||
|
||||
In order for kdump facilities like kexec-tools to be able to check
|
||||
the specified command-line parameters in advance, introduce the
|
||||
--check-params option that only checks them and exits immediately.
|
||||
|
||||
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
---
|
||||
makedumpfile.8 | 5 ++++
|
||||
makedumpfile.c | 75 ++++++++++++++++++++++++++++++++++++++------------
|
||||
print_info.c | 4 +++
|
||||
4 files changed, 69 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/makedumpfile-1.6.7/makedumpfile.8 b/makedumpfile-1.6.7/makedumpfile.8
|
||||
index bf156a8..c5d4806 100644
|
||||
--- a/makedumpfile-1.6.7/makedumpfile.8
|
||||
+++ b/makedumpfile-1.6.7/makedumpfile.8
|
||||
@@ -632,6 +632,11 @@ Show help message and LZO/snappy support status (enabled/disabled).
|
||||
\fB\-v\fR
|
||||
Show the version of makedumpfile.
|
||||
|
||||
+.TP
|
||||
+\fB\-\-check-params\fR
|
||||
+Only check whether the command-line parameters are valid or not, and exit.
|
||||
+Preferable to be given as the first parameter.
|
||||
+
|
||||
.SH ENVIRONMENT VARIABLES
|
||||
|
||||
.TP 8
|
||||
diff --git a/makedumpfile-1.6.7/makedumpfile.c b/makedumpfile-1.6.7/makedumpfile.c
|
||||
index 607e07f..f5860a1 100644
|
||||
--- a/makedumpfile-1.6.7/makedumpfile.c
|
||||
+++ b/makedumpfile-1.6.7/makedumpfile.c
|
||||
@@ -10978,12 +10978,6 @@ check_param_for_creating_dumpfile(int argc, char *argv[])
|
||||
if (info->flag_generate_vmcoreinfo || info->flag_rearrange)
|
||||
return FALSE;
|
||||
|
||||
- if ((message_level < MIN_MSG_LEVEL)
|
||||
- || (MAX_MSG_LEVEL < message_level)) {
|
||||
- message_level = DEFAULT_MSG_LEVEL;
|
||||
- MSG("Message_level is invalid.\n");
|
||||
- return FALSE;
|
||||
- }
|
||||
if ((info->flag_compress && info->flag_elf_dumpfile)
|
||||
|| (info->flag_read_vmcoreinfo && info->name_vmlinux)
|
||||
|| (info->flag_read_vmcoreinfo && info->name_xen_syms))
|
||||
@@ -11013,6 +11007,11 @@ check_param_for_creating_dumpfile(int argc, char *argv[])
|
||||
if (info->flag_partial_dmesg && !info->flag_dmesg)
|
||||
return FALSE;
|
||||
|
||||
+ if (info->flag_excludevm && !info->working_dir) {
|
||||
+ MSG("-%c requires --work-dir\n", OPT_EXCLUDE_UNUSED_VM);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
if ((argc == optind + 2) && !info->flag_flatten
|
||||
&& !info->flag_split
|
||||
&& !info->flag_sadump_diskset) {
|
||||
@@ -11408,6 +11407,23 @@ int show_mem_usage(void)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+static int set_message_level(char *str_ml)
|
||||
+{
|
||||
+ int ml;
|
||||
+
|
||||
+ ml = atoi(str_ml);
|
||||
+ if ((ml < MIN_MSG_LEVEL) || (MAX_MSG_LEVEL < ml)) {
|
||||
+ message_level = DEFAULT_MSG_LEVEL;
|
||||
+ MSG("Message_level(%d) is invalid.\n", ml);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ if (info->flag_check_params)
|
||||
+ return TRUE;
|
||||
+
|
||||
+ message_level = ml;
|
||||
+ return TRUE;
|
||||
+}
|
||||
|
||||
static struct option longopts[] = {
|
||||
{"split", no_argument, NULL, OPT_SPLIT},
|
||||
@@ -11429,6 +11445,7 @@ static struct option longopts[] = {
|
||||
{"splitblock-size", required_argument, NULL, OPT_SPLITBLOCK_SIZE},
|
||||
{"work-dir", required_argument, NULL, OPT_WORKING_DIR},
|
||||
{"num-threads", required_argument, NULL, OPT_NUM_THREADS},
|
||||
+ {"check-params", no_argument, NULL, OPT_CHECK_PARAMS},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
@@ -11527,7 +11544,8 @@ main(int argc, char *argv[])
|
||||
info->flag_compress = DUMP_DH_COMPRESSED_LZO;
|
||||
break;
|
||||
case OPT_MESSAGE_LEVEL:
|
||||
- message_level = atoi(optarg);
|
||||
+ if (!set_message_level(optarg))
|
||||
+ goto out;
|
||||
break;
|
||||
case OPT_DUMP_DMESG:
|
||||
info->flag_dmesg = 1;
|
||||
@@ -11590,6 +11608,10 @@ main(int argc, char *argv[])
|
||||
case OPT_NUM_THREADS:
|
||||
info->num_threads = MAX(atoi(optarg), 0);
|
||||
break;
|
||||
+ case OPT_CHECK_PARAMS:
|
||||
+ info->flag_check_params = TRUE;
|
||||
+ message_level = DEFAULT_MSG_LEVEL;
|
||||
+ break;
|
||||
case '?':
|
||||
MSG("Commandline parameter is invalid.\n");
|
||||
MSG("Try `makedumpfile --help' for more information.\n");
|
||||
@@ -11599,11 +11621,9 @@ main(int argc, char *argv[])
|
||||
if (flag_debug)
|
||||
message_level |= ML_PRINT_DEBUG_MSG;
|
||||
|
||||
- if (info->flag_excludevm && !info->working_dir) {
|
||||
- ERRMSG("Error: -%c requires --work-dir\n", OPT_EXCLUDE_UNUSED_VM);
|
||||
- ERRMSG("Try `makedumpfile --help' for more information\n");
|
||||
- return COMPLETED;
|
||||
- }
|
||||
+ if (info->flag_check_params)
|
||||
+ /* suppress debugging messages */
|
||||
+ message_level = DEFAULT_MSG_LEVEL;
|
||||
|
||||
if (info->flag_show_usage) {
|
||||
print_usage();
|
||||
@@ -11634,6 +11654,9 @@ main(int argc, char *argv[])
|
||||
MSG("Try `makedumpfile --help' for more information.\n");
|
||||
goto out;
|
||||
}
|
||||
+ if (info->flag_check_params)
|
||||
+ goto check_ok;
|
||||
+
|
||||
if (!open_files_for_generating_vmcoreinfo())
|
||||
goto out;
|
||||
|
||||
@@ -11657,6 +11680,9 @@ main(int argc, char *argv[])
|
||||
MSG("Try `makedumpfile --help' for more information.\n");
|
||||
goto out;
|
||||
}
|
||||
+ if (info->flag_check_params)
|
||||
+ goto check_ok;
|
||||
+
|
||||
if (!check_dump_file(info->name_dumpfile))
|
||||
goto out;
|
||||
|
||||
@@ -11677,6 +11703,9 @@ main(int argc, char *argv[])
|
||||
MSG("Try `makedumpfile --help' for more information.\n");
|
||||
goto out;
|
||||
}
|
||||
+ if (info->flag_check_params)
|
||||
+ goto check_ok;
|
||||
+
|
||||
if (!check_dump_file(info->name_dumpfile))
|
||||
goto out;
|
||||
|
||||
@@ -11690,6 +11719,9 @@ main(int argc, char *argv[])
|
||||
MSG("Try `makedumpfile --help' for more information.\n");
|
||||
goto out;
|
||||
}
|
||||
+ if (info->flag_check_params)
|
||||
+ goto check_ok;
|
||||
+
|
||||
if (!check_dump_file(info->name_dumpfile))
|
||||
goto out;
|
||||
if (!dump_dmesg())
|
||||
@@ -11703,6 +11735,9 @@ main(int argc, char *argv[])
|
||||
MSG("Try `makedumpfile --help' for more information.\n");
|
||||
goto out;
|
||||
}
|
||||
+ if (info->flag_check_params)
|
||||
+ goto check_ok;
|
||||
+
|
||||
if (!populate_kernel_version())
|
||||
goto out;
|
||||
|
||||
@@ -11721,6 +11756,9 @@ main(int argc, char *argv[])
|
||||
MSG("Try `makedumpfile --help' for more information.\n");
|
||||
goto out;
|
||||
}
|
||||
+ if (info->flag_check_params)
|
||||
+ goto check_ok;
|
||||
+
|
||||
if (info->flag_split) {
|
||||
for (i = 0; i < info->num_dumpfile; i++) {
|
||||
SPLITTING_FD_BITMAP(i) = -1;
|
||||
@@ -11748,13 +11786,16 @@ main(int argc, char *argv[])
|
||||
MSG("The dumpfile is saved to %s.\n", info->name_dumpfile);
|
||||
}
|
||||
}
|
||||
+check_ok:
|
||||
retcd = COMPLETED;
|
||||
out:
|
||||
- MSG("\n");
|
||||
- if (retcd != COMPLETED)
|
||||
- MSG("makedumpfile Failed.\n");
|
||||
- else if (!info->flag_mem_usage)
|
||||
- MSG("makedumpfile Completed.\n");
|
||||
+ if (!info->flag_check_params) {
|
||||
+ MSG("\n");
|
||||
+ if (retcd != COMPLETED)
|
||||
+ MSG("makedumpfile Failed.\n");
|
||||
+ else if (!info->flag_mem_usage)
|
||||
+ MSG("makedumpfile Completed.\n");
|
||||
+ }
|
||||
|
||||
free_for_parallel();
|
||||
|
||||
diff --git a/makedumpfile-1.6.7/makedumpfile.h b/makedumpfile-1.6.7/makedumpfile.h
|
||||
index 7217407..03fb4ce 100644
|
||||
--- a/makedumpfile-1.6.7/makedumpfile.h
|
||||
+++ b/makedumpfile-1.6.7/makedumpfile.h
|
||||
@@ -1303,6 +1303,7 @@ struct DumpInfo {
|
||||
int flag_read_vmcoreinfo; /* flag of reading vmcoreinfo file */
|
||||
int flag_show_usage; /* flag of showing usage */
|
||||
int flag_show_version; /* flag of showing version */
|
||||
+ int flag_check_params; /* only check parameters */
|
||||
int flag_flatten; /* flag of outputting flattened
|
||||
format to a standard out */
|
||||
int flag_rearrange; /* flag of creating dumpfile from
|
||||
@@ -2364,6 +2365,7 @@ struct elf_prstatus {
|
||||
#define OPT_WORKING_DIR OPT_START+15
|
||||
#define OPT_NUM_THREADS OPT_START+16
|
||||
#define OPT_PARTIAL_DMESG OPT_START+17
|
||||
+#define OPT_CHECK_PARAMS OPT_START+18
|
||||
|
||||
/*
|
||||
* Function Prototype.
|
||||
diff --git a/makedumpfile-1.6.7/print_info.c b/makedumpfile-1.6.7/print_info.c
|
||||
index 0be12ea..e0c38b4 100644
|
||||
--- a/makedumpfile-1.6.7/print_info.c
|
||||
+++ b/makedumpfile-1.6.7/print_info.c
|
||||
@@ -321,6 +321,10 @@ print_usage(void)
|
||||
MSG(" [-v]:\n");
|
||||
MSG(" Show the version of makedumpfile.\n");
|
||||
MSG("\n");
|
||||
+ MSG(" [--check-params]:\n");
|
||||
+ MSG(" Only check whether the command-line parameters are valid or not, and exit.\n");
|
||||
+ MSG(" Preferable to be given as the first parameter.\n");
|
||||
+ MSG("\n");
|
||||
MSG(" VMLINUX:\n");
|
||||
MSG(" This is a pathname to the first kernel's vmlinux.\n");
|
||||
MSG(" This file must have the debug information of the first kernel to analyze\n");
|
||||
--
|
||||
2.24.1
|
||||
|
||||
|
||||
@ -1,76 +0,0 @@
|
||||
From efa29d476996a20052be80878767cfe09e4b6224 Mon Sep 17 00:00:00 2001
|
||||
From: Kairui Song <kasong@redhat.com>
|
||||
Date: Wed, 29 Jan 2020 10:59:08 +0800
|
||||
Subject: [PATCH] makedumpfile: Remove duplicated variable declarations
|
||||
|
||||
When building on Fedora 32, following error is observed:
|
||||
|
||||
/usr/bin/ld: erase_info.o:/builddir/build/BUILD/kexec-tools-2.0.20/makedumpfile-1.6.7/makedumpfile.h:2010:
|
||||
multiple definition of `crash_reserved_mem_nr'; elf_info.o:/builddir/build/BUILD/kexec-tools-2.0.20/makedumpfile-1.6.7/makedumpfile.h:2010: first defined here
|
||||
/usr/bin/ld: erase_info.o:/builddir/build/BUILD/kexec-tools-2.0.20/makedumpfile-1.6.7/makedumpfile.h:2009:
|
||||
multiple definition of `crash_reserved_mem'; elf_info.o:/builddir/build/BUILD/kexec-tools-2.0.20/makedumpfile-1.6.7/makedumpfile.h:2009: first defined here
|
||||
/usr/bin/ld: erase_info.o:/builddir/build/BUILD/kexec-tools-2.0.20/makedumpfile-1.6.7/makedumpfile.h:1278:
|
||||
multiple definition of `parallel_info_t'; elf_info.o:/builddir/build/BUILD/kexec-tools-2.0.20/makedumpfile-1.6.7/makedumpfile.h:1278: first defined here
|
||||
/usr/bin/ld: erase_info.o:/builddir/build/BUILD/kexec-tools-2.0.20/makedumpfile-1.6.7/makedumpfile.h:1265:
|
||||
multiple definition of `splitting_info_t'; elf_info.o:/builddir/build/BUILD/kexec-tools-2.0.20/makedumpfile-1.6.7/makedumpfile.h:1265: first defined here
|
||||
|
||||
And apparently, these variables are wrongly declared multiple times. So
|
||||
remove duplicated declaration.
|
||||
|
||||
Signed-off-by: Kairui Song <kasong@redhat.com>
|
||||
---
|
||||
makedumpfile.c | 2 ++
|
||||
makedumpfile.h | 10 ++++++----
|
||||
2 files changed, 8 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/makedumpfile.c b/makedumpfile.c
|
||||
index e290fbd..9aad77b 100644
|
||||
--- a/makedumpfile-1.6.7/makedumpfile.c
|
||||
+++ b/makedumpfile-1.6.7/makedumpfile.c
|
||||
@@ -34,6 +34,8 @@ struct array_table array_table;
|
||||
struct number_table number_table;
|
||||
struct srcfile_table srcfile_table;
|
||||
struct save_control sc;
|
||||
+struct parallel_info parallel_info_t;
|
||||
+struct splitting_info splitting_info_t;
|
||||
|
||||
struct vm_table vt = { 0 };
|
||||
struct DumpInfo *info = NULL;
|
||||
diff --git a/makedumpfile.h b/makedumpfile.h
|
||||
index 68d9691..614764c 100644
|
||||
--- a/makedumpfile-1.6.7/makedumpfile.h
|
||||
+++ b/makedumpfile-1.6.7/makedumpfile.h
|
||||
@@ -1262,7 +1262,8 @@ struct splitting_info {
|
||||
mdf_pfn_t end_pfn;
|
||||
off_t offset_eraseinfo;
|
||||
unsigned long size_eraseinfo;
|
||||
-} splitting_info_t;
|
||||
+};
|
||||
+extern struct splitting_info splitting_info_t;
|
||||
|
||||
struct parallel_info {
|
||||
int fd_memory;
|
||||
@@ -1275,7 +1276,8 @@ struct parallel_info {
|
||||
#ifdef USELZO
|
||||
lzo_bytep wrkmem;
|
||||
#endif
|
||||
-} parallel_info_t;
|
||||
+};
|
||||
+extern struct parallel_info parallel_info_t;
|
||||
|
||||
struct ppc64_vmemmap {
|
||||
unsigned long phys;
|
||||
@@ -2006,8 +2008,8 @@ struct memory_range {
|
||||
};
|
||||
|
||||
#define CRASH_RESERVED_MEM_NR 8
|
||||
-struct memory_range crash_reserved_mem[CRASH_RESERVED_MEM_NR];
|
||||
-int crash_reserved_mem_nr;
|
||||
+extern struct memory_range crash_reserved_mem[CRASH_RESERVED_MEM_NR];
|
||||
+extern int crash_reserved_mem_nr;
|
||||
|
||||
unsigned long read_vmcoreinfo_symbol(char *str_symbol);
|
||||
int readmem(int type_addr, unsigned long long addr, void *bufptr, size_t size);
|
||||
--
|
||||
2.24.1
|
||||
|
||||
Binary file not shown.
BIN
kexec-tools-2.0.23.tar.xz
Normal file
BIN
kexec-tools-2.0.23.tar.xz
Normal file
Binary file not shown.
@ -1,225 +0,0 @@
|
||||
From 4f77da6340356de40af70473d3c3ae6ec663fbdf Mon Sep 17 00:00:00 2001
|
||||
From: Petr Tesarik <ptesarik@suse.com>
|
||||
Date: Fri, 13 Mar 2020 15:09:28 +0100
|
||||
Subject: [PATCH] kexec-tools: Fix kexec_file_load(2) error handling
|
||||
|
||||
The handling of kexec_file_load() error conditions needs some
|
||||
improvement.
|
||||
|
||||
First, on failure, the system call itself returns -1 and sets
|
||||
errno. It is wrong to check the return value itself.
|
||||
|
||||
Second, do_kexec_file_load() mixes different types of error
|
||||
codes (-1, return value of a load method, negative kernel error
|
||||
number). Let it always return one of the reason codes defined in
|
||||
kexec/kexec.h.
|
||||
|
||||
Third, the caller of do_kexec_file_load() cannot know what exactly
|
||||
failed inside that function, so it should not check errno directly.
|
||||
All it needs to know is whether it makes sense to fall back to the
|
||||
other syscall. Add an error code for that purpose (EFALLBACK), and
|
||||
let do_kexec_file_load() decide.
|
||||
|
||||
Fourth, do_kexec_file_load() should not print any error message if
|
||||
it returns EFALLBACK, because the fallback syscall may succeed
|
||||
later, and the user is confused whether the command failed, or not.
|
||||
Move the error message towards the end of main().
|
||||
|
||||
Signed-off-by: Petr Tesarik <ptesarik@suse.com>
|
||||
Signed-off-by: Simon Horman <horms@verge.net.au>
|
||||
|
||||
diff --git a/kexec/kexec.c b/kexec/kexec.c
|
||||
index bc6ab3d..33c1b4b 100644
|
||||
--- a/kexec/kexec.c
|
||||
+++ b/kexec/kexec.c
|
||||
@@ -836,11 +836,21 @@ static int kexec_file_unload(unsigned long kexec_file_flags)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
+ if (!is_kexec_file_load_implemented())
|
||||
+ return EFALLBACK;
|
||||
+
|
||||
ret = kexec_file_load(-1, -1, 0, NULL, kexec_file_flags);
|
||||
if (ret != 0) {
|
||||
- /* The unload failed, print some debugging information */
|
||||
- fprintf(stderr, "kexec_file_load(unload) failed\n: %s\n",
|
||||
- strerror(errno));
|
||||
+ if (errno == ENOSYS) {
|
||||
+ ret = EFALLBACK;
|
||||
+ } else {
|
||||
+ /*
|
||||
+ * The unload failed, print some debugging
|
||||
+ * information */
|
||||
+ fprintf(stderr, "kexec_file_load(unload) failed: %s\n",
|
||||
+ strerror(errno));
|
||||
+ ret = EFAILED;
|
||||
+ }
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -1182,15 +1192,13 @@ static int do_kexec_file_load(int fileind, int argc, char **argv,
|
||||
info.file_mode = 1;
|
||||
info.initrd_fd = -1;
|
||||
|
||||
- if (!is_kexec_file_load_implemented()) {
|
||||
- fprintf(stderr, "syscall kexec_file_load not available.\n");
|
||||
- return -ENOSYS;
|
||||
- }
|
||||
+ if (!is_kexec_file_load_implemented())
|
||||
+ return EFALLBACK;
|
||||
|
||||
if (argc - fileind <= 0) {
|
||||
fprintf(stderr, "No kernel specified\n");
|
||||
usage();
|
||||
- return -1;
|
||||
+ return EFAILED;
|
||||
}
|
||||
|
||||
kernel = argv[fileind];
|
||||
@@ -1199,7 +1207,7 @@ static int do_kexec_file_load(int fileind, int argc, char **argv,
|
||||
if (kernel_fd == -1) {
|
||||
fprintf(stderr, "Failed to open file %s:%s\n", kernel,
|
||||
strerror(errno));
|
||||
- return -1;
|
||||
+ return EFAILED;
|
||||
}
|
||||
|
||||
/* slurp in the input kernel */
|
||||
@@ -1225,7 +1233,7 @@ static int do_kexec_file_load(int fileind, int argc, char **argv,
|
||||
if (i == file_types) {
|
||||
fprintf(stderr, "Cannot determine the file type " "of %s\n",
|
||||
kernel);
|
||||
- return -1;
|
||||
+ return EFAILED;
|
||||
}
|
||||
|
||||
ret = file_type[i].load(argc, argv, kernel_buf, kernel_size, &info);
|
||||
@@ -1243,9 +1251,43 @@ static int do_kexec_file_load(int fileind, int argc, char **argv,
|
||||
|
||||
ret = kexec_file_load(kernel_fd, info.initrd_fd, info.command_line_len,
|
||||
info.command_line, info.kexec_flags);
|
||||
- if (ret != 0)
|
||||
- fprintf(stderr, "kexec_file_load failed: %s\n",
|
||||
- strerror(errno));
|
||||
+ if (ret != 0) {
|
||||
+ switch (errno) {
|
||||
+ /*
|
||||
+ * Something failed with signature verification.
|
||||
+ * Reject the image.
|
||||
+ */
|
||||
+ case ELIBBAD:
|
||||
+ case EKEYREJECTED:
|
||||
+ case ENOPKG:
|
||||
+ case ENOKEY:
|
||||
+ case EBADMSG:
|
||||
+ case EMSGSIZE:
|
||||
+ /* Reject by default. */
|
||||
+ default:
|
||||
+ ret = EFAILED;
|
||||
+ break;
|
||||
+
|
||||
+ /* Not implemented. */
|
||||
+ case ENOSYS:
|
||||
+ /*
|
||||
+ * Parsing image or other options failed
|
||||
+ * The image may be invalid or image
|
||||
+ * type may not supported by kernel so
|
||||
+ * retry parsing in kexec-tools.
|
||||
+ */
|
||||
+ case EINVAL:
|
||||
+ case ENOEXEC:
|
||||
+ /*
|
||||
+ * ENOTSUP can be unsupported image
|
||||
+ * type or unsupported PE signature
|
||||
+ * wrapper type, duh.
|
||||
+ */
|
||||
+ case ENOTSUP:
|
||||
+ ret = EFALLBACK;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
close(kernel_fd);
|
||||
return ret;
|
||||
@@ -1496,7 +1538,7 @@ int main(int argc, char *argv[])
|
||||
if (do_unload) {
|
||||
if (do_kexec_file_syscall) {
|
||||
result = kexec_file_unload(kexec_file_flags);
|
||||
- if ((result == -ENOSYS) && do_kexec_fallback)
|
||||
+ if (result == EFALLBACK && do_kexec_fallback)
|
||||
do_kexec_file_syscall = 0;
|
||||
}
|
||||
if (!do_kexec_file_syscall)
|
||||
@@ -1506,46 +1548,8 @@ int main(int argc, char *argv[])
|
||||
if (do_kexec_file_syscall) {
|
||||
result = do_kexec_file_load(fileind, argc, argv,
|
||||
kexec_file_flags);
|
||||
- if (do_kexec_fallback) switch (result) {
|
||||
- /*
|
||||
- * Something failed with signature verification.
|
||||
- * Reject the image.
|
||||
- */
|
||||
- case -ELIBBAD:
|
||||
- case -EKEYREJECTED:
|
||||
- case -ENOPKG:
|
||||
- case -ENOKEY:
|
||||
- case -EBADMSG:
|
||||
- case -EMSGSIZE:
|
||||
- /*
|
||||
- * By default reject or do nothing if
|
||||
- * succeded
|
||||
- */
|
||||
- default: break;
|
||||
- case -ENOSYS: /* not implemented */
|
||||
- /*
|
||||
- * Parsing image or other options failed
|
||||
- * The image may be invalid or image
|
||||
- * type may not supported by kernel so
|
||||
- * retry parsing in kexec-tools.
|
||||
- */
|
||||
- case -EINVAL:
|
||||
- case -ENOEXEC:
|
||||
- /*
|
||||
- * ENOTSUP can be unsupported image
|
||||
- * type or unsupported PE signature
|
||||
- * wrapper type, duh
|
||||
- *
|
||||
- * The kernel sometimes wrongly
|
||||
- * returns ENOTSUPP (524) - ignore
|
||||
- * that. It is not supposed to be seen
|
||||
- * by userspace so seeing it is a
|
||||
- * kernel bug
|
||||
- */
|
||||
- case -ENOTSUP:
|
||||
- do_kexec_file_syscall = 0;
|
||||
- break;
|
||||
- }
|
||||
+ if (result == EFALLBACK && do_kexec_fallback)
|
||||
+ do_kexec_file_syscall = 0;
|
||||
}
|
||||
if (!do_kexec_file_syscall)
|
||||
result = my_load(type, fileind, argc, argv,
|
||||
@@ -1570,6 +1574,8 @@ int main(int argc, char *argv[])
|
||||
if ((result == 0) && do_load_jump_back_helper) {
|
||||
result = my_load_jump_back_helper(kexec_flags, entry);
|
||||
}
|
||||
+ if (result == EFALLBACK)
|
||||
+ fputs("syscall kexec_file_load not available.\n", stderr);
|
||||
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
diff --git a/kexec/kexec.h b/kexec/kexec.h
|
||||
index a97b9ce..28fd129 100644
|
||||
--- a/kexec/kexec.h
|
||||
+++ b/kexec/kexec.h
|
||||
@@ -63,6 +63,7 @@
|
||||
*/
|
||||
#define EFAILED -1 /* default error code */
|
||||
#define ENOCRASHKERNEL -2 /* no memory reserved for crashkernel */
|
||||
+#define EFALLBACK -3 /* fallback to kexec_load(2) may work */
|
||||
|
||||
/*
|
||||
* This function doesn't actually exist. The idea is that when someone
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,31 +0,0 @@
|
||||
From 775f258fbd1895ba669be22f108faf817247a47a Mon Sep 17 00:00:00 2001
|
||||
From: Helge Deller <deller@gmx.de>
|
||||
Date: Tue, 1 Oct 2019 17:06:05 +0200
|
||||
Subject: [PATCH] kexec-tools: Fix possible out-of-bounds access in ifdown
|
||||
|
||||
Fix a possible out-of-bounds access in function ifdown():
|
||||
|
||||
ifdown.c: In function 'ifdown':
|
||||
ifdown.c:56:4: warning: 'strncpy' specified bound 16 equals destination size [-Wstringop-truncation]
|
||||
56 | strncpy(ifr.ifr_name, ifp->if_name, IFNAMSIZ);
|
||||
|
||||
Signed-off-by: Helge Deller <deller@gmx.de>
|
||||
Signed-off-by: Simon Horman <horms@verge.net.au>
|
||||
|
||||
diff --git a/kexec/ifdown.c b/kexec/ifdown.c
|
||||
index 9679ad7..3ac19c1 100644
|
||||
--- a/kexec/ifdown.c
|
||||
+++ b/kexec/ifdown.c
|
||||
@@ -53,7 +53,8 @@ int ifdown(void)
|
||||
if (strchr(ifp->if_name, ':') != NULL)
|
||||
continue;
|
||||
|
||||
- strncpy(ifr.ifr_name, ifp->if_name, IFNAMSIZ);
|
||||
+ strncpy(ifr.ifr_name, ifp->if_name, IFNAMSIZ-1);
|
||||
+ ifr.ifr_name[IFNAMSIZ-1] = 0;
|
||||
if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
|
||||
fprintf(stderr, "ifdown: shutdown ");
|
||||
perror(ifp->if_name);
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,51 +0,0 @@
|
||||
From 9cf721279f6cb0dec09c8752e471f15fb662406b Mon Sep 17 00:00:00 2001
|
||||
From: Petr Tesarik <ptesarik@suse.com>
|
||||
Date: Fri, 13 Mar 2020 15:09:29 +0100
|
||||
Subject: [PATCH] kexec-tools: Reset getopt before falling back to legacy
|
||||
syscall
|
||||
|
||||
The modules may need to parse the arguments again after
|
||||
kexec_file_load(2) failed, but getopt is not reset.
|
||||
|
||||
This change fixes the --initrd option on s390x. Without this patch,
|
||||
it will fail to load the initrd on kernels that do not implement
|
||||
kexec_file_load(2).
|
||||
|
||||
Signed-off-by: Petr Tesarik <ptesarik@suse.com>
|
||||
Signed-off-by: Simon Horman <horms@verge.net.au>
|
||||
|
||||
diff --git a/kexec/kexec.c b/kexec/kexec.c
|
||||
index 33c1b4b..6601f1f 100644
|
||||
--- a/kexec/kexec.c
|
||||
+++ b/kexec/kexec.c
|
||||
@@ -1538,8 +1538,12 @@ int main(int argc, char *argv[])
|
||||
if (do_unload) {
|
||||
if (do_kexec_file_syscall) {
|
||||
result = kexec_file_unload(kexec_file_flags);
|
||||
- if (result == EFALLBACK && do_kexec_fallback)
|
||||
+ if (result == EFALLBACK && do_kexec_fallback) {
|
||||
+ /* Reset getopt for fallback */
|
||||
+ opterr = 1;
|
||||
+ optind = 1;
|
||||
do_kexec_file_syscall = 0;
|
||||
+ }
|
||||
}
|
||||
if (!do_kexec_file_syscall)
|
||||
result = k_unload(kexec_flags);
|
||||
@@ -1548,8 +1552,12 @@ int main(int argc, char *argv[])
|
||||
if (do_kexec_file_syscall) {
|
||||
result = do_kexec_file_load(fileind, argc, argv,
|
||||
kexec_file_flags);
|
||||
- if (result == EFALLBACK && do_kexec_fallback)
|
||||
+ if (result == EFALLBACK && do_kexec_fallback) {
|
||||
+ /* Reset getopt for fallback */
|
||||
+ opterr = 1;
|
||||
+ optind = 1;
|
||||
do_kexec_file_syscall = 0;
|
||||
+ }
|
||||
}
|
||||
if (!do_kexec_file_syscall)
|
||||
result = my_load(type, fileind, argc, argv,
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
%global eppic_ver d84c3541035d95077aa8571f5d5c3e07c6ef510b
|
||||
%global eppic_ver e8844d3793471163ae4a56d8f95897be9e5bd554
|
||||
%global eppic_shortver %(c=%{eppic_ver}; echo ${c:0:7})
|
||||
%global mkdf_ver 1.6.7
|
||||
%global mkdf_ver 1.7.0
|
||||
|
||||
Name: kexec-tools
|
||||
Version: 2.0.20
|
||||
Release: 7
|
||||
Version: 2.0.23
|
||||
Release: 1
|
||||
License: GPLv2
|
||||
Summary: The kexec/kdump userspace component
|
||||
URL: https://www.kernel.org/
|
||||
@ -16,7 +16,7 @@ Source4: kdump.sysconfig.i386
|
||||
Source5: kdump.sysconfig.ppc64
|
||||
Source7: mkdumprd
|
||||
Source8: kdump.conf
|
||||
Source9: http://downloads.sourceforge.net/project/makedumpfile/makedumpfile/%{mkdf_ver}/makedumpfile-%{mkdf_ver}.tar.gz
|
||||
Source9: https://github.com/makedumpfile/makedumpfile/releases/download/%{mkdf_ver}/makedumpfile-%{mkdf_ver}.tar.gz
|
||||
Source12: mkdumprd.8
|
||||
Source13: 98-kexec.rules
|
||||
Source14: 98-kexec.rules.ppc64
|
||||
@ -69,45 +69,10 @@ Requires: systemd-udev%{?_isa}
|
||||
|
||||
%undefine _hardened_build
|
||||
|
||||
Patch0: kexec-tools-2.0.20-fix-broken-multiboot2-buliding-for-i386.patch
|
||||
Patch1: kexec-tools-2.0.20-eppic-Remove-duplicated-variable-declaration.patch
|
||||
Patch2: kexec-tools-2.0.20-makedumpfile-Remove-duplicated-variable-declarations.patch
|
||||
Patch3: kexec-tools-2.0.20-Remove-duplicated-variable-declarations.patch
|
||||
Patch4: kexec-tools-2.0.20-makedumpfile-Introduce-check-params-option.patch
|
||||
Patch5: kexec-add-variant-helper-functions-for-handling-memory-regions.patch
|
||||
Patch6: arm64-kexec-allocate-memory-space-avoiding-reserved-regions.patch
|
||||
|
||||
Patch7: x86-Fix-PAGE_OFFSET-for-kernels-since-4.20.patch
|
||||
Patch8: Cleanup-remove-the-read_elf_kcore.patch
|
||||
Patch9: Fix-an-error-definition-about-the-variable-fname.patch
|
||||
Patch10: Cleanup-move-it-back-from-util_lib-elf_info.c.patch
|
||||
Patch11: Limit-the-size-of-vmcore-dmesg.txt-to-2G.patch
|
||||
Patch12: vmcore-dmesg-vmcore-dmesg.c-Fix-shifting-error-reported-by-cppcheck.patch
|
||||
Patch13: kexec-tools-Fix-possible-out-of-bounds-access-in-ifdown.patch
|
||||
Patch14: kexec-tools-Fix-kexec_file_load-2-error-handling.patch
|
||||
Patch15: kexec-tools-Reset-getopt-before-falling-back-to-legacy.patch
|
||||
Patch16: kexec-support-parsing-the-string-Reserved-to-get-the-correct-e820-reserved-region.patch
|
||||
Patch17: arm64-kdump-deal-with-a-lot-of-resource-entries-in-proc-iomem.patch
|
||||
|
||||
%ifarch aarch64
|
||||
Patch18: arm64-support-more-than-one-crash-kernel-regions.patch
|
||||
%endif
|
||||
|
||||
Patch19: add-secure-compile-options-for-makedumpfile.patch
|
||||
Patch20: fix-header-offset-overflow-when-large-pfn.patch
|
||||
Patch21: kexec-Add-quick-kexec-support.patch
|
||||
|
||||
%ifarch aarch64
|
||||
Patch22: kexec-Quick-kexec-implementation-for-arm64.patch
|
||||
%endif
|
||||
|
||||
Patch23: backport-PATCH-Align-PMD_SECTION_MASK-with-PHYS_MASK.patch
|
||||
Patch24: backport-PATCH-arm64-Add-support-for-ARMv8.2-LPA-52-bit-PA-su.patch
|
||||
Patch25: backport-PATCH-1-3-Use-vmcoreinfo-note-in-proc-kcore-for-mem-.patch
|
||||
Patch26: backport-PATCH-2-3-arm64-Make-use-of-NUMBER-VA_BITS-in-vmcore.patch
|
||||
Patch27: backport-PATCH-3-3-arm64-support-flipped-VA-and-52-bit-kernel.patch
|
||||
Patch28: backport-print-add-support-for-lockless-ringbuffer.patch
|
||||
Patch29: 0001-fix-build-fail-caused-by-file-format-not-recognized.patch
|
||||
Patch0001: arm64-support-more-than-one-crash-kernel-regions.patch
|
||||
Patch0002: add-secure-compile-options-for-makedumpfile.patch
|
||||
Patch0003: kexec-Add-quick-kexec-support.patch
|
||||
Patch0004: kexec-Quick-kexec-implementation-for-arm64.patch
|
||||
|
||||
%description
|
||||
kexec-tools provides /sbin/kexec binary that facilitates a new
|
||||
@ -130,44 +95,15 @@ mkdir -p -m755 kcp
|
||||
tar -z -x -v -f %{SOURCE9}
|
||||
tar -z -x -v -f %{SOURCE19}
|
||||
|
||||
%patch0 -p1
|
||||
%patch1 -p1
|
||||
%patch2 -p1
|
||||
%patch3 -p1
|
||||
%patch4 -p1
|
||||
%patch5 -p1
|
||||
%patch6 -p1
|
||||
%patch7 -p1
|
||||
%patch8 -p1
|
||||
%patch9 -p1
|
||||
%patch10 -p1
|
||||
%patch11 -p1
|
||||
%patch12 -p1
|
||||
%patch13 -p1
|
||||
%patch14 -p1
|
||||
%patch15 -p1
|
||||
%patch16 -p1
|
||||
%patch17 -p1
|
||||
|
||||
%ifarch aarch64
|
||||
%patch18 -p1
|
||||
%patch0001 -p1
|
||||
%endif
|
||||
%patch0002 -p1
|
||||
%patch0003 -p1
|
||||
%ifarch aarch64
|
||||
%patch0004 -p1
|
||||
%endif
|
||||
|
||||
%patch19 -p1
|
||||
%patch20 -p1
|
||||
%patch21 -p1
|
||||
|
||||
%ifarch aarch64
|
||||
%patch22 -p1
|
||||
%endif
|
||||
|
||||
%patch23 -p1
|
||||
%patch24 -p1
|
||||
%patch25 -p1
|
||||
%patch26 -p1
|
||||
%patch27 -p1
|
||||
%patch28 -p1
|
||||
%patch29 -p1
|
||||
|
||||
%build
|
||||
autoreconf
|
||||
@ -353,6 +289,9 @@ done
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Sat Dec 25 2021 zhouwenpei <zhouwenpei1@huawei.com> - 2.0.23-1
|
||||
- update to 2.0.23
|
||||
|
||||
* Tue Jul 27 2021 zhouwenpei <zhouwenpei1@huawei.com> - 2.0.20-7
|
||||
- fix build fail caused by file format not recognized
|
||||
|
||||
|
||||
Binary file not shown.
BIN
makedumpfile-1.7.0.tar.gz
Normal file
BIN
makedumpfile-1.7.0.tar.gz
Normal file
Binary file not shown.
@ -1,35 +0,0 @@
|
||||
From a46c686f615a86933134c0924c3391ba598a02b8 Mon Sep 17 00:00:00 2001
|
||||
From: Bhupesh Sharma <bhsharma@redhat.com>
|
||||
Date: Tue, 10 Sep 2019 15:51:49 +0530
|
||||
Subject: [PATCH] vmcore-dmesg/vmcore-dmesg.c: Fix shifting error reported by
|
||||
cppcheck
|
||||
|
||||
Running 'cppcheck' static code analyzer (see cppcheck(1))
|
||||
on 'vmcore-dmesg/vmcore-dmesg.c' shows the following
|
||||
shifting error:
|
||||
|
||||
$ cppcheck --enable=all vmcore-dmesg/vmcore-dmesg.c
|
||||
Checking vmcore-dmesg/vmcore-dmesg.c ...
|
||||
[vmcore-dmesg/vmcore-dmesg.c:17]: (error) Shifting signed 32-bit value by 31 bits is undefined behaviour
|
||||
|
||||
Fix the same via this patch.
|
||||
|
||||
Signed-off-by: Bhupesh Sharma <bhsharma@redhat.com>
|
||||
Signed-off-by: Simon Horman <horms@verge.net.au>
|
||||
|
||||
diff --git a/vmcore-dmesg/vmcore-dmesg.c b/vmcore-dmesg/vmcore-dmesg.c
|
||||
index 81c2a58..122e536 100644
|
||||
--- a/vmcore-dmesg/vmcore-dmesg.c
|
||||
+++ b/vmcore-dmesg/vmcore-dmesg.c
|
||||
@@ -6,7 +6,7 @@ typedef Elf32_Nhdr Elf_Nhdr;
|
||||
extern const char *fname;
|
||||
|
||||
/* stole this macro from kernel printk.c */
|
||||
-#define LOG_BUF_LEN_MAX (uint32_t)(1 << 31)
|
||||
+#define LOG_BUF_LEN_MAX (uint32_t)(1U << 31)
|
||||
|
||||
static void write_to_stdout(char *buf, unsigned int nr)
|
||||
{
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,44 +0,0 @@
|
||||
From 23b67f048ddef88e59ffe40f6392aeef92af9066 Mon Sep 17 00:00:00 2001
|
||||
From: Donald Buczek <buczek@molgen.mpg.de>
|
||||
Date: Fri, 30 Aug 2019 11:12:58 +0200
|
||||
Subject: [PATCH] x86: Fix PAGE_OFFSET for kernels since 4.20
|
||||
|
||||
Linux kernel commit d52888aa2753 ("x86/mm: Move LDT remap out of KASLR
|
||||
region on 5-level paging") changed the base of the direct mapping
|
||||
from 0xffff880000000000 to 0xffff888000000000. This was merged
|
||||
into v4.20-rc2.
|
||||
|
||||
Update to new address accordingly.
|
||||
|
||||
Signed-off-by: Simon Horman <horms@verge.net.au>
|
||||
|
||||
diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c
|
||||
index a2aea31..c79791f 100644
|
||||
--- a/kexec/arch/i386/crashdump-x86.c
|
||||
+++ b/kexec/arch/i386/crashdump-x86.c
|
||||
@@ -61,6 +61,8 @@ static int get_kernel_page_offset(struct kexec_info *UNUSED(info),
|
||||
|
||||
if (kv < KERNEL_VERSION(2, 6, 27))
|
||||
elf_info->page_offset = X86_64_PAGE_OFFSET_PRE_2_6_27;
|
||||
+ else if (kv < KERNEL_VERSION(4, 20, 0))
|
||||
+ elf_info->page_offset = X86_64_PAGE_OFFSET_PRE_4_20_0;
|
||||
else
|
||||
elf_info->page_offset = X86_64_PAGE_OFFSET;
|
||||
}
|
||||
diff --git a/kexec/arch/i386/crashdump-x86.h b/kexec/arch/i386/crashdump-x86.h
|
||||
index ddee19f..e4fdc82 100644
|
||||
--- a/kexec/arch/i386/crashdump-x86.h
|
||||
+++ b/kexec/arch/i386/crashdump-x86.h
|
||||
@@ -13,7 +13,8 @@ int load_crashdump_segments(struct kexec_info *info, char *mod_cmdline,
|
||||
|
||||
#define X86_64__START_KERNEL_map 0xffffffff80000000ULL
|
||||
#define X86_64_PAGE_OFFSET_PRE_2_6_27 0xffff810000000000ULL
|
||||
-#define X86_64_PAGE_OFFSET 0xffff880000000000ULL
|
||||
+#define X86_64_PAGE_OFFSET_PRE_4_20_0 0xffff880000000000ULL
|
||||
+#define X86_64_PAGE_OFFSET 0xffff888000000000ULL
|
||||
|
||||
#define X86_64_MAXMEM 0x3fffffffffffUL
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user