What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
ioctl(vcpu_fd, KVM_RUN) asks KVM to run the guest virtual CPU associated with that vCPU file descriptor. When the call returns successfully, userspace checks struct kvm_run to learn why execution returned and what action, if any, it must take before calling KVM_RUN again. The ioctl result and the exit reason are separate: a successful return is not the same thing as an error or interruption.
What does KVM_RUN do?
The Linux kernel’s KVM API reference describes KVM_RUN as the ioctl “used to run a guest virtual cpu.” A virtual-machine monitor (VMM) creates a VM and its vCPUs through the KVM API, then calls this ioctl on a vCPU file descriptor to let KVM execute that virtual CPU.
As an Amazon Associate I earn from qualifying purchases.
The call’s parameter block is implicit rather than passed as an ioctl argument: userspace maps the vCPU file descriptor at offset zero, using the size returned by KVM_GET_VCPU_MMAP_SIZE. That mapping is formatted as struct kvm_run. The Linux KVM UAPI header also defines the structure as the data returned by mapping a vCPU file descriptor at offset zero.
How the VM-exit loop works
- The VMM prepares the vCPU’s mapped
struct kvm_run, setting any documented input fields it needs. - It calls
KVM_RUN. KVM executes the guest until it can continue internally or must return control to userspace. - After a successful return, the VMM reads
exit_reasonand the corresponding data in the structure’s union. - The VMM performs any required userspace work, such as servicing an emulated device operation, then calls
KVM_RUNagain to resume the vCPU.
A VM exit is a transition out of guest execution; it does not necessarily mean that the VMM receives control. KVM handles many events inside the kernel. The userspace loop sees the conditions KVM reports through this API, not every underlying hardware exit.
#1 Best Overall
What struct kvm_run tells userspace
On a successful return, exit_reason identifies why KVM_RUN returned, and the union member for that reason contains relevant details. As the Linux Kernel Documentation puts it: “When KVM_RUN has returned successfully (return value 0), this informs application code why KVM_RUN has returned.” The structure also includes documented fields userspace may set before entering KVM, plus architecture-specific fields and details.
KVM_EXIT_IO: x86 port I/O
On x86, this exit reports a guest port-I/O operation that KVM could not satisfy. Its data describes the direction, access size, port, count, and offset of the packed I/O data in the mapped region. For an input operation, userspace places the requested data in the indicated location before re-entering the kernel.
Rank #2
KVM_EXIT_MMIO: memory-mapped I/O
This exit reports a memory-mapped I/O operation that KVM could not satisfy. The exit data includes the physical address, access length, direction, and data. For a read, userspace supplies the value where the structure indicates so the guest can receive it after resumption.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Repair Windows errors before they cause bigger problems3Scan for outdated or missing drivers - takes under a minuteFor KVM_EXIT_IO, KVM_EXIT_MMIO, and several other userspace-mediated exits listed in the API, the operation is not complete and guest state is not consistent until userspace re-enters with KVM_RUN. The pending-operation state is not preserved in state visible to userspace. A handler therefore should not treat the operation as completed while indefinitely postponing that re-entry.
Rank #3
How to distinguish an exit from an ioctl error
Check the ioctl’s return value before interpreting exit_reason. The API documents zero for a successful return and -1 for an error; on error, the program should inspect errno. Only a successful return should be interpreted as an exit reported through struct kvm_run.
| Result | What it means | What userspace should check |
|---|---|---|
Return value 0 |
KVM_RUN returned successfully. |
Read exit_reason and the matching union member. |
Return value -1, with errno set |
The ioctl failed or was interrupted; this is not by itself a successful device exit. | Apply the program’s error or interruption policy using errno. |
The API lists EINTR when an unmasked signal is pending. Separately, where KVM_CAP_IMMEDIATE_EXIT is supported, userspace can set the immediate_exit field: KVM polls it as KVM_RUN starts, and a nonzero value requests an immediate return with -EINTR.
Interrupt injection and architecture-specific fields
request_interrupt_window asks KVM to return when an external interrupt can be injected. When that request was made, ready_for_interrupt_injection reports whether injection is ready. This is different from immediate_exit, which requests an immediate return rather than waiting for an injection window.
Fields such as if_flag, cr8, and apic_base have constraints, including dependencies on whether an in-kernel local APIC is used. The API also defines architecture-specific flags and exit details. Although KVM_RUN is available on all architectures, not every exit type, structure member, or behavior is identical across them.
Best Value
The API reference recommends KVM_EXIT_IO on x86 or KVM_EXIT_MMIO on architectures other than s390 when guest functionality must interact with host userspace; it says KVM_EXIT_IO is significantly faster than KVM_EXIT_MMIO. This is qualitative API guidance, not a numeric benchmark or a universal claim about all device emulation. Use the KVM API documentation and headers for the target kernel version and architecture when implementing these details. The documentation was checked on October 7, 2026, and the reference and mainline header can evolve.
Minimal control-flow sketch
for (;;) {
int rc = ioctl(vcpu_fd, KVM_RUN);
if (rc == -1) {
/* Inspect errno; handle EINTR or another error by policy. */
continue_or_handle_error();
}
switch (run->exit_reason) {
case KVM_EXIT_IO:
handle_port_io(run);
break;
case KVM_EXIT_MMIO:
handle_mmio(run);
break;
default:
handle_other_exit(run);
break;
}
/* Re-enter KVM_RUN when the exit handling requires resumption. */
}
This sketch shows the distinction between syscall status and a successful exit, not a complete VMM. Real code must handle every exit type relevant to its guest, architecture, and device model, and must follow the documented fields and completion rules for each exit.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




