xref: /openbmc/linux/arch/x86/kernel/trace.c (revision 9bd98576)
1 #include <asm/trace/irq_vectors.h>
2 #include <linux/trace.h>
3 
4 #if defined(CONFIG_OSNOISE_TRACER) && defined(CONFIG_X86_LOCAL_APIC)
5 /*
6  * trace_intel_irq_entry - record intel specific IRQ entry
7  */
trace_intel_irq_entry(void * data,int vector)8 static void trace_intel_irq_entry(void *data, int vector)
9 {
10 	osnoise_trace_irq_entry(vector);
11 }
12 
13 /*
14  * trace_intel_irq_exit - record intel specific IRQ exit
15  */
trace_intel_irq_exit(void * data,int vector)16 static void trace_intel_irq_exit(void *data, int vector)
17 {
18 	char *vector_desc = (char *) data;
19 
20 	osnoise_trace_irq_exit(vector, vector_desc);
21 }
22 
23 /*
24  * register_intel_irq_tp - Register intel specific IRQ entry tracepoints
25  */
osnoise_arch_register(void)26 int osnoise_arch_register(void)
27 {
28 	int ret;
29 
30 	ret = register_trace_local_timer_entry(trace_intel_irq_entry, NULL);
31 	if (ret)
32 		goto out_err;
33 
34 	ret = register_trace_local_timer_exit(trace_intel_irq_exit, "local_timer");
35 	if (ret)
36 		goto out_timer_entry;
37 
38 #ifdef CONFIG_X86_THERMAL_VECTOR
39 	ret = register_trace_thermal_apic_entry(trace_intel_irq_entry, NULL);
40 	if (ret)
41 		goto out_timer_exit;
42 
43 	ret = register_trace_thermal_apic_exit(trace_intel_irq_exit, "thermal_apic");
44 	if (ret)
45 		goto out_thermal_entry;
46 #endif /* CONFIG_X86_THERMAL_VECTOR */
47 
48 #ifdef CONFIG_X86_MCE_AMD
49 	ret = register_trace_deferred_error_apic_entry(trace_intel_irq_entry, NULL);
50 	if (ret)
51 		goto out_thermal_exit;
52 
53 	ret = register_trace_deferred_error_apic_exit(trace_intel_irq_exit, "deferred_error");
54 	if (ret)
55 		goto out_deferred_entry;
56 #endif
57 
58 #ifdef CONFIG_X86_MCE_THRESHOLD
59 	ret = register_trace_threshold_apic_entry(trace_intel_irq_entry, NULL);
60 	if (ret)
61 		goto out_deferred_exit;
62 
63 	ret = register_trace_threshold_apic_exit(trace_intel_irq_exit, "threshold_apic");
64 	if (ret)
65 		goto out_threshold_entry;
66 #endif /* CONFIG_X86_MCE_THRESHOLD */
67 
68 #ifdef CONFIG_SMP
69 	ret = register_trace_call_function_single_entry(trace_intel_irq_entry, NULL);
70 	if (ret)
71 		goto out_threshold_exit;
72 
73 	ret = register_trace_call_function_single_exit(trace_intel_irq_exit,
74 						       "call_function_single");
75 	if (ret)
76 		goto out_call_function_single_entry;
77 
78 	ret = register_trace_call_function_entry(trace_intel_irq_entry, NULL);
79 	if (ret)
80 		goto out_call_function_single_exit;
81 
82 	ret = register_trace_call_function_exit(trace_intel_irq_exit, "call_function");
83 	if (ret)
84 		goto out_call_function_entry;
85 
86 	ret = register_trace_reschedule_entry(trace_intel_irq_entry, NULL);
87 	if (ret)
88 		goto out_call_function_exit;
89 
90 	ret = register_trace_reschedule_exit(trace_intel_irq_exit, "reschedule");
91 	if (ret)
92 		goto out_reschedule_entry;
93 #endif /* CONFIG_SMP */
94 
95 #ifdef CONFIG_IRQ_WORK
96 	ret = register_trace_irq_work_entry(trace_intel_irq_entry, NULL);
97 	if (ret)
98 		goto out_reschedule_exit;
99 
100 	ret = register_trace_irq_work_exit(trace_intel_irq_exit, "irq_work");
101 	if (ret)
102 		goto out_irq_work_entry;
103 #endif
104 
105 	ret = register_trace_x86_platform_ipi_entry(trace_intel_irq_entry, NULL);
106 	if (ret)
107 		goto out_irq_work_exit;
108 
109 	ret = register_trace_x86_platform_ipi_exit(trace_intel_irq_exit, "x86_platform_ipi");
110 	if (ret)
111 		goto out_x86_ipi_entry;
112 
113 	ret = register_trace_error_apic_entry(trace_intel_irq_entry, NULL);
114 	if (ret)
115 		goto out_x86_ipi_exit;
116 
117 	ret = register_trace_error_apic_exit(trace_intel_irq_exit, "error_apic");
118 	if (ret)
119 		goto out_error_apic_entry;
120 
121 	ret = register_trace_spurious_apic_entry(trace_intel_irq_entry, NULL);
122 	if (ret)
123 		goto out_error_apic_exit;
124 
125 	ret = register_trace_spurious_apic_exit(trace_intel_irq_exit, "spurious_apic");
126 	if (ret)
127 		goto out_spurious_apic_entry;
128 
129 	return 0;
130 
131 out_spurious_apic_entry:
132 	unregister_trace_spurious_apic_entry(trace_intel_irq_entry, NULL);
133 out_error_apic_exit:
134 	unregister_trace_error_apic_exit(trace_intel_irq_exit, "error_apic");
135 out_error_apic_entry:
136 	unregister_trace_error_apic_entry(trace_intel_irq_entry, NULL);
137 out_x86_ipi_exit:
138 	unregister_trace_x86_platform_ipi_exit(trace_intel_irq_exit, "x86_platform_ipi");
139 out_x86_ipi_entry:
140 	unregister_trace_x86_platform_ipi_entry(trace_intel_irq_entry, NULL);
141 out_irq_work_exit:
142 
143 #ifdef CONFIG_IRQ_WORK
144 	unregister_trace_irq_work_exit(trace_intel_irq_exit, "irq_work");
145 out_irq_work_entry:
146 	unregister_trace_irq_work_entry(trace_intel_irq_entry, NULL);
147 out_reschedule_exit:
148 #endif
149 
150 #ifdef CONFIG_SMP
151 	unregister_trace_reschedule_exit(trace_intel_irq_exit, "reschedule");
152 out_reschedule_entry:
153 	unregister_trace_reschedule_entry(trace_intel_irq_entry, NULL);
154 out_call_function_exit:
155 	unregister_trace_call_function_exit(trace_intel_irq_exit, "call_function");
156 out_call_function_entry:
157 	unregister_trace_call_function_entry(trace_intel_irq_entry, NULL);
158 out_call_function_single_exit:
159 	unregister_trace_call_function_single_exit(trace_intel_irq_exit, "call_function_single");
160 out_call_function_single_entry:
161 	unregister_trace_call_function_single_entry(trace_intel_irq_entry, NULL);
162 out_threshold_exit:
163 #endif
164 
165 #ifdef CONFIG_X86_MCE_THRESHOLD
166 	unregister_trace_threshold_apic_exit(trace_intel_irq_exit, "threshold_apic");
167 out_threshold_entry:
168 	unregister_trace_threshold_apic_entry(trace_intel_irq_entry, NULL);
169 out_deferred_exit:
170 #endif
171 
172 #ifdef CONFIG_X86_MCE_AMD
173 	unregister_trace_deferred_error_apic_exit(trace_intel_irq_exit, "deferred_error");
174 out_deferred_entry:
175 	unregister_trace_deferred_error_apic_entry(trace_intel_irq_entry, NULL);
176 out_thermal_exit:
177 #endif /* CONFIG_X86_MCE_AMD */
178 
179 #ifdef CONFIG_X86_THERMAL_VECTOR
180 	unregister_trace_thermal_apic_exit(trace_intel_irq_exit, "thermal_apic");
181 out_thermal_entry:
182 	unregister_trace_thermal_apic_entry(trace_intel_irq_entry, NULL);
183 out_timer_exit:
184 #endif /* CONFIG_X86_THERMAL_VECTOR */
185 
186 	unregister_trace_local_timer_exit(trace_intel_irq_exit, "local_timer");
187 out_timer_entry:
188 	unregister_trace_local_timer_entry(trace_intel_irq_entry, NULL);
189 out_err:
190 	return -EINVAL;
191 }
192 
osnoise_arch_unregister(void)193 void osnoise_arch_unregister(void)
194 {
195 	unregister_trace_spurious_apic_exit(trace_intel_irq_exit, "spurious_apic");
196 	unregister_trace_spurious_apic_entry(trace_intel_irq_entry, NULL);
197 	unregister_trace_error_apic_exit(trace_intel_irq_exit, "error_apic");
198 	unregister_trace_error_apic_entry(trace_intel_irq_entry, NULL);
199 	unregister_trace_x86_platform_ipi_exit(trace_intel_irq_exit, "x86_platform_ipi");
200 	unregister_trace_x86_platform_ipi_entry(trace_intel_irq_entry, NULL);
201 
202 #ifdef CONFIG_IRQ_WORK
203 	unregister_trace_irq_work_exit(trace_intel_irq_exit, "irq_work");
204 	unregister_trace_irq_work_entry(trace_intel_irq_entry, NULL);
205 #endif
206 
207 #ifdef CONFIG_SMP
208 	unregister_trace_reschedule_exit(trace_intel_irq_exit, "reschedule");
209 	unregister_trace_reschedule_entry(trace_intel_irq_entry, NULL);
210 	unregister_trace_call_function_exit(trace_intel_irq_exit, "call_function");
211 	unregister_trace_call_function_entry(trace_intel_irq_entry, NULL);
212 	unregister_trace_call_function_single_exit(trace_intel_irq_exit, "call_function_single");
213 	unregister_trace_call_function_single_entry(trace_intel_irq_entry, NULL);
214 #endif
215 
216 #ifdef CONFIG_X86_MCE_THRESHOLD
217 	unregister_trace_threshold_apic_exit(trace_intel_irq_exit, "threshold_apic");
218 	unregister_trace_threshold_apic_entry(trace_intel_irq_entry, NULL);
219 #endif
220 
221 #ifdef CONFIG_X86_MCE_AMD
222 	unregister_trace_deferred_error_apic_exit(trace_intel_irq_exit, "deferred_error");
223 	unregister_trace_deferred_error_apic_entry(trace_intel_irq_entry, NULL);
224 #endif
225 
226 #ifdef CONFIG_X86_THERMAL_VECTOR
227 	unregister_trace_thermal_apic_exit(trace_intel_irq_exit, "thermal_apic");
228 	unregister_trace_thermal_apic_entry(trace_intel_irq_entry, NULL);
229 #endif /* CONFIG_X86_THERMAL_VECTOR */
230 
231 	unregister_trace_local_timer_exit(trace_intel_irq_exit, "local_timer");
232 	unregister_trace_local_timer_entry(trace_intel_irq_entry, NULL);
233 }
234 #endif /* CONFIG_OSNOISE_TRACER && CONFIG_X86_LOCAL_APIC */
235