kvm: robustify steal time record
authorWanpeng Li <wanpeng.li@hotmail.com>
Tue, 3 May 2016 03:43:10 +0000 (11:43 +0800)
committerRadim Krčmář <rkrcmar@redhat.com>
Tue, 3 May 2016 15:19:05 +0000 (17:19 +0200)
Guest should only trust data to be valid when version haven't changed
before and after reads of steal time. Besides not changing, it has to
be an even number. Hypervisor may write an odd number to version field
to indicate that an update is in progress.

kvm_steal_clock() in guest has already done the read side, make write
side in hypervisor more robust by following the above rule.

Reviewed-by: Wincy Van <fanwenyi0529@gmail.com>
Signed-off-by: Wanpeng Li <wanpeng.li@hotmail.com>
Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
arch/x86/kvm/x86.c

index 96e81d284deb36d58d62410f7bf940f4b7f6583c..57a62d1e2f5d387fbe7af49df47ae2cff20778f5 100644 (file)
@@ -2011,10 +2011,26 @@ static void record_steal_time(struct kvm_vcpu *vcpu)
                &vcpu->arch.st.steal, sizeof(struct kvm_steal_time))))
                return;
 
+       if (vcpu->arch.st.steal.version & 1)
+               vcpu->arch.st.steal.version += 1;  /* first time write, random junk */
+
+       vcpu->arch.st.steal.version += 1;
+
+       kvm_write_guest_cached(vcpu->kvm, &vcpu->arch.st.stime,
+               &vcpu->arch.st.steal, sizeof(struct kvm_steal_time));
+
+       smp_wmb();
+
        vcpu->arch.st.steal.steal += current->sched_info.run_delay -
                vcpu->arch.st.last_steal;
        vcpu->arch.st.last_steal = current->sched_info.run_delay;
-       vcpu->arch.st.steal.version += 2;
+
+       kvm_write_guest_cached(vcpu->kvm, &vcpu->arch.st.stime,
+               &vcpu->arch.st.steal, sizeof(struct kvm_steal_time));
+
+       smp_wmb();
+
+       vcpu->arch.st.steal.version += 1;
 
        kvm_write_guest_cached(vcpu->kvm, &vcpu->arch.st.stime,
                &vcpu->arch.st.steal, sizeof(struct kvm_steal_time));