| From ff40c74018d869be15569ad0788d64b2e8fa079b Mon Sep 17 00:00:00 2001 |
| From: Avi Kivity <avi@redhat.com> |
| Date: Tue, 4 May 2010 15:00:37 +0300 |
| Subject: KVM: Fix wallclock version writing race |
| |
| From: Avi Kivity <avi@redhat.com> |
| |
| 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> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| (cherry picked from commit 9ed3c444ab8987c7b219173a2f7807e3f71e234e) |
| --- |
| arch/x86/kvm/x86.c | 12 ++++++++++-- |
| 1 file changed, 10 insertions(+), 2 deletions(-) |
| |
| --- a/arch/x86/kvm/x86.c |
| +++ b/arch/x86/kvm/x86.c |
| @@ -554,14 +554,22 @@ static int do_set_msr(struct kvm_vcpu *v |
| |
| static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock) |
| { |
| - static int version; |
| + int version; |
| + int r; |
| struct pvclock_wall_clock wc; |
| struct timespec boot; |
| |
| if (!wall_clock) |
| return; |
| |
| - version++; |
| + r = kvm_read_guest(kvm, wall_clock, &version, sizeof(version)); |
| + if (r) |
| + return; |
| + |
| + if (version & 1) |
| + ++version; /* first time write, random junk */ |
| + |
| + ++version; |
| |
| kvm_write_guest(kvm, wall_clock, &version, sizeof(version)); |
| |