Skip to content

llext: x86: support for pinned sections #90184

@laurenmurphyx64

Description

@laurenmurphyx64

Is your enhancement proposal related to a problem? Please describe.
I recently put up a PR adding x86 support. On x86, if demand paging is on, which usually means CONFIG_LINKER_USE_PINNED_SECTION is on too, symbols that need to be pinned in memory (such as syscalls) will be put in .pinned_* sections during linking. During boot, these sections are marked "pinned" in memory i.e. they will never be paged.

Tom (@teburd) and I were wondering if we wanted to make that happen for extensions. Since we load the sections ourselves, they aren't actually "pinned". Do we want them to be? I think we'd have to call mark_linker_section_pinned...

To see what sorts of functions / data go in pinned sections, search "_pinned_func" / "_pinned_data". syscalls_ext.c / threads_kernel_objects_ext.c both produced .pinned_* sections.

$ west build -p -b qemu_x86/atom/virt tests/subsys/llext
$ readelf -r build/llext/threads_kernel_objects.llext
...
Relocation section '.rel.pinned_text' at offset 0xb1c contains 7 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
00000007  00000302 R_386_PC32        00000000   z_impl_device_get[...]
00000019  00000402 R_386_PC32        00000000   z_impl_device_is_ready
00000049  00000502 R_386_PC32        00000000   z_impl_k_thread_create
00000061  00000602 R_386_PC32        00000000   z_impl_k_thread_join
00000073  00000702 R_386_PC32        00000000   z_impl_k_wakeup
0000008c  00000802 R_386_PC32        00000000   z_impl_k_sem_take
0000009e  00000902 R_386_PC32        00000000   z_impl_k_sem_give
...

$ readelf -r build/llext/syscalls.llext
...
Relocation section '.rel.pinned_text' at offset 0x3b4 contains 1 entry:
 Offset     Info    Type            Sym.Value  Sym. Name
00000007  00000302 R_386_PC32        00000000   z_impl_ext_syscall_ok

These sections are admittedly rather small, compared to the MMU page size e.g. CONFIG_MMU_PAGE_SIZE being 0x1000, but I guess for a real extension they could be a lot bigger.

$ readelf -S build/llext/threads_kernel_objects.llext
...
[Nr] Name                Type                   Addr         Off         Size       ES  Flg Lk Inf Al
[ 5] .pinned_text      PROGBITS        00000000 000380 0000aa 00  AX  0   0   1
...
$ readelf -S build/llext/syscalls.llext
...
[ 5] .pinned_text      PROGBITS        00000000 000128 000012 00  AX  0   0  1
...

Describe the solution you'd like
I don't have a particular solution I'd like, just raising the issue as an enhancement.

Describe alternatives you've considered
If people don't think extensions should have sections pinned in memory, we don't need to, I guess.

Additional Context
A related problem to keep in mind is the fact that the pinned sections - .pinned_text, .pinned_rodata, .pinned_data, .pinned_bss, and .pinned_noinit - will appear in the extension in the order that the first instance of data or code in that section appears in the extension.c.i (preprocessed) file. This can cause issues, for example when .pinned_text appears such that .rodata is in between it and .text - the LLEXT loader needs .text like sections to be grouped together, and fails with an "overlapping region" error (rodata region inside text region). I worked around this in my PR introducing x86 LLEXT support by just moving up the syscalls_ext.h header include.

Metadata

Metadata

Assignees

No one assigned

    Labels

    EnhancementChanges/Updates/Additions to existing featuresarea: llextLinkable Loadable Extensionsplatform: X86x86 and x86-64

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions