mm/execmem, arch: convert remaining overrides of module_alloc to execmem
[linux-block.git] / arch / powerpc / kernel / module.c
CommitLineData
1a59d1b8 1// SPDX-License-Identifier: GPL-2.0-or-later
f0c426bc
KG
2/* Kernel module help for powerpc.
3 Copyright (C) 2001, 2003 Rusty Russell IBM Corporation.
4 Copyright (C) 2008 Freescale Semiconductor, Inc.
5
f0c426bc 6*/
f0c426bc
KG
7#include <linux/elf.h>
8#include <linux/moduleloader.h>
9#include <linux/err.h>
10#include <linux/vmalloc.h>
8abddd96 11#include <linux/mm.h>
f0c426bc 12#include <linux/bug.h>
223b5e57 13#include <linux/execmem.h>
f0c426bc 14#include <asm/module.h>
7c0f6ba6 15#include <linux/uaccess.h>
f0c426bc
KG
16#include <asm/firmware.h>
17#include <linux/sort.h>
b88c4767 18#include <asm/setup.h>
2ec13df1 19#include <asm/sections.h>
f0c426bc 20
7c98bd72 21static LIST_HEAD(module_bug_list);
f0c426bc 22
f0c426bc
KG
23static const Elf_Shdr *find_section(const Elf_Ehdr *hdr,
24 const Elf_Shdr *sechdrs,
25 const char *name)
26{
27 char *secstrings;
28 unsigned int i;
29
30 secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
31 for (i = 1; i < hdr->e_shnum; i++)
32 if (strcmp(secstrings+sechdrs[i].sh_name, name) == 0)
33 return &sechdrs[i];
34 return NULL;
35}
36
37int module_finalize(const Elf_Ehdr *hdr,
38 const Elf_Shdr *sechdrs, struct module *me)
39{
40 const Elf_Shdr *sect;
136cd345
ME
41 int rc;
42
43 rc = module_finalize_ftrace(me, sechdrs);
44 if (rc)
45 return rc;
f0c426bc 46
f0c426bc
KG
47 /* Apply feature fixups */
48 sect = find_section(hdr, sechdrs, "__ftr_fixup");
49 if (sect != NULL)
50 do_feature_fixups(cur_cpu_spec->cpu_features,
51 (void *)sect->sh_addr,
52 (void *)sect->sh_addr + sect->sh_size);
53
7c03d653
BH
54 sect = find_section(hdr, sechdrs, "__mmu_ftr_fixup");
55 if (sect != NULL)
56 do_feature_fixups(cur_cpu_spec->mmu_features,
57 (void *)sect->sh_addr,
58 (void *)sect->sh_addr + sect->sh_size);
59
f0c426bc
KG
60#ifdef CONFIG_PPC64
61 sect = find_section(hdr, sechdrs, "__fw_ftr_fixup");
62 if (sect != NULL)
63 do_feature_fixups(powerpc_firmware_features,
64 (void *)sect->sh_addr,
65 (void *)sect->sh_addr + sect->sh_size);
179ab1cb 66#endif /* CONFIG_PPC64 */
815069ca 67
7d40aff8 68#ifdef CONFIG_PPC64_ELF_ABI_V1
59fe7eaf
NR
69 sect = find_section(hdr, sechdrs, ".opd");
70 if (sect != NULL) {
71 me->arch.start_opd = sect->sh_addr;
72 me->arch.end_opd = sect->sh_addr + sect->sh_size;
73 }
7d40aff8 74#endif /* CONFIG_PPC64_ELF_ABI_V1 */
59fe7eaf 75
179ab1cb 76#ifdef CONFIG_PPC_BARRIER_NOSPEC
815069ca
MS
77 sect = find_section(hdr, sechdrs, "__spec_barrier_fixup");
78 if (sect != NULL)
79 do_barrier_nospec_fixups_range(barrier_nospec_enabled,
80 (void *)sect->sh_addr,
81 (void *)sect->sh_addr + sect->sh_size);
179ab1cb 82#endif /* CONFIG_PPC_BARRIER_NOSPEC */
f0c426bc 83
2d1b2027
KG
84 sect = find_section(hdr, sechdrs, "__lwsync_fixup");
85 if (sect != NULL)
86 do_lwsync_fixups(cur_cpu_spec->cpu_features,
87 (void *)sect->sh_addr,
88 (void *)sect->sh_addr + sect->sh_size);
89
f0c426bc
KG
90 return 0;
91}
7fbc22ce 92
223b5e57
MRI
93static struct execmem_info execmem_info __ro_after_init;
94
95struct execmem_info __init *execmem_arch_setup(void)
2ec13df1 96{
4fcc6366 97 pgprot_t prot = strict_module_rwx_enabled() ? PAGE_KERNEL : PAGE_KERNEL_EXEC;
223b5e57
MRI
98 unsigned long fallback_start = 0, fallback_end = 0;
99 unsigned long start, end;
4fcc6366 100
8abddd96 101 /*
223b5e57
MRI
102 * BOOK3S_32 and 8xx define MODULES_VADDR for text allocations and
103 * allow allocating data in the entire vmalloc space
8abddd96 104 */
8abddd96 105#ifdef MODULES_VADDR
2ec13df1 106 unsigned long limit = (unsigned long)_etext - SZ_32M;
2ec13df1 107
7fbc22ce
CL
108 BUILD_BUG_ON(TASK_SIZE > MODULES_VADDR);
109
2ec13df1 110 /* First try within 32M limit from _etext to avoid branch trampolines */
223b5e57
MRI
111 if (MODULES_VADDR < PAGE_OFFSET && MODULES_END > limit) {
112 start = limit;
113 fallback_start = MODULES_VADDR;
114 fallback_end = MODULES_END;
115 } else {
116 start = MODULES_VADDR;
117 }
2ec13df1 118
223b5e57 119 end = MODULES_END;
8abddd96 120#else
223b5e57
MRI
121 start = VMALLOC_START;
122 end = VMALLOC_END;
7fbc22ce 123#endif
223b5e57
MRI
124
125 execmem_info = (struct execmem_info){
126 .ranges = {
127 [EXECMEM_DEFAULT] = {
128 .start = start,
129 .end = end,
130 .pgprot = prot,
131 .alignment = 1,
132 .fallback_start = fallback_start,
133 .fallback_end = fallback_end,
134 },
135 [EXECMEM_MODULE_DATA] = {
136 .start = VMALLOC_START,
137 .end = VMALLOC_END,
138 .pgprot = PAGE_KERNEL,
139 .alignment = 1,
140 },
141 },
142 };
143
144 return &execmem_info;
8abddd96 145}