diff options
Diffstat (limited to 'arch/arm/kernel/module.c')
| -rw-r--r-- | arch/arm/kernel/module.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c index 2cfe8161b478..6d4105e6872f 100644 --- a/arch/arm/kernel/module.c +++ b/arch/arm/kernel/module.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | 22 | ||
| 23 | #include <asm/pgtable.h> | 23 | #include <asm/pgtable.h> |
| 24 | #include <asm/sections.h> | 24 | #include <asm/sections.h> |
| 25 | #include <asm/smp_plat.h> | ||
| 25 | #include <asm/unwind.h> | 26 | #include <asm/unwind.h> |
| 26 | 27 | ||
| 27 | #ifdef CONFIG_XIP_KERNEL | 28 | #ifdef CONFIG_XIP_KERNEL |
| @@ -268,12 +269,28 @@ struct mod_unwind_map { | |||
| 268 | const Elf_Shdr *txt_sec; | 269 | const Elf_Shdr *txt_sec; |
| 269 | }; | 270 | }; |
| 270 | 271 | ||
| 272 | static const Elf_Shdr *find_mod_section(const Elf32_Ehdr *hdr, | ||
| 273 | const Elf_Shdr *sechdrs, const char *name) | ||
| 274 | { | ||
| 275 | const Elf_Shdr *s, *se; | ||
| 276 | const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; | ||
| 277 | |||
| 278 | for (s = sechdrs, se = sechdrs + hdr->e_shnum; s < se; s++) | ||
| 279 | if (strcmp(name, secstrs + s->sh_name) == 0) | ||
| 280 | return s; | ||
| 281 | |||
| 282 | return NULL; | ||
| 283 | } | ||
| 284 | |||
| 285 | extern void fixup_smp(const void *, unsigned long); | ||
| 286 | |||
| 271 | int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs, | 287 | int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs, |
| 272 | struct module *mod) | 288 | struct module *mod) |
| 273 | { | 289 | { |
| 290 | const Elf_Shdr * __maybe_unused s = NULL; | ||
| 274 | #ifdef CONFIG_ARM_UNWIND | 291 | #ifdef CONFIG_ARM_UNWIND |
| 275 | const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; | 292 | const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; |
| 276 | const Elf_Shdr *s, *sechdrs_end = sechdrs + hdr->e_shnum; | 293 | const Elf_Shdr *sechdrs_end = sechdrs + hdr->e_shnum; |
| 277 | struct mod_unwind_map maps[ARM_SEC_MAX]; | 294 | struct mod_unwind_map maps[ARM_SEC_MAX]; |
| 278 | int i; | 295 | int i; |
| 279 | 296 | ||
| @@ -315,6 +332,9 @@ int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs, | |||
| 315 | maps[i].txt_sec->sh_addr, | 332 | maps[i].txt_sec->sh_addr, |
| 316 | maps[i].txt_sec->sh_size); | 333 | maps[i].txt_sec->sh_size); |
| 317 | #endif | 334 | #endif |
| 335 | s = find_mod_section(hdr, sechdrs, ".alt.smp.init"); | ||
| 336 | if (s && !is_smp()) | ||
| 337 | fixup_smp((void *)s->sh_addr, s->sh_size); | ||
| 318 | return 0; | 338 | return 0; |
| 319 | } | 339 | } |
| 320 | 340 | ||
