]> git.baikalelectronics.ru Git - kernel.git/commitdiff
Merge branch 'x86-timers-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 18 Dec 2016 21:59:10 +0000 (13:59 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 18 Dec 2016 21:59:10 +0000 (13:59 -0800)
Pull timer updates from Thomas Gleixner:
 "This is the last functional update from the tip tree for 4.10. It got
  delayed due to a newly reported and anlyzed variant of BIOS bug and
  the resulting wreckage:

   - Seperation of TSC being marked realiable and the fact that the
     platform provides the TSC frequency via CPUID/MSRs and making use
     for it for GOLDMONT.

   - TSC adjust MSR validation and sanitizing:

     The TSC adjust MSR contains the offset to the hardware counter. The
     sum of the adjust MSR and the counter is the TSC value which is
     read via RDTSC.

     On at least two machines from different vendors the BIOS sets the
     TSC adjust MSR to negative values. This happens on cold and warm
     boot. While on cold boot the offset is a few milliseconds, on warm
     boot it basically compensates the power on time of the system. The
     BIOSes are not even using the adjust MSR to set all CPUs in the
     package to the same offset. The offsets are different which renders
     the TSC unusable,

     What's worse is that the TSC deadline timer has a HW feature^Wbug.
     It malfunctions when the TSC adjust value is negative or greater
     equal 0x80000000 resulting in silent boot failures, hard lockups or
     non firing timers. This looks like some hardware internal 32/64bit
     issue with a sign extension problem. Intel has been silent so far
     on the issue.

     The update contains sanity checks and keeps the adjust register
     within working limits and in sync on the package.

     As it looks like this disease is spreading via BIOS crapware, we
     need to address this urgently as the boot failures are hard to
     debug for users"

* 'x86-timers-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/tsc: Limit the adjust value further
  x86/tsc: Annotate printouts as firmware bug
  x86/tsc: Force TSC_ADJUST register to value >= zero
  x86/tsc: Validate TSC_ADJUST after resume
  x86/tsc: Validate cpumask pointer before accessing it
  x86/tsc: Fix broken CONFIG_X86_TSC=n build
  x86/tsc: Try to adjust TSC if sync test fails
  x86/tsc: Prepare warp test for TSC adjustment
  x86/tsc: Move sync cleanup to a safe place
  x86/tsc: Sync test only for the first cpu in a package
  x86/tsc: Verify TSC_ADJUST from idle
  x86/tsc: Store and check TSC ADJUST MSR
  x86/tsc: Detect random warps
  x86/tsc: Use X86_FEATURE_TSC_ADJUST in detect_art()
  x86/tsc: Finalize the split of the TSC_RELIABLE flag
  x86/tsc: Set TSC_KNOWN_FREQ and TSC_RELIABLE flags on Intel Atom SoCs
  x86/tsc: Mark Intel ATOM_GOLDMONT TSC reliable
  x86/tsc: Mark TSC frequency determined by CPUID as known
  x86/tsc: Add X86_FEATURE_TSC_KNOWN_FREQ flag

1  2 
arch/x86/include/asm/cpufeatures.h
arch/x86/kernel/Makefile
arch/x86/kernel/process.c

index 59ac427960d4dcfdc9eb13c2a171fa33f22b79fd,7f6a5f88d5aeac0955b24801eb64b87d47839bc8..6ccbf1aaa7ce1f72021757593c99b555480f78da
  #define X86_FEATURE_EXTD_APICID       ( 3*32+26) /* has extended APICID (8 bits) */
  #define X86_FEATURE_AMD_DCM     ( 3*32+27) /* multi-node processor */
  #define X86_FEATURE_APERFMPERF        ( 3*32+28) /* APERFMPERF */
 -#define X86_FEATURE_EAGER_FPU ( 3*32+29) /* "eagerfpu" Non lazy FPU restore */
  #define X86_FEATURE_NONSTOP_TSC_S3 ( 3*32+30) /* TSC doesn't stop in S3 state */
+ #define X86_FEATURE_TSC_KNOWN_FREQ ( 3*32+31) /* TSC has known frequency */
  
  /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
  #define X86_FEATURE_XMM3      ( 4*32+ 0) /* "pni" SSE-3 */
Simple merge
index 43c36d8a6ae25b43a90610dcf3079633792f8aed,a67e0f0cdaab23f3d1890adea54203179b5347fd..37363e46b1f0beda54e6591583256c11e56cedee
@@@ -233,9 -251,40 +233,10 @@@ static inline void play_dead(void
  }
  #endif
  
 -#ifdef CONFIG_X86_64
 -void enter_idle(void)
 -{
 -      this_cpu_write(is_idle, 1);
 -      atomic_notifier_call_chain(&idle_notifier, IDLE_START, NULL);
 -}
 -
 -static void __exit_idle(void)
 -{
 -      if (x86_test_and_clear_bit_percpu(0, is_idle) == 0)
 -              return;
 -      atomic_notifier_call_chain(&idle_notifier, IDLE_END, NULL);
 -}
 -
 -/* Called from interrupts to signify idle end */
 -void exit_idle(void)
 -{
 -      /* idle loop has pid 0 */
 -      if (current->pid)
 -              return;
 -      __exit_idle();
 -}
 -#endif
 -
  void arch_cpu_idle_enter(void)
  {
+       tsc_verify_tsc_adjust(false);
        local_touch_nmi();
 -      enter_idle();
 -}
 -
 -void arch_cpu_idle_exit(void)
 -{
 -      __exit_idle();
  }
  
  void arch_cpu_idle_dead(void)