1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
2c49f6353SAnton Blanchard #include <linux/percpu.h>
3c49f6353SAnton Blanchard #include <linux/jump_label.h>
4c49f6353SAnton Blanchard #include <asm/trace.h>
5c49f6353SAnton Blanchard 
6e9666d10SMasahiro Yamada #ifdef CONFIG_JUMP_LABEL
7c49f6353SAnton Blanchard struct static_key opal_tracepoint_key = STATIC_KEY_INIT;
8c49f6353SAnton Blanchard 
opal_tracepoint_regfunc(void)98cf868afSSteven Rostedt (Red Hat) int opal_tracepoint_regfunc(void)
10c49f6353SAnton Blanchard {
11c49f6353SAnton Blanchard 	static_key_slow_inc(&opal_tracepoint_key);
128cf868afSSteven Rostedt (Red Hat) 	return 0;
13c49f6353SAnton Blanchard }
14c49f6353SAnton Blanchard 
opal_tracepoint_unregfunc(void)15c49f6353SAnton Blanchard void opal_tracepoint_unregfunc(void)
16c49f6353SAnton Blanchard {
17c49f6353SAnton Blanchard 	static_key_slow_dec(&opal_tracepoint_key);
18c49f6353SAnton Blanchard }
19c49f6353SAnton Blanchard #else
20c49f6353SAnton Blanchard /*
21c49f6353SAnton Blanchard  * We optimise OPAL calls by placing opal_tracepoint_refcount
22c49f6353SAnton Blanchard  * directly in the TOC so we can check if the opal tracepoints are
23c49f6353SAnton Blanchard  * enabled via a single load.
24c49f6353SAnton Blanchard  */
25c49f6353SAnton Blanchard 
26c49f6353SAnton Blanchard /* NB: reg/unreg are called while guarded with the tracepoints_mutex */
27c49f6353SAnton Blanchard extern long opal_tracepoint_refcount;
28c49f6353SAnton Blanchard 
opal_tracepoint_regfunc(void)298cf868afSSteven Rostedt (Red Hat) int opal_tracepoint_regfunc(void)
30c49f6353SAnton Blanchard {
31c49f6353SAnton Blanchard 	opal_tracepoint_refcount++;
328cf868afSSteven Rostedt (Red Hat) 	return 0;
33c49f6353SAnton Blanchard }
34c49f6353SAnton Blanchard 
opal_tracepoint_unregfunc(void)35c49f6353SAnton Blanchard void opal_tracepoint_unregfunc(void)
36c49f6353SAnton Blanchard {
37c49f6353SAnton Blanchard 	opal_tracepoint_refcount--;
38c49f6353SAnton Blanchard }
39c49f6353SAnton Blanchard #endif
40c49f6353SAnton Blanchard 
41c49f6353SAnton Blanchard /*
42c49f6353SAnton Blanchard  * Since the tracing code might execute OPAL calls we need to guard against
43c49f6353SAnton Blanchard  * recursion.
44c49f6353SAnton Blanchard  */
45c49f6353SAnton Blanchard static DEFINE_PER_CPU(unsigned int, opal_trace_depth);
46c49f6353SAnton Blanchard 
__trace_opal_entry(unsigned long opcode,unsigned long * args)47c49f6353SAnton Blanchard void __trace_opal_entry(unsigned long opcode, unsigned long *args)
48c49f6353SAnton Blanchard {
49c49f6353SAnton Blanchard 	unsigned long flags;
50c49f6353SAnton Blanchard 	unsigned int *depth;
51c49f6353SAnton Blanchard 
52c49f6353SAnton Blanchard 	local_irq_save(flags);
53c49f6353SAnton Blanchard 
5469111bacSChristoph Lameter 	depth = this_cpu_ptr(&opal_trace_depth);
55c49f6353SAnton Blanchard 
56c49f6353SAnton Blanchard 	if (*depth)
57c49f6353SAnton Blanchard 		goto out;
58c49f6353SAnton Blanchard 
59c49f6353SAnton Blanchard 	(*depth)++;
60c49f6353SAnton Blanchard 	preempt_disable();
61c49f6353SAnton Blanchard 	trace_opal_entry(opcode, args);
62c49f6353SAnton Blanchard 	(*depth)--;
63c49f6353SAnton Blanchard 
64c49f6353SAnton Blanchard out:
65c49f6353SAnton Blanchard 	local_irq_restore(flags);
66c49f6353SAnton Blanchard }
67c49f6353SAnton Blanchard 
__trace_opal_exit(long opcode,unsigned long retval)68c49f6353SAnton Blanchard void __trace_opal_exit(long opcode, unsigned long retval)
69c49f6353SAnton Blanchard {
70c49f6353SAnton Blanchard 	unsigned long flags;
71c49f6353SAnton Blanchard 	unsigned int *depth;
72c49f6353SAnton Blanchard 
73c49f6353SAnton Blanchard 	local_irq_save(flags);
74c49f6353SAnton Blanchard 
7569111bacSChristoph Lameter 	depth = this_cpu_ptr(&opal_trace_depth);
76c49f6353SAnton Blanchard 
77c49f6353SAnton Blanchard 	if (*depth)
78c49f6353SAnton Blanchard 		goto out;
79c49f6353SAnton Blanchard 
80c49f6353SAnton Blanchard 	(*depth)++;
81c49f6353SAnton Blanchard 	trace_opal_exit(opcode, retval);
82c49f6353SAnton Blanchard 	preempt_enable();
83c49f6353SAnton Blanchard 	(*depth)--;
84c49f6353SAnton Blanchard 
85c49f6353SAnton Blanchard out:
86c49f6353SAnton Blanchard 	local_irq_restore(flags);
87c49f6353SAnton Blanchard }
88