[DTrace-devel] [PATCH 2/2] Handle BPF_send_signal() return value

Kris Van Hees kris.van.hees at oracle.com
Tue Jul 21 14:18:17 PDT 2020


Let's leave handling the return value of the helper for future enhancement.
DTrace on supports a single failure mode: ILLOP fault if the signal is not
valid.  Since the BPF helper may return a variety of other failures modes,
we may want to consider seeing which of those we can or want to support.

Since the ERROR probe support is still lacking, it is too early to handle
this.

On Fri, Jul 17, 2020 at 03:00:06PM -0400, eugene.loh at oracle.com wrote:
> From: Eugene Loh <eugene.loh at oracle.com>
> 
> Handle the return value of BPF_send_signal(), which is used to
> implement raise().  Specifically, if the value is nonzero, store
> it in dctx->mst->fault and jump to the exit label.
> 
> This patch is separate from the previous one, which introduced
> raise() support, for the purpose of code review.  It can be
> squashed into that previous patch if both patches are accepted.
> 
> Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
> ---
>  libdtrace/dt_cg.c | 30 ++++++++++++++++++++++++++++++
>  1 file changed, 30 insertions(+)
> 
> diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
> index e78491b7..4413e80b 100644
> --- a/libdtrace/dt_cg.c
> +++ b/libdtrace/dt_cg.c
> @@ -701,6 +701,8 @@ dt_cg_act_raise(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind)
>  	struct bpf_insn	instr;
>  	dt_irlist_t	*dlp = &pcb->pcb_ir;
>  	dt_regset_t	*drp = pcb->pcb_regs;
> +	uint_t		lbl_zero = dt_irlist_label(dlp);
> +	int		r;
>  
>  	dt_cg_node(dnp->dn_args, &pcb->pcb_ir, drp);
>  
> @@ -713,6 +715,34 @@ dt_cg_act_raise(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind)
>  	instr = BPF_CALL_HELPER(BPF_FUNC_send_signal);
>  	dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
>  	dt_regset_free_args(drp);
> +
> +	/*
> +	 * if (send_signal() != 0) {
> +	 *     // lddw %r, [%fp + DT_STK_DCTX]
> +	 *     // lddw %r, [%r + DCTX_MST]
> +	 *     // stdw [%r + DMST_FAULT], %r0
> +	 *     dctx->mst->fault = r0;
> +	 *     exit;
> +	 * }
> +	 *
> +	 * Note that we need a temporary register.
> +	 * Since we know %r1-%r5 are free, we could just use
> +	 * r=BPF_REG_1 and dispense with the dt_regset_free(drp,r).
> +	 */
> +	instr = BPF_BRANCH_IMM(BPF_JEQ, BPF_REG_0, 0, lbl_zero);
> +	dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
> +	if ((r = dt_regset_alloc(drp)) == -1)
> +		longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
> +	instr = BPF_LOAD(BPF_DW, r, BPF_REG_FP, DT_STK_DCTX);
> +	dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
> +	instr = BPF_LOAD(BPF_DW, r, r, DCTX_MST);
> +	dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
> +	instr = BPF_STORE(BPF_DW, r, DMST_FAULT, BPF_REG_0);
> +	dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
> +	dt_regset_free(drp, r);
> +	instr = BPF_JUMP(pcb->pcb_exitlbl);
> +	dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
> +	dt_irlist_append(dlp, dt_cg_node_alloc(lbl_zero, BPF_NOP()));
>  	dt_regset_free(drp, BPF_REG_0);
>  }
>  
> -- 
> 2.18.2
> 
> 
> _______________________________________________
> 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