Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 #include <linux/percpu.h>
0003 #include <linux/jump_label.h>
0004 #include <asm/trace.h>
0005 
0006 #ifdef CONFIG_JUMP_LABEL
0007 struct static_key opal_tracepoint_key = STATIC_KEY_INIT;
0008 
0009 int opal_tracepoint_regfunc(void)
0010 {
0011     static_key_slow_inc(&opal_tracepoint_key);
0012     return 0;
0013 }
0014 
0015 void opal_tracepoint_unregfunc(void)
0016 {
0017     static_key_slow_dec(&opal_tracepoint_key);
0018 }
0019 #else
0020 /*
0021  * We optimise OPAL calls by placing opal_tracepoint_refcount
0022  * directly in the TOC so we can check if the opal tracepoints are
0023  * enabled via a single load.
0024  */
0025 
0026 /* NB: reg/unreg are called while guarded with the tracepoints_mutex */
0027 extern long opal_tracepoint_refcount;
0028 
0029 int opal_tracepoint_regfunc(void)
0030 {
0031     opal_tracepoint_refcount++;
0032     return 0;
0033 }
0034 
0035 void opal_tracepoint_unregfunc(void)
0036 {
0037     opal_tracepoint_refcount--;
0038 }
0039 #endif
0040 
0041 /*
0042  * Since the tracing code might execute OPAL calls we need to guard against
0043  * recursion.
0044  */
0045 static DEFINE_PER_CPU(unsigned int, opal_trace_depth);
0046 
0047 void __trace_opal_entry(unsigned long opcode, unsigned long *args)
0048 {
0049     unsigned long flags;
0050     unsigned int *depth;
0051 
0052     local_irq_save(flags);
0053 
0054     depth = this_cpu_ptr(&opal_trace_depth);
0055 
0056     if (*depth)
0057         goto out;
0058 
0059     (*depth)++;
0060     preempt_disable();
0061     trace_opal_entry(opcode, args);
0062     (*depth)--;
0063 
0064 out:
0065     local_irq_restore(flags);
0066 }
0067 
0068 void __trace_opal_exit(long opcode, unsigned long retval)
0069 {
0070     unsigned long flags;
0071     unsigned int *depth;
0072 
0073     local_irq_save(flags);
0074 
0075     depth = this_cpu_ptr(&opal_trace_depth);
0076 
0077     if (*depth)
0078         goto out;
0079 
0080     (*depth)++;
0081     trace_opal_exit(opcode, retval);
0082     preempt_enable();
0083     (*depth)--;
0084 
0085 out:
0086     local_irq_restore(flags);
0087 }