module.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /* Kernel module help for powerpc.
  3. Copyright (C) 2001, 2003 Rusty Russell IBM Corporation.
  4. Copyright (C) 2008 Freescale Semiconductor, Inc.
  5. */
  6. #include <linux/elf.h>
  7. #include <linux/moduleloader.h>
  8. #include <linux/err.h>
  9. #include <linux/vmalloc.h>
  10. #include <linux/mm.h>
  11. #include <linux/bug.h>
  12. #include <asm/module.h>
  13. #include <linux/uaccess.h>
  14. #include <asm/firmware.h>
  15. #include <linux/sort.h>
  16. #include <asm/setup.h>
  17. #include <asm/sections.h>
  18. static LIST_HEAD(module_bug_list);
  19. static const Elf_Shdr *find_section(const Elf_Ehdr *hdr,
  20. const Elf_Shdr *sechdrs,
  21. const char *name)
  22. {
  23. char *secstrings;
  24. unsigned int i;
  25. secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
  26. for (i = 1; i < hdr->e_shnum; i++)
  27. if (strcmp(secstrings+sechdrs[i].sh_name, name) == 0)
  28. return &sechdrs[i];
  29. return NULL;
  30. }
  31. int module_finalize(const Elf_Ehdr *hdr,
  32. const Elf_Shdr *sechdrs, struct module *me)
  33. {
  34. const Elf_Shdr *sect;
  35. int rc;
  36. rc = module_finalize_ftrace(me, sechdrs);
  37. if (rc)
  38. return rc;
  39. /* Apply feature fixups */
  40. sect = find_section(hdr, sechdrs, "__ftr_fixup");
  41. if (sect != NULL)
  42. do_feature_fixups(cur_cpu_spec->cpu_features,
  43. (void *)sect->sh_addr,
  44. (void *)sect->sh_addr + sect->sh_size);
  45. sect = find_section(hdr, sechdrs, "__mmu_ftr_fixup");
  46. if (sect != NULL)
  47. do_feature_fixups(cur_cpu_spec->mmu_features,
  48. (void *)sect->sh_addr,
  49. (void *)sect->sh_addr + sect->sh_size);
  50. #ifdef CONFIG_PPC64
  51. sect = find_section(hdr, sechdrs, "__fw_ftr_fixup");
  52. if (sect != NULL)
  53. do_feature_fixups(powerpc_firmware_features,
  54. (void *)sect->sh_addr,
  55. (void *)sect->sh_addr + sect->sh_size);
  56. #endif /* CONFIG_PPC64 */
  57. #ifdef CONFIG_PPC64_ELF_ABI_V1
  58. sect = find_section(hdr, sechdrs, ".opd");
  59. if (sect != NULL) {
  60. me->arch.start_opd = sect->sh_addr;
  61. me->arch.end_opd = sect->sh_addr + sect->sh_size;
  62. }
  63. #endif /* CONFIG_PPC64_ELF_ABI_V1 */
  64. #ifdef CONFIG_PPC_BARRIER_NOSPEC
  65. sect = find_section(hdr, sechdrs, "__spec_barrier_fixup");
  66. if (sect != NULL)
  67. do_barrier_nospec_fixups_range(barrier_nospec_enabled,
  68. (void *)sect->sh_addr,
  69. (void *)sect->sh_addr + sect->sh_size);
  70. #endif /* CONFIG_PPC_BARRIER_NOSPEC */
  71. sect = find_section(hdr, sechdrs, "__lwsync_fixup");
  72. if (sect != NULL)
  73. do_lwsync_fixups(cur_cpu_spec->cpu_features,
  74. (void *)sect->sh_addr,
  75. (void *)sect->sh_addr + sect->sh_size);
  76. return 0;
  77. }
  78. static __always_inline void *
  79. __module_alloc(unsigned long size, unsigned long start, unsigned long end, bool nowarn)
  80. {
  81. pgprot_t prot = strict_module_rwx_enabled() ? PAGE_KERNEL : PAGE_KERNEL_EXEC;
  82. gfp_t gfp = GFP_KERNEL | (nowarn ? __GFP_NOWARN : 0);
  83. /*
  84. * Don't do huge page allocations for modules yet until more testing
  85. * is done. STRICT_MODULE_RWX may require extra work to support this
  86. * too.
  87. */
  88. return __vmalloc_node_range(size, 1, start, end, gfp, prot,
  89. VM_FLUSH_RESET_PERMS,
  90. NUMA_NO_NODE, __builtin_return_address(0));
  91. }
  92. void *module_alloc(unsigned long size)
  93. {
  94. #ifdef MODULES_VADDR
  95. unsigned long limit = (unsigned long)_etext - SZ_32M;
  96. void *ptr = NULL;
  97. BUILD_BUG_ON(TASK_SIZE > MODULES_VADDR);
  98. /* First try within 32M limit from _etext to avoid branch trampolines */
  99. if (MODULES_VADDR < PAGE_OFFSET && MODULES_END > limit)
  100. ptr = __module_alloc(size, limit, MODULES_END, true);
  101. if (!ptr)
  102. ptr = __module_alloc(size, MODULES_VADDR, MODULES_END, false);
  103. return ptr;
  104. #else
  105. return __module_alloc(size, VMALLOC_START, VMALLOC_END, false);
  106. #endif
  107. }