All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] alpha: fix R_ALPHA_LITERAL reloc for large modules
@ 2022-10-13  8:37 Edward Humes
  0 siblings, 0 replies; 3+ messages in thread
From: Edward Humes @ 2022-10-13  8:37 UTC (permalink / raw)
  To: linux-alpha; +Cc: mattst88, ink, richard.henderson, Edward Humes

Previously, R_ALPHA_LITERAL relocations would overflow for large kernel
modules.

This was because the Alpha's apply_relocate_add was relying on the kernel's
module loader to have sorted the GOT towards the very end of the module as it
was mapped into memory in order to correctly assign the global pointer. While
this behavior would mostly work fine for small kernel modules, this approach
would overflow on kernel modules with large GOT's since the global pointer
would be very far away from the GOT, and thus, certain entries would be out of
range.

This patch fixes this by instead using the Tru64 behavior of assigning the
global pointer to be 32KB away from the start of the GOT. The change made
in this patch won't work for multi-GOT kernel modules as it makes the
assumption the module only has one GOT located at the beginning of .got,
although for the vast majority kernel modules, this should be fine. Of the
kernel modules that would previously result in a relocation error, none of
them, even modules like nouveau, have even come close to filling up a single
GOT, and they've all worked fine under this patch.

Signed-off-by: Edward Humes <aurxenon@lunos.org>
---
 arch/alpha/kernel/module.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/arch/alpha/kernel/module.c b/arch/alpha/kernel/module.c
index 5b60c248de9e..cbefa5a77384 100644
--- a/arch/alpha/kernel/module.c
+++ b/arch/alpha/kernel/module.c
@@ -146,10 +146,8 @@ apply_relocate_add(Elf64_Shdr *sechdrs, const char *strtab,
 	base = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr;
 	symtab = (Elf64_Sym *)sechdrs[symindex].sh_addr;
 
-	/* The small sections were sorted to the end of the segment.
-	   The following should definitely cover them.  */
-	gp = (u64)me->core_layout.base + me->core_layout.size - 0x8000;
 	got = sechdrs[me->arch.gotsecindex].sh_addr;
+	gp = got + 0x8000;
 
 	for (i = 0; i < n; i++) {
 		unsigned long r_sym = ELF64_R_SYM (rela[i].r_info);
-- 
2.34.1


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

* Re: [PATCH] alpha: fix R_ALPHA_LITERAL reloc for large modules
  2022-08-27  6:49 Edward Humes
@ 2023-02-26  2:04 ` Matt Turner
  0 siblings, 0 replies; 3+ messages in thread
From: Matt Turner @ 2023-02-26  2:04 UTC (permalink / raw)
  To: Edward Humes; +Cc: linux-alpha, ink, richard.henderson

On Sat, Aug 27, 2022 at 2:49 AM Edward Humes <aurxenon@lunos.org> wrote:
>
> Previously, R_ALPHA_LITERAL relocations would overflow for large kernel
> modules.
>
> This was because the Alpha's apply_relocate_add was relying on the kernel's
> module loader to have sorted the GOT towards the very end of the module as it
> was mapped into memory in order to correctly assign the global pointer. While
> this behavior would mostly work fine for small kernel modules, this approach
> would overflow on kernel modules with large GOT's since the global pointer
> would be very far away from the GOT, and thus, certain entries would be out of
> range.
>
> This patch fixes this by instead using the Tru64 behavior of assigning the
> global pointer to be 32KB away from the start of the GOT. The change made
> in this patch won't work for multi-GOT kernel modules as it makes the
> assumption the module only has one GOT located at the beginning of .got,
> although for the vast majority kernel modules, this should be fine. Of the
> kernel modules that would previously result in a relocation error, none of
> them, even modules like nouveau, have even come close to filling up a single
> GOT, and they've all worked fine under this patch.
>
> Signed-off-by: Edward Humes <aurxenon@lunos.org>
> ---
>  arch/alpha/kernel/module.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
>
> diff --git a/arch/alpha/kernel/module.c b/arch/alpha/kernel/module.c
> index 5b60c248de9e..cbefa5a77384 100644
> --- a/arch/alpha/kernel/module.c
> +++ b/arch/alpha/kernel/module.c
> @@ -146,10 +146,8 @@ apply_relocate_add(Elf64_Shdr *sechdrs, const char *strtab,
>         base = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr;
>         symtab = (Elf64_Sym *)sechdrs[symindex].sh_addr;
>
> -       /* The small sections were sorted to the end of the segment.
> -          The following should definitely cover them.  */
> -       gp = (u64)me->core_layout.base + me->core_layout.size - 0x8000;
>         got = sechdrs[me->arch.gotsecindex].sh_addr;
> +       gp = got + 0x8000;
>
>         for (i = 0; i < n; i++) {
>                 unsigned long r_sym = ELF64_R_SYM (rela[i].r_info);
> --
> 2.34.1
>

Thanks for the patch! This was included in my pull request today and
is now upstream in Linus' tree.

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

* [PATCH] alpha: fix R_ALPHA_LITERAL reloc for large modules
@ 2022-08-27  6:49 Edward Humes
  2023-02-26  2:04 ` Matt Turner
  0 siblings, 1 reply; 3+ messages in thread
From: Edward Humes @ 2022-08-27  6:49 UTC (permalink / raw)
  To: linux-alpha; +Cc: mattst88, ink, richard.henderson, Edward Humes

Previously, R_ALPHA_LITERAL relocations would overflow for large kernel
modules.

This was because the Alpha's apply_relocate_add was relying on the kernel's
module loader to have sorted the GOT towards the very end of the module as it
was mapped into memory in order to correctly assign the global pointer. While
this behavior would mostly work fine for small kernel modules, this approach
would overflow on kernel modules with large GOT's since the global pointer
would be very far away from the GOT, and thus, certain entries would be out of
range.

This patch fixes this by instead using the Tru64 behavior of assigning the
global pointer to be 32KB away from the start of the GOT. The change made
in this patch won't work for multi-GOT kernel modules as it makes the
assumption the module only has one GOT located at the beginning of .got,
although for the vast majority kernel modules, this should be fine. Of the
kernel modules that would previously result in a relocation error, none of
them, even modules like nouveau, have even come close to filling up a single
GOT, and they've all worked fine under this patch.

Signed-off-by: Edward Humes <aurxenon@lunos.org>
---
 arch/alpha/kernel/module.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/arch/alpha/kernel/module.c b/arch/alpha/kernel/module.c
index 5b60c248de9e..cbefa5a77384 100644
--- a/arch/alpha/kernel/module.c
+++ b/arch/alpha/kernel/module.c
@@ -146,10 +146,8 @@ apply_relocate_add(Elf64_Shdr *sechdrs, const char *strtab,
 	base = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr;
 	symtab = (Elf64_Sym *)sechdrs[symindex].sh_addr;
 
-	/* The small sections were sorted to the end of the segment.
-	   The following should definitely cover them.  */
-	gp = (u64)me->core_layout.base + me->core_layout.size - 0x8000;
 	got = sechdrs[me->arch.gotsecindex].sh_addr;
+	gp = got + 0x8000;
 
 	for (i = 0; i < n; i++) {
 		unsigned long r_sym = ELF64_R_SYM (rela[i].r_info);
-- 
2.34.1


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

end of thread, other threads:[~2023-02-26  2:04 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-13  8:37 [PATCH] alpha: fix R_ALPHA_LITERAL reloc for large modules Edward Humes
  -- strict thread matches above, loose matches on Subject: below --
2022-08-27  6:49 Edward Humes
2023-02-26  2:04 ` Matt Turner

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.