FABRIC-3.md §I.5: Milestone 7 trust tiers (QEMU-vs-real-hardware), closing it

Closes the contributor-capsule/trust-tier punch-list item. Decided
direction: QEMU-vs-real-hardware conditional enforcement.

Found before building on that decision: the obvious mechanism (expose
TimerInfo.vm_mode) only works on amd64 -- aarch64 and riscv64 both had
vm_mode hardcoded to 1 unconditionally, meaning they'd always report
"running under QEMU" even on real hardware. Built real detection for
both instead of shipping that: aarch64 checks the ACPI RSDP's OEM ID
for QEMU's "BOCHS " SeaBIOS-heritage signature; riscv64 checks the
devicetree root compatible property for "qemu". Confirmed vm_mode was
otherwise unread anywhere else in either file first -- zero risk to
existing timing behavior.

CAPSULE_FLAG_CONTRIB (mkcapsule.c: FLAG_CONTRIB) path-matches on
capsules/contrib/, mirroring FLAG_MAMA_INIT's exact-match pattern.
contrib_capsule_refused() (capsule_birth.c) enforces: no additional
check under QEMU (same WARN-only as everything else); on real hardware,
a contrib capsule additionally requires CAPSULE_SIG_OK, since it has no
other provenance to fall back on. Wired into capsule_birth_baby() and
capsule_run_experiment().

Also updates §I.7 (Milestone 9): its stated precondition (Milestone 7
closing) is now met, flagged as stale rather than treated as a green
light to design networking from nothing.

Verified 3-arch boot to ok> (amd64/aarch64/riscv64, each in the
foreground) -- compile/boot verification only; the real-hardware
enforcement branch is unverifiable from this environment, same as all
of §I.6. logs and DoE CSVs from this session's verification runs
included per this repo's own audit-artifact convention.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019YcT3H2PQeyujrzjqS3Var
This commit is contained in:
Robert Allan James
2026-09-04 11:04:25 -04:00
co-authored by Claude Sonnet 5
parent 5567d03c12
commit eeceec21a5
15 changed files with 27811 additions and 25 deletions
+32 -1
View File
@@ -25,6 +25,37 @@
#include "uefi.h"
#include "starkernel/fdt.h"
#include <stdint.h>
#include <string.h>
/* FABRIC-3.md §I.5, 2026-09-04: real hypervisor-vs-hardware detection.
* s_cal.vm_mode was hardcoded to 1 unconditionally below -- see
* aarch64/timer.c's own running_under_hypervisor() doc comment for why
* that's wrong to reuse as a general "are we in QEMU" signal elsewhere
* (contrib-capsule trust-tier enforcement, §I.5). RISC-V has no ACPI
* here (this file's own devicetree-only timebase-frequency discovery
* above is the proof) but does have a devicetree, already parsed for
* exactly one other property -- the root node's "compatible" property
* carries QEMU's own machine-model string ("qemu" appears in it for the
* virt board) on every QEMU riscv64 target; real hardware vendors set
* their own compatible strings, never this one. bytes_contain() is a
* tiny local substring search -- no strstr dependency assumed available
* in this translation unit. */
static int bytes_contain(const uint8_t *hay, uint32_t haylen, const char *needle) {
size_t nlen = strlen(needle);
if (nlen == 0 || haylen < nlen) return 0;
for (uint32_t i = 0; i + nlen <= haylen; i++) {
if (memcmp(hay + i, needle, nlen) == 0) return 1;
}
return 0;
}
static int running_under_hypervisor(BootInfo *boot_info) {
if (!boot_info || !fdt_valid(boot_info->dtb)) return 0;
uint32_t len = 0;
const void *prop = fdt_find_prop(boot_info->dtb, "compatible", &len);
if (!prop) return 0;
return bytes_contain((const uint8_t *) prop, len, "qemu");
}
/**
* @brief Read the RISC-V wall-clock counter (@c rdtime, CSR @c time 0xC01).
@@ -145,7 +176,7 @@ int timer_init(BootInfo *boot_info)
s_cal.hpet_hz = 0;
s_cal.pit_hz_mean = 0;
s_cal.converged = 1;
s_cal.vm_mode = 1;
s_cal.vm_mode = running_under_hypervisor(boot_info) ? 1 : 0;
/* ABSOLUTE only when the rate came from firmware. On the fallback the
* counter is still monotonic and invariant, but its scaling to real time
* is a guess, which is exactly the RELATIVE case. */