sandbox: the proof and microvm oracles read RAPL MSRs where powercap lists none; sandbox-tee attests rapl-msr as RAPL #651

Merged
dcharlot merged 1 commit from sandbox/proof-tee-msr into main 2026-11-06 02:40:02 -05:00
Owner

This finishes the MSR fallback in the sandbox standard (follow-up to #629). Since #629, the production path already reads MSRs: sandbox-meter's RaplPackages::host() falls back to them, and sandbox-exec-microvm's RaplMeter::host() is that same probe. Two test oracles and an example's mapping still assumed powercap. On a host with no powercap zone, run as root, the oracles disagreed with the meter and the tests failed, and the example attested an MSR reading as Estimator.

Changes

  • sandbox-proof: the test oracle, oracle_package_uj_at(powercap, root), is independent of the crate.
    • It reads powercap package zones where any is listed (package-<n> or package-<n>-die-<m>).
    • Otherwise it reads each RAPL domain's energy MSR on that domain's first CPU: per die on Intel, per package on AMD and Hygon.
    • New fake-file test: a two-die Intel package, an AMD package whose CPUs list several die_ids, a zero unit, and a powercap die zone taking precedence.
  • sandbox-exec-microvm: in tests/rapl_hardware.rs the oracle now accepts die zones and falls back to its own MSR reader (watch_host()). Both tests bracket the meter's figure with MSR reads where powercap lists no package. RaplMeter's docs describe the fallback.
  • sandbox-tee: the attested_efficiency example maps "rapl-msr" like "rapl-powercap", to CounterClass::Rapl; it's the same hardware counter. Its test pins each probe name to its class.

Verified

  • Linux: cargo check --workspace --all-targets is clean. Tests pass for sandbox-proof (25), sandbox-tee (43, and 52 with amd-kds,intel-pcs) and sandbox-exec-microvm (22). Clippy is clean.
  • macOS: the CI steps pass: sandbox-proof (28, with its grep) and sandbox-tee (43). Clippy is clean.
  • Two bare-metal servers with no powercap zone. All tests pass in each mode below:
Mode One socket Two sockets
root the in-process meter reads rapl-msr, ratio 1.000 to its oracle; RaplMeter 8.90 J and MsrRaplMeter 8.86 J, both inside the MSR bracket; the example attests rapl, sealed HwShunt ratio 0.999; 23.54 J and 23.56 J inside the bracket, with domains package-0-die-0 and package-1-die-0
unprivileged RAPL Unavailable; the example attests estimator same
unprivileged with the msr group and CAP_SYS_RAWIO matches root matches root

🤖 Generated with Claude Code

This finishes the MSR fallback in the sandbox standard (follow-up to #629). Since #629, the production path already reads MSRs: `sandbox-meter`'s `RaplPackages::host()` falls back to them, and `sandbox-exec-microvm`'s `RaplMeter::host()` is that same probe. Two test oracles and an example's mapping still assumed powercap. On a host with no powercap zone, run as root, the oracles disagreed with the meter and the tests failed, and the example attested an MSR reading as `Estimator`. ## Changes - **`sandbox-proof`:** the test oracle, `oracle_package_uj_at(powercap, root)`, is independent of the crate. - It reads powercap package zones where any is listed (`package-<n>` or `package-<n>-die-<m>`). - Otherwise it reads each RAPL domain's energy MSR on that domain's first CPU: per die on Intel, per package on AMD and Hygon. - New fake-file test: a two-die Intel package, an AMD package whose CPUs list several `die_id`s, a zero unit, and a powercap die zone taking precedence. - **`sandbox-exec-microvm`:** in `tests/rapl_hardware.rs` the oracle now accepts die zones and falls back to its own MSR reader (`watch_host()`). Both tests bracket the meter's figure with MSR reads where powercap lists no package. `RaplMeter`'s docs describe the fallback. - **`sandbox-tee`:** the `attested_efficiency` example maps `"rapl-msr"` like `"rapl-powercap"`, to `CounterClass::Rapl`; it's the same hardware counter. Its test pins each probe name to its class. ## Verified - **Linux:** `cargo check --workspace --all-targets` is clean. Tests pass for `sandbox-proof` (25), `sandbox-tee` (43, and 52 with `amd-kds,intel-pcs`) and `sandbox-exec-microvm` (22). Clippy is clean. - **macOS:** the CI steps pass: `sandbox-proof` (28, with its grep) and `sandbox-tee` (43). Clippy is clean. - **Two bare-metal servers with no powercap zone.** All tests pass in each mode below: | Mode | One socket | Two sockets | |---|---|---| | root | the in-process meter reads `rapl-msr`, ratio 1.000 to its oracle; `RaplMeter` 8.90 J and `MsrRaplMeter` 8.86 J, both inside the MSR bracket; the example attests `rapl`, sealed `HwShunt` | ratio 0.999; 23.54 J and 23.56 J inside the bracket, with domains `package-0-die-0` and `package-1-die-0` | | unprivileged | RAPL Unavailable; the example attests `estimator` | same | | unprivileged with the `msr` group and `CAP_SYS_RAWIO` | matches root | matches root | 🤖 Generated with [Claude Code](https://claude.com/claude-code)
sandbox: RAPL read through the MSRs is attested as RAPL, and the hardware tests' oracles read the MSRs where powercap lists no package
All checks were successful
energy meters on real hardware / RAPL and NVML on jetson-hub (pull_request) Successful in 38s
energy meters on real hardware / sink decode table · RAPL on jetson-hub (NVML surveyed) (pull_request) Successful in 2m45s
standards workspaces build + test / which workspaces this change touches (pull_request) Successful in 7s
standards workspaces build + test / jcp-rs (jcp-conformance, jcp/jcp-rs, -p jcp-energy --features nvml, jcp-rs, linux) (pull_request) Successful in 1m1s
standards workspaces build + test / joule-ui-rs (joule-ui/joule-ui-rs, joule-ui-rs, linux) (pull_request) Successful in 1m13s
standards workspaces build + test / proof-rs (proof/conformance/v1/joulespec.toml, proof-conformance, proof/proof-rs, proof-rs, linux, true) (pull_request) Successful in 1m27s
standards workspaces build + test / sandbox-rs (sandbox-conformance, sandbox/sandbox-rs, -p sandbox-tee --features amd-kds,intel-pcs, sandbox-rs, linux) (pull_request) Successful in 2m7s
energy meters on real hardware / sink decode table · per-task energy and the GPU rail on macOS (pull_request) Successful in 3m17s
standards workspaces build + test / macOS energy backends (pull_request) Successful in 4m56s
standards workspaces build + test / jouledesk-rs (jouledesk/jouledesk-rs, jouledesk-rs, macos) (pull_request) Successful in 5m40s
repository checks / lockfiles, advisories, tests in CI, workflow hygiene, spec and section references, public text (pull_request) Successful in 2m1s
standards workspaces build + test / joulecontract-rs (joulecontract/joulecontract-rs, joulecontract-rs, linux-arm64, true) (pull_request) Successful in 2m48s
standards workspaces build + test / joule-code-rs (joule-code/joule-code-rs, joule-code-rs, linux-arm64, true) (pull_request) Successful in 15m55s
96bd3eb836
Since sandbox-meter's RAPL probe falls back to the energy-status MSRs where
powercap lists no package zone, everything built on it reads such a host:
PowerMeter (`rapl-msr`), and sandbox-exec-microvm's RaplMeter, which is that
probe and which sandbox-proof's S5 proof meters with. Three places still
assumed powercap.

- sandbox-tee's attested_efficiency example named only `rapl-powercap` as a
  CPU counter, so on an MSR host it attested the reading as `Estimator`. Both
  probes are the same hardware counter: `rapl-msr` now attests as
  CounterClass::Rapl and seals HwShunt, as `rapl-powercap` does. Its test
  accepts either probe for the class, and a new test pins every probe name to
  its class.
- sandbox-proof's accelerator test read its oracle from powercap only, so
  where the meter read the MSRs the oracle had no package and the test
  panicked. The oracle (oracle_package_uj_at, independent of the crate) now
  reads the powercap package zones where any is listed (package-<n>, or
  package-<n>-die-<m>), and otherwise each RAPL domain's energy-status MSR on
  its first CPU: a die of a package on Intel, a package on AMD and Hygon, its
  32-bit count at its own unit, wrapping at 2^32 counts. A new test drives it
  over fake files: two dies of one Intel package, an AMD package whose CPUs
  list several die_ids, a zero unit, and a powercap die zone preferred.
- sandbox-exec-microvm's rapl_hardware oracle watched only powercap, so where
  RaplMeter opened on the MSRs the oracle called the host Unreadable; and the
  MSR meter's test bracketed its figure with powercap zones a host without
  powercap does not have. The oracle now watches and brackets with its own MSR
  reads there, scoped the same way, and accepts die zones as packages.
  RaplMeter's docs say what it reads.

On two bare-metal servers with no powercap zone (a one-socket Xeon E-2278G,
two Xeon Silver 4215R sockets), as root: the accelerator span read rapl-msr
at a ratio of 1.000 and 0.999 to the oracle around the call; both microvm
hardware tests sat inside the oracle's MSR bracket (RaplMeter 8.9 J and
23.5 J over a 300 ms burn); the example attested `rapl` and sealed HwShunt.
As an unprivileged user every counter is Unavailable, the figures are
estimates, and every test passes; as that user with the msr group and
CAP_SYS_RAWIO (systemd-run), the results match root's.

Linux x86_64: sandbox-proof, sandbox-tee (default and amd-kds,intel-pcs)
and sandbox-exec-microvm tests pass, `cargo check --workspace --all-targets`
is clean, clippy -D warnings is clean for the three crates. macOS: the CI
step for sandbox-proof passes with its grep, sandbox-tee passes, clippy is
clean for sandbox-meter, sandbox-proof, sandbox-tee and sandbox-exec-microvm.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Transaction-Science/open-standards!651
No description provided.