]>
Commit | Line | Data |
---|---|---|
cf910e83 SA |
1 | /* |
2 | * Code for supporting irq vector tracepoints. | |
3 | * | |
4 | * Copyright (C) 2013 Seiji Aguchi <seiji.aguchi@hds.com> | |
5 | * | |
6 | */ | |
7 | #include <asm/hw_irq.h> | |
8 | #include <asm/desc.h> | |
9 | #include <linux/atomic.h> | |
10 | ||
11 | atomic_t trace_idt_ctr = ATOMIC_INIT(0); | |
12 | struct desc_ptr trace_idt_descr = { NR_VECTORS * 16 - 1, | |
13 | (unsigned long) trace_idt_table }; | |
14 | ||
15 | #ifndef CONFIG_X86_64 | |
16 | gate_desc trace_idt_table[NR_VECTORS] __page_aligned_data | |
17 | = { { { { 0, 0 } } }, }; | |
18 | #endif | |
19 | ||
20 | static int trace_irq_vector_refcount; | |
21 | static DEFINE_MUTEX(irq_vector_mutex); | |
22 | ||
23 | static void set_trace_idt_ctr(int val) | |
24 | { | |
25 | atomic_set(&trace_idt_ctr, val); | |
26 | /* Ensure the trace_idt_ctr is set before sending IPI */ | |
27 | wmb(); | |
28 | } | |
29 | ||
30 | static void switch_idt(void *arg) | |
31 | { | |
32 | load_current_idt(); | |
33 | } | |
34 | ||
35 | void trace_irq_vector_regfunc(void) | |
36 | { | |
37 | mutex_lock(&irq_vector_mutex); | |
38 | if (!trace_irq_vector_refcount) { | |
39 | set_trace_idt_ctr(1); | |
40 | smp_call_function(switch_idt, NULL, 0); | |
41 | switch_idt(NULL); | |
42 | } | |
43 | trace_irq_vector_refcount++; | |
44 | mutex_unlock(&irq_vector_mutex); | |
45 | } | |
46 | ||
47 | void trace_irq_vector_unregfunc(void) | |
48 | { | |
49 | mutex_lock(&irq_vector_mutex); | |
50 | trace_irq_vector_refcount--; | |
51 | if (!trace_irq_vector_refcount) { | |
52 | set_trace_idt_ctr(0); | |
53 | smp_call_function(switch_idt, NULL, 0); | |
54 | switch_idt(NULL); | |
55 | } | |
56 | mutex_unlock(&irq_vector_mutex); | |
57 | } |