powerpc: Move common module code into its own file
Refactor common code between ppc32 and ppc64 module handling into a shared filed. Signed-off-by: Kumar Gala <galak@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
This commit is contained in:
		
				
					committed by
					
						 Paul Mackerras
						Paul Mackerras
					
				
			
			
				
	
			
			
			
						parent
						
							87e9ab13c3
						
					
				
				
					commit
					f0c426bc35
				
			| @@ -44,7 +44,7 @@ obj-$(CONFIG_TAU)		+= tau_6xx.o | ||||
| obj-$(CONFIG_HIBERNATION)	+= swsusp.o suspend.o \ | ||||
| 				   swsusp_$(CONFIG_WORD_SIZE).o | ||||
| obj64-$(CONFIG_HIBERNATION)	+= swsusp_asm64.o | ||||
| obj-$(CONFIG_MODULES)		+= module_$(CONFIG_WORD_SIZE).o | ||||
| obj-$(CONFIG_MODULES)		+= module.o module_$(CONFIG_WORD_SIZE).o | ||||
| obj-$(CONFIG_44x)		+= cpu_setup_44x.o | ||||
|  | ||||
| ifeq ($(CONFIG_PPC_MERGE),y) | ||||
|   | ||||
							
								
								
									
										110
									
								
								arch/powerpc/kernel/module.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								arch/powerpc/kernel/module.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,110 @@ | ||||
| /*  Kernel module help for powerpc. | ||||
|     Copyright (C) 2001, 2003 Rusty Russell IBM Corporation. | ||||
|     Copyright (C) 2008 Freescale Semiconductor, Inc. | ||||
|  | ||||
|     This program is free software; you can redistribute it and/or modify | ||||
|     it under the terms of the GNU General Public License as published by | ||||
|     the Free Software Foundation; either version 2 of the License, or | ||||
|     (at your option) any later version. | ||||
|  | ||||
|     This program is distributed in the hope that it will be useful, | ||||
|     but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|     GNU General Public License for more details. | ||||
|  | ||||
|     You should have received a copy of the GNU General Public License | ||||
|     along with this program; if not, write to the Free Software | ||||
|     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | ||||
| */ | ||||
| #include <linux/module.h> | ||||
| #include <linux/elf.h> | ||||
| #include <linux/moduleloader.h> | ||||
| #include <linux/err.h> | ||||
| #include <linux/vmalloc.h> | ||||
| #include <linux/bug.h> | ||||
| #include <asm/module.h> | ||||
| #include <asm/uaccess.h> | ||||
| #include <asm/firmware.h> | ||||
| #include <linux/sort.h> | ||||
|  | ||||
| #include "setup.h" | ||||
|  | ||||
| LIST_HEAD(module_bug_list); | ||||
|  | ||||
| void *module_alloc(unsigned long size) | ||||
| { | ||||
| 	if (size == 0) | ||||
| 		return NULL; | ||||
|  | ||||
| 	return vmalloc_exec(size); | ||||
| } | ||||
|  | ||||
| /* Free memory returned from module_alloc */ | ||||
| void module_free(struct module *mod, void *module_region) | ||||
| { | ||||
| 	vfree(module_region); | ||||
| 	/* FIXME: If module_region == mod->init_region, trim exception | ||||
|            table entries. */ | ||||
| } | ||||
|  | ||||
| static const Elf_Shdr *find_section(const Elf_Ehdr *hdr, | ||||
| 				    const Elf_Shdr *sechdrs, | ||||
| 				    const char *name) | ||||
| { | ||||
| 	char *secstrings; | ||||
| 	unsigned int i; | ||||
|  | ||||
| 	secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; | ||||
| 	for (i = 1; i < hdr->e_shnum; i++) | ||||
| 		if (strcmp(secstrings+sechdrs[i].sh_name, name) == 0) | ||||
| 			return &sechdrs[i]; | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
| int module_finalize(const Elf_Ehdr *hdr, | ||||
| 		const Elf_Shdr *sechdrs, struct module *me) | ||||
| { | ||||
| 	const Elf_Shdr *sect; | ||||
| 	int err; | ||||
|  | ||||
| 	err = module_bug_finalize(hdr, sechdrs, me); | ||||
| 	if (err) | ||||
| 		return err; | ||||
|  | ||||
| 	/* Apply feature fixups */ | ||||
| 	sect = find_section(hdr, sechdrs, "__ftr_fixup"); | ||||
| 	if (sect != NULL) | ||||
| 		do_feature_fixups(cur_cpu_spec->cpu_features, | ||||
| 				  (void *)sect->sh_addr, | ||||
| 				  (void *)sect->sh_addr + sect->sh_size); | ||||
|  | ||||
| #ifdef CONFIG_PPC64 | ||||
| 	sect = find_section(hdr, sechdrs, "__fw_ftr_fixup"); | ||||
| 	if (sect != NULL) | ||||
| 		do_feature_fixups(powerpc_firmware_features, | ||||
| 				  (void *)sect->sh_addr, | ||||
| 				  (void *)sect->sh_addr + sect->sh_size); | ||||
| #endif | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| void module_arch_cleanup(struct module *mod) | ||||
| { | ||||
| 	module_bug_cleanup(mod); | ||||
| } | ||||
|  | ||||
| struct bug_entry *module_find_bug(unsigned long bugaddr) | ||||
| { | ||||
| 	struct mod_arch_specific *mod; | ||||
| 	unsigned int i; | ||||
| 	struct bug_entry *bug; | ||||
|  | ||||
| 	list_for_each_entry(mod, &module_bug_list, bug_list) { | ||||
| 		bug = mod->bug_table; | ||||
| 		for (i = 0; i < mod->num_bugs; ++i, ++bug) | ||||
| 			if (bugaddr == bug->bug_addr) | ||||
| 				return bug; | ||||
| 	} | ||||
| 	return NULL; | ||||
| } | ||||
| @@ -34,23 +34,6 @@ | ||||
| #define DEBUGP(fmt , ...) | ||||
| #endif | ||||
|  | ||||
| LIST_HEAD(module_bug_list); | ||||
|  | ||||
| void *module_alloc(unsigned long size) | ||||
| { | ||||
| 	if (size == 0) | ||||
| 		return NULL; | ||||
| 	return vmalloc(size); | ||||
| } | ||||
|  | ||||
| /* Free memory returned from module_alloc */ | ||||
| void module_free(struct module *mod, void *module_region) | ||||
| { | ||||
| 	vfree(module_region); | ||||
| 	/* FIXME: If module_region == mod->init_region, trim exception | ||||
|            table entries. */ | ||||
| } | ||||
|  | ||||
| /* Count how many different relocations (different symbol, different | ||||
|    addend) */ | ||||
| static unsigned int count_relocs(const Elf32_Rela *rela, unsigned int num) | ||||
| @@ -325,58 +308,3 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static const Elf_Shdr *find_section(const Elf_Ehdr *hdr, | ||||
| 				    const Elf_Shdr *sechdrs, | ||||
| 				    const char *name) | ||||
| { | ||||
| 	char *secstrings; | ||||
| 	unsigned int i; | ||||
|  | ||||
| 	secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; | ||||
| 	for (i = 1; i < hdr->e_shnum; i++) | ||||
| 		if (strcmp(secstrings+sechdrs[i].sh_name, name) == 0) | ||||
| 			return &sechdrs[i]; | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
| int module_finalize(const Elf_Ehdr *hdr, | ||||
| 		    const Elf_Shdr *sechdrs, | ||||
| 		    struct module *me) | ||||
| { | ||||
| 	const Elf_Shdr *sect; | ||||
| 	int err; | ||||
|  | ||||
| 	err = module_bug_finalize(hdr, sechdrs, me); | ||||
| 	if (err)		/* never true, currently */ | ||||
| 		return err; | ||||
|  | ||||
| 	/* Apply feature fixups */ | ||||
| 	sect = find_section(hdr, sechdrs, "__ftr_fixup"); | ||||
| 	if (sect != NULL) | ||||
| 		do_feature_fixups(cur_cpu_spec->cpu_features, | ||||
| 				  (void *)sect->sh_addr, | ||||
| 				  (void *)sect->sh_addr + sect->sh_size); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| void module_arch_cleanup(struct module *mod) | ||||
| { | ||||
| 	module_bug_cleanup(mod); | ||||
| } | ||||
|  | ||||
| struct bug_entry *module_find_bug(unsigned long bugaddr) | ||||
| { | ||||
| 	struct mod_arch_specific *mod; | ||||
| 	unsigned int i; | ||||
| 	struct bug_entry *bug; | ||||
|  | ||||
| 	list_for_each_entry(mod, &module_bug_list, bug_list) { | ||||
| 		bug = mod->bug_table; | ||||
| 		for (i = 0; i < mod->num_bugs; ++i, ++bug) | ||||
| 			if (bugaddr == bug->bug_addr) | ||||
| 				return bug; | ||||
| 	} | ||||
| 	return NULL; | ||||
| } | ||||
|   | ||||
| @@ -101,22 +101,6 @@ static unsigned int count_relocs(const Elf64_Rela *rela, unsigned int num) | ||||
| 	return _count_relocs; | ||||
| } | ||||
|  | ||||
| void *module_alloc(unsigned long size) | ||||
| { | ||||
| 	if (size == 0) | ||||
| 		return NULL; | ||||
|  | ||||
| 	return vmalloc_exec(size); | ||||
| } | ||||
|  | ||||
| /* Free memory returned from module_alloc */ | ||||
| void module_free(struct module *mod, void *module_region) | ||||
| { | ||||
| 	vfree(module_region); | ||||
| 	/* FIXME: If module_region == mod->init_region, trim exception | ||||
|            table entries. */ | ||||
| } | ||||
|  | ||||
| static int relacmp(const void *_x, const void *_y) | ||||
| { | ||||
| 	const Elf64_Rela *x, *y; | ||||
| @@ -466,65 +450,3 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| LIST_HEAD(module_bug_list); | ||||
|  | ||||
| static const Elf_Shdr *find_section(const Elf_Ehdr *hdr, | ||||
| 				    const Elf_Shdr *sechdrs, | ||||
| 				    const char *name) | ||||
| { | ||||
| 	char *secstrings; | ||||
| 	unsigned int i; | ||||
|  | ||||
| 	secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; | ||||
| 	for (i = 1; i < hdr->e_shnum; i++) | ||||
| 		if (strcmp(secstrings+sechdrs[i].sh_name, name) == 0) | ||||
| 			return &sechdrs[i]; | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
| int module_finalize(const Elf_Ehdr *hdr, | ||||
| 		const Elf_Shdr *sechdrs, struct module *me) | ||||
| { | ||||
| 	const Elf_Shdr *sect; | ||||
| 	int err; | ||||
|  | ||||
| 	err = module_bug_finalize(hdr, sechdrs, me); | ||||
| 	if (err) | ||||
| 		return err; | ||||
|  | ||||
| 	/* Apply feature fixups */ | ||||
| 	sect = find_section(hdr, sechdrs, "__ftr_fixup"); | ||||
| 	if (sect != NULL) | ||||
| 		do_feature_fixups(cur_cpu_spec->cpu_features, | ||||
| 				  (void *)sect->sh_addr, | ||||
| 				  (void *)sect->sh_addr + sect->sh_size); | ||||
|  | ||||
| 	sect = find_section(hdr, sechdrs, "__fw_ftr_fixup"); | ||||
| 	if (sect != NULL) | ||||
| 		do_feature_fixups(powerpc_firmware_features, | ||||
| 				  (void *)sect->sh_addr, | ||||
| 				  (void *)sect->sh_addr + sect->sh_size); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| void module_arch_cleanup(struct module *mod) | ||||
| { | ||||
| 	module_bug_cleanup(mod); | ||||
| } | ||||
|  | ||||
| struct bug_entry *module_find_bug(unsigned long bugaddr) | ||||
| { | ||||
| 	struct mod_arch_specific *mod; | ||||
| 	unsigned int i; | ||||
| 	struct bug_entry *bug; | ||||
|  | ||||
| 	list_for_each_entry(mod, &module_bug_list, bug_list) { | ||||
| 		bug = mod->bug_table; | ||||
| 		for (i = 0; i < mod->num_bugs; ++i, ++bug) | ||||
| 			if (bugaddr == bug->bug_addr) | ||||
| 				return bug; | ||||
| 	} | ||||
| 	return NULL; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user