|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [linux-2.6.18-xen] x86/time: fix wc_version retry check
# HG changeset patch
# User Jan Beulich <jbeulich@xxxxxxxx>
# Date 1390208471 -3600
# Node ID ca683fddd28a1878b1bea536eb99f3d2ddee7020
# Parent 777c424881e19f8f0c3106fd795873c536d93798
x86/time: fix wc_version retry check
When using | instead of || (attempting to make the compiler issue just
a single branch), both sides of the operator aren't separated by a
sequence point, and hence evaluation can happen in any order. In
particular the rightmost read of s->wc_version could get carried out
before the leftmost one. Use a local variable to prevent this. (In
reality the compiler is very likely to do only a single memory read
here anyway.)
Reported-by: Julian Stecklina <jsteckli@xxxxxxxxxxxxxxxxxxxx>
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
---
diff -r 777c424881e1 -r ca683fddd28a arch/i386/kernel/time-xen.c
--- a/arch/i386/kernel/time-xen.c Fri Dec 20 16:37:05 2013 +0100
+++ b/arch/i386/kernel/time-xen.c Mon Jan 20 10:01:11 2014 +0100
@@ -257,6 +257,7 @@ static void __update_wallclock(time_t se
static void update_wallclock(void)
{
shared_info_t *s = HYPERVISOR_shared_info;
+ u32 version;
do {
shadow_tv_version = s->wc_version;
@@ -264,7 +265,8 @@ static void update_wallclock(void)
shadow_tv.tv_sec = s->wc_sec;
shadow_tv.tv_nsec = s->wc_nsec;
rmb();
- } while ((s->wc_version & 1) | (shadow_tv_version ^ s->wc_version));
+ version = s->wc_version;
+ } while ((version & 1) | (shadow_tv_version ^ version));
if (!independent_wallclock)
__update_wallclock(shadow_tv.tv_sec, shadow_tv.tv_nsec);
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |