* intel_bts events don't coexist with intel PMU's BTS events because of
  * x86_add_exclusive(x86_lbr_exclusive_lbr); there's no need to keep them
  * disabled around intel PMU's event batching etc, only inside the PMI handler.
+ *
+ * Avoid PEBS_ENABLE MSR access in PMIs.
+ * The GLOBAL_CTRL has been disabled. All the counters do not count anymore.
+ * It doesn't matter if the PEBS is enabled or not.
+ * Usually, the PEBS status are not changed in PMIs. It's unnecessary to
+ * access PEBS_ENABLE MSR in disable_all()/enable_all().
+ * However, there are some cases which may change PEBS status, e.g. PMI
+ * throttle. The PEBS_ENABLE should be updated where the status changes.
  */
 static void __intel_pmu_disable_all(void)
 {
 
        if (test_bit(INTEL_PMC_IDX_FIXED_BTS, cpuc->active_mask))
                intel_pmu_disable_bts();
-
-       intel_pmu_pebs_disable_all();
 }
 
 static void intel_pmu_disable_all(void)
 {
        __intel_pmu_disable_all();
+       intel_pmu_pebs_disable_all();
        intel_pmu_lbr_disable_all();
 }
 
 {
        struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
 
-       intel_pmu_pebs_enable_all();
        intel_pmu_lbr_enable_all(pmi);
        wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL,
                        x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_guest_mask);
 
 static void intel_pmu_enable_all(int added)
 {
+       intel_pmu_pebs_enable_all();
        __intel_pmu_enable_all(added, false);
 }
 
         * PEBS overflow sets bit 62 in the global status register
         */
        if (__test_and_clear_bit(62, (unsigned long *)&status)) {
+               u64 pebs_enabled = cpuc->pebs_enabled;
+
                handled++;
                x86_pmu.drain_pebs(regs);
                status &= x86_pmu.intel_ctrl | GLOBAL_STATUS_TRACE_TOPAPMI;
+
+               /*
+                * PMI throttle may be triggered, which stops the PEBS event.
+                * Although cpuc->pebs_enabled is updated accordingly, the
+                * MSR_IA32_PEBS_ENABLE is not updated. Because the
+                * cpuc->enabled has been forced to 0 in PMI.
+                * Update the MSR if pebs_enabled is changed.
+                */
+               if (pebs_enabled != cpuc->pebs_enabled)
+                       wrmsrl(MSR_IA32_PEBS_ENABLE, cpuc->pebs_enabled);
        }
 
        /*