All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] x86/tools: deal with 64-bit relative relocations for per-CPU symbols
@ 2019-05-22 17:40 ` Ard Biesheuvel
  0 siblings, 0 replies; 4+ messages in thread
From: Ard Biesheuvel @ 2019-05-22 17:40 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: marc.zyngier, james.morse, will.deacon, guillaume.gardet,
	mark.rutland, mingo, jeyu, linux-kernel, linux-arch, arnd, x86,
	Ard Biesheuvel

In order to fix an issue in the place relative ksymtab code, we
need to switch to 64-bit place relative references, which
require special handling in the x86 'relocs' tool. The reason
is that per-CPU symbols on x86_64 live in a separate link time
section, whose load time address is not reflected in the ELF
metadata, and so relative references emitted by the toolchain
are guaranteed to be wrong.

So fix this by extending the handling of 32-bit relative references
to per-CPU variables to support 64-bit relative references as
well.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
---
This is a follow-up to [0] and a prerequisite to the change it
implements: using 64-bit relative references on x86_64 requires
this handling in the 'relocs' tool and in the decompressor.

[0] https://lore.kernel.org/linux-arm-kernel/20190522150239.19314-1-ard.biesheuvel@arm.com

This patch plus [0] build and boot tested with x86_64_defconfig on QEMU/kvm + OVMF.

 arch/x86/boot/compressed/misc.c | 12 ++++++++++++
 arch/x86/tools/relocs.c         | 15 ++++++++++-----
 2 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c
index 5a237e8dbf8d..e089d78bd86a 100644
--- a/arch/x86/boot/compressed/misc.c
+++ b/arch/x86/boot/compressed/misc.c
@@ -218,6 +218,8 @@ static void handle_relocations(void *output, unsigned long output_len,
 	 * Format is:
 	 *
 	 * kernel bits...
+	 * 0 - zero terminator for inverse 64 bit relocations
+	 * 64 bit inverse relocation repeated
 	 * 0 - zero terminator for 64 bit relocations
 	 * 64 bit relocation repeated
 	 * 0 - zero terminator for inverse 32 bit relocations
@@ -258,6 +260,16 @@ static void handle_relocations(void *output, unsigned long output_len,
 
 		*(uint64_t *)ptr += delta;
 	}
+	while (*--reloc) {
+		long extended = *reloc;
+		extended += map;
+
+		ptr = (unsigned long)extended;
+		if (ptr < min_addr || ptr > max_addr)
+			error("inverse 64-bit relocation outside of kernel!\n");
+
+		*(uint64_t *)ptr -= delta;
+	}
 #endif
 }
 #else
diff --git a/arch/x86/tools/relocs.c b/arch/x86/tools/relocs.c
index ce7188cbdae5..d6a2bb90dfa6 100644
--- a/arch/x86/tools/relocs.c
+++ b/arch/x86/tools/relocs.c
@@ -26,6 +26,7 @@ static struct relocs relocs32;
 #if ELF_BITS == 64
 static struct relocs relocs32neg;
 static struct relocs relocs64;
+static struct relocs relocs64neg;
 #endif
 
 struct section {
@@ -800,12 +801,8 @@ static int do_reloc64(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym,
 		break;
 
 	case R_X86_64_PC64:
-		/*
-		 * Only used by jump labels
-		 */
 		if (is_percpu_sym(sym, symname))
-			die("Invalid R_X86_64_PC64 relocation against per-CPU symbol %s\n",
-			    symname);
+			add_reloc(&relocs64neg, offset);
 		break;
 
 	case R_X86_64_32:
@@ -1027,6 +1024,7 @@ static void emit_relocs(int as_text, int use_real_mode)
 #if ELF_BITS == 64
 	sort_relocs(&relocs32neg);
 	sort_relocs(&relocs64);
+	sort_relocs(&relocs64neg);
 #else
 	sort_relocs(&relocs16);
 #endif
@@ -1054,6 +1052,13 @@ static void emit_relocs(int as_text, int use_real_mode)
 		/* Print a stop */
 		write_reloc(0, stdout);
 
+		/* Now print each inverse 64-bit relocation */
+		for (i = 0; i < relocs64neg.count; i++)
+			write_reloc(relocs64neg.offset[i], stdout);
+
+		/* Print a stop */
+		write_reloc(0, stdout);
+
 		/* Now print each relocation */
 		for (i = 0; i < relocs64.count; i++)
 			write_reloc(relocs64.offset[i], stdout);
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH] x86/tools: deal with 64-bit relative relocations for per-CPU symbols
@ 2019-05-22 17:40 ` Ard Biesheuvel
  0 siblings, 0 replies; 4+ messages in thread
From: Ard Biesheuvel @ 2019-05-22 17:40 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: mark.rutland, linux-arch, arnd, guillaume.gardet, marc.zyngier,
	x86, will.deacon, linux-kernel, james.morse, Ard Biesheuvel,
	jeyu, mingo

In order to fix an issue in the place relative ksymtab code, we
need to switch to 64-bit place relative references, which
require special handling in the x86 'relocs' tool. The reason
is that per-CPU symbols on x86_64 live in a separate link time
section, whose load time address is not reflected in the ELF
metadata, and so relative references emitted by the toolchain
are guaranteed to be wrong.

So fix this by extending the handling of 32-bit relative references
to per-CPU variables to support 64-bit relative references as
well.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
---
This is a follow-up to [0] and a prerequisite to the change it
implements: using 64-bit relative references on x86_64 requires
this handling in the 'relocs' tool and in the decompressor.

[0] https://lore.kernel.org/linux-arm-kernel/20190522150239.19314-1-ard.biesheuvel@arm.com

This patch plus [0] build and boot tested with x86_64_defconfig on QEMU/kvm + OVMF.

 arch/x86/boot/compressed/misc.c | 12 ++++++++++++
 arch/x86/tools/relocs.c         | 15 ++++++++++-----
 2 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c
index 5a237e8dbf8d..e089d78bd86a 100644
--- a/arch/x86/boot/compressed/misc.c
+++ b/arch/x86/boot/compressed/misc.c
@@ -218,6 +218,8 @@ static void handle_relocations(void *output, unsigned long output_len,
 	 * Format is:
 	 *
 	 * kernel bits...
+	 * 0 - zero terminator for inverse 64 bit relocations
+	 * 64 bit inverse relocation repeated
 	 * 0 - zero terminator for 64 bit relocations
 	 * 64 bit relocation repeated
 	 * 0 - zero terminator for inverse 32 bit relocations
@@ -258,6 +260,16 @@ static void handle_relocations(void *output, unsigned long output_len,
 
 		*(uint64_t *)ptr += delta;
 	}
+	while (*--reloc) {
+		long extended = *reloc;
+		extended += map;
+
+		ptr = (unsigned long)extended;
+		if (ptr < min_addr || ptr > max_addr)
+			error("inverse 64-bit relocation outside of kernel!\n");
+
+		*(uint64_t *)ptr -= delta;
+	}
 #endif
 }
 #else
diff --git a/arch/x86/tools/relocs.c b/arch/x86/tools/relocs.c
index ce7188cbdae5..d6a2bb90dfa6 100644
--- a/arch/x86/tools/relocs.c
+++ b/arch/x86/tools/relocs.c
@@ -26,6 +26,7 @@ static struct relocs relocs32;
 #if ELF_BITS == 64
 static struct relocs relocs32neg;
 static struct relocs relocs64;
+static struct relocs relocs64neg;
 #endif
 
 struct section {
@@ -800,12 +801,8 @@ static int do_reloc64(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym,
 		break;
 
 	case R_X86_64_PC64:
-		/*
-		 * Only used by jump labels
-		 */
 		if (is_percpu_sym(sym, symname))
-			die("Invalid R_X86_64_PC64 relocation against per-CPU symbol %s\n",
-			    symname);
+			add_reloc(&relocs64neg, offset);
 		break;
 
 	case R_X86_64_32:
@@ -1027,6 +1024,7 @@ static void emit_relocs(int as_text, int use_real_mode)
 #if ELF_BITS == 64
 	sort_relocs(&relocs32neg);
 	sort_relocs(&relocs64);
+	sort_relocs(&relocs64neg);
 #else
 	sort_relocs(&relocs16);
 #endif
@@ -1054,6 +1052,13 @@ static void emit_relocs(int as_text, int use_real_mode)
 		/* Print a stop */
 		write_reloc(0, stdout);
 
+		/* Now print each inverse 64-bit relocation */
+		for (i = 0; i < relocs64neg.count; i++)
+			write_reloc(relocs64neg.offset[i], stdout);
+
+		/* Print a stop */
+		write_reloc(0, stdout);
+
 		/* Now print each relocation */
 		for (i = 0; i < relocs64.count; i++)
 			write_reloc(relocs64.offset[i], stdout);
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] x86/tools: deal with 64-bit relative relocations for per-CPU symbols
  2019-05-22 17:40 ` Ard Biesheuvel
@ 2019-05-24 17:42   ` Josh Poimboeuf
  -1 siblings, 0 replies; 4+ messages in thread
From: Josh Poimboeuf @ 2019-05-24 17:42 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: linux-arm-kernel, marc.zyngier, james.morse, will.deacon,
	guillaume.gardet, mark.rutland, mingo, jeyu, linux-kernel,
	linux-arch, arnd, x86

On Wed, May 22, 2019 at 06:40:57PM +0100, Ard Biesheuvel wrote:
> In order to fix an issue in the place relative ksymtab code, we
> need to switch to 64-bit place relative references, which
> require special handling in the x86 'relocs' tool. The reason
> is that per-CPU symbols on x86_64 live in a separate link time
> section, whose load time address is not reflected in the ELF
> metadata, and so relative references emitted by the toolchain
> are guaranteed to be wrong.
> 
> So fix this by extending the handling of 32-bit relative references
> to per-CPU variables to support 64-bit relative references as
> well.
> 
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
> ---
> This is a follow-up to [0] and a prerequisite to the change it
> implements: using 64-bit relative references on x86_64 requires
> this handling in the 'relocs' tool and in the decompressor.
> 
> [0] https://lore.kernel.org/linux-arm-kernel/20190522150239.19314-1-ard.biesheuvel@arm.com
> 
> This patch plus [0] build and boot tested with x86_64_defconfig on QEMU/kvm + OVMF.

NACK based on

https://lkml.kernel.org/r/f2141ee5-d07a-6dd9-47c6-97e8fbdccf34@arm.com

-- 
Josh

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] x86/tools: deal with 64-bit relative relocations for per-CPU symbols
@ 2019-05-24 17:42   ` Josh Poimboeuf
  0 siblings, 0 replies; 4+ messages in thread
From: Josh Poimboeuf @ 2019-05-24 17:42 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: mark.rutland, linux-arch, arnd, guillaume.gardet, marc.zyngier,
	x86, will.deacon, linux-kernel, james.morse, jeyu, mingo,
	linux-arm-kernel

On Wed, May 22, 2019 at 06:40:57PM +0100, Ard Biesheuvel wrote:
> In order to fix an issue in the place relative ksymtab code, we
> need to switch to 64-bit place relative references, which
> require special handling in the x86 'relocs' tool. The reason
> is that per-CPU symbols on x86_64 live in a separate link time
> section, whose load time address is not reflected in the ELF
> metadata, and so relative references emitted by the toolchain
> are guaranteed to be wrong.
> 
> So fix this by extending the handling of 32-bit relative references
> to per-CPU variables to support 64-bit relative references as
> well.
> 
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
> ---
> This is a follow-up to [0] and a prerequisite to the change it
> implements: using 64-bit relative references on x86_64 requires
> this handling in the 'relocs' tool and in the decompressor.
> 
> [0] https://lore.kernel.org/linux-arm-kernel/20190522150239.19314-1-ard.biesheuvel@arm.com
> 
> This patch plus [0] build and boot tested with x86_64_defconfig on QEMU/kvm + OVMF.

NACK based on

https://lkml.kernel.org/r/f2141ee5-d07a-6dd9-47c6-97e8fbdccf34@arm.com

-- 
Josh

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-05-24 17:42 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-22 17:40 [PATCH] x86/tools: deal with 64-bit relative relocations for per-CPU symbols Ard Biesheuvel
2019-05-22 17:40 ` Ard Biesheuvel
2019-05-24 17:42 ` Josh Poimboeuf
2019-05-24 17:42   ` Josh Poimboeuf

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.