From mboxrd@z Thu Jan 1 00:00:00 1970 Return-path: Received: from e23smtp02.au.ibm.com ([202.81.31.144]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1WCXfL-0006cP-63 for kexec@lists.infradead.org; Sun, 09 Feb 2014 16:55:36 +0000 Received: from /spool/local by e23smtp02.au.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 10 Feb 2014 02:55:08 +1000 Received: from d23relay03.au.ibm.com (d23relay03.au.ibm.com [9.190.235.21]) by d23dlp02.au.ibm.com (Postfix) with ESMTP id A4E462BB0052 for ; Mon, 10 Feb 2014 03:55:04 +1100 (EST) Received: from d23av04.au.ibm.com (d23av04.au.ibm.com [9.190.235.139]) by d23relay03.au.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id s19Gsnjn8061260 for ; Mon, 10 Feb 2014 03:54:51 +1100 Received: from d23av04.au.ibm.com (localhost [127.0.0.1]) by d23av04.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id s19Gt25a025853 for ; Mon, 10 Feb 2014 03:55:02 +1100 Subject: [PATCH] kexec/ppc64: Fix up ELF header and dt for PowerNV platform. From: Mahesh J Salgaonkar Date: Sun, 09 Feb 2014 22:24:59 +0530 Message-ID: <20140209165459.29541.26032.stgit@mars> MIME-Version: 1.0 List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "kexec" Errors-To: kexec-bounces+dwmw2=twosheds.infradead.org@lists.infradead.org To: Simon Horman , Kexec-ml Cc: Benjamin Herrenschmidt , Laurent Dufour From: Mahesh Salgaonkar On PowerNV platform, OPAL region is overlapped with crashkernel, need to create ELF Program header for the overlapped memory. The changes are similar to the way RTAS region was handled. Signed-off-by: Mahesh Salgaonkar --- kexec/arch/ppc/crashdump-powerpc.h | 2 ++ kexec/arch/ppc64/crashdump-ppc64.c | 28 +++++++++++++++++++++++ kexec/arch/ppc64/crashdump-ppc64.h | 2 ++ kexec/arch/ppc64/kexec-ppc64.c | 44 +++++++++++++++++++++++++++++++++++- kexec/fs2dt.c | 4 +++ 5 files changed, 79 insertions(+), 1 deletion(-) diff --git a/kexec/arch/ppc/crashdump-powerpc.h b/kexec/arch/ppc/crashdump-powerpc.h index efdc7e3..9b9b01e 100644 --- a/kexec/arch/ppc/crashdump-powerpc.h +++ b/kexec/arch/ppc/crashdump-powerpc.h @@ -40,6 +40,8 @@ extern unsigned long long crash_base; extern unsigned long long crash_size; extern unsigned int rtas_base; extern unsigned int rtas_size; +extern uint64_t opal_base; +extern uint64_t opal_size; extern uint64_t memory_limit; #endif /* CRASHDUMP_POWERPC_H */ diff --git a/kexec/arch/ppc64/crashdump-ppc64.c b/kexec/arch/ppc64/crashdump-ppc64.c index c0d575d..00a0e63 100644 --- a/kexec/arch/ppc64/crashdump-ppc64.c +++ b/kexec/arch/ppc64/crashdump-ppc64.c @@ -294,6 +294,34 @@ static int get_crash_memory_ranges(struct memory_range **range, int *ranges) crash_memory_range[memory_ranges++].end = cend; } + /* + * If OPAL region is overlapped with crashkernel, need to create ELF + * Program header for the overlapped memory. + */ + if (crash_base < opal_base + opal_size && + opal_base < crash_base + crash_size) { + page_size = getpagesize(); + cstart = opal_base; + cend = opal_base + opal_size; + if (cstart < crash_base) + cstart = crash_base; + if (cend > crash_base + crash_size) + cend = crash_base + crash_size; + /* + * The opal section created here is formed by reading opal-base + * and opal-size from /proc/device-tree/ibm,opal. Unfortunately + * opal-size is not required to be a multiple of PAGE_SIZE + * The remainder of the page it ends on is just garbage, and is + * safe to read, its just not accounted in opal-size. Since + * we're creating an elf section here though, lets round it up + * to the next page size boundary though, so makedumpfile can + * read it safely without going south on us. + */ + cend = _ALIGN(cend, page_size); + + crash_memory_range[memory_ranges].start = cstart; + crash_memory_range[memory_ranges++].end = cend; + } *range = crash_memory_range; *ranges = memory_ranges; diff --git a/kexec/arch/ppc64/crashdump-ppc64.h b/kexec/arch/ppc64/crashdump-ppc64.h index 001be3a..d654c6b 100644 --- a/kexec/arch/ppc64/crashdump-ppc64.h +++ b/kexec/arch/ppc64/crashdump-ppc64.h @@ -31,6 +31,8 @@ extern uint64_t crash_size; extern uint64_t memory_limit; extern unsigned int rtas_base; extern unsigned int rtas_size; +extern uint64_t opal_base; +extern uint64_t opal_size; uint64_t lmb_size; unsigned int num_of_lmbs; diff --git a/kexec/arch/ppc64/kexec-ppc64.c b/kexec/arch/ppc64/kexec-ppc64.c index 49b291d..5956836 100644 --- a/kexec/arch/ppc64/kexec-ppc64.c +++ b/kexec/arch/ppc64/kexec-ppc64.c @@ -43,6 +43,7 @@ uint64_t memory_limit; static int nr_memory_ranges, nr_exclude_ranges; uint64_t crash_base, crash_size; unsigned int rtas_base, rtas_size; +uint64_t opal_base, opal_size; int max_memory_ranges; static void cleanup_memory_ranges(void) @@ -343,7 +344,8 @@ static int get_devtree_details(unsigned long kexec_flags) 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,opal", 8)) continue; strcpy(fname, device_tree); strcat(fname, dentry->d_name); @@ -575,6 +577,46 @@ static int get_devtree_details(unsigned long kexec_flags) add_usable_mem_rgns(rtas_base, rtas_size); } /* rtas */ + if (strncmp(dentry->d_name, "ibm,opal", 8) == 0) { + strcat(fname, "/opal-base-address"); + file = fopen(fname, "r"); + if (file == NULL) { + perror(fname); + goto error_opencdir; + } + if (fread(&opal_base, sizeof(uint64_t), 1, file) != 1) { + perror(fname); + goto error_openfile; + } + opal_base = be64_to_cpu(opal_base); + fclose(file); + + memset(fname, 0, sizeof(fname)); + strcpy(fname, device_tree); + strcat(fname, dentry->d_name); + strcat(fname, "/opal-runtime-size"); + file = fopen(fname, "r"); + if (file == NULL) { + perror(fname); + goto error_opencdir; + } + if (fread(&opal_size, sizeof(uint64_t), 1, file) != 1) { + perror(fname); + goto error_openfile; + } + fclose(file); + closedir(cdir); + opal_size = be64_to_cpu(opal_size); + /* Add OPAL to exclude_range */ + exclude_range[i].start = opal_base; + exclude_range[i].end = opal_base + opal_size; + i++; + if (i >= max_memory_ranges) + realloc_memory_ranges(); + if (kexec_flags & KEXEC_ON_CRASH) + add_usable_mem_rgns(opal_base, opal_size); + } /* ibm,opal */ + if (!strncmp(dentry->d_name, "memory@", 7) || !strcmp(dentry->d_name, "memory")) { strcat(fname, "/reg"); diff --git a/kexec/fs2dt.c b/kexec/fs2dt.c index 5e6b98d..44510cb 100644 --- a/kexec/fs2dt.c +++ b/kexec/fs2dt.c @@ -113,6 +113,10 @@ static void checkprop(char *name, unsigned *data, int len) die("unrecoverable error: no property data"); else if (!strcmp(name, "linux,rtas-base")) base = be32_to_cpu(*data); + else if (!strcmp(name, "opal-base-address")) + base = be64_to_cpu(*(unsigned long long *)data); + else if (!strcmp(name, "opal-runtime-size")) + size = be64_to_cpu(*(unsigned long long *)data); else if (!strcmp(name, "linux,tce-base")) base = be64_to_cpu(*(unsigned long long *) data); else if (!strcmp(name, "rtas-size") || _______________________________________________ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec