History

module: handle ppc64 relocating kcrctabs when CONFIG_RELOCATABLE=y

powerpc applies relocations to the kcrctab. They're absolute symbols, but it's not completely unreasonable: other archs may too, but the relocation is often 0. http://lists.ozlabs.org/pipermail/linuxppc-dev/2009-November/077972.html

Rusty Russell committed 16 years ago

Commit d4703ae1 parent a8773763 files · +29 −7Browse files

Unified · Split

3 files
  1. arch/powerpc/include/asm/module.h +5 −0
  2. arch/powerpc/kernel/vmlinux.lds.S +3 −0
  3. kernel/module.c +21 −7
arch/powerpc/include/asm/module.h+5−0
@@ -87,5 +87,10 @@ struct exception_table_entry; · 86 unmodified lines
8787 void sort_ex_table(struct exception_table_entry *start,
8888 struct exception_table_entry *finish);
8989
90+#ifdef CONFIG_MODVERSIONS
91+#define ARCH_RELOCATES_KCRCTAB
92+
93+extern const unsigned long reloc_start[];
94+#endif
9095 #endif /* __KERNEL__ */
9196 #endif /* _ASM_POWERPC_MODULE_H */
arch/powerpc/kernel/vmlinux.lds.S+3−0
@@ -38,6 +38,9 @@ jiffies = jiffies_64 + 4; · 37 unmodified lines
3838 #endif
3939 SECTIONS
4040 {
41+ . = 0;
42+ reloc_start = .;
43+
4144 . = KERNELBASE;
4245
4346 /*
kernel/module.c+21−7
@@ -880,11 +880,23 @@ static int try_to_force_load(struct module *mod, const char *reason) · 879 unmodified lines
880880 }
881881
882882 #ifdef CONFIG_MODVERSIONS
883+/* If the arch applies (non-zero) relocations to kernel kcrctab, unapply it. */
884+static unsigned long maybe_relocated(unsigned long crc,
885+ const struct module *crc_owner)
886+{
887+#ifdef ARCH_RELOCATES_KCRCTAB
888+ if (crc_owner == NULL)
889+ return crc - (unsigned long)reloc_start;
890+#endif
891+ return crc;
892+}
893+
883894 static int check_version(Elf_Shdr *sechdrs,
884895 unsigned int versindex,
885896 const char *symname,
886897 struct module *mod,
887− const unsigned long *crc)
898+ const unsigned long *crc,
899+ const struct module *crc_owner)
888900 {
889901 unsigned int i, num_versions;
890902 struct modversion_info *versions;
@@ -905,10 +917,10 @@ static int check_version(Elf_Shdr *sechdrs, · 14 unmodified lines
905917 if (strcmp(versions[i].name, symname) != 0)
906918 continue;
907919
908− if (versions[i].crc == *crc)
920+ if (versions[i].crc == maybe_relocated(*crc, crc_owner))
909921 return 1;
910922 DEBUGP("Found checksum %lX vs module %lX\n",
911− *crc, versions[i].crc);
923+ maybe_relocated(*crc, crc_owner), versions[i].crc);
912924 goto bad_version;
913925 }
914926
@@ -931,7 +943,8 @@ static inline int check_modstruct_version(Elf_Shdr *sechdrs, · 16 unmodified lines
931943 if (!find_symbol(MODULE_SYMBOL_PREFIX "module_layout", NULL,
932944 &crc, true, false))
933945 BUG();
934− return check_version(sechdrs, versindex, "module_layout", mod, crc);
946+ return check_version(sechdrs, versindex, "module_layout", mod, crc,
947+ NULL);
935948 }
936949
937950 /* First part is kernel version, which we ignore if module has crcs. */
@@ -949,7 +962,8 @@ static inline int check_version(Elf_Shdr *sechdrs, · 11 unmodified lines
949962 unsigned int versindex,
950963 const char *symname,
951964 struct module *mod,
952− const unsigned long *crc)
965+ const unsigned long *crc,
966+ const struct module *crc_owner)
953967 {
954968 return 1;
955969 }
@@ -984,8 +998,8 @@ static const struct kernel_symbol *resolve_symbol(Elf_Shdr *sechdrs, · 28 unmodified lines
984998 /* use_module can fail due to OOM,
985999 or module initialization or unloading */
9861000 if (sym) {
987− if (!check_version(sechdrs, versindex, name, mod, crc) ||
988− !use_module(mod, owner))
1001+ if (!check_version(sechdrs, versindex, name, mod, crc, owner)
1002+ || !use_module(mod, owner))
9891003 sym = NULL;
9901004 }
9911005 return sym;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t