Page MenuHomeFreeBSD

Add support for re-resolving arm64 ifuncs when all CPUs are online
ClosedPublic

Authored by andrew on Jun 25 2020, 5:27 PM.

Details

Summary

As arm64 uses rela relocations the addend is stored in in the relocaation.
As nothing writes to these we can re-run ifunc resolvers late in the
boot process to allow them to take into account the new CPUs that have
come online.

Diff Detail

Repository
rS FreeBSD src repository
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.

Event Timeline

I'm working on a patch to generate a common kernel view of the ID registers that will be available when link_elf_late_ireloc is called. It will also store the ID registers of CPU 0 when the resolvers are initially called so the resolvers will be identical early in the boot and after all CPUs have started.

sys/arm64/arm64/mp_machdep.c
171 ↗(On Diff #73648)

Is it fine to re-reloc only on SMP ?

sys/kern/link_elf.c
1929 ↗(On Diff #73648)

This should be not arm64 specific, rather it should depend on RELA vs REL.

I have created D25463 to create the common kernel view that will be used by ifunc resolvers.

  • Call link_elf_late_ireloc from a SYSINIT function
  • Pass a flag into elf_reloc_internal rather than more arguments
andrew added inline comments.
sys/kern/link_elf.c
1929 ↗(On Diff #73648)

It needs an implementation of elf_reloc_late in the per-arch code. I've only implemented it on arm64 as I'm unsure what other architectures use RELA relocations.

sys/kern/link_elf.c
1929 ↗(On Diff #73648)

I think for now it is enough to have aarch64 and amd64.

Add untested amd64 support

It is fine, except one detail that I do not like. You do the late pass after the APs were released.

I mean, despite the fact that relocations are idempotent, there are some dependencies between the set of functions returned by resolver. For instance, on amd64 pmap_activate() and pmap_invalidate_*() must be aligned.

I believe that it is needed to park other CPUs into safe loops that cannot be preempted while the resolution is performed.

Aren't the CPUs parked until release_aps is called? This will be in SI_SUB_SMP which is later than SI_SUB_CPU where the ifunc resolvers are called.

Aren't the CPUs parked until release_aps is called? This will be in SI_SUB_SMP which is later than SI_SUB_CPU where the ifunc resolvers are called.

I see, I mixed _CPU/_SMP.

This revision is now accepted and ready to land.Jul 3 2020, 12:03 PM