Add vcpu run loop hooks - #245
Conversation
jserv
left a comment
There was a problem hiding this comment.
Review of the vCPU run-loop hook API. Three points below, anchored inline.
| /* Optional embedder hook. Called on the vCPU owner thread before each | ||
| * hv_vcpu_run() re-entry. Return nonzero to stop the loop. | ||
| */ | ||
| typedef int (*vcpu_run_loop_tick_fn)(guest_t *g, void *opaque); |
There was a problem hiding this comment.
The hook contract is underspecified in three ways:
- Stop semantics: state what the function returns when tick returns nonzero (currently exit code 0, indistinguishable from guest exit 0).
- Concurrency and lifetime: when one vcpu_run_hooks_t/opaque is shared across worker vCPUs, tick is called concurrently from multiple threads, so it must be thread-safe. The implementation keeps no copy and dereferences hooks/opaque every iteration, so the caller must keep both alive until the function returns.
- Cooperative-only timing: the tick fires only at the top of the loop (host round-trips), not after hv_vcpu_run() returns. A worker (timeout_sec == 0, no alarm()) spinning entirely in EL0 never reaches the top, so a hook cannot interrupt a runaway guest -- only exit_group's hv_vcpus_exit() kick can. "before each hv_vcpu_run() re-entry" reads as periodic; clarify it is checked at host boundaries only.
| .opaque = (void *) 0x1, | ||
| }; | ||
|
|
||
| if (hooks.tick == NULL || hooks.opaque == NULL) { |
There was a problem hiding this comment.
The runtime half of this test is tautological: given the initializer, hooks.tick/hooks.opaque are never NULL, so the if can't fire and main always reaches PASS; the tick function is defined but never called. The real value is the two _Static_assert's, which fire at compile time -- building the object is what matters, not running the binary, yet mk/tests.mk prints a "unit test" banner and executes it, implying runtime validation that does not exist. The new executable behavior (invoke tick, break on nonzero) has no coverage since no in-tree caller passes non-NULL hooks. Either make it a compile-only target, or have main actually call tick(g, opaque) and assert on both the non-NULL and NULL-opaque short-circuit results.
Add an optional hook API for embedders that need to run host-side work before re-entering hv_vcpu_run on the vCPU owner thread. Keep the existing vcpu_run_loop signature as a compatibility wrapper around the extended entry point with no hooks installed. Add a host-side compile test that pins the public signatures and verifies the hook structure can be initialized. Run it from the normal host test paths used by check and check-sanitizer. Fix sysprog21#244
b3ebc9a to
e19686a
Compare
|
Here is a summary of my update:
|
|
Thank @doanbaotrung for contributing! |
Add an optional hook API for embedders that need to run host-side work before re-entering hv_vcpu_run on the vCPU owner thread.
Keep the existing vcpu_run_loop signature as a compatibility wrapper around the extended entry point with no hooks installed.
Add a host-side compile test that pins the public signatures and verifies the hook structure can be initialized. Run it from the normal host test paths used by check and check-sanitizer.
Fix #244
Summary by cubic
Add
vcpu_run_loop_with_hooksto let embedders run host work before eachhv_vcpu_runre-entry. Keepvcpu_run_loopas a wrapper and add a host compile test.vcpu_run_loop_with_hooks(..., const vcpu_run_hooks_t *hooks)andvcpu_run_hooks_twith an optionaltick.tickruns on the vCPU owner thread beforehv_vcpu_run(), checked only at host boundaries; nonzero return stops the loop.vcpu_run_loopremains as a no-hook wrapper for API compatibility.test-vcpu-run-hooks-host; wired intocheck,check-sanitizer, andmake test-vcpu-run-hooks-host.Written for commit e19686a. Summary will update on new commits.