KVM: x86: introduce do_shl32_div32
authorPaolo Bonzini <pbonzini@redhat.com>
Fri, 22 Jan 2016 10:39:22 +0000 (11:39 +0100)
committerPaolo Bonzini <pbonzini@redhat.com>
Tue, 9 Feb 2016 12:24:37 +0000 (13:24 +0100)
This is similar to the existing div_frac function, but it returns the
remainder too.  Unlike div_frac, it can be used to implement long
division, e.g. (a << 64) / b for 32-bit a and b.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/x86.c
arch/x86/kvm/x86.h

index 4244c2b..5b937fd 100644 (file)
@@ -1196,14 +1196,8 @@ static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock)
 
 static uint32_t div_frac(uint32_t dividend, uint32_t divisor)
 {
-       uint32_t quotient, remainder;
-
-       /* Don't try to replace with do_div(), this one calculates
-        * "(dividend << 32) / divisor" */
-       __asm__ ( "divl %4"
-                 : "=a" (quotient), "=d" (remainder)
-                 : "0" (0), "1" (dividend), "r" (divisor) );
-       return quotient;
+       do_shl32_div32(dividend, divisor);
+       return dividend;
 }
 
 static void kvm_get_time_scale(uint32_t scaled_khz, uint32_t base_khz,
index f2afa5f..34f4164 100644 (file)
@@ -192,4 +192,19 @@ extern unsigned int min_timer_period_us;
 extern unsigned int lapic_timer_advance_ns;
 
 extern struct static_key kvm_no_apic_vcpu;
+
+/* Same "calling convention" as do_div:
+ * - divide (n << 32) by base
+ * - put result in n
+ * - return remainder
+ */
+#define do_shl32_div32(n, base)                                        \
+       ({                                                      \
+           u32 __quot, __rem;                                  \
+           asm("divl %2" : "=a" (__quot), "=d" (__rem)         \
+                       : "rm" (base), "0" (0), "1" ((u32) n)); \
+           n = __quot;                                         \
+           __rem;                                              \
+        })
+
 #endif