data: 64-byte alignment physical address of a memory area which must be in guest RAM, plus an enable bit in bit 0. This memory is expected to hold a copy of the following structure:
whose data will be filled in by the hypervisor periodically. Only one write, or registration, is needed for each VCPU. The interval between updates of this structure is arbitrary and implementation-dependent. The hypervisor may update this structure at any time it sees fit until anything with bit0 == 0 is written to it. Guest is required to make sure this structure is initialized to zero.
Fields have the following meanings:
version: a sequence counter. In other words, guest has to check this field before and after grabbing time information and make sure they are both equal and even. An odd version indicates an in-progress update.
flags: At this point, always zero. May be used to indicate changes in this structure in the future.
steal: the amount of time in which this vCPU did not run, in nanoseconds. Time during which the vcpu is idle, will not be reported as steal time.
preempted: indicate the vCPU who owns this struct is running or not. Non-zero values mean the vCPU has been preempted. Zero means the vCPU is not preempted. NOTE, it is always zero if the the hypervisor doesn't support this field.
version的作用类似于rtc的”Update in progress” flag,防止读到中间状态。 guest grab time information时,应该包含如下逻辑:
1 2 3 4 5
do { version1 = before grabbing time information do something to grab time information version2 = after grabbing time information } while(!(version1 == version2 && version1为偶数));
5. Host calculate steal time
1 2 3 4 5 6 7
// https://elixir.bootlin.com/linux/v4.19/source/include/linux/sched.h#L290 structsched_info { ... /* Time spent waiting on a runqueue: */ unsignedlonglong run_delay; ... };