diff options
| author | Tiezhu Yang <yangtiezhu@loongson.cn> | 2026-08-17 22:07:14 +0800 |
|---|---|---|
| committer | Huacai Chen <chenhuacai@loongson.cn> | 2026-08-17 22:07:14 +0800 |
| commit | 18210a104bb97e28c26dc31fd9fc7b5c381fec62 (patch) | |
| tree | 42f4e06e9a0577fc60d76df19bead230aa468072 | |
| parent | 2677f97a67fdbc62a82ce1faa67791f54451d36f (diff) | |
LoongArch: Expand module virtual address space to 2GB
The current 256MB module virtual address space is easily exhausted when
loading massive graphics drivers such as amdgpu along with the large
unstripped symbol tables, resulting in allocation failures of "execmem:
unable to allocate memory".
Thus, expand the module virtual address space to 2GB while keeping
the current normal code model '-mcmodel=normal', rather than using the
medium code model '-mcmodel=medium'. This approach avoids the extra
performance overhead and larger binary size of forcing every function
call into a 2-instruction sequence of 'pcaddu18i + jirl'.
Given that individual module code segments rarely exceed 128MB, most
jumps remain fast direct calls by using the bl instruction. For the
long-distance jumps exceeding the +/-128MB limit, apply_r_larch_b26()
emits PLT entries, while signed_imm_check() guarantees the run-time
safety by rejecting any out-of-bound instruction offsets.
There is still a risk that the distance between .init.text and .text of
the same module exceeds 128MB. So we divide the 2GB virtual space to be
two sub-regions: the first 256MB is for module text, and the rest is for
module data.
Cc: stable@vger.kernel.org
Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
| -rw-r--r-- | arch/loongarch/include/asm/pgtable.h | 2 | ||||
| -rw-r--r-- | arch/loongarch/mm/init.c | 17 |
2 files changed, 15 insertions, 4 deletions
diff --git a/arch/loongarch/include/asm/pgtable.h b/arch/loongarch/include/asm/pgtable.h index 59b37a824bab..a2191044435d 100644 --- a/arch/loongarch/include/asm/pgtable.h +++ b/arch/loongarch/include/asm/pgtable.h @@ -96,7 +96,7 @@ struct vm_area_struct; #ifdef CONFIG_64BIT #define MODULES_VADDR (vm_map_base + PCI_IOSIZE + (2 * PAGE_SIZE)) -#define MODULES_END (MODULES_VADDR + SZ_256M) +#define MODULES_END (MODULES_VADDR + SZ_2G) /* 256MB for text, rest for data */ #ifdef CONFIG_KFENCE #define KFENCE_AREA_SIZE (((CONFIG_KFENCE_NUM_OBJECTS + 1) * 2 + 2) * PAGE_SIZE) diff --git a/arch/loongarch/mm/init.c b/arch/loongarch/mm/init.c index 3407030f3e7a..4b46c5d30708 100644 --- a/arch/loongarch/mm/init.c +++ b/arch/loongarch/mm/init.c @@ -237,15 +237,26 @@ pte_t invalid_pte_table[PTRS_PER_PTE] __page_aligned_bss; EXPORT_SYMBOL(invalid_pte_table); #if defined(CONFIG_EXECMEM) && defined(MODULES_VADDR) +#define MODULES_TEXT_START (MODULES_VADDR) +#define MODULES_TEXT_END (MODULES_VADDR + SZ_256M) +#define MODULES_DATA_START (MODULES_VADDR + SZ_256M) +#define MODULES_DATA_END (MODULES_END) + static struct execmem_info execmem_info __ro_after_init; struct execmem_info __init *execmem_arch_setup(void) { execmem_info = (struct execmem_info){ .ranges = { - [EXECMEM_DEFAULT] = { - .start = MODULES_VADDR, - .end = MODULES_END, + [EXECMEM_MODULE_TEXT] = { + .start = MODULES_TEXT_START, + .end = MODULES_TEXT_END, + .pgprot = PAGE_KERNEL, + .alignment = 1, + }, + [EXECMEM_MODULE_DATA] = { + .start = MODULES_DATA_START, + .end = MODULES_DATA_END, .pgprot = PAGE_KERNEL, .alignment = 1, }, |
