Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b51012de authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

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
Loading
Loading
Loading
Loading
+2 −8
Original line number Diff line number Diff line
@@ -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,
+15 −0
Original line number Diff line number Diff line
@@ -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