mirror of
https://git.yoctoproject.org/meta-ti
synced 2026-07-16 22:38:04 +00:00
646ff9d602
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net> Signed-off-by: Denys Dmytriyenko <denys@ti.com>
71 lines
2.8 KiB
Diff
71 lines
2.8 KiB
Diff
From 5c6f8c50fe40cec7015a6bfa9762bf76d52211d6 Mon Sep 17 00:00:00 2001
|
|
From: Steffen Rumler <steffen.rumler.ext@nsn.com>
|
|
Date: Wed, 6 Jun 2012 16:37:17 +0200
|
|
Subject: [PATCH 07/67] powerpc: Fix kernel panic during kernel module load
|
|
|
|
commit 3c75296562f43e6fbc6cddd3de948a7b3e4e9bcf upstream.
|
|
|
|
This fixes a problem which can causes kernel oopses while loading
|
|
a kernel module.
|
|
|
|
According to the PowerPC EABI specification, GPR r11 is assigned
|
|
the dedicated function to point to the previous stack frame.
|
|
In the powerpc-specific kernel module loader, do_plt_call()
|
|
(in arch/powerpc/kernel/module_32.c), GPR r11 is also used
|
|
to generate trampoline code.
|
|
|
|
This combination crashes the kernel, in the case where the compiler
|
|
chooses to use a helper function for saving GPRs on entry, and the
|
|
module loader has placed the .init.text section far away from the
|
|
.text section, meaning that it has to generate a trampoline for
|
|
functions in the .init.text section to call the GPR save helper.
|
|
Because the trampoline trashes r11, references to the stack frame
|
|
using r11 can cause an oops.
|
|
|
|
The fix just uses GPR r12 instead of GPR r11 for generating the
|
|
trampoline code. According to the statements from Freescale, this is
|
|
safe from an EABI perspective.
|
|
|
|
I've tested the fix for kernel 2.6.33 on MPC8541.
|
|
|
|
Signed-off-by: Steffen Rumler <steffen.rumler.ext@nsn.com>
|
|
[paulus@samba.org: reworded the description]
|
|
Signed-off-by: Paul Mackerras <paulus@samba.org>
|
|
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
|
---
|
|
arch/powerpc/kernel/module_32.c | 11 +++++------
|
|
1 file changed, 5 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/arch/powerpc/kernel/module_32.c b/arch/powerpc/kernel/module_32.c
|
|
index 0b6d796..2e3200c 100644
|
|
--- a/arch/powerpc/kernel/module_32.c
|
|
+++ b/arch/powerpc/kernel/module_32.c
|
|
@@ -176,8 +176,8 @@ int module_frob_arch_sections(Elf32_Ehdr *hdr,
|
|
|
|
static inline int entry_matches(struct ppc_plt_entry *entry, Elf32_Addr val)
|
|
{
|
|
- if (entry->jump[0] == 0x3d600000 + ((val + 0x8000) >> 16)
|
|
- && entry->jump[1] == 0x396b0000 + (val & 0xffff))
|
|
+ if (entry->jump[0] == 0x3d800000 + ((val + 0x8000) >> 16)
|
|
+ && entry->jump[1] == 0x398c0000 + (val & 0xffff))
|
|
return 1;
|
|
return 0;
|
|
}
|
|
@@ -204,10 +204,9 @@ static uint32_t do_plt_call(void *location,
|
|
entry++;
|
|
}
|
|
|
|
- /* Stolen from Paul Mackerras as well... */
|
|
- entry->jump[0] = 0x3d600000+((val+0x8000)>>16); /* lis r11,sym@ha */
|
|
- entry->jump[1] = 0x396b0000 + (val&0xffff); /* addi r11,r11,sym@l*/
|
|
- entry->jump[2] = 0x7d6903a6; /* mtctr r11 */
|
|
+ entry->jump[0] = 0x3d800000+((val+0x8000)>>16); /* lis r12,sym@ha */
|
|
+ entry->jump[1] = 0x398c0000 + (val&0xffff); /* addi r12,r12,sym@l*/
|
|
+ entry->jump[2] = 0x7d8903a6; /* mtctr r12 */
|
|
entry->jump[3] = 0x4e800420; /* bctr */
|
|
|
|
DEBUGP("Initialized plt for 0x%x at %p\n", val, entry);
|
|
--
|
|
1.7.9.5
|
|
|