linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] x86/tsc: Fix 32bit mode issue in get_loops_per_jiffy()
@ 2018-09-06 10:03 Chuanhua Lei
  2018-09-06 12:25 ` [tip:x86/urgent] x86/tsc: Prevent result truncation on 32bit tip-bot for Chuanhua Lei
  0 siblings, 1 reply; 2+ messages in thread
From: Chuanhua Lei @ 2018-09-06 10:03 UTC (permalink / raw)
  To: yixin.zhu, chuanhua.lei
  Cc: H. Peter Anvin, Peter Zijlstra, x86, linux-kernel,
	Thomas Gleixner, Len Brown, Pavel Tatashin, Rajvi Jingar,
	Ingo Molnar, Dou Liyang

lpj returns as zero which is not expected in 32 bit mode
After disassembling the code,
0xc1239a9e <+199>:   imul   $0x3e8,0xc12296e4,%edx
0xc1239aa8 <+209>:   xor    %ecx,%ecx
0xc1239aaa <+211>:   test   %edx,%edx
0xc1239aac <+213>:   mov    %eax,%ebx
0xc1239aae <+215>:   je     0xc1239abd <tsc_init+230>
0xc1239ab0 <+217>:   mov    $0x64,%ecx
0xc1239ab5 <+222>:   mov    %edx,%eax
0xc1239ab7 <+224>:   xor    %edx,%edx
0xc1239ab9 <+226>:   div    %ecx
0xc1239abb <+228>:   mov    %eax,%ecx
0xc1239abd <+230>:   mov    %ebx,%eax
0xc1239abf <+232>:   mov    $0x64,%ebx
0xc1239ac4 <+237>:   div    %ebx
0xc1239ac6 <+239>:   mov    %ecx,%edx

imul will load the result into %edx, %edx supposed to be high 32 bit
which is not zero. It should be zero in this case. Both lpj and tsc_khz
should be u64 to work properly for both 32 bit and 64 bit mode.

Signed-off-by: Chuanhua Lei <chuanhua.lei@linux.intel.com>
---

 arch/x86/kernel/tsc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 1463468..b346e3f 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -1415,7 +1415,7 @@ static bool __init determine_cpu_tsc_frequencies(bool early)
 
 static unsigned long __init get_loops_per_jiffy(void)
 {
-	unsigned long lpj = tsc_khz * KHZ;
+	u64 lpj = ((u64)tsc_khz * KHZ);
 
 	do_div(lpj, HZ);
 	return lpj;
-- 
2.7.5


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* [tip:x86/urgent] x86/tsc: Prevent result truncation on 32bit
  2018-09-06 10:03 [PATCH] x86/tsc: Fix 32bit mode issue in get_loops_per_jiffy() Chuanhua Lei
@ 2018-09-06 12:25 ` tip-bot for Chuanhua Lei
  0 siblings, 0 replies; 2+ messages in thread
From: tip-bot for Chuanhua Lei @ 2018-09-06 12:25 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: rajvi.jingar, peterz, linux-kernel, hpa, douly.fnst, tglx,
	chuanhua.lei, mingo, len.brown, pasha.tatashin

Commit-ID:  17f6bac2249356c795339e03a0742cd79be3cab8
Gitweb:     https://git.kernel.org/tip/17f6bac2249356c795339e03a0742cd79be3cab8
Author:     Chuanhua Lei <chuanhua.lei@linux.intel.com>
AuthorDate: Thu, 6 Sep 2018 18:03:23 +0800
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Thu, 6 Sep 2018 14:22:01 +0200

x86/tsc: Prevent result truncation on 32bit

Loops per jiffy is calculated by multiplying tsc_khz with 1e3 and then
dividing it by HZ.

Both tsc_khz and the temporary variable holding the multiplication result
are of type unsigned long, so on 32bit the result is truncated to the lower
32bit.

Use u64 as type for the temporary variable and cast tsc_khz to it before
multiplying.

[ tglx: Massaged changelog and removed pointless braces ]

Fixes: cf7a63ef4e02 ("x86/tsc: Calibrate tsc only once")
Signed-off-by: Chuanhua Lei <chuanhua.lei@linux.intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: yixin.zhu@linux.intel.com
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Len Brown <len.brown@intel.com>
Cc: Pavel Tatashin <pasha.tatashin@microsoft.com>
Cc: Rajvi Jingar <rajvi.jingar@intel.com>
Cc: Dou Liyang <douly.fnst@cn.fujitsu.com>
Link: https://lkml.kernel.org/r/1536228203-18701-1-git-send-email-chuanhua.lei@linux.intel.com

---
 arch/x86/kernel/tsc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 1463468ba9a0..6490f618e096 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -1415,7 +1415,7 @@ static bool __init determine_cpu_tsc_frequencies(bool early)
 
 static unsigned long __init get_loops_per_jiffy(void)
 {
-	unsigned long lpj = tsc_khz * KHZ;
+	u64 lpj = (u64)tsc_khz * KHZ;
 
 	do_div(lpj, HZ);
 	return lpj;

^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2018-09-06 12:25 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-06 10:03 [PATCH] x86/tsc: Fix 32bit mode issue in get_loops_per_jiffy() Chuanhua Lei
2018-09-06 12:25 ` [tip:x86/urgent] x86/tsc: Prevent result truncation on 32bit tip-bot for Chuanhua Lei

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).