aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/events/core.c2
-rw-r--r--arch/x86/include/asm/mmu_context.h8
-rw-r--r--arch/x86/include/asm/tlbflush.h30
-rw-r--r--arch/x86/mm/tlb.c2
4 files changed, 29 insertions, 13 deletions
diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index 81b005e4c7d9..cfe256ca76df 100644
--- a/arch/x86/events/core.c
+++ b/arch/x86/events/core.c
@@ -2087,7 +2087,7 @@ static int x86_pmu_event_init(struct perf_event *event)
2087 2087
2088static void refresh_pce(void *ignored) 2088static void refresh_pce(void *ignored)
2089{ 2089{
2090 load_mm_cr4(this_cpu_read(cpu_tlbstate.loaded_mm)); 2090 load_mm_cr4_irqsoff(this_cpu_read(cpu_tlbstate.loaded_mm));
2091} 2091}
2092 2092
2093static void x86_pmu_event_mapped(struct perf_event *event, struct mm_struct *mm) 2093static void x86_pmu_event_mapped(struct perf_event *event, struct mm_struct *mm)
diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h
index 9024236693d2..16ae821483c8 100644
--- a/arch/x86/include/asm/mmu_context.h
+++ b/arch/x86/include/asm/mmu_context.h
@@ -28,16 +28,16 @@ static inline void paravirt_activate_mm(struct mm_struct *prev,
28 28
29DECLARE_STATIC_KEY_FALSE(rdpmc_always_available_key); 29DECLARE_STATIC_KEY_FALSE(rdpmc_always_available_key);
30 30
31static inline void load_mm_cr4(struct mm_struct *mm) 31static inline void load_mm_cr4_irqsoff(struct mm_struct *mm)
32{ 32{
33 if (static_branch_unlikely(&rdpmc_always_available_key) || 33 if (static_branch_unlikely(&rdpmc_always_available_key) ||
34 atomic_read(&mm->context.perf_rdpmc_allowed)) 34 atomic_read(&mm->context.perf_rdpmc_allowed))
35 cr4_set_bits(X86_CR4_PCE); 35 cr4_set_bits_irqsoff(X86_CR4_PCE);
36 else 36 else
37 cr4_clear_bits(X86_CR4_PCE); 37 cr4_clear_bits_irqsoff(X86_CR4_PCE);
38} 38}
39#else 39#else
40static inline void load_mm_cr4(struct mm_struct *mm) {} 40static inline void load_mm_cr4_irqsoff(struct mm_struct *mm) {}
41#endif 41#endif
42 42
43#ifdef CONFIG_MODIFY_LDT_SYSCALL 43#ifdef CONFIG_MODIFY_LDT_SYSCALL
diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h
index dee375831962..6f66d841262d 100644
--- a/arch/x86/include/asm/tlbflush.h
+++ b/arch/x86/include/asm/tlbflush.h
@@ -290,26 +290,42 @@ static inline void __cr4_set(unsigned long cr4)
290} 290}
291 291
292/* Set in this cpu's CR4. */ 292/* Set in this cpu's CR4. */
293static inline void cr4_set_bits(unsigned long mask) 293static inline void cr4_set_bits_irqsoff(unsigned long mask)
294{ 294{
295 unsigned long cr4, flags; 295 unsigned long cr4;
296 296
297 local_irq_save(flags);
298 cr4 = this_cpu_read(cpu_tlbstate.cr4); 297 cr4 = this_cpu_read(cpu_tlbstate.cr4);
299 if ((cr4 | mask) != cr4) 298 if ((cr4 | mask) != cr4)
300 __cr4_set(cr4 | mask); 299 __cr4_set(cr4 | mask);
301 local_irq_restore(flags);
302} 300}
303 301
304/* Clear in this cpu's CR4. */ 302/* Clear in this cpu's CR4. */
305static inline void cr4_clear_bits(unsigned long mask) 303static inline void cr4_clear_bits_irqsoff(unsigned long mask)
306{ 304{
307 unsigned long cr4, flags; 305 unsigned long cr4;
308 306
309 local_irq_save(flags);
310 cr4 = this_cpu_read(cpu_tlbstate.cr4); 307 cr4 = this_cpu_read(cpu_tlbstate.cr4);
311 if ((cr4 & ~mask) != cr4) 308 if ((cr4 & ~mask) != cr4)
312 __cr4_set(cr4 & ~mask); 309 __cr4_set(cr4 & ~mask);
310}
311
312/* Set in this cpu's CR4. */
313static inline void cr4_set_bits(unsigned long mask)
314{
315 unsigned long flags;
316
317 local_irq_save(flags);
318 cr4_set_bits_irqsoff(mask);
319 local_irq_restore(flags);
320}
321
322/* Clear in this cpu's CR4. */
323static inline void cr4_clear_bits(unsigned long mask)
324{
325 unsigned long flags;
326
327 local_irq_save(flags);
328 cr4_clear_bits_irqsoff(mask);
313 local_irq_restore(flags); 329 local_irq_restore(flags);
314} 330}
315 331
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
index 4de9704c4aaf..e6a9edc5baaf 100644
--- a/arch/x86/mm/tlb.c
+++ b/arch/x86/mm/tlb.c
@@ -440,7 +440,7 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
440 this_cpu_write(cpu_tlbstate.loaded_mm_asid, new_asid); 440 this_cpu_write(cpu_tlbstate.loaded_mm_asid, new_asid);
441 441
442 if (next != real_prev) { 442 if (next != real_prev) {
443 load_mm_cr4(next); 443 load_mm_cr4_irqsoff(next);
444 switch_ldt(real_prev, next); 444 switch_ldt(real_prev, next);
445 } 445 }
446} 446}