From efdef3a09f1286201a5bb4f51a4213bbd66ebf7a Mon Sep 17 00:00:00 2001 From: esma Date: Fri, 11 Sep 2026 12:14:48 -0400 Subject: [PATCH 1/2] chal: extract the ASID once so CR3_NO_FLUSH takes effect chal_pgtbl_update() extracts the ASID from pt->protdom, then hands it to chal_cached_pt_curr() and chal_cached_pt_update(), which applied PROTDOM_ASID() to it again. Every ASID below 16 collapsed onto slot 0 of tlb_asid_map, so the cached-pgtbl check missed on every component crossing and CR3_NO_FLUSH was never set: each sinv and sret flushed the TLB entries of the PCID being loaded. The helpers now take the ASID directly. tlb_asid_map also gets the slot for ASID NUM_ASID_MAX, which PROTDOM_ASID() can return and which the collapse had been masking. On bare metal (Xeon Platinum 8160) the ping_pong round trip drops from 1127 to 851 cycles, and from 1152 to 851 with sched_ping_pong. The flushes that remain are one cold miss per ASID plus reloads of a PCID with a different page table (the booter shares ASID 0), which are required. Nothing relied on the extra flushes for memory reuse: chal_flush_tlb() is empty on x86, and the quiescence checks gating retype, remap and kmem release fail closed. Revocation by unmap is weaker, though: a component whose page is unmapped keeps its stale translation on the local core until that ASID's cached page table changes. It was never enforced on remote cores (chal_remote_tlb_flush() is empty). Co-Authored-By: Claude Opus 5 --- src/platform/i386/chal/chal_proto.h | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/platform/i386/chal/chal_proto.h b/src/platform/i386/chal/chal_proto.h index 62de4685d..eba7cf2e5 100644 --- a/src/platform/i386/chal/chal_proto.h +++ b/src/platform/i386/chal/chal_proto.h @@ -146,23 +146,31 @@ chal_protdom_read(void) #endif /* MPK_ENABLED */ +/* + * Indexed by ASID, so it needs a slot for every representable name: + * PROTDOM_ASID() yields 0..NUM_ASID_MAX inclusive. + */ struct cpu_tlb_asid_map { - pgtbl_t mapped_pt[NUM_ASID_MAX]; + pgtbl_t mapped_pt[NUM_ASID_MAX + 1]; } CACHE_ALIGNED; extern struct cpu_tlb_asid_map tlb_asid_map[NUM_CPU]; +/* + * These take an ASID, not a prot_domain_t: the caller has already + * extracted it. Applying PROTDOM_ASID() again here collapsed every + * ASID < 16 onto slot 0, so the cached-pgtbl check missed on every + * component crossing and CR3_NO_FLUSH was never set. + */ static inline pgtbl_t -chal_cached_pt_curr(prot_domain_t protdom) +chal_cached_pt_curr(u16_t asid) { - u16_t asid = PROTDOM_ASID(protdom); return tlb_asid_map[get_cpuid()].mapped_pt[asid]; } static inline void -chal_cached_pt_update(pgtbl_t pt, prot_domain_t protdom) +chal_cached_pt_update(pgtbl_t pt, u16_t asid) { - u16_t asid = PROTDOM_ASID(protdom); tlb_asid_map[get_cpuid()].mapped_pt[asid] = pt; } From 4e069fedd8b1163b6d74c29b8993f82cefbaba14 Mon Sep 17 00:00:00 2001 From: esma Date: Fri, 11 Sep 2026 12:22:54 -0400 Subject: [PATCH 2/2] ps: update submodule to gwsystems/ps master The pinned ps (f7bcdbe) does not define PS_LOCK_INITIALIZER, which capmgr uses, so compositions with a capmgr (e.g. sched_ping_pong.toml) failed to build. master (ca50b3f) defines it; the rest of the update is comment fixes in ps_list.h and a standalone list example. Co-Authored-By: Claude Opus 5 --- src/components/lib/ps/ps | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/lib/ps/ps b/src/components/lib/ps/ps index f7bcdbe09..ca50b3f1b 160000 --- a/src/components/lib/ps/ps +++ b/src/components/lib/ps/ps @@ -1 +1 @@ -Subproject commit f7bcdbe097377976210c20beb22a2b95db104afc +Subproject commit ca50b3f1b2a87e5bdf75e618257ed3097e9d4bfd