[DTrace-devel] [PATCH 2/3] Provide and use standard functions to clear or copy CPU registers
Kris Van Hees
kris.van.hees at oracle.com
Tue Jul 6 10:56:04 PDT 2021
On Fri, Jul 02, 2021 at 02:48:27PM -0400, Eugene Loh wrote:
> Reviewed-by: Eugene Loh <eugene.loh at oracle.com>
> Out of personal curiosity, why are %r7 and %r8 handled differently?
> That is, r7 is hardwired into the callees while r8 is passed in as an
> arg. Why not consistent? That is, both hardwired in or (more likely)
> both passed in as args?
The main reason is a bit historical. The prologue to the trampoline sets up
%r7 and %r8 as specific values. Those may be used by the provider-specific
code to do some work, and then there are other trampoline functions we call
that depend on %r7. We use %r8 or a derivative value when we need to pass
access to the pt_regs struct.
I could perhaps pass %r7 as a return value from the prologue, and then pass
it to the other functions, but the desisgn right now is very much based on
%r7 being reserved for this use during the trampoline creation. Passing it
as a value would make it seem more 'dynamic' (in my opinion) than it really is.
Kris
> On 7/2/21 2:19 PM, Kris Van Hees wrote:
> > Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
> > ---
> > libdtrace/dt_cg.c | 44 +++++++++++++++++++++++++++++++++++++
> > libdtrace/dt_cg.h | 2 ++
> > libdtrace/dt_dctx.h | 2 --
> > libdtrace/dt_prov_dtrace.c | 16 +-------------
> > libdtrace/dt_prov_fbt.c | 11 +---------
> > libdtrace/dt_prov_pid.c | 16 +-------------
> > libdtrace/dt_prov_profile.c | 13 +----------
> > libdtrace/dt_prov_sdt.c | 16 +++-----------
> > libdtrace/dt_prov_syscall.c | 11 +---------
> > 9 files changed, 54 insertions(+), 77 deletions(-)
> >
> > diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
> > index 99e5c05a..be61b4b0 100644
> > --- a/libdtrace/dt_cg.c
> > +++ b/libdtrace/dt_cg.c
> > @@ -196,6 +196,50 @@ dt_cg_tramp_prologue(dt_pcb_t *pcb)
> > dt_cg_tramp_prologue_act(pcb, DT_ACTIVITY_ACTIVE);
> > }
> >
> > +/*
> > + * Clear the content of the 'regs' member of the machine state.
> > + *
> > + * The caller must ensure that %r7 contains the value set by the
> > + * dt_cg_tramp_prologue*() functions.
> > + */
> > +void
> > +dt_cg_tramp_clear_regs(dt_pcb_t *pcb)
> > +{
> > + dt_irlist_t *dlp = &pcb->pcb_ir;
> > + int i;
> > +
> > + /*
> > + * memset(&dctx->mst->regs, 0, sizeof(dt_pt_regs);
> > + * // stdw [%7 + DMST_REGS + 0 * 8], 0
> > + * // stdw [%7 + DMST_REGS + 1 * 8], 0
> > + * // (...)
> > + */
> > + for (i = 0; i < sizeof(dt_pt_regs); i += 8)
> > + emit(dlp, BPF_STORE_IMM(BPF_DW, BPF_REG_7, DMST_REGS + i, 0));
> > +}
> > +
> > +/*
> > + * Copy the content of a dt_pt_regs structure referenced by the 'rp' argument
> > + * into the 'regs' member of the machine state.
> > + *
> > + * The caller must ensure that %r7 contains the value set by the
> > + * dt_cg_tramp_prologue*() functions.
> > + */
> > +void
> > +dt_cg_tramp_copy_regs(dt_pcb_t *pcb, int rp)
> > +{
> > + dt_irlist_t *dlp = &pcb->pcb_ir;
> > + int i;
> > +
> > + /*
> > + * dctx->mst->regs = *(dt_pt_regs *)rp;
> > + */
> > + for (i = 0; i < sizeof(dt_pt_regs); i += 8) {
> > + emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_8, i));
> > + emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_REGS + i, BPF_REG_0));
> > + }
> > +}
> > +
> > /*
> > * Copy arguments from a dt_pt_regs structure referenced by the 'rp' argument.
> > *
> > diff --git a/libdtrace/dt_cg.h b/libdtrace/dt_cg.h
> > index 96ce56f8..5752151b 100644
> > --- a/libdtrace/dt_cg.h
> > +++ b/libdtrace/dt_cg.h
> > @@ -22,6 +22,8 @@ extern void dt_cg_xsetx(dt_irlist_t *, dt_ident_t *, uint_t, int, uint64_t);
> > extern dt_irnode_t *dt_cg_node_alloc(uint_t, struct bpf_insn);
> > extern void dt_cg_tramp_prologue_act(dt_pcb_t *pcb, dt_activity_t act);
> > extern void dt_cg_tramp_prologue(dt_pcb_t *pcb);
> > +extern void dt_cg_tramp_clear_regs(dt_pcb_t *pcb);
> > +extern void dt_cg_tramp_copy_regs(dt_pcb_t *pcb, int rp);
> > extern void dt_cg_tramp_copy_args_from_regs(dt_pcb_t *pcb, int rp);
> > extern void dt_cg_tramp_call_clauses(dt_pcb_t *pcb, const dt_probe_t *prp,
> > dt_activity_t act);
> > diff --git a/libdtrace/dt_dctx.h b/libdtrace/dt_dctx.h
> > index f0d42f4b..c065dc70 100644
> > --- a/libdtrace/dt_dctx.h
> > +++ b/libdtrace/dt_dctx.h
> > @@ -25,9 +25,7 @@ typedef struct dt_mstate {
> > int32_t syscall_errno; /* syscall errno */
> > uint64_t fault; /* DTrace fault flags */
> > uint64_t tstamp; /* cached timestamp value */
> > -#if 0
> > dt_pt_regs regs; /* CPU registers */
> > -#endif
> > uint64_t argv[10]; /* Probe arguments */
> > } dt_mstate_t;
> >
> > diff --git a/libdtrace/dt_prov_dtrace.c b/libdtrace/dt_prov_dtrace.c
> > index 1c40c233..c8a55475 100644
> > --- a/libdtrace/dt_prov_dtrace.c
> > +++ b/libdtrace/dt_prov_dtrace.c
> > @@ -155,21 +155,7 @@ static void trampoline(dt_pcb_t *pcb)
> > emit(dlp, BPF_MOV_IMM(BPF_REG_4, BPF_ANY));
> > emit(dlp, BPF_CALL_HELPER(BPF_FUNC_map_update_elem));
> >
> > -#if 0
> > - /*
> > - * dctx->mst->regs = *(dt_pt_regs *)dctx->ctx;
> > - * // lddw %r0, [%r8 + 0]
> > - * // stdw [%r7 + DMST_REGS + 0], %r0
> > - * // lddw %r0, [%r8 + 8]
> > - * // stdw [%r7 + DMST_REGS + 8], %r0
> > - * // (...)
> > - */
> > - for (i = 0; i < sizeof(dt_pt_regs); i += 8) {
> > - emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_8, i));
> > - emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_REGS + i, BPF_REG_0));
> > - }
> > -#endif
> > -
> > + dt_cg_tramp_copy_regs(pcb, BPF_REG_8);
> > dt_cg_tramp_copy_args_from_regs(pcb, BPF_REG_8);
> >
> > dt_cg_tramp_epilogue_advance(pcb, act);
> > diff --git a/libdtrace/dt_prov_fbt.c b/libdtrace/dt_prov_fbt.c
> > index 80bbf721..62fea51e 100644
> > --- a/libdtrace/dt_prov_fbt.c
> > +++ b/libdtrace/dt_prov_fbt.c
> > @@ -168,16 +168,7 @@ static void trampoline(dt_pcb_t *pcb)
> > * // (%r8 = dctx->ctx)
> > */
> >
> > -#if 0
> > - /*
> > - * dctx->mst->regs = *(dt_pt_regs *)dctx->ctx;
> > - */
> > - for (i = 0; i < sizeof(dt_pt_regs); i += 8) {
> > - emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_8, i));
> > - emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_REGS + i, BPF_REG_0));
> > - }
> > -#endif
> > -
> > + dt_cg_tramp_copy_regs(pcb, BPF_REG_8);
> > dt_cg_tramp_copy_args_from_regs(pcb, BPF_REG_8);
> > dt_cg_tramp_epilogue(pcb);
> > }
> > diff --git a/libdtrace/dt_prov_pid.c b/libdtrace/dt_prov_pid.c
> > index 2e9c5bee..af894f79 100644
> > --- a/libdtrace/dt_prov_pid.c
> > +++ b/libdtrace/dt_prov_pid.c
> > @@ -210,21 +210,7 @@ static void trampoline(dt_pcb_t *pcb)
> > * // (%r8 = dctx->ctx)
> > */
> >
> > -#if 0
> > - /*
> > - * dctx->mst->regs = *(dt_pt_regs *)dctx->ctx;
> > - * // lddw %r0, [%r8 + 0]
> > - * // stdw [%r7 + DMST_REGS + 0], %r0
> > - * // lddw %r0, [%r8 + 8]
> > - * // stdw [%r7 + DMST_REGS + 8], %r0
> > - * // (...)
> > - */
> > - for (i = 0; i < sizeof(dt_pt_regs); i += 8) {
> > - emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_8, i));
> > - emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_REGS + i, BPF_REG_0));
> > - }
> > -#endif
> > -
> > + dt_cg_tramp_copy_regs(pcb, BPF_REG_8);
> > dt_cg_tramp_copy_args_from_regs(pcb, BPF_REG_8);
> >
> > /*
> > diff --git a/libdtrace/dt_prov_profile.c b/libdtrace/dt_prov_profile.c
> > index 313c8c9c..caa414ca 100644
> > --- a/libdtrace/dt_prov_profile.c
> > +++ b/libdtrace/dt_prov_profile.c
> > @@ -226,18 +226,7 @@ static void trampoline(dt_pcb_t *pcb)
> > * // (%r8 = dctx->ctx)
> > */
> >
> > -#if 0
> > - /*
> > - * dctx->mst->regs = *(dt_pt_regs *)&dctx->ctx->regs;
> > - * // (we use the fact that regs is the
> > - * // member at offset 0, and there can
> > - * // copy *(dt_pt_regs *)dctx->ctx)
> > - */
> > - for (i = 0; i < sizeof(dt_pt_regs); i += 8) {
> > - emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_8, i));
> > - emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_REGS + i, BPF_REG_0));
> > - }
> > -#endif
> > + dt_cg_tramp_copy_regs(pcb, BPF_REG_8);
> >
> > /*
> > * TODO:
> > diff --git a/libdtrace/dt_prov_sdt.c b/libdtrace/dt_prov_sdt.c
> > index 320edbd2..712f533f 100644
> > --- a/libdtrace/dt_prov_sdt.c
> > +++ b/libdtrace/dt_prov_sdt.c
> > @@ -121,7 +121,7 @@ static int populate(dtrace_hdl_t *dtp)
> > * The trampoline function is called when a SDT probe triggers, and it must
> > * satisfy the following prototype:
> > *
> > - * int dt_sdt(struct syscall_data *scd)
> > + * int dt_sdt(void *data)
> > *
> > * The trampoline will populate a dt_dctx_t struct and then call the function
> > * that implements the compiled D clause. It returns the value that it gets
> > @@ -142,17 +142,7 @@ static void trampoline(dt_pcb_t *pcb)
> > * // (%r8 = dctx->ctx)
> > */
> >
> > -#if 0
> > - /*
> > - * memset(&dctx->mst->regs, 0, sizeof(dt_pt_regs);
> > - * // stdw [%7 + DMST_REGS + 0], 0
> > - * // stdw [%7 + DMST_REGS + 8], 0
> > - * // (...)
> > - */
> > - for (i = 0; i < sizeof(dt_pt_regs); i += 8) {
> > - emit(dlp, BPF_STORE_IMM(BPF_DW, BPF_REG_7, DMST_REGS + i, 0));
> > - }
> > -#endif
> > + dt_cg_tramp_clear_regs(pcb);
> >
> > /*
> > * for (i = 0; i < ARRAY_SIZE(((dt_mstate_t *)0)->argv); i++)
> > @@ -175,7 +165,7 @@ static int probe_info(dtrace_hdl_t *dtp, const dt_probe_t *prp,
> >
> > /*
> > * If the tracepoint has already been created and we have its info,
> > - * there is no need to retrive the info again.
> > + * there is no need to retrieve the info again.
> > */
> > if (dt_tp_is_created(tpp))
> > return -1;
> > diff --git a/libdtrace/dt_prov_syscall.c b/libdtrace/dt_prov_syscall.c
> > index bbf45888..2c6644d4 100644
> > --- a/libdtrace/dt_prov_syscall.c
> > +++ b/libdtrace/dt_prov_syscall.c
> > @@ -156,16 +156,7 @@ static void trampoline(dt_pcb_t *pcb)
> > * // (%r8 = dctx->ctx)
> > */
> >
> > -#if 0
> > - /*
> > - * memset(&dctx->mst->regs, 0, sizeof(dt_pt_regs);
> > - * // stdw [%7 + DMST_REGS + 0], 0
> > - * // stdw [%7 + DMST_REGS + 8], 0
> > - * // (...)
> > - */
> > - for (i = 0; i < sizeof(dt_pt_regs); i += 8)
> > - emit(dlp, BPF_STORE_IMM(BPF_DW, BPF_REG_7, DMST_REGS + i, 0));
> > -#endif
> > + dt_cg_tramp_clear_regs(pcb);
> >
> > /*
> > * for (i = 0; i < argc; i++)
>
> _______________________________________________
> DTrace-devel mailing list
> DTrace-devel at oss.oracle.com
> https://oss.oracle.com/mailman/listinfo/dtrace-devel
More information about the DTrace-devel
mailing list