Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755693AbcJTWrQ (ORCPT ); Thu, 20 Oct 2016 18:47:16 -0400 Received: from 67-148-5-81.dia.static.qwest.net ([67.148.5.81]:1904 "EHLO amakhalov-virtual-machine" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753107AbcJTWrN (ORCPT ); Thu, 20 Oct 2016 18:47:13 -0400 X-Greylist: delayed 1292 seconds by postgrey-1.27 at vger.kernel.org; Thu, 20 Oct 2016 18:47:13 EDT Date: Wed, 19 Oct 2016 22:02:11 -0700 From: Alexey Makhalov To: Alok Kataria , Thomas Gleixner , Ingo Molnar , "H. Peter Anvin" , x86@kernel.org, virtualization@lists.linux-foundation.org, linux-kernel@vger.kernel.org Subject: [PATCH] x86/vmware: Read tsc_khz only once - at boot time Message-ID: <20161020050211.GA25304@amakhalov-virtual-machine> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2124 Lines: 77 Re-factor the vmware platform setup code to query the hypervisor for tsc frequency only once during boot. Since the VMware hypervisor guarantees constant TSC, calibrate_tsc now uses the saved value. Signed-off-by: Alexey Makhalov Acked-by: Alok N Kataria --- arch/x86/kernel/cpu/vmware.c | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c index 5130985..46c7b9d 100644 --- a/arch/x86/kernel/cpu/vmware.c +++ b/arch/x86/kernel/cpu/vmware.c @@ -48,6 +48,8 @@ "2"(VMWARE_HYPERVISOR_PORT), "3"(UINT_MAX) : \ "memory"); +static unsigned long vmware_tsc_khz __ro_after_init; + static inline int __vmware_platform(void) { uint32_t eax, ebx, ecx, edx; @@ -57,35 +59,32 @@ static inline int __vmware_platform(void) static unsigned long vmware_get_tsc_khz(void) { - uint64_t tsc_hz, lpj; - uint32_t eax, ebx, ecx, edx; - - VMWARE_PORT(GETHZ, eax, ebx, ecx, edx); - - tsc_hz = eax | (((uint64_t)ebx) << 32); - do_div(tsc_hz, 1000); - BUG_ON(tsc_hz >> 32); - pr_info("TSC freq read from hypervisor : %lu.%03lu MHz\n", - (unsigned long) tsc_hz / 1000, - (unsigned long) tsc_hz % 1000); - - if (!preset_lpj) { - lpj = ((u64)tsc_hz * 1000); - do_div(lpj, HZ); - preset_lpj = lpj; - } - - return tsc_hz; + return vmware_tsc_khz; } static void __init vmware_platform_setup(void) { uint32_t eax, ebx, ecx, edx; + uint64_t lpj, tsc_khz; VMWARE_PORT(GETHZ, eax, ebx, ecx, edx); if (ebx != UINT_MAX) { + lpj = tsc_khz = eax | (((uint64_t)ebx) << 32); + do_div(tsc_khz, 1000); + WARN_ON(tsc_khz >> 32); + pr_info("TSC freq read from hypervisor : %lu.%03lu MHz\n", + (unsigned long) tsc_khz / 1000, + (unsigned long) tsc_khz % 1000); + + if (!preset_lpj) { + do_div(lpj, HZ); + preset_lpj = lpj; + } + + vmware_tsc_khz = tsc_khz; x86_platform.calibrate_tsc = vmware_get_tsc_khz; + #ifdef CONFIG_X86_LOCAL_APIC /* Skip lapic calibration since we know the bus frequency. */ lapic_timer_frequency = ecx / HZ; -- 1.9.1