Commit 088af9a6e05d51e7c3dc85d45d8b7a52c3ee08d7

Authored by Helge Deller
Committed by Rusty Russell
1 parent d1e99d7ae4

module: fix module loading failure of large kernel modules for parisc

When creating the final layout of a kernel module in memory, allow the
module loader to reserve some additional memory in front of a given section.
This is currently only needed for the parisc port which needs to put the
stub entries there to fulfill the 17/22bit PCREL relocations with large
kernel modules like xfs.

Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> (renamed fn)

Showing 2 changed files with 16 additions and 3 deletions Side-by-side Diff

include/linux/moduleloader.h
... ... @@ -13,6 +13,9 @@
13 13 char *secstrings,
14 14 struct module *mod);
15 15  
  16 +/* Additional bytes needed by arch in front of individual sections */
  17 +unsigned int arch_mod_section_prepend(struct module *mod, unsigned int section);
  18 +
16 19 /* Allocator used for allocating struct module, core sections and init
17 20 sections. Returns NULL on failure. */
18 21 void *module_alloc(unsigned long size);
... ... @@ -1578,11 +1578,21 @@
1578 1578 return ret;
1579 1579 }
1580 1580  
  1581 +/* Additional bytes needed by arch in front of individual sections */
  1582 +unsigned int __weak arch_mod_section_prepend(struct module *mod,
  1583 + unsigned int section)
  1584 +{
  1585 + /* default implementation just returns zero */
  1586 + return 0;
  1587 +}
  1588 +
1581 1589 /* Update size with this section: return offset. */
1582   -static long get_offset(unsigned int *size, Elf_Shdr *sechdr)
  1590 +static long get_offset(struct module *mod, unsigned int *size,
  1591 + Elf_Shdr *sechdr, unsigned int section)
1583 1592 {
1584 1593 long ret;
1585 1594  
  1595 + *size += arch_mod_section_prepend(mod, section);
1586 1596 ret = ALIGN(*size, sechdr->sh_addralign ?: 1);
1587 1597 *size = ret + sechdr->sh_size;
1588 1598 return ret;
... ... @@ -1622,7 +1632,7 @@
1622 1632 || strncmp(secstrings + s->sh_name,
1623 1633 ".init", 5) == 0)
1624 1634 continue;
1625   - s->sh_entsize = get_offset(&mod->core_size, s);
  1635 + s->sh_entsize = get_offset(mod, &mod->core_size, s, i);
1626 1636 DEBUGP("\t%s\n", secstrings + s->sh_name);
1627 1637 }
1628 1638 if (m == 0)
... ... @@ -1640,7 +1650,7 @@
1640 1650 || strncmp(secstrings + s->sh_name,
1641 1651 ".init", 5) != 0)
1642 1652 continue;
1643   - s->sh_entsize = (get_offset(&mod->init_size, s)
  1653 + s->sh_entsize = (get_offset(mod, &mod->init_size, s, i)
1644 1654 | INIT_OFFSET_MASK);
1645 1655 DEBUGP("\t%s\n", secstrings + s->sh_name);
1646 1656 }