vcpu_run_loop has no embedder progress callback for UI/event pumps
Description
vcpu_run_loop() currently owns guest execution until the guest exits,
times out, or hits a fatal condition. This works well for normal command-line
guest programs, but it is difficult for embedders that need to service host-side
event sources while the guest remains alive.
For example, an embedder may need to periodically run a host event pump,
flush pending host-side callbacks, or service synthetic devices from the same
thread that owns the vCPU. Since vcpu_run_loop() does not expose a progress
or idle callback, the embedder cannot safely do this while the guest is running.
Running the vCPU loop on a worker thread is not a reliable workaround because
some host hypervisor backends require vCPU operations to remain on the thread
that created/owns the vCPU.
Current Behavior
The public loop shape is effectively:
int vcpu_run_loop(hv_vcpu_t vcpu,
hv_vcpu_exit_t *vexit,
guest_t *g,
bool verbose,
int timeout_sec,
int *wait_status);
Once called, control does not return to the embedder until guest termination or
timeout. The embedder has no opportunity to perform periodic host-side work
between guest exits, syscalls, HVC handling, signal checks, or timer wakeups.
Expected Behavior
vcpu_run_loop() should optionally allow an embedder to run a small callback
from inside the loop on the same host thread as the vCPU.
The callback should be optional and preserve current behavior when unset.
Possible API shape:
typedef bool (*vcpu_embedder_tick_fn)(guest_t *g, void *opaque);
typedef struct vcpu_run_hooks {
vcpu_embedder_tick_fn tick;
void *opaque;
} vcpu_run_hooks_t;
int vcpu_run_loop_ex(hv_vcpu_t vcpu,
hv_vcpu_exit_t *vexit,
guest_t *g,
bool verbose,
int timeout_sec,
int *wait_status,
const vcpu_run_hooks_t *hooks);
The existing vcpu_run_loop() could remain as a compatibility wrapper around
vcpu_run_loop_ex(..., NULL).
Suggested Semantics
The callback could run at safe progress points such as:
- after handling a guest exit
- after syscall/HVC dispatch completes
- after signal/timer checks
- before sleeping or returning to
hv_vcpu_run()
The callback should:
- run on the same host thread as
hv_vcpu_run()
- be optional
- avoid changing behavior for existing callers
- return whether it performed work, if that is useful for scheduling decisions
Why This Is Needed
Some embedders need to keep host-side state machines alive while guest code is
still running. Without a callback, those embedders must choose between:
- blocking forever inside
vcpu_run_loop()
- using a timeout and repeatedly re-entering the loop
- moving the vCPU loop to another thread, which can conflict with hypervisor
thread-affinity constraints
- patching elfuse locally
An optional in-loop callback would provide a cleaner and more general embedding
interface without affecting normal Linux binary execution.
Compatibility
This can be implemented without changing current users by keeping the existing
vcpu_run_loop() signature and adding a new extended API or optional hooks
structure.
vcpu_run_loop has no embedder progress callback for UI/event pumps
Description
vcpu_run_loop()currently owns guest execution until the guest exits,times out, or hits a fatal condition. This works well for normal command-line
guest programs, but it is difficult for embedders that need to service host-side
event sources while the guest remains alive.
For example, an embedder may need to periodically run a host event pump,
flush pending host-side callbacks, or service synthetic devices from the same
thread that owns the vCPU. Since
vcpu_run_loop()does not expose a progressor idle callback, the embedder cannot safely do this while the guest is running.
Running the vCPU loop on a worker thread is not a reliable workaround because
some host hypervisor backends require vCPU operations to remain on the thread
that created/owns the vCPU.
Current Behavior
The public loop shape is effectively:
Once called, control does not return to the embedder until guest termination or
timeout. The embedder has no opportunity to perform periodic host-side work
between guest exits, syscalls, HVC handling, signal checks, or timer wakeups.
Expected Behavior
vcpu_run_loop()should optionally allow an embedder to run a small callbackfrom inside the loop on the same host thread as the vCPU.
The callback should be optional and preserve current behavior when unset.
Possible API shape:
The existing
vcpu_run_loop()could remain as a compatibility wrapper aroundvcpu_run_loop_ex(..., NULL).Suggested Semantics
The callback could run at safe progress points such as:
hv_vcpu_run()The callback should:
hv_vcpu_run()Why This Is Needed
Some embedders need to keep host-side state machines alive while guest code is
still running. Without a callback, those embedders must choose between:
vcpu_run_loop()thread-affinity constraints
An optional in-loop callback would provide a cleaner and more general embedding
interface without affecting normal Linux binary execution.
Compatibility
This can be implemented without changing current users by keeping the existing
vcpu_run_loop()signature and adding a new extended API or optional hooksstructure.