perf/x86: Only allow rdpmc if a perf_event is mapped
[deliverable/linux.git] / arch / x86 / include / asm / mmu_context.h
index 52c18359f1dcaf68e093007e17a30a8f71acee37..89c1fece224e7875d8d539c00846823a46df09a9 100644 (file)
@@ -18,6 +18,18 @@ static inline void paravirt_activate_mm(struct mm_struct *prev,
 }
 #endif /* !CONFIG_PARAVIRT */
 
+#ifdef CONFIG_PERF_EVENTS
+static inline void load_mm_cr4(struct mm_struct *mm)
+{
+       if (atomic_read(&mm->context.perf_rdpmc_allowed))
+               cr4_set_bits(X86_CR4_PCE);
+       else
+               cr4_clear_bits(X86_CR4_PCE);
+}
+#else
+static inline void load_mm_cr4(struct mm_struct *mm) {}
+#endif
+
 /*
  * Used for LDT copy/destruction.
  */
@@ -52,6 +64,9 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
                /* Stop flush ipis for the previous mm */
                cpumask_clear_cpu(cpu, mm_cpumask(prev));
 
+               /* Load per-mm CR4 state */
+               load_mm_cr4(next);
+
                /*
                 * Load the LDT, if the LDT is different.
                 *
@@ -87,6 +102,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
                         */
                        load_cr3(next->pgd);
                        trace_tlb_flush(TLB_FLUSH_ON_TASK_SWITCH, TLB_FLUSH_ALL);
+                       load_mm_cr4(next);
                        load_LDT_nolock(&next->context);
                }
        }
This page took 0.024277 seconds and 5 git commands to generate.