mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-10 07:00:48 +00:00
powerpc/rtas: add tracepoints around RTAS entry
Decompose the RTAS entry C code into tracing and non-tracing variants, calling the just-added tracepoints in the tracing-enabled path. Skip tracing in contexts known to be unsafe (real mode, CPU offline). Signed-off-by: Nathan Lynch <nathanl@linux.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20230125-b4-powerpc-rtas-queue-v3-11-26929c8cce78@linux.ibm.com
This commit is contained in:
parent
2c81ca7fba
commit
24098f580e
@ -38,6 +38,7 @@
|
|||||||
#include <asm/page.h>
|
#include <asm/page.h>
|
||||||
#include <asm/rtas.h>
|
#include <asm/rtas.h>
|
||||||
#include <asm/time.h>
|
#include <asm/time.h>
|
||||||
|
#include <asm/trace.h>
|
||||||
#include <asm/udbg.h>
|
#include <asm/udbg.h>
|
||||||
|
|
||||||
struct rtas_filter {
|
struct rtas_filter {
|
||||||
@ -523,24 +524,70 @@ static const struct rtas_function *rtas_token_to_function(s32 token)
|
|||||||
/* This is here deliberately so it's only used in this file */
|
/* This is here deliberately so it's only used in this file */
|
||||||
void enter_rtas(unsigned long);
|
void enter_rtas(unsigned long);
|
||||||
|
|
||||||
|
static void __do_enter_rtas(struct rtas_args *args)
|
||||||
|
{
|
||||||
|
enter_rtas(__pa(args));
|
||||||
|
srr_regs_clobbered(); /* rtas uses SRRs, invalidate */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __do_enter_rtas_trace(struct rtas_args *args)
|
||||||
|
{
|
||||||
|
const char *name = NULL;
|
||||||
|
/*
|
||||||
|
* If the tracepoints that consume the function name aren't
|
||||||
|
* active, avoid the lookup.
|
||||||
|
*/
|
||||||
|
if ((trace_rtas_input_enabled() || trace_rtas_output_enabled())) {
|
||||||
|
const s32 token = be32_to_cpu(args->token);
|
||||||
|
const struct rtas_function *func = rtas_token_to_function(token);
|
||||||
|
|
||||||
|
name = func->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
trace_rtas_input(args, name);
|
||||||
|
trace_rtas_ll_entry(args);
|
||||||
|
|
||||||
|
__do_enter_rtas(args);
|
||||||
|
|
||||||
|
trace_rtas_ll_exit(args);
|
||||||
|
trace_rtas_output(args, name);
|
||||||
|
}
|
||||||
|
|
||||||
static void do_enter_rtas(struct rtas_args *args)
|
static void do_enter_rtas(struct rtas_args *args)
|
||||||
{
|
{
|
||||||
unsigned long msr;
|
const unsigned long msr = mfmsr();
|
||||||
|
/*
|
||||||
|
* Situations where we want to skip any active tracepoints for
|
||||||
|
* safety reasons:
|
||||||
|
*
|
||||||
|
* 1. The last code executed on an offline CPU as it stops,
|
||||||
|
* i.e. we're about to call stop-self. The tracepoints'
|
||||||
|
* function name lookup uses xarray, which uses RCU, which
|
||||||
|
* isn't valid to call on an offline CPU. Any events
|
||||||
|
* emitted on an offline CPU will be discarded anyway.
|
||||||
|
*
|
||||||
|
* 2. In real mode, as when invoking ibm,nmi-interlock from
|
||||||
|
* the pseries MCE handler. We cannot count on trace
|
||||||
|
* buffers or the entries in rtas_token_to_function_xarray
|
||||||
|
* to be contained in the RMO.
|
||||||
|
*/
|
||||||
|
const unsigned long mask = MSR_IR | MSR_DR;
|
||||||
|
const bool can_trace = likely(cpu_online(raw_smp_processor_id()) &&
|
||||||
|
(msr & mask) == mask);
|
||||||
/*
|
/*
|
||||||
* Make sure MSR[RI] is currently enabled as it will be forced later
|
* Make sure MSR[RI] is currently enabled as it will be forced later
|
||||||
* in enter_rtas.
|
* in enter_rtas.
|
||||||
*/
|
*/
|
||||||
msr = mfmsr();
|
|
||||||
BUG_ON(!(msr & MSR_RI));
|
BUG_ON(!(msr & MSR_RI));
|
||||||
|
|
||||||
BUG_ON(!irqs_disabled());
|
BUG_ON(!irqs_disabled());
|
||||||
|
|
||||||
hard_irq_disable(); /* Ensure MSR[EE] is disabled on PPC64 */
|
hard_irq_disable(); /* Ensure MSR[EE] is disabled on PPC64 */
|
||||||
|
|
||||||
enter_rtas(__pa(args));
|
if (can_trace)
|
||||||
|
__do_enter_rtas_trace(args);
|
||||||
srr_regs_clobbered(); /* rtas uses SRRs, invalidate */
|
else
|
||||||
|
__do_enter_rtas(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct rtas_t rtas;
|
struct rtas_t rtas;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user