From nobody Mon Dec 1 22:05:35 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CA2EA3375C4; Thu, 27 Nov 2025 15:54:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764258889; cv=none; b=n38kw715eJOBpUXwIzpzvC02uJyYIUP6G+Tqh061NVymM46WhcDNiFlCzHAL7gUx61hKArnE1eimDJrbGGaQhoQaIAndhFKp9ampa/qA98MMIz6DlVxEn+6RAYKRp3eg7SN+JOlXixqwr/WAXJ88sDTnr7vbPzZ0dVavRy2SCuU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764258889; c=relaxed/simple; bh=aQx7HiOi3X1vk14M3py2qMHO/WxzFvSZYrjY6JZIBO4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Wumeh2iEggBulesHuuZXBzoj9YJhwfs7hols+pNwFWV3EZ2Xl/gYmCOb38BSJMsTSAjJitWmMFLs5ZWUsWkopjkpJWisoLXrdg7KkkjcvLIsxIN+b9YwnsfIL3ZSYhsgVzrl3ZFTO3xfESic5GSxsI6zoePY0d9IuI1TCDkZJC4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 85CF8C4CEF8; Thu, 27 Nov 2025 15:54:46 +0000 (UTC) From: Huacai Chen To: Huacai Chen Cc: loongarch@lists.linux.dev, Xuefeng Li , Guo Ren , Xuerui Wang , Jiaxun Yang , linux-kernel@vger.kernel.org, Huacai Chen , Arnd Bergmann Subject: [PATCH V4 08/14] LoongArch: Adjust module loader for 32BIT/64BIT Date: Thu, 27 Nov 2025 23:48:26 +0800 Message-ID: <20251127154832.137925-9-chenhuacai@loongson.cn> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251127154832.137925-1-chenhuacai@loongson.cn> References: <20251127154832.137925-1-chenhuacai@loongson.cn> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Adjust module loader for both 32BIT and 64BIT, including: change the s64 type to long, change the u64 type to unsigned long, change the plt entry definition and handling, etc. Reviewed-by: Arnd Bergmann Signed-off-by: Jiaxun Yang Signed-off-by: Huacai Chen --- arch/loongarch/include/asm/module.h | 11 ++++ arch/loongarch/include/asm/percpu.h | 2 +- arch/loongarch/kernel/module.c | 80 +++++++++++++++++------------ 3 files changed, 59 insertions(+), 34 deletions(-) diff --git a/arch/loongarch/include/asm/module.h b/arch/loongarch/include/a= sm/module.h index f33f3fd32ecc..d56a968273de 100644 --- a/arch/loongarch/include/asm/module.h +++ b/arch/loongarch/include/asm/module.h @@ -38,8 +38,10 @@ struct got_entry { =20 struct plt_entry { u32 inst_lu12iw; +#ifdef CONFIG_64BIT u32 inst_lu32id; u32 inst_lu52id; +#endif u32 inst_jirl; }; =20 @@ -57,6 +59,14 @@ static inline struct got_entry emit_got_entry(Elf_Addr v= al) =20 static inline struct plt_entry emit_plt_entry(unsigned long val) { +#ifdef CONFIG_32BIT + u32 lu12iw, jirl; + + lu12iw =3D larch_insn_gen_lu12iw(LOONGARCH_GPR_T1, ADDR_IMM(val, LU12IW)); + jirl =3D larch_insn_gen_jirl(0, LOONGARCH_GPR_T1, ADDR_IMM(val, ORI)); + + return (struct plt_entry) { lu12iw, jirl }; +#else u32 lu12iw, lu32id, lu52id, jirl; =20 lu12iw =3D larch_insn_gen_lu12iw(LOONGARCH_GPR_T1, ADDR_IMM(val, LU12IW)); @@ -65,6 +75,7 @@ static inline struct plt_entry emit_plt_entry(unsigned lo= ng val) jirl =3D larch_insn_gen_jirl(0, LOONGARCH_GPR_T1, ADDR_IMM(val, ORI)); =20 return (struct plt_entry) { lu12iw, lu32id, lu52id, jirl }; +#endif } =20 static inline struct plt_idx_entry emit_plt_idx_entry(unsigned long val) diff --git a/arch/loongarch/include/asm/percpu.h b/arch/loongarch/include/a= sm/percpu.h index 44a8aea2b0e5..583f2466262f 100644 --- a/arch/loongarch/include/asm/percpu.h +++ b/arch/loongarch/include/asm/percpu.h @@ -13,7 +13,7 @@ * the loading address of main kernel image, but far from where the module= s are * loaded. Tell the compiler this fact when using explicit relocs. */ -#if defined(MODULE) && defined(CONFIG_AS_HAS_EXPLICIT_RELOCS) +#if defined(MODULE) && defined(CONFIG_AS_HAS_EXPLICIT_RELOCS) && defined(C= ONFIG_64BIT) # if __has_attribute(model) # define PER_CPU_ATTRIBUTES __attribute__((model("extreme"))) # else diff --git a/arch/loongarch/kernel/module.c b/arch/loongarch/kernel/module.c index 36d6d9eeb7c7..27f6d6b2e3ff 100644 --- a/arch/loongarch/kernel/module.c +++ b/arch/loongarch/kernel/module.c @@ -22,72 +22,76 @@ #include #include =20 -static int rela_stack_push(s64 stack_value, s64 *rela_stack, size_t *rela_= stack_top) +static int rela_stack_push(long stack_value, long *rela_stack, size_t *rel= a_stack_top) { if (*rela_stack_top >=3D RELA_STACK_DEPTH) return -ENOEXEC; =20 rela_stack[(*rela_stack_top)++] =3D stack_value; - pr_debug("%s stack_value =3D 0x%llx\n", __func__, stack_value); + pr_debug("%s stack_value =3D 0x%lx\n", __func__, stack_value); =20 return 0; } =20 -static int rela_stack_pop(s64 *stack_value, s64 *rela_stack, size_t *rela_= stack_top) +static int rela_stack_pop(long *stack_value, long *rela_stack, size_t *rel= a_stack_top) { if (*rela_stack_top =3D=3D 0) return -ENOEXEC; =20 *stack_value =3D rela_stack[--(*rela_stack_top)]; - pr_debug("%s stack_value =3D 0x%llx\n", __func__, *stack_value); + pr_debug("%s stack_value =3D 0x%lx\n", __func__, *stack_value); =20 return 0; } =20 static int apply_r_larch_none(struct module *mod, u32 *location, Elf_Addr = v, - s64 *rela_stack, size_t *rela_stack_top, unsigned int type) + long *rela_stack, size_t *rela_stack_top, unsigned int type) { return 0; } =20 static int apply_r_larch_error(struct module *me, u32 *location, Elf_Addr = v, - s64 *rela_stack, size_t *rela_stack_top, unsigned int type) + long *rela_stack, size_t *rela_stack_top, unsigned int type) { pr_err("%s: Unsupport relocation type %u, please add its support.\n", me-= >name, type); return -EINVAL; } =20 static int apply_r_larch_32(struct module *mod, u32 *location, Elf_Addr v, - s64 *rela_stack, size_t *rela_stack_top, unsigned int type) + long *rela_stack, size_t *rela_stack_top, unsigned int type) { *location =3D v; return 0; } =20 +#ifdef CONFIG_32BIT +#define apply_r_larch_64 apply_r_larch_error +#else static int apply_r_larch_64(struct module *mod, u32 *location, Elf_Addr v, - s64 *rela_stack, size_t *rela_stack_top, unsigned int type) + long *rela_stack, size_t *rela_stack_top, unsigned int type) { *(Elf_Addr *)location =3D v; return 0; } +#endif =20 static int apply_r_larch_sop_push_pcrel(struct module *mod, u32 *location,= Elf_Addr v, - s64 *rela_stack, size_t *rela_stack_top, unsigned int type) + long *rela_stack, size_t *rela_stack_top, unsigned int type) { - return rela_stack_push(v - (u64)location, rela_stack, rela_stack_top); + return rela_stack_push(v - (unsigned long)location, rela_stack, rela_stac= k_top); } =20 static int apply_r_larch_sop_push_absolute(struct module *mod, u32 *locati= on, Elf_Addr v, - s64 *rela_stack, size_t *rela_stack_top, unsigned int type) + long *rela_stack, size_t *rela_stack_top, unsigned int type) { return rela_stack_push(v, rela_stack, rela_stack_top); } =20 static int apply_r_larch_sop_push_dup(struct module *mod, u32 *location, E= lf_Addr v, - s64 *rela_stack, size_t *rela_stack_top, unsigned int type) + long *rela_stack, size_t *rela_stack_top, unsigned int type) { int err =3D 0; - s64 opr1; + long opr1; =20 err =3D rela_stack_pop(&opr1, rela_stack, rela_stack_top); if (err) @@ -104,7 +108,7 @@ static int apply_r_larch_sop_push_dup(struct module *mo= d, u32 *location, Elf_Add =20 static int apply_r_larch_sop_push_plt_pcrel(struct module *mod, Elf_Shdr *sechdrs, u32 *location, Elf_Addr v, - s64 *rela_stack, size_t *rela_stack_top, unsigned int type) + long *rela_stack, size_t *rela_stack_top, unsigned int type) { ptrdiff_t offset =3D (void *)v - (void *)location; =20 @@ -118,10 +122,10 @@ static int apply_r_larch_sop_push_plt_pcrel(struct mo= dule *mod, } =20 static int apply_r_larch_sop(struct module *mod, u32 *location, Elf_Addr v, - s64 *rela_stack, size_t *rela_stack_top, unsigned int type) + long *rela_stack, size_t *rela_stack_top, unsigned int type) { int err =3D 0; - s64 opr1, opr2, opr3; + long opr1, opr2, opr3; =20 if (type =3D=3D R_LARCH_SOP_IF_ELSE) { err =3D rela_stack_pop(&opr3, rela_stack, rela_stack_top); @@ -164,10 +168,10 @@ static int apply_r_larch_sop(struct module *mod, u32 = *location, Elf_Addr v, } =20 static int apply_r_larch_sop_imm_field(struct module *mod, u32 *location, = Elf_Addr v, - s64 *rela_stack, size_t *rela_stack_top, unsigned int type) + long *rela_stack, size_t *rela_stack_top, unsigned int type) { int err =3D 0; - s64 opr1; + long opr1; union loongarch_instruction *insn =3D (union loongarch_instruction *)loca= tion; =20 err =3D rela_stack_pop(&opr1, rela_stack, rela_stack_top); @@ -244,31 +248,33 @@ static int apply_r_larch_sop_imm_field(struct module = *mod, u32 *location, Elf_Ad } =20 overflow: - pr_err("module %s: opr1 =3D 0x%llx overflow! dangerous %s (%u) relocation= \n", + pr_err("module %s: opr1 =3D 0x%lx overflow! dangerous %s (%u) relocation\= n", mod->name, opr1, __func__, type); return -ENOEXEC; =20 unaligned: - pr_err("module %s: opr1 =3D 0x%llx unaligned! dangerous %s (%u) relocatio= n\n", + pr_err("module %s: opr1 =3D 0x%lx unaligned! dangerous %s (%u) relocation= \n", mod->name, opr1, __func__, type); return -ENOEXEC; } =20 static int apply_r_larch_add_sub(struct module *mod, u32 *location, Elf_Ad= dr v, - s64 *rela_stack, size_t *rela_stack_top, unsigned int type) + long *rela_stack, size_t *rela_stack_top, unsigned int type) { switch (type) { case R_LARCH_ADD32: *(s32 *)location +=3D v; return 0; - case R_LARCH_ADD64: - *(s64 *)location +=3D v; - return 0; case R_LARCH_SUB32: *(s32 *)location -=3D v; return 0; +#ifdef CONFIG_64BIT + case R_LARCH_ADD64: + *(s64 *)location +=3D v; + return 0; case R_LARCH_SUB64: *(s64 *)location -=3D v; +#endif return 0; default: pr_err("%s: Unsupport relocation type %u\n", mod->name, type); @@ -278,7 +284,7 @@ static int apply_r_larch_add_sub(struct module *mod, u3= 2 *location, Elf_Addr v, =20 static int apply_r_larch_b26(struct module *mod, Elf_Shdr *sechdrs, u32 *location, Elf_Addr v, - s64 *rela_stack, size_t *rela_stack_top, unsigned int type) + long *rela_stack, size_t *rela_stack_top, unsigned int type) { ptrdiff_t offset =3D (void *)v - (void *)location; union loongarch_instruction *insn =3D (union loongarch_instruction *)loca= tion; @@ -311,14 +317,16 @@ static int apply_r_larch_b26(struct module *mod, } =20 static int apply_r_larch_pcala(struct module *mod, u32 *location, Elf_Addr= v, - s64 *rela_stack, size_t *rela_stack_top, unsigned int type) + long *rela_stack, size_t *rela_stack_top, unsigned int type) { union loongarch_instruction *insn =3D (union loongarch_instruction *)loca= tion; /* Use s32 for a sign-extension deliberately. */ s32 offset_hi20 =3D (void *)((v + 0x800) & ~0xfff) - (void *)((Elf_Addr)location & ~0xfff); +#ifdef CONFIG_64BIT Elf_Addr anchor =3D (((Elf_Addr)location) & ~0xfff) + offset_hi20; ptrdiff_t offset_rem =3D (void *)v - (void *)anchor; +#endif =20 switch (type) { case R_LARCH_PCALA_LO12: @@ -328,6 +336,7 @@ static int apply_r_larch_pcala(struct module *mod, u32 = *location, Elf_Addr v, v =3D offset_hi20 >> 12; insn->reg1i20_format.immediate =3D v & 0xfffff; break; +#ifdef CONFIG_64BIT case R_LARCH_PCALA64_LO20: v =3D offset_rem >> 32; insn->reg1i20_format.immediate =3D v & 0xfffff; @@ -336,6 +345,7 @@ static int apply_r_larch_pcala(struct module *mod, u32 = *location, Elf_Addr v, v =3D offset_rem >> 52; insn->reg2i12_format.immediate =3D v & 0xfff; break; +#endif default: pr_err("%s: Unsupport relocation type %u\n", mod->name, type); return -EINVAL; @@ -346,7 +356,7 @@ static int apply_r_larch_pcala(struct module *mod, u32 = *location, Elf_Addr v, =20 static int apply_r_larch_got_pc(struct module *mod, Elf_Shdr *sechdrs, u32 *location, Elf_Addr v, - s64 *rela_stack, size_t *rela_stack_top, unsigned int type) + long *rela_stack, size_t *rela_stack_top, unsigned int type) { Elf_Addr got =3D module_emit_got_entry(mod, sechdrs, v); =20 @@ -369,7 +379,7 @@ static int apply_r_larch_got_pc(struct module *mod, } =20 static int apply_r_larch_32_pcrel(struct module *mod, u32 *location, Elf_A= ddr v, - s64 *rela_stack, size_t *rela_stack_top, unsigned int type) + long *rela_stack, size_t *rela_stack_top, unsigned int type) { ptrdiff_t offset =3D (void *)v - (void *)location; =20 @@ -377,14 +387,18 @@ static int apply_r_larch_32_pcrel(struct module *mod,= u32 *location, Elf_Addr v, return 0; } =20 +#ifdef CONFIG_32BIT +#define apply_r_larch_64_pcrel apply_r_larch_error +#else static int apply_r_larch_64_pcrel(struct module *mod, u32 *location, Elf_A= ddr v, - s64 *rela_stack, size_t *rela_stack_top, unsigned int type) + long *rela_stack, size_t *rela_stack_top, unsigned int type) { ptrdiff_t offset =3D (void *)v - (void *)location; =20 *(u64 *)location =3D offset; return 0; } +#endif =20 /* * reloc_handlers_rela() - Apply a particular relocation to a module @@ -397,7 +411,7 @@ static int apply_r_larch_64_pcrel(struct module *mod, u= 32 *location, Elf_Addr v, * Return: 0 upon success, else -ERRNO */ typedef int (*reloc_rela_handler)(struct module *mod, u32 *location, Elf_A= ddr v, - s64 *rela_stack, size_t *rela_stack_top, unsigned int type); + long *rela_stack, size_t *rela_stack_top, unsigned int type); =20 /* The handlers for known reloc types */ static reloc_rela_handler reloc_rela_handlers[] =3D { @@ -425,7 +439,7 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *s= trtab, { int i, err; unsigned int type; - s64 rela_stack[RELA_STACK_DEPTH]; + long rela_stack[RELA_STACK_DEPTH]; size_t rela_stack_top =3D 0; reloc_rela_handler handler; void *location; @@ -462,9 +476,9 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *s= trtab, return -EINVAL; } =20 - pr_debug("type %d st_value %llx r_addend %llx loc %llx\n", + pr_debug("type %d st_value %lx r_addend %lx loc %lx\n", (int)ELF_R_TYPE(rel[i].r_info), - sym->st_value, rel[i].r_addend, (u64)location); + (unsigned long)sym->st_value, (unsigned long)rel[i].r_addend, (un= signed long)location); =20 v =3D sym->st_value + rel[i].r_addend; switch (type) { --=20 2.47.3