Skip to contentSkip to conversation

Pass struct mem_sym into machine_apply_elf_rel()

PATCH In review Anton Blanchard 5 participants 8 messages Feb 26, 2016 – Mar 24, 2016

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/3 Pass struct mem_sym into machine_apply_elf_rel()

On PowerPC64 ABIv2 we need to look at the symbol to determine if it has a local entry point. Pass struct mem_sym into machine_apply_elf_rel() so we can.

---
 kexec/arch/arm/kexec-elf-rel-arm.c       | 5 +++--
 kexec/arch/cris/kexec-elf-rel-cris.c     | 5 +++--
 kexec/arch/i386/kexec-elf-rel-x86.c      | 5 +++--
 kexec/arch/ia64/kexec-elf-rel-ia64.c     | 5 +++--
 kexec/arch/m68k/kexec-elf-rel-m68k.c     | 4 +++-
 kexec/arch/mips/kexec-elf-rel-mips.c     | 4 +++-
 kexec/arch/ppc/kexec-elf-rel-ppc.c       | 5 +++--
 kexec/arch/ppc64/kexec-elf-rel-ppc64.c   | 5 +++--
 kexec/arch/s390/kexec-elf-rel-s390.c     | 3 ++-
 kexec/arch/sh/kexec-elf-rel-sh.c         | 5 +++--
 kexec/arch/x86_64/kexec-elf-rel-x86_64.c | 5 +++--
 kexec/kexec-elf-rel.c                    | 2 +-
 kexec/kexec-elf.h                        | 5 +++--
 13 files changed, 36 insertions(+), 22 deletions(-)
kexec/arch/arm/kexec-elf-rel-arm.c +3 -2
index 214f0cc..a939cf4 100644
@@ -18,8 +18,9 @@ int machine_verify_elf_rel(struct mem_ehdr *ehdr)
 	return 1;
 }
 
-void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr), unsigned long r_type,
-	void *location, unsigned long address, unsigned long value)
+void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr),
+	struct mem_sym *UNUSED(sym), unsigned long r_type, void *location,
+	unsigned long address, unsigned long value)
 {
 	switch(r_type) {
 	case R_ARM_ABS32:
kexec/arch/cris/kexec-elf-rel-cris.c +3 -2
index c4427cc..255cc2c 100644
@@ -29,8 +29,9 @@ int machine_verify_elf_rel(struct mem_ehdr *ehdr)
 	return 1;
 }
 
-void machine_apply_elf_rel(struct mem_ehdr *ehdr, unsigned long r_type,
-	void *location, unsigned long address, unsigned long value)
+void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr),
+	struct mem_sym *UNUSED(sym), unsigned long r_type, void *location,
+	unsigned long address, unsigned long value)
 {
 	switch(r_type) {
 
kexec/arch/i386/kexec-elf-rel-x86.c +3 -2
index fdc3d52..55a214e 100644
@@ -18,8 +18,9 @@ int machine_verify_elf_rel(struct mem_ehdr *ehdr)
 	return 1;
 }
 
-void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr), unsigned long r_type,
-	void *location, unsigned long address, unsigned long value)
+void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr),
+	struct mem_sym *UNUSED(sym), unsigned long r_type, void *location,
+	unsigned long address, unsigned long value)
 {
 	switch(r_type) {
 	case R_386_32:
kexec/arch/ia64/kexec-elf-rel-ia64.c +3 -2
index cfb1061..f847626 100644
@@ -72,8 +72,9 @@ bundle (const uint64_t insn)
         return insn & ~0xfUL;
 }
 
-void machine_apply_elf_rel(struct mem_ehdr *ehdr, unsigned long r_type,
-	void *location, unsigned long address, unsigned long value)
+void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr),
+	struct mem_sym *UNUSED(sym), unsigned long r_type, void *location,
+	unsigned long address, unsigned long value)
 {
 	uint64_t gp_value = ehdr->rel_addr + 0x200000;
 	switch(r_type) {
kexec/arch/m68k/kexec-elf-rel-m68k.c +3 -1
index fa12a16..0cc38cc 100644
@@ -23,7 +23,9 @@ int machine_verify_elf_rel(struct mem_ehdr *ehdr)
 	return 1;
 }
 
-void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr), unsigned long r_type,
+void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr),
+			   struct mem_sym *UNUSED(sym),
+			   unsigned long r_type,
 			   void *UNUSED(location),
 			   unsigned long UNUSED(address),
 			   unsigned long UNUSED(value))
kexec/arch/mips/kexec-elf-rel-mips.c +3 -1
index 6f43639..5bc22d5 100644
@@ -29,7 +29,9 @@ int machine_verify_elf_rel(struct mem_ehdr *ehdr)
 	return 1;
 }
 
-void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr), unsigned long r_type,
+void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr),
+			   struct mem_sym *UNUSED(sym),
+			   unsigned long r_type,
 			   void *UNUSED(location),
 			   unsigned long UNUSED(address),
 			   unsigned long UNUSED(value))
kexec/arch/ppc/kexec-elf-rel-ppc.c +3 -2
index 90a66f4..1acbd86 100644
@@ -17,8 +17,9 @@ int machine_verify_elf_rel(struct mem_ehdr *ehdr)
 	return 1;
 }
 
-void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr), unsigned long r_type,
-	void *location, unsigned long address, unsigned long value)
+void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr),
+	struct mem_sym *UNUSED(sym), unsigned long r_type, void *location,
+	unsigned long address, unsigned long value)
 {
 	switch(r_type) {
 	case R_PPC_ADDR32:
kexec/arch/ppc64/kexec-elf-rel-ppc64.c +3 -2
index 9b191d0..8604c4f 100644
@@ -63,8 +63,9 @@ static void do_relative_toc(unsigned long value, uint16_t *location,
 	*location = (*location & ~mask) | (value & mask);
 }
 
-void machine_apply_elf_rel(struct mem_ehdr *ehdr, unsigned long r_type,
-	void *location, unsigned long address, unsigned long value)
+void machine_apply_elf_rel(struct mem_ehdr *ehdr, struct mem_sym *sym,
+	unsigned long r_type, void *location, unsigned long address,
+	unsigned long value)
 {
 	switch(r_type) {
 	case R_PPC64_ADDR32:
kexec/arch/s390/kexec-elf-rel-s390.c +2 -1
index 80bcd1b..a5e1b73 100644
@@ -23,7 +23,8 @@ int machine_verify_elf_rel(struct mem_ehdr *ehdr)
 	return 1;
 }
 
-void machine_apply_elf_rel(struct mem_ehdr *ehdr,
+void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr),
+			   struct mem_sym *UNUSED(sym),
 			   unsigned long r_type,
 			   void *loc,
 			   unsigned long address,
kexec/arch/sh/kexec-elf-rel-sh.c +3 -2
index 0bfc45e..3993ee8 100644
@@ -28,8 +28,9 @@ int machine_verify_elf_rel(struct mem_ehdr *ehdr)
 	return 1;
 }
 
-void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr), unsigned long r_type,
-	void *orig_loc, unsigned long UNUSED(address), unsigned long relocation)
+void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr),
+	struct mem_sym *UNUSED(sym), unsigned long r_type, void *orig_loc,
+	unsigned long UNUSED(address), unsigned long relocation)
 {
 	uint32_t *location = orig_loc;
 	uint32_t value;
kexec/arch/x86_64/kexec-elf-rel-x86_64.c +3 -2
index c795037..7fdde73 100644
@@ -57,8 +57,9 @@ static const char *reloc_name(unsigned long r_type)
 	return name;
 }
 
-void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr), unsigned long r_type,
-	void *location, unsigned long address, unsigned long value)
+void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr),
+	struct mem_sym *UNUSED(sym), unsigned long r_type, void *location,
+	unsigned long address, unsigned long value)
 {
 	dbgprintf("%s\n", reloc_name(r_type));
 	switch(r_type) {
kexec/kexec-elf-rel.c +1 -1
index c625f30..9a6e63d 100644
@@ -408,7 +408,7 @@ int elf_rel_load(struct mem_ehdr *ehdr, struct kexec_info *info,
 			dbgprintf("sym: %s value: %lx addr: %lx\n",
 				name, value, address);
 
-			machine_apply_elf_rel(ehdr, rel.r_type,
+			machine_apply_elf_rel(ehdr, &sym, rel.r_type,
 				(void *)location, address, value);
 		}
 	}
kexec/kexec-elf.h +3 -2
index d0e9dc0..1164db4 100644
@@ -129,7 +129,8 @@ unsigned long elf_max_addr(const struct mem_ehdr *ehdr);
 
 /* Architecture specific helper functions */
 extern int machine_verify_elf_rel(struct mem_ehdr *ehdr);
-extern void machine_apply_elf_rel(struct mem_ehdr *ehdr, unsigned long r_type, 
-	void *location, unsigned long address, unsigned long value);
+extern void machine_apply_elf_rel(struct mem_ehdr *ehdr, struct mem_sym *sym,
+	unsigned long r_type, void *location, unsigned long address,
+	unsigned long value);
 #endif /* KEXEC_ELF_H */
 
Signature · 7 lines
2.5.0


_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
#1 lore raw

PATCH 2/3 ppc64: purgatory: Handle local symbols in ELF ABIv2

The PowerPC64 ELF ABIv2 has the concept of global and local symbols and information on this is encoded in sym->st_other. When doing a R_PPC64_REL24 branch we want to hit the local entry point, so adjust it as necessary.

---
 kexec/arch/ppc64/kexec-elf-rel-ppc64.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

v2: In local_entry_offset() mark sym as unused when compiling ABIv1.

kexec/arch/ppc64/kexec-elf-rel-ppc64.c +19 -0
index 8604c4f..43851f6 100644
@@ -5,6 +5,24 @@
 #include "../../kexec-elf.h"
 #include "kexec-ppc64.h"
 
+#if defined(_CALL_ELF) && _CALL_ELF == 2
+#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(struct mem_sym *sym)
+{
+	/* If this symbol has a local entry point, use it. */
+	return PPC64_LOCAL_ENTRY_OFFSET(sym->st_other);
+}
+#else
+static unsigned int local_entry_offset(struct mem_sym *UNUSED(sym))
+{
+	return 0;
+}
+#endif
+
 int machine_verify_elf_rel(struct mem_ehdr *ehdr)
 {
 	if (ehdr->ei_class != ELFCLASS64) {
@@ -114,6 +132,7 @@ void machine_apply_elf_rel(struct mem_ehdr *ehdr, struct mem_sym *sym,
 		break;
 
 	case R_PPC64_REL24:
+		value += local_entry_offset(sym);
 		/* Convert value to relative */
 		value -= address;
 		if (value + 0x2000000 > 0x3ffffff || (value & 3) != 0) {
Signature · 7 lines
2.5.0


_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
#2 lore raw

PATCH 3/3 Properly align powerpc64 .toc

In reply to Anton Blanchard

From: Alan Modra <[email protected]>

gcc leaves .toc byte aligned, relying on the linker to align the section.

* kexec/arch/ppc64/kexec-elf-rel-ppc64.c (machine_verify_elf_rel):
Fudge alignment of .toc section.

---
 kexec/arch/ppc64/kexec-elf-rel-ppc64.c | 30 ++++++++++++++++++------------
 1 file changed, 18 insertions(+), 12 deletions(-)
kexec/arch/ppc64/kexec-elf-rel-ppc64.c +18 -12
index 43851f6..5f8e3f2 100644
@@ -23,18 +23,6 @@ static unsigned int local_entry_offset(struct mem_sym *UNUSED(sym))
 }
 #endif
 
-int machine_verify_elf_rel(struct mem_ehdr *ehdr)
-{
-	if (ehdr->ei_class != ELFCLASS64) {
-		return 0;
-	}
-	if (ehdr->e_machine != EM_PPC64) {
-		return 0;
-	}
-
-	return 1;
-}
-
 static struct mem_shdr *toc_section(const struct mem_ehdr *ehdr)
 {
 	struct mem_shdr *shdr, *shdr_end;
@@ -52,6 +40,24 @@ static struct mem_shdr *toc_section(const struct mem_ehdr *ehdr)
 	return NULL;
 }
 
+int machine_verify_elf_rel(struct mem_ehdr *ehdr)
+{
+	struct mem_shdr *toc;
+
+	if (ehdr->ei_class != ELFCLASS64) {
+		return 0;
+	}
+	if (ehdr->e_machine != EM_PPC64) {
+		return 0;
+	}
+
+	/* Ensure .toc is sufficiently aligned.  */
+	toc = toc_section(ehdr);
+	if (toc && toc->sh_addralign < 256)
+		toc->sh_addralign = 256;
+	return 1;
+}
+
 /* 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) */
Signature · 7 lines
2.5.0


_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
Tested-by on v1 1/3
#3 lore raw
In reply to Anton Blanchard
Quoted 229 lines · Anton Blanchard

On PowerPC64 ABIv2 we need to look at the symbol to determine if it has a local entry point. Pass struct mem_sym into machine_apply_elf_rel() so we can.

---
 kexec/arch/arm/kexec-elf-rel-arm.c       | 5 +++--
 kexec/arch/cris/kexec-elf-rel-cris.c     | 5 +++--
 kexec/arch/i386/kexec-elf-rel-x86.c      | 5 +++--
 kexec/arch/ia64/kexec-elf-rel-ia64.c     | 5 +++--
 kexec/arch/m68k/kexec-elf-rel-m68k.c     | 4 +++-
 kexec/arch/mips/kexec-elf-rel-mips.c     | 4 +++-
 kexec/arch/ppc/kexec-elf-rel-ppc.c       | 5 +++--
 kexec/arch/ppc64/kexec-elf-rel-ppc64.c   | 5 +++--
 kexec/arch/s390/kexec-elf-rel-s390.c     | 3 ++-
 kexec/arch/sh/kexec-elf-rel-sh.c         | 5 +++--
 kexec/arch/x86_64/kexec-elf-rel-x86_64.c | 5 +++--
 kexec/kexec-elf-rel.c                    | 2 +-
 kexec/kexec-elf.h                        | 5 +++--
 13 files changed, 36 insertions(+), 22 deletions(-)
kexec/arch/arm/kexec-elf-rel-arm.c +3 -2
index 214f0cc..a939cf4 100644
@@ -18,8 +18,9 @@ int machine_verify_elf_rel(struct mem_ehdr *ehdr)
 	return 1;
 }
 
-void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr), unsigned long r_type,
-	void *location, unsigned long address, unsigned long value)
+void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr),
+	struct mem_sym *UNUSED(sym), unsigned long r_type, void *location,
+	unsigned long address, unsigned long value)
 {
 	switch(r_type) {
 	case R_ARM_ABS32:
kexec/arch/cris/kexec-elf-rel-cris.c +3 -2
index c4427cc..255cc2c 100644
@@ -29,8 +29,9 @@ int machine_verify_elf_rel(struct mem_ehdr *ehdr)
 	return 1;
 }
 
-void machine_apply_elf_rel(struct mem_ehdr *ehdr, unsigned long r_type,
-	void *location, unsigned long address, unsigned long value)
+void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr),
+	struct mem_sym *UNUSED(sym), unsigned long r_type, void *location,
+	unsigned long address, unsigned long value)
 {
 	switch(r_type) {
 
kexec/arch/i386/kexec-elf-rel-x86.c +3 -2
index fdc3d52..55a214e 100644
@@ -18,8 +18,9 @@ int machine_verify_elf_rel(struct mem_ehdr *ehdr)
 	return 1;
 }
 
-void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr), unsigned long r_type,
-	void *location, unsigned long address, unsigned long value)
+void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr),
+	struct mem_sym *UNUSED(sym), unsigned long r_type, void *location,
+	unsigned long address, unsigned long value)
 {
 	switch(r_type) {
 	case R_386_32:
kexec/arch/ia64/kexec-elf-rel-ia64.c +3 -2
index cfb1061..f847626 100644
@@ -72,8 +72,9 @@ bundle (const uint64_t insn)
         return insn & ~0xfUL;
 }
 
-void machine_apply_elf_rel(struct mem_ehdr *ehdr, unsigned long r_type,
-	void *location, unsigned long address, unsigned long value)
+void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr),
+	struct mem_sym *UNUSED(sym), unsigned long r_type, void *location,
+	unsigned long address, unsigned long value)
 {
 	uint64_t gp_value = ehdr->rel_addr + 0x200000;
 	switch(r_type) {
kexec/arch/m68k/kexec-elf-rel-m68k.c +3 -1
index fa12a16..0cc38cc 100644
@@ -23,7 +23,9 @@ int machine_verify_elf_rel(struct mem_ehdr *ehdr)
 	return 1;
 }
 
-void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr), unsigned long r_type,
+void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr),
+			   struct mem_sym *UNUSED(sym),
+			   unsigned long r_type,
 			   void *UNUSED(location),
 			   unsigned long UNUSED(address),
 			   unsigned long UNUSED(value))
kexec/arch/mips/kexec-elf-rel-mips.c +3 -1
index 6f43639..5bc22d5 100644
@@ -29,7 +29,9 @@ int machine_verify_elf_rel(struct mem_ehdr *ehdr)
 	return 1;
 }
 
-void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr), unsigned long r_type,
+void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr),
+			   struct mem_sym *UNUSED(sym),
+			   unsigned long r_type,
 			   void *UNUSED(location),
 			   unsigned long UNUSED(address),
 			   unsigned long UNUSED(value))
kexec/arch/ppc/kexec-elf-rel-ppc.c +3 -2
index 90a66f4..1acbd86 100644
@@ -17,8 +17,9 @@ int machine_verify_elf_rel(struct mem_ehdr *ehdr)
 	return 1;
 }
 
-void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr), unsigned long r_type,
-	void *location, unsigned long address, unsigned long value)
+void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr),
+	struct mem_sym *UNUSED(sym), unsigned long r_type, void *location,
+	unsigned long address, unsigned long value)
 {
 	switch(r_type) {
 	case R_PPC_ADDR32:
kexec/arch/ppc64/kexec-elf-rel-ppc64.c +3 -2
index 9b191d0..8604c4f 100644
@@ -63,8 +63,9 @@ static void do_relative_toc(unsigned long value, uint16_t *location,
 	*location = (*location & ~mask) | (value & mask);
 }
 
-void machine_apply_elf_rel(struct mem_ehdr *ehdr, unsigned long r_type,
-	void *location, unsigned long address, unsigned long value)
+void machine_apply_elf_rel(struct mem_ehdr *ehdr, struct mem_sym *sym,
+	unsigned long r_type, void *location, unsigned long address,
+	unsigned long value)
 {
 	switch(r_type) {
 	case R_PPC64_ADDR32:
kexec/arch/s390/kexec-elf-rel-s390.c +2 -1
index 80bcd1b..a5e1b73 100644
@@ -23,7 +23,8 @@ int machine_verify_elf_rel(struct mem_ehdr *ehdr)
 	return 1;
 }
 
-void machine_apply_elf_rel(struct mem_ehdr *ehdr,
+void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr),
+			   struct mem_sym *UNUSED(sym),
 			   unsigned long r_type,
 			   void *loc,
 			   unsigned long address,
kexec/arch/sh/kexec-elf-rel-sh.c +3 -2
index 0bfc45e..3993ee8 100644
@@ -28,8 +28,9 @@ int machine_verify_elf_rel(struct mem_ehdr *ehdr)
 	return 1;
 }
 
-void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr), unsigned long r_type,
-	void *orig_loc, unsigned long UNUSED(address), unsigned long relocation)
+void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr),
+	struct mem_sym *UNUSED(sym), unsigned long r_type, void *orig_loc,
+	unsigned long UNUSED(address), unsigned long relocation)
 {
 	uint32_t *location = orig_loc;
 	uint32_t value;
kexec/arch/x86_64/kexec-elf-rel-x86_64.c +3 -2
index c795037..7fdde73 100644
@@ -57,8 +57,9 @@ static const char *reloc_name(unsigned long r_type)
 	return name;
 }
 
-void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr), unsigned long r_type,
-	void *location, unsigned long address, unsigned long value)
+void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr),
+	struct mem_sym *UNUSED(sym), unsigned long r_type, void *location,
+	unsigned long address, unsigned long value)
 {
 	dbgprintf("%s\n", reloc_name(r_type));
 	switch(r_type) {
kexec/kexec-elf-rel.c +1 -1
index c625f30..9a6e63d 100644
@@ -408,7 +408,7 @@ int elf_rel_load(struct mem_ehdr *ehdr, struct kexec_info *info,
 			dbgprintf("sym: %s value: %lx addr: %lx\n",
 				name, value, address);
 
-			machine_apply_elf_rel(ehdr, rel.r_type,
+			machine_apply_elf_rel(ehdr, &sym, rel.r_type,
 				(void *)location, address, value);
 		}
 	}
kexec/kexec-elf.h +3 -2
index d0e9dc0..1164db4 100644
@@ -129,7 +129,8 @@ unsigned long elf_max_addr(const struct mem_ehdr *ehdr);
 
 /* Architecture specific helper functions */
 extern int machine_verify_elf_rel(struct mem_ehdr *ehdr);
-extern void machine_apply_elf_rel(struct mem_ehdr *ehdr, unsigned long r_type, 
-	void *location, unsigned long address, unsigned long value);
+extern void machine_apply_elf_rel(struct mem_ehdr *ehdr, struct mem_sym *sym,
+	unsigned long r_type, void *location, unsigned long address,
+	unsigned long value);
 #endif /* KEXEC_ELF_H */
 
Signature · 7 lines
2.5.0


_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

Tested the 3 patches on ppc64le installed Fedora 23 With the patches applied, I can not reproduce the bug below:
https://bugzilla.redhat.com/show_bug.cgi?id=1310495

But loading older kernel ie. 3.10 kernel from RHEL it is not sufficient, still need another patch:
http://lists.infradead.org/pipermail/kexec/2016-February/015445.html

But above one is only necessary for old kernel, there may be some kernel changes for dtb in recent kernel, I'm not sure why kernel versions matter.

Thanks
Dave

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#4 lore raw
Quoted 235 lines · Dave Young
Quoted 229 lines · Anton Blanchard

On PowerPC64 ABIv2 we need to look at the symbol to determine if it has a local entry point. Pass struct mem_sym into machine_apply_elf_rel() so we can.

---
 kexec/arch/arm/kexec-elf-rel-arm.c       | 5 +++--
 kexec/arch/cris/kexec-elf-rel-cris.c     | 5 +++--
 kexec/arch/i386/kexec-elf-rel-x86.c      | 5 +++--
 kexec/arch/ia64/kexec-elf-rel-ia64.c     | 5 +++--
 kexec/arch/m68k/kexec-elf-rel-m68k.c     | 4 +++-
 kexec/arch/mips/kexec-elf-rel-mips.c     | 4 +++-
 kexec/arch/ppc/kexec-elf-rel-ppc.c       | 5 +++--
 kexec/arch/ppc64/kexec-elf-rel-ppc64.c   | 5 +++--
 kexec/arch/s390/kexec-elf-rel-s390.c     | 3 ++-
 kexec/arch/sh/kexec-elf-rel-sh.c         | 5 +++--
 kexec/arch/x86_64/kexec-elf-rel-x86_64.c | 5 +++--
 kexec/kexec-elf-rel.c                    | 2 +-
 kexec/kexec-elf.h                        | 5 +++--
 13 files changed, 36 insertions(+), 22 deletions(-)
kexec/arch/arm/kexec-elf-rel-arm.c +3 -2
index 214f0cc..a939cf4 100644
@@ -18,8 +18,9 @@ int machine_verify_elf_rel(struct mem_ehdr *ehdr)
 	return 1;
 }
 
-void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr), unsigned long r_type,
-	void *location, unsigned long address, unsigned long value)
+void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr),
+	struct mem_sym *UNUSED(sym), unsigned long r_type, void *location,
+	unsigned long address, unsigned long value)
 {
 	switch(r_type) {
 	case R_ARM_ABS32:
kexec/arch/cris/kexec-elf-rel-cris.c +3 -2
index c4427cc..255cc2c 100644
@@ -29,8 +29,9 @@ int machine_verify_elf_rel(struct mem_ehdr *ehdr)
 	return 1;
 }
 
-void machine_apply_elf_rel(struct mem_ehdr *ehdr, unsigned long r_type,
-	void *location, unsigned long address, unsigned long value)
+void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr),
+	struct mem_sym *UNUSED(sym), unsigned long r_type, void *location,
+	unsigned long address, unsigned long value)
 {
 	switch(r_type) {
 
kexec/arch/i386/kexec-elf-rel-x86.c +3 -2
index fdc3d52..55a214e 100644
@@ -18,8 +18,9 @@ int machine_verify_elf_rel(struct mem_ehdr *ehdr)
 	return 1;
 }
 
-void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr), unsigned long r_type,
-	void *location, unsigned long address, unsigned long value)
+void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr),
+	struct mem_sym *UNUSED(sym), unsigned long r_type, void *location,
+	unsigned long address, unsigned long value)
 {
 	switch(r_type) {
 	case R_386_32:
kexec/arch/ia64/kexec-elf-rel-ia64.c +3 -2
index cfb1061..f847626 100644
@@ -72,8 +72,9 @@ bundle (const uint64_t insn)
         return insn & ~0xfUL;
 }
 
-void machine_apply_elf_rel(struct mem_ehdr *ehdr, unsigned long r_type,
-	void *location, unsigned long address, unsigned long value)
+void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr),
+	struct mem_sym *UNUSED(sym), unsigned long r_type, void *location,
+	unsigned long address, unsigned long value)
 {
 	uint64_t gp_value = ehdr->rel_addr + 0x200000;
 	switch(r_type) {
kexec/arch/m68k/kexec-elf-rel-m68k.c +3 -1
index fa12a16..0cc38cc 100644
@@ -23,7 +23,9 @@ int machine_verify_elf_rel(struct mem_ehdr *ehdr)
 	return 1;
 }
 
-void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr), unsigned long r_type,
+void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr),
+			   struct mem_sym *UNUSED(sym),
+			   unsigned long r_type,
 			   void *UNUSED(location),
 			   unsigned long UNUSED(address),
 			   unsigned long UNUSED(value))
kexec/arch/mips/kexec-elf-rel-mips.c +3 -1
index 6f43639..5bc22d5 100644
@@ -29,7 +29,9 @@ int machine_verify_elf_rel(struct mem_ehdr *ehdr)
 	return 1;
 }
 
-void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr), unsigned long r_type,
+void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr),
+			   struct mem_sym *UNUSED(sym),
+			   unsigned long r_type,
 			   void *UNUSED(location),
 			   unsigned long UNUSED(address),
 			   unsigned long UNUSED(value))
kexec/arch/ppc/kexec-elf-rel-ppc.c +3 -2
index 90a66f4..1acbd86 100644
@@ -17,8 +17,9 @@ int machine_verify_elf_rel(struct mem_ehdr *ehdr)
 	return 1;
 }
 
-void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr), unsigned long r_type,
-	void *location, unsigned long address, unsigned long value)
+void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr),
+	struct mem_sym *UNUSED(sym), unsigned long r_type, void *location,
+	unsigned long address, unsigned long value)
 {
 	switch(r_type) {
 	case R_PPC_ADDR32:
kexec/arch/ppc64/kexec-elf-rel-ppc64.c +3 -2
index 9b191d0..8604c4f 100644
@@ -63,8 +63,9 @@ static void do_relative_toc(unsigned long value, uint16_t *location,
 	*location = (*location & ~mask) | (value & mask);
 }
 
-void machine_apply_elf_rel(struct mem_ehdr *ehdr, unsigned long r_type,
-	void *location, unsigned long address, unsigned long value)
+void machine_apply_elf_rel(struct mem_ehdr *ehdr, struct mem_sym *sym,
+	unsigned long r_type, void *location, unsigned long address,
+	unsigned long value)
 {
 	switch(r_type) {
 	case R_PPC64_ADDR32:
kexec/arch/s390/kexec-elf-rel-s390.c +2 -1
index 80bcd1b..a5e1b73 100644
@@ -23,7 +23,8 @@ int machine_verify_elf_rel(struct mem_ehdr *ehdr)
 	return 1;
 }
 
-void machine_apply_elf_rel(struct mem_ehdr *ehdr,
+void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr),
+			   struct mem_sym *UNUSED(sym),
 			   unsigned long r_type,
 			   void *loc,
 			   unsigned long address,
kexec/arch/sh/kexec-elf-rel-sh.c +3 -2
index 0bfc45e..3993ee8 100644
@@ -28,8 +28,9 @@ int machine_verify_elf_rel(struct mem_ehdr *ehdr)
 	return 1;
 }
 
-void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr), unsigned long r_type,
-	void *orig_loc, unsigned long UNUSED(address), unsigned long relocation)
+void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr),
+	struct mem_sym *UNUSED(sym), unsigned long r_type, void *orig_loc,
+	unsigned long UNUSED(address), unsigned long relocation)
 {
 	uint32_t *location = orig_loc;
 	uint32_t value;
kexec/arch/x86_64/kexec-elf-rel-x86_64.c +3 -2
index c795037..7fdde73 100644
@@ -57,8 +57,9 @@ static const char *reloc_name(unsigned long r_type)
 	return name;
 }
 
-void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr), unsigned long r_type,
-	void *location, unsigned long address, unsigned long value)
+void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr),
+	struct mem_sym *UNUSED(sym), unsigned long r_type, void *location,
+	unsigned long address, unsigned long value)
 {
 	dbgprintf("%s\n", reloc_name(r_type));
 	switch(r_type) {
kexec/kexec-elf-rel.c +1 -1
index c625f30..9a6e63d 100644
@@ -408,7 +408,7 @@ int elf_rel_load(struct mem_ehdr *ehdr, struct kexec_info *info,
 			dbgprintf("sym: %s value: %lx addr: %lx\n",
 				name, value, address);
 
-			machine_apply_elf_rel(ehdr, rel.r_type,
+			machine_apply_elf_rel(ehdr, &sym, rel.r_type,
 				(void *)location, address, value);
 		}
 	}
kexec/kexec-elf.h +3 -2
index d0e9dc0..1164db4 100644
@@ -129,7 +129,8 @@ unsigned long elf_max_addr(const struct mem_ehdr *ehdr);
 
 /* Architecture specific helper functions */
 extern int machine_verify_elf_rel(struct mem_ehdr *ehdr);
-extern void machine_apply_elf_rel(struct mem_ehdr *ehdr, unsigned long r_type, 
-	void *location, unsigned long address, unsigned long value);
+extern void machine_apply_elf_rel(struct mem_ehdr *ehdr, struct mem_sym *sym,
+	unsigned long r_type, void *location, unsigned long address,
+	unsigned long value);
 #endif /* KEXEC_ELF_H */
 
Signature · 7 lines
2.5.0


_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

Tested the 3 patches on ppc64le installed Fedora 23 With the patches applied, I can not reproduce the bug below:
https://bugzilla.redhat.com/show_bug.cgi?id=1310495

Quoted 9 lines

But loading older kernel ie. 3.10 kernel from RHEL it is not sufficient, still need another patch:
http://lists.infradead.org/pipermail/kexec/2016-February/015445.html

But above one is only necessary for old kernel, there may be some kernel changes for dtb in recent kernel, I'm not sure why kernel versions matter.

Can ppc people review these three patches? they works for me, test passed for bug below:
https://bugzilla.redhat.com/show_bug.cgi?id=1310495

I hope we can get it merged in Simon's next release.

Who is the right people to cc?

Thanks
Dave

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#5 lore raw
In reply to Anton Blanchard
Quoted 5 lines · Anton Blanchard

On PowerPC64 ABIv2 we need to look at the symbol to determine if it has a local entry point. Pass struct mem_sym into machine_apply_elf_rel() so we can.

Anton, Alan and Bill clearly know this stuff inside and out but can we get a review from other PPC folks ?

It'd be awesom to see this merged in distros.

Tony.

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#6 lore raw
Quoted 10 lines · Tony Breeds
Quoted 5 lines · Anton Blanchard

On PowerPC64 ABIv2 we need to look at the symbol to determine if it has a local entry point. Pass struct mem_sym into machine_apply_elf_rel() so we can.

Anton, Alan and Bill clearly know this stuff inside and out but can we get a review from other PPC folks ?

LGTM.

cheers

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#7 lore raw
Quoted 8 lines · Michael Ellerman
Quoted 6 lines · Tony Breeds
Quoted 4 lines · Anton Blanchard

On PowerPC64 ABIv2 we need to look at the symbol to determine if it has a local entry point. Pass struct mem_sym into machine_apply_elf_rel() so we can.

Quoted 6 lines
Quoted 4 lines
Quoted 1 line

Anton, Alan and Bill clearly know this stuff inside and out but can we get a review from other PPC folks ?

LGTM.

Thanks, I have applied the entire series.

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec