diff options
author | Matthew McClintock <msm@freescale.com> | 2010-07-20 23:42:59 -0500 |
---|---|---|
committer | Simon Horman <horms@verge.net.au> | 2010-07-29 18:02:18 +0900 |
commit | 8b5809f1b09aff3e4cbd0715e14416f11cf449b8 (patch) | |
tree | ad1de2b66770aa9832aa9905c36e33a0d578a6d8 | |
parent | 655703ffbcb7a3387994dce29b09b5f9fe79042c (diff) |
Fix case where phys_addr_t != unsigned long when reading proc entries
On some actitectures the physical memory can be 64 bits, therefore
the code that reads proc entries needs to take into account it could
read either a 32 bit or 64bit value for the physical addresses.
Signed-off-by: Matthew McClintock <msm@freescale.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
-rw-r--r-- | kexec/arch/ppc/kexec-elf-ppc.c | 1 | ||||
-rw-r--r-- | kexec/arch/ppc/kexec-ppc.c | 198 |
2 files changed, 114 insertions, 85 deletions
diff --git a/kexec/arch/ppc/kexec-elf-ppc.c b/kexec/arch/ppc/kexec-elf-ppc.c index d155bde..ab2d343 100644 --- a/kexec/arch/ppc/kexec-elf-ppc.c +++ b/kexec/arch/ppc/kexec-elf-ppc.c @@ -32,7 +32,6 @@ static const int probe_debug = 0; -unsigned long long initrd_base, initrd_size; unsigned char reuse_initrd; const char *ramdisk; int create_flatten_tree(struct kexec_info *, unsigned char **, unsigned long *, diff --git a/kexec/arch/ppc/kexec-ppc.c b/kexec/arch/ppc/kexec-ppc.c index ca33303..e1547a8 100644 --- a/kexec/arch/ppc/kexec-ppc.c +++ b/kexec/arch/ppc/kexec-ppc.c @@ -28,6 +28,7 @@ uint64_t rmo_top; unsigned long long crash_base, crash_size; +unsigned long long initrd_base, initrd_size; unsigned int rtas_base, rtas_size; int max_memory_ranges; @@ -262,14 +263,14 @@ static int get_base_ranges(void) } } - if (n == 8) { + if (n == sizeof(uint32_t) * 2) { base_memory_range[local_memory_ranges].start = ((uint32_t *)buf)[0]; base_memory_range[local_memory_ranges].end = base_memory_range[local_memory_ranges].start + ((uint32_t *)buf)[1]; } - else if (n == 16) { + else if (n == sizeof(uint64_t) * 2) { base_memory_range[local_memory_ranges].start = ((uint64_t *)buf)[0]; base_memory_range[local_memory_ranges].end = @@ -317,9 +318,7 @@ static int get_devtree_details(unsigned long kexec_flags) DIR *dir, *cdir; FILE *file; struct dirent *dentry; - struct stat fstat; int n, i = 0; - unsigned long tmp_long; if ((dir = opendir(device_tree)) == NULL) { perror(device_tree); @@ -349,12 +348,18 @@ static int get_devtree_details(unsigned long kexec_flags) perror(fname); goto error_opencdir; } - if (fread(&tmp_long, sizeof(unsigned long), 1, file) - != 1) { + if ((n = fread(buf, 1, MAXBYTES, file)) < 0) { perror(fname); goto error_openfile; } - kernel_end = tmp_long; + if (n == sizeof(uint32_t)) { + kernel_end = ((uint32_t *)buf)[0]; + } else if (n == sizeof(uint64_t)) { + kernel_end = ((uint64_t *)buf)[0]; + } else { + fprintf(stderr, "%s node has invalid size: %d\n", fname, n); + goto error_openfile; + } fclose(file); /* Add kernel memory to exclude_range */ @@ -364,37 +369,50 @@ static int get_devtree_details(unsigned long kexec_flags) if (i >= max_memory_ranges) realloc_memory_ranges(); memset(fname, 0, sizeof(fname)); - strcpy(fname, device_tree); - strcat(fname, dentry->d_name); - strcat(fname, "/linux,crashkernel-base"); + sprintf(fname, "%s%s%s", + device_tree, dentry->d_name, + "/linux,crashkernel-base"); file = fopen(fname, "r"); if (!file) { perror(fname); goto error_opencdir; } - if (fread(&tmp_long, sizeof(unsigned long), 1, - file) != 1) { + if ((n = fread(buf, 1, MAXBYTES, file)) < 0) { perror(fname); goto error_openfile; } - crash_base = tmp_long; + if (n == sizeof(uint32_t)) { + crash_base = ((uint32_t *)buf)[0]; + } else if (n == sizeof(uint64_t)) { + crash_base = ((uint64_t *)buf)[0]; + } else { + fprintf(stderr, "%s node has invalid size: %d\n", fname, n); + goto error_openfile; + } fclose(file); memset(fname, 0, sizeof(fname)); - strcpy(fname, device_tree); - strcat(fname, dentry->d_name); - strcat(fname, "/linux,crashkernel-size"); + sprintf(fname, "%s%s%s", + device_tree, dentry->d_name, + "/linux,crashkernel-size"); file = fopen(fname, "r"); if (!file) { perror(fname); goto error_opencdir; } - if (fread(&tmp_long, sizeof(unsigned long), 1, - file) != 1) { + if ((n = fread(buf, 1, MAXBYTES, file)) < 0) { perror(fname); goto error_openfile; } - crash_size = tmp_long; + if (n == sizeof(uint32_t)) { + crash_size = ((uint32_t *)buf)[0]; + } else if (n == sizeof(uint64_t)) { + crash_size = ((uint64_t *)buf)[0]; + } else { + fprintf(stderr, "%s node has invalid size: %d\n", fname, n); + goto error_openfile; + } + fclose(file); if (crash_base > mem_min) mem_min = crash_base; @@ -405,10 +423,74 @@ static int get_devtree_details(unsigned long kexec_flags) reserve(KDUMP_BACKUP_LIMIT, crash_base-KDUMP_BACKUP_LIMIT); } + /* reserve the initrd_start and end locations. */ memset(fname, 0, sizeof(fname)); - strcpy(fname, device_tree); - strcat(fname, dentry->d_name); - strcat(fname, "/linux,htab-base"); + sprintf(fname, "%s%s%s", + device_tree, dentry->d_name, + "/linux,initrd-start"); + file = fopen(fname, "r"); + if (!file) { + errno = 0; + initrd_start = 0; + } else { + if ((n = fread(buf, 1, MAXBYTES, file)) < 0) { + perror(fname); + goto error_openfile; + } + if (n == sizeof(uint32_t)) { + initrd_start = ((uint32_t *)buf)[0]; + } else if (n == sizeof(uint64_t)) { + initrd_start = ((uint64_t *)buf)[0]; + } else { + fprintf(stderr, "%s node has invalid size: %d\n", fname, n); + goto error_openfile; + } + fclose(file); + } + + memset(fname, 0, sizeof(fname)); + sprintf(fname, "%s%s%s", + device_tree, dentry->d_name, + "/linux,initrd-end"); + file = fopen(fname, "r"); + if (!file) { + errno = 0; + initrd_end = 0; + } else { + if ((n = fread(buf, 1, MAXBYTES, file)) < 0) { + perror(fname); + goto error_openfile; + } + if (n == sizeof(uint32_t)) { + initrd_end = ((uint32_t *)buf)[0]; + } else if (n == sizeof(uint64_t)) { + initrd_end = ((uint64_t *)buf)[0]; + } else { + fprintf(stderr, "%s node has invalid size: %d\n", fname, n); + goto error_openfile; + } + fclose(file); + } + + if ((initrd_end - initrd_start) != 0 ) { + initrd_base = initrd_start; + initrd_size = initrd_end - initrd_start + 1; + } + + if (reuse_initrd) { + /* Add initrd address to exclude_range */ + exclude_range[i].start = initrd_start; + exclude_range[i].end = initrd_end; + i++; + if (i >= max_memory_ranges) + realloc_memory_ranges(); + } + + /* HTAB */ + memset(fname, 0, sizeof(fname)); + sprintf(fname, "%s%s%s", + device_tree, dentry->d_name, + "/linux,htab-base"); file = fopen(fname, "r"); if (!file) { closedir(cdir); @@ -426,9 +508,9 @@ static int get_devtree_details(unsigned long kexec_flags) goto error_openfile; } memset(fname, 0, sizeof(fname)); - strcpy(fname, device_tree); - strcat(fname, dentry->d_name); - strcat(fname, "/linux,htab-size"); + sprintf(fname, "%s%s%s", + device_tree, dentry->d_name, + "/linux,htab-size"); file = fopen(fname, "r"); if (!file) { perror(fname); @@ -446,59 +528,7 @@ static int get_devtree_details(unsigned long kexec_flags) if (i >= max_memory_ranges) realloc_memory_ranges(); - /* reserve the initrd_start and end locations. */ - if (reuse_initrd) { - memset(fname, 0, sizeof(fname)); - strcpy(fname, device_tree); - strcat(fname, dentry->d_name); - strcat(fname, "/linux,initrd-start"); - file = fopen(fname, "r"); - if (!file) { - perror(fname); - goto error_opencdir; - } - /* check for 4 and 8 byte initrd offset sizes */ - if (stat(fname, &fstat) != 0) { - perror(fname); - goto error_openfile; - } - if (fread(&initrd_start, fstat.st_size, 1, file) - != 1) { - perror(fname); - goto error_openfile; - } - fclose(file); - - memset(fname, 0, sizeof(fname)); - strcpy(fname, device_tree); - strcat(fname, dentry->d_name); - strcat(fname, "/linux,initrd-end"); - file = fopen(fname, "r"); - if (!file) { - perror(fname); - goto error_opencdir; - } - /* check for 4 and 8 byte initrd offset sizes */ - if (stat(fname, &fstat) != 0) { - perror(fname); - goto error_openfile; - } - if (fread(&initrd_end, fstat.st_size, 1, file) - != 1) { - perror(fname); - goto error_openfile; - } - fclose(file); - - /* Add initrd address to exclude_range */ - exclude_range[i].start = initrd_start; - exclude_range[i].end = initrd_end; - i++; - if (i >= max_memory_ranges) - realloc_memory_ranges(); - } } /* chosen */ - if (strncmp(dentry->d_name, "rtas", 4) == 0) { strcat(fname, "/linux,rtas-base"); if ((file = fopen(fname, "r")) == NULL) { @@ -511,9 +541,9 @@ static int get_devtree_details(unsigned long kexec_flags) goto error_openfile; } memset(fname, 0, sizeof(fname)); - strcpy(fname, device_tree); - strcat(fname, dentry->d_name); - strcat(fname, "/rtas-size"); + sprintf(fname, "%s%s%s", + device_tree, dentry->d_name, + "/linux,rtas-size"); if ((file = fopen(fname, "r")) == NULL) { perror(fname); goto error_opencdir; @@ -543,7 +573,7 @@ static int get_devtree_details(unsigned long kexec_flags) perror(fname); goto error_openfile; } - if (n == 8) { + if (n == sizeof(uint64_t)) { rmo_base = ((uint32_t *)buf)[0]; rmo_top = rmo_base + ((uint32_t *)buf)[1]; } else if (n == 16) { @@ -580,9 +610,9 @@ static int get_devtree_details(unsigned long kexec_flags) return -1; } memset(fname, 0, sizeof(fname)); - strcpy(fname, device_tree); - strcat(fname, dentry->d_name); - strcat(fname, "/linux,tce-size"); + sprintf(fname, "%s%s%s", + device_tree, dentry->d_name, + "/linux,tce-size"); file = fopen(fname, "r"); if (!file) { perror(fname); |