Accepting request 27300 from home:bwalle:branches:openSUSE:Factory
Copy from home:bwalle:branches:openSUSE:Factory/kexec-tools based on submit request 27300 from user bwalle OBS-URL: https://build.opensuse.org/request/show/27300 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/kexec-tools?expand=0&rev=73
This commit is contained in:
parent
a5d626ae36
commit
0b982ca6ed
@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:41439d49957d0400c7bd9e26b7573049025133cb5edac18c1eb08993953e2044
|
||||
size 262331
|
3
kexec-tools-2.0.1.tar.bz2
Normal file
3
kexec-tools-2.0.1.tar.bz2
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:f61f7be8896d4e3ee788712c564296bcb431e2e0b0564cc14b40a81b6df8d311
|
||||
size 269432
|
@ -1,106 +0,0 @@
|
||||
From cd8497a9a9e487684679b6747f7ba3f0a557328b Mon Sep 17 00:00:00 2001
|
||||
From: Chandru <chandru@in.ibm.com>
|
||||
Date: Wed, 24 Sep 2008 17:19:18 +0530
|
||||
Subject: [PATCH] kexec/kdump : add a new linux, usable-drconf-memory node to the device tree
|
||||
|
||||
Add a new linux,usable-drconf-memory property to the device tree passed to the
|
||||
2nd kernel. Each entry in the property is of the form: a count followed by so
|
||||
many (base, size) pairs of usable memory regions. The total number of such
|
||||
entries is equal to number of lmb's in ibm,dynamic-memory property.
|
||||
|
||||
Signed-off-by: Chandru Siddalingappa <chandru@in.ibm.com>
|
||||
Signed-off-by: Simon Horman <horms@verge.net.au>
|
||||
Acked-by: Bernhard Walle <bwalle@suse.de>
|
||||
|
||||
---
|
||||
kexec/arch/ppc64/fs2dt.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 72 insertions(+)
|
||||
|
||||
--- a/kexec/arch/ppc64/fs2dt.c
|
||||
+++ b/kexec/arch/ppc64/fs2dt.c
|
||||
@@ -122,6 +122,74 @@ static unsigned propnum(const char *name
|
||||
return offset;
|
||||
}
|
||||
|
||||
+static void add_dyn_reconf_usable_mem_property(int fd)
|
||||
+{
|
||||
+ char fname[MAXPATH], *bname;
|
||||
+ uint64_t buf[32];
|
||||
+ uint64_t ranges[2*MAX_MEMORY_RANGES];
|
||||
+ uint64_t base, end, loc_base, loc_end;
|
||||
+ int range, rlen = 0, i;
|
||||
+ int rngs_cnt, tmp_indx;
|
||||
+
|
||||
+ strcpy(fname, pathname);
|
||||
+ bname = strrchr(fname, '/');
|
||||
+ bname[0] = '\0';
|
||||
+ bname = strrchr(fname, '/');
|
||||
+ if (strncmp(bname, "/ibm,dynamic-reconfiguration-memory", 36))
|
||||
+ return;
|
||||
+
|
||||
+ if (lseek(fd, 4, SEEK_SET) < 0)
|
||||
+ die("unrecoverable error: error seeking in \"%s\": %s\n",
|
||||
+ pathname, strerror(errno));
|
||||
+
|
||||
+ rlen = 0;
|
||||
+ for (i = 0; i < num_of_lmbs; i++) {
|
||||
+ if (read(fd, buf, 24) < 0)
|
||||
+ die("unrecoverable error: error reading \"%s\": %s\n",
|
||||
+ pathname, strerror(errno));
|
||||
+
|
||||
+ base = (uint64_t) buf[0];
|
||||
+ end = base + lmb_size;
|
||||
+ if (~0ULL - base < end)
|
||||
+ die("unrecoverable error: mem property overflow\n");
|
||||
+
|
||||
+ tmp_indx = rlen++;
|
||||
+
|
||||
+ rngs_cnt = 0;
|
||||
+ for (range = 0; range < usablemem_rgns.size; range++) {
|
||||
+ loc_base = usablemem_rgns.ranges[range].start;
|
||||
+ loc_end = usablemem_rgns.ranges[range].end;
|
||||
+ if (loc_base >= base && loc_end <= end) {
|
||||
+ ranges[rlen++] = loc_base;
|
||||
+ ranges[rlen++] = loc_end - loc_base;
|
||||
+ rngs_cnt++;
|
||||
+ } else if (base < loc_end && end > loc_base) {
|
||||
+ if (loc_base < base)
|
||||
+ loc_base = base;
|
||||
+ if (loc_end > end)
|
||||
+ loc_end = end;
|
||||
+ ranges[rlen++] = loc_base;
|
||||
+ ranges[rlen++] = loc_end - loc_base;
|
||||
+ rngs_cnt++;
|
||||
+ }
|
||||
+ }
|
||||
+ /* Store the count of (base, size) duple */
|
||||
+ ranges[tmp_indx] = rngs_cnt;
|
||||
+ }
|
||||
+
|
||||
+ rlen = rlen * sizeof(uint64_t);
|
||||
+ /*
|
||||
+ * Add linux,drconf-usable-memory property.
|
||||
+ */
|
||||
+ *dt++ = 3;
|
||||
+ *dt++ = rlen;
|
||||
+ *dt++ = propnum("linux,drconf-usable-memory");
|
||||
+ if ((rlen >= 8) && ((unsigned long)dt & 0x4))
|
||||
+ dt++;
|
||||
+ memcpy(dt, &ranges, rlen);
|
||||
+ dt += (rlen + 3)/4;
|
||||
+}
|
||||
+
|
||||
static void add_usable_mem_property(int fd, int len)
|
||||
{
|
||||
char fname[MAXPATH], *bname;
|
||||
@@ -267,6 +335,10 @@ static void putprops(char *fn, struct di
|
||||
dt += (len + 3)/4;
|
||||
if (!strcmp(dp->d_name, "reg") && usablemem_rgns.size)
|
||||
add_usable_mem_property(fd, len);
|
||||
+ if (!strcmp(dp->d_name, "ibm,dynamic-memory") &&
|
||||
+ usablemem_rgns.size)
|
||||
+ add_dyn_reconf_usable_mem_property(fd);
|
||||
+
|
||||
close(fd);
|
||||
}
|
||||
|
@ -1,53 +0,0 @@
|
||||
From c1d13f4bd287f48c5fce02c3916b132f618c40fb Mon Sep 17 00:00:00 2001
|
||||
From: Geoff Levand <geoffrey.levand@am.sony.com>
|
||||
Date: Wed, 10 Sep 2008 18:40:42 -0700
|
||||
Subject: [PATCH] Fix build warnings
|
||||
|
||||
Fix these 64 bit build warnings:
|
||||
|
||||
kexec/firmware_memmap.c:241: warning: format '%d' expects type 'int', but argument 3 has type 'size_t'
|
||||
kexec/crashdump-elf.c:160: warning: format '%llx' expects type 'long long unsigned int', but argument 4 has type 'Elf64_Off'
|
||||
kexec/crashdump-elf.c:160: warning: format '%llx' expects type 'long long unsigned int', but argument 5 has type 'Elf64_Addr'
|
||||
kexec/crashdump-elf.c:160: warning: format '%llx' expects type 'long long unsigned int', but argument 6 has type 'Elf64_Addr'
|
||||
kexec/crashdump-elf.c:160: warning: format '%llx' expects type 'long long unsigned int', but argument 7 has type 'Elf64_Xword'
|
||||
kexec/crashdump-elf.c:160: warning: format '%llx' expects type 'long long unsigned int', but argument 8 has type 'Elf64_Xword'
|
||||
|
||||
Tested on PS3 (ppc64) with 32 and 64 bit builds.
|
||||
|
||||
Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
|
||||
Signed-off-by: Simon Horman <horms@verge.net.au>
|
||||
Acked-by: Bernhard Walle <bwalle@suse.de>
|
||||
|
||||
---
|
||||
kexec/crashdump-elf.c | 8 ++++++--
|
||||
kexec/firmware_memmap.c | 2 +-
|
||||
2 files changed, 7 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/kexec/crashdump-elf.c
|
||||
+++ b/kexec/crashdump-elf.c
|
||||
@@ -8,8 +8,12 @@
|
||||
do { \
|
||||
dbgprintf("%s: p_type = %u, p_offset = 0x%llx p_paddr = 0x%llx " \
|
||||
"p_vaddr = 0x%llx p_filesz = 0x%llx p_memsz = 0x%llx\n", \
|
||||
- (prefix), (phdr)->p_type, (phdr)->p_offset, (phdr)->p_paddr, \
|
||||
- (phdr)->p_vaddr, (phdr)->p_filesz, (phdr)->p_memsz); \
|
||||
+ (prefix), (phdr)->p_type, \
|
||||
+ (unsigned long long)((phdr)->p_offset), \
|
||||
+ (unsigned long long)((phdr)->p_paddr), \
|
||||
+ (unsigned long long)((phdr)->p_vaddr), \
|
||||
+ (unsigned long long)((phdr)->p_filesz), \
|
||||
+ (unsigned long long)((phdr)->p_memsz)); \
|
||||
} while(0)
|
||||
#else
|
||||
#define dbgprintf_phdr(prefix, phdr) \
|
||||
--- a/kexec/firmware_memmap.c
|
||||
+++ b/kexec/firmware_memmap.c
|
||||
@@ -239,7 +239,7 @@ int get_firmware_memmap_ranges(struct me
|
||||
/* array overflow check */
|
||||
if ((size_t)i >= *ranges) {
|
||||
fprintf(stderr, "The firmware provides more entries "
|
||||
- "allowed (%d). Please report that as bug.\n",
|
||||
+ "allowed (%zd). Please report that as bug.\n",
|
||||
*ranges);
|
||||
goto error;
|
||||
}
|
@ -1,187 +0,0 @@
|
||||
From 726c130af8b1371aa32dc14f108a3fb1695860bb Mon Sep 17 00:00:00 2001
|
||||
From: Chandru <chandru@in.ibm.com>
|
||||
Date: Wed, 24 Sep 2008 17:19:07 +0530
|
||||
Subject: [PATCH] kexec/kdump: read crash memory ranges from drconf memory
|
||||
|
||||
Get the memory ranges of the 1st kernel excluding the memory reserved for
|
||||
kexec/kdump kernel in case of ibm,dynamic-reconfiguration-memory node of
|
||||
device tree
|
||||
|
||||
Signed-off-by: Chandru Siddalingappa <chandru@in.ibm.com>
|
||||
Signed-off-by: Simon Horman <horms@verge.net.au>
|
||||
Acked-by: Bernhard Walle <bwalle@suse.de>
|
||||
|
||||
---
|
||||
kexec/arch/ppc64/crashdump-ppc64.c | 121 ++++++++++++++++++++++++++-----------
|
||||
kexec/arch/ppc64/crashdump-ppc64.h | 3
|
||||
2 files changed, 90 insertions(+), 34 deletions(-)
|
||||
|
||||
--- a/kexec/arch/ppc64/crashdump-ppc64.c
|
||||
+++ b/kexec/arch/ppc64/crashdump-ppc64.c
|
||||
@@ -84,6 +84,82 @@ mem_rgns_t usablemem_rgns = {0, NULL};
|
||||
*/
|
||||
uint64_t saved_max_mem = 0;
|
||||
|
||||
+static unsigned long long cstart, cend;
|
||||
+static int memory_ranges;
|
||||
+
|
||||
+/*
|
||||
+ * Exclude the region that lies within crashkernel
|
||||
+ */
|
||||
+static void exclude_crash_region(uint64_t start, uint64_t end)
|
||||
+{
|
||||
+ if (cstart < end && cend > start) {
|
||||
+ if (start < cstart && end > cend) {
|
||||
+ crash_memory_range[memory_ranges].start = start;
|
||||
+ crash_memory_range[memory_ranges].end = cstart;
|
||||
+ crash_memory_range[memory_ranges].type = RANGE_RAM;
|
||||
+ memory_ranges++;
|
||||
+ crash_memory_range[memory_ranges].start = cend;
|
||||
+ crash_memory_range[memory_ranges].end = end;
|
||||
+ crash_memory_range[memory_ranges].type = RANGE_RAM;
|
||||
+ memory_ranges++;
|
||||
+ } else if (start < cstart) {
|
||||
+ crash_memory_range[memory_ranges].start = start;
|
||||
+ crash_memory_range[memory_ranges].end = cstart;
|
||||
+ crash_memory_range[memory_ranges].type = RANGE_RAM;
|
||||
+ memory_ranges++;
|
||||
+ } else if (end > cend) {
|
||||
+ crash_memory_range[memory_ranges].start = cend;
|
||||
+ crash_memory_range[memory_ranges].end = end;
|
||||
+ crash_memory_range[memory_ranges].type = RANGE_RAM;
|
||||
+ memory_ranges++;
|
||||
+ }
|
||||
+ } else {
|
||||
+ crash_memory_range[memory_ranges].start = start;
|
||||
+ crash_memory_range[memory_ranges].end = end;
|
||||
+ crash_memory_range[memory_ranges].type = RANGE_RAM;
|
||||
+ memory_ranges++;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int get_dyn_reconf_crash_memory_ranges()
|
||||
+{
|
||||
+ uint64_t start, end;
|
||||
+ char fname[128], buf[32];
|
||||
+ FILE *file;
|
||||
+ int i, n;
|
||||
+
|
||||
+ strcpy(fname, "/proc/device-tree/");
|
||||
+ strcat(fname, "ibm,dynamic-reconfiguration-memory/ibm,dynamic-memory");
|
||||
+ if ((file = fopen(fname, "r")) == NULL) {
|
||||
+ perror(fname);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ fseek(file, 4, SEEK_SET);
|
||||
+ for (i = 0; i < num_of_lmbs; i++) {
|
||||
+ if ((n = fread(buf, 1, 24, file)) < 0) {
|
||||
+ perror(fname);
|
||||
+ fclose(file);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ if (memory_ranges >= (max_memory_ranges + 1)) {
|
||||
+ /* No space to insert another element. */
|
||||
+ fprintf(stderr,
|
||||
+ "Error: Number of crash memory ranges"
|
||||
+ " excedeed the max limit\n");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ start = ((uint64_t *)buf)[0];
|
||||
+ end = start + lmb_size;
|
||||
+ if (start == 0 && end >= (BACKUP_SRC_END + 1))
|
||||
+ start = BACKUP_SRC_END + 1;
|
||||
+ exclude_crash_region(start, end);
|
||||
+ }
|
||||
+ fclose(file);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/* Reads the appropriate file and retrieves the SYSTEM RAM regions for whom to
|
||||
* create Elf headers. Keeping it separate from get_memory_ranges() as
|
||||
* requirements are different in the case of normal kexec and crashdumps.
|
||||
@@ -98,7 +174,6 @@ uint64_t saved_max_mem = 0;
|
||||
static int get_crash_memory_ranges(struct memory_range **range, int *ranges)
|
||||
{
|
||||
|
||||
- int memory_ranges = 0;
|
||||
char device_tree[256] = "/proc/device-tree/";
|
||||
char fname[256];
|
||||
char buf[MAXBYTES];
|
||||
@@ -106,7 +181,7 @@ static int get_crash_memory_ranges(struc
|
||||
FILE *file;
|
||||
struct dirent *dentry, *mentry;
|
||||
int i, n, crash_rng_len = 0;
|
||||
- unsigned long long start, end, cstart, cend;
|
||||
+ unsigned long long start, end;
|
||||
int page_size;
|
||||
|
||||
crash_max_memory_ranges = max_memory_ranges + 6;
|
||||
@@ -129,7 +204,16 @@ static int get_crash_memory_ranges(struc
|
||||
perror(device_tree);
|
||||
goto err;
|
||||
}
|
||||
+
|
||||
+ cstart = crash_base;
|
||||
+ cend = crash_base + crash_size;
|
||||
+
|
||||
while ((dentry = readdir(dir)) != NULL) {
|
||||
+ if (!strncmp(dentry->d_name,
|
||||
+ "ibm,dynamic-reconfiguration-memory", 35)){
|
||||
+ get_dyn_reconf_crash_memory_ranges();
|
||||
+ continue;
|
||||
+ }
|
||||
if (strncmp(dentry->d_name, "memory@", 7) &&
|
||||
strcmp(dentry->d_name, "memory"))
|
||||
continue;
|
||||
@@ -170,38 +254,7 @@ static int get_crash_memory_ranges(struc
|
||||
if (start == 0 && end >= (BACKUP_SRC_END + 1))
|
||||
start = BACKUP_SRC_END + 1;
|
||||
|
||||
- cstart = crash_base;
|
||||
- cend = crash_base + crash_size;
|
||||
- /*
|
||||
- * Exclude the region that lies within crashkernel
|
||||
- */
|
||||
- if (cstart < end && cend > start) {
|
||||
- if (start < cstart && end > cend) {
|
||||
- crash_memory_range[memory_ranges].start = start;
|
||||
- crash_memory_range[memory_ranges].end = cstart;
|
||||
- crash_memory_range[memory_ranges].type = RANGE_RAM;
|
||||
- memory_ranges++;
|
||||
- crash_memory_range[memory_ranges].start = cend;
|
||||
- crash_memory_range[memory_ranges].end = end;
|
||||
- crash_memory_range[memory_ranges].type = RANGE_RAM;
|
||||
- memory_ranges++;
|
||||
- } else if (start < cstart) {
|
||||
- crash_memory_range[memory_ranges].start = start;
|
||||
- crash_memory_range[memory_ranges].end = cstart;
|
||||
- crash_memory_range[memory_ranges].type = RANGE_RAM;
|
||||
- memory_ranges++;
|
||||
- } else if (end > cend){
|
||||
- crash_memory_range[memory_ranges].start = cend;
|
||||
- crash_memory_range[memory_ranges].end = end;
|
||||
- crash_memory_range[memory_ranges].type = RANGE_RAM;
|
||||
- memory_ranges++;
|
||||
- }
|
||||
- } else {
|
||||
- crash_memory_range[memory_ranges].start = start;
|
||||
- crash_memory_range[memory_ranges].end = end;
|
||||
- crash_memory_range[memory_ranges].type = RANGE_RAM;
|
||||
- memory_ranges++;
|
||||
- }
|
||||
+ exclude_crash_region(start, end);
|
||||
fclose(file);
|
||||
}
|
||||
closedir(dmem);
|
||||
--- a/kexec/arch/ppc64/crashdump-ppc64.h
|
||||
+++ b/kexec/arch/ppc64/crashdump-ppc64.h
|
||||
@@ -28,4 +28,7 @@ extern uint64_t crash_size;
|
||||
extern unsigned int rtas_base;
|
||||
extern unsigned int rtas_size;
|
||||
|
||||
+uint64_t lmb_size;
|
||||
+unsigned int num_of_lmbs;
|
||||
+
|
||||
#endif /* CRASHDUMP_PPC64_H */
|
@ -1,41 +0,0 @@
|
||||
From 344883869c1e7e7dd873e920a709950ce0546140 Mon Sep 17 00:00:00 2001
|
||||
From: Bernhard Walle <bwalle@suse.de>
|
||||
Date: Thu, 9 Oct 2008 18:58:12 +0200
|
||||
Subject: [PATCH] Use return value of count_dyn_reconf_memory_ranges()
|
||||
|
||||
This patch fixes the build error
|
||||
|
||||
kexec/arch/ppc64/kexec-ppc64.c:140: \
|
||||
warning: control reaches end of non-void function
|
||||
|
||||
The patch returns 0 on success, and checks when the function is called
|
||||
for a non-zero value.
|
||||
|
||||
|
||||
Signed-off-by: Bernhard Walle <bwalle@suse.de>
|
||||
|
||||
---
|
||||
kexec/arch/ppc64/kexec-ppc64.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/kexec/arch/ppc64/kexec-ppc64.c
|
||||
+++ b/kexec/arch/ppc64/kexec-ppc64.c
|
||||
@@ -137,6 +137,8 @@ static int count_dyn_reconf_memory_range
|
||||
num_of_lmbs = ((unsigned int *)buf)[0];
|
||||
max_memory_ranges += num_of_lmbs;
|
||||
fclose(file);
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -158,7 +160,8 @@ static int count_memory_ranges(void)
|
||||
while ((dentry = readdir(dir)) != NULL) {
|
||||
if (!strncmp(dentry->d_name,
|
||||
"ibm,dynamic-reconfiguration-memory", 35)){
|
||||
- count_dyn_reconf_memory_ranges();
|
||||
+ if (count_dyn_reconf_memory_ranges() != 0)
|
||||
+ return -1;
|
||||
continue;
|
||||
}
|
||||
|
@ -1,100 +0,0 @@
|
||||
Signed-off-by: Chandru S <chandru@in.ibm.com>
|
||||
---
|
||||
|
||||
---
|
||||
kexec/arch/x86_64/crashdump-x86_64.c | 39 ++++++++++++++++++++---------------
|
||||
1 file changed, 23 insertions(+), 16 deletions(-)
|
||||
|
||||
--- a/kexec/arch/x86_64/crashdump-x86_64.c
|
||||
+++ b/kexec/arch/x86_64/crashdump-x86_64.c
|
||||
@@ -47,7 +47,7 @@ static struct crash_elf_info elf_info =
|
||||
};
|
||||
|
||||
/* Forward Declaration. */
|
||||
-static int exclude_crash_reserve_region(int *nr_ranges);
|
||||
+static int exclude_region(int *nr_ranges, uint64_t start, uint64_t end);
|
||||
|
||||
#define KERN_VADDR_ALIGN 0x100000 /* 1MB */
|
||||
|
||||
@@ -164,10 +164,11 @@ static struct memory_range crash_reserve
|
||||
static int get_crash_memory_ranges(struct memory_range **range, int *ranges)
|
||||
{
|
||||
const char *iomem= proc_iomem();
|
||||
- int memory_ranges = 0;
|
||||
+ int memory_ranges = 0, gart = 0;
|
||||
char line[MAX_LINE];
|
||||
FILE *fp;
|
||||
unsigned long long start, end;
|
||||
+ uint64_t gart_start = 0, gart_end = 0;
|
||||
|
||||
fp = fopen(iomem, "r");
|
||||
if (!fp) {
|
||||
@@ -219,6 +220,11 @@ static int get_crash_memory_ranges(struc
|
||||
type = RANGE_ACPI;
|
||||
} else if(memcmp(str,"ACPI Non-volatile Storage\n",26) == 0 ) {
|
||||
type = RANGE_ACPI_NVS;
|
||||
+ } else if (memcmp(str, "GART\n", 5) == 0) {
|
||||
+ gart_start = start;
|
||||
+ gart_end = end;
|
||||
+ gart = 1;
|
||||
+ continue;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
@@ -233,8 +239,14 @@ static int get_crash_memory_ranges(struc
|
||||
memory_ranges++;
|
||||
}
|
||||
fclose(fp);
|
||||
- if (exclude_crash_reserve_region(&memory_ranges) < 0)
|
||||
+ if (exclude_region(&memory_ranges, crash_reserved_mem.start,
|
||||
+ crash_reserved_mem.end) < 0)
|
||||
return -1;
|
||||
+ if (gart) {
|
||||
+ /* exclude GART region if the system has one */
|
||||
+ if (exclude_region(&memory_ranges, gart_start, gart_end) < 0)
|
||||
+ return -1;
|
||||
+ }
|
||||
*range = crash_memory_range;
|
||||
*ranges = memory_ranges;
|
||||
#ifdef DEBUG
|
||||
@@ -252,32 +264,27 @@ static int get_crash_memory_ranges(struc
|
||||
/* Removes crash reserve region from list of memory chunks for whom elf program
|
||||
* headers have to be created. Assuming crash reserve region to be a single
|
||||
* continuous area fully contained inside one of the memory chunks */
|
||||
-static int exclude_crash_reserve_region(int *nr_ranges)
|
||||
+static int exclude_region(int *nr_ranges, uint64_t start, uint64_t end)
|
||||
{
|
||||
int i, j, tidx = -1;
|
||||
- unsigned long long cstart, cend;
|
||||
struct memory_range temp_region;
|
||||
|
||||
- /* Crash reserved region. */
|
||||
- cstart = crash_reserved_mem.start;
|
||||
- cend = crash_reserved_mem.end;
|
||||
-
|
||||
for (i = 0; i < (*nr_ranges); i++) {
|
||||
unsigned long long mstart, mend;
|
||||
mstart = crash_memory_range[i].start;
|
||||
mend = crash_memory_range[i].end;
|
||||
- if (cstart < mend && cend > mstart) {
|
||||
- if (cstart != mstart && cend != mend) {
|
||||
+ if (start < mend && end > mstart) {
|
||||
+ if (start != mstart && end != mend) {
|
||||
/* Split memory region */
|
||||
- crash_memory_range[i].end = cstart - 1;
|
||||
- temp_region.start = cend + 1;
|
||||
+ crash_memory_range[i].end = start - 1;
|
||||
+ temp_region.start = end + 1;
|
||||
temp_region.end = mend;
|
||||
temp_region.type = RANGE_RAM;
|
||||
tidx = i+1;
|
||||
- } else if (cstart != mstart)
|
||||
- crash_memory_range[i].end = cstart - 1;
|
||||
+ } else if (start != mstart)
|
||||
+ crash_memory_range[i].end = start - 1;
|
||||
else
|
||||
- crash_memory_range[i].start = cend + 1;
|
||||
+ crash_memory_range[i].start = end + 1;
|
||||
}
|
||||
}
|
||||
/* Insert split memory region, if any. */
|
@ -1,229 +0,0 @@
|
||||
From 1d19ca0c4306c3c684cf4d277781975e4ad1c193 Mon Sep 17 00:00:00 2001
|
||||
From: Chandru <chandru@in.ibm.com>
|
||||
Date: Wed, 24 Sep 2008 17:19:29 +0530
|
||||
Subject: [PATCH] kexec/kdump : get details of ibm, dynamic-reconfiguration-memory node of device tree
|
||||
|
||||
Get number of lmb's (logical memory blocks) , size of each lmb from
|
||||
ibm,dynamic-memory property , get base memory ranges from
|
||||
ibm,dynamic-reconfiguration-memory node.
|
||||
|
||||
Signed-off-by: Chandru Siddalingappa <chandru@in.ibm.com>
|
||||
Signed-off-by: Simon Horman <horms@verge.net.au>
|
||||
Acked-by: Bernhard Walle <bwalle@suse.de>
|
||||
|
||||
---
|
||||
kexec/arch/ppc64/kexec-ppc64.c | 145 ++++++++++++++++++++++++++++++++++++-----
|
||||
1 file changed, 130 insertions(+), 15 deletions(-)
|
||||
|
||||
--- a/kexec/arch/ppc64/kexec-ppc64.c
|
||||
+++ b/kexec/arch/ppc64/kexec-ppc64.c
|
||||
@@ -96,6 +96,49 @@ err1:
|
||||
|
||||
}
|
||||
|
||||
+static int count_dyn_reconf_memory_ranges(void)
|
||||
+{
|
||||
+ char device_tree[] = "/proc/device-tree/";
|
||||
+ char fname[128];
|
||||
+ char buf[32];
|
||||
+ FILE *file;
|
||||
+
|
||||
+ strcpy(fname, device_tree);
|
||||
+ strcat(fname, "ibm,dynamic-reconfiguration-memory/ibm,lmb-size");
|
||||
+ if ((file = fopen(fname, "r")) == NULL) {
|
||||
+ perror(fname);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (fread(buf, 1, 8, file) < 0) {
|
||||
+ perror(fname);
|
||||
+ fclose(file);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ lmb_size = ((uint64_t *)buf)[0];
|
||||
+ fclose(file);
|
||||
+
|
||||
+ /* Get number of lmbs from ibm,dynamic-memory */
|
||||
+ strcpy(fname, device_tree);
|
||||
+ strcat(fname, "ibm,dynamic-reconfiguration-memory/ibm,dynamic-memory");
|
||||
+ if ((file = fopen(fname, "r")) == NULL) {
|
||||
+ perror(fname);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ /*
|
||||
+ * first 4 bytes provide number of entries(lmbs)
|
||||
+ */
|
||||
+ if (fread(buf, 1, 4, file) < 0) {
|
||||
+ perror(fname);
|
||||
+ fclose(file);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ num_of_lmbs = ((unsigned int *)buf)[0];
|
||||
+ max_memory_ranges += num_of_lmbs;
|
||||
+ fclose(file);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Count the memory nodes under /proc/device-tree and populate the
|
||||
* max_memory_ranges variable. This variable replaces MAX_MEMORY_RANGES
|
||||
@@ -113,6 +156,12 @@ static int count_memory_ranges(void)
|
||||
}
|
||||
|
||||
while ((dentry = readdir(dir)) != NULL) {
|
||||
+ if (!strncmp(dentry->d_name,
|
||||
+ "ibm,dynamic-reconfiguration-memory", 35)){
|
||||
+ count_dyn_reconf_memory_ranges();
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
if (strncmp(dentry->d_name, "memory@", 7) &&
|
||||
strcmp(dentry->d_name, "memory") &&
|
||||
strncmp(dentry->d_name, "pci@", 4))
|
||||
@@ -128,7 +177,52 @@ static int count_memory_ranges(void)
|
||||
|
||||
return 0;
|
||||
}
|
||||
+static void add_base_memory_range(uint64_t start, uint64_t end)
|
||||
+{
|
||||
+ base_memory_range[nr_memory_ranges].start = start;
|
||||
+ base_memory_range[nr_memory_ranges].end = end;
|
||||
+ base_memory_range[nr_memory_ranges].type = RANGE_RAM;
|
||||
+ nr_memory_ranges++;
|
||||
+
|
||||
+ dbgprintf("%016llx-%016llx : %x\n",
|
||||
+ base_memory_range[nr_memory_ranges-1].start,
|
||||
+ base_memory_range[nr_memory_ranges-1].end,
|
||||
+ base_memory_range[nr_memory_ranges-1].type);
|
||||
+}
|
||||
+
|
||||
+static int get_dyn_reconf_base_ranges(void)
|
||||
+{
|
||||
+ uint64_t start, end;
|
||||
+ char fname[128], buf[32];
|
||||
+ FILE *file;
|
||||
+ int i, n;
|
||||
+
|
||||
|
||||
+ strcpy(fname, "/proc/device-tree/");
|
||||
+ strcat(fname,
|
||||
+ "ibm,dynamic-reconfiguration-memory/ibm,dynamic-memory");
|
||||
+ if ((file = fopen(fname, "r")) == NULL) {
|
||||
+ perror(fname);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ fseek(file, 4, SEEK_SET);
|
||||
+ for (i = 0; i < num_of_lmbs; i++) {
|
||||
+ if ((n = fread(buf, 1, 24, file)) < 0) {
|
||||
+ perror(fname);
|
||||
+ fclose(file);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ if (nr_memory_ranges >= max_memory_ranges)
|
||||
+ return -1;
|
||||
+
|
||||
+ start = ((uint64_t *)buf)[0];
|
||||
+ end = start + lmb_size;
|
||||
+ add_base_memory_range(start, end);
|
||||
+ }
|
||||
+ fclose(file);
|
||||
+ return 0;
|
||||
+}
|
||||
/* Sort the base ranges in memory - this is useful for ensuring that our
|
||||
* ranges are in ascending order, even if device-tree read of memory nodes
|
||||
* is done differently. Also, could be used for other range coalescing later
|
||||
@@ -156,7 +250,7 @@ static int sort_base_ranges(void)
|
||||
/* Get base memory ranges */
|
||||
static int get_base_ranges(void)
|
||||
{
|
||||
- int local_memory_ranges = 0;
|
||||
+ uint64_t start, end;
|
||||
char device_tree[256] = "/proc/device-tree/";
|
||||
char fname[256];
|
||||
char buf[MAXBYTES];
|
||||
@@ -170,6 +264,11 @@ static int get_base_ranges(void)
|
||||
return -1;
|
||||
}
|
||||
while ((dentry = readdir(dir)) != NULL) {
|
||||
+ if (!strncmp(dentry->d_name,
|
||||
+ "ibm,dynamic-reconfiguration-memory", 35)) {
|
||||
+ get_dyn_reconf_base_ranges();
|
||||
+ continue;
|
||||
+ }
|
||||
if (strncmp(dentry->d_name, "memory@", 7) &&
|
||||
strcmp(dentry->d_name, "memory"))
|
||||
continue;
|
||||
@@ -197,27 +296,18 @@ static int get_base_ranges(void)
|
||||
closedir(dir);
|
||||
return -1;
|
||||
}
|
||||
- if (local_memory_ranges >= max_memory_ranges) {
|
||||
+ if (nr_memory_ranges >= max_memory_ranges) {
|
||||
fclose(file);
|
||||
break;
|
||||
}
|
||||
- base_memory_range[local_memory_ranges].start =
|
||||
- ((uint64_t *)buf)[0];
|
||||
- base_memory_range[local_memory_ranges].end =
|
||||
- base_memory_range[local_memory_ranges].start +
|
||||
- ((uint64_t *)buf)[1];
|
||||
- base_memory_range[local_memory_ranges].type = RANGE_RAM;
|
||||
- local_memory_ranges++;
|
||||
- dbgprintf("%016llx-%016llx : %x\n",
|
||||
- base_memory_range[local_memory_ranges-1].start,
|
||||
- base_memory_range[local_memory_ranges-1].end,
|
||||
- base_memory_range[local_memory_ranges-1].type);
|
||||
+ start = ((uint64_t *)buf)[0];
|
||||
+ end = start + ((uint64_t *)buf)[1];
|
||||
+ add_base_memory_range(start, end);
|
||||
fclose(file);
|
||||
}
|
||||
closedir(dmem);
|
||||
}
|
||||
closedir(dir);
|
||||
- nr_memory_ranges = local_memory_ranges;
|
||||
sort_base_ranges();
|
||||
memory_max = base_memory_range[nr_memory_ranges - 1].end;
|
||||
#ifdef DEBUG
|
||||
@@ -276,7 +366,9 @@ static int get_devtree_details(unsigned
|
||||
strncmp(dentry->d_name, "memory@", 7) &&
|
||||
strcmp(dentry->d_name, "memory") &&
|
||||
strncmp(dentry->d_name, "pci@", 4) &&
|
||||
- strncmp(dentry->d_name, "rtas", 4))
|
||||
+ strncmp(dentry->d_name, "rtas", 4) &&
|
||||
+ strncmp(dentry->d_name,
|
||||
+ "ibm,dynamic-reconfiguration-memory", 35))
|
||||
continue;
|
||||
strcpy(fname, device_tree);
|
||||
strcat(fname, dentry->d_name);
|
||||
@@ -474,6 +566,29 @@ static int get_devtree_details(unsigned
|
||||
closedir(cdir);
|
||||
} /* memory */
|
||||
|
||||
+ if (!strncmp(dentry->d_name,
|
||||
+ "ibm,dynamic-reconfiguration-memory", 35)) {
|
||||
+ unsigned int k;
|
||||
+ strcat(fname, "/ibm,dynamic-memory");
|
||||
+ if ((file = fopen(fname, "r")) == NULL) {
|
||||
+ perror(fname);
|
||||
+ goto error_opencdir;
|
||||
+ }
|
||||
+ fseek(file, 4, SEEK_SET);
|
||||
+ for (k = 0; k < num_of_lmbs; k++) {
|
||||
+ if ((n = fread(buf, 1, 24, file)) < 0) {
|
||||
+ perror(fname);
|
||||
+ goto error_openfile;
|
||||
+ }
|
||||
+ rmo_base = ((uint64_t *)buf)[0];
|
||||
+ rmo_top = rmo_base + lmb_size;
|
||||
+ if (rmo_top > 0x30000000UL)
|
||||
+ rmo_top = 0x30000000UL;
|
||||
+ }
|
||||
+ fclose(file);
|
||||
+ closedir(cdir);
|
||||
+ } /* ibm,dynamic-reconfiguration-memory */
|
||||
+
|
||||
if (strncmp(dentry->d_name, "pci@", 4) == 0) {
|
||||
strcat(fname, "/linux,tce-base");
|
||||
if ((file = fopen(fname, "r")) == NULL) {
|
@ -1,46 +0,0 @@
|
||||
From 4bd67d530f92313fd66bb462d96e3995b8e08af3 Mon Sep 17 00:00:00 2001
|
||||
From: Bjorn Helgaas <bjorn.helgaas@hp.com>
|
||||
Date: Mon, 6 Oct 2008 09:24:03 -0600
|
||||
Subject: [PATCH] ia64: make PA() work for both physical identity-mapped virtual addresses
|
||||
|
||||
The EFI Runtime Services Table contains pointers to ia64 function
|
||||
descriptors. On existing, pre-Tiano, firmware, SetVirtualAddressMap()
|
||||
converts *all* these pointers from physical to virtual. On Tiano-based
|
||||
firmware, the pointer to the SetVirtualAddressMap() function descriptor
|
||||
is not converted, so it remains a physical pointer.
|
||||
|
||||
The ia64 kexec purgatory patches the SetVirtualAddressMap() function
|
||||
descriptor so that when the new kernel calls SetVirtualAddressMap(), it
|
||||
never reaches firmware. Instead, it calls a dummy function that just
|
||||
returns success.
|
||||
|
||||
Purgatory runs in physical mode, so it must convert the pointer from the
|
||||
RuntimeServicesTable to a physical address. This patch makes that
|
||||
conversion work both for old firmware (where the pointer is an identity-
|
||||
mapped virtual address) and new Tiano firmware (where the pointer is a
|
||||
physical address).
|
||||
|
||||
Without this patch, kexec on Tiano firmware causes an MCA because
|
||||
ia64_env_setup() subtracts PAGE_OFFSET from a physical address and ends
|
||||
up with an invalid physical address. Referencing that address causes
|
||||
the MCA.
|
||||
|
||||
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
|
||||
Signed-off-by: Simon Horman <horms@verge.net.au>
|
||||
Acked-by: Bernhard Walle <bwalle@suse.de>
|
||||
|
||||
---
|
||||
purgatory/arch/ia64/purgatory-ia64.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/purgatory/arch/ia64/purgatory-ia64.c
|
||||
+++ b/purgatory/arch/ia64/purgatory-ia64.c
|
||||
@@ -147,7 +147,7 @@ setup_arch(void)
|
||||
|
||||
inline unsigned long PA(unsigned long addr)
|
||||
{
|
||||
- return addr - PAGE_OFFSET;
|
||||
+ return addr & 0x0fffffffffffffffLL;
|
||||
}
|
||||
|
||||
void
|
@ -1,51 +0,0 @@
|
||||
Date: Wed, 8 Oct 2008 17:49:41 +1100
|
||||
From: Simon Horman <horms@verge.net.au>
|
||||
To: linux-ia64@vger.kernel.org, kexec@lists.infradead.org
|
||||
Cc: Jay Lan <jlan@sgi.com>, "Luck, Tony" <tony.luck@intel.com>,
|
||||
Bernhard Walle <bwalle@suse.de>
|
||||
Subject: [patch] ia64: Order of operations bug in PT_LOAD segment reader
|
||||
|
||||
This bug was discovered by Jay Lan and he also proposed this fix, however
|
||||
thee is some discussion about what if any related changes should be made at
|
||||
the same time.
|
||||
|
||||
The bug comes about because the break statment was never executed because
|
||||
the if clause would bever be true because the if clause will never be true
|
||||
because & has higher precedence than !=.
|
||||
|
||||
My position on this is that with the if logic fixed, as per this patch, the
|
||||
break statment and the rest of the while() loop makes sense and should work
|
||||
as intended.
|
||||
|
||||
As I understand it, Jay's position is that the code should be simplified,
|
||||
after all it never worked as intended.
|
||||
|
||||
There is a related kernel bug that lead Jay to discover this problem.
|
||||
The kernel bug has been resolved by Tony Luck and was
|
||||
included in Linus's tree between 2.6.27-rc8 and 2.6.27-rc9 as
|
||||
"[IA64] Put the space for cpu0 per-cpu area into .data section".
|
||||
|
||||
Now that the kernel bug is out of the way, I am providing this patch to
|
||||
continue discussion on what to do on the kexec-tools side of things. I do
|
||||
not intend to apply this patch until there is some conclusion in the
|
||||
discussion between Jay and myself.
|
||||
|
||||
Cc: Jay Lan <jlan@sgi.com>
|
||||
Signed-off-by: Simon Horman <horms@verge.net.au>
|
||||
Acked-by: Bernhard Walle <bwalle@suse.de>
|
||||
|
||||
---
|
||||
kexec/arch/ia64/crashdump-ia64.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/kexec/arch/ia64/crashdump-ia64.c
|
||||
+++ b/kexec/arch/ia64/crashdump-ia64.c
|
||||
@@ -91,7 +91,7 @@ static void add_loaded_segments_info(str
|
||||
if (phdr->p_type != PT_LOAD)
|
||||
break;
|
||||
if (loaded_segments[loaded_segments_num].end !=
|
||||
- phdr->p_paddr & ~(ELF_PAGE_SIZE-1))
|
||||
+ (phdr->p_paddr & ~(ELF_PAGE_SIZE-1)))
|
||||
break;
|
||||
loaded_segments[loaded_segments_num].end +=
|
||||
(phdr->p_memsz + ELF_PAGE_SIZE - 1) &
|
@ -1,93 +0,0 @@
|
||||
From c466edd86b31a9d34cde3db24b093223108627d2 Mon Sep 17 00:00:00 2001
|
||||
From: Jay Lan <jlan@sgi.com>
|
||||
Date: Fri, 12 Sep 2008 13:10:34 -0700
|
||||
Subject: [PATCH] IA64: do not include uncached memory to vmcore
|
||||
|
||||
Currently a memory segment in memory map with attribute of EFI_MEMORY_UC
|
||||
is denoted as "System RAM" in /proc/iomem, while memory of attribute
|
||||
(EFI_MEMORY_WB|EFI_MEMORY_UC) is also labeled the same.
|
||||
|
||||
The kexec utility then includes uncached memory as part of vmcore.
|
||||
The kdump kernel may MCA when it tries to save the vmcore to a disk.
|
||||
A normal "cached" access can cause MCAs.
|
||||
|
||||
Since kexec assembled memory ranges with memory tagged as "System RAM",
|
||||
the uncached memory will be excluded if it is labeled differently.
|
||||
|
||||
Simon, since only IA64 will create "Uncached RAM" label, i do not
|
||||
make changes to other arch.
|
||||
|
||||
Our HP machine in the lab is dead. I am sorry that i can not test
|
||||
against other IA64 systems (than SGI's). Feedback is very much
|
||||
appreciated.
|
||||
|
||||
The corresponding kernel patch is needed to test this kexec patch:
|
||||
http://marc.info/?l=linux-ia64&m=122122791230130&w=2
|
||||
This patch without the kernel patch will have no effect and do no
|
||||
harm.
|
||||
|
||||
The kernel patch has been commited as
|
||||
"[IA64] kexec fails on systems with blocks of uncached memory".
|
||||
|
||||
Signed-off-by: Jay Lan <jlan@sgi.com>
|
||||
Signed-off-by: Simon Horman <horms@verge.net.au>
|
||||
Acked-by: Bernhard Walle <bwalle@suse.de>
|
||||
|
||||
---
|
||||
kexec/arch/ia64/crashdump-ia64.c | 5 ++++-
|
||||
kexec/arch/ia64/kexec-ia64.c | 5 ++++-
|
||||
kexec/firmware_memmap.c | 2 ++
|
||||
kexec/kexec.h | 1 +
|
||||
4 files changed, 11 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/kexec/arch/ia64/crashdump-ia64.c
|
||||
+++ b/kexec/arch/ia64/crashdump-ia64.c
|
||||
@@ -192,8 +192,11 @@ static int get_crash_memory_ranges(struc
|
||||
kernel_code_start = start;
|
||||
kernel_code_end = end;
|
||||
continue;
|
||||
- }else
|
||||
+ } else if (memcmp(str, "Uncached RAM\n", 13) == 0) {
|
||||
+ type = RANGE_UNCACHED;
|
||||
+ } else {
|
||||
continue;
|
||||
+ }
|
||||
crash_memory_range[memory_ranges].start = start;
|
||||
crash_memory_range[memory_ranges].end = end;
|
||||
crash_memory_range[memory_ranges].type = type;
|
||||
--- a/kexec/arch/ia64/kexec-ia64.c
|
||||
+++ b/kexec/arch/ia64/kexec-ia64.c
|
||||
@@ -139,8 +139,11 @@ int get_memory_ranges(struct memory_rang
|
||||
memory_ranges = split_range(memory_ranges, start, end);
|
||||
saved_efi_memmap_size = end - start;
|
||||
continue;
|
||||
- } else
|
||||
+ } else if (memcmp(str, "Uncached RAM\n", 13) == 0) {
|
||||
+ type = RANGE_UNCACHED;
|
||||
+ } else {
|
||||
continue;
|
||||
+ }
|
||||
/*
|
||||
* Check if this memory range can be coalesced with
|
||||
* the previous range
|
||||
--- a/kexec/firmware_memmap.c
|
||||
+++ b/kexec/firmware_memmap.c
|
||||
@@ -158,6 +158,8 @@ static int parse_memmap_entry(const char
|
||||
range->type = RANGE_RESERVED;
|
||||
else if (strcmp(type, "ACPI Non-volatile Storage") == 0)
|
||||
range->type = RANGE_ACPI_NVS;
|
||||
+ else if (strcmp(type, "Uncached RAM") == 0)
|
||||
+ range->type = RANGE_UNCACHED;
|
||||
else {
|
||||
fprintf(stderr, "Unknown type (%s) while parsing %s. Please "
|
||||
"report this as bug. Using RANGE_RESERVED now.\n",
|
||||
--- a/kexec/kexec.h
|
||||
+++ b/kexec/kexec.h
|
||||
@@ -110,6 +110,7 @@ struct memory_range {
|
||||
#define RANGE_RESERVED 1
|
||||
#define RANGE_ACPI 2
|
||||
#define RANGE_ACPI_NVS 3
|
||||
+#define RANGE_UNCACHED 4
|
||||
};
|
||||
|
||||
struct kexec_info {
|
@ -1,30 +0,0 @@
|
||||
Fix compile warnings in get_memory_ranges()
|
||||
|
||||
This patch fixes:
|
||||
|
||||
kexec/arch/i386/kexec-x86-common.c: In function ‘get_memory_ranges’:
|
||||
kexec/arch/i386/kexec-x86-common.c:189: \
|
||||
warning: passing argument 2 of ‘parse_iomem_single’ from incompatible pointer type
|
||||
kexec/arch/i386/kexec-x86-common.c:189: \
|
||||
warning: passing argument 3 of ‘parse_iomem_single’ from incompatible pointer type
|
||||
|
||||
Yes, that was my own code. :-(
|
||||
|
||||
|
||||
Signed-off-by: Bernhard Walle <bwalle@suse.de>
|
||||
|
||||
---
|
||||
kexec/arch/i386/kexec-x86-common.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/kexec/arch/i386/kexec-x86-common.c
|
||||
+++ b/kexec/arch/i386/kexec-x86-common.c
|
||||
@@ -181,7 +181,7 @@ int get_memory_ranges(struct memory_rang
|
||||
* subset of user defined values.
|
||||
*/
|
||||
if (kexec_flags & KEXEC_ON_CRASH) {
|
||||
- unsigned long long start, end;
|
||||
+ uint64_t start, end;
|
||||
|
||||
ret = parse_iomem_single("Crash kernel\n", &start, &end);
|
||||
if (ret != 0) {
|
@ -1,74 +0,0 @@
|
||||
From: Chandru <chandru@in.ibm.com>
|
||||
Subject: kdump: check flags field from drconf memory
|
||||
References: bnc#438086
|
||||
X-Git-Id: 802a8a5e396e06a514251c44454c982bff3c5073
|
||||
|
||||
On a powerpc machine when memory is dynamically removed/added from an lpar, the
|
||||
corresponding flags field in the drconf memory reflects the same with the bits
|
||||
unset/set accordingly. The kernel does a check on these flags while booting.
|
||||
Following are the similar changes brought in to kexec-tools. This makes
|
||||
kexec-tools to skip those memory regions that do not belong or are not
|
||||
assigned to the current partition ( but are available to dynamically add them
|
||||
back ). Without this patch (and with memory remove operation) copying vmcore
|
||||
fails with error as
|
||||
|
||||
Copying data : [ 84 %] readmem: Can't read the dump
|
||||
memory(/proc/vmcore). Bad address
|
||||
read_pfn: Can't get the page data.
|
||||
|
||||
|
||||
Signed-off-by : Chandru S <chandru@in.ibm.com>
|
||||
Signed-off-by: Simon Horman <horms@verge.net.au>
|
||||
Acked-by: Bernhard Walle <bwalle@suse.de>
|
||||
|
||||
---
|
||||
kexec/arch/ppc64/crashdump-ppc64.c | 12 ++++++++++--
|
||||
kexec/arch/ppc64/crashdump-ppc64.h | 3 +++
|
||||
2 files changed, 13 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/kexec/arch/ppc64/crashdump-ppc64.c
|
||||
+++ b/kexec/arch/ppc64/crashdump-ppc64.c
|
||||
@@ -121,12 +121,13 @@ static void exclude_crash_region(uint64_
|
||||
}
|
||||
}
|
||||
|
||||
-static int get_dyn_reconf_crash_memory_ranges()
|
||||
+static int get_dyn_reconf_crash_memory_ranges(void)
|
||||
{
|
||||
uint64_t start, end;
|
||||
char fname[128], buf[32];
|
||||
FILE *file;
|
||||
int i, n;
|
||||
+ uint32_t flags;
|
||||
|
||||
strcpy(fname, "/proc/device-tree/");
|
||||
strcat(fname, "ibm,dynamic-reconfiguration-memory/ibm,dynamic-memory");
|
||||
@@ -150,10 +151,17 @@ static int get_dyn_reconf_crash_memory_r
|
||||
return -1;
|
||||
}
|
||||
|
||||
- start = ((uint64_t *)buf)[0];
|
||||
+ start = ((uint64_t *)buf)[DRCONF_ADDR];
|
||||
end = start + lmb_size;
|
||||
if (start == 0 && end >= (BACKUP_SRC_END + 1))
|
||||
start = BACKUP_SRC_END + 1;
|
||||
+
|
||||
+ flags = (*((uint32_t *)&buf[DRCONF_FLAGS]));
|
||||
+ /* skip this block if the reserved bit is set in flags (0x80)
|
||||
+ or if the block is not assigned to this partition (0x8) */
|
||||
+ if ((flags & 0x80) || !(flags & 0x8))
|
||||
+ continue;
|
||||
+
|
||||
exclude_crash_region(start, end);
|
||||
}
|
||||
fclose(file);
|
||||
--- a/kexec/arch/ppc64/crashdump-ppc64.h
|
||||
+++ b/kexec/arch/ppc64/crashdump-ppc64.h
|
||||
@@ -31,4 +31,7 @@ extern unsigned int rtas_size;
|
||||
uint64_t lmb_size;
|
||||
unsigned int num_of_lmbs;
|
||||
|
||||
+#define DRCONF_ADDR 0
|
||||
+#define DRCONF_FLAGS 20
|
||||
+
|
||||
#endif /* CRASHDUMP_PPC64_H */
|
@ -1,28 +0,0 @@
|
||||
From 93792363d3455459c7af7c646c0a1d1238c772fb Mon Sep 17 00:00:00 2001
|
||||
From: Maxim Shchetynin <maxim@de.ibm.com>
|
||||
Date: Wed, 27 Aug 2008 10:04:56 +0200
|
||||
Subject: [PATCH] Let kexec work on IBM QS2x blade servers
|
||||
|
||||
Hello,
|
||||
|
||||
please have a look at the following patch. This patch allows kexec to work
|
||||
on IBM QS2x blades. Would it be possible to apply this patch to a next
|
||||
kexec version?
|
||||
|
||||
Signed-off-by: Maxim Shchetynin <maxim@de.ibm.com>
|
||||
Signed-off-by: Simon Horman <horms@verge.net.au>
|
||||
|
||||
---
|
||||
kexec/arch/ppc64/kexec-elf-rel-ppc64.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/kexec/arch/ppc64/kexec-elf-rel-ppc64.c
|
||||
+++ b/kexec/arch/ppc64/kexec-elf-rel-ppc64.c
|
||||
@@ -56,6 +56,7 @@ void machine_apply_elf_rel(struct mem_eh
|
||||
break;
|
||||
|
||||
case R_PPC64_ADDR64:
|
||||
+ case R_PPC64_REL64:
|
||||
/* Simply set it */
|
||||
*(uint64_t *)location = value;
|
||||
break;
|
@ -1,129 +0,0 @@
|
||||
From b422925d35151caa65471c0f0d774727bde4a347 Mon Sep 17 00:00:00 2001
|
||||
From: Geoff Levand <geoffrey.levand@am.sony.com>
|
||||
Date: Wed, 10 Sep 2008 18:40:46 -0700
|
||||
Subject: [PATCH] Fix ppc64 build warnings
|
||||
|
||||
Fix these ppc64 32 bit build warnings:
|
||||
|
||||
kexec/arch/ppc64/kexec-zImage-ppc64.c: In function 'zImage_ppc64_load':
|
||||
kexec/arch/ppc64/kexec-zImage-ppc64.c:164: warning: cast to pointer from integer of different size
|
||||
kexec/arch/ppc64/kexec-elf-ppc64.c: In function 'elf_ppc64_load':
|
||||
kexec/arch/ppc64/kexec-elf-ppc64.c:121: warning: integer constant is too large for 'unsigned long' type
|
||||
kexec/arch/ppc64/kexec-elf-ppc64.c:237: warning: cast from pointer to integer of different size
|
||||
kexec/arch/ppc64/kexec-elf-ppc64.c:276: warning: cast from pointer to integer of different size
|
||||
kexec/arch/ppc64/kexec-elf-ppc64.c:283: warning: cast from pointer to integer of different size
|
||||
kexec/arch/ppc64/kexec-elf-ppc64.c:287: warning: cast from pointer to integer of different size
|
||||
kexec/arch/ppc64/kexec-elf-ppc64.c:341: warning: format '%lx' expects type 'long unsigned int', but argument 3 has type 'uint64_t'
|
||||
kexec/arch/ppc64/kexec-elf-ppc64.c:352: warning: format '%ld' expects type 'long int', but argument 5 has type 'size_t'
|
||||
kexec/arch/ppc64/crashdump-ppc64.c:45: warning: integer constant is too large for 'long' type
|
||||
kexec/arch/ppc64/crashdump-ppc64.c:46: warning: integer constant is too large for 'long' type
|
||||
kexec/arch/ppc64/crashdump-ppc64.c:56: warning: integer constant is too large for 'long' type
|
||||
kexec/arch/ppc64/crashdump-ppc64.c:57: warning: integer constant is too large for 'long' type
|
||||
|
||||
Tested on PS3 (ppc64) with 32 and 64 bit builds.
|
||||
|
||||
Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
|
||||
Signed-off-by: Simon Horman <horms@verge.net.au>
|
||||
Acked-by: Bernhard Walle <bwalle@suse.de>
|
||||
|
||||
---
|
||||
kexec/arch/ppc64/crashdump-ppc64.h | 4 ++--
|
||||
kexec/arch/ppc64/kexec-elf-ppc64.c | 26 ++++++++++++++------------
|
||||
kexec/arch/ppc64/kexec-zImage-ppc64.c | 2 +-
|
||||
3 files changed, 17 insertions(+), 15 deletions(-)
|
||||
|
||||
--- a/kexec/arch/ppc64/crashdump-ppc64.h
|
||||
+++ b/kexec/arch/ppc64/crashdump-ppc64.h
|
||||
@@ -6,9 +6,9 @@ int load_crashdump_segments(struct kexec
|
||||
uint64_t max_addr, unsigned long min_base);
|
||||
void add_usable_mem_rgns(unsigned long long base, unsigned long long size);
|
||||
|
||||
-#define PAGE_OFFSET 0xC000000000000000
|
||||
+#define PAGE_OFFSET 0xC000000000000000ULL
|
||||
#define KERNELBASE PAGE_OFFSET
|
||||
-#define VMALLOCBASE 0xD000000000000000
|
||||
+#define VMALLOCBASE 0xD000000000000000ULL
|
||||
|
||||
#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET)
|
||||
#define MAXMEM (-KERNELBASE-VMALLOCBASE)
|
||||
--- a/kexec/arch/ppc64/kexec-elf-ppc64.c
|
||||
+++ b/kexec/arch/ppc64/kexec-elf-ppc64.c
|
||||
@@ -118,7 +118,7 @@ int elf_ppc64_load(int argc, char **argv
|
||||
cmdline = 0;
|
||||
ramdisk = 0;
|
||||
devicetreeblob = 0;
|
||||
- max_addr = 0xFFFFFFFFFFFFFFFFUL;
|
||||
+ max_addr = 0xFFFFFFFFFFFFFFFFULL;
|
||||
hole_addr = 0;
|
||||
|
||||
while ((opt = getopt_long(argc, argv, short_options,
|
||||
@@ -233,7 +233,7 @@ int elf_ppc64_load(int argc, char **argv
|
||||
}
|
||||
seg_buf = (unsigned char *)slurp_file(ramdisk, &seg_size);
|
||||
add_buffer(info, seg_buf, seg_size, seg_size, 0, 0, max_addr, 1);
|
||||
- hole_addr = (uint64_t)
|
||||
+ hole_addr = (uintptr_t)
|
||||
info->segment[info->nr_segments-1].mem;
|
||||
initrd_base = hole_addr;
|
||||
initrd_size = (uint64_t)
|
||||
@@ -272,7 +272,7 @@ int elf_ppc64_load(int argc, char **argv
|
||||
while (*rsvmap_ptr || *(rsvmap_ptr+1))
|
||||
rsvmap_ptr += 2;
|
||||
rsvmap_ptr -= 2;
|
||||
- *rsvmap_ptr = (uint64_t)(
|
||||
+ *rsvmap_ptr = (uintptr_t)(
|
||||
info->segment[(info->nr_segments)-1].mem);
|
||||
rsvmap_ptr++;
|
||||
*rsvmap_ptr = (uint64_t)bb_ptr->totalsize;
|
||||
@@ -280,11 +280,11 @@ int elf_ppc64_load(int argc, char **argv
|
||||
nr_segments = info->nr_segments;
|
||||
|
||||
/* Set kernel */
|
||||
- my_kernel = (uint64_t)info->segment[0].mem;
|
||||
+ my_kernel = (uintptr_t)info->segment[0].mem;
|
||||
elf_rel_set_symbol(&info->rhdr, "kernel", &my_kernel, sizeof(my_kernel));
|
||||
|
||||
/* Set dt_offset */
|
||||
- my_dt_offset = (uint64_t)info->segment[nr_segments-1].mem;
|
||||
+ my_dt_offset = (uintptr_t)info->segment[nr_segments-1].mem;
|
||||
elf_rel_set_symbol(&info->rhdr, "dt_offset", &my_dt_offset,
|
||||
sizeof(my_dt_offset));
|
||||
|
||||
@@ -338,17 +338,19 @@ int elf_ppc64_load(int argc, char **argv
|
||||
sizeof(toc_addr));
|
||||
|
||||
fprintf(stderr, "info->entry is %p\n", info->entry);
|
||||
- fprintf(stderr, "kernel is %lx\n", my_kernel);
|
||||
- fprintf(stderr, "dt_offset is %lx\n", my_dt_offset);
|
||||
+ fprintf(stderr, "kernel is %llx\n", (unsigned long long)my_kernel);
|
||||
+ fprintf(stderr, "dt_offset is %llx\n",
|
||||
+ (unsigned long long)my_dt_offset);
|
||||
fprintf(stderr, "panic_kernel is %x\n", my_panic_kernel);
|
||||
- fprintf(stderr, "backup_start is %lx\n", my_backup_start);
|
||||
- fprintf(stderr, "stack is %lx\n", my_stack);
|
||||
- fprintf(stderr, "toc_addr is %lx\n", toc_addr);
|
||||
- fprintf(stderr, "purgatory size is %lu\n", purgatory_size);
|
||||
+ fprintf(stderr, "backup_start is %llx\n",
|
||||
+ (unsigned long long)my_backup_start);
|
||||
+ fprintf(stderr, "stack is %llx\n", (unsigned long long)my_stack);
|
||||
+ fprintf(stderr, "toc_addr is %llx\n", (unsigned long long)toc_addr);
|
||||
+ fprintf(stderr, "purgatory size is %zu\n", purgatory_size);
|
||||
#endif
|
||||
|
||||
for (i = 0; i < nr_segments; i++)
|
||||
- fprintf(stderr, "segment[%d].mem:%p memsz:%ld\n", i,
|
||||
+ fprintf(stderr, "segment[%d].mem:%p memsz:%zu\n", i,
|
||||
info->segment[i].mem, info->segment[i].memsz);
|
||||
|
||||
return 0;
|
||||
--- a/kexec/arch/ppc64/kexec-zImage-ppc64.c
|
||||
+++ b/kexec/arch/ppc64/kexec-zImage-ppc64.c
|
||||
@@ -161,7 +161,7 @@ int zImage_ppc64_load(FILE *file, int ar
|
||||
segment->mem = (void *) load_loc;
|
||||
segment->memsz = memsize;
|
||||
segment->bufsz = filesize;
|
||||
- *ret_entry = (void *)((uint64_t)elf.e_entry);
|
||||
+ *ret_entry = (void *)(uintptr_t)elf.e_entry;
|
||||
*ret_nr_segments = i - 1;
|
||||
free(ph);
|
||||
return 0;
|
@ -1,25 +0,0 @@
|
||||
From b4b79993adc9ac3094361900f34582e36f5de162 Mon Sep 17 00:00:00 2001
|
||||
From: Bernhard Walle <bwalle@suse.de>
|
||||
Date: Fri, 16 Jan 2009 18:52:29 +0100
|
||||
Subject: [PATCH] [PPC64] Fix typo in realloc_memory_ranges()
|
||||
|
||||
The base_memory_range should not become memory_range. We need to realloc
|
||||
base_memory_range to not change the contents of memory. That was a copy & paste
|
||||
error.
|
||||
|
||||
|
||||
Signed-off-by: Bernhard Walle <bwalle@suse.de>
|
||||
|
||||
diff --git a/kexec/arch/ppc64/kexec-ppc64.c b/kexec/arch/ppc64/kexec-ppc64.c
|
||||
index d8347f1..b0d8acd 100644
|
||||
--- a/kexec/arch/ppc64/kexec-ppc64.c
|
||||
+++ b/kexec/arch/ppc64/kexec-ppc64.c
|
||||
@@ -107,7 +107,7 @@ static int realloc_memory_ranges(void)
|
||||
if (!memory_range)
|
||||
goto err;
|
||||
|
||||
- base_memory_range = (struct memory_range *) realloc(memory_range, memory_range_len);
|
||||
+ base_memory_range = (struct memory_range *) realloc(base_memory_range, memory_range_len);
|
||||
if (!base_memory_range)
|
||||
goto err;
|
||||
|
@ -1,44 +0,0 @@
|
||||
From ef3f522c99c0e8af06ae5af625225885f8930b19 Mon Sep 17 00:00:00 2001
|
||||
From: Bernhard Walle <bwalle@suse.de>
|
||||
Date: Fri, 16 Jan 2009 18:52:26 +0100
|
||||
Subject: [PATCH] [PPC64] Fix memory corruption when using realloc_memory_ranges()
|
||||
|
||||
Because realloc_memory_ranges() makes the old memory invalid, and we return
|
||||
a pointer to memory_range in get_memory_ranges(), we need to copy the contents
|
||||
in get_memory_ranges().
|
||||
|
||||
Some code that calls realloc_memory_ranges() may be triggered by
|
||||
get_base_ranges() which is called after get_memory_ranges().
|
||||
|
||||
Yes, the memory needs to be deleted somewhere, but I don't know currently
|
||||
where it's the best, and since it's not in a loop and memory is deleted
|
||||
anyway after program termination I don't want to introduce unneccessary
|
||||
complexity. The problem is that get_base_ranges() gets called from
|
||||
architecture independent code and that allocation is PPC64-specific here.
|
||||
|
||||
|
||||
Signed-off-by: Bernhard Walle <bwalle@suse.de>diff --git a/kexec/arch/ppc64/kexec-ppc64.c b/kexec/arch/ppc64/kexec-ppc64.c
|
||||
index b0d8acd..ad8a31c 100644
|
||||
|
||||
diff --git a/kexec/arch/ppc64/kexec-ppc64.c b/kexec/arch/ppc64/kexec-ppc64.c
|
||||
index b0d8acd..ad8a31c 100644
|
||||
--- a/kexec/arch/ppc64/kexec-ppc64.c
|
||||
+++ b/kexec/arch/ppc64/kexec-ppc64.c
|
||||
@@ -715,7 +715,16 @@ int get_memory_ranges(struct memory_range **range, int *ranges,
|
||||
if (setup_memory_ranges(kexec_flags))
|
||||
return -1;
|
||||
|
||||
- *range = memory_range;
|
||||
+ /*
|
||||
+ * copy the memory here, another realloc_memory_ranges might
|
||||
+ * corrupt the old memory
|
||||
+ */
|
||||
+ *range = calloc(sizeof(struct memory_range), nr_memory_ranges);
|
||||
+ if (*range == NULL)
|
||||
+ return -1;
|
||||
+ memmove(*range, memory_range,
|
||||
+ sizeof(struct memory_range) * nr_memory_ranges);
|
||||
+
|
||||
*ranges = nr_memory_ranges;
|
||||
fprintf(stderr, "get memory ranges:%d\n", nr_memory_ranges);
|
||||
return 0;
|
@ -1,45 +0,0 @@
|
||||
From 8a2f02cc303147cb09f00a9d322c6bfaee32492d Mon Sep 17 00:00:00 2001
|
||||
From: Bernhard Walle <bwalle@suse.de>
|
||||
Date: Fri, 16 Jan 2009 18:52:10 +0100
|
||||
Subject: [PATCH] [PPC64] printf() consolidation
|
||||
|
||||
Remove the fprintf(stderr,...) in get_memory_ranges() that adds unnecessary
|
||||
output in the normal kexec case that the user don't want to see.
|
||||
|
||||
Use dbgprintf() in get_base_ranges() instead of
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr,...)
|
||||
#endif
|
||||
|
||||
to to make the code more readable.
|
||||
|
||||
|
||||
Signed-off-by: Bernhard Walle <bwalle@suse.de>diff --git a/kexec/arch/ppc64/kexec-ppc64.c b/kexec/arch/ppc64/kexec-ppc64.c
|
||||
index ad8a31c..8d4e42b 100644
|
||||
|
||||
diff --git a/kexec/arch/ppc64/kexec-ppc64.c b/kexec/arch/ppc64/kexec-ppc64.c
|
||||
index ad8a31c..8d4e42b 100644
|
||||
--- a/kexec/arch/ppc64/kexec-ppc64.c
|
||||
+++ b/kexec/arch/ppc64/kexec-ppc64.c
|
||||
@@ -263,9 +263,8 @@ static int get_base_ranges(void)
|
||||
closedir(dir);
|
||||
sort_base_ranges();
|
||||
memory_max = base_memory_range[nr_memory_ranges - 1].end;
|
||||
-#ifdef DEBUG
|
||||
- fprintf(stderr, "get base memory ranges:%d\n", nr_memory_ranges);
|
||||
-#endif
|
||||
+ dbgprintf("get base memory ranges:%d\n", nr_memory_ranges);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -726,7 +725,7 @@ int get_memory_ranges(struct memory_range **range, int *ranges,
|
||||
sizeof(struct memory_range) * nr_memory_ranges);
|
||||
|
||||
*ranges = nr_memory_ranges;
|
||||
- fprintf(stderr, "get memory ranges:%d\n", nr_memory_ranges);
|
||||
+ dbgprintf("get memory ranges:%d\n", nr_memory_ranges);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,187 +0,0 @@
|
||||
From d182ce5434c7b66569118db0ccfe63e5d8a03687 Mon Sep 17 00:00:00 2001
|
||||
From: Maxim Uvarov <muvarov@gmail.com>
|
||||
Date: Wed, 15 Oct 2008 12:46:24 +0400
|
||||
Subject: [PATCH] ppc64: kexec memory ranges dynamic allocation
|
||||
|
||||
Do not count max_memory_range for allocation. Increase allocation buffers
|
||||
when it is needed. This actually allows us to avoid a lot of troubles with
|
||||
various device-tree files.
|
||||
|
||||
Signed-off-by: Maxim Uvarov <muvarov@gmail.com>
|
||||
Signed-off-by: Simon Horman <horms@verge.net.au>
|
||||
|
||||
diff --git a/kexec/arch/ppc64/kexec-ppc64.c b/kexec/arch/ppc64/kexec-ppc64.c
|
||||
index 069a9fc..f60c9ec 100644
|
||||
--- a/kexec/arch/ppc64/kexec-ppc64.c
|
||||
+++ b/kexec/arch/ppc64/kexec-ppc64.c
|
||||
@@ -96,96 +96,46 @@ err1:
|
||||
|
||||
}
|
||||
|
||||
-static int count_dyn_reconf_memory_ranges(void)
|
||||
+static int realloc_memory_ranges()
|
||||
{
|
||||
- char device_tree[] = "/proc/device-tree/";
|
||||
- char fname[128];
|
||||
- char buf[32];
|
||||
- FILE *file;
|
||||
-
|
||||
- strcpy(fname, device_tree);
|
||||
- strcat(fname, "ibm,dynamic-reconfiguration-memory/ibm,lmb-size");
|
||||
- if ((file = fopen(fname, "r")) == NULL) {
|
||||
- perror(fname);
|
||||
- return -1;
|
||||
- }
|
||||
+ size_t memory_range_len;
|
||||
|
||||
- if (fread(buf, 1, 8, file) < 0) {
|
||||
- perror(fname);
|
||||
- fclose(file);
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- lmb_size = ((uint64_t *)buf)[0];
|
||||
- fclose(file);
|
||||
+ max_memory_ranges++;
|
||||
+ memory_range_len = sizeof(struct memory_range) * max_memory_ranges;
|
||||
|
||||
- /* Get number of lmbs from ibm,dynamic-memory */
|
||||
- strcpy(fname, device_tree);
|
||||
- strcat(fname, "ibm,dynamic-reconfiguration-memory/ibm,dynamic-memory");
|
||||
- if ((file = fopen(fname, "r")) == NULL) {
|
||||
- perror(fname);
|
||||
- return -1;
|
||||
- }
|
||||
- /*
|
||||
- * first 4 bytes provide number of entries(lmbs)
|
||||
- */
|
||||
- if (fread(buf, 1, 4, file) < 0) {
|
||||
- perror(fname);
|
||||
- fclose(file);
|
||||
- return -1;
|
||||
- }
|
||||
- num_of_lmbs = ((unsigned int *)buf)[0];
|
||||
- max_memory_ranges += num_of_lmbs;
|
||||
- fclose(file);
|
||||
+ memory_range = (struct memory_range *) realloc(memory_range, memory_range_len);
|
||||
+ if (!memory_range)
|
||||
+ goto err;
|
||||
|
||||
- return 0;
|
||||
-}
|
||||
+ base_memory_range = (struct memory_range *) realloc(memory_range, memory_range_len);
|
||||
+ if (!base_memory_range)
|
||||
+ goto err;
|
||||
|
||||
-/*
|
||||
- * Count the memory nodes under /proc/device-tree and populate the
|
||||
- * max_memory_ranges variable. This variable replaces MAX_MEMORY_RANGES
|
||||
- * macro used earlier.
|
||||
- */
|
||||
-static int count_memory_ranges(void)
|
||||
-{
|
||||
- char device_tree[256] = "/proc/device-tree/";
|
||||
- struct dirent *dentry;
|
||||
- DIR *dir;
|
||||
+ exclude_range = (struct memory_range *) realloc(exclude_range, memory_range_len);
|
||||
+ if (!exclude_range)
|
||||
+ goto err;
|
||||
|
||||
- if ((dir = opendir(device_tree)) == NULL) {
|
||||
- perror(device_tree);
|
||||
- return -1;
|
||||
- }
|
||||
+ usablemem_rgns.ranges = (struct memory_range *)
|
||||
+ realloc(usablemem_rgns.ranges, memory_range_len);
|
||||
+ if (!(usablemem_rgns.ranges))
|
||||
+ goto err;
|
||||
|
||||
- while ((dentry = readdir(dir)) != NULL) {
|
||||
- if (!strncmp(dentry->d_name,
|
||||
- "ibm,dynamic-reconfiguration-memory", 35)){
|
||||
- if (count_dyn_reconf_memory_ranges() != 0)
|
||||
- return -1;
|
||||
- continue;
|
||||
- }
|
||||
+ return 0;
|
||||
|
||||
- if (strncmp(dentry->d_name, "memory@", 7) &&
|
||||
- strcmp(dentry->d_name, "memory") &&
|
||||
- strncmp(dentry->d_name, "pci@", 4))
|
||||
- continue;
|
||||
- max_memory_ranges++;
|
||||
- }
|
||||
- /* need to add extra region for retained initrd */
|
||||
- if (reuse_initrd) {
|
||||
- max_memory_ranges++;
|
||||
- }
|
||||
+err:
|
||||
+ fprintf(stderr, "memory range structure re-allocation failure\n");
|
||||
+ return -1;
|
||||
+}
|
||||
|
||||
- closedir(dir);
|
||||
|
||||
- return 0;
|
||||
-}
|
||||
static void add_base_memory_range(uint64_t start, uint64_t end)
|
||||
{
|
||||
base_memory_range[nr_memory_ranges].start = start;
|
||||
base_memory_range[nr_memory_ranges].end = end;
|
||||
base_memory_range[nr_memory_ranges].type = RANGE_RAM;
|
||||
nr_memory_ranges++;
|
||||
+ if (nr_memory_ranges >= max_memory_ranges)
|
||||
+ realloc_memory_ranges();
|
||||
|
||||
dbgprintf("%016llx-%016llx : %x\n",
|
||||
base_memory_range[nr_memory_ranges-1].start,
|
||||
@@ -300,8 +250,8 @@ static int get_base_ranges(void)
|
||||
return -1;
|
||||
}
|
||||
if (nr_memory_ranges >= max_memory_ranges) {
|
||||
- fclose(file);
|
||||
- break;
|
||||
+ if (realloc_memory_ranges() < 0)
|
||||
+ break;
|
||||
}
|
||||
start = ((uint64_t *)buf)[0];
|
||||
end = start + ((uint64_t *)buf)[1];
|
||||
@@ -396,6 +346,8 @@ static int get_devtree_details(unsigned long kexec_flags)
|
||||
exclude_range[i].start = 0x0UL;
|
||||
exclude_range[i].end = kernel_end;
|
||||
i++;
|
||||
+ if (i >= max_memory_ranges)
|
||||
+ realloc_memory_ranges();
|
||||
|
||||
if (kexec_flags & KEXEC_ON_CRASH) {
|
||||
memset(fname, 0, sizeof(fname));
|
||||
@@ -470,6 +422,8 @@ static int get_devtree_details(unsigned long kexec_flags)
|
||||
exclude_range[i].start = htab_base;
|
||||
exclude_range[i].end = htab_base + htab_size;
|
||||
i++;
|
||||
+ if (i >= max_memory_ranges)
|
||||
+ realloc_memory_ranges();
|
||||
|
||||
/* reserve the initrd_start and end locations. */
|
||||
if (reuse_initrd) {
|
||||
@@ -545,6 +499,8 @@ static int get_devtree_details(unsigned long kexec_flags)
|
||||
exclude_range[i].start = rtas_base;
|
||||
exclude_range[i].end = rtas_base + rtas_size;
|
||||
i++;
|
||||
+ if (i >= max_memory_ranges)
|
||||
+ realloc_memory_ranges();
|
||||
if (kexec_flags & KEXEC_ON_CRASH)
|
||||
add_usable_mem_rgns(rtas_base, rtas_size);
|
||||
} /* rtas */
|
||||
@@ -741,8 +697,9 @@ out:
|
||||
int get_memory_ranges(struct memory_range **range, int *ranges,
|
||||
unsigned long kexec_flags)
|
||||
{
|
||||
- if (count_memory_ranges())
|
||||
- return -1;
|
||||
+ /* allocate memory_range dynamically */
|
||||
+ max_memory_ranges = 1;
|
||||
+
|
||||
if (alloc_memory_ranges())
|
||||
return -1;
|
||||
if (setup_memory_ranges(kexec_flags))
|
@ -1,68 +0,0 @@
|
||||
From: Chandru S <chandru@linux.vnet.ibm.com>
|
||||
Subject: [PATCH] powerpc: initialize drconf variables
|
||||
References: bnc #468571
|
||||
|
||||
The ppc64-memory-ranges-dynamic.diff patch which added
|
||||
realloc_memory_ranges() code to kexec-tools somehow removed
|
||||
the initialization of lmb-size and num_of_lmbs required in
|
||||
case of /proc/ibm,dynamic-reconfiguration-memory node.
|
||||
Add the code here to initialize them back again in kexec-tools
|
||||
|
||||
Signed-off-by: Chandru S <chandru@linux.vnet.ibm.com>
|
||||
Acked-by: Bernhard Walle <bwalle@suse.de>
|
||||
|
||||
---
|
||||
kexec/arch/ppc64/kexec-ppc64.c | 27 +++++++++++++++++++++++++--
|
||||
1 file changed, 25 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/kexec/arch/ppc64/kexec-ppc64.c
|
||||
+++ b/kexec/arch/ppc64/kexec-ppc64.c
|
||||
@@ -96,7 +96,7 @@ err1:
|
||||
|
||||
}
|
||||
|
||||
-static int realloc_memory_ranges()
|
||||
+static int realloc_memory_ranges(void)
|
||||
{
|
||||
size_t memory_range_len;
|
||||
|
||||
@@ -150,6 +150,23 @@ static int get_dyn_reconf_base_ranges(vo
|
||||
FILE *file;
|
||||
int i, n;
|
||||
|
||||
+ strcpy(fname, "/proc/device-tree/");
|
||||
+ strcat(fname, "ibm,dynamic-reconfiguration-memory/ibm,lmb-size");
|
||||
+ if ((file = fopen(fname, "r")) == NULL) {
|
||||
+ perror(fname);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ if (fread(buf, 1, 8, file) != 8) {
|
||||
+ perror(fname);
|
||||
+ fclose(file);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ /*
|
||||
+ * lmb_size, num_of_lmbs(global variables) are
|
||||
+ * initialized once here.
|
||||
+ */
|
||||
+ lmb_size = ((uint64_t *)buf)[0];
|
||||
+ fclose(file);
|
||||
|
||||
strcpy(fname, "/proc/device-tree/");
|
||||
strcat(fname,
|
||||
@@ -158,8 +175,14 @@ static int get_dyn_reconf_base_ranges(vo
|
||||
perror(fname);
|
||||
return -1;
|
||||
}
|
||||
+ /* first 4 bytes tell the number of lmbs */
|
||||
+ if (fread(buf, 1, 4, file) != 4) {
|
||||
+ perror(fname);
|
||||
+ fclose(file);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ num_of_lmbs = ((unsigned int *)buf)[0];
|
||||
|
||||
- fseek(file, 4, SEEK_SET);
|
||||
for (i = 0; i < num_of_lmbs; i++) {
|
||||
if ((n = fread(buf, 1, 24, file)) < 0) {
|
||||
perror(fname);
|
@ -1,30 +0,0 @@
|
||||
From: Bernhard Walle <bwalle@suse.de>
|
||||
Subject: [PATCH] Don't use /sys/firmware/memmap with Xen
|
||||
|
||||
On Xen (Dom0) kernels, the /sys/firmware/memmap is wrong. Just use the old
|
||||
/proc/iomem there.
|
||||
|
||||
|
||||
Signed-off-by: Bernhard Walle <bwalle@suse.de>
|
||||
|
||||
---
|
||||
kexec/arch/i386/kexec-x86-common.c | 8 +++++++-
|
||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/kexec/arch/i386/kexec-x86-common.c
|
||||
+++ b/kexec/arch/i386/kexec-x86-common.c
|
||||
@@ -147,7 +147,13 @@ int get_memory_ranges(struct memory_rang
|
||||
{
|
||||
int ret, i;
|
||||
|
||||
- if (have_sys_firmware_memmap())
|
||||
+ /*
|
||||
+ * When using Xen, /sys/firmware/memmap (i.e., the E820 map) is
|
||||
+ * wrong, it just provides one large memory are and that cannot
|
||||
+ * be used for Kdump. Use always the /proc/iomem interface there
|
||||
+ * even if we have /sys/firmware/memmap.
|
||||
+ */
|
||||
+ if (!xen_present() && have_sys_firmware_memmap())
|
||||
ret = get_memory_ranges_sysfs(range, ranges);
|
||||
else
|
||||
ret = get_memory_ranges_proc_iomem(range, ranges);
|
@ -1,25 +0,0 @@
|
||||
From: Bernhard Walle <bwalle@suse.de>
|
||||
Date: Fri, 14 Nov 2008 10:47:29 +0100
|
||||
Subject: [PATCH] Fix spell error in help output
|
||||
References: bnc#444714
|
||||
|
||||
This patch just fixes a spell error. Found by Dave Plater.
|
||||
|
||||
|
||||
Signed-off-by: Bernhard Walle <bwalle@suse.de>
|
||||
|
||||
---
|
||||
kexec/kexec.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/kexec/kexec.c
|
||||
+++ b/kexec/kexec.c
|
||||
@@ -786,7 +786,7 @@ void usage(void)
|
||||
" load code into.\n"
|
||||
" --mem-max=<addr> Specify the highest memory address to\n"
|
||||
" load code into.\n"
|
||||
- " --reuseinird Reuse initrd from first boot.\n"
|
||||
+ " --reuseinitrd Reuse initrd from first boot.\n"
|
||||
"\n"
|
||||
"Supported kernel file types and options: \n");
|
||||
for (i = 0; i < file_types; i++) {
|
@ -1,3 +1,31 @@
|
||||
-------------------------------------------------------------------
|
||||
Sun Dec 20 17:33:50 CET 2009 - bernhard@bwalle.de
|
||||
|
||||
- Update to kexec-tools 2.0.1 (bug fix release).
|
||||
- Drop following patches because they are upstream now (or the
|
||||
problem is fixed otherwise upstream):
|
||||
o kexec-tools-ia64-uncached-memory.diff
|
||||
o kexec-tools-ia64-PA.diff
|
||||
o kexec-tools-build-warnings.diff
|
||||
o kexec-tools-ppc64-build-warnings.diff
|
||||
o kexec-tools-ppc64-IBM-QS2x-blades.diff
|
||||
o kexec-tools-ia64-kdump-PT_LOAD-order.diff
|
||||
o kexec-tools-crash-memory-ranges-drconf.diff
|
||||
o kexec-tools-add-usable-drconf-memory-node-to-device-tree.diff
|
||||
o kexec-tools-get-details-dynamic-reconfiguration-memory-node.diff
|
||||
o kexec-tools-get-details-dynamic-reconfiguration-memory-node.diff
|
||||
o kexec-tools-device-tree-return.diff
|
||||
o kexec-tools-ppc-check-flags.diff
|
||||
o kexec-tools-spell.diff
|
||||
o kexec-tools-proc-iomem-xen.diff
|
||||
o kexec-tools-parse-iomem-single-warning.diff
|
||||
o kexec-tools-exclude-gart.diff
|
||||
o kexec-tools-ppc64-memory-ranges-dynamic.diff
|
||||
o kexec-tools-ppc64-dynamic-fix-1.diff
|
||||
o kexec-tools-ppc64-dynamic-fix-2.diff
|
||||
o kexec-tools-ppc64-dynamic-fix-3.diff
|
||||
o kexec-tools-ppc64-reinit.diff
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Aug 12 09:46:46 CEST 2009 - tiwai@suse.de
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# spec file for package kexec-tools (Version 2.0.0)
|
||||
# spec file for package kexec-tools (Version 2.0.1)
|
||||
#
|
||||
# Copyright (c) 2009 SUSE LINUX Products GmbH, Nuernberg, Germany.
|
||||
#
|
||||
@ -22,42 +22,22 @@ Name: kexec-tools
|
||||
%ifarch ppc
|
||||
BuildRequires: gcc-64bit glibc-devel-64bit
|
||||
%endif
|
||||
License: GPL v2 or later
|
||||
License: GPLv2+
|
||||
Group: System/Kernel
|
||||
Requires: perl-Bootloader
|
||||
PreReq: %insserv_prereq %fillup_prereq
|
||||
AutoReqProv: on
|
||||
Summary: Tools for fast kernel loading
|
||||
Version: 2.0.0
|
||||
Release: 56
|
||||
Version: 2.0.1
|
||||
Release: 1
|
||||
Source: %{name}-%{version}.tar.bz2
|
||||
Source1: kexec-bootloader
|
||||
Source2: kexec-bootloader.8.txt
|
||||
Source3: kexec.init
|
||||
Source4: %{name}-%{version}-rpmlintrc
|
||||
Patch0: %{name}-ia64-uncached-memory.diff
|
||||
Patch1: %{name}-ia64-PA.diff
|
||||
Patch2: %{name}-build-warnings.diff
|
||||
Patch3: %{name}-ppc64-build-warnings.diff
|
||||
Patch4: %{name}-ppc64-IBM-QS2x-blades.diff
|
||||
Patch5: %{name}-ia64-kdump-PT_LOAD-order.diff
|
||||
Patch6: %{name}-crash-memory-ranges-drconf.diff
|
||||
Patch7: %{name}-add-usable-drconf-memory-node-to-device-tree.diff
|
||||
Patch8: %{name}-get-details-dynamic-reconfiguration-memory-node.diff
|
||||
Patch9: %{name}-device-tree-return.diff
|
||||
Patch10: %{name}-ppc-check-flags.diff
|
||||
Patch11: %{name}-no-vga-output.diff
|
||||
Patch12: %{name}-spell.diff
|
||||
Patch13: %{name}-xen-static.diff
|
||||
Patch14: %{name}-proc-iomem-xen.diff
|
||||
Patch15: %{name}-parse-iomem-single-warning.diff
|
||||
Patch16: %{name}-exclude-gart.diff
|
||||
Patch17: %{name}-ppc64-memory-ranges-dynamic.diff
|
||||
Patch18: %{name}-ppc64-dynamic-fix-1.diff
|
||||
Patch19: %{name}-ppc64-dynamic-fix-2.diff
|
||||
Patch20: %{name}-ppc64-dynamic-fix-3.diff
|
||||
Patch21: %{name}-ppc64-reinit.diff
|
||||
Patch22: %{name}-increase-kernel-text-size.diff
|
||||
Patch0: %{name}-no-vga-output.diff
|
||||
Patch1: %{name}-xen-static.diff
|
||||
Patch2: %{name}-increase-kernel-text-size.diff
|
||||
Url: http://ftp.kernel.org/pub/linux/kernel/people/horms/kexec-tools/
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||
#!BuildIgnore: fop
|
||||
@ -91,26 +71,6 @@ Authors:
|
||||
%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
|
||||
%patch18 -p1
|
||||
%patch19 -p1
|
||||
%patch20 -p1
|
||||
%patch21 -p1
|
||||
%patch22 -p1
|
||||
|
||||
%build
|
||||
# disable as-needed
|
||||
|
Loading…
Reference in New Issue
Block a user