diff options
| -rw-r--r-- | arch/x86/include/asm/desc.h | 10 | ||||
| -rw-r--r-- | arch/x86/kernel/tracepoint.c | 4 |
2 files changed, 8 insertions, 6 deletions
diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h index 1377ecb29d8d..b90e5dfeee46 100644 --- a/arch/x86/include/asm/desc.h +++ b/arch/x86/include/asm/desc.h | |||
| @@ -497,21 +497,19 @@ static inline void load_trace_idt(void) | |||
| 497 | #endif | 497 | #endif |
| 498 | 498 | ||
| 499 | /* | 499 | /* |
| 500 | * the load_current_idt() is called with interrupt disabled by local_irq_save() | 500 | * The load_current_idt() must be called with interrupts disabled |
| 501 | * to avoid races. That way the IDT will always be set back to the expected | 501 | * to avoid races. That way the IDT will always be set back to the expected |
| 502 | * descriptor. | 502 | * descriptor. It's also called when a CPU is being initialized, and |
| 503 | * that doesn't need to disable interrupts, as nothing should be | ||
| 504 | * bothering the CPU then. | ||
| 503 | */ | 505 | */ |
| 504 | static inline void load_current_idt(void) | 506 | static inline void load_current_idt(void) |
| 505 | { | 507 | { |
| 506 | unsigned long flags; | ||
| 507 | |||
| 508 | local_irq_save(flags); | ||
| 509 | if (is_debug_idt_enabled()) | 508 | if (is_debug_idt_enabled()) |
| 510 | load_debug_idt(); | 509 | load_debug_idt(); |
| 511 | else if (is_trace_idt_enabled()) | 510 | else if (is_trace_idt_enabled()) |
| 512 | load_trace_idt(); | 511 | load_trace_idt(); |
| 513 | else | 512 | else |
| 514 | load_idt((const struct desc_ptr *)&idt_descr); | 513 | load_idt((const struct desc_ptr *)&idt_descr); |
| 515 | local_irq_restore(flags); | ||
| 516 | } | 514 | } |
| 517 | #endif /* _ASM_X86_DESC_H */ | 515 | #endif /* _ASM_X86_DESC_H */ |
diff --git a/arch/x86/kernel/tracepoint.c b/arch/x86/kernel/tracepoint.c index 1423efe98fbc..4e584a8d6edd 100644 --- a/arch/x86/kernel/tracepoint.c +++ b/arch/x86/kernel/tracepoint.c | |||
| @@ -29,7 +29,11 @@ static void set_trace_idt_ctr(int val) | |||
| 29 | 29 | ||
| 30 | static void switch_idt(void *arg) | 30 | static void switch_idt(void *arg) |
| 31 | { | 31 | { |
| 32 | unsigned long flags; | ||
| 33 | |||
| 34 | local_irq_save(flags); | ||
| 32 | load_current_idt(); | 35 | load_current_idt(); |
| 36 | local_irq_restore(flags); | ||
| 33 | } | 37 | } |
| 34 | 38 | ||
| 35 | void trace_irq_vector_regfunc(void) | 39 | void trace_irq_vector_regfunc(void) |
