From mboxrd@z Thu Jan 1 00:00:00 1970 From: Yunhong Jiang Subject: [RFC PATCH V3 2/5] Add function for left shift and 64 bit division Date: Fri, 3 Jun 2016 17:42:28 -0700 Message-ID: <1465000951-13343-3-git-send-email-yunhong.jiang@linux.intel.com> References: <1465000951-13343-1-git-send-email-yunhong.jiang@linux.intel.com> Cc: mtosatti@redhat.com, rkrcmar@redhat.com, pbonzini@redhat.com, kernellwp@gmail.com To: kvm@vger.kernel.org Return-path: Received: from mga02.intel.com ([134.134.136.20]:57293 "EHLO mga02.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750897AbcFDAq1 (ORCPT ); Fri, 3 Jun 2016 20:46:27 -0400 In-Reply-To: <1465000951-13343-1-git-send-email-yunhong.jiang@linux.intel.com> Sender: kvm-owner@vger.kernel.org List-ID: From: Yunhong Jiang Sometimes we need convert from guest tsc to host tsc, which is: host_tsc = ((unsigned __int128)(guest_tsc - tsc_offset) << kvm_tsc_scaling_ratio_frac_bits) / vcpu->arch.tsc_scaling_ratio; where guest_tsc and host_tsc are both 64 bit. A helper function is provided to achieve this conversion. Only supported on x86_64 platform now. A generic solution can be provided in future if needed. Signed-off-by: Yunhong Jiang --- arch/x86/include/asm/div64.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/arch/x86/include/asm/div64.h b/arch/x86/include/asm/div64.h index ced283ac79df..6937d6d4c81a 100644 --- a/arch/x86/include/asm/div64.h +++ b/arch/x86/include/asm/div64.h @@ -60,6 +60,24 @@ static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder) #define div_u64_rem div_u64_rem #else +#include +/* (a << shift) / divisor, return 1 if overflow otherwise 0 */ +static inline int u64_shl_div_u64(u64 a, unsigned int shift, + u64 divisor, u64 *result) +{ + u64 low = a << shift, high = a >> (64 - shift); + + /* To avoid the overflow on divq */ + if (high > divisor) + return 1; + + /* Low hold the result, high hold rem which is discarded */ + asm("divq %2\n\t" : "=a" (low), "=d" (high) : + "rm" (divisor), "0" (low), "1" (high)); + *result = low; + + return 0; +} # include #endif /* CONFIG_X86_32 */ -- 1.8.3.1