From: Yunhong Jiang <yunhong.jiang@xxxxxxxxx> 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 <yunhong.jiang@xxxxxxxxx> --- 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 <linux/types.h> +/* (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 <asm-generic/div64.h> #endif /* CONFIG_X86_32 */ -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html