Commit b51012de authored by Paolo Bonzini's avatar Paolo Bonzini

KVM: x86: introduce do_shl32_div32

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: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 765bdb40
...@@ -1196,14 +1196,8 @@ static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock) ...@@ -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) static uint32_t div_frac(uint32_t dividend, uint32_t divisor)
{ {
uint32_t quotient, remainder; do_shl32_div32(dividend, divisor);
return dividend;
/* 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;
} }
static void kvm_get_time_scale(uint32_t scaled_khz, uint32_t base_khz, static void kvm_get_time_scale(uint32_t scaled_khz, uint32_t base_khz,
......
...@@ -192,4 +192,19 @@ extern unsigned int min_timer_period_us; ...@@ -192,4 +192,19 @@ extern unsigned int min_timer_period_us;
extern unsigned int lapic_timer_advance_ns; extern unsigned int lapic_timer_advance_ns;
extern struct static_key kvm_no_apic_vcpu; 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 #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment