xref: /openbmc/linux/arch/x86/kernel/module.c (revision 2d5bf28fb9e3c178db4f5536e2fe38d3a5ed7f40)
1*2d5bf28fSAmerigo Wang /*  Kernel module help for x86.
2*2d5bf28fSAmerigo Wang     Copyright (C) 2001 Rusty Russell.
3*2d5bf28fSAmerigo Wang 
4*2d5bf28fSAmerigo Wang     This program is free software; you can redistribute it and/or modify
5*2d5bf28fSAmerigo Wang     it under the terms of the GNU General Public License as published by
6*2d5bf28fSAmerigo Wang     the Free Software Foundation; either version 2 of the License, or
7*2d5bf28fSAmerigo Wang     (at your option) any later version.
8*2d5bf28fSAmerigo Wang 
9*2d5bf28fSAmerigo Wang     This program is distributed in the hope that it will be useful,
10*2d5bf28fSAmerigo Wang     but WITHOUT ANY WARRANTY; without even the implied warranty of
11*2d5bf28fSAmerigo Wang     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12*2d5bf28fSAmerigo Wang     GNU General Public License for more details.
13*2d5bf28fSAmerigo Wang 
14*2d5bf28fSAmerigo Wang     You should have received a copy of the GNU General Public License
15*2d5bf28fSAmerigo Wang     along with this program; if not, write to the Free Software
16*2d5bf28fSAmerigo Wang     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17*2d5bf28fSAmerigo Wang */
18*2d5bf28fSAmerigo Wang #include <linux/moduleloader.h>
19*2d5bf28fSAmerigo Wang #include <linux/elf.h>
20*2d5bf28fSAmerigo Wang #include <linux/vmalloc.h>
21*2d5bf28fSAmerigo Wang #include <linux/fs.h>
22*2d5bf28fSAmerigo Wang #include <linux/string.h>
23*2d5bf28fSAmerigo Wang #include <linux/kernel.h>
24*2d5bf28fSAmerigo Wang #include <linux/bug.h>
25*2d5bf28fSAmerigo Wang #include <linux/mm.h>
26*2d5bf28fSAmerigo Wang 
27*2d5bf28fSAmerigo Wang #include <asm/system.h>
28*2d5bf28fSAmerigo Wang #include <asm/page.h>
29*2d5bf28fSAmerigo Wang #include <asm/pgtable.h>
30*2d5bf28fSAmerigo Wang 
31*2d5bf28fSAmerigo Wang #if 0
32*2d5bf28fSAmerigo Wang #define DEBUGP printk
33*2d5bf28fSAmerigo Wang #else
34*2d5bf28fSAmerigo Wang #define DEBUGP(fmt...)
35*2d5bf28fSAmerigo Wang #endif
36*2d5bf28fSAmerigo Wang 
37*2d5bf28fSAmerigo Wang /* Free memory returned from module_alloc */
38*2d5bf28fSAmerigo Wang void module_free(struct module *mod, void *module_region)
39*2d5bf28fSAmerigo Wang {
40*2d5bf28fSAmerigo Wang 	vfree(module_region);
41*2d5bf28fSAmerigo Wang 	/* FIXME: If module_region == mod->init_region, trim exception
42*2d5bf28fSAmerigo Wang 	   table entries. */
43*2d5bf28fSAmerigo Wang }
44*2d5bf28fSAmerigo Wang 
45*2d5bf28fSAmerigo Wang /* We don't need anything special. */
46*2d5bf28fSAmerigo Wang int module_frob_arch_sections(Elf_Ehdr *hdr,
47*2d5bf28fSAmerigo Wang 			      Elf_Shdr *sechdrs,
48*2d5bf28fSAmerigo Wang 			      char *secstrings,
49*2d5bf28fSAmerigo Wang 			      struct module *mod)
50*2d5bf28fSAmerigo Wang {
51*2d5bf28fSAmerigo Wang 	return 0;
52*2d5bf28fSAmerigo Wang }
53*2d5bf28fSAmerigo Wang 
54*2d5bf28fSAmerigo Wang int module_finalize(const Elf_Ehdr *hdr,
55*2d5bf28fSAmerigo Wang 		    const Elf_Shdr *sechdrs,
56*2d5bf28fSAmerigo Wang 		    struct module *me)
57*2d5bf28fSAmerigo Wang {
58*2d5bf28fSAmerigo Wang 	const Elf_Shdr *s, *text = NULL, *alt = NULL, *locks = NULL,
59*2d5bf28fSAmerigo Wang 		*para = NULL;
60*2d5bf28fSAmerigo Wang 	char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
61*2d5bf28fSAmerigo Wang 
62*2d5bf28fSAmerigo Wang 	for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
63*2d5bf28fSAmerigo Wang 		if (!strcmp(".text", secstrings + s->sh_name))
64*2d5bf28fSAmerigo Wang 			text = s;
65*2d5bf28fSAmerigo Wang 		if (!strcmp(".altinstructions", secstrings + s->sh_name))
66*2d5bf28fSAmerigo Wang 			alt = s;
67*2d5bf28fSAmerigo Wang 		if (!strcmp(".smp_locks", secstrings + s->sh_name))
68*2d5bf28fSAmerigo Wang 			locks = s;
69*2d5bf28fSAmerigo Wang 		if (!strcmp(".parainstructions", secstrings + s->sh_name))
70*2d5bf28fSAmerigo Wang 			para = s;
71*2d5bf28fSAmerigo Wang 	}
72*2d5bf28fSAmerigo Wang 
73*2d5bf28fSAmerigo Wang 	if (alt) {
74*2d5bf28fSAmerigo Wang 		/* patch .altinstructions */
75*2d5bf28fSAmerigo Wang 		void *aseg = (void *)alt->sh_addr;
76*2d5bf28fSAmerigo Wang 		apply_alternatives(aseg, aseg + alt->sh_size);
77*2d5bf28fSAmerigo Wang 	}
78*2d5bf28fSAmerigo Wang 	if (locks && text) {
79*2d5bf28fSAmerigo Wang 		void *lseg = (void *)locks->sh_addr;
80*2d5bf28fSAmerigo Wang 		void *tseg = (void *)text->sh_addr;
81*2d5bf28fSAmerigo Wang 		alternatives_smp_module_add(me, me->name,
82*2d5bf28fSAmerigo Wang 					    lseg, lseg + locks->sh_size,
83*2d5bf28fSAmerigo Wang 					    tseg, tseg + text->sh_size);
84*2d5bf28fSAmerigo Wang 	}
85*2d5bf28fSAmerigo Wang 
86*2d5bf28fSAmerigo Wang 	if (para) {
87*2d5bf28fSAmerigo Wang 		void *pseg = (void *)para->sh_addr;
88*2d5bf28fSAmerigo Wang 		apply_paravirt(pseg, pseg + para->sh_size);
89*2d5bf28fSAmerigo Wang 	}
90*2d5bf28fSAmerigo Wang 
91*2d5bf28fSAmerigo Wang 	return module_bug_finalize(hdr, sechdrs, me);
92*2d5bf28fSAmerigo Wang }
93*2d5bf28fSAmerigo Wang 
94*2d5bf28fSAmerigo Wang void module_arch_cleanup(struct module *mod)
95*2d5bf28fSAmerigo Wang {
96*2d5bf28fSAmerigo Wang 	alternatives_smp_module_del(mod);
97*2d5bf28fSAmerigo Wang 	module_bug_cleanup(mod);
98*2d5bf28fSAmerigo Wang }
99