aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitchell Horne <mhorne@FreeBSD.org>2026-02-05 16:11:25 +0000
committerMitchell Horne <mhorne@FreeBSD.org>2026-02-05 16:32:16 +0000
commitcf41d1113377c44be5aad20c2f7ff2c5324ca89f (patch)
treee8138f88548b11af20a7943c70cf7be9e6b30638
parent157d6664aeb815db3b758bd3038fd1512a0f4e2c (diff)
riscv: implement kernel ifunc resolution
This completes the set of architectures implementing this feature. Move the calls to sched_instance_select() and link_elf_ireloc() later in initriscv(), after identify_cpu(0). There will be more information available to any resolver functions at this time. Reviewed by: imp, kib MFC after: 2 weeks Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D55082
-rw-r--r--sys/conf/kern.pre.mk5
-rw-r--r--sys/kern/link_elf.c2
-rw-r--r--sys/riscv/include/ifunc.h2
-rw-r--r--sys/riscv/riscv/elf_machdep.c11
-rw-r--r--sys/riscv/riscv/machdep.c6
5 files changed, 14 insertions, 12 deletions
diff --git a/sys/conf/kern.pre.mk b/sys/conf/kern.pre.mk
index 93e291b45bb6..cf5e4a96ad49 100644
--- a/sys/conf/kern.pre.mk
+++ b/sys/conf/kern.pre.mk
@@ -119,10 +119,9 @@ CFLAGS+= ${CONF_CFLAGS}
LDFLAGS+= --build-id=sha1
.endif
-.if ${MACHINE_CPUARCH} != "riscv" && \
- defined(LINKER_FEATURES) && ${LINKER_FEATURES:Mifunc} == "" && \
+.if defined(LINKER_FEATURES) && ${LINKER_FEATURES:Mifunc} == "" && \
!make(install)
-.error amd64/arm/arm64/i386/ppc* kernel requires linker ifunc support
+.error kernel requires linker ifunc support
.endif
.if ${MACHINE_CPUARCH} == "amd64"
LDFLAGS+= -z max-page-size=2097152
diff --git a/sys/kern/link_elf.c b/sys/kern/link_elf.c
index 2a9e2a02709d..4c77f444d961 100644
--- a/sys/kern/link_elf.c
+++ b/sys/kern/link_elf.c
@@ -2041,7 +2041,6 @@ link_elf_propagate_vnets(linker_file_t lf)
}
#endif
-#if !defined(__riscv)
/*
* Use this lookup routine when performing relocations early during boot.
* The generic lookup routine depends on kobj, which is not initialized
@@ -2104,4 +2103,3 @@ link_elf_late_ireloc(void)
relocate_file1(ef, elf_lookup_ifunc, elf_reloc_late, true);
}
#endif
-#endif
diff --git a/sys/riscv/include/ifunc.h b/sys/riscv/include/ifunc.h
index 0d91014ccce8..0f9747a2aa14 100644
--- a/sys/riscv/include/ifunc.h
+++ b/sys/riscv/include/ifunc.h
@@ -30,8 +30,6 @@
#ifndef __RISCV_IFUNC_H
#define __RISCV_IFUNC_H
-#define __DO_NOT_HAVE_SYS_IFUNCS 1
-
#define DEFINE_IFUNC(qual, ret_type, name, args) \
static ret_type (*name##_resolver(void))args __used; \
qual ret_type name args __attribute__((ifunc(#name "_resolver"))); \
diff --git a/sys/riscv/riscv/elf_machdep.c b/sys/riscv/riscv/elf_machdep.c
index 5bd4af4c15f8..b52050e56a14 100644
--- a/sys/riscv/riscv/elf_machdep.c
+++ b/sys/riscv/riscv/elf_machdep.c
@@ -271,10 +271,10 @@ reloctype_to_str(int type)
}
bool
-elf_is_ifunc_reloc(Elf_Size r_info __unused)
+elf_is_ifunc_reloc(Elf_Size r_info)
{
- return (false);
+ return (ELF_R_TYPE(r_info) == R_RISCV_IRELATIVE);
}
/*
@@ -501,7 +501,12 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
(local ? 'l' : 'g'), reloctype_to_str(rtype),
before32, *insn32p);
break;
-
+ case R_RISCV_IRELATIVE:
+ addr = relocbase + addend;
+ val = ((Elf64_Addr (*)(void))addr)();
+ if (*where != val)
+ *where = val;
+ break;
default:
printf("kldload: unexpected relocation type %ld, "
"symbol index %ld\n", rtype, symidx);
diff --git a/sys/riscv/riscv/machdep.c b/sys/riscv/riscv/machdep.c
index b213e8812bc7..0214426eea18 100644
--- a/sys/riscv/riscv/machdep.c
+++ b/sys/riscv/riscv/machdep.c
@@ -479,8 +479,6 @@ parse_metadata(void)
/* Initialize preload_kmdp */
preload_initkmdp(true);
- sched_instance_select();
- /* link_elf_ireloc(); */
/* Read the boot metadata */
boothowto = MD_FETCH(preload_kmdp, MODINFOMD_HOWTO, int);
@@ -626,6 +624,10 @@ initriscv(struct riscv_bootparams *rvbp)
*/
identify_cpu(0);
+ sched_instance_select();
+
+ link_elf_ireloc();
+
/* Do basic tuning, hz etc */
init_param1();