From 3f9808cac06c8dd4f800101e04f84fe3180198b0 Mon Sep 17 00:00:00 2001 From: Oliver Upton Date: Thu, 16 Sep 2021 18:15:51 +0000 Subject: selftests: KVM: Introduce system counter offset test Introduce a KVM selftest to verify that userspace manipulation of the TSC (via the new vCPU attribute) results in the correct behavior within the guest. Reviewed-by: Andrew Jones Signed-off-by: Oliver Upton Message-Id: <20210916181555.973085-6-oupton@google.com> Signed-off-by: Paolo Bonzini --- Documentation/virt/kvm/devices/vcpu.rst | 41 ++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 14 deletions(-) (limited to 'Documentation/virt') diff --git a/Documentation/virt/kvm/devices/vcpu.rst b/Documentation/virt/kvm/devices/vcpu.rst index 3b399d727c11..60a29972d3f1 100644 --- a/Documentation/virt/kvm/devices/vcpu.rst +++ b/Documentation/virt/kvm/devices/vcpu.rst @@ -184,37 +184,50 @@ TSC is then derived by the following equation: guest_tsc = host_tsc + KVM_VCPU_TSC_OFFSET -This attribute is useful for the precise migration of a guest's TSC. The -following describes a possible algorithm to use for the migration of a -guest's TSC: +This attribute is useful to adjust the guest's TSC on live migration, +so that the TSC counts the time during which the VM was paused. The +following describes a possible algorithm to use for this purpose. From the source VMM process: -1. Invoke the KVM_GET_CLOCK ioctl to record the host TSC (t_0), - kvmclock nanoseconds (k_0), and realtime nanoseconds (r_0). +1. Invoke the KVM_GET_CLOCK ioctl to record the host TSC (tsc_src), + kvmclock nanoseconds (guest_src), and host CLOCK_REALTIME nanoseconds + (host_src). 2. Read the KVM_VCPU_TSC_OFFSET attribute for every vCPU to record the - guest TSC offset (off_n). + guest TSC offset (ofs_src[i]). 3. Invoke the KVM_GET_TSC_KHZ ioctl to record the frequency of the guest's TSC (freq). From the destination VMM process: -4. Invoke the KVM_SET_CLOCK ioctl, providing the kvmclock nanoseconds - (k_0) and realtime nanoseconds (r_0) in their respective fields. - Ensure that the KVM_CLOCK_REALTIME flag is set in the provided - structure. KVM will advance the VM's kvmclock to account for elapsed - time since recording the clock values. +4. Invoke the KVM_SET_CLOCK ioctl, providing the source nanoseconds from + kvmclock (guest_src) and CLOCK_REALTIME (host_src) in their respective + fields. Ensure that the KVM_CLOCK_REALTIME flag is set in the provided + structure. -5. Invoke the KVM_GET_CLOCK ioctl to record the host TSC (t_1) and - kvmclock nanoseconds (k_1). + KVM will advance the VM's kvmclock to account for elapsed time since + recording the clock values. Note that this will cause problems in + the guest (e.g., timeouts) unless CLOCK_REALTIME is synchronized + between the source and destination, and a reasonably short time passes + between the source pausing the VMs and the destination executing + steps 4-7. + +5. Invoke the KVM_GET_CLOCK ioctl to record the host TSC (tsc_dest) and + kvmclock nanoseconds (guest_dest). 6. Adjust the guest TSC offsets for every vCPU to account for (1) time elapsed since recording state and (2) difference in TSCs between the source and destination machine: - new_off_n = t_0 + off_n + (k_1 - k_0) * freq - t_1 + ofs_dst[i] = ofs_src[i] - + (guest_src - guest_dest) * freq + + (tsc_src - tsc_dest) + + ("ofs[i] + tsc - guest * freq" is the guest TSC value corresponding to + a time of 0 in kvmclock. The above formula ensures that it is the + same on the destination as it was on the source). 7. Write the KVM_VCPU_TSC_OFFSET attribute for every vCPU with the respective value derived in the previous step. -- cgit v1.2.3