From 5f8abe8bda6f54f35d0bb3db8c4ffb8aa112e75a Mon Sep 17 00:00:00 2001 From: Dapeng Gao Date: Fri, 12 Apr 2024 13:48:41 +0100 Subject: [PATCH] c18n: Use superpages to store trampolines --- libexec/rtld-elf/rtld_c18n.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/libexec/rtld-elf/rtld_c18n.c b/libexec/rtld-elf/rtld_c18n.c index e4d19f1508a1..6493a094112e 100644 --- a/libexec/rtld-elf/rtld_c18n.c +++ b/libexec/rtld-elf/rtld_c18n.c @@ -974,16 +974,12 @@ struct tramp_pg { _Alignas(_Alignof(void *)) char trampolines[]; }; -/* - * 64K is the largest size such that any capability-aligned proper - * sub-range can be exactly bounded by a Morello capability. - */ -#define C18N_TRAMPOLINE_PAGE_SIZE 64 * 1024 +static size_t tramp_pg_size; static struct tramp_pg * tramp_pg_new(struct tramp_pg *next) { - size_t capacity = C18N_TRAMPOLINE_PAGE_SIZE; + size_t capacity = tramp_pg_size; struct tramp_pg *pg; pg = mmap(NULL, capacity, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON, @@ -1015,7 +1011,7 @@ tramp_pg_push(struct tramp_pg *pg, size_t len) */ &size, n_size, memory_order_relaxed, memory_order_relaxed)); - tramp = cheri_setbounds(tramp, len); + tramp = cheri_setboundsexact(tramp, len); assert(cheri_gettag(tramp)); return (tramp); @@ -1512,10 +1508,17 @@ c18n_init(Obj_Entry *obj_rtld) } } +/* + * Trampoline pages should be large to minimise pressure on the TLB, but not too + * large. 4MB is a reasonable threshold. + */ +#define MAX_TRAMP_PG_SIZE (4 * 1024 * 1024) + void c18n_init2(void) { uintptr_t sealer; + int n = npagesizes; /* * Allocate otypes for RTLD use @@ -1551,8 +1554,14 @@ c18n_init2(void) expand_tramp_table(9); /* - * Create the first trampoline page. + * Find a suitable page size and create the first trampoline page. */ + while (n-- > 0) + if (pagesizes[n] <= MAX_TRAMP_PG_SIZE) { + tramp_pg_size = pagesizes[n]; + break; + } + assert(tramp_pg_size > 0); atomic_store_explicit(&tramp_pgs.head, tramp_pg_new(NULL), memory_order_relaxed); }