linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [GIT pull] x86/timers updates for 4.13
@ 2017-07-03  8:20 Thomas Gleixner
  2017-07-04  1:06 ` Linus Torvalds
  0 siblings, 1 reply; 3+ messages in thread
From: Thomas Gleixner @ 2017-07-03  8:20 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: LKML, Andrew Morton, Ingo Molnar, H. Peter Anvin

Linus,

please pull the latest x86-timers-for-linus git tree from:

   git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86-timers-for-linus

This update contains:

   - The final solution for the TSC deadline timer borkage, which is caused
     by a hardware problem in the TSC_ADJUST/TSC_DEADLINE_TIMER logic.

     The problem is documented now fixed with a microcode update, so we can
     remove the workaround and check for the microcode version. If the
     microcode is not up to date, then the TSC deadline timer is
     enabled. If the borkage is fixed by the proper micro code version,
     then the deadline timer can be used. In both cases the restrictions to
     the range of the TSC_ADJUST value, which were added as workarounds,
     are removed.

  - A few simple fixes and updates to the timer related x86 code.

Thanks,

	tglx

------------------>
Borislav Petkov (1):
      x86/hpet: Do not use smp_processor_id() in preemptible code

Dou Liyang (1):
      x86/time: Make setup_default_timer_irq() static

Peter Zijlstra (3):
      x86/apic: Change the lapic name in deadline mode
      x86/apic: Add TSC_DEADLINE quirk due to errata
      x86/tsc: Remove the TSC_ADJUST clamp

Zhenzhong Duan (1):
      x86/tsc: Call check_system_tsc_reliable() before unsynchronized_tsc()


 arch/x86/include/asm/setup.h |  1 -
 arch/x86/kernel/apic/apic.c  | 80 ++++++++++++++++++++++++++++++++++++++++++++
 arch/x86/kernel/hpet.c       |  2 +-
 arch/x86/kernel/time.c       |  2 +-
 arch/x86/kernel/tsc.c        |  4 +--
 arch/x86/kernel/tsc_sync.c   | 21 +-----------
 6 files changed, 85 insertions(+), 25 deletions(-)

diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h
index ac1d5da14734..e4585a393965 100644
--- a/arch/x86/include/asm/setup.h
+++ b/arch/x86/include/asm/setup.h
@@ -44,7 +44,6 @@ extern unsigned long saved_video_mode;
 
 extern void reserve_standard_io_resources(void);
 extern void i386_reserve_resources(void);
-extern void setup_default_timer_irq(void);
 
 #ifdef CONFIG_X86_INTEL_MID
 extern void x86_intel_mid_early_setup(void);
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 2d75faf743f2..3b215ff36016 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -54,6 +54,8 @@
 #include <asm/mce.h>
 #include <asm/tsc.h>
 #include <asm/hypervisor.h>
+#include <asm/cpu_device_id.h>
+#include <asm/intel-family.h>
 
 unsigned int num_processors;
 
@@ -545,6 +547,81 @@ static struct clock_event_device lapic_clockevent = {
 };
 static DEFINE_PER_CPU(struct clock_event_device, lapic_events);
 
+#define DEADLINE_MODEL_MATCH_FUNC(model, func)	\
+	{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)&func }
+
+#define DEADLINE_MODEL_MATCH_REV(model, rev)	\
+	{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)rev }
+
+static u32 hsx_deadline_rev(void)
+{
+	switch (boot_cpu_data.x86_mask) {
+	case 0x02: return 0x3a; /* EP */
+	case 0x04: return 0x0f; /* EX */
+	}
+
+	return ~0U;
+}
+
+static u32 bdx_deadline_rev(void)
+{
+	switch (boot_cpu_data.x86_mask) {
+	case 0x02: return 0x00000011;
+	case 0x03: return 0x0700000e;
+	case 0x04: return 0x0f00000c;
+	case 0x05: return 0x0e000003;
+	}
+
+	return ~0U;
+}
+
+static const struct x86_cpu_id deadline_match[] = {
+	DEADLINE_MODEL_MATCH_FUNC( INTEL_FAM6_HASWELL_X,	hsx_deadline_rev),
+	DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_BROADWELL_X,	0x0b000020),
+	DEADLINE_MODEL_MATCH_FUNC( INTEL_FAM6_BROADWELL_XEON_D,	bdx_deadline_rev),
+	DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_SKYLAKE_X,	0x02000014),
+
+	DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_HASWELL_CORE,	0x22),
+	DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_HASWELL_ULT,	0x20),
+	DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_HASWELL_GT3E,	0x17),
+
+	DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_BROADWELL_CORE,	0x25),
+	DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_BROADWELL_GT3E,	0x17),
+
+	DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_SKYLAKE_MOBILE,	0xb2),
+	DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_SKYLAKE_DESKTOP,	0xb2),
+
+	DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_KABYLAKE_MOBILE,	0x52),
+	DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_KABYLAKE_DESKTOP,	0x52),
+
+	{},
+};
+
+static void apic_check_deadline_errata(void)
+{
+	const struct x86_cpu_id *m = x86_match_cpu(deadline_match);
+	u32 rev;
+
+	if (!m)
+		return;
+
+	/*
+	 * Function pointers will have the MSB set due to address layout,
+	 * immediate revisions will not.
+	 */
+	if ((long)m->driver_data < 0)
+		rev = ((u32 (*)(void))(m->driver_data))();
+	else
+		rev = (u32)m->driver_data;
+
+	if (boot_cpu_data.microcode >= rev)
+		return;
+
+	setup_clear_cpu_cap(X86_FEATURE_TSC_DEADLINE_TIMER);
+	pr_err(FW_BUG "TSC_DEADLINE disabled due to Errata; "
+	       "please update microcode to version: 0x%x (or later)\n", rev);
+}
+
 /*
  * Setup the local APIC timer for this CPU. Copy the initialized values
  * of the boot CPU and register the clock event in the framework.
@@ -563,6 +640,7 @@ static void setup_APIC_timer(void)
 	levt->cpumask = cpumask_of(smp_processor_id());
 
 	if (this_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER)) {
+		levt->name = "lapic-deadline";
 		levt->features &= ~(CLOCK_EVT_FEAT_PERIODIC |
 				    CLOCK_EVT_FEAT_DUMMY);
 		levt->set_next_event = lapic_next_deadline;
@@ -1779,6 +1857,8 @@ void __init init_apic_mappings(void)
 {
 	unsigned int new_apicid;
 
+	apic_check_deadline_errata();
+
 	if (x2apic_mode) {
 		boot_cpu_physical_apicid = read_apic_id();
 		return;
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index 89ff7af2de50..16f82a3aaec7 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -285,7 +285,7 @@ static void hpet_legacy_clockevent_register(void)
 	 * Start hpet with the boot cpu mask and make it
 	 * global after the IO_APIC has been initialized.
 	 */
-	hpet_clockevent.cpumask = cpumask_of(smp_processor_id());
+	hpet_clockevent.cpumask = cpumask_of(boot_cpu_data.cpu_index);
 	clockevents_config_and_register(&hpet_clockevent, hpet_freq,
 					HPET_MIN_PROG_DELTA, 0x7FFFFFFF);
 	global_clock_event = &hpet_clockevent;
diff --git a/arch/x86/kernel/time.c b/arch/x86/kernel/time.c
index d39c09119db6..e0754cdbad37 100644
--- a/arch/x86/kernel/time.c
+++ b/arch/x86/kernel/time.c
@@ -66,7 +66,7 @@ static struct irqaction irq0  = {
 	.name = "timer"
 };
 
-void __init setup_default_timer_irq(void)
+static void __init setup_default_timer_irq(void)
 {
 	if (!nr_legacy_irqs())
 		return;
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 714dfba6a1e7..a316bdd42a37 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -1412,11 +1412,11 @@ void __init tsc_init(void)
 
 	use_tsc_delay();
 
+	check_system_tsc_reliable();
+
 	if (unsynchronized_tsc())
 		mark_tsc_unstable("TSCs unsynchronized");
 
-	check_system_tsc_reliable();
-
 	detect_art();
 }
 
diff --git a/arch/x86/kernel/tsc_sync.c b/arch/x86/kernel/tsc_sync.c
index 728f75378475..7842371bc9e4 100644
--- a/arch/x86/kernel/tsc_sync.c
+++ b/arch/x86/kernel/tsc_sync.c
@@ -71,13 +71,8 @@ static void tsc_sanitize_first_cpu(struct tsc_adjust *cur, s64 bootval,
 	 * non zero. We don't do that on non boot cpus because physical
 	 * hotplug should have set the ADJUST register to a value > 0 so
 	 * the TSC is in sync with the already running cpus.
-	 *
-	 * But we always force positive ADJUST values. Otherwise the TSC
-	 * deadline timer creates an interrupt storm. We also have to
-	 * prevent values > 0x7FFFFFFF as those wreckage the timer as well.
 	 */
-	if ((bootcpu && bootval != 0) || (!bootcpu && bootval < 0) ||
-	    (bootval > 0x7FFFFFFF)) {
+	if (bootcpu && bootval != 0) {
 		pr_warn(FW_BUG "TSC ADJUST: CPU%u: %lld force to 0\n", cpu,
 			bootval);
 		wrmsrl(MSR_IA32_TSC_ADJUST, 0);
@@ -451,20 +446,6 @@ void check_tsc_sync_target(void)
 	 */
 	cur->adjusted += cur_max_warp;
 
-	/*
-	 * TSC deadline timer stops working or creates an interrupt storm
-	 * with adjust values < 0 and > x07ffffff.
-	 *
-	 * To allow adjust values > 0x7FFFFFFF we need to disable the
-	 * deadline timer and use the local APIC timer, but that requires
-	 * more intrusive changes and we do not have any useful information
-	 * from Intel about the underlying HW wreckage yet.
-	 */
-	if (cur->adjusted < 0)
-		cur->adjusted = 0;
-	if (cur->adjusted > 0x7FFFFFFF)
-		cur->adjusted = 0x7FFFFFFF;
-
 	pr_warn("TSC ADJUST compensate: CPU%u observed %lld warp. Adjust: %lld\n",
 		cpu, cur_max_warp, cur->adjusted);
 

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

* Re: [GIT pull] x86/timers updates for 4.13
  2017-07-03  8:20 [GIT pull] x86/timers updates for 4.13 Thomas Gleixner
@ 2017-07-04  1:06 ` Linus Torvalds
  2017-07-04  7:27   ` Thomas Gleixner
  0 siblings, 1 reply; 3+ messages in thread
From: Linus Torvalds @ 2017-07-04  1:06 UTC (permalink / raw)
  To: Thomas Gleixner; +Cc: LKML, Andrew Morton, Ingo Molnar, H. Peter Anvin

On Mon, Jul 3, 2017 at 1:20 AM, Thomas Gleixner <tglx@linutronix.de> wrote:
>
> This update contains:
>
>    - The final solution for the TSC deadline timer borkage, which is caused
>      by a hardware problem in the TSC_ADJUST/TSC_DEADLINE_TIMER logic.
>
>      The problem is documented now fixed with a microcode update, so we can
>      remove the workaround and check for the microcode version. If the
>      microcode is not up to date, then the TSC deadline timer is
>      enabled. If the borkage is fixed by the proper micro code version,
>      then the deadline timer can be used. In both cases the restrictions to
>      the range of the TSC_ADJUST value, which were added as workarounds,
>      are removed.
>
>   - A few simple fixes and updates to the timer related x86 code.

That deadline timer explanation made no sense.

I edited it to what I think you wanted to say in the commit message.

               Linus

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

* Re: [GIT pull] x86/timers updates for 4.13
  2017-07-04  1:06 ` Linus Torvalds
@ 2017-07-04  7:27   ` Thomas Gleixner
  0 siblings, 0 replies; 3+ messages in thread
From: Thomas Gleixner @ 2017-07-04  7:27 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: LKML, Andrew Morton, Ingo Molnar, H. Peter Anvin

On Mon, 3 Jul 2017, Linus Torvalds wrote:
> On Mon, Jul 3, 2017 at 1:20 AM, Thomas Gleixner <tglx@linutronix.de> wrote:
> >
> > This update contains:
> >
> >    - The final solution for the TSC deadline timer borkage, which is caused
> >      by a hardware problem in the TSC_ADJUST/TSC_DEADLINE_TIMER logic.
> >
> >      The problem is documented now fixed with a microcode update, so we can
> >      remove the workaround and check for the microcode version. If the
> >      microcode is not up to date, then the TSC deadline timer is
> >      enabled. If the borkage is fixed by the proper micro code version,
> >      then the deadline timer can be used. In both cases the restrictions to
> >      the range of the TSC_ADJUST value, which were added as workarounds,
> >      are removed.
> >
> >   - A few simple fixes and updates to the timer related x86 code.
> 
> That deadline timer explanation made no sense.

Indeed. Sorry.

> I edited it to what I think you wanted to say in the commit message.

Yes. Thank you for fixing it up!

     tglx

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

end of thread, other threads:[~2017-07-04  7:27 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-07-03  8:20 [GIT pull] x86/timers updates for 4.13 Thomas Gleixner
2017-07-04  1:06 ` Linus Torvalds
2017-07-04  7:27   ` Thomas Gleixner

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