The Linux Kernel Mailing List
 help / color / mirror / Atom feed
From: Kuan-Wei Chiu <visitorckw@gmail.com>
To: Nicholas Dudar <main.kalliope@gmail.com>
Cc: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org,
	eddyz87@gmail.com, memxor@gmail.com, davem@davemloft.net,
	andreas@gaisler.com, bpf@vger.kernel.org,
	sparclinux@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH bpf-next] bpf, sparc: Add support for BPF_SDIV and BPF_SMOD in the sparc64 JIT
Date: Wed, 29 Jul 2026 08:33:15 +0800	[thread overview]
Message-ID: <amlKS9s1YYh5mOEi@google.com> (raw)
In-Reply-To: <20260716151110.1716607-1-main.kalliope@gmail.com>

On Thu, Jul 16, 2026 at 11:11:10AM -0400, Nicholas Dudar wrote:
> build_insn()'s div/mod emit sites pick DIV/UDIVX by ALU width only,
> never by insn->off, so the sparc64 JIT does not implement signed
> BPF_SDIV and BPF_SMOD (off == 1). Signed ALU32 and ALU64 div/mod get
> an unsigned quotient and remainder rather than the verifier's and the
> interpreter's signed result for negative operands.
> 
> Emit SDIV/SDIVX on the signed path across the ALU32 and ALU64, X-form
> and K-form div/mod sites. The 32-bit signed divide takes a 64-bit
> dividend from %y:dst, so sign-fill %y from dst before SDIV where the
> unsigned path zeroes it; the 64-bit SDIVX skips the %y write. Route the
> signed ALU32 result through do_alu32_trunc, since SDIV does not leave
> bits 63:32 clear the way unsigned DIV does.
> 
> The verifier and bpf_do_misc_fixups() remove the zero divisor and
> INT_MIN / -1 cases before the JIT runs.
> 
> Signed-off-by: Nicholas Dudar <main.kalliope@gmail.com>
> Assisted-by: Claude:claude-opus-4-8
> ---
>  arch/sparc/net/bpf_jit_comp_64.c | 92 +++++++++++++++++++++++++++-----
>  1 file changed, 80 insertions(+), 12 deletions(-)

I saw that your bpf jit patches span multiple architectures.
Assuming you don't have access to all these different hardware platforms.
Just out of curiosity how were these patches tested?

Regards,
Kuan-Wei

> 
> diff --git a/arch/sparc/net/bpf_jit_comp_64.c b/arch/sparc/net/bpf_jit_comp_64.c
> index 2fa0e9375127..6de9fb29944c 100644
> --- a/arch/sparc/net/bpf_jit_comp_64.c
> +++ b/arch/sparc/net/bpf_jit_comp_64.c
> @@ -149,6 +149,8 @@ static u32 WDISP10(u32 off)
>  #define MULX		F3(2, 0x09)
>  #define UDIVX		F3(2, 0x0d)
>  #define DIV		F3(2, 0x0e)
> +#define SDIV		F3(2, 0x0f)
> +#define SDIVX		F3(2, 0x2d)
>  #define SLL		F3(2, 0x25)
>  #define SLLX		(F3(2, 0x25)|(1<<12))
>  #define SRA		F3(2, 0x27)
> @@ -941,32 +943,69 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
>  	case BPF_ALU64 | BPF_MUL | BPF_X:
>  		emit_alu(MULX, src, dst, ctx);
>  		break;
> -	case BPF_ALU | BPF_DIV | BPF_X:
> +	case BPF_ALU | BPF_DIV | BPF_X: {
> +		const bool is_signed = (off == 1);
> +
> +		if (is_signed) {
> +			const u8 tmp = bpf2sparc[TMP_REG_1];
> +
> +			ctx->tmp_1_used = true;
> +
> +			/* Sign-extend dst into %y for 32-bit sdiv. */
> +			emit_alu3_K(SRA, dst, 31, tmp, ctx);
> +			emit_write_y(tmp, ctx);
> +			emit_alu(SDIV, src, dst, ctx);
> +			/*
> +			 * SDIV does not guarantee the zero-extension that
> +			 * the unsigned DIV path relies on, so clear bits
> +			 * 63:32 through the shared truncation instead of
> +			 * consuming the verifier's zext marker, as the
> +			 * other ALU32 ops do.
> +			 */
> +			goto do_alu32_trunc;
> +		}
>  		emit_write_y(G0, ctx);
>  		emit_alu(DIV, src, dst, ctx);
>  		if (insn_is_zext(&insn[1]))
>  			return 1;
>  		break;
> +	}
>  	case BPF_ALU64 | BPF_DIV | BPF_X:
> -		emit_alu(UDIVX, src, dst, ctx);
> +		if (off == 1)
> +			emit_alu(SDIVX, src, dst, ctx);
> +		else
> +			emit_alu(UDIVX, src, dst, ctx);
>  		break;
>  	case BPF_ALU | BPF_MOD | BPF_X: {
>  		const u8 tmp = bpf2sparc[TMP_REG_1];
> +		const bool is_signed = (off == 1);
>  
>  		ctx->tmp_1_used = true;
>  
> -		emit_write_y(G0, ctx);
> -		emit_alu3(DIV, dst, src, tmp, ctx);
> +		if (is_signed) {
> +			const u8 tmp2 = bpf2sparc[TMP_REG_2];
> +
> +			ctx->tmp_2_used = true;
> +
> +			/* Sign-extend dst into %y for 32-bit sdiv. */
> +			emit_alu3_K(SRA, dst, 31, tmp2, ctx);
> +			emit_write_y(tmp2, ctx);
> +			emit_alu3(SDIV, dst, src, tmp, ctx);
> +		} else {
> +			emit_write_y(G0, ctx);
> +			emit_alu3(DIV, dst, src, tmp, ctx);
> +		}
>  		emit_alu3(MULX, tmp, src, tmp, ctx);
>  		emit_alu3(SUB, dst, tmp, dst, ctx);
>  		goto do_alu32_trunc;
>  	}
>  	case BPF_ALU64 | BPF_MOD | BPF_X: {
>  		const u8 tmp = bpf2sparc[TMP_REG_1];
> +		const unsigned int mod = (off == 1) ? SDIVX : UDIVX;
>  
>  		ctx->tmp_1_used = true;
>  
> -		emit_alu3(UDIVX, dst, src, tmp, ctx);
> +		emit_alu3(mod, dst, src, tmp, ctx);
>  		emit_alu3(MULX, tmp, src, tmp, ctx);
>  		emit_alu3(SUB, dst, tmp, dst, ctx);
>  		break;
> @@ -1096,33 +1135,62 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
>  	case BPF_ALU64 | BPF_MUL | BPF_K:
>  		emit_alu_K(MULX, dst, imm, ctx);
>  		break;
> -	case BPF_ALU | BPF_DIV | BPF_K:
> +	case BPF_ALU | BPF_DIV | BPF_K: {
> +		const bool is_signed = (off == 1);
> +
>  		if (imm == 0)
>  			return -EINVAL;
>  
> -		emit_write_y(G0, ctx);
> -		emit_alu_K(DIV, dst, imm, ctx);
> +		if (is_signed) {
> +			const u8 tmp = bpf2sparc[TMP_REG_2];
> +
> +			ctx->tmp_2_used = true;
> +
> +			/* Sign-extend dst into %y for 32-bit sdiv. */
> +			emit_alu3_K(SRA, dst, 31, tmp, ctx);
> +			emit_write_y(tmp, ctx);
> +			emit_alu_K(SDIV, dst, imm, ctx);
> +		} else {
> +			emit_write_y(G0, ctx);
> +			emit_alu_K(DIV, dst, imm, ctx);
> +		}
>  		goto do_alu32_trunc;
> +	}
>  	case BPF_ALU64 | BPF_DIV | BPF_K:
>  		if (imm == 0)
>  			return -EINVAL;
>  
> -		emit_alu_K(UDIVX, dst, imm, ctx);
> +		emit_alu_K((off == 1) ? SDIVX : UDIVX, dst, imm, ctx);
>  		break;
>  	case BPF_ALU64 | BPF_MOD | BPF_K:
>  	case BPF_ALU | BPF_MOD | BPF_K: {
>  		const u8 tmp = bpf2sparc[TMP_REG_2];
> +		const bool is_signed = (off == 1);
>  		unsigned int div;
>  
>  		if (imm == 0)
>  			return -EINVAL;
>  
> -		div = (BPF_CLASS(code) == BPF_ALU64) ? UDIVX : DIV;
> +		if (BPF_CLASS(code) == BPF_ALU64)
> +			div = is_signed ? SDIVX : UDIVX;
> +		else
> +			div = is_signed ? SDIV : DIV;
>  
>  		ctx->tmp_2_used = true;
>  
> -		if (BPF_CLASS(code) != BPF_ALU64)
> -			emit_write_y(G0, ctx);
> +		if (BPF_CLASS(code) != BPF_ALU64) {
> +			if (is_signed) {
> +				const u8 tmp3 = bpf2sparc[TMP_REG_3];
> +
> +				ctx->tmp_3_used = true;
> +
> +				/* Sign-extend dst into %y for 32-bit sdiv. */
> +				emit_alu3_K(SRA, dst, 31, tmp3, ctx);
> +				emit_write_y(tmp3, ctx);
> +			} else {
> +				emit_write_y(G0, ctx);
> +			}
> +		}
>  		if (is_simm13(imm)) {
>  			emit(div | IMMED | RS1(dst) | S13(imm) | RD(tmp), ctx);
>  			emit(MULX | IMMED | RS1(tmp) | S13(imm) | RD(tmp), ctx);
> 
> base-commit: d1f4b56417a3dc1a0600f960b14f46bd25eda89d
> -- 
> 2.34.1
> 

  reply	other threads:[~2026-07-29  0:33 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-16 15:11 [PATCH bpf-next] bpf, sparc: Add support for BPF_SDIV and BPF_SMOD in the sparc64 JIT Nicholas Dudar
2026-07-29  0:33 ` Kuan-Wei Chiu [this message]
2026-07-29  1:36   ` Nicholas Dudar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=amlKS9s1YYh5mOEi@google.com \
    --to=visitorckw@gmail.com \
    --cc=andreas@gaisler.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=davem@davemloft.net \
    --cc=eddyz87@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=main.kalliope@gmail.com \
    --cc=memxor@gmail.com \
    --cc=sparclinux@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox