diff options
author | Jan Beulich <jbeulich@suse.com> | 2012-11-27 13:25:17 +0100 |
---|---|---|
committer | Jan Beulich <jbeulich@suse.com> | 2012-11-27 13:25:17 +0100 |
commit | 13190e476d9ed62e377219c8a1e6e3759b3af6da (patch) | |
tree | f1a2b00cdba23f89df36ec94ae115ee1993699e2 | |
parent | 3ab152559314eaa84c6ddb3cb6d5f58918310432 (diff) | |
download | xen-13190e476d9ed62e377219c8a1e6e3759b3af6da.tar.gz xen-13190e476d9ed62e377219c8a1e6e3759b3af6da.tar.bz2 xen-13190e476d9ed62e377219c8a1e6e3759b3af6da.zip |
x86/time: fix scale_delta() inline assembly
The way it was coded, it clobbered %rdx without telling the compiler.
This generally didn't cause any problems except when there are two back
to back invocations (as in plt_overflow()), as in that case the
compiler may validly assume that it can re-use for the second instance
the value loaded into %rdx before the first one.
Once at it, also properly relax the second operand of "mul" (there's no
need for it to be in %rdx, or a register at all), and switch away from
using explicit register names in the instruction operands.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Keir Fraser <keir@xen.org>
xen-unstable changeset: 26188:16bf7f3069a7
xen-unstable date: Mon Nov 26 16:20:39 UTC 2012
-rw-r--r-- | xen/arch/x86/time.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c index f944e3d8f3..65d58a4c15 100644 --- a/xen/arch/x86/time.c +++ b/xen/arch/x86/time.c @@ -142,8 +142,9 @@ static inline u64 scale_delta(u64 delta, struct time_scale *scale) : "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (scale->mul_frac) ); #else asm ( - "mul %%rdx ; shrd $32,%%rdx,%%rax" - : "=a" (product) : "0" (delta), "d" ((u64)scale->mul_frac) ); + "mul %2 ; shrd $32,%1,%0" + : "=a" (product), "=d" (delta) + : "rm" (delta), "0" ((u64)scale->mul_frac) ); #endif return product; |