Technology — CPU Cap Enforcement

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
Every 5ms, unconditionally, independent of how the guest schedules its own work.

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.

Fail-closed

If the signal handler can't install, the VM is treated as unrunnable rather than allowed to run uncapped.

Boot-grace window

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.

Both architectures

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.