Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 11 Apr 2014 18:58:33 +0000 (11:58 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 11 Apr 2014 18:58:33 +0000 (11:58 -0700)
Pull x86 fixes from Peter Anvin:
 "This is a collection of minor fixes for x86, plus the IRET information
  leak fix (forbid the use of 16-bit segments in 64-bit mode)"

NOTE! We may have to relax the "forbid the use of 16-bit segments in
64-bit mode" part, since there may be people who still run and depend on
16-bit Windows binaries under Wine.

But I'm taking this in the current unconditional form for now to see who
(if anybody) screams bloody murder.  Maybe nobody cares.  And maybe
we'll have to update it with some kind of runtime enablement (like our
vm.mmap_min_addr tunable that people who run dosemu/qemu/wine already
need to tweak).

* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86-64, modify_ldt: Ban 16-bit segments on 64-bit kernels
  efi: Pass correct file handle to efi_file_{read,close}
  x86/efi: Correct EFI boot stub use of code32_start
  x86/efi: Fix boot failure with EFI stub
  x86/platform/hyperv: Handle VMBUS driver being a module
  x86/apic: Reinstate error IRQ Pentium erratum 3AP workaround
  x86, CMCI: Add proper detection of end of CMCI storms

1  2 
arch/x86/kernel/apic/apic.c
arch/x86/kernel/cpu/mcheck/mce.c

index 481ae38f6a44f5ac240fdd39b06f8708f66522d5,005ed3fb03917bdd02b58cbdd0517f02fcb3d20e..ad28db7e6bdea3594a4bfad1d70d0c975ded7021
@@@ -1996,7 -1996,8 +1996,8 @@@ static inline void __smp_error_interrup
        };
  
        /* First tickle the hardware, only then report what went on. -- REW */
-       apic_write(APIC_ESR, 0);
+       if (lapic_get_maxlvt() > 3)     /* Due to the Pentium erratum 3AP. */
+               apic_write(APIC_ESR, 0);
        v = apic_read(APIC_ESR);
        ack_APIC_irq();
        atomic_inc(&irq_err_count);
@@@ -2136,6 -2137,7 +2137,6 @@@ int generic_processor_info(int apicid, 
         *
         * - arch/x86/kernel/mpparse.c: MP_processor_info()
         * - arch/x86/mm/amdtopology.c: amd_numa_init()
 -       * - arch/x86/platform/visws/visws_quirks.c: MP_processor_info()
         *
         * This function is executed with the modified
         * boot_cpu_physical_apicid. So, disabled_cpu_apicid kernel
index 9b7734b1f975a4c0cfc9776749aecc83ace1cd10,78c92125db8afef99a2f8cb9f75352e97f45d4b2..eeee23ff75ef8ddb28a002d26b5bee98b21e03ca
@@@ -89,6 -89,9 +89,9 @@@ static DECLARE_WAIT_QUEUE_HEAD(mce_chrd
  static DEFINE_PER_CPU(struct mce, mces_seen);
  static int                    cpu_missing;
  
+ /* CMCI storm detection filter */
+ static DEFINE_PER_CPU(unsigned long, mce_polled_error);
  /*
   * MCA banks polled by the period polling timer for corrected events.
   * With Intel CMCI, this only has MCA banks which do not support CMCI (if any).
@@@ -595,6 -598,7 +598,7 @@@ void machine_check_poll(enum mcp_flags 
  {
        struct mce m;
        int i;
+       unsigned long *v;
  
        this_cpu_inc(mce_poll_count);
  
                if (!(m.status & MCI_STATUS_VAL))
                        continue;
  
+               v = &get_cpu_var(mce_polled_error);
+               set_bit(0, v);
                /*
                 * Uncorrected or signalled events are handled by the exception
                 * handler when it is enabled, so don't process those here.
@@@ -1278,10 -1284,18 +1284,18 @@@ static unsigned long mce_adjust_timer_d
  static unsigned long (*mce_adjust_timer)(unsigned long interval) =
        mce_adjust_timer_default;
  
+ static int cmc_error_seen(void)
+ {
+       unsigned long *v = &__get_cpu_var(mce_polled_error);
+       return test_and_clear_bit(0, v);
+ }
  static void mce_timer_fn(unsigned long data)
  {
        struct timer_list *t = &__get_cpu_var(mce_timer);
        unsigned long iv;
+       int notify;
  
        WARN_ON(smp_processor_id() != data);
  
         * polling interval, otherwise increase the polling interval.
         */
        iv = __this_cpu_read(mce_next_interval);
-       if (mce_notify_irq()) {
+       notify = mce_notify_irq();
+       notify |= cmc_error_seen();
+       if (notify) {
                iv = max(iv / 2, (unsigned long) HZ/100);
        } else {
                iv = min(iv * 2, round_jiffies_relative(check_interval * HZ));
@@@ -2434,18 -2450,14 +2450,18 @@@ static __init int mcheck_init_device(vo
        if (err)
                return err;
  
 +      cpu_notifier_register_begin();
        for_each_online_cpu(i) {
                err = mce_device_create(i);
 -              if (err)
 +              if (err) {
 +                      cpu_notifier_register_done();
                        return err;
 +              }
        }
  
        register_syscore_ops(&mce_syscore_ops);
 -      register_hotcpu_notifier(&mce_cpu_notifier);
 +      __register_hotcpu_notifier(&mce_cpu_notifier);
 +      cpu_notifier_register_done();
  
        /* register character device /dev/mcelog */
        misc_register(&mce_chrdev_device);