Make litebox_shim_linux generic over its platform - #1056

Merged
Jay Bosamiya (Microsoft) (jaybosamiya-ms) merged 3 commits into
microsoft:mainfrom
jstarks:generic2
Jul 21, 2026
Merged

Make litebox_shim_linux generic over its platform#1056
Jay Bosamiya (Microsoft) (jaybosamiya-ms) merged 3 commits into
microsoft:mainfrom
jstarks:generic2

Conversation

@jstarks

@jstarksJohn Starks (jstarks) commented Jul 21, 2026

Copy link
Copy Markdown
Member

The Linux shim was hard-wired to the global litebox_platform_multiplex::Platform singleton (set via set_platform, fetched via platform()). This made the shim non-generic and forced platform selection through cargo features. This PR parameterizes the shim over a platform type Platform end-to-end.

…iplex
The Linux shim was hard-wired to the global `litebox_platform_multiplex::Platform`
singleton (set via `set_platform`, fetched via `platform()`). This made the shim
non-generic and forced platform selection through cargo features.
Parameterize the shim over a platform type `Platform` end-to-end (alongside the
existing `FS`): `LinuxShimBuilder<Platform>`, `LinuxShim<Platform, FS>`,
`GlobalState`, `Task`, `LoadedProgram`, and every subsystem type (epoll, unix
sockets, eventfd, channels, signals, process/thread state, transport, ELF loader).
`LinuxShimBuilder::new(platform)` now takes a `&'static Platform`; the global
accessor is gone.
- Add a sealed `ShimPlatform` aggregate bound (with blanket impl) so impls read
`impl<Platform: ShimPlatform, FS: ShimFS>`. It also pins the associated types
the shim relies on: ThreadProvider::ExecutionContext = PtRegs, Timer/Signal
Provider::Signal = common Signal, and VmemPageFaultHandler.
- Remove the litebox_platform_multiplex dependency and platform_* features from
litebox_shim_linux. Tests pick a concrete platform by build target via a
`TestPlatform` alias (LinuxUserland / WindowsUserland) with target-scoped
dev-deps.
- Update the runners to depend on their concrete platform crate and instantiate
`LinuxShimBuilder::new(platform_ref)`: linux_userland (LinuxUserland),
linux_on_windows_userland (WindowsUserland), snp (SnpLinuxKernel). The SNP
page-fault handler reaches the platform through a new `LinuxShim::platform()`
accessor instead of a global.
- Update README to describe the threaded-platform model.
@jstarks
John Starks (jstarks) marked this pull request as ready for review July 21, 2026 08:26

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall LGTM, I've made a few minor notes of nits, I've also updated the PR description to reduce some of the verbosity.

Comment threadlitebox_runner_snp/src/main.rs
Comment threadlitebox_shim_linux/src/lib.rs
Comment threadlitebox_shim_linux/README.md
@jaybosamiya-ms

Copy link
Copy Markdown
Member

Also, since semver-checks CI bot does not fire on branches from forks, here's its output as of 04dc576 (basically expected tweaks):

click to unfold
--- failure feature_missing: package feature removed or renamed ---
Description:
A feature has been removed from this package's Cargo.toml. This will break downstream crates which enable that feature.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#cargo-feature-remove
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.49.0/src/lints/feature_missing.ron
Failed in:
feature platform_linux_userland in the package's Cargo.toml
feature platform_windows_userland in the package's Cargo.toml
feature platform_linux_snp in the package's Cargo.toml
--- failure method_parameter_count_changed: pub method parameter count changed ---
Description:
A publicly-visible method now takes a different number of parameters, not counting the receiver (self) parameter.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#fn-change-arity
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.49.0/src/lints/method_parameter_count_changed.ron
Failed in:
litebox_shim_linux::LinuxShimBuilder::new takes 0 parameters in /home/runner/work/litebox/litebox/target/semver-checks/git-main/30e3a38e80ded90e8ea438866862948a82cadd79/litebox_shim_linux/src/lib.rs:170, but now takes 1 parameters in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:208
--- failure trait_requires_more_generic_type_params: trait now requires more generic type parameters ---
Description:
A trait now requires more generic type parameters than it used to. Uses of this trait that supplied the previously-required number of generic types will be broken. To fix this, consider supplying default values for newly-added generic types.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#trait-new-parameter-no-default
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.49.0/src/lints/trait_requires_more_generic_type_params.ron
Failed in:
trait LinuxShim (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:249
trait LinuxShimEntrypoints (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:134
trait ShimTransport (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/transport.rs:51
trait LoadedProgram (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:356
trait LinuxShimProcess (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:364
trait LinuxShimBuilder (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:201
--- failure type_requires_more_generic_type_params: type now requires more generic type parameters ---
Description:
A type now requires more generic type parameters than it used to. Uses of this type that supplied the previously-required number of generic types will be broken. To fix this, consider supplying default values for newly-added generic types.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#trait-new-parameter-no-default
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.49.0/src/lints/type_requires_more_generic_type_params.ron
Failed in:
Struct LinuxShim (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:249
Struct LinuxShimEntrypoints (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:134
Struct ShimTransport (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/transport.rs:51
Struct LoadedProgram (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:356
Struct LinuxShimProcess (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:364
Struct LinuxShimBuilder (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:201

Merged via the queue into microsoft:main with commit 864239bJul 21, 2026
9 checks passed
pullBot pushed a commit to Mu-L/litebox that referenced this pull request Jul 22, 2026
Makes SNP shim initialization safer via `OnceBox`, and cleans up some
documentation.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 28, 2026
…#1056
`set_platform` was a private one-liner with a single caller, wrapping one
`OnceRef::set`. It mirrored the shape of `litebox_platform_multiplex`, which
needed a setter because it was a separate crate exporting one to foreign
callers. Inside a single module with one call site it is ceremony, and it made
the design read as more global-oriented than it is. `init` now sets the cell
directly and `platform()` is the sole named accessor.
The `PLATFORM` cell itself stays and cannot reasonably go: `Platform::new` runs
only on the BSP and leaks its result, and the AP bring-up trampoline is naked
assembly whose only payload is the `is_bsp` flag in `edi`, so an AP has no
channel to receive the pointer. The doc comment now states that rather than
gesturing at it.
Two artifacts found by comparing against how PR #1056 handled the same job for
litebox_shim_linux:
- The shim's test helper still branched on `cfg(not(target_os = "linux"))` to
call a different `Platform::new`. `Platform` is now hardcoded to
`LinuxUserland`, so that arm was unreachable and would not have compiled.
- The CI `no_std` allow-list rationale for `litebox_shim_optee` claimed it
"depends on `litebox_platform_multiplex`", which is no longer true. #1056
deleted the equivalent entry for litebox_shim_linux outright. That is not
possible here: building litebox_shim_optee for `x86_64-unknown-none` still
fails, but in `sha2`, for the same soft-float/asm reason
`litebox_service_heki` is excluded. The entry stays; the comment now says why.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 28, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Also corrects two stale CI artifacts: the `no_std` rationale for
`litebox_shim_optee` claimed a multiplex dependency, when it is excluded because
its crypto dependencies fail to build for `x86_64-unknown-none`, as with
`litebox_service_heki`.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 28, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
The shim was bound to `litebox_platform_multiplex::Platform`, so platform
selection happened via cargo features and every platform access went through a
panicking global. It is now parameterized end-to-end, mirroring what PR #1056 did
for litebox_shim_linux.
`OpteeShimPlatform` collects the required capabilities. It includes
`VmapManager<PAGE_SIZE>`, which is what the previous two commits bought: the
shim's need to read and write normal-world physical memory is now a trait bound
rather than a consequence of which platform the build happened to select.
Both runners drop the `litebox_platform_multiplex` dependency and name their
platform directly. Neither gains anything it did not already have:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is exactly what the
multiplex `platform_linux_userland_with_optee_syscall` feature was enabling.
The session registry moved from the shim to each runner. This is not cosmetic: a
`static` cannot name a generic parameter, and a shim instance is built per
session, so the shim has nowhere to put it. The composition root names a concrete
platform, so it can hold the `static` and hand out
`&'static SessionManager<ConcretePlatform>`. `GlobalState` now carries that
reference, which is how `current_client_identity` reaches it.
Honest accounting of the global ratchet: this relocates globals more than it
removes them. litebox_shim_optee stays at 5 (it loses the session registry but
its tests gain a platform and a registry, and `INIT_FUNC` goes away).
litebox_runner_lvbs goes 6 -> 8: the platform handle and the session registry.
litebox_runner_optee_on_linux_userland gets a new entry of 1 for its registry.
The platform and shim crates no longer reach for ambient state; the composition
roots do, which is where that belongs.
`litebox_platform_multiplex` now has zero workspace consumers. It is left in the
tree pending a separate decision.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
The shim was bound to `litebox_platform_multiplex::Platform`, so platform
selection happened via cargo features and every platform access went through a
panicking global. It is now parameterized end-to-end, mirroring what PR #1056 did
for litebox_shim_linux.
`OpteeShimPlatform` collects the required capabilities. It includes
`VmapManager<PAGE_SIZE>`, which is what the previous two commits bought: the
shim's need to read and write normal-world physical memory is now a trait bound
rather than a consequence of which platform the build happened to select.
Both runners drop the `litebox_platform_multiplex` dependency and name their
platform directly. Neither gains anything it did not already have:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is exactly what the
multiplex `platform_linux_userland_with_optee_syscall` feature was enabling.
The session registry moved from the shim to each runner. This is not cosmetic: a
`static` cannot name a generic parameter, and a shim instance is built per
session, so the shim has nowhere to put it. The composition root names a concrete
platform, so it can hold the `static` and hand out
`&'static SessionManager<ConcretePlatform>`. `GlobalState` now carries that
reference, which is how `current_client_identity` reaches it.
Honest accounting of the global ratchet: this relocates globals more than it
removes them. litebox_shim_optee stays at 5 (it loses the session registry but
its tests gain a platform and a registry, and `INIT_FUNC` goes away).
litebox_runner_lvbs goes 6 -> 8: the platform handle and the session registry.
litebox_runner_optee_on_linux_userland gets a new entry of 1 for its registry.
The platform and shim crates no longer reach for ambient state; the composition
roots do, which is where that belongs.
`litebox_platform_multiplex` now has zero workspace consumers. It is left in the
tree pending a separate decision.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@jstarks@jaybosamiya-ms
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Make litebox_shim_linux generic over its platform - #1056

Merged
Jay Bosamiya (Microsoft) (jaybosamiya-ms) merged 3 commits into
microsoft:mainfrom
jstarks:generic2
Jul 21, 2026
Merged

Make litebox_shim_linux generic over its platform#1056
Jay Bosamiya (Microsoft) (jaybosamiya-ms) merged 3 commits into
microsoft:mainfrom
jstarks:generic2

Conversation

@jstarks

@jstarksJohn Starks (jstarks) commented Jul 21, 2026

Copy link
Copy Markdown
Member

The Linux shim was hard-wired to the global litebox_platform_multiplex::Platform singleton (set via set_platform, fetched via platform()). This made the shim non-generic and forced platform selection through cargo features. This PR parameterizes the shim over a platform type Platform end-to-end.

…iplex
The Linux shim was hard-wired to the global `litebox_platform_multiplex::Platform`
singleton (set via `set_platform`, fetched via `platform()`). This made the shim
non-generic and forced platform selection through cargo features.
Parameterize the shim over a platform type `Platform` end-to-end (alongside the
existing `FS`): `LinuxShimBuilder<Platform>`, `LinuxShim<Platform, FS>`,
`GlobalState`, `Task`, `LoadedProgram`, and every subsystem type (epoll, unix
sockets, eventfd, channels, signals, process/thread state, transport, ELF loader).
`LinuxShimBuilder::new(platform)` now takes a `&'static Platform`; the global
accessor is gone.
- Add a sealed `ShimPlatform` aggregate bound (with blanket impl) so impls read
`impl<Platform: ShimPlatform, FS: ShimFS>`. It also pins the associated types
the shim relies on: ThreadProvider::ExecutionContext = PtRegs, Timer/Signal
Provider::Signal = common Signal, and VmemPageFaultHandler.
- Remove the litebox_platform_multiplex dependency and platform_* features from
litebox_shim_linux. Tests pick a concrete platform by build target via a
`TestPlatform` alias (LinuxUserland / WindowsUserland) with target-scoped
dev-deps.
- Update the runners to depend on their concrete platform crate and instantiate
`LinuxShimBuilder::new(platform_ref)`: linux_userland (LinuxUserland),
linux_on_windows_userland (WindowsUserland), snp (SnpLinuxKernel). The SNP
page-fault handler reaches the platform through a new `LinuxShim::platform()`
accessor instead of a global.
- Update README to describe the threaded-platform model.
@jstarks
John Starks (jstarks) marked this pull request as ready for review July 21, 2026 08:26

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall LGTM, I've made a few minor notes of nits, I've also updated the PR description to reduce some of the verbosity.

Comment threadlitebox_runner_snp/src/main.rs
Comment threadlitebox_shim_linux/src/lib.rs
Comment threadlitebox_shim_linux/README.md
@jaybosamiya-ms

Copy link
Copy Markdown
Member

Also, since semver-checks CI bot does not fire on branches from forks, here's its output as of 04dc576 (basically expected tweaks):

click to unfold
--- failure feature_missing: package feature removed or renamed ---
Description:
A feature has been removed from this package's Cargo.toml. This will break downstream crates which enable that feature.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#cargo-feature-remove
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.49.0/src/lints/feature_missing.ron
Failed in:
feature platform_linux_userland in the package's Cargo.toml
feature platform_windows_userland in the package's Cargo.toml
feature platform_linux_snp in the package's Cargo.toml
--- failure method_parameter_count_changed: pub method parameter count changed ---
Description:
A publicly-visible method now takes a different number of parameters, not counting the receiver (self) parameter.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#fn-change-arity
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.49.0/src/lints/method_parameter_count_changed.ron
Failed in:
litebox_shim_linux::LinuxShimBuilder::new takes 0 parameters in /home/runner/work/litebox/litebox/target/semver-checks/git-main/30e3a38e80ded90e8ea438866862948a82cadd79/litebox_shim_linux/src/lib.rs:170, but now takes 1 parameters in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:208
--- failure trait_requires_more_generic_type_params: trait now requires more generic type parameters ---
Description:
A trait now requires more generic type parameters than it used to. Uses of this trait that supplied the previously-required number of generic types will be broken. To fix this, consider supplying default values for newly-added generic types.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#trait-new-parameter-no-default
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.49.0/src/lints/trait_requires_more_generic_type_params.ron
Failed in:
trait LinuxShim (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:249
trait LinuxShimEntrypoints (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:134
trait ShimTransport (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/transport.rs:51
trait LoadedProgram (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:356
trait LinuxShimProcess (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:364
trait LinuxShimBuilder (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:201
--- failure type_requires_more_generic_type_params: type now requires more generic type parameters ---
Description:
A type now requires more generic type parameters than it used to. Uses of this type that supplied the previously-required number of generic types will be broken. To fix this, consider supplying default values for newly-added generic types.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#trait-new-parameter-no-default
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.49.0/src/lints/type_requires_more_generic_type_params.ron
Failed in:
Struct LinuxShim (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:249
Struct LinuxShimEntrypoints (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:134
Struct ShimTransport (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/transport.rs:51
Struct LoadedProgram (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:356
Struct LinuxShimProcess (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:364
Struct LinuxShimBuilder (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:201

Merged via the queue into microsoft:main with commit 864239bJul 21, 2026
9 checks passed
pullBot pushed a commit to Mu-L/litebox that referenced this pull request Jul 22, 2026
Makes SNP shim initialization safer via `OnceBox`, and cleans up some
documentation.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 28, 2026
…#1056
`set_platform` was a private one-liner with a single caller, wrapping one
`OnceRef::set`. It mirrored the shape of `litebox_platform_multiplex`, which
needed a setter because it was a separate crate exporting one to foreign
callers. Inside a single module with one call site it is ceremony, and it made
the design read as more global-oriented than it is. `init` now sets the cell
directly and `platform()` is the sole named accessor.
The `PLATFORM` cell itself stays and cannot reasonably go: `Platform::new` runs
only on the BSP and leaks its result, and the AP bring-up trampoline is naked
assembly whose only payload is the `is_bsp` flag in `edi`, so an AP has no
channel to receive the pointer. The doc comment now states that rather than
gesturing at it.
Two artifacts found by comparing against how PR #1056 handled the same job for
litebox_shim_linux:
- The shim's test helper still branched on `cfg(not(target_os = "linux"))` to
call a different `Platform::new`. `Platform` is now hardcoded to
`LinuxUserland`, so that arm was unreachable and would not have compiled.
- The CI `no_std` allow-list rationale for `litebox_shim_optee` claimed it
"depends on `litebox_platform_multiplex`", which is no longer true. #1056
deleted the equivalent entry for litebox_shim_linux outright. That is not
possible here: building litebox_shim_optee for `x86_64-unknown-none` still
fails, but in `sha2`, for the same soft-float/asm reason
`litebox_service_heki` is excluded. The entry stays; the comment now says why.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 28, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Also corrects two stale CI artifacts: the `no_std` rationale for
`litebox_shim_optee` claimed a multiplex dependency, when it is excluded because
its crypto dependencies fail to build for `x86_64-unknown-none`, as with
`litebox_service_heki`.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 28, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
The shim was bound to `litebox_platform_multiplex::Platform`, so platform
selection happened via cargo features and every platform access went through a
panicking global. It is now parameterized end-to-end, mirroring what PR #1056 did
for litebox_shim_linux.
`OpteeShimPlatform` collects the required capabilities. It includes
`VmapManager<PAGE_SIZE>`, which is what the previous two commits bought: the
shim's need to read and write normal-world physical memory is now a trait bound
rather than a consequence of which platform the build happened to select.
Both runners drop the `litebox_platform_multiplex` dependency and name their
platform directly. Neither gains anything it did not already have:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is exactly what the
multiplex `platform_linux_userland_with_optee_syscall` feature was enabling.
The session registry moved from the shim to each runner. This is not cosmetic: a
`static` cannot name a generic parameter, and a shim instance is built per
session, so the shim has nowhere to put it. The composition root names a concrete
platform, so it can hold the `static` and hand out
`&'static SessionManager<ConcretePlatform>`. `GlobalState` now carries that
reference, which is how `current_client_identity` reaches it.
Honest accounting of the global ratchet: this relocates globals more than it
removes them. litebox_shim_optee stays at 5 (it loses the session registry but
its tests gain a platform and a registry, and `INIT_FUNC` goes away).
litebox_runner_lvbs goes 6 -> 8: the platform handle and the session registry.
litebox_runner_optee_on_linux_userland gets a new entry of 1 for its registry.
The platform and shim crates no longer reach for ambient state; the composition
roots do, which is where that belongs.
`litebox_platform_multiplex` now has zero workspace consumers. It is left in the
tree pending a separate decision.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
The shim was bound to `litebox_platform_multiplex::Platform`, so platform
selection happened via cargo features and every platform access went through a
panicking global. It is now parameterized end-to-end, mirroring what PR #1056 did
for litebox_shim_linux.
`OpteeShimPlatform` collects the required capabilities. It includes
`VmapManager<PAGE_SIZE>`, which is what the previous two commits bought: the
shim's need to read and write normal-world physical memory is now a trait bound
rather than a consequence of which platform the build happened to select.
Both runners drop the `litebox_platform_multiplex` dependency and name their
platform directly. Neither gains anything it did not already have:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is exactly what the
multiplex `platform_linux_userland_with_optee_syscall` feature was enabling.
The session registry moved from the shim to each runner. This is not cosmetic: a
`static` cannot name a generic parameter, and a shim instance is built per
session, so the shim has nowhere to put it. The composition root names a concrete
platform, so it can hold the `static` and hand out
`&'static SessionManager<ConcretePlatform>`. `GlobalState` now carries that
reference, which is how `current_client_identity` reaches it.
Honest accounting of the global ratchet: this relocates globals more than it
removes them. litebox_shim_optee stays at 5 (it loses the session registry but
its tests gain a platform and a registry, and `INIT_FUNC` goes away).
litebox_runner_lvbs goes 6 -> 8: the platform handle and the session registry.
litebox_runner_optee_on_linux_userland gets a new entry of 1 for its registry.
The platform and shim crates no longer reach for ambient state; the composition
roots do, which is where that belongs.
`litebox_platform_multiplex` now has zero workspace consumers. It is left in the
tree pending a separate decision.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@jstarks@jaybosamiya-ms
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Make litebox_shim_linux generic over its platform - #1056

Merged
Jay Bosamiya (Microsoft) (jaybosamiya-ms) merged 3 commits into
microsoft:mainfrom
jstarks:generic2
Jul 21, 2026
Merged

Make litebox_shim_linux generic over its platform#1056
Jay Bosamiya (Microsoft) (jaybosamiya-ms) merged 3 commits into
microsoft:mainfrom
jstarks:generic2

Conversation

@jstarks

@jstarksJohn Starks (jstarks) commented Jul 21, 2026

Copy link
Copy Markdown
Member

The Linux shim was hard-wired to the global litebox_platform_multiplex::Platform singleton (set via set_platform, fetched via platform()). This made the shim non-generic and forced platform selection through cargo features. This PR parameterizes the shim over a platform type Platform end-to-end.

…iplex
The Linux shim was hard-wired to the global `litebox_platform_multiplex::Platform`
singleton (set via `set_platform`, fetched via `platform()`). This made the shim
non-generic and forced platform selection through cargo features.
Parameterize the shim over a platform type `Platform` end-to-end (alongside the
existing `FS`): `LinuxShimBuilder<Platform>`, `LinuxShim<Platform, FS>`,
`GlobalState`, `Task`, `LoadedProgram`, and every subsystem type (epoll, unix
sockets, eventfd, channels, signals, process/thread state, transport, ELF loader).
`LinuxShimBuilder::new(platform)` now takes a `&'static Platform`; the global
accessor is gone.
- Add a sealed `ShimPlatform` aggregate bound (with blanket impl) so impls read
`impl<Platform: ShimPlatform, FS: ShimFS>`. It also pins the associated types
the shim relies on: ThreadProvider::ExecutionContext = PtRegs, Timer/Signal
Provider::Signal = common Signal, and VmemPageFaultHandler.
- Remove the litebox_platform_multiplex dependency and platform_* features from
litebox_shim_linux. Tests pick a concrete platform by build target via a
`TestPlatform` alias (LinuxUserland / WindowsUserland) with target-scoped
dev-deps.
- Update the runners to depend on their concrete platform crate and instantiate
`LinuxShimBuilder::new(platform_ref)`: linux_userland (LinuxUserland),
linux_on_windows_userland (WindowsUserland), snp (SnpLinuxKernel). The SNP
page-fault handler reaches the platform through a new `LinuxShim::platform()`
accessor instead of a global.
- Update README to describe the threaded-platform model.
@jstarks
John Starks (jstarks) marked this pull request as ready for review July 21, 2026 08:26

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall LGTM, I've made a few minor notes of nits, I've also updated the PR description to reduce some of the verbosity.

Comment threadlitebox_runner_snp/src/main.rs
Comment threadlitebox_shim_linux/src/lib.rs
Comment threadlitebox_shim_linux/README.md
@jaybosamiya-ms

Copy link
Copy Markdown
Member

Also, since semver-checks CI bot does not fire on branches from forks, here's its output as of 04dc576 (basically expected tweaks):

click to unfold
--- failure feature_missing: package feature removed or renamed ---
Description:
A feature has been removed from this package's Cargo.toml. This will break downstream crates which enable that feature.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#cargo-feature-remove
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.49.0/src/lints/feature_missing.ron
Failed in:
feature platform_linux_userland in the package's Cargo.toml
feature platform_windows_userland in the package's Cargo.toml
feature platform_linux_snp in the package's Cargo.toml
--- failure method_parameter_count_changed: pub method parameter count changed ---
Description:
A publicly-visible method now takes a different number of parameters, not counting the receiver (self) parameter.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#fn-change-arity
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.49.0/src/lints/method_parameter_count_changed.ron
Failed in:
litebox_shim_linux::LinuxShimBuilder::new takes 0 parameters in /home/runner/work/litebox/litebox/target/semver-checks/git-main/30e3a38e80ded90e8ea438866862948a82cadd79/litebox_shim_linux/src/lib.rs:170, but now takes 1 parameters in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:208
--- failure trait_requires_more_generic_type_params: trait now requires more generic type parameters ---
Description:
A trait now requires more generic type parameters than it used to. Uses of this trait that supplied the previously-required number of generic types will be broken. To fix this, consider supplying default values for newly-added generic types.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#trait-new-parameter-no-default
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.49.0/src/lints/trait_requires_more_generic_type_params.ron
Failed in:
trait LinuxShim (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:249
trait LinuxShimEntrypoints (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:134
trait ShimTransport (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/transport.rs:51
trait LoadedProgram (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:356
trait LinuxShimProcess (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:364
trait LinuxShimBuilder (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:201
--- failure type_requires_more_generic_type_params: type now requires more generic type parameters ---
Description:
A type now requires more generic type parameters than it used to. Uses of this type that supplied the previously-required number of generic types will be broken. To fix this, consider supplying default values for newly-added generic types.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#trait-new-parameter-no-default
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.49.0/src/lints/type_requires_more_generic_type_params.ron
Failed in:
Struct LinuxShim (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:249
Struct LinuxShimEntrypoints (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:134
Struct ShimTransport (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/transport.rs:51
Struct LoadedProgram (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:356
Struct LinuxShimProcess (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:364
Struct LinuxShimBuilder (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:201

Merged via the queue into microsoft:main with commit 864239bJul 21, 2026
9 checks passed
pullBot pushed a commit to Mu-L/litebox that referenced this pull request Jul 22, 2026
Makes SNP shim initialization safer via `OnceBox`, and cleans up some
documentation.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 28, 2026
…#1056
`set_platform` was a private one-liner with a single caller, wrapping one
`OnceRef::set`. It mirrored the shape of `litebox_platform_multiplex`, which
needed a setter because it was a separate crate exporting one to foreign
callers. Inside a single module with one call site it is ceremony, and it made
the design read as more global-oriented than it is. `init` now sets the cell
directly and `platform()` is the sole named accessor.
The `PLATFORM` cell itself stays and cannot reasonably go: `Platform::new` runs
only on the BSP and leaks its result, and the AP bring-up trampoline is naked
assembly whose only payload is the `is_bsp` flag in `edi`, so an AP has no
channel to receive the pointer. The doc comment now states that rather than
gesturing at it.
Two artifacts found by comparing against how PR #1056 handled the same job for
litebox_shim_linux:
- The shim's test helper still branched on `cfg(not(target_os = "linux"))` to
call a different `Platform::new`. `Platform` is now hardcoded to
`LinuxUserland`, so that arm was unreachable and would not have compiled.
- The CI `no_std` allow-list rationale for `litebox_shim_optee` claimed it
"depends on `litebox_platform_multiplex`", which is no longer true. #1056
deleted the equivalent entry for litebox_shim_linux outright. That is not
possible here: building litebox_shim_optee for `x86_64-unknown-none` still
fails, but in `sha2`, for the same soft-float/asm reason
`litebox_service_heki` is excluded. The entry stays; the comment now says why.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 28, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Also corrects two stale CI artifacts: the `no_std` rationale for
`litebox_shim_optee` claimed a multiplex dependency, when it is excluded because
its crypto dependencies fail to build for `x86_64-unknown-none`, as with
`litebox_service_heki`.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 28, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
The shim was bound to `litebox_platform_multiplex::Platform`, so platform
selection happened via cargo features and every platform access went through a
panicking global. It is now parameterized end-to-end, mirroring what PR #1056 did
for litebox_shim_linux.
`OpteeShimPlatform` collects the required capabilities. It includes
`VmapManager<PAGE_SIZE>`, which is what the previous two commits bought: the
shim's need to read and write normal-world physical memory is now a trait bound
rather than a consequence of which platform the build happened to select.
Both runners drop the `litebox_platform_multiplex` dependency and name their
platform directly. Neither gains anything it did not already have:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is exactly what the
multiplex `platform_linux_userland_with_optee_syscall` feature was enabling.
The session registry moved from the shim to each runner. This is not cosmetic: a
`static` cannot name a generic parameter, and a shim instance is built per
session, so the shim has nowhere to put it. The composition root names a concrete
platform, so it can hold the `static` and hand out
`&'static SessionManager<ConcretePlatform>`. `GlobalState` now carries that
reference, which is how `current_client_identity` reaches it.
Honest accounting of the global ratchet: this relocates globals more than it
removes them. litebox_shim_optee stays at 5 (it loses the session registry but
its tests gain a platform and a registry, and `INIT_FUNC` goes away).
litebox_runner_lvbs goes 6 -> 8: the platform handle and the session registry.
litebox_runner_optee_on_linux_userland gets a new entry of 1 for its registry.
The platform and shim crates no longer reach for ambient state; the composition
roots do, which is where that belongs.
`litebox_platform_multiplex` now has zero workspace consumers. It is left in the
tree pending a separate decision.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
The shim was bound to `litebox_platform_multiplex::Platform`, so platform
selection happened via cargo features and every platform access went through a
panicking global. It is now parameterized end-to-end, mirroring what PR #1056 did
for litebox_shim_linux.
`OpteeShimPlatform` collects the required capabilities. It includes
`VmapManager<PAGE_SIZE>`, which is what the previous two commits bought: the
shim's need to read and write normal-world physical memory is now a trait bound
rather than a consequence of which platform the build happened to select.
Both runners drop the `litebox_platform_multiplex` dependency and name their
platform directly. Neither gains anything it did not already have:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is exactly what the
multiplex `platform_linux_userland_with_optee_syscall` feature was enabling.
The session registry moved from the shim to each runner. This is not cosmetic: a
`static` cannot name a generic parameter, and a shim instance is built per
session, so the shim has nowhere to put it. The composition root names a concrete
platform, so it can hold the `static` and hand out
`&'static SessionManager<ConcretePlatform>`. `GlobalState` now carries that
reference, which is how `current_client_identity` reaches it.
Honest accounting of the global ratchet: this relocates globals more than it
removes them. litebox_shim_optee stays at 5 (it loses the session registry but
its tests gain a platform and a registry, and `INIT_FUNC` goes away).
litebox_runner_lvbs goes 6 -> 8: the platform handle and the session registry.
litebox_runner_optee_on_linux_userland gets a new entry of 1 for its registry.
The platform and shim crates no longer reach for ambient state; the composition
roots do, which is where that belongs.
`litebox_platform_multiplex` now has zero workspace consumers. It is left in the
tree pending a separate decision.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@jstarks@jaybosamiya-ms
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Make litebox_shim_linux generic over its platform - #1056

Merged
Jay Bosamiya (Microsoft) (jaybosamiya-ms) merged 3 commits into
microsoft:mainfrom
jstarks:generic2
Jul 21, 2026
Merged

Make litebox_shim_linux generic over its platform#1056
Jay Bosamiya (Microsoft) (jaybosamiya-ms) merged 3 commits into
microsoft:mainfrom
jstarks:generic2

Conversation

@jstarks

@jstarksJohn Starks (jstarks) commented Jul 21, 2026

Copy link
Copy Markdown
Member

The Linux shim was hard-wired to the global litebox_platform_multiplex::Platform singleton (set via set_platform, fetched via platform()). This made the shim non-generic and forced platform selection through cargo features. This PR parameterizes the shim over a platform type Platform end-to-end.

…iplex
The Linux shim was hard-wired to the global `litebox_platform_multiplex::Platform`
singleton (set via `set_platform`, fetched via `platform()`). This made the shim
non-generic and forced platform selection through cargo features.
Parameterize the shim over a platform type `Platform` end-to-end (alongside the
existing `FS`): `LinuxShimBuilder<Platform>`, `LinuxShim<Platform, FS>`,
`GlobalState`, `Task`, `LoadedProgram`, and every subsystem type (epoll, unix
sockets, eventfd, channels, signals, process/thread state, transport, ELF loader).
`LinuxShimBuilder::new(platform)` now takes a `&'static Platform`; the global
accessor is gone.
- Add a sealed `ShimPlatform` aggregate bound (with blanket impl) so impls read
`impl<Platform: ShimPlatform, FS: ShimFS>`. It also pins the associated types
the shim relies on: ThreadProvider::ExecutionContext = PtRegs, Timer/Signal
Provider::Signal = common Signal, and VmemPageFaultHandler.
- Remove the litebox_platform_multiplex dependency and platform_* features from
litebox_shim_linux. Tests pick a concrete platform by build target via a
`TestPlatform` alias (LinuxUserland / WindowsUserland) with target-scoped
dev-deps.
- Update the runners to depend on their concrete platform crate and instantiate
`LinuxShimBuilder::new(platform_ref)`: linux_userland (LinuxUserland),
linux_on_windows_userland (WindowsUserland), snp (SnpLinuxKernel). The SNP
page-fault handler reaches the platform through a new `LinuxShim::platform()`
accessor instead of a global.
- Update README to describe the threaded-platform model.
@jstarks
John Starks (jstarks) marked this pull request as ready for review July 21, 2026 08:26

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall LGTM, I've made a few minor notes of nits, I've also updated the PR description to reduce some of the verbosity.

Comment threadlitebox_runner_snp/src/main.rs
Comment threadlitebox_shim_linux/src/lib.rs
Comment threadlitebox_shim_linux/README.md
@jaybosamiya-ms

Copy link
Copy Markdown
Member

Also, since semver-checks CI bot does not fire on branches from forks, here's its output as of 04dc576 (basically expected tweaks):

click to unfold
--- failure feature_missing: package feature removed or renamed ---
Description:
A feature has been removed from this package's Cargo.toml. This will break downstream crates which enable that feature.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#cargo-feature-remove
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.49.0/src/lints/feature_missing.ron
Failed in:
feature platform_linux_userland in the package's Cargo.toml
feature platform_windows_userland in the package's Cargo.toml
feature platform_linux_snp in the package's Cargo.toml
--- failure method_parameter_count_changed: pub method parameter count changed ---
Description:
A publicly-visible method now takes a different number of parameters, not counting the receiver (self) parameter.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#fn-change-arity
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.49.0/src/lints/method_parameter_count_changed.ron
Failed in:
litebox_shim_linux::LinuxShimBuilder::new takes 0 parameters in /home/runner/work/litebox/litebox/target/semver-checks/git-main/30e3a38e80ded90e8ea438866862948a82cadd79/litebox_shim_linux/src/lib.rs:170, but now takes 1 parameters in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:208
--- failure trait_requires_more_generic_type_params: trait now requires more generic type parameters ---
Description:
A trait now requires more generic type parameters than it used to. Uses of this trait that supplied the previously-required number of generic types will be broken. To fix this, consider supplying default values for newly-added generic types.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#trait-new-parameter-no-default
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.49.0/src/lints/trait_requires_more_generic_type_params.ron
Failed in:
trait LinuxShim (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:249
trait LinuxShimEntrypoints (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:134
trait ShimTransport (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/transport.rs:51
trait LoadedProgram (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:356
trait LinuxShimProcess (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:364
trait LinuxShimBuilder (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:201
--- failure type_requires_more_generic_type_params: type now requires more generic type parameters ---
Description:
A type now requires more generic type parameters than it used to. Uses of this type that supplied the previously-required number of generic types will be broken. To fix this, consider supplying default values for newly-added generic types.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#trait-new-parameter-no-default
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.49.0/src/lints/type_requires_more_generic_type_params.ron
Failed in:
Struct LinuxShim (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:249
Struct LinuxShimEntrypoints (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:134
Struct ShimTransport (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/transport.rs:51
Struct LoadedProgram (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:356
Struct LinuxShimProcess (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:364
Struct LinuxShimBuilder (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:201

Merged via the queue into microsoft:main with commit 864239bJul 21, 2026
9 checks passed
pullBot pushed a commit to Mu-L/litebox that referenced this pull request Jul 22, 2026
Makes SNP shim initialization safer via `OnceBox`, and cleans up some
documentation.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 28, 2026
…#1056
`set_platform` was a private one-liner with a single caller, wrapping one
`OnceRef::set`. It mirrored the shape of `litebox_platform_multiplex`, which
needed a setter because it was a separate crate exporting one to foreign
callers. Inside a single module with one call site it is ceremony, and it made
the design read as more global-oriented than it is. `init` now sets the cell
directly and `platform()` is the sole named accessor.
The `PLATFORM` cell itself stays and cannot reasonably go: `Platform::new` runs
only on the BSP and leaks its result, and the AP bring-up trampoline is naked
assembly whose only payload is the `is_bsp` flag in `edi`, so an AP has no
channel to receive the pointer. The doc comment now states that rather than
gesturing at it.
Two artifacts found by comparing against how PR #1056 handled the same job for
litebox_shim_linux:
- The shim's test helper still branched on `cfg(not(target_os = "linux"))` to
call a different `Platform::new`. `Platform` is now hardcoded to
`LinuxUserland`, so that arm was unreachable and would not have compiled.
- The CI `no_std` allow-list rationale for `litebox_shim_optee` claimed it
"depends on `litebox_platform_multiplex`", which is no longer true. #1056
deleted the equivalent entry for litebox_shim_linux outright. That is not
possible here: building litebox_shim_optee for `x86_64-unknown-none` still
fails, but in `sha2`, for the same soft-float/asm reason
`litebox_service_heki` is excluded. The entry stays; the comment now says why.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 28, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Also corrects two stale CI artifacts: the `no_std` rationale for
`litebox_shim_optee` claimed a multiplex dependency, when it is excluded because
its crypto dependencies fail to build for `x86_64-unknown-none`, as with
`litebox_service_heki`.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 28, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
The shim was bound to `litebox_platform_multiplex::Platform`, so platform
selection happened via cargo features and every platform access went through a
panicking global. It is now parameterized end-to-end, mirroring what PR #1056 did
for litebox_shim_linux.
`OpteeShimPlatform` collects the required capabilities. It includes
`VmapManager<PAGE_SIZE>`, which is what the previous two commits bought: the
shim's need to read and write normal-world physical memory is now a trait bound
rather than a consequence of which platform the build happened to select.
Both runners drop the `litebox_platform_multiplex` dependency and name their
platform directly. Neither gains anything it did not already have:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is exactly what the
multiplex `platform_linux_userland_with_optee_syscall` feature was enabling.
The session registry moved from the shim to each runner. This is not cosmetic: a
`static` cannot name a generic parameter, and a shim instance is built per
session, so the shim has nowhere to put it. The composition root names a concrete
platform, so it can hold the `static` and hand out
`&'static SessionManager<ConcretePlatform>`. `GlobalState` now carries that
reference, which is how `current_client_identity` reaches it.
Honest accounting of the global ratchet: this relocates globals more than it
removes them. litebox_shim_optee stays at 5 (it loses the session registry but
its tests gain a platform and a registry, and `INIT_FUNC` goes away).
litebox_runner_lvbs goes 6 -> 8: the platform handle and the session registry.
litebox_runner_optee_on_linux_userland gets a new entry of 1 for its registry.
The platform and shim crates no longer reach for ambient state; the composition
roots do, which is where that belongs.
`litebox_platform_multiplex` now has zero workspace consumers. It is left in the
tree pending a separate decision.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
The shim was bound to `litebox_platform_multiplex::Platform`, so platform
selection happened via cargo features and every platform access went through a
panicking global. It is now parameterized end-to-end, mirroring what PR #1056 did
for litebox_shim_linux.
`OpteeShimPlatform` collects the required capabilities. It includes
`VmapManager<PAGE_SIZE>`, which is what the previous two commits bought: the
shim's need to read and write normal-world physical memory is now a trait bound
rather than a consequence of which platform the build happened to select.
Both runners drop the `litebox_platform_multiplex` dependency and name their
platform directly. Neither gains anything it did not already have:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is exactly what the
multiplex `platform_linux_userland_with_optee_syscall` feature was enabling.
The session registry moved from the shim to each runner. This is not cosmetic: a
`static` cannot name a generic parameter, and a shim instance is built per
session, so the shim has nowhere to put it. The composition root names a concrete
platform, so it can hold the `static` and hand out
`&'static SessionManager<ConcretePlatform>`. `GlobalState` now carries that
reference, which is how `current_client_identity` reaches it.
Honest accounting of the global ratchet: this relocates globals more than it
removes them. litebox_shim_optee stays at 5 (it loses the session registry but
its tests gain a platform and a registry, and `INIT_FUNC` goes away).
litebox_runner_lvbs goes 6 -> 8: the platform handle and the session registry.
litebox_runner_optee_on_linux_userland gets a new entry of 1 for its registry.
The platform and shim crates no longer reach for ambient state; the composition
roots do, which is where that belongs.
`litebox_platform_multiplex` now has zero workspace consumers. It is left in the
tree pending a separate decision.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@jstarks@jaybosamiya-ms
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Make litebox_shim_linux generic over its platform - #1056

Merged
Jay Bosamiya (Microsoft) (jaybosamiya-ms) merged 3 commits into
microsoft:mainfrom
jstarks:generic2
Jul 21, 2026
Merged

Make litebox_shim_linux generic over its platform#1056
Jay Bosamiya (Microsoft) (jaybosamiya-ms) merged 3 commits into
microsoft:mainfrom
jstarks:generic2

Conversation

@jstarks

@jstarksJohn Starks (jstarks) commented Jul 21, 2026

Copy link
Copy Markdown
Member

The Linux shim was hard-wired to the global litebox_platform_multiplex::Platform singleton (set via set_platform, fetched via platform()). This made the shim non-generic and forced platform selection through cargo features. This PR parameterizes the shim over a platform type Platform end-to-end.

…iplex
The Linux shim was hard-wired to the global `litebox_platform_multiplex::Platform`
singleton (set via `set_platform`, fetched via `platform()`). This made the shim
non-generic and forced platform selection through cargo features.
Parameterize the shim over a platform type `Platform` end-to-end (alongside the
existing `FS`): `LinuxShimBuilder<Platform>`, `LinuxShim<Platform, FS>`,
`GlobalState`, `Task`, `LoadedProgram`, and every subsystem type (epoll, unix
sockets, eventfd, channels, signals, process/thread state, transport, ELF loader).
`LinuxShimBuilder::new(platform)` now takes a `&'static Platform`; the global
accessor is gone.
- Add a sealed `ShimPlatform` aggregate bound (with blanket impl) so impls read
`impl<Platform: ShimPlatform, FS: ShimFS>`. It also pins the associated types
the shim relies on: ThreadProvider::ExecutionContext = PtRegs, Timer/Signal
Provider::Signal = common Signal, and VmemPageFaultHandler.
- Remove the litebox_platform_multiplex dependency and platform_* features from
litebox_shim_linux. Tests pick a concrete platform by build target via a
`TestPlatform` alias (LinuxUserland / WindowsUserland) with target-scoped
dev-deps.
- Update the runners to depend on their concrete platform crate and instantiate
`LinuxShimBuilder::new(platform_ref)`: linux_userland (LinuxUserland),
linux_on_windows_userland (WindowsUserland), snp (SnpLinuxKernel). The SNP
page-fault handler reaches the platform through a new `LinuxShim::platform()`
accessor instead of a global.
- Update README to describe the threaded-platform model.
@jstarks
John Starks (jstarks) marked this pull request as ready for review July 21, 2026 08:26

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall LGTM, I've made a few minor notes of nits, I've also updated the PR description to reduce some of the verbosity.

Comment threadlitebox_runner_snp/src/main.rs
Comment threadlitebox_shim_linux/src/lib.rs
Comment threadlitebox_shim_linux/README.md
@jaybosamiya-ms

Copy link
Copy Markdown
Member

Also, since semver-checks CI bot does not fire on branches from forks, here's its output as of 04dc576 (basically expected tweaks):

click to unfold
--- failure feature_missing: package feature removed or renamed ---
Description:
A feature has been removed from this package's Cargo.toml. This will break downstream crates which enable that feature.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#cargo-feature-remove
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.49.0/src/lints/feature_missing.ron
Failed in:
feature platform_linux_userland in the package's Cargo.toml
feature platform_windows_userland in the package's Cargo.toml
feature platform_linux_snp in the package's Cargo.toml
--- failure method_parameter_count_changed: pub method parameter count changed ---
Description:
A publicly-visible method now takes a different number of parameters, not counting the receiver (self) parameter.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#fn-change-arity
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.49.0/src/lints/method_parameter_count_changed.ron
Failed in:
litebox_shim_linux::LinuxShimBuilder::new takes 0 parameters in /home/runner/work/litebox/litebox/target/semver-checks/git-main/30e3a38e80ded90e8ea438866862948a82cadd79/litebox_shim_linux/src/lib.rs:170, but now takes 1 parameters in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:208
--- failure trait_requires_more_generic_type_params: trait now requires more generic type parameters ---
Description:
A trait now requires more generic type parameters than it used to. Uses of this trait that supplied the previously-required number of generic types will be broken. To fix this, consider supplying default values for newly-added generic types.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#trait-new-parameter-no-default
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.49.0/src/lints/trait_requires_more_generic_type_params.ron
Failed in:
trait LinuxShim (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:249
trait LinuxShimEntrypoints (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:134
trait ShimTransport (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/transport.rs:51
trait LoadedProgram (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:356
trait LinuxShimProcess (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:364
trait LinuxShimBuilder (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:201
--- failure type_requires_more_generic_type_params: type now requires more generic type parameters ---
Description:
A type now requires more generic type parameters than it used to. Uses of this type that supplied the previously-required number of generic types will be broken. To fix this, consider supplying default values for newly-added generic types.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#trait-new-parameter-no-default
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.49.0/src/lints/type_requires_more_generic_type_params.ron
Failed in:
Struct LinuxShim (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:249
Struct LinuxShimEntrypoints (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:134
Struct ShimTransport (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/transport.rs:51
Struct LoadedProgram (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:356
Struct LinuxShimProcess (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:364
Struct LinuxShimBuilder (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:201

Merged via the queue into microsoft:main with commit 864239bJul 21, 2026
9 checks passed
pullBot pushed a commit to Mu-L/litebox that referenced this pull request Jul 22, 2026
Makes SNP shim initialization safer via `OnceBox`, and cleans up some
documentation.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 28, 2026
…#1056
`set_platform` was a private one-liner with a single caller, wrapping one
`OnceRef::set`. It mirrored the shape of `litebox_platform_multiplex`, which
needed a setter because it was a separate crate exporting one to foreign
callers. Inside a single module with one call site it is ceremony, and it made
the design read as more global-oriented than it is. `init` now sets the cell
directly and `platform()` is the sole named accessor.
The `PLATFORM` cell itself stays and cannot reasonably go: `Platform::new` runs
only on the BSP and leaks its result, and the AP bring-up trampoline is naked
assembly whose only payload is the `is_bsp` flag in `edi`, so an AP has no
channel to receive the pointer. The doc comment now states that rather than
gesturing at it.
Two artifacts found by comparing against how PR #1056 handled the same job for
litebox_shim_linux:
- The shim's test helper still branched on `cfg(not(target_os = "linux"))` to
call a different `Platform::new`. `Platform` is now hardcoded to
`LinuxUserland`, so that arm was unreachable and would not have compiled.
- The CI `no_std` allow-list rationale for `litebox_shim_optee` claimed it
"depends on `litebox_platform_multiplex`", which is no longer true. #1056
deleted the equivalent entry for litebox_shim_linux outright. That is not
possible here: building litebox_shim_optee for `x86_64-unknown-none` still
fails, but in `sha2`, for the same soft-float/asm reason
`litebox_service_heki` is excluded. The entry stays; the comment now says why.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 28, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Also corrects two stale CI artifacts: the `no_std` rationale for
`litebox_shim_optee` claimed a multiplex dependency, when it is excluded because
its crypto dependencies fail to build for `x86_64-unknown-none`, as with
`litebox_service_heki`.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 28, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
The shim was bound to `litebox_platform_multiplex::Platform`, so platform
selection happened via cargo features and every platform access went through a
panicking global. It is now parameterized end-to-end, mirroring what PR #1056 did
for litebox_shim_linux.
`OpteeShimPlatform` collects the required capabilities. It includes
`VmapManager<PAGE_SIZE>`, which is what the previous two commits bought: the
shim's need to read and write normal-world physical memory is now a trait bound
rather than a consequence of which platform the build happened to select.
Both runners drop the `litebox_platform_multiplex` dependency and name their
platform directly. Neither gains anything it did not already have:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is exactly what the
multiplex `platform_linux_userland_with_optee_syscall` feature was enabling.
The session registry moved from the shim to each runner. This is not cosmetic: a
`static` cannot name a generic parameter, and a shim instance is built per
session, so the shim has nowhere to put it. The composition root names a concrete
platform, so it can hold the `static` and hand out
`&'static SessionManager<ConcretePlatform>`. `GlobalState` now carries that
reference, which is how `current_client_identity` reaches it.
Honest accounting of the global ratchet: this relocates globals more than it
removes them. litebox_shim_optee stays at 5 (it loses the session registry but
its tests gain a platform and a registry, and `INIT_FUNC` goes away).
litebox_runner_lvbs goes 6 -> 8: the platform handle and the session registry.
litebox_runner_optee_on_linux_userland gets a new entry of 1 for its registry.
The platform and shim crates no longer reach for ambient state; the composition
roots do, which is where that belongs.
`litebox_platform_multiplex` now has zero workspace consumers. It is left in the
tree pending a separate decision.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
The shim was bound to `litebox_platform_multiplex::Platform`, so platform
selection happened via cargo features and every platform access went through a
panicking global. It is now parameterized end-to-end, mirroring what PR #1056 did
for litebox_shim_linux.
`OpteeShimPlatform` collects the required capabilities. It includes
`VmapManager<PAGE_SIZE>`, which is what the previous two commits bought: the
shim's need to read and write normal-world physical memory is now a trait bound
rather than a consequence of which platform the build happened to select.
Both runners drop the `litebox_platform_multiplex` dependency and name their
platform directly. Neither gains anything it did not already have:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is exactly what the
multiplex `platform_linux_userland_with_optee_syscall` feature was enabling.
The session registry moved from the shim to each runner. This is not cosmetic: a
`static` cannot name a generic parameter, and a shim instance is built per
session, so the shim has nowhere to put it. The composition root names a concrete
platform, so it can hold the `static` and hand out
`&'static SessionManager<ConcretePlatform>`. `GlobalState` now carries that
reference, which is how `current_client_identity` reaches it.
Honest accounting of the global ratchet: this relocates globals more than it
removes them. litebox_shim_optee stays at 5 (it loses the session registry but
its tests gain a platform and a registry, and `INIT_FUNC` goes away).
litebox_runner_lvbs goes 6 -> 8: the platform handle and the session registry.
litebox_runner_optee_on_linux_userland gets a new entry of 1 for its registry.
The platform and shim crates no longer reach for ambient state; the composition
roots do, which is where that belongs.
`litebox_platform_multiplex` now has zero workspace consumers. It is left in the
tree pending a separate decision.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@jstarks@jaybosamiya-ms
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Make litebox_shim_linux generic over its platform - #1056

Merged
Jay Bosamiya (Microsoft) (jaybosamiya-ms) merged 3 commits into
microsoft:mainfrom
jstarks:generic2
Jul 21, 2026
Merged

Make litebox_shim_linux generic over its platform#1056
Jay Bosamiya (Microsoft) (jaybosamiya-ms) merged 3 commits into
microsoft:mainfrom
jstarks:generic2

Conversation

@jstarks

@jstarksJohn Starks (jstarks) commented Jul 21, 2026

Copy link
Copy Markdown
Member

The Linux shim was hard-wired to the global litebox_platform_multiplex::Platform singleton (set via set_platform, fetched via platform()). This made the shim non-generic and forced platform selection through cargo features. This PR parameterizes the shim over a platform type Platform end-to-end.

…iplex
The Linux shim was hard-wired to the global `litebox_platform_multiplex::Platform`
singleton (set via `set_platform`, fetched via `platform()`). This made the shim
non-generic and forced platform selection through cargo features.
Parameterize the shim over a platform type `Platform` end-to-end (alongside the
existing `FS`): `LinuxShimBuilder<Platform>`, `LinuxShim<Platform, FS>`,
`GlobalState`, `Task`, `LoadedProgram`, and every subsystem type (epoll, unix
sockets, eventfd, channels, signals, process/thread state, transport, ELF loader).
`LinuxShimBuilder::new(platform)` now takes a `&'static Platform`; the global
accessor is gone.
- Add a sealed `ShimPlatform` aggregate bound (with blanket impl) so impls read
`impl<Platform: ShimPlatform, FS: ShimFS>`. It also pins the associated types
the shim relies on: ThreadProvider::ExecutionContext = PtRegs, Timer/Signal
Provider::Signal = common Signal, and VmemPageFaultHandler.
- Remove the litebox_platform_multiplex dependency and platform_* features from
litebox_shim_linux. Tests pick a concrete platform by build target via a
`TestPlatform` alias (LinuxUserland / WindowsUserland) with target-scoped
dev-deps.
- Update the runners to depend on their concrete platform crate and instantiate
`LinuxShimBuilder::new(platform_ref)`: linux_userland (LinuxUserland),
linux_on_windows_userland (WindowsUserland), snp (SnpLinuxKernel). The SNP
page-fault handler reaches the platform through a new `LinuxShim::platform()`
accessor instead of a global.
- Update README to describe the threaded-platform model.
@jstarks
John Starks (jstarks) marked this pull request as ready for review July 21, 2026 08:26

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall LGTM, I've made a few minor notes of nits, I've also updated the PR description to reduce some of the verbosity.

Comment threadlitebox_runner_snp/src/main.rs
Comment threadlitebox_shim_linux/src/lib.rs
Comment threadlitebox_shim_linux/README.md
@jaybosamiya-ms

Copy link
Copy Markdown
Member

Also, since semver-checks CI bot does not fire on branches from forks, here's its output as of 04dc576 (basically expected tweaks):

click to unfold
--- failure feature_missing: package feature removed or renamed ---
Description:
A feature has been removed from this package's Cargo.toml. This will break downstream crates which enable that feature.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#cargo-feature-remove
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.49.0/src/lints/feature_missing.ron
Failed in:
feature platform_linux_userland in the package's Cargo.toml
feature platform_windows_userland in the package's Cargo.toml
feature platform_linux_snp in the package's Cargo.toml
--- failure method_parameter_count_changed: pub method parameter count changed ---
Description:
A publicly-visible method now takes a different number of parameters, not counting the receiver (self) parameter.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#fn-change-arity
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.49.0/src/lints/method_parameter_count_changed.ron
Failed in:
litebox_shim_linux::LinuxShimBuilder::new takes 0 parameters in /home/runner/work/litebox/litebox/target/semver-checks/git-main/30e3a38e80ded90e8ea438866862948a82cadd79/litebox_shim_linux/src/lib.rs:170, but now takes 1 parameters in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:208
--- failure trait_requires_more_generic_type_params: trait now requires more generic type parameters ---
Description:
A trait now requires more generic type parameters than it used to. Uses of this trait that supplied the previously-required number of generic types will be broken. To fix this, consider supplying default values for newly-added generic types.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#trait-new-parameter-no-default
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.49.0/src/lints/trait_requires_more_generic_type_params.ron
Failed in:
trait LinuxShim (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:249
trait LinuxShimEntrypoints (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:134
trait ShimTransport (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/transport.rs:51
trait LoadedProgram (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:356
trait LinuxShimProcess (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:364
trait LinuxShimBuilder (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:201
--- failure type_requires_more_generic_type_params: type now requires more generic type parameters ---
Description:
A type now requires more generic type parameters than it used to. Uses of this type that supplied the previously-required number of generic types will be broken. To fix this, consider supplying default values for newly-added generic types.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#trait-new-parameter-no-default
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.49.0/src/lints/type_requires_more_generic_type_params.ron
Failed in:
Struct LinuxShim (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:249
Struct LinuxShimEntrypoints (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:134
Struct ShimTransport (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/transport.rs:51
Struct LoadedProgram (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:356
Struct LinuxShimProcess (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:364
Struct LinuxShimBuilder (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:201

Merged via the queue into microsoft:main with commit 864239bJul 21, 2026
9 checks passed
pullBot pushed a commit to Mu-L/litebox that referenced this pull request Jul 22, 2026
Makes SNP shim initialization safer via `OnceBox`, and cleans up some
documentation.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 28, 2026
…#1056
`set_platform` was a private one-liner with a single caller, wrapping one
`OnceRef::set`. It mirrored the shape of `litebox_platform_multiplex`, which
needed a setter because it was a separate crate exporting one to foreign
callers. Inside a single module with one call site it is ceremony, and it made
the design read as more global-oriented than it is. `init` now sets the cell
directly and `platform()` is the sole named accessor.
The `PLATFORM` cell itself stays and cannot reasonably go: `Platform::new` runs
only on the BSP and leaks its result, and the AP bring-up trampoline is naked
assembly whose only payload is the `is_bsp` flag in `edi`, so an AP has no
channel to receive the pointer. The doc comment now states that rather than
gesturing at it.
Two artifacts found by comparing against how PR #1056 handled the same job for
litebox_shim_linux:
- The shim's test helper still branched on `cfg(not(target_os = "linux"))` to
call a different `Platform::new`. `Platform` is now hardcoded to
`LinuxUserland`, so that arm was unreachable and would not have compiled.
- The CI `no_std` allow-list rationale for `litebox_shim_optee` claimed it
"depends on `litebox_platform_multiplex`", which is no longer true. #1056
deleted the equivalent entry for litebox_shim_linux outright. That is not
possible here: building litebox_shim_optee for `x86_64-unknown-none` still
fails, but in `sha2`, for the same soft-float/asm reason
`litebox_service_heki` is excluded. The entry stays; the comment now says why.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 28, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Also corrects two stale CI artifacts: the `no_std` rationale for
`litebox_shim_optee` claimed a multiplex dependency, when it is excluded because
its crypto dependencies fail to build for `x86_64-unknown-none`, as with
`litebox_service_heki`.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 28, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
The shim was bound to `litebox_platform_multiplex::Platform`, so platform
selection happened via cargo features and every platform access went through a
panicking global. It is now parameterized end-to-end, mirroring what PR #1056 did
for litebox_shim_linux.
`OpteeShimPlatform` collects the required capabilities. It includes
`VmapManager<PAGE_SIZE>`, which is what the previous two commits bought: the
shim's need to read and write normal-world physical memory is now a trait bound
rather than a consequence of which platform the build happened to select.
Both runners drop the `litebox_platform_multiplex` dependency and name their
platform directly. Neither gains anything it did not already have:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is exactly what the
multiplex `platform_linux_userland_with_optee_syscall` feature was enabling.
The session registry moved from the shim to each runner. This is not cosmetic: a
`static` cannot name a generic parameter, and a shim instance is built per
session, so the shim has nowhere to put it. The composition root names a concrete
platform, so it can hold the `static` and hand out
`&'static SessionManager<ConcretePlatform>`. `GlobalState` now carries that
reference, which is how `current_client_identity` reaches it.
Honest accounting of the global ratchet: this relocates globals more than it
removes them. litebox_shim_optee stays at 5 (it loses the session registry but
its tests gain a platform and a registry, and `INIT_FUNC` goes away).
litebox_runner_lvbs goes 6 -> 8: the platform handle and the session registry.
litebox_runner_optee_on_linux_userland gets a new entry of 1 for its registry.
The platform and shim crates no longer reach for ambient state; the composition
roots do, which is where that belongs.
`litebox_platform_multiplex` now has zero workspace consumers. It is left in the
tree pending a separate decision.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
The shim was bound to `litebox_platform_multiplex::Platform`, so platform
selection happened via cargo features and every platform access went through a
panicking global. It is now parameterized end-to-end, mirroring what PR #1056 did
for litebox_shim_linux.
`OpteeShimPlatform` collects the required capabilities. It includes
`VmapManager<PAGE_SIZE>`, which is what the previous two commits bought: the
shim's need to read and write normal-world physical memory is now a trait bound
rather than a consequence of which platform the build happened to select.
Both runners drop the `litebox_platform_multiplex` dependency and name their
platform directly. Neither gains anything it did not already have:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is exactly what the
multiplex `platform_linux_userland_with_optee_syscall` feature was enabling.
The session registry moved from the shim to each runner. This is not cosmetic: a
`static` cannot name a generic parameter, and a shim instance is built per
session, so the shim has nowhere to put it. The composition root names a concrete
platform, so it can hold the `static` and hand out
`&'static SessionManager<ConcretePlatform>`. `GlobalState` now carries that
reference, which is how `current_client_identity` reaches it.
Honest accounting of the global ratchet: this relocates globals more than it
removes them. litebox_shim_optee stays at 5 (it loses the session registry but
its tests gain a platform and a registry, and `INIT_FUNC` goes away).
litebox_runner_lvbs goes 6 -> 8: the platform handle and the session registry.
litebox_runner_optee_on_linux_userland gets a new entry of 1 for its registry.
The platform and shim crates no longer reach for ambient state; the composition
roots do, which is where that belongs.
`litebox_platform_multiplex` now has zero workspace consumers. It is left in the
tree pending a separate decision.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@jstarks@jaybosamiya-ms
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Make litebox_shim_linux generic over its platform - #1056

Merged
Jay Bosamiya (Microsoft) (jaybosamiya-ms) merged 3 commits into
microsoft:mainfrom
jstarks:generic2
Jul 21, 2026
Merged

Make litebox_shim_linux generic over its platform#1056
Jay Bosamiya (Microsoft) (jaybosamiya-ms) merged 3 commits into
microsoft:mainfrom
jstarks:generic2

Conversation

@jstarks

@jstarksJohn Starks (jstarks) commented Jul 21, 2026

Copy link
Copy Markdown
Member

The Linux shim was hard-wired to the global litebox_platform_multiplex::Platform singleton (set via set_platform, fetched via platform()). This made the shim non-generic and forced platform selection through cargo features. This PR parameterizes the shim over a platform type Platform end-to-end.

…iplex
The Linux shim was hard-wired to the global `litebox_platform_multiplex::Platform`
singleton (set via `set_platform`, fetched via `platform()`). This made the shim
non-generic and forced platform selection through cargo features.
Parameterize the shim over a platform type `Platform` end-to-end (alongside the
existing `FS`): `LinuxShimBuilder<Platform>`, `LinuxShim<Platform, FS>`,
`GlobalState`, `Task`, `LoadedProgram`, and every subsystem type (epoll, unix
sockets, eventfd, channels, signals, process/thread state, transport, ELF loader).
`LinuxShimBuilder::new(platform)` now takes a `&'static Platform`; the global
accessor is gone.
- Add a sealed `ShimPlatform` aggregate bound (with blanket impl) so impls read
`impl<Platform: ShimPlatform, FS: ShimFS>`. It also pins the associated types
the shim relies on: ThreadProvider::ExecutionContext = PtRegs, Timer/Signal
Provider::Signal = common Signal, and VmemPageFaultHandler.
- Remove the litebox_platform_multiplex dependency and platform_* features from
litebox_shim_linux. Tests pick a concrete platform by build target via a
`TestPlatform` alias (LinuxUserland / WindowsUserland) with target-scoped
dev-deps.
- Update the runners to depend on their concrete platform crate and instantiate
`LinuxShimBuilder::new(platform_ref)`: linux_userland (LinuxUserland),
linux_on_windows_userland (WindowsUserland), snp (SnpLinuxKernel). The SNP
page-fault handler reaches the platform through a new `LinuxShim::platform()`
accessor instead of a global.
- Update README to describe the threaded-platform model.
@jstarks
John Starks (jstarks) marked this pull request as ready for review July 21, 2026 08:26

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall LGTM, I've made a few minor notes of nits, I've also updated the PR description to reduce some of the verbosity.

Comment threadlitebox_runner_snp/src/main.rs
Comment threadlitebox_shim_linux/src/lib.rs
Comment threadlitebox_shim_linux/README.md
@jaybosamiya-ms

Copy link
Copy Markdown
Member

Also, since semver-checks CI bot does not fire on branches from forks, here's its output as of 04dc576 (basically expected tweaks):

click to unfold
--- failure feature_missing: package feature removed or renamed ---
Description:
A feature has been removed from this package's Cargo.toml. This will break downstream crates which enable that feature.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#cargo-feature-remove
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.49.0/src/lints/feature_missing.ron
Failed in:
feature platform_linux_userland in the package's Cargo.toml
feature platform_windows_userland in the package's Cargo.toml
feature platform_linux_snp in the package's Cargo.toml
--- failure method_parameter_count_changed: pub method parameter count changed ---
Description:
A publicly-visible method now takes a different number of parameters, not counting the receiver (self) parameter.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#fn-change-arity
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.49.0/src/lints/method_parameter_count_changed.ron
Failed in:
litebox_shim_linux::LinuxShimBuilder::new takes 0 parameters in /home/runner/work/litebox/litebox/target/semver-checks/git-main/30e3a38e80ded90e8ea438866862948a82cadd79/litebox_shim_linux/src/lib.rs:170, but now takes 1 parameters in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:208
--- failure trait_requires_more_generic_type_params: trait now requires more generic type parameters ---
Description:
A trait now requires more generic type parameters than it used to. Uses of this trait that supplied the previously-required number of generic types will be broken. To fix this, consider supplying default values for newly-added generic types.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#trait-new-parameter-no-default
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.49.0/src/lints/trait_requires_more_generic_type_params.ron
Failed in:
trait LinuxShim (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:249
trait LinuxShimEntrypoints (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:134
trait ShimTransport (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/transport.rs:51
trait LoadedProgram (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:356
trait LinuxShimProcess (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:364
trait LinuxShimBuilder (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:201
--- failure type_requires_more_generic_type_params: type now requires more generic type parameters ---
Description:
A type now requires more generic type parameters than it used to. Uses of this type that supplied the previously-required number of generic types will be broken. To fix this, consider supplying default values for newly-added generic types.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#trait-new-parameter-no-default
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.49.0/src/lints/type_requires_more_generic_type_params.ron
Failed in:
Struct LinuxShim (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:249
Struct LinuxShimEntrypoints (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:134
Struct ShimTransport (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/transport.rs:51
Struct LoadedProgram (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:356
Struct LinuxShimProcess (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:364
Struct LinuxShimBuilder (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:201

Merged via the queue into microsoft:main with commit 864239bJul 21, 2026
9 checks passed
pullBot pushed a commit to Mu-L/litebox that referenced this pull request Jul 22, 2026
Makes SNP shim initialization safer via `OnceBox`, and cleans up some
documentation.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 28, 2026
…#1056
`set_platform` was a private one-liner with a single caller, wrapping one
`OnceRef::set`. It mirrored the shape of `litebox_platform_multiplex`, which
needed a setter because it was a separate crate exporting one to foreign
callers. Inside a single module with one call site it is ceremony, and it made
the design read as more global-oriented than it is. `init` now sets the cell
directly and `platform()` is the sole named accessor.
The `PLATFORM` cell itself stays and cannot reasonably go: `Platform::new` runs
only on the BSP and leaks its result, and the AP bring-up trampoline is naked
assembly whose only payload is the `is_bsp` flag in `edi`, so an AP has no
channel to receive the pointer. The doc comment now states that rather than
gesturing at it.
Two artifacts found by comparing against how PR #1056 handled the same job for
litebox_shim_linux:
- The shim's test helper still branched on `cfg(not(target_os = "linux"))` to
call a different `Platform::new`. `Platform` is now hardcoded to
`LinuxUserland`, so that arm was unreachable and would not have compiled.
- The CI `no_std` allow-list rationale for `litebox_shim_optee` claimed it
"depends on `litebox_platform_multiplex`", which is no longer true. #1056
deleted the equivalent entry for litebox_shim_linux outright. That is not
possible here: building litebox_shim_optee for `x86_64-unknown-none` still
fails, but in `sha2`, for the same soft-float/asm reason
`litebox_service_heki` is excluded. The entry stays; the comment now says why.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 28, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Also corrects two stale CI artifacts: the `no_std` rationale for
`litebox_shim_optee` claimed a multiplex dependency, when it is excluded because
its crypto dependencies fail to build for `x86_64-unknown-none`, as with
`litebox_service_heki`.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 28, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
The shim was bound to `litebox_platform_multiplex::Platform`, so platform
selection happened via cargo features and every platform access went through a
panicking global. It is now parameterized end-to-end, mirroring what PR #1056 did
for litebox_shim_linux.
`OpteeShimPlatform` collects the required capabilities. It includes
`VmapManager<PAGE_SIZE>`, which is what the previous two commits bought: the
shim's need to read and write normal-world physical memory is now a trait bound
rather than a consequence of which platform the build happened to select.
Both runners drop the `litebox_platform_multiplex` dependency and name their
platform directly. Neither gains anything it did not already have:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is exactly what the
multiplex `platform_linux_userland_with_optee_syscall` feature was enabling.
The session registry moved from the shim to each runner. This is not cosmetic: a
`static` cannot name a generic parameter, and a shim instance is built per
session, so the shim has nowhere to put it. The composition root names a concrete
platform, so it can hold the `static` and hand out
`&'static SessionManager<ConcretePlatform>`. `GlobalState` now carries that
reference, which is how `current_client_identity` reaches it.
Honest accounting of the global ratchet: this relocates globals more than it
removes them. litebox_shim_optee stays at 5 (it loses the session registry but
its tests gain a platform and a registry, and `INIT_FUNC` goes away).
litebox_runner_lvbs goes 6 -> 8: the platform handle and the session registry.
litebox_runner_optee_on_linux_userland gets a new entry of 1 for its registry.
The platform and shim crates no longer reach for ambient state; the composition
roots do, which is where that belongs.
`litebox_platform_multiplex` now has zero workspace consumers. It is left in the
tree pending a separate decision.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
The shim was bound to `litebox_platform_multiplex::Platform`, so platform
selection happened via cargo features and every platform access went through a
panicking global. It is now parameterized end-to-end, mirroring what PR #1056 did
for litebox_shim_linux.
`OpteeShimPlatform` collects the required capabilities. It includes
`VmapManager<PAGE_SIZE>`, which is what the previous two commits bought: the
shim's need to read and write normal-world physical memory is now a trait bound
rather than a consequence of which platform the build happened to select.
Both runners drop the `litebox_platform_multiplex` dependency and name their
platform directly. Neither gains anything it did not already have:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is exactly what the
multiplex `platform_linux_userland_with_optee_syscall` feature was enabling.
The session registry moved from the shim to each runner. This is not cosmetic: a
`static` cannot name a generic parameter, and a shim instance is built per
session, so the shim has nowhere to put it. The composition root names a concrete
platform, so it can hold the `static` and hand out
`&'static SessionManager<ConcretePlatform>`. `GlobalState` now carries that
reference, which is how `current_client_identity` reaches it.
Honest accounting of the global ratchet: this relocates globals more than it
removes them. litebox_shim_optee stays at 5 (it loses the session registry but
its tests gain a platform and a registry, and `INIT_FUNC` goes away).
litebox_runner_lvbs goes 6 -> 8: the platform handle and the session registry.
litebox_runner_optee_on_linux_userland gets a new entry of 1 for its registry.
The platform and shim crates no longer reach for ambient state; the composition
roots do, which is where that belongs.
`litebox_platform_multiplex` now has zero workspace consumers. It is left in the
tree pending a separate decision.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@jstarks@jaybosamiya-ms
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Make litebox_shim_linux generic over its platform - #1056

Merged
Jay Bosamiya (Microsoft) (jaybosamiya-ms) merged 3 commits into
microsoft:mainfrom
jstarks:generic2
Jul 21, 2026
Merged

Make litebox_shim_linux generic over its platform#1056
Jay Bosamiya (Microsoft) (jaybosamiya-ms) merged 3 commits into
microsoft:mainfrom
jstarks:generic2

Conversation

@jstarks

@jstarksJohn Starks (jstarks) commented Jul 21, 2026

Copy link
Copy Markdown
Member

The Linux shim was hard-wired to the global litebox_platform_multiplex::Platform singleton (set via set_platform, fetched via platform()). This made the shim non-generic and forced platform selection through cargo features. This PR parameterizes the shim over a platform type Platform end-to-end.

…iplex
The Linux shim was hard-wired to the global `litebox_platform_multiplex::Platform`
singleton (set via `set_platform`, fetched via `platform()`). This made the shim
non-generic and forced platform selection through cargo features.
Parameterize the shim over a platform type `Platform` end-to-end (alongside the
existing `FS`): `LinuxShimBuilder<Platform>`, `LinuxShim<Platform, FS>`,
`GlobalState`, `Task`, `LoadedProgram`, and every subsystem type (epoll, unix
sockets, eventfd, channels, signals, process/thread state, transport, ELF loader).
`LinuxShimBuilder::new(platform)` now takes a `&'static Platform`; the global
accessor is gone.
- Add a sealed `ShimPlatform` aggregate bound (with blanket impl) so impls read
`impl<Platform: ShimPlatform, FS: ShimFS>`. It also pins the associated types
the shim relies on: ThreadProvider::ExecutionContext = PtRegs, Timer/Signal
Provider::Signal = common Signal, and VmemPageFaultHandler.
- Remove the litebox_platform_multiplex dependency and platform_* features from
litebox_shim_linux. Tests pick a concrete platform by build target via a
`TestPlatform` alias (LinuxUserland / WindowsUserland) with target-scoped
dev-deps.
- Update the runners to depend on their concrete platform crate and instantiate
`LinuxShimBuilder::new(platform_ref)`: linux_userland (LinuxUserland),
linux_on_windows_userland (WindowsUserland), snp (SnpLinuxKernel). The SNP
page-fault handler reaches the platform through a new `LinuxShim::platform()`
accessor instead of a global.
- Update README to describe the threaded-platform model.
@jstarks
John Starks (jstarks) marked this pull request as ready for review July 21, 2026 08:26

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall LGTM, I've made a few minor notes of nits, I've also updated the PR description to reduce some of the verbosity.

Comment threadlitebox_runner_snp/src/main.rs
Comment threadlitebox_shim_linux/src/lib.rs
Comment threadlitebox_shim_linux/README.md
@jaybosamiya-ms

Copy link
Copy Markdown
Member

Also, since semver-checks CI bot does not fire on branches from forks, here's its output as of 04dc576 (basically expected tweaks):

click to unfold
--- failure feature_missing: package feature removed or renamed ---
Description:
A feature has been removed from this package's Cargo.toml. This will break downstream crates which enable that feature.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#cargo-feature-remove
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.49.0/src/lints/feature_missing.ron
Failed in:
feature platform_linux_userland in the package's Cargo.toml
feature platform_windows_userland in the package's Cargo.toml
feature platform_linux_snp in the package's Cargo.toml
--- failure method_parameter_count_changed: pub method parameter count changed ---
Description:
A publicly-visible method now takes a different number of parameters, not counting the receiver (self) parameter.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#fn-change-arity
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.49.0/src/lints/method_parameter_count_changed.ron
Failed in:
litebox_shim_linux::LinuxShimBuilder::new takes 0 parameters in /home/runner/work/litebox/litebox/target/semver-checks/git-main/30e3a38e80ded90e8ea438866862948a82cadd79/litebox_shim_linux/src/lib.rs:170, but now takes 1 parameters in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:208
--- failure trait_requires_more_generic_type_params: trait now requires more generic type parameters ---
Description:
A trait now requires more generic type parameters than it used to. Uses of this trait that supplied the previously-required number of generic types will be broken. To fix this, consider supplying default values for newly-added generic types.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#trait-new-parameter-no-default
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.49.0/src/lints/trait_requires_more_generic_type_params.ron
Failed in:
trait LinuxShim (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:249
trait LinuxShimEntrypoints (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:134
trait ShimTransport (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/transport.rs:51
trait LoadedProgram (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:356
trait LinuxShimProcess (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:364
trait LinuxShimBuilder (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:201
--- failure type_requires_more_generic_type_params: type now requires more generic type parameters ---
Description:
A type now requires more generic type parameters than it used to. Uses of this type that supplied the previously-required number of generic types will be broken. To fix this, consider supplying default values for newly-added generic types.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#trait-new-parameter-no-default
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.49.0/src/lints/type_requires_more_generic_type_params.ron
Failed in:
Struct LinuxShim (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:249
Struct LinuxShimEntrypoints (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:134
Struct ShimTransport (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/transport.rs:51
Struct LoadedProgram (1 -> 2 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:356
Struct LinuxShimProcess (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:364
Struct LinuxShimBuilder (0 -> 1 required generic types) in /home/runner/work/litebox/litebox/litebox_shim_linux/src/lib.rs:201

Merged via the queue into microsoft:main with commit 864239bJul 21, 2026
9 checks passed
pullBot pushed a commit to Mu-L/litebox that referenced this pull request Jul 22, 2026
Makes SNP shim initialization safer via `OnceBox`, and cleans up some
documentation.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 28, 2026
…#1056
`set_platform` was a private one-liner with a single caller, wrapping one
`OnceRef::set`. It mirrored the shape of `litebox_platform_multiplex`, which
needed a setter because it was a separate crate exporting one to foreign
callers. Inside a single module with one call site it is ceremony, and it made
the design read as more global-oriented than it is. `init` now sets the cell
directly and `platform()` is the sole named accessor.
The `PLATFORM` cell itself stays and cannot reasonably go: `Platform::new` runs
only on the BSP and leaks its result, and the AP bring-up trampoline is naked
assembly whose only payload is the `is_bsp` flag in `edi`, so an AP has no
channel to receive the pointer. The doc comment now states that rather than
gesturing at it.
Two artifacts found by comparing against how PR #1056 handled the same job for
litebox_shim_linux:
- The shim's test helper still branched on `cfg(not(target_os = "linux"))` to
call a different `Platform::new`. `Platform` is now hardcoded to
`LinuxUserland`, so that arm was unreachable and would not have compiled.
- The CI `no_std` allow-list rationale for `litebox_shim_optee` claimed it
"depends on `litebox_platform_multiplex`", which is no longer true. #1056
deleted the equivalent entry for litebox_shim_linux outright. That is not
possible here: building litebox_shim_optee for `x86_64-unknown-none` still
fails, but in `sha2`, for the same soft-float/asm reason
`litebox_service_heki` is excluded. The entry stays; the comment now says why.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 28, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Also corrects two stale CI artifacts: the `no_std` rationale for
`litebox_shim_optee` claimed a multiplex dependency, when it is excluded because
its crypto dependencies fail to build for `x86_64-unknown-none`, as with
`litebox_service_heki`.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 28, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
`litebox_shim_optee` was hard-wired to `litebox_platform_multiplex::Platform`,
so the platform was chosen by cargo feature and fetched from a panicking global.
`litebox_platform_lvbs` separately reached itself through `platform_low()`. This
parameterizes the shim over its platform, mirroring what #1056 did for
`litebox_shim_linux`, and gives LVBS one sanctioned platform accessor.
Neither was reachable without first fixing `GlobalVmapManager`. Its `manager()`
is a `self`-less method returning `&'static Self::Manager`, so every implementor
had to reach a global -- which is the reason both `platform_low()` and
`multiplex::platform()` were on the physical-pointer paths. The trait is gone;
`PhysMutPtr`/`PhysConstPtr` now hold `mgr: &'m M` and take it at construction.
Every construction site outside `litebox_common_linux` is a short-lived local, so
the lifetime never escapes a function body.
`litebox_shim_optee` is generic over `Platform`, bounded by `OpteeShimPlatform`.
The bound includes `VmapManager<PAGE_SIZE>`, so the shim's need to touch
normal-world physical memory is stated in the type system rather than implied by
the selected platform. The session registry moves to each runner: a `static`
cannot name a generic parameter and a shim is built per session, so the shim has
nowhere to hold it, while a runner names a concrete platform.
`litebox_platform_lvbs` keeps a single instance behind `platform()`, renamed from
`platform_low()` and documented as intended rather than as a workaround. A
`static` is required regardless -- APs receive only `is_bsp` from the bring-up
trampoline -- so the choice was only whether the one instance has one home or
many. Caching it in the types that need it was tried and abandoned: it put seven
handles to the platform inside the platform's own structs. The three VSM gates
and `PrivilegedVmap` stay zero-sized.
Both runners name their platform directly. Neither gains anything it lacked:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is what the
multiplex feature enabled. `litebox_platform_multiplex` then has no consumers and
is deleted, along with its workspace entries, ratchet entry, and `no_std` CI
allow-list entry.
Globals ratchet: litebox_platform_lvbs 23 (unchanged), litebox_runner_lvbs 6 -> 7
for the session registry, a new entry of 1 for
litebox_runner_optee_on_linux_userland, and litebox_platform_multiplex removed.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
The shim was bound to `litebox_platform_multiplex::Platform`, so platform
selection happened via cargo features and every platform access went through a
panicking global. It is now parameterized end-to-end, mirroring what PR #1056 did
for litebox_shim_linux.
`OpteeShimPlatform` collects the required capabilities. It includes
`VmapManager<PAGE_SIZE>`, which is what the previous two commits bought: the
shim's need to read and write normal-world physical memory is now a trait bound
rather than a consequence of which platform the build happened to select.
Both runners drop the `litebox_platform_multiplex` dependency and name their
platform directly. Neither gains anything it did not already have:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is exactly what the
multiplex `platform_linux_userland_with_optee_syscall` feature was enabling.
The session registry moved from the shim to each runner. This is not cosmetic: a
`static` cannot name a generic parameter, and a shim instance is built per
session, so the shim has nowhere to put it. The composition root names a concrete
platform, so it can hold the `static` and hand out
`&'static SessionManager<ConcretePlatform>`. `GlobalState` now carries that
reference, which is how `current_client_identity` reaches it.
Honest accounting of the global ratchet: this relocates globals more than it
removes them. litebox_shim_optee stays at 5 (it loses the session registry but
its tests gain a platform and a registry, and `INIT_FUNC` goes away).
litebox_runner_lvbs goes 6 -> 8: the platform handle and the session registry.
litebox_runner_optee_on_linux_userland gets a new entry of 1 for its registry.
The platform and shim crates no longer reach for ambient state; the composition
roots do, which is where that belongs.
`litebox_platform_multiplex` now has zero workspace consumers. It is left in the
tree pending a separate decision.
Sangho Lee (sangho2) pushed a commit that referenced this pull request Jul 29, 2026
The shim was bound to `litebox_platform_multiplex::Platform`, so platform
selection happened via cargo features and every platform access went through a
panicking global. It is now parameterized end-to-end, mirroring what PR #1056 did
for litebox_shim_linux.
`OpteeShimPlatform` collects the required capabilities. It includes
`VmapManager<PAGE_SIZE>`, which is what the previous two commits bought: the
shim's need to read and write normal-world physical memory is now a trait bound
rather than a consequence of which platform the build happened to select.
Both runners drop the `litebox_platform_multiplex` dependency and name their
platform directly. Neither gains anything it did not already have:
`litebox_runner_optee_on_linux_userland` already depended on
`litebox_platform_linux_userland` with `optee_syscall`, which is exactly what the
multiplex `platform_linux_userland_with_optee_syscall` feature was enabling.
The session registry moved from the shim to each runner. This is not cosmetic: a
`static` cannot name a generic parameter, and a shim instance is built per
session, so the shim has nowhere to put it. The composition root names a concrete
platform, so it can hold the `static` and hand out
`&'static SessionManager<ConcretePlatform>`. `GlobalState` now carries that
reference, which is how `current_client_identity` reaches it.
Honest accounting of the global ratchet: this relocates globals more than it
removes them. litebox_shim_optee stays at 5 (it loses the session registry but
its tests gain a platform and a registry, and `INIT_FUNC` goes away).
litebox_runner_lvbs goes 6 -> 8: the platform handle and the session registry.
litebox_runner_optee_on_linux_userland gets a new entry of 1 for its registry.
The platform and shim crates no longer reach for ambient state; the composition
roots do, which is where that belongs.
`litebox_platform_multiplex` now has zero workspace consumers. It is left in the
tree pending a separate decision.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@jstarks@jaybosamiya-ms