stable.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Daniel Drake <drake@endlessm.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	Andy Lutomirski <luto@kernel.org>, Borislav Petkov <bp@alien8.de>,
	"H . Peter Anvin" <hpa@zytor.com>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Peter Zijlstra <peterz@infradead.org>,
	len.brown@intel.com, linux@endlessm.com,
	rafael.j.wysocki@intel.com, Ingo Molnar <mingo@kernel.org>,
	Sasha Levin <sashal@kernel.org>
Subject: [PATCH AUTOSEL 5.2 013/249] x86/tsc: Use CPUID.0x16 to calculate missing crystal frequency
Date: Mon, 15 Jul 2019 09:31:54 -0400	[thread overview]
Message-ID: <20190715133550.1772-13-sashal@kernel.org> (raw)
In-Reply-To: <20190715133550.1772-1-sashal@kernel.org>

From: Daniel Drake <drake@endlessm.com>

[ Upstream commit 604dc9170f2435d27da5039a3efd757dceadc684 ]

native_calibrate_tsc() had a data mapping Intel CPU families
and crystal clock speed, but hardcoded tables are not ideal, and this
approach was already problematic at least in the Skylake X case, as
seen in commit:

  b51120309348 ("x86/tsc: Fix erroneous TSC rate on Skylake Xeon")

By examining CPUID data from http://instlatx64.atw.hu/ and units
in the lab, we have found that 3 different scenarios need to be dealt
with, and we can eliminate most of the hardcoded data using an approach a
little more advanced than before:

 1. ApolloLake, GeminiLake, CannonLake (and presumably all new chipsets
    from this point) report the crystal frequency directly via CPUID.0x15.
    That's definitive data that we can rely upon.

 2. Skylake, Kabylake and all variants of those two chipsets report a
    crystal frequency of zero, however we can calculate the crystal clock
    speed by condidering data from CPUID.0x16.

    This method correctly distinguishes between the two crystal clock
    frequencies present on different Skylake X variants that caused
    headaches before.

    As the calculations do not quite match the previously-hardcoded values
    in some cases (e.g. 23913043Hz instead of 24MHz), TSC refinement is
    enabled on all platforms where we had to calculate the crystal
    frequency in this way.

 3. Denverton (GOLDMONT_X) reports a crystal frequency of zero and does
    not support CPUID.0x16, so we leave this entry hardcoded.

Suggested-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Daniel Drake <drake@endlessm.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: len.brown@intel.com
Cc: linux@endlessm.com
Cc: rafael.j.wysocki@intel.com
Link: http://lkml.kernel.org/r/20190509055417.13152-1-drake@endlessm.com
Link: https://lkml.kernel.org/r/20190419083533.32388-1-drake@endlessm.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/x86/kernel/tsc.c | 47 +++++++++++++++++++++++++------------------
 1 file changed, 27 insertions(+), 20 deletions(-)

diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 0b29e58f288e..da029fd21460 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -632,31 +632,38 @@ unsigned long native_calibrate_tsc(void)
 
 	crystal_khz = ecx_hz / 1000;
 
-	if (crystal_khz == 0) {
-		switch (boot_cpu_data.x86_model) {
-		case INTEL_FAM6_SKYLAKE_MOBILE:
-		case INTEL_FAM6_SKYLAKE_DESKTOP:
-		case INTEL_FAM6_KABYLAKE_MOBILE:
-		case INTEL_FAM6_KABYLAKE_DESKTOP:
-			crystal_khz = 24000;	/* 24.0 MHz */
-			break;
-		case INTEL_FAM6_ATOM_GOLDMONT_X:
-			crystal_khz = 25000;	/* 25.0 MHz */
-			break;
-		case INTEL_FAM6_ATOM_GOLDMONT:
-			crystal_khz = 19200;	/* 19.2 MHz */
-			break;
-		}
-	}
+	/*
+	 * Denverton SoCs don't report crystal clock, and also don't support
+	 * CPUID.0x16 for the calculation below, so hardcode the 25MHz crystal
+	 * clock.
+	 */
+	if (crystal_khz == 0 &&
+			boot_cpu_data.x86_model == INTEL_FAM6_ATOM_GOLDMONT_X)
+		crystal_khz = 25000;
 
-	if (crystal_khz == 0)
-		return 0;
 	/*
-	 * TSC frequency determined by CPUID is a "hardware reported"
+	 * TSC frequency reported directly by CPUID is a "hardware reported"
 	 * frequency and is the most accurate one so far we have. This
 	 * is considered a known frequency.
 	 */
-	setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+	if (crystal_khz != 0)
+		setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+
+	/*
+	 * Some Intel SoCs like Skylake and Kabylake don't report the crystal
+	 * clock, but we can easily calculate it to a high degree of accuracy
+	 * by considering the crystal ratio and the CPU speed.
+	 */
+	if (crystal_khz == 0 && boot_cpu_data.cpuid_level >= 0x16) {
+		unsigned int eax_base_mhz, ebx, ecx, edx;
+
+		cpuid(0x16, &eax_base_mhz, &ebx, &ecx, &edx);
+		crystal_khz = eax_base_mhz * 1000 *
+			eax_denominator / ebx_numerator;
+	}
+
+	if (crystal_khz == 0)
+		return 0;
 
 	/*
 	 * For Atom SoCs TSC is the only reliable clocksource.
-- 
2.20.1


  parent reply	other threads:[~2019-07-15 13:36 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-07-15 13:31 [PATCH AUTOSEL 5.2 001/249] ath10k: Check tx_stats before use it Sasha Levin
2019-07-15 13:31 ` [PATCH AUTOSEL 5.2 002/249] ath10k: htt: don't use txdone_fifo with SDIO Sasha Levin
2019-07-15 13:31 ` [PATCH AUTOSEL 5.2 003/249] ath10k: fix incorrect multicast/broadcast rate setting Sasha Levin
2019-07-15 13:31 ` [PATCH AUTOSEL 5.2 004/249] ath9k: Don't trust TX status TID number when reporting airtime Sasha Levin
2019-07-15 13:31 ` [PATCH AUTOSEL 5.2 005/249] wil6210: fix potential out-of-bounds read Sasha Levin
2019-07-15 13:31 ` [PATCH AUTOSEL 5.2 006/249] ath10k: Do not send probe response template for mesh Sasha Levin
2019-07-15 13:31 ` [PATCH AUTOSEL 5.2 007/249] spi: rockchip: turn down tx dma bursts Sasha Levin
2019-07-15 13:31 ` [PATCH AUTOSEL 5.2 008/249] ath9k: Check for errors when reading SREV register Sasha Levin
2019-07-15 13:31 ` [PATCH AUTOSEL 5.2 009/249] ath10k: Fix the wrong value of enums for wmi tlv stats id Sasha Levin
2019-07-15 13:31 ` [PATCH AUTOSEL 5.2 010/249] wil6210: fix missed MISC mbox interrupt Sasha Levin
2019-07-15 13:31 ` [PATCH AUTOSEL 5.2 011/249] ath6kl: add some bounds checking Sasha Levin
2019-07-15 13:31 ` [PATCH AUTOSEL 5.2 012/249] ath10k: add peer id check in ath10k_peer_find_by_id Sasha Levin
2019-07-15 13:31 ` Sasha Levin [this message]
2019-07-15 13:31 ` [PATCH AUTOSEL 5.2 014/249] wil6210: fix spurious interrupts in 3-msi Sasha Levin
2019-07-15 13:31 ` [PATCH AUTOSEL 5.2 015/249] ath: DFS JP domain W56 fixed pulse type 3 RADAR detection Sasha Levin
2019-07-15 13:31 ` [PATCH AUTOSEL 5.2 016/249] ath10k: Fix encoding for protected management frames Sasha Levin
2019-07-15 13:31 ` [PATCH AUTOSEL 5.2 017/249] regmap: debugfs: Fix memory leak in regmap_debugfs_init Sasha Levin
2019-07-15 13:31 ` [PATCH AUTOSEL 5.2 018/249] batman-adv: fix for leaked TVLV handler Sasha Levin
2019-07-15 13:32 ` [PATCH AUTOSEL 5.2 019/249] media: dvb: usb: fix use after free in dvb_usb_device_exit Sasha Levin
2019-07-15 13:32 ` [PATCH AUTOSEL 5.2 020/249] media: spi: IR LED: add missing of table registration Sasha Levin
2019-07-15 13:32 ` [PATCH AUTOSEL 5.2 021/249] crypto: talitos - fix skcipher failure due to wrong output IV Sasha Levin
2019-07-15 13:32 ` [PATCH AUTOSEL 5.2 022/249] media: ov7740: avoid invalid framesize setting Sasha Levin
2019-07-15 13:32 ` [PATCH AUTOSEL 5.2 023/249] media: marvell-ccic: fix DMA s/g desc number calculation Sasha Levin
2019-07-15 13:32 ` [PATCH AUTOSEL 5.2 024/249] selftests/bpf: adjust verifier scale test Sasha Levin
  -- strict thread matches above, loose matches on Subject: below --
2019-07-15 13:42 [PATCH AUTOSEL 5.2 001/249] ath10k: Check tx_stats before use it Sasha Levin
2019-07-15 13:42 ` [PATCH AUTOSEL 5.2 013/249] x86/tsc: Use CPUID.0x16 to calculate missing crystal frequency Sasha Levin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190715133550.1772-13-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=bp@alien8.de \
    --cc=drake@endlessm.com \
    --cc=hpa@zytor.com \
    --cc=len.brown@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@endlessm.com \
    --cc=luto@kernel.org \
    --cc=mingo@kernel.org \
    --cc=peterz@infradead.org \
    --cc=rafael.j.wysocki@intel.com \
    --cc=stable@vger.kernel.org \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).