Merge branch 'x86/ras' into x86/core, to fix conflicts
authorIngo Molnar <mingo@kernel.org>
Sun, 7 Jun 2015 13:35:27 +0000 (15:35 +0200)
committerIngo Molnar <mingo@kernel.org>
Sun, 7 Jun 2015 13:35:27 +0000 (15:35 +0200)
Conflicts:
arch/x86/include/asm/irq_vectors.h

Signed-off-by: Ingo Molnar <mingo@kernel.org>
1  2 
arch/x86/include/asm/entry_arch.h
arch/x86/include/asm/hardirq.h
arch/x86/include/asm/hw_irq.h
arch/x86/include/asm/irq_vectors.h
arch/x86/include/uapi/asm/msr-index.h
arch/x86/kernel/cpu/mcheck/mce.c
arch/x86/kernel/entry_64.S
arch/x86/kernel/irq.c
arch/x86/kernel/irqinit.c
arch/x86/kernel/traps.c

index 27ca0afcccd747ebbac51b0fe2c4c2700bc47c2b,6da46dbaac8798d2d179b6ac3c7cbf32f32307ec..df002992d8fd3dffa9d9d0913e823ae52f9e2256
@@@ -23,8 -23,6 +23,8 @@@ BUILD_INTERRUPT(x86_platform_ipi, X86_P
  #ifdef CONFIG_HAVE_KVM
  BUILD_INTERRUPT3(kvm_posted_intr_ipi, POSTED_INTR_VECTOR,
                 smp_kvm_posted_intr_ipi)
 +BUILD_INTERRUPT3(kvm_posted_intr_wakeup_ipi, POSTED_INTR_WAKEUP_VECTOR,
 +               smp_kvm_posted_intr_wakeup_ipi)
  #endif
  
  /*
@@@ -52,4 -50,7 +52,7 @@@ BUILD_INTERRUPT(thermal_interrupt,THERM
  BUILD_INTERRUPT(threshold_interrupt,THRESHOLD_APIC_VECTOR)
  #endif
  
+ #ifdef CONFIG_X86_MCE_AMD
+ BUILD_INTERRUPT(deferred_error_interrupt, DEFERRED_ERROR_VECTOR)
+ #endif
  #endif
index 98660653939537a7e6a594e5d52666f11671ef92,db9f536f482f5fcf58923e4b00e35aa2f7673267..7178043b0e1dd69d20a6ff5ddaa37ee6c32841f8
@@@ -14,7 -14,6 +14,7 @@@ typedef struct 
  #endif
  #ifdef CONFIG_HAVE_KVM
        unsigned int kvm_posted_intr_ipis;
 +      unsigned int kvm_posted_intr_wakeup_ipis;
  #endif
        unsigned int x86_platform_ipis; /* arch dependent */
        unsigned int apic_perf_irqs;
@@@ -34,6 -33,9 +34,9 @@@
  #ifdef CONFIG_X86_MCE_THRESHOLD
        unsigned int irq_threshold_count;
  #endif
+ #ifdef CONFIG_X86_MCE_AMD
+       unsigned int irq_deferred_error_count;
+ #endif
  #if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN)
        unsigned int irq_hv_callback_count;
  #endif
index 10c80d4f8386bacd3809ded146bec92539832438,f71e489d75379a0cab19161db3b5239bfc6245a0..6615032e19c80b79f3cd023ee291c790bcb07ae2
@@@ -29,7 -29,6 +29,7 @@@
  extern asmlinkage void apic_timer_interrupt(void);
  extern asmlinkage void x86_platform_ipi(void);
  extern asmlinkage void kvm_posted_intr_ipi(void);
 +extern asmlinkage void kvm_posted_intr_wakeup_ipi(void);
  extern asmlinkage void error_interrupt(void);
  extern asmlinkage void irq_work_interrupt(void);
  
@@@ -37,9 -36,44 +37,10 @@@ extern asmlinkage void spurious_interru
  extern asmlinkage void thermal_interrupt(void);
  extern asmlinkage void reschedule_interrupt(void);
  
 -extern asmlinkage void invalidate_interrupt(void);
 -extern asmlinkage void invalidate_interrupt0(void);
 -extern asmlinkage void invalidate_interrupt1(void);
 -extern asmlinkage void invalidate_interrupt2(void);
 -extern asmlinkage void invalidate_interrupt3(void);
 -extern asmlinkage void invalidate_interrupt4(void);
 -extern asmlinkage void invalidate_interrupt5(void);
 -extern asmlinkage void invalidate_interrupt6(void);
 -extern asmlinkage void invalidate_interrupt7(void);
 -extern asmlinkage void invalidate_interrupt8(void);
 -extern asmlinkage void invalidate_interrupt9(void);
 -extern asmlinkage void invalidate_interrupt10(void);
 -extern asmlinkage void invalidate_interrupt11(void);
 -extern asmlinkage void invalidate_interrupt12(void);
 -extern asmlinkage void invalidate_interrupt13(void);
 -extern asmlinkage void invalidate_interrupt14(void);
 -extern asmlinkage void invalidate_interrupt15(void);
 -extern asmlinkage void invalidate_interrupt16(void);
 -extern asmlinkage void invalidate_interrupt17(void);
 -extern asmlinkage void invalidate_interrupt18(void);
 -extern asmlinkage void invalidate_interrupt19(void);
 -extern asmlinkage void invalidate_interrupt20(void);
 -extern asmlinkage void invalidate_interrupt21(void);
 -extern asmlinkage void invalidate_interrupt22(void);
 -extern asmlinkage void invalidate_interrupt23(void);
 -extern asmlinkage void invalidate_interrupt24(void);
 -extern asmlinkage void invalidate_interrupt25(void);
 -extern asmlinkage void invalidate_interrupt26(void);
 -extern asmlinkage void invalidate_interrupt27(void);
 -extern asmlinkage void invalidate_interrupt28(void);
 -extern asmlinkage void invalidate_interrupt29(void);
 -extern asmlinkage void invalidate_interrupt30(void);
 -extern asmlinkage void invalidate_interrupt31(void);
 -
  extern asmlinkage void irq_move_cleanup_interrupt(void);
  extern asmlinkage void reboot_interrupt(void);
  extern asmlinkage void threshold_interrupt(void);
+ extern asmlinkage void deferred_error_interrupt(void);
  
  extern asmlinkage void call_function_interrupt(void);
  extern asmlinkage void call_function_single_interrupt(void);
@@@ -54,92 -88,61 +55,93 @@@ extern void trace_spurious_interrupt(vo
  extern void trace_thermal_interrupt(void);
  extern void trace_reschedule_interrupt(void);
  extern void trace_threshold_interrupt(void);
+ extern void trace_deferred_error_interrupt(void);
  extern void trace_call_function_interrupt(void);
  extern void trace_call_function_single_interrupt(void);
  #define trace_irq_move_cleanup_interrupt  irq_move_cleanup_interrupt
  #define trace_reboot_interrupt  reboot_interrupt
  #define trace_kvm_posted_intr_ipi kvm_posted_intr_ipi
 +#define trace_kvm_posted_intr_wakeup_ipi kvm_posted_intr_wakeup_ipi
  #endif /* CONFIG_TRACING */
  
 -#ifdef CONFIG_IRQ_REMAP
 -/* Intel specific interrupt remapping information */
 -struct irq_2_iommu {
 -      struct intel_iommu *iommu;
 -      u16 irte_index;
 -      u16 sub_handle;
 -      u8  irte_mask;
 -};
 -
 -/* AMD specific interrupt remapping information */
 -struct irq_2_irte {
 -      u16 devid; /* Device ID for IRTE table */
 -      u16 index; /* Index into IRTE table*/
 -};
 -#endif        /* CONFIG_IRQ_REMAP */
 -
  #ifdef        CONFIG_X86_LOCAL_APIC
  struct irq_data;
 +struct pci_dev;
 +struct msi_desc;
 +
 +enum irq_alloc_type {
 +      X86_IRQ_ALLOC_TYPE_IOAPIC = 1,
 +      X86_IRQ_ALLOC_TYPE_HPET,
 +      X86_IRQ_ALLOC_TYPE_MSI,
 +      X86_IRQ_ALLOC_TYPE_MSIX,
 +      X86_IRQ_ALLOC_TYPE_DMAR,
 +      X86_IRQ_ALLOC_TYPE_UV,
 +};
  
 -struct irq_cfg {
 -      cpumask_var_t           domain;
 -      cpumask_var_t           old_domain;
 -      u8                      vector;
 -      u8                      move_in_progress : 1;
 -#ifdef CONFIG_IRQ_REMAP
 -      u8                      remapped : 1;
 +struct irq_alloc_info {
 +      enum irq_alloc_type     type;
 +      u32                     flags;
 +      const struct cpumask    *mask;  /* CPU mask for vector allocation */
        union {
 -              struct irq_2_iommu irq_2_iommu;
 -              struct irq_2_irte  irq_2_irte;
 -      };
 +              int             unused;
 +#ifdef        CONFIG_HPET_TIMER
 +              struct {
 +                      int             hpet_id;
 +                      int             hpet_index;
 +                      void            *hpet_data;
 +              };
  #endif
 -      union {
 -#ifdef CONFIG_X86_IO_APIC
 +#ifdef        CONFIG_PCI_MSI
                struct {
 -                      struct list_head        irq_2_pin;
 +                      struct pci_dev  *msi_dev;
 +                      irq_hw_number_t msi_hwirq;
 +              };
 +#endif
 +#ifdef        CONFIG_X86_IO_APIC
 +              struct {
 +                      int             ioapic_id;
 +                      int             ioapic_pin;
 +                      int             ioapic_node;
 +                      u32             ioapic_trigger : 1;
 +                      u32             ioapic_polarity : 1;
 +                      u32             ioapic_valid : 1;
 +                      struct IO_APIC_route_entry *ioapic_entry;
 +              };
 +#endif
 +#ifdef        CONFIG_DMAR_TABLE
 +              struct {
 +                      int             dmar_id;
 +                      void            *dmar_data;
 +              };
 +#endif
 +#ifdef        CONFIG_HT_IRQ
 +              struct {
 +                      int             ht_pos;
 +                      int             ht_idx;
 +                      struct pci_dev  *ht_dev;
 +                      void            *ht_update;
 +              };
 +#endif
 +#ifdef        CONFIG_X86_UV
 +              struct {
 +                      int             uv_limit;
 +                      int             uv_blade;
 +                      unsigned long   uv_offset;
 +                      char            *uv_name;
                };
  #endif
        };
  };
  
 +struct irq_cfg {
 +      unsigned int            dest_apicid;
 +      u8                      vector;
 +};
 +
  extern struct irq_cfg *irq_cfg(unsigned int irq);
  extern struct irq_cfg *irqd_cfg(struct irq_data *irq_data);
 -extern struct irq_cfg *alloc_irq_and_cfg_at(unsigned int at, int node);
  extern void lock_vector_lock(void);
  extern void unlock_vector_lock(void);
 -extern int assign_irq_vector(int, struct irq_cfg *, const struct cpumask *);
 -extern void clear_irq_vector(int irq, struct irq_cfg *cfg);
  extern void setup_vector_irq(int cpu);
  #ifdef CONFIG_SMP
  extern void send_cleanup_vector(struct irq_cfg *);
@@@ -149,7 -152,10 +151,7 @@@ static inline void send_cleanup_vector(
  static inline void irq_complete_move(struct irq_cfg *c) { }
  #endif
  
 -extern int apic_retrigger_irq(struct irq_data *data);
  extern void apic_ack_edge(struct irq_data *data);
 -extern int apic_set_affinity(struct irq_data *data, const struct cpumask *mask,
 -                           unsigned int *dest_id);
  #else /*  CONFIG_X86_LOCAL_APIC */
  static inline void lock_vector_lock(void) {}
  static inline void unlock_vector_lock(void) {}
  extern atomic_t irq_err_count;
  extern atomic_t irq_mis_count;
  
 -/* EISA */
 -extern void eisa_set_level_irq(unsigned int irq);
 +extern void elcr_set_level_irq(unsigned int irq);
  
  /* SMP */
  extern __visible void smp_apic_timer_interrupt(struct pt_regs *);
@@@ -173,6 -180,7 +175,6 @@@ extern asmlinkage void smp_irq_move_cle
  extern __visible void smp_reschedule_interrupt(struct pt_regs *);
  extern __visible void smp_call_function_interrupt(struct pt_regs *);
  extern __visible void smp_call_function_single_interrupt(struct pt_regs *);
 -extern __visible void smp_invalidate_interrupt(struct pt_regs *);
  #endif
  
  extern char irq_entries_start[];
index 0ed29ac13a9dd446ed1db20d7abeb642b3b6bf2b,8900ba444ad7dc1eb8c6178ad02f1b1561174cba..4c2d2eb2060a0b4b74d71bae834e49e51e777cff
  #define IRQ_MOVE_CLEANUP_VECTOR               FIRST_EXTERNAL_VECTOR
  
  #define IA32_SYSCALL_VECTOR           0x80
 -#ifdef CONFIG_X86_32
 -# define SYSCALL_VECTOR                       0x80
 -#endif
  
  /*
   * Vectors 0x30-0x3f are used for ISA interrupts.
   *   round up to the next 16-vector boundary
   */
 -#define IRQ0_VECTOR                   ((FIRST_EXTERNAL_VECTOR + 16) & ~15)
 -
 -#define IRQ1_VECTOR                   (IRQ0_VECTOR +  1)
 -#define IRQ2_VECTOR                   (IRQ0_VECTOR +  2)
 -#define IRQ3_VECTOR                   (IRQ0_VECTOR +  3)
 -#define IRQ4_VECTOR                   (IRQ0_VECTOR +  4)
 -#define IRQ5_VECTOR                   (IRQ0_VECTOR +  5)
 -#define IRQ6_VECTOR                   (IRQ0_VECTOR +  6)
 -#define IRQ7_VECTOR                   (IRQ0_VECTOR +  7)
 -#define IRQ8_VECTOR                   (IRQ0_VECTOR +  8)
 -#define IRQ9_VECTOR                   (IRQ0_VECTOR +  9)
 -#define IRQ10_VECTOR                  (IRQ0_VECTOR + 10)
 -#define IRQ11_VECTOR                  (IRQ0_VECTOR + 11)
 -#define IRQ12_VECTOR                  (IRQ0_VECTOR + 12)
 -#define IRQ13_VECTOR                  (IRQ0_VECTOR + 13)
 -#define IRQ14_VECTOR                  (IRQ0_VECTOR + 14)
 -#define IRQ15_VECTOR                  (IRQ0_VECTOR + 15)
 +#define ISA_IRQ_VECTOR(irq)           (((FIRST_EXTERNAL_VECTOR + 16) & ~15) + irq)
  
  /*
   * Special IRQ vectors used by the SMP architecture, 0xf0-0xff
   */
  #define X86_PLATFORM_IPI_VECTOR               0xf7
  
- /* Vector for KVM to deliver posted interrupt IPI */
- #ifdef CONFIG_HAVE_KVM
- #define POSTED_INTR_VECTOR            0xf2
 +#define POSTED_INTR_WAKEUP_VECTOR     0xf1
- #endif
  /*
   * IRQ work vector:
   */
  #define IRQ_WORK_VECTOR                       0xf6
  
  #define UV_BAU_MESSAGE                        0xf5
+ #define DEFERRED_ERROR_VECTOR         0xf4
  
  /* Vector on which hypervisor callbacks will be delivered */
  #define HYPERVISOR_CALLBACK_VECTOR    0xf3
  
+ /* Vector for KVM to deliver posted interrupt IPI */
+ #ifdef CONFIG_HAVE_KVM
+ #define POSTED_INTR_VECTOR            0xf2
+ #endif
  /*
   * Local APIC timer IRQ vector is on a different priority level,
   * to work around the 'lost local interrupt if more than 2 IRQ
@@@ -137,22 -156,18 +138,22 @@@ static inline int invalid_vm86_irq(int 
   * static arrays.
   */
  
 -#define NR_IRQS_LEGACY                          16
 +#define NR_IRQS_LEGACY                        16
  
 -#define IO_APIC_VECTOR_LIMIT          ( 32 * MAX_IO_APICS )
 +#define CPU_VECTOR_LIMIT              (64 * NR_CPUS)
 +#define IO_APIC_VECTOR_LIMIT          (32 * MAX_IO_APICS)
  
 -#ifdef CONFIG_X86_IO_APIC
 -# define CPU_VECTOR_LIMIT             (64 * NR_CPUS)
 -# define NR_IRQS                                      \
 +#if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_PCI_MSI)
 +#define NR_IRQS                                               \
        (CPU_VECTOR_LIMIT > IO_APIC_VECTOR_LIMIT ?      \
                (NR_VECTORS + CPU_VECTOR_LIMIT)  :      \
                (NR_VECTORS + IO_APIC_VECTOR_LIMIT))
 -#else /* !CONFIG_X86_IO_APIC: */
 -# define NR_IRQS                      NR_IRQS_LEGACY
 +#elif defined(CONFIG_X86_IO_APIC)
 +#define       NR_IRQS                         (NR_VECTORS + IO_APIC_VECTOR_LIMIT)
 +#elif defined(CONFIG_PCI_MSI)
 +#define NR_IRQS                               (NR_VECTORS + CPU_VECTOR_LIMIT)
 +#else
 +#define NR_IRQS                               NR_IRQS_LEGACY
  #endif
  
  #endif /* _ASM_X86_IRQ_VECTORS_H */
index 3c6bb342a48f1ad123ba82261c517c18266227b6,32c69d5fbeacbb83625bce6822b2ab25d00fba55..9ebc3d0093736bcc2e62646a89fbac1f75c878d7
@@@ -56,6 -56,7 +56,7 @@@
  #define MSR_IA32_MCG_CAP              0x00000179
  #define MSR_IA32_MCG_STATUS           0x0000017a
  #define MSR_IA32_MCG_CTL              0x0000017b
+ #define MSR_IA32_MCG_EXT_CTL          0x000004d0
  
  #define MSR_OFFCORE_RSP_0             0x000001a6
  #define MSR_OFFCORE_RSP_1             0x000001a7
  #define MSR_CORE_C3_RESIDENCY         0x000003fc
  #define MSR_CORE_C6_RESIDENCY         0x000003fd
  #define MSR_CORE_C7_RESIDENCY         0x000003fe
 +#define MSR_KNL_CORE_C6_RESIDENCY     0x000003ff
  #define MSR_PKG_C2_RESIDENCY          0x0000060d
  #define MSR_PKG_C8_RESIDENCY          0x00000630
  #define MSR_PKG_C9_RESIDENCY          0x00000631
  #define FEATURE_CONTROL_LOCKED                                (1<<0)
  #define FEATURE_CONTROL_VMXON_ENABLED_INSIDE_SMX      (1<<1)
  #define FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX     (1<<2)
+ #define FEATURE_CONTROL_LMCE                          (1<<20)
  
  #define MSR_IA32_APICBASE             0x0000001b
  #define MSR_IA32_APICBASE_BSP         (1<<8)
index 20190bdac9d58ecabddd3cbe6692d0f52bb687ad,ddc46d67d93e9cff9c2100d108ca259f74340d8a..5b974c97e31e77766ee7fbf7bbf524c5e82d915d
@@@ -708,7 -708,6 +708,7 @@@ static int mce_no_way_out(struct mce *m
                          struct pt_regs *regs)
  {
        int i, ret = 0;
 +      char *tmp;
  
        for (i = 0; i < mca_cfg.banks; i++) {
                m->status = mce_rdmsrl(MSR_IA32_MCx_STATUS(i));
                        if (quirk_no_way_out)
                                quirk_no_way_out(i, m, regs);
                }
 -              if (mce_severity(m, mca_cfg.tolerant, msg, true) >=
 -                  MCE_PANIC_SEVERITY)
 +
 +              if (mce_severity(m, mca_cfg.tolerant, &tmp, true) >= MCE_PANIC_SEVERITY) {
 +                      *msg = tmp;
                        ret = 1;
 +              }
        }
        return ret;
  }
@@@ -1050,6 -1047,7 +1050,7 @@@ void do_machine_check(struct pt_regs *r
        char *msg = "Unknown";
        u64 recover_paddr = ~0ull;
        int flags = MF_ACTION_REQUIRED;
+       int lmce = 0;
  
        prev_state = ist_enter(regs);
  
                kill_it = 1;
  
        /*
-        * Go through all the banks in exclusion of the other CPUs.
-        * This way we don't report duplicated events on shared banks
-        * because the first one to see it will clear it.
+        * Check if this MCE is signaled to only this logical processor
         */
-       order = mce_start(&no_way_out);
+       if (m.mcgstatus & MCG_STATUS_LMCES)
+               lmce = 1;
+       else {
+               /*
+                * Go through all the banks in exclusion of the other CPUs.
+                * This way we don't report duplicated events on shared banks
+                * because the first one to see it will clear it.
+                * If this is a Local MCE, then no need to perform rendezvous.
+                */
+               order = mce_start(&no_way_out);
+       }
        for (i = 0; i < cfg->banks; i++) {
                __clear_bit(i, toclear);
                if (!test_bit(i, valid_banks))
         * Do most of the synchronization with other CPUs.
         * When there's any problem use only local no_way_out state.
         */
-       if (mce_end(order) < 0)
-               no_way_out = worst >= MCE_PANIC_SEVERITY;
+       if (!lmce) {
+               if (mce_end(order) < 0)
+                       no_way_out = worst >= MCE_PANIC_SEVERITY;
+       } else {
+               /*
+                * Local MCE skipped calling mce_reign()
+                * If we found a fatal error, we need to panic here.
+                */
+                if (worst >= MCE_PANIC_SEVERITY && mca_cfg.tolerant < 3)
+                       mce_panic("Machine check from unknown source",
+                               NULL, NULL);
+       }
  
        /*
         * At insane "tolerant" levels we take no action. Otherwise
@@@ -1640,10 -1657,16 +1660,16 @@@ static void __mcheck_cpu_init_vendor(st
                mce_intel_feature_init(c);
                mce_adjust_timer = cmci_intel_adjust_timer;
                break;
-       case X86_VENDOR_AMD:
+       case X86_VENDOR_AMD: {
+               u32 ebx = cpuid_ebx(0x80000007);
                mce_amd_feature_init(c);
-               mce_flags.overflow_recov = cpuid_ebx(0x80000007) & 0x1;
+               mce_flags.overflow_recov = !!(ebx & BIT(0));
+               mce_flags.succor         = !!(ebx & BIT(1));
                break;
+               }
        default:
                break;
        }
@@@ -1979,6 -2002,7 +2005,7 @@@ void mce_disable_bank(int bank
  /*
   * mce=off Disables machine check
   * mce=no_cmci Disables CMCI
+  * mce=no_lmce Disables LMCE
   * mce=dont_log_ce Clears corrected events silently, no log created for CEs.
   * mce=ignore_ce Disables polling and CMCI, corrected events are not cleared.
   * mce=TOLERANCELEVEL[,monarchtimeout] (number, see above)
@@@ -2002,6 -2026,8 +2029,8 @@@ static int __init mcheck_enable(char *s
                cfg->disabled = true;
        else if (!strcmp(str, "no_cmci"))
                cfg->cmci_disabled = true;
+       else if (!strcmp(str, "no_lmce"))
+               cfg->lmce_disabled = true;
        else if (!strcmp(str, "dont_log_ce"))
                cfg->dont_log_ce = true;
        else if (!strcmp(str, "ignore_ce"))
        else if (!strcmp(str, "bios_cmci_threshold"))
                cfg->bios_cmci_threshold = true;
        else if (isdigit(str[0])) {
-               get_option(&str, &(cfg->tolerant));
-               if (*str == ',') {
-                       ++str;
+               if (get_option(&str, &cfg->tolerant) == 2)
                        get_option(&str, &(cfg->monarch_timeout));
-               }
        } else {
                pr_info("mce argument %s ignored. Please use /sys\n", str);
                return 0;
index 22aadc917868ea3c4e0e62af16501aa576ed13aa,12aea85fe738bf3fab7a58f670a2eb4ddbdb3ec6..0395a59f67c4a645e718a89d3368eb4a50edcd61
@@@ -216,7 -216,7 +216,7 @@@ ENTRY(system_call
  GLOBAL(system_call_after_swapgs)
  
        movq    %rsp,PER_CPU_VAR(rsp_scratch)
 -      movq    PER_CPU_VAR(kernel_stack),%rsp
 +      movq    PER_CPU_VAR(cpu_current_top_of_stack),%rsp
  
        /* Construct struct pt_regs on stack */
        pushq_cfi $__USER_DS                    /* pt_regs->ss */
@@@ -419,27 -419,26 +419,27 @@@ syscall_return
         * a completely clean 64-bit userspace context.
         */
        movq RCX(%rsp),%rcx
 -      cmpq %rcx,RIP(%rsp)             /* RCX == RIP */
 +      movq RIP(%rsp),%r11
 +      cmpq %rcx,%r11                  /* RCX == RIP */
        jne opportunistic_sysret_failed
  
        /*
         * On Intel CPUs, SYSRET with non-canonical RCX/RIP will #GP
         * in kernel space.  This essentially lets the user take over
 -       * the kernel, since userspace controls RSP.  It's not worth
 -       * testing for canonicalness exactly -- this check detects any
 -       * of the 17 high bits set, which is true for non-canonical
 -       * or kernel addresses.  (This will pessimize vsyscall=native.
 -       * Big deal.)
 +       * the kernel, since userspace controls RSP.
         *
 -       * If virtual addresses ever become wider, this will need
 +       * If width of "canonical tail" ever becomes variable, this will need
         * to be updated to remain correct on both old and new CPUs.
         */
        .ifne __VIRTUAL_MASK_SHIFT - 47
        .error "virtual address width changed -- SYSRET checks need update"
        .endif
 -      shr $__VIRTUAL_MASK_SHIFT, %rcx
 -      jnz opportunistic_sysret_failed
 +      /* Change top 16 bits to be the sign-extension of 47th bit */
 +      shl     $(64 - (__VIRTUAL_MASK_SHIFT+1)), %rcx
 +      sar     $(64 - (__VIRTUAL_MASK_SHIFT+1)), %rcx
 +      /* If this changed %rcx, it was not canonical */
 +      cmpq    %rcx, %r11
 +      jne     opportunistic_sysret_failed
  
        cmpq $__USER_CS,CS(%rsp)        /* CS must match SYSRET */
        jne opportunistic_sysret_failed
         */
  syscall_return_via_sysret:
        CFI_REMEMBER_STATE
 -      /* r11 is already restored (see code above) */
 -      RESTORE_C_REGS_EXCEPT_R11
 +      /* rcx and r11 are already restored (see code above) */
 +      RESTORE_C_REGS_EXCEPT_RCX_R11
        movq RSP(%rsp),%rsp
        USERGS_SYSRET64
        CFI_RESTORE_STATE
@@@ -534,27 -533,40 +534,27 @@@ GLOBAL(stub_execveat
        CFI_ENDPROC
  END(stub_execveat)
  
 -#ifdef CONFIG_X86_X32_ABI
 +#if defined(CONFIG_X86_X32_ABI) || defined(CONFIG_IA32_EMULATION)
        .align  8
  GLOBAL(stub_x32_execve)
 +GLOBAL(stub32_execve)
        CFI_STARTPROC
        DEFAULT_FRAME 0, 8
        call    compat_sys_execve
        jmp     return_from_execve
        CFI_ENDPROC
 +END(stub32_execve)
  END(stub_x32_execve)
        .align  8
  GLOBAL(stub_x32_execveat)
 -      CFI_STARTPROC
 -      DEFAULT_FRAME 0, 8
 -      call    compat_sys_execveat
 -      jmp     return_from_execve
 -      CFI_ENDPROC
 -END(stub_x32_execveat)
 -#endif
 -
 -#ifdef CONFIG_IA32_EMULATION
 -      .align  8
 -GLOBAL(stub32_execve)
 -      CFI_STARTPROC
 -      call    compat_sys_execve
 -      jmp     return_from_execve
 -      CFI_ENDPROC
 -END(stub32_execve)
 -      .align  8
  GLOBAL(stub32_execveat)
        CFI_STARTPROC
 +      DEFAULT_FRAME 0, 8
        call    compat_sys_execveat
        jmp     return_from_execve
        CFI_ENDPROC
  END(stub32_execveat)
 +END(stub_x32_execveat)
  #endif
  
  /*
@@@ -610,7 -622,7 +610,7 @@@ ENTRY(ret_from_fork
  
        RESTORE_EXTRA_REGS
  
 -      testl $3,CS(%rsp)                       # from kernel_thread?
 +      testb   $3, CS(%rsp)                    # from kernel_thread?
  
        /*
         * By the time we get here, we have no idea whether our pt_regs,
@@@ -674,8 -686,8 +674,8 @@@ END(irq_entries_start
  
        leaq -RBP(%rsp),%rdi    /* arg1 for \func (pointer to pt_regs) */
  
 -      testl $3, CS-RBP(%rsp)
 -      je 1f
 +      testb   $3, CS-RBP(%rsp)
 +      jz      1f
        SWAPGS
  1:
        /*
@@@ -729,8 -741,8 +729,8 @@@ ret_from_intr
        CFI_DEF_CFA_REGISTER    rsp
        CFI_ADJUST_CFA_OFFSET   RBP
  
 -      testl $3,CS(%rsp)
 -      je retint_kernel
 +      testb   $3, CS(%rsp)
 +      jz      retint_kernel
        /* Interrupt came from user space */
  
        GET_THREAD_INFO(%rcx)
@@@ -916,8 -928,6 +916,8 @@@ apicinterrupt X86_PLATFORM_IPI_VECTOR 
  #ifdef CONFIG_HAVE_KVM
  apicinterrupt3 POSTED_INTR_VECTOR \
        kvm_posted_intr_ipi smp_kvm_posted_intr_ipi
 +apicinterrupt3 POSTED_INTR_WAKEUP_VECTOR \
 +      kvm_posted_intr_wakeup_ipi smp_kvm_posted_intr_wakeup_ipi
  #endif
  
  #ifdef CONFIG_X86_MCE_THRESHOLD
@@@ -925,6 -935,11 +925,11 @@@ apicinterrupt THRESHOLD_APIC_VECTOR 
        threshold_interrupt smp_threshold_interrupt
  #endif
  
+ #ifdef CONFIG_X86_MCE_AMD
+ apicinterrupt DEFERRED_ERROR_VECTOR \
+       deferred_error_interrupt smp_deferred_error_interrupt
+ #endif
  #ifdef CONFIG_X86_THERMAL_VECTOR
  apicinterrupt THERMAL_APIC_VECTOR \
        thermal_interrupt smp_thermal_interrupt
@@@ -979,7 -994,7 +984,7 @@@ ENTRY(\sym
        .if \paranoid
        .if \paranoid == 1
        CFI_REMEMBER_STATE
 -      testl $3, CS(%rsp)              /* If coming from userspace, switch */
 +      testb   $3, CS(%rsp)            /* If coming from userspace, switch */
        jnz 1f                          /* stacks. */
        .endif
        call paranoid_entry
@@@ -1192,17 -1207,17 +1197,17 @@@ ENTRY(xen_failsafe_callback
        /*CFI_REL_OFFSET ds,DS*/
        CFI_REL_OFFSET r11,8
        CFI_REL_OFFSET rcx,0
 -      movw %ds,%cx
 +      movl %ds,%ecx
        cmpw %cx,0x10(%rsp)
        CFI_REMEMBER_STATE
        jne 1f
 -      movw %es,%cx
 +      movl %es,%ecx
        cmpw %cx,0x18(%rsp)
        jne 1f
 -      movw %fs,%cx
 +      movl %fs,%ecx
        cmpw %cx,0x20(%rsp)
        jne 1f
 -      movw %gs,%cx
 +      movl %gs,%ecx
        cmpw %cx,0x28(%rsp)
        jne 1f
        /* All segments match their saved values => Category 2 (Bad IRET). */
@@@ -1320,8 -1335,8 +1325,8 @@@ ENTRY(error_entry
        SAVE_C_REGS 8
        SAVE_EXTRA_REGS 8
        xorl %ebx,%ebx
 -      testl $3,CS+8(%rsp)
 -      je error_kernelspace
 +      testb   $3, CS+8(%rsp)
 +      jz      error_kernelspace
  error_swapgs:
        SWAPGS
  error_sti:
@@@ -1372,7 -1387,7 +1377,7 @@@ ENTRY(error_exit
        TRACE_IRQS_OFF
        GET_THREAD_INFO(%rcx)
        testl %eax,%eax
 -      jne retint_kernel
 +      jnz retint_kernel
        LOCKDEP_SYS_EXIT_IRQ
        movl TI_flags(%rcx),%edx
        movl $_TIF_WORK_MASK,%edi
@@@ -1617,6 -1632,7 +1622,6 @@@ end_repeat_nmi
        je 1f
        movq %r12, %cr2
  1:
 -      
        testl %ebx,%ebx                         /* swapgs needed? */
        jnz nmi_restore
  nmi_swapgs:
diff --combined arch/x86/kernel/irq.c
index 7e10c8b4b31823b415e3680a51e9d970bdc8edbc,590ed6c1bf51d1a5d34b09fadf4167de39250de7..88b366487b0e44b613e83d412febfad74381ca92
  #define CREATE_TRACE_POINTS
  #include <asm/trace/irq_vectors.h>
  
 +DEFINE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
 +EXPORT_PER_CPU_SYMBOL(irq_stat);
 +
 +DEFINE_PER_CPU(struct pt_regs *, irq_regs);
 +EXPORT_PER_CPU_SYMBOL(irq_regs);
 +
  atomic_t irq_err_count;
  
  /* Function pointer for generic interrupt vector handling */
@@@ -122,6 -116,12 +122,12 @@@ int arch_show_interrupts(struct seq_fil
                seq_printf(p, "%10u ", irq_stats(j)->irq_threshold_count);
        seq_puts(p, "  Threshold APIC interrupts\n");
  #endif
+ #ifdef CONFIG_X86_MCE_AMD
+       seq_printf(p, "%*s: ", prec, "DFR");
+       for_each_online_cpu(j)
+               seq_printf(p, "%10u ", irq_stats(j)->irq_deferred_error_count);
+       seq_puts(p, "  Deferred Error APIC interrupts\n");
+ #endif
  #ifdef CONFIG_X86_MCE
        seq_printf(p, "%*s: ", prec, "MCE");
        for_each_online_cpu(j)
        seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read(&irq_err_count));
  #if defined(CONFIG_X86_IO_APIC)
        seq_printf(p, "%*s: %10u\n", prec, "MIS", atomic_read(&irq_mis_count));
 +#endif
 +#ifdef CONFIG_HAVE_KVM
 +      seq_printf(p, "%*s: ", prec, "PIN");
 +      for_each_online_cpu(j)
 +              seq_printf(p, "%10u ", irq_stats(j)->kvm_posted_intr_ipis);
 +      seq_puts(p, "  Posted-interrupt notification event\n");
 +
 +      seq_printf(p, "%*s: ", prec, "PIW");
 +      for_each_online_cpu(j)
 +              seq_printf(p, "%10u ",
 +                         irq_stats(j)->kvm_posted_intr_wakeup_ipis);
 +      seq_puts(p, "  Posted-interrupt wakeup event\n");
  #endif
        return 0;
  }
@@@ -210,7 -198,8 +216,7 @@@ __visible unsigned int __irq_entry do_I
        unsigned vector = ~regs->orig_ax;
        unsigned irq;
  
 -      irq_enter();
 -      exit_idle();
 +      entering_irq();
  
        irq = __this_cpu_read(vector_irq[vector]);
  
                }
        }
  
 -      irq_exit();
 +      exiting_irq();
  
        set_irq_regs(old_regs);
        return 1;
@@@ -254,18 -243,6 +260,18 @@@ __visible void smp_x86_platform_ipi(str
  }
  
  #ifdef CONFIG_HAVE_KVM
 +static void dummy_handler(void) {}
 +static void (*kvm_posted_intr_wakeup_handler)(void) = dummy_handler;
 +
 +void kvm_set_posted_intr_wakeup_handler(void (*handler)(void))
 +{
 +      if (handler)
 +              kvm_posted_intr_wakeup_handler = handler;
 +      else
 +              kvm_posted_intr_wakeup_handler = dummy_handler;
 +}
 +EXPORT_SYMBOL_GPL(kvm_set_posted_intr_wakeup_handler);
 +
  /*
   * Handler for POSTED_INTERRUPT_VECTOR.
   */
@@@ -273,23 -250,16 +279,23 @@@ __visible void smp_kvm_posted_intr_ipi(
  {
        struct pt_regs *old_regs = set_irq_regs(regs);
  
 -      ack_APIC_irq();
 -
 -      irq_enter();
 -
 -      exit_idle();
 -
 +      entering_ack_irq();
        inc_irq_stat(kvm_posted_intr_ipis);
 +      exiting_irq();
 +      set_irq_regs(old_regs);
 +}
  
 -      irq_exit();
 +/*
 + * Handler for POSTED_INTERRUPT_WAKEUP_VECTOR.
 + */
 +__visible void smp_kvm_posted_intr_wakeup_ipi(struct pt_regs *regs)
 +{
 +      struct pt_regs *old_regs = set_irq_regs(regs);
  
 +      entering_ack_irq();
 +      inc_irq_stat(kvm_posted_intr_wakeup_ipis);
 +      kvm_posted_intr_wakeup_handler();
 +      exiting_irq();
        set_irq_regs(old_regs);
  }
  #endif
index 680723a8e4b63c530deb56fa020187b0533f3d16,d7ec6e7b2b5b329f1533fabec5d1db685fab09fa..a3a5e158ed69553eaa623678d3812e008a4e24c7
@@@ -86,7 -86,7 +86,7 @@@ void __init init_IRQ(void
        int i;
  
        /*
 -       * On cpu 0, Assign IRQ0_VECTOR..IRQ15_VECTOR's to IRQ 0..15.
 +       * On cpu 0, Assign ISA_IRQ_VECTOR(irq) to IRQ 0..15.
         * If these IRQ's are handled by legacy interrupt-controllers like PIC,
         * then this configuration will likely be static after the boot. If
         * these IRQ's are handled by more mordern controllers like IO-APIC,
@@@ -94,7 -94,7 +94,7 @@@
         * irq's migrate etc.
         */
        for (i = 0; i < nr_legacy_irqs(); i++)
 -              per_cpu(vector_irq, 0)[IRQ0_VECTOR + i] = i;
 +              per_cpu(vector_irq, 0)[ISA_IRQ_VECTOR(i)] = i;
  
        x86_init.irqs.intr_init();
  }
@@@ -135,6 -135,10 +135,10 @@@ static void __init apic_intr_init(void
        alloc_intr_gate(THRESHOLD_APIC_VECTOR, threshold_interrupt);
  #endif
  
+ #ifdef CONFIG_X86_MCE_AMD
+       alloc_intr_gate(DEFERRED_ERROR_VECTOR, deferred_error_interrupt);
+ #endif
  #ifdef CONFIG_X86_LOCAL_APIC
        /* self generated IPI for local APIC timer */
        alloc_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt);
  #ifdef CONFIG_HAVE_KVM
        /* IPI for KVM to deliver posted interrupt */
        alloc_intr_gate(POSTED_INTR_VECTOR, kvm_posted_intr_ipi);
 +      /* IPI for KVM to deliver interrupt to wake up tasks */
 +      alloc_intr_gate(POSTED_INTR_WAKEUP_VECTOR, kvm_posted_intr_wakeup_ipi);
  #endif
  
        /* IPI vectors for APIC spurious and error interrupts */
diff --combined arch/x86/kernel/traps.c
index 5e0791f9d3dca6c74de6f72d353d08224e395514,2768bb663f94075b8a69001e881d6905b0fd9e8d..c30bbb5d56e2d8baa74996475cee1bc3a2f74f89
@@@ -813,18 -813,6 +813,6 @@@ dotraplinkage voi
  do_spurious_interrupt_bug(struct pt_regs *regs, long error_code)
  {
        conditional_sti(regs);
- #if 0
-       /* No need to warn about this any longer. */
-       pr_info("Ignoring P6 Local APIC Spurious Interrupt Bug...\n");
- #endif
- }
- asmlinkage __visible void __attribute__((weak)) smp_thermal_interrupt(void)
- {
- }
- asmlinkage __visible void __attribute__((weak)) smp_threshold_interrupt(void)
- {
  }
  
  /*
@@@ -997,8 -985,8 +985,8 @@@ void __init trap_init(void
  #endif
  
  #ifdef CONFIG_X86_32
 -      set_system_trap_gate(SYSCALL_VECTOR, &system_call);
 -      set_bit(SYSCALL_VECTOR, used_vectors);
 +      set_system_trap_gate(IA32_SYSCALL_VECTOR, &system_call);
 +      set_bit(IA32_SYSCALL_VECTOR, used_vectors);
  #endif
  
        /*