No cgroups, no guest cooperation
Enforcement is userspace signal-based — no dependency on cgroup CPU controllers, no assumption that the guest kernel cooperates with the throttle.
Technology — CPU Cap Enforcement
A rate limiter that only acts when a vCPU thread exits KVM_RUN on its own misses a guest that minimizes voluntary exits. FlashVMM uses a background thread that forces the exit.
sequenceDiagram
participant Pacer as Pacer thread
participant Vcpu as vCPU thread
participant Budget as CpuBudget
loop every 5ms
Pacer->>Vcpu: tgkill(SIGUSR1), no SA_RESTART
Vcpu-->>Vcpu: KVM_RUN forced to return EINTR
Vcpu->>Budget: tick() — checked CLOCK_THREAD_CPUTIME_ID
against this thread's budget
alt over budget
Budget->>Vcpu: sleep until budget window resets
end
end
Enforcement is userspace signal-based — no dependency on cgroup CPU controllers, no assumption that the guest kernel cooperates with the throttle.
If the signal handler can't install, the VM is treated as unrunnable rather than allowed to run uncapped.
Capping a guest from the instant it powers on regresses boot time from under 2 seconds to 90+ — kernel init, device probing, and early userspace need genuine CPU during that window. A boot-grace period (default 8 seconds, configurable, 0 to disable) holds off the cap until then.
The cap engages at whichever comes first: the guest's own Start hand-off, or the grace window elapsing. A restore gets no grace — a repeated capture→restore cycle can't be used to hold a permanent uncapped state.
The pacer, budget tracking, and boot-grace logic run on both x86_64 and aarch64, with the same fail-closed and boot-grace semantics on each.