diff options
-rw-r--r-- | arch/x86/events/core.c | 2 | ||||
-rw-r--r-- | arch/x86/include/asm/mmu_context.h | 8 | ||||
-rw-r--r-- | arch/x86/include/asm/tlbflush.h | 30 | ||||
-rw-r--r-- | arch/x86/mm/tlb.c | 2 |
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 | ||
2088 | static void refresh_pce(void *ignored) | 2088 | static 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 | ||
2093 | static void x86_pmu_event_mapped(struct perf_event *event, struct mm_struct *mm) | 2093 | static 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 | ||
29 | DECLARE_STATIC_KEY_FALSE(rdpmc_always_available_key); | 29 | DECLARE_STATIC_KEY_FALSE(rdpmc_always_available_key); |
30 | 30 | ||
31 | static inline void load_mm_cr4(struct mm_struct *mm) | 31 | static 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 |
40 | static inline void load_mm_cr4(struct mm_struct *mm) {} | 40 | static 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. */ |
293 | static inline void cr4_set_bits(unsigned long mask) | 293 | static 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. */ |
305 | static inline void cr4_clear_bits(unsigned long mask) | 303 | static 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. */ | ||
313 | static 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. */ | ||
323 | static 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 | } |