Search code examples
ckvm

Timeout for KVM userspace guest


I am building a custom VMM, and I am trying to implement a timeout without using signals (which are "sent" to the whole process) or threads (I'm not going to use threads).

Now, one idea is to implement the LAPIC and just before executing the guest code we could program the LAPIC TIMER to trigger after a certain time. It should be possible to have a fairly decent timeout with this. However, this solution is fairly painful to do just for simple timeout behavior.

Is there no other, better way to get KVM to interrupt itself after a certain amount of time? I was really hoping for an argument to KVM_RUN or just about anything, really.

As should be plain from the title, the guest is executing in userspace most of the time. There is a razor thin kernel layer. I don't really want to install a LAPIC unless I absolutely have to. Ideas?


Solution

  • Using KVM_CREATE_IRQCHIP in combination with KVM_SET_LAPIC we can utilize the emulated LVT timer to get per-thread execution timeouts on KVM without any trouble. It is expensive to call KVM_SET_LAPIC, but it is necessary in order to avoid exposing the MSRs and device to the guest.

    I tried alternatively to write the MSRs using KVM API, however even that is not possible (I'm guessing without the proper CPUID bits). Either way, the LAPIC timer works no matter how many features you disable in the guest.

    KVM_SET_LAPIC costs around 3 microseconds (which is extreme) on my machine, so I'm still looking for alternatives. I speculate that given you trust ring-0 in the kernel writing just the x2APIC TIMER and INITCNT MSRs might be cheaper.

    One thing to remember is to also set the CURRENTCNT register at the same time, because KVM_SET_LAPIC is explicit, and if you end up with a CURRENTCNT > INITCNT you will get a dmesg log entry, which can be expensive.