Inter-revision diff: patch 5

Comparing v8 (message) to v10 (message)

--- v8
+++ v10
@@ -1,902 +1,437 @@
-The kexec_file_load system call needs to relocate the purgatory, so
-factor out the module relocation code so that it can be shared.
+Commit 2965faa5e03d ("kexec: split kexec_load syscall from kexec core
+code") introduced CONFIG_KEXEC_CORE so that CONFIG_KEXEC means whether
+the kexec_load system call should be compiled-in and CONFIG_KEXEC_FILE
+means whether the kexec_file_load system call should be compiled-in.
+These options can be set independently from each other.
 
-This patch's purpose is to move the ELF relocation logic from
-apply_relocate_add to elf_util_64.c with as few changes as
-possible. The following changes were needed:
-
-To avoid having module-specific code in a general purpose utility
-function, struct elf_info was created to contain the information
-needed for ELF binaries manipulation.
-
-my_r2, stub_for_addr and create_stub were changed to use it instead of
-having to receive a struct module, since they are called from
-elf64_apply_relocate_add.
-
-local_entry_offset and squash_toc_save_inst were only used by
-apply_rellocate_add, so they were moved to elf_util_64.c as well.
+Since until now powerpc only supported kexec_load, CONFIG_KEXEC and
+CONFIG_KEXEC_CORE were synonyms. That is not the case anymore, so we
+need to make a distinction. Almost all places where CONFIG_KEXEC was
+being used should be using CONFIG_KEXEC_CORE instead, since
+kexec_file_load also needs that code compiled in.
 
 Signed-off-by: Thiago Jung Bauermann <bauerman@linux.vnet.ibm.com>
 ---
- arch/powerpc/include/asm/elf_util.h |  70 ++++++++
- arch/powerpc/include/asm/module.h   |  14 +-
- arch/powerpc/kernel/Makefile        |   4 +
- arch/powerpc/kernel/elf_util_64.c   | 269 +++++++++++++++++++++++++++++++
- arch/powerpc/kernel/module_64.c     | 312 ++++--------------------------------
- 5 files changed, 386 insertions(+), 283 deletions(-)
+ arch/powerpc/Kconfig                          | 2 +-
+ arch/powerpc/include/asm/debug.h              | 2 +-
+ arch/powerpc/include/asm/kexec.h              | 6 +++---
+ arch/powerpc/include/asm/machdep.h            | 4 ++--
+ arch/powerpc/include/asm/smp.h                | 2 +-
+ arch/powerpc/kernel/Makefile                  | 4 ++--
+ arch/powerpc/kernel/head_64.S                 | 2 +-
+ arch/powerpc/kernel/misc_32.S                 | 2 +-
+ arch/powerpc/kernel/misc_64.S                 | 6 +++---
+ arch/powerpc/kernel/prom.c                    | 2 +-
+ arch/powerpc/kernel/setup_64.c                | 4 ++--
+ arch/powerpc/kernel/smp.c                     | 6 +++---
+ arch/powerpc/kernel/traps.c                   | 2 +-
+ arch/powerpc/platforms/85xx/corenet_generic.c | 2 +-
+ arch/powerpc/platforms/85xx/smp.c             | 8 ++++----
+ arch/powerpc/platforms/cell/spu_base.c        | 2 +-
+ arch/powerpc/platforms/powernv/setup.c        | 6 +++---
+ arch/powerpc/platforms/ps3/setup.c            | 4 ++--
+ arch/powerpc/platforms/pseries/Makefile       | 2 +-
+ arch/powerpc/platforms/pseries/setup.c        | 4 ++--
+ 20 files changed, 36 insertions(+), 36 deletions(-)
 
-diff --git a/arch/powerpc/include/asm/elf_util.h b/arch/powerpc/include/asm/elf_util.h
-new file mode 100644
-index 000000000000..37372559fe62
---- /dev/null
-+++ b/arch/powerpc/include/asm/elf_util.h
-@@ -0,0 +1,70 @@
-+/*
-+ * Utility functions to work with ELF files.
-+ *
-+ * Copyright (C) 2016, IBM Corporation
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2, or (at your option)
-+ * any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#ifndef _ASM_POWERPC_ELF_UTIL_H
-+#define _ASM_POWERPC_ELF_UTIL_H
-+
-+#include <linux/elf.h>
-+
-+struct elf_info {
-+	struct elf_shdr *sechdrs;
-+
-+	/* Index of stubs section. */
-+	unsigned int stubs_section;
-+	/* Index of TOC section. */
-+	unsigned int toc_section;
-+};
-+
-+#ifdef __powerpc64__
-+#ifdef PPC64_ELF_ABI_v2
-+
-+/* An address is simply the address of the function. */
-+typedef unsigned long func_desc_t;
-+#else
-+
-+/* An address is address of the OPD entry, which contains address of fn. */
-+typedef struct ppc64_opd_entry func_desc_t;
-+#endif /* PPC64_ELF_ABI_v2 */
-+
-+/* Like PPC32, we need little trampolines to do > 24-bit jumps (into
-+   the kernel itself).  But on PPC64, these need to be used for every
-+   jump, actually, to reset r2 (TOC+0x8000). */
-+struct ppc64_stub_entry
-+{
-+	/* 28 byte jump instruction sequence (7 instructions). We only
-+	 * need 6 instructions on ABIv2 but we always allocate 7 so
-+	 * so we don't have to modify the trampoline load instruction. */
-+	u32 jump[7];
-+	/* Used by ftrace to identify stubs */
-+	u32 magic;
-+	/* Data for the above code */
-+	func_desc_t funcdata;
-+};
-+#endif
-+
-+/* r2 is the TOC pointer: it actually points 0x8000 into the TOC (this
-+   gives the value maximum span in an instruction which uses a signed
-+   offset) */
-+static inline unsigned long my_r2(const struct elf_info *elf_info)
-+{
-+	return elf_info->sechdrs[elf_info->toc_section].sh_addr + 0x8000;
-+}
-+
-+int elf64_apply_relocate_add(const struct elf_info *elf_info,
-+			     const char *strtab, unsigned int symindex,
-+			     unsigned int relsec, const char *obj_name);
-+
-+#endif /* _ASM_POWERPC_ELF_UTIL_H */
-diff --git a/arch/powerpc/include/asm/module.h b/arch/powerpc/include/asm/module.h
-index cd4ffd86765f..f2073115d518 100644
---- a/arch/powerpc/include/asm/module.h
-+++ b/arch/powerpc/include/asm/module.h
-@@ -12,7 +12,14 @@
- #include <linux/list.h>
- #include <asm/bug.h>
- #include <asm-generic/module.h>
-+#include <asm/elf_util.h>
- 
-+/* Both low and high 16 bits are added as SIGNED additions, so if low
-+   16 bits has high bit set, high 16 bits must be adjusted.  These
-+   macros do that (stolen from binutils). */
-+#define PPC_LO(v) ((v) & 0xffff)
-+#define PPC_HI(v) (((v) >> 16) & 0xffff)
-+#define PPC_HA(v) PPC_HI ((v) + 0x8000)
- 
- #ifndef __powerpc64__
+diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
+index 65fba4c34cd7..6cb59c6e5ba4 100644
+--- a/arch/powerpc/Kconfig
++++ b/arch/powerpc/Kconfig
+@@ -489,7 +489,7 @@ config CRASH_DUMP
+ 
+ config FA_DUMP
+ 	bool "Firmware-assisted dump"
+-	depends on PPC64 && PPC_RTAS && CRASH_DUMP && KEXEC
++	depends on PPC64 && PPC_RTAS && CRASH_DUMP && KEXEC_CORE
+ 	help
+ 	  A robust mechanism to get reliable kernel crash dump with
+ 	  assistance from firmware. This approach does not use kexec,
+diff --git a/arch/powerpc/include/asm/debug.h b/arch/powerpc/include/asm/debug.h
+index a954e4975049..86308f177f2d 100644
+--- a/arch/powerpc/include/asm/debug.h
++++ b/arch/powerpc/include/asm/debug.h
+@@ -10,7 +10,7 @@ struct pt_regs;
+ 
+ extern struct dentry *powerpc_debugfs_root;
+ 
+-#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
++#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC_CORE)
+ 
+ extern int (*__debugger)(struct pt_regs *regs);
+ extern int (*__debugger_ipi)(struct pt_regs *regs);
+diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h
+index a46f5f45570c..eca2f975bf44 100644
+--- a/arch/powerpc/include/asm/kexec.h
++++ b/arch/powerpc/include/asm/kexec.h
+@@ -53,7 +53,7 @@
+ 
+ typedef void (*crash_shutdown_t)(void);
+ 
+-#ifdef CONFIG_KEXEC
++#ifdef CONFIG_KEXEC_CORE
+ 
  /*
-@@ -33,8 +40,7 @@ struct ppc_plt_entry {
- 
- struct mod_arch_specific {
- #ifdef __powerpc64__
--	unsigned int stubs_section;	/* Index of stubs section in module */
--	unsigned int toc_section;	/* What section is the TOC? */
-+	struct elf_info elf_info;
- 	bool toc_fixed;			/* Have we fixed up .TOC.? */
- #ifdef CONFIG_DYNAMIC_FTRACE
- 	unsigned long toc;
-@@ -90,6 +96,10 @@ static inline int module_finalize_ftrace(struct module *mod, const Elf_Shdr *sec
- }
- #endif
- 
-+unsigned long stub_for_addr(const struct elf_info *elf_info, unsigned long addr,
-+			    const char *obj_name);
-+int restore_r2(u32 *instruction, const char *obj_name);
-+
- struct exception_table_entry;
- void sort_ex_table(struct exception_table_entry *start,
- 		   struct exception_table_entry *finish);
+  * This function is responsible for capturing register states if coming
+@@ -91,7 +91,7 @@ static inline bool kdump_in_progress(void)
+ 	return crashing_cpu >= 0;
+ }
+ 
+-#else /* !CONFIG_KEXEC */
++#else /* !CONFIG_KEXEC_CORE */
+ static inline void crash_kexec_secondary(struct pt_regs *regs) { }
+ 
+ static inline int overlaps_crashkernel(unsigned long start, unsigned long size)
+@@ -116,7 +116,7 @@ static inline bool kdump_in_progress(void)
+ 	return false;
+ }
+ 
+-#endif /* CONFIG_KEXEC */
++#endif /* CONFIG_KEXEC_CORE */
+ #endif /* ! __ASSEMBLY__ */
+ #endif /* __KERNEL__ */
+ #endif /* _ASM_POWERPC_KEXEC_H */
+diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
+index e02cbc6a6c70..5011b69107a7 100644
+--- a/arch/powerpc/include/asm/machdep.h
++++ b/arch/powerpc/include/asm/machdep.h
+@@ -183,7 +183,7 @@ struct machdep_calls {
+ 	 */
+ 	void (*machine_shutdown)(void);
+ 
+-#ifdef CONFIG_KEXEC
++#ifdef CONFIG_KEXEC_CORE
+ 	void (*kexec_cpu_down)(int crash_shutdown, int secondary);
+ 
+ 	/* Called to do what every setup is needed on image and the
+@@ -198,7 +198,7 @@ struct machdep_calls {
+ 	 * no return.
+ 	 */
+ 	void (*machine_kexec)(struct kimage *image);
+-#endif /* CONFIG_KEXEC */
++#endif /* CONFIG_KEXEC_CORE */
+ 
+ #ifdef CONFIG_SUSPEND
+ 	/* These are called to disable and enable, respectively, IRQs when
+diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h
+index 0d02c11dc331..32db16d2e7ad 100644
+--- a/arch/powerpc/include/asm/smp.h
++++ b/arch/powerpc/include/asm/smp.h
+@@ -176,7 +176,7 @@ static inline void set_hard_smp_processor_id(int cpu, int phys)
+ #endif /* !CONFIG_SMP */
+ #endif /* !CONFIG_PPC64 */
+ 
+-#if defined(CONFIG_PPC64) && (defined(CONFIG_SMP) || defined(CONFIG_KEXEC))
++#if defined(CONFIG_PPC64) && (defined(CONFIG_SMP) || defined(CONFIG_KEXEC_CORE))
+ extern void smp_release_cpus(void);
+ #else
+ static inline void smp_release_cpus(void) { };
 diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
-index 79a9821cf129..4ff806f6f3fd 100644
+index 1925341dbb9c..22534a56c914 100644
 --- a/arch/powerpc/kernel/Makefile
 +++ b/arch/powerpc/kernel/Makefile
-@@ -123,6 +123,10 @@ ifneq ($(CONFIG_PPC_INDIRECT_PIO),y)
- obj-y				+= iomap.o
+@@ -107,7 +107,7 @@ pci64-$(CONFIG_PPC64)		+= pci_dn.o pci-hotplug.o isa-bridge.o
+ obj-$(CONFIG_PCI)		+= pci_$(BITS).o $(pci64-y) \
+ 				   pci-common.o pci_of_scan.o
+ obj-$(CONFIG_PCI_MSI)		+= msi.o
+-obj-$(CONFIG_KEXEC)		+= machine_kexec.o crash.o \
++obj-$(CONFIG_KEXEC_CORE)	+= machine_kexec.o crash.o \
+ 				   machine_kexec_$(BITS).o
+ obj-$(CONFIG_AUDIT)		+= audit.o
+ obj64-$(CONFIG_AUDIT)		+= compat_audit.o
+@@ -128,7 +128,7 @@ obj64-$(CONFIG_PPC_TRANSACTIONAL_MEM)	+= tm.o
+ obj-$(CONFIG_PPC64)		+= $(obj64-y)
+ obj-$(CONFIG_PPC32)		+= $(obj32-y)
+ 
+-ifneq ($(CONFIG_XMON)$(CONFIG_KEXEC),)
++ifneq ($(CONFIG_XMON)$(CONFIG_KEXEC_CORE),)
+ obj-y				+= ppc_save_regs.o
  endif
  
-+ifeq ($(CONFIG_MODULES)$(CONFIG_WORD_SIZE),y64)
-+obj-y				+= elf_util_64.o
-+endif
-+
- obj64-$(CONFIG_PPC_TRANSACTIONAL_MEM)	+= tm.o
- 
- obj-$(CONFIG_PPC64)		+= $(obj64-y)
-diff --git a/arch/powerpc/kernel/elf_util_64.c b/arch/powerpc/kernel/elf_util_64.c
-new file mode 100644
-index 000000000000..decad2c34f38
---- /dev/null
-+++ b/arch/powerpc/kernel/elf_util_64.c
-@@ -0,0 +1,269 @@
-+/*
-+ * Utility functions to work with ELF files.
-+ *
-+ * Copyright (C) 2016, IBM Corporation
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2, or (at your option)
-+ * any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#include <asm/ppc-opcode.h>
-+#include <asm/elf_util.h>
-+
-+/*
-+ * We just need to use the functions defined in <asm/module.h>, so just declare
-+ * struct module here and avoid having to import <linux/module.h>.
-+ */
-+struct module;
-+#include <asm/module.h>
-+
-+#ifdef PPC64_ELF_ABI_v2
-+/* PowerPC64 specific values for the Elf64_Sym st_other field.  */
-+#define STO_PPC64_LOCAL_BIT	5
-+#define STO_PPC64_LOCAL_MASK	(7 << STO_PPC64_LOCAL_BIT)
-+#define PPC64_LOCAL_ENTRY_OFFSET(other)					\
-+ (((1 << (((other) & STO_PPC64_LOCAL_MASK) >> STO_PPC64_LOCAL_BIT)) >> 2) << 2)
-+
-+static unsigned int local_entry_offset(const Elf64_Sym *sym)
-+{
-+	/* sym->st_other indicates offset to local entry point
-+	 * (otherwise it will assume r12 is the address of the start
-+	 * of function and try to derive r2 from it). */
-+	return PPC64_LOCAL_ENTRY_OFFSET(sym->st_other);
-+}
-+#else
-+static unsigned int local_entry_offset(const Elf64_Sym *sym)
-+{
-+	return 0;
-+}
-+#endif
-+
-+#ifdef CC_USING_MPROFILE_KERNEL
-+/*
-+ * In case of _mcount calls, do not save the current callee's TOC (in r2) into
-+ * the original caller's stack frame. If we did we would clobber the saved TOC
-+ * value of the original caller.
-+ */
-+static void squash_toc_save_inst(const char *name, unsigned long addr)
-+{
-+	struct ppc64_stub_entry *stub = (struct ppc64_stub_entry *)addr;
-+
-+	/* Only for calls to _mcount */
-+	if (strcmp("_mcount", name) != 0)
-+		return;
-+
-+	stub->jump[2] = PPC_INST_NOP;
-+}
-+#else
-+static void squash_toc_save_inst(const char *name, unsigned long addr) { }
-+#endif
-+
-+/**
-+ * elf64_apply_relocate_add - apply 64 bit RELA relocations
-+ * @elf_info:		Support information for the ELF binary being relocated.
-+ * @strtab:		String table for the associated symbol table.
-+ * @symindex:		Section header index for the associated symbol table.
-+ * @relsec:		Section header index for the relocations to apply.
-+ * @obj_name:		The name of the ELF binary, for information messages.
-+ */
-+int elf64_apply_relocate_add(const struct elf_info *elf_info,
-+			     const char *strtab, unsigned int symindex,
-+			     unsigned int relsec, const char *obj_name)
-+{
-+	unsigned int i;
-+	Elf64_Shdr *sechdrs = elf_info->sechdrs;
-+	Elf64_Rela *rela = (void *)sechdrs[relsec].sh_addr;
-+	Elf64_Sym *sym;
-+	unsigned long *location;
-+	unsigned long value;
-+
-+
-+	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rela); i++) {
-+		/* This is where to make the change */
-+		location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
-+			+ rela[i].r_offset;
-+		/* This is the symbol it is referring to */
-+		sym = (Elf64_Sym *)sechdrs[symindex].sh_addr
-+			+ ELF64_R_SYM(rela[i].r_info);
-+
-+		pr_debug("RELOC at %p: %li-type as %s (0x%lx) + %li\n",
-+		       location, (long)ELF64_R_TYPE(rela[i].r_info),
-+		       strtab + sym->st_name, (unsigned long)sym->st_value,
-+		       (long)rela[i].r_addend);
-+
-+		/* `Everything is relative'. */
-+		value = sym->st_value + rela[i].r_addend;
-+
-+		switch (ELF64_R_TYPE(rela[i].r_info)) {
-+		case R_PPC64_ADDR32:
-+			/* Simply set it */
-+			*(u32 *)location = value;
-+			break;
-+
-+		case R_PPC64_ADDR64:
-+			/* Simply set it */
-+			*(unsigned long *)location = value;
-+			break;
-+
-+		case R_PPC64_TOC:
-+			*(unsigned long *)location = my_r2(elf_info);
-+			break;
-+
-+		case R_PPC64_TOC16:
-+			/* Subtract TOC pointer */
-+			value -= my_r2(elf_info);
-+			if (value + 0x8000 > 0xffff) {
-+				pr_err("%s: bad TOC16 relocation (0x%lx)\n",
-+				       obj_name, value);
-+				return -ENOEXEC;
-+			}
-+			*((uint16_t *) location)
-+				= (*((uint16_t *) location) & ~0xffff)
-+				| (value & 0xffff);
-+			break;
-+
-+		case R_PPC64_TOC16_LO:
-+			/* Subtract TOC pointer */
-+			value -= my_r2(elf_info);
-+			*((uint16_t *) location)
-+				= (*((uint16_t *) location) & ~0xffff)
-+				| (value & 0xffff);
-+			break;
-+
-+		case R_PPC64_TOC16_DS:
-+			/* Subtract TOC pointer */
-+			value -= my_r2(elf_info);
-+			if ((value & 3) != 0 || value + 0x8000 > 0xffff) {
-+				pr_err("%s: bad TOC16_DS relocation (0x%lx)\n",
-+				       obj_name, value);
-+				return -ENOEXEC;
-+			}
-+			*((uint16_t *) location)
-+				= (*((uint16_t *) location) & ~0xfffc)
-+				| (value & 0xfffc);
-+			break;
-+
-+		case R_PPC64_TOC16_LO_DS:
-+			/* Subtract TOC pointer */
-+			value -= my_r2(elf_info);
-+			if ((value & 3) != 0) {
-+				pr_err("%s: bad TOC16_LO_DS relocation (0x%lx)\n",
-+				       obj_name, value);
-+				return -ENOEXEC;
-+			}
-+			*((uint16_t *) location)
-+				= (*((uint16_t *) location) & ~0xfffc)
-+				| (value & 0xfffc);
-+			break;
-+
-+		case R_PPC64_TOC16_HA:
-+			/* Subtract TOC pointer */
-+			value -= my_r2(elf_info);
-+			value = ((value + 0x8000) >> 16);
-+			*((uint16_t *) location)
-+				= (*((uint16_t *) location) & ~0xffff)
-+				| (value & 0xffff);
-+			break;
-+
-+		case R_PPC_REL24:
-+			/* FIXME: Handle weak symbols here --RR */
-+			if (sym->st_shndx == SHN_UNDEF) {
-+				/* External: go via stub */
-+				value = stub_for_addr(elf_info, value, obj_name);
-+				if (!value)
-+					return -ENOENT;
-+				if (!restore_r2((u32 *)location + 1, obj_name))
-+					return -ENOEXEC;
-+
-+				squash_toc_save_inst(strtab + sym->st_name, value);
-+			} else
-+				value += local_entry_offset(sym);
-+
-+			/* Convert value to relative */
-+			value -= (unsigned long)location;
-+			if (value + 0x2000000 > 0x3ffffff || (value & 3) != 0){
-+				pr_err("%s: REL24 %li out of range!\n",
-+				       obj_name, (long int)value);
-+				return -ENOEXEC;
-+			}
-+
-+			/* Only replace bits 2 through 26 */
-+			*(uint32_t *)location
-+				= (*(uint32_t *)location & ~0x03fffffc)
-+				| (value & 0x03fffffc);
-+			break;
-+
-+		case R_PPC64_REL64:
-+			/* 64 bits relative (used by features fixups) */
-+			*location = value - (unsigned long)location;
-+			break;
-+
-+		case R_PPC64_TOCSAVE:
-+			/*
-+			 * Marker reloc indicates we don't have to save r2.
-+			 * That would only save us one instruction, so ignore
-+			 * it.
-+			 */
-+			break;
-+
-+		case R_PPC64_ENTRY:
-+			/*
-+			 * Optimize ELFv2 large code model entry point if
-+			 * the TOC is within 2GB range of current location.
-+			 */
-+			value = my_r2(elf_info) - (unsigned long)location;
-+			if (value + 0x80008000 > 0xffffffff)
-+				break;
-+			/*
-+			 * Check for the large code model prolog sequence:
-+			 *	ld r2, ...(r12)
-+			 *	add r2, r2, r12
-+			 */
-+			if ((((uint32_t *)location)[0] & ~0xfffc)
-+			    != 0xe84c0000)
-+				break;
-+			if (((uint32_t *)location)[1] != 0x7c426214)
-+				break;
-+			/*
-+			 * If found, replace it with:
-+			 *	addis r2, r12, (.TOC.-func)@ha
-+			 *	addi r2, r12, (.TOC.-func)@l
-+			 */
-+			((uint32_t *)location)[0] = 0x3c4c0000 + PPC_HA(value);
-+			((uint32_t *)location)[1] = 0x38420000 + PPC_LO(value);
-+			break;
-+
-+		case R_PPC64_REL16_HA:
-+			/* Subtract location pointer */
-+			value -= (unsigned long)location;
-+			value = ((value + 0x8000) >> 16);
-+			*((uint16_t *) location)
-+				= (*((uint16_t *) location) & ~0xffff)
-+				| (value & 0xffff);
-+			break;
-+
-+		case R_PPC64_REL16_LO:
-+			/* Subtract location pointer */
-+			value -= (unsigned long)location;
-+			*((uint16_t *) location)
-+				= (*((uint16_t *) location) & ~0xffff)
-+				| (value & 0xffff);
-+			break;
-+
-+		default:
-+			pr_err("%s: Unknown ADD relocation: %lu\n",
-+			       obj_name,
-+			       (unsigned long)ELF64_R_TYPE(rela[i].r_info));
-+			return -ENOEXEC;
-+		}
-+	}
-+
-+	return 0;
-+}
-diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
-index 183368e008cf..b929560ecd5b 100644
---- a/arch/powerpc/kernel/module_64.c
-+++ b/arch/powerpc/kernel/module_64.c
-@@ -19,7 +19,7 @@
- #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
- 
- #include <linux/module.h>
--#include <linux/elf.h>
-+#include <asm/elf_util.h>
- #include <linux/moduleloader.h>
- #include <linux/err.h>
- #include <linux/vmalloc.h>
-@@ -43,9 +43,6 @@
- 
- #ifdef PPC64_ELF_ABI_v2
- 
--/* An address is simply the address of the function. */
--typedef unsigned long func_desc_t;
--
- static func_desc_t func_desc(unsigned long addr)
- {
- 	return addr;
-@@ -58,25 +55,8 @@ static unsigned long stub_func_addr(func_desc_t func)
- {
- 	return func;
- }
--
--/* PowerPC64 specific values for the Elf64_Sym st_other field.  */
--#define STO_PPC64_LOCAL_BIT	5
--#define STO_PPC64_LOCAL_MASK	(7 << STO_PPC64_LOCAL_BIT)
--#define PPC64_LOCAL_ENTRY_OFFSET(other)					\
-- (((1 << (((other) & STO_PPC64_LOCAL_MASK) >> STO_PPC64_LOCAL_BIT)) >> 2) << 2)
--
--static unsigned int local_entry_offset(const Elf64_Sym *sym)
--{
--	/* sym->st_other indicates offset to local entry point
--	 * (otherwise it will assume r12 is the address of the start
--	 * of function and try to derive r2 from it). */
--	return PPC64_LOCAL_ENTRY_OFFSET(sym->st_other);
--}
+diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
+index 04c546e20cc0..d3d482b628a6 100644
+--- a/arch/powerpc/kernel/head_64.S
++++ b/arch/powerpc/kernel/head_64.S
+@@ -153,7 +153,7 @@ __secondary_hold:
+ 	cmpdi	0,r12,0
+ 	beq	100b
+ 
+-#if defined(CONFIG_SMP) || defined(CONFIG_KEXEC)
++#if defined(CONFIG_SMP) || defined(CONFIG_KEXEC_CORE)
+ #ifdef CONFIG_PPC_BOOK3E
+ 	tovirt(r12,r12)
+ #endif
+diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
+index 93cf7a5846a6..1863324c6a3c 100644
+--- a/arch/powerpc/kernel/misc_32.S
++++ b/arch/powerpc/kernel/misc_32.S
+@@ -614,7 +614,7 @@ _GLOBAL(start_secondary_resume)
+ _GLOBAL(__main)
+ 	blr
+ 
+-#ifdef CONFIG_KEXEC
++#ifdef CONFIG_KEXEC_CORE
+ 	/*
+ 	 * Must be relocatable PIC code callable as a C function.
+ 	 */
+diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S
+index 4f178671f230..32be2a844947 100644
+--- a/arch/powerpc/kernel/misc_64.S
++++ b/arch/powerpc/kernel/misc_64.S
+@@ -478,7 +478,7 @@ _GLOBAL(kexec_wait)
+ 	addi	r5,r5,kexec_flag-1b
+ 
+ 99:	HMT_LOW
+-#ifdef CONFIG_KEXEC		/* use no memory without kexec */
++#ifdef CONFIG_KEXEC_CORE	/* use no memory without kexec */
+ 	lwz	r4,0(r5)
+ 	cmpwi	0,r4,0
+ 	beq	99b
+@@ -503,7 +503,7 @@ kexec_flag:
+ 	.long	0
+ 
+ 
+-#ifdef CONFIG_KEXEC
++#ifdef CONFIG_KEXEC_CORE
+ #ifdef CONFIG_PPC_BOOK3E
+ /*
+  * BOOK3E has no real MMU mode, so we have to setup the initial TLB
+@@ -716,4 +716,4 @@ _GLOBAL(kexec_sequence)
+ 	mtlr	4
+ 	li	r5,0
+ 	blr	/* image->start(physid, image->start, 0); */
+-#endif /* CONFIG_KEXEC */
++#endif /* CONFIG_KEXEC_CORE */
+diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
+index b0245bed6f54..fa7aea479fba 100644
+--- a/arch/powerpc/kernel/prom.c
++++ b/arch/powerpc/kernel/prom.c
+@@ -427,7 +427,7 @@ static int __init early_init_dt_scan_chosen_ppc(unsigned long node,
+ 		tce_alloc_end = *lprop;
+ #endif
+ 
+-#ifdef CONFIG_KEXEC
++#ifdef CONFIG_KEXEC_CORE
+ 	lprop = of_get_flat_dt_prop(node, "linux,crashkernel-base", NULL);
+ 	if (lprop)
+ 		crashk_res.start = *lprop;
+diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
+index 7ac8e6eaab5b..c3e129080c31 100644
+--- a/arch/powerpc/kernel/setup_64.c
++++ b/arch/powerpc/kernel/setup_64.c
+@@ -346,7 +346,7 @@ void early_setup_secondary(void)
+ 
+ #endif /* CONFIG_SMP */
+ 
+-#if defined(CONFIG_SMP) || defined(CONFIG_KEXEC)
++#if defined(CONFIG_SMP) || defined(CONFIG_KEXEC_CORE)
+ static bool use_spinloop(void)
+ {
+ 	if (!IS_ENABLED(CONFIG_PPC_BOOK3E))
+@@ -391,7 +391,7 @@ void smp_release_cpus(void)
+ 
+ 	DBG(" <- smp_release_cpus()\n");
+ }
+-#endif /* CONFIG_SMP || CONFIG_KEXEC */
++#endif /* CONFIG_SMP || CONFIG_KEXEC_CORE */
+ 
+ /*
+  * Initialize some remaining members of the ppc64_caches and systemcfg
+diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
+index 9c6f3fd58059..893bd7f79be6 100644
+--- a/arch/powerpc/kernel/smp.c
++++ b/arch/powerpc/kernel/smp.c
+@@ -193,7 +193,7 @@ int smp_request_message_ipi(int virq, int msg)
+ 	if (msg < 0 || msg > PPC_MSG_DEBUGGER_BREAK) {
+ 		return -EINVAL;
+ 	}
+-#if !defined(CONFIG_DEBUGGER) && !defined(CONFIG_KEXEC)
++#if !defined(CONFIG_DEBUGGER) && !defined(CONFIG_KEXEC_CORE)
+ 	if (msg == PPC_MSG_DEBUGGER_BREAK) {
+ 		return 1;
+ 	}
+@@ -325,7 +325,7 @@ void tick_broadcast(const struct cpumask *mask)
+ }
+ #endif
+ 
+-#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
++#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC_CORE)
+ void smp_send_debugger_break(void)
+ {
+ 	int cpu;
+@@ -340,7 +340,7 @@ void smp_send_debugger_break(void)
+ }
+ #endif
+ 
+-#ifdef CONFIG_KEXEC
++#ifdef CONFIG_KEXEC_CORE
+ void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *))
+ {
+ 	crash_ipi_function_ptr = crash_ipi_callback;
+diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
+index 023a462725b5..d26605d950fe 100644
+--- a/arch/powerpc/kernel/traps.c
++++ b/arch/powerpc/kernel/traps.c
+@@ -65,7 +65,7 @@
+ #include <asm/hmi.h>
+ #include <sysdev/fsl_pci.h>
+ 
+-#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
++#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC_CORE)
+ int (*__debugger)(struct pt_regs *regs) __read_mostly;
+ int (*__debugger_ipi)(struct pt_regs *regs) __read_mostly;
+ int (*__debugger_bpt)(struct pt_regs *regs) __read_mostly;
+diff --git a/arch/powerpc/platforms/85xx/corenet_generic.c b/arch/powerpc/platforms/85xx/corenet_generic.c
+index 1179115a4b5c..3803b0addf65 100644
+--- a/arch/powerpc/platforms/85xx/corenet_generic.c
++++ b/arch/powerpc/platforms/85xx/corenet_generic.c
+@@ -220,7 +220,7 @@ define_machine(corenet_generic) {
+  *
+  * Likewise, problems have been seen with kexec when coreint is enabled.
+  */
+-#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_KEXEC)
++#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_KEXEC_CORE)
+ 	.get_irq		= mpic_get_irq,
  #else
- 
--/* An address is address of the OPD entry, which contains address of fn. */
--typedef struct ppc64_opd_entry func_desc_t;
--
- static func_desc_t func_desc(unsigned long addr)
- {
- 	return *(struct ppc64_opd_entry *)addr;
-@@ -89,29 +69,10 @@ static unsigned long stub_func_addr(func_desc_t func)
- {
- 	return func.funcaddr;
- }
--static unsigned int local_entry_offset(const Elf64_Sym *sym)
--{
--	return 0;
--}
- #endif
- 
- #define STUB_MAGIC 0x73747562 /* stub */
- 
--/* Like PPC32, we need little trampolines to do > 24-bit jumps (into
--   the kernel itself).  But on PPC64, these need to be used for every
--   jump, actually, to reset r2 (TOC+0x8000). */
--struct ppc64_stub_entry
--{
--	/* 28 byte jump instruction sequence (7 instructions). We only
--	 * need 6 instructions on ABIv2 but we always allocate 7 so
--	 * so we don't have to modify the trampoline load instruction. */
--	u32 jump[7];
--	/* Used by ftrace to identify stubs */
--	u32 magic;
--	/* Data for the above code */
--	func_desc_t funcdata;
--};
--
- /*
-  * PPC64 uses 24 bit jumps, but we need to jump into other modules or
-  * the kernel which may be further.  So we jump to a stub.
-@@ -346,9 +307,9 @@ int module_frob_arch_sections(Elf64_Ehdr *hdr,
- 	for (i = 1; i < hdr->e_shnum; i++) {
- 		char *p;
- 		if (strcmp(secstrings + sechdrs[i].sh_name, ".stubs") == 0)
--			me->arch.stubs_section = i;
-+			me->arch.elf_info.stubs_section = i;
- 		else if (strcmp(secstrings + sechdrs[i].sh_name, ".toc") == 0)
--			me->arch.toc_section = i;
-+			me->arch.elf_info.toc_section = i;
- 		else if (strcmp(secstrings+sechdrs[i].sh_name,"__versions")==0)
- 			dedotify_versions((void *)hdr + sechdrs[i].sh_offset,
- 					  sechdrs[i].sh_size);
-@@ -364,7 +325,7 @@ int module_frob_arch_sections(Elf64_Ehdr *hdr,
- 				 + sechdrs[sechdrs[i].sh_link].sh_offset);
+ 	.get_irq		= mpic_get_coreint_irq,
+diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c
+index fe9f19e5e935..a83a6d26090d 100644
+--- a/arch/powerpc/platforms/85xx/smp.c
++++ b/arch/powerpc/platforms/85xx/smp.c
+@@ -349,13 +349,13 @@ struct smp_ops_t smp_85xx_ops = {
+ 	.cpu_disable	= generic_cpu_disable,
+ 	.cpu_die	= generic_cpu_die,
+ #endif
+-#if defined(CONFIG_KEXEC) && !defined(CONFIG_PPC64)
++#if defined(CONFIG_KEXEC_CORE) && !defined(CONFIG_PPC64)
+ 	.give_timebase	= smp_generic_give_timebase,
+ 	.take_timebase	= smp_generic_take_timebase,
+ #endif
+ };
+ 
+-#ifdef CONFIG_KEXEC
++#ifdef CONFIG_KEXEC_CORE
+ #ifdef CONFIG_PPC32
+ atomic_t kexec_down_cpus = ATOMIC_INIT(0);
+ 
+@@ -458,7 +458,7 @@ static void mpc85xx_smp_machine_kexec(struct kimage *image)
+ 
+ 	default_machine_kexec(image);
+ }
+-#endif /* CONFIG_KEXEC */
++#endif /* CONFIG_KEXEC_CORE */
+ 
+ static void smp_85xx_basic_setup(int cpu_nr)
+ {
+@@ -512,7 +512,7 @@ void __init mpc85xx_smp_init(void)
+ #endif
+ 	smp_ops = &smp_85xx_ops;
+ 
+-#ifdef CONFIG_KEXEC
++#ifdef CONFIG_KEXEC_CORE
+ 	ppc_md.kexec_cpu_down = mpc85xx_smp_kexec_cpu_down;
+ 	ppc_md.machine_kexec = mpc85xx_smp_machine_kexec;
+ #endif
+diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
+index e84d8fbc2e21..96c2b8a40630 100644
+--- a/arch/powerpc/platforms/cell/spu_base.c
++++ b/arch/powerpc/platforms/cell/spu_base.c
+@@ -676,7 +676,7 @@ static ssize_t spu_stat_show(struct device *dev,
+ 
+ static DEVICE_ATTR(stat, 0444, spu_stat_show, NULL);
+ 
+-#ifdef CONFIG_KEXEC
++#ifdef CONFIG_KEXEC_CORE
+ 
+ struct crash_spu_info {
+ 	struct spu *spu;
+diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c
+index efe8b6bb168b..d50c7d99baaf 100644
+--- a/arch/powerpc/platforms/powernv/setup.c
++++ b/arch/powerpc/platforms/powernv/setup.c
+@@ -174,7 +174,7 @@ static void pnv_shutdown(void)
+ 	opal_shutdown();
+ }
+ 
+-#ifdef CONFIG_KEXEC
++#ifdef CONFIG_KEXEC_CORE
+ static void pnv_kexec_wait_secondaries_down(void)
+ {
+ 	int my_cpu, i, notified = -1;
+@@ -245,7 +245,7 @@ static void pnv_kexec_cpu_down(int crash_shutdown, int secondary)
+ 		opal_reinit_cpus(OPAL_REINIT_CPUS_HILE_BE);
  	}
- 
--	if (!me->arch.stubs_section) {
-+	if (!me->arch.elf_info.stubs_section) {
- 		pr_err("%s: doesn't contain .stubs.\n", me->name);
- 		return -ENOEXEC;
- 	}
-@@ -373,44 +334,32 @@ int module_frob_arch_sections(Elf64_Ehdr *hdr,
- 	   to some reasonable value in case the module calls out to
- 	   other functions via a stub, or if a function pointer escapes
- 	   the module by some means.  */
--	if (!me->arch.toc_section)
--		me->arch.toc_section = me->arch.stubs_section;
-+	if (!me->arch.elf_info.toc_section)
-+		me->arch.elf_info.toc_section = me->arch.elf_info.stubs_section;
- 
- 	/* Override the stubs size */
--	sechdrs[me->arch.stubs_section].sh_size = get_stubs_size(hdr, sechdrs);
--	return 0;
--}
-+	sechdrs[me->arch.elf_info.stubs_section].sh_size = get_stubs_size(hdr, sechdrs);
- 
--/* r2 is the TOC pointer: it actually points 0x8000 into the TOC (this
--   gives the value maximum span in an instruction which uses a signed
--   offset) */
--static inline unsigned long my_r2(const Elf64_Shdr *sechdrs, struct module *me)
--{
--	return sechdrs[me->arch.toc_section].sh_addr + 0x8000;
--}
-+	/* For the elf_util functions. */
-+	me->arch.elf_info.sechdrs = sechdrs;
- 
--/* Both low and high 16 bits are added as SIGNED additions, so if low
--   16 bits has high bit set, high 16 bits must be adjusted.  These
--   macros do that (stolen from binutils). */
--#define PPC_LO(v) ((v) & 0xffff)
--#define PPC_HI(v) (((v) >> 16) & 0xffff)
--#define PPC_HA(v) PPC_HI ((v) + 0x8000)
-+	return 0;
-+}
- 
- /* Patch stub to reference function and correct r2 value. */
--static inline int create_stub(const Elf64_Shdr *sechdrs,
-+static inline int create_stub(const struct elf_info *elf_info,
- 			      struct ppc64_stub_entry *entry,
--			      unsigned long addr,
--			      struct module *me)
-+			      unsigned long addr, const char *obj_name)
- {
- 	long reladdr;
- 
- 	memcpy(entry->jump, ppc64_stub_insns, sizeof(ppc64_stub_insns));
- 
- 	/* Stub uses address relative to r2. */
--	reladdr = (unsigned long)entry - my_r2(sechdrs, me);
-+	reladdr = (unsigned long)entry - my_r2(elf_info);
- 	if (reladdr > 0x7FFFFFFF || reladdr < -(0x80000000L)) {
- 		pr_err("%s: Address %p of stub out of range of %p.\n",
--		       me->name, (void *)reladdr, (void *)my_r2);
-+		       obj_name, (void *)reladdr, (void *)my_r2);
- 		return 0;
- 	}
- 	pr_debug("Stub %p get data from reladdr %li\n", entry, reladdr);
-@@ -425,17 +374,17 @@ static inline int create_stub(const Elf64_Shdr *sechdrs,
- 
- /* Create stub to jump to function described in this OPD/ptr: we need the
-    stub to set up the TOC ptr (r2) for the function. */
--static unsigned long stub_for_addr(const Elf64_Shdr *sechdrs,
--				   unsigned long addr,
--				   struct module *me)
-+unsigned long stub_for_addr(const struct elf_info *elf_info, unsigned long addr,
-+			    const char *obj_name)
- {
-+	struct elf_shdr *stubs_sec = &elf_info->sechdrs[elf_info->stubs_section];
- 	struct ppc64_stub_entry *stubs;
- 	unsigned int i, num_stubs;
- 
--	num_stubs = sechdrs[me->arch.stubs_section].sh_size / sizeof(*stubs);
-+	num_stubs = stubs_sec->sh_size / sizeof(*stubs);
- 
- 	/* Find this stub, or if that fails, the next avail. entry */
--	stubs = (void *)sechdrs[me->arch.stubs_section].sh_addr;
-+	stubs = (void *) stubs_sec->sh_addr;
- 	for (i = 0; stub_func_addr(stubs[i].funcdata); i++) {
- 		BUG_ON(i >= num_stubs);
- 
-@@ -443,7 +392,7 @@ static unsigned long stub_for_addr(const Elf64_Shdr *sechdrs,
- 			return (unsigned long)&stubs[i];
- 	}
- 
--	if (!create_stub(sechdrs, &stubs[i], addr, me))
-+	if (!create_stub(elf_info, &stubs[i], addr, obj_name))
- 		return 0;
- 
- 	return (unsigned long)&stubs[i];
-@@ -465,24 +414,7 @@ static bool is_early_mcount_callsite(u32 *instruction)
- 	return false;
- }
- 
--/*
-- * In case of _mcount calls, do not save the current callee's TOC (in r2) into
-- * the original caller's stack frame. If we did we would clobber the saved TOC
-- * value of the original caller.
-- */
--static void squash_toc_save_inst(const char *name, unsigned long addr)
--{
--	struct ppc64_stub_entry *stub = (struct ppc64_stub_entry *)addr;
--
--	/* Only for calls to _mcount */
--	if (strcmp("_mcount", name) != 0)
--		return;
--
--	stub->jump[2] = PPC_INST_NOP;
--}
- #else
--static void squash_toc_save_inst(const char *name, unsigned long addr) { }
--
- /* without -mprofile-kernel, mcount calls are never early */
- static bool is_early_mcount_callsite(u32 *instruction)
- {
-@@ -492,14 +424,14 @@ static bool is_early_mcount_callsite(u32 *instruction)
- 
- /* We expect a noop next: if it is, replace it with instruction to
-    restore r2. */
--static int restore_r2(u32 *instruction, struct module *me)
-+int restore_r2(u32 *instruction, const char *obj_name)
- {
- 	if (is_early_mcount_callsite(instruction - 1))
- 		return 1;
- 
- 	if (*instruction != PPC_INST_NOP) {
- 		pr_err("%s: Expect noop after relocate, got %08x\n",
--		       me->name, *instruction);
-+		       obj_name, *instruction);
- 		return 0;
- 	}
- 	/* ld r2,R2_STACK_OFFSET(r1) */
-@@ -513,11 +445,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
- 		       unsigned int relsec,
- 		       struct module *me)
- {
--	unsigned int i;
--	Elf64_Rela *rela = (void *)sechdrs[relsec].sh_addr;
- 	Elf64_Sym *sym;
--	unsigned long *location;
--	unsigned long value;
- 
- 	pr_debug("Applying ADD relocate section %u to %u\n", relsec,
- 	       sechdrs[relsec].sh_info);
-@@ -528,191 +456,12 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
- 		/* It's theoretically possible that a module doesn't want a
- 		 * .TOC. so don't fail it just for that. */
- 		if (sym)
--			sym->st_value = my_r2(sechdrs, me);
-+			sym->st_value = my_r2(&me->arch.elf_info);
- 		me->arch.toc_fixed = true;
- 	}
- 
--	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rela); i++) {
--		/* This is where to make the change */
--		location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
--			+ rela[i].r_offset;
--		/* This is the symbol it is referring to */
--		sym = (Elf64_Sym *)sechdrs[symindex].sh_addr
--			+ ELF64_R_SYM(rela[i].r_info);
--
--		pr_debug("RELOC at %p: %li-type as %s (0x%lx) + %li\n",
--		       location, (long)ELF64_R_TYPE(rela[i].r_info),
--		       strtab + sym->st_name, (unsigned long)sym->st_value,
--		       (long)rela[i].r_addend);
--
--		/* `Everything is relative'. */
--		value = sym->st_value + rela[i].r_addend;
--
--		switch (ELF64_R_TYPE(rela[i].r_info)) {
--		case R_PPC64_ADDR32:
--			/* Simply set it */
--			*(u32 *)location = value;
--			break;
--
--		case R_PPC64_ADDR64:
--			/* Simply set it */
--			*(unsigned long *)location = value;
--			break;
--
--		case R_PPC64_TOC:
--			*(unsigned long *)location = my_r2(sechdrs, me);
--			break;
--
--		case R_PPC64_TOC16:
--			/* Subtract TOC pointer */
--			value -= my_r2(sechdrs, me);
--			if (value + 0x8000 > 0xffff) {
--				pr_err("%s: bad TOC16 relocation (0x%lx)\n",
--				       me->name, value);
--				return -ENOEXEC;
--			}
--			*((uint16_t *) location)
--				= (*((uint16_t *) location) & ~0xffff)
--				| (value & 0xffff);
--			break;
--
--		case R_PPC64_TOC16_LO:
--			/* Subtract TOC pointer */
--			value -= my_r2(sechdrs, me);
--			*((uint16_t *) location)
--				= (*((uint16_t *) location) & ~0xffff)
--				| (value & 0xffff);
--			break;
--
--		case R_PPC64_TOC16_DS:
--			/* Subtract TOC pointer */
--			value -= my_r2(sechdrs, me);
--			if ((value & 3) != 0 || value + 0x8000 > 0xffff) {
--				pr_err("%s: bad TOC16_DS relocation (0x%lx)\n",
--				       me->name, value);
--				return -ENOEXEC;
--			}
--			*((uint16_t *) location)
--				= (*((uint16_t *) location) & ~0xfffc)
--				| (value & 0xfffc);
--			break;
--
--		case R_PPC64_TOC16_LO_DS:
--			/* Subtract TOC pointer */
--			value -= my_r2(sechdrs, me);
--			if ((value & 3) != 0) {
--				pr_err("%s: bad TOC16_LO_DS relocation (0x%lx)\n",
--				       me->name, value);
--				return -ENOEXEC;
--			}
--			*((uint16_t *) location)
--				= (*((uint16_t *) location) & ~0xfffc)
--				| (value & 0xfffc);
--			break;
--
--		case R_PPC64_TOC16_HA:
--			/* Subtract TOC pointer */
--			value -= my_r2(sechdrs, me);
--			value = ((value + 0x8000) >> 16);
--			*((uint16_t *) location)
--				= (*((uint16_t *) location) & ~0xffff)
--				| (value & 0xffff);
--			break;
--
--		case R_PPC_REL24:
--			/* FIXME: Handle weak symbols here --RR */
--			if (sym->st_shndx == SHN_UNDEF) {
--				/* External: go via stub */
--				value = stub_for_addr(sechdrs, value, me);
--				if (!value)
--					return -ENOENT;
--				if (!restore_r2((u32 *)location + 1, me))
--					return -ENOEXEC;
--
--				squash_toc_save_inst(strtab + sym->st_name, value);
--			} else
--				value += local_entry_offset(sym);
--
--			/* Convert value to relative */
--			value -= (unsigned long)location;
--			if (value + 0x2000000 > 0x3ffffff || (value & 3) != 0){
--				pr_err("%s: REL24 %li out of range!\n",
--				       me->name, (long int)value);
--				return -ENOEXEC;
--			}
--
--			/* Only replace bits 2 through 26 */
--			*(uint32_t *)location
--				= (*(uint32_t *)location & ~0x03fffffc)
--				| (value & 0x03fffffc);
--			break;
--
--		case R_PPC64_REL64:
--			/* 64 bits relative (used by features fixups) */
--			*location = value - (unsigned long)location;
--			break;
--
--		case R_PPC64_TOCSAVE:
--			/*
--			 * Marker reloc indicates we don't have to save r2.
--			 * That would only save us one instruction, so ignore
--			 * it.
--			 */
--			break;
--
--		case R_PPC64_ENTRY:
--			/*
--			 * Optimize ELFv2 large code model entry point if
--			 * the TOC is within 2GB range of current location.
--			 */
--			value = my_r2(sechdrs, me) - (unsigned long)location;
--			if (value + 0x80008000 > 0xffffffff)
--				break;
--			/*
--			 * Check for the large code model prolog sequence:
--		         *	ld r2, ...(r12)
--			 *	add r2, r2, r12
--			 */
--			if ((((uint32_t *)location)[0] & ~0xfffc)
--			    != 0xe84c0000)
--				break;
--			if (((uint32_t *)location)[1] != 0x7c426214)
--				break;
--			/*
--			 * If found, replace it with:
--			 *	addis r2, r12, (.TOC.-func)@ha
--			 *	addi r2, r12, (.TOC.-func)@l
--			 */
--			((uint32_t *)location)[0] = 0x3c4c0000 + PPC_HA(value);
--			((uint32_t *)location)[1] = 0x38420000 + PPC_LO(value);
--			break;
--
--		case R_PPC64_REL16_HA:
--			/* Subtract location pointer */
--			value -= (unsigned long)location;
--			value = ((value + 0x8000) >> 16);
--			*((uint16_t *) location)
--				= (*((uint16_t *) location) & ~0xffff)
--				| (value & 0xffff);
--			break;
--
--		case R_PPC64_REL16_LO:
--			/* Subtract location pointer */
--			value -= (unsigned long)location;
--			*((uint16_t *) location)
--				= (*((uint16_t *) location) & ~0xffff)
--				| (value & 0xffff);
--			break;
--
--		default:
--			pr_err("%s: Unknown ADD relocation: %lu\n",
--			       me->name,
--			       (unsigned long)ELF64_R_TYPE(rela[i].r_info));
--			return -ENOEXEC;
--		}
--	}
--
--	return 0;
-+	return elf64_apply_relocate_add(&me->arch.elf_info, strtab, symindex,
-+					relsec, me->name);
- }
- 
- #ifdef CONFIG_DYNAMIC_FTRACE
-@@ -746,10 +495,10 @@ static unsigned long create_ftrace_stub(const Elf64_Shdr *sechdrs, struct module
- 	};
- 	long reladdr;
- 
--	num_stubs = sechdrs[me->arch.stubs_section].sh_size / sizeof(*entry);
-+	num_stubs = sechdrs[me->arch.elf_info.stubs_section].sh_size / sizeof(*entry);
- 
- 	/* Find the next available stub entry */
--	entry = (void *)sechdrs[me->arch.stubs_section].sh_addr;
-+	entry = (void *)sechdrs[me->arch.elf_info.stubs_section].sh_addr;
- 	for (i = 0; i < num_stubs && stub_func_addr(entry->funcdata); i++, entry++);
- 
- 	if (i >= num_stubs) {
-@@ -778,13 +527,14 @@ static unsigned long create_ftrace_stub(const Elf64_Shdr *sechdrs, struct module
- #else
- static unsigned long create_ftrace_stub(const Elf64_Shdr *sechdrs, struct module *me)
- {
--	return stub_for_addr(sechdrs, (unsigned long)ftrace_caller, me);
-+	return stub_for_addr(&me->arch.elf_info, (unsigned long)ftrace_caller,
-+			     me->name);
- }
- #endif
- 
- int module_finalize_ftrace(struct module *mod, const Elf_Shdr *sechdrs)
- {
--	mod->arch.toc = my_r2(sechdrs, mod);
-+	mod->arch.toc = my_r2(&mod->arch.elf_info);
- 	mod->arch.tramp = create_ftrace_stub(sechdrs, mod);
- 
- 	if (!mod->arch.tramp)
+ }
+-#endif /* CONFIG_KEXEC */
++#endif /* CONFIG_KEXEC_CORE */
+ 
+ #ifdef CONFIG_MEMORY_HOTPLUG_SPARSE
+ static unsigned long pnv_memory_block_size(void)
+@@ -311,7 +311,7 @@ define_machine(powernv) {
+ 	.machine_shutdown	= pnv_shutdown,
+ 	.power_save             = NULL,
+ 	.calibrate_decr		= generic_calibrate_decr,
+-#ifdef CONFIG_KEXEC
++#ifdef CONFIG_KEXEC_CORE
+ 	.kexec_cpu_down		= pnv_kexec_cpu_down,
+ #endif
+ #ifdef CONFIG_MEMORY_HOTPLUG_SPARSE
+diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c
+index 3a487e7f4a5e..6244bc849469 100644
+--- a/arch/powerpc/platforms/ps3/setup.c
++++ b/arch/powerpc/platforms/ps3/setup.c
+@@ -250,7 +250,7 @@ static int __init ps3_probe(void)
+ 	return 1;
+ }
+ 
+-#if defined(CONFIG_KEXEC)
++#if defined(CONFIG_KEXEC_CORE)
+ static void ps3_kexec_cpu_down(int crash_shutdown, int secondary)
+ {
+ 	int cpu = smp_processor_id();
+@@ -276,7 +276,7 @@ define_machine(ps3) {
+ 	.progress			= ps3_progress,
+ 	.restart			= ps3_restart,
+ 	.halt				= ps3_halt,
+-#if defined(CONFIG_KEXEC)
++#if defined(CONFIG_KEXEC_CORE)
+ 	.kexec_cpu_down			= ps3_kexec_cpu_down,
+ #endif
+ };
+diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
+index fedc2ccf029d..dd9d9c2ba71b 100644
+--- a/arch/powerpc/platforms/pseries/Makefile
++++ b/arch/powerpc/platforms/pseries/Makefile
+@@ -8,7 +8,7 @@ obj-y			:= lpar.o hvCall.o nvram.o reconfig.o \
+ 			   pci.o pci_dlpar.o eeh_pseries.o msi.o
+ obj-$(CONFIG_SMP)	+= smp.o
+ obj-$(CONFIG_SCANLOG)	+= scanlog.o
+-obj-$(CONFIG_KEXEC)	+= kexec.o
++obj-$(CONFIG_KEXEC_CORE)	+= kexec.o
+ obj-$(CONFIG_PSERIES_ENERGY)	+= pseries_energy.o
+ 
+ obj-$(CONFIG_HOTPLUG_CPU)	+= hotplug-cpu.o
+diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
+index 97aa3f332f24..7736352f7279 100644
+--- a/arch/powerpc/platforms/pseries/setup.c
++++ b/arch/powerpc/platforms/pseries/setup.c
+@@ -367,7 +367,7 @@ void pseries_disable_reloc_on_exc(void)
+ }
+ EXPORT_SYMBOL(pseries_disable_reloc_on_exc);
+ 
+-#ifdef CONFIG_KEXEC
++#ifdef CONFIG_KEXEC_CORE
+ static void pSeries_machine_kexec(struct kimage *image)
+ {
+ 	if (firmware_has_feature(FW_FEATURE_SET_MODE))
+@@ -725,7 +725,7 @@ define_machine(pseries) {
+ 	.progress		= rtas_progress,
+ 	.system_reset_exception = pSeries_system_reset_exception,
+ 	.machine_check_exception = pSeries_machine_check_exception,
+-#ifdef CONFIG_KEXEC
++#ifdef CONFIG_KEXEC_CORE
+ 	.machine_kexec          = pSeries_machine_kexec,
+ 	.kexec_cpu_down         = pseries_kexec_cpu_down,
+ #endif
 -- 
-1.9.1
+2.7.4
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help