aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2010-05-04 08:00:37 -0400
committerAvi Kivity <avi@redhat.com>2010-05-19 04:36:36 -0400
commit9ed3c444ab8987c7b219173a2f7807e3f71e234e (patch)
tree4214bfb01447b73768ae1e8175b04fccb2b3495f
parent8facbbff071ff2b19268d3732e31badc60471e21 (diff)
KVM: Fix wallclock version writing race
Wallclock writing uses an unprotected global variable to hold the version; this can cause one guest to interfere with another if both write their wallclock at the same time. Acked-by: Glauber Costa <glommer@redhat.com> Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r--arch/x86/kvm/x86.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index dff08e527ec7..54f73b6a006b 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -754,14 +754,22 @@ static int do_set_msr(struct kvm_vcpu *vcpu, unsigned index, u64 *data)
754 754
755static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock) 755static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock)
756{ 756{
757 static int version; 757 int version;
758 int r;
758 struct pvclock_wall_clock wc; 759 struct pvclock_wall_clock wc;
759 struct timespec boot; 760 struct timespec boot;
760 761
761 if (!wall_clock) 762 if (!wall_clock)
762 return; 763 return;
763 764
764 version++; 765 r = kvm_read_guest(kvm, wall_clock, &version, sizeof(version));
766 if (r)
767 return;
768
769 if (version & 1)
770 ++version; /* first time write, random junk */
771
772 ++version;
765 773
766 kvm_write_guest(kvm, wall_clock, &version, sizeof(version)); 774 kvm_write_guest(kvm, wall_clock, &version, sizeof(version));
767 775