mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Kuan-Wei Chiu <visitorckw@gmail.com>
To: Greg Ungerer <gerg@polyxeno.com>
Cc: geert@linux-m68k.org, ast@kernel.org, daniel@iogearbox.net,
	andrii@kernel.org, eddyz87@gmail.com, memxor@gmail.com,
	martin.lau@linux.dev, song@kernel.org, yonghong.song@linux.dev,
	jolsa@kernel.org, jserv@ccns.ncku.edu.tw, eleanor15x@gmail.com,
	marscheng@google.com, linux-kernel@vger.kernel.org,
	linux-m68k@lists.linux-m68k.org, bpf@vger.kernel.org,
	Daniel Palmer <daniel@thingy.jp>
Subject: Re: [PATCH bpf-next v4 RESEND] m68k, bpf: Add initial BPF JIT compiler support
Date: Mon, 24 Aug 2026 00:28:25 +0800	[thread overview]
Message-ID: <aosfqVMeIISRiv4K@google.com> (raw)
In-Reply-To: <75501d4b-7a75-4f0d-8d88-0d631016c9ab@polyxeno.com>

On Wed, Aug 12, 2026 at 09:22:59AM +1000, Greg Ungerer wrote:
> Hi Kuan-Wei,
> 
> On 10/8/26 20:04, Kuan-Wei Chiu wrote:
> > On Fri, Aug 07, 2026 at 01:28:20AM +1000, Greg Ungerer wrote:
> >> Hi Kuan-Wei,
> >>
> >> On 29/7/26 10:27, Kuan-Wei Chiu wrote:
> >>> Add a BPF JIT compiler for the m68k architecture.
> >>>
> >>> The JIT generates m68k machine code targeting m68020+ processors. It
> >>> currently excludes 68000/68010 and coldfire processors, as it relies on
> >>> 32 bit branch displacements (b<cc>.l) to handle large bpf programs.
> >>
> >> I was interested to see how difficult this would be to get working on
> >> a ColdFire target. There is a little more to it than just the 32bit
> >> branch displacements. If you limit the target space to ColdFire parts
> >> that have an MMU (so parts that have the ISA_B or ISA_C instruction
> >> set) then 32bit branch displacements are supported. So that is no longer
> >> a problem.
> >>
> >> The following are issues I hit:
> >>
> >> 1. lack of movem with pre-decrement and post-increment modes
> >>    used in quite a few places
> >>
> >> 2. lack of register exchange instruction ("exg")
> >>    used in emit_atomic()
> >>    used in emit_call()
> >>    used in 64bit bpf shitf operations in emit_alu64_shift()
> >>
> >> 3. lack of rotate instructions ("ror" and "rox")
> >>    used for bpf shift operations in emit_alu64_shift()
> >>    used for endian transformation in emit_bpf_end()
> >>
> >> Issue (1) is easy to work around, manually manipulating %sp as required
> >> with an extra instruction.
> >>
> >> Issue (2) also is easy enough, needing temporary storage.
> >>
> >> Issue (3) is annoying and means a bunch more instructions to carry
> >> out the equivalent operations. None the less it is not too difficult to
> >> modify for. ISA_C does have a "byterev" instruction that would make this
> >> really easy - but only the very most modern ColdFire silicon use that
> >> (like the 5441x family).
> >>
> >> The attached patch is my first pass at it. It works and passes the
> >> test_bpf.ko module with no failures(*). Surely could be optimized a little
> >> more, but good enough to get it working. Tested and running on an
> >> M5475 ColdFire target.
> >>
> >>     test_bpf: Summary: 1061 PASSED, 0 FAILED, [1049/1049 JIT'ed]
> >>     test_bpf: test_tail_calls: Summary: 10 PASSED, 0 FAILED, [10/10 JIT'ed]
> >>
> >>
> >> (*) I did come across a cache flush issue specific to ColdFire - but it
> >> is not related to this code and can be worked around.
> >>
> >>
> > 
> > Thanks for testing the jit and providing the patch to enable coldfire
> > support. It's great to see it running successfully on the M5475 target.
> > 
> > For v5, please let me know how you would prefer to proceed. I can
> > either squash your changes directly into my current patch, or keep your
> > work as an independent patch and send them together as a patch series.
> > Let me know what works best for you.
> 
> I am happy if you want to fold it into your existing patch if you think
> it is good enough in its current form. Breaking out the ColdFire specific
> changes into mostly separate functions seemed like the cleanest approach.

For initial support, the current form is enough for me.
I'll fold it into v5.

> 
> Do you think the Kconfig change - to only condition on MMU - is enough?
> I figured that would exclude plain 68000 as well.

I haven't tested it on plain 68000 yet, so conditioning on mmu is
enough for now.

Regards,
Kuan-Wei

> >>
> > 
> >> --- a/arch/m68k/net/bpf_jit_comp.c
> >> +++ b/arch/m68k/net/bpf_jit_comp.c
> >> @@ -518,6 +518,47 @@
> >>  	bpf_put_reg32(dst[0], d_hi, ctx);
> >>  }
> >>  
> >> +static inline void emit_lsh64(struct jit_ctx *ctx, s8 d_lo, s8 d_hi)
> >> +{
> >> +	if (CPU_IS_COLDFIRE) {
> >> +		emit_16(ctx, 0xd080 | (d_lo << 9) | d_lo);		/* add.l d_lo, d_lo */
> >> +		emit_16(ctx, 0xd180 | (d_hi << 9) | d_hi);		/* addx.l d_hi, d_hi */
> >> +	} else {
> >> +		emit_16(ctx, 0xe388 | d_lo);				/* lsll #1, d_lo */
> >> +		emit_16(ctx, 0xe390 | d_hi);				/* roxl.l #1, d_hi */
> >> +	}
> >> +}
> >> +
> >> +static inline void emit_rsh64(struct jit_ctx *ctx, s8 d_lo, s8 d_hi)
> >> +{
> >> +	if (CPU_IS_COLDFIRE) {
> >> +		emit_16(ctx, 0xe288 | d_lo);				/* lsr.l #1, d_lo */
> >> +		emit_16(ctx, 0xe288 | d_hi);				/* lsr.l #1, d_hi */
> >> +		emit_16(ctx, 0x6400);					/* bcc 1f */
> >> +		emit_16(ctx, 0x0006);
> >> +		emit_16(ctx, 0x08c0 | d_lo);				/* bset #31, d_lo */
> >> +		emit_16(ctx, 0x001f);
> >> +	} else {
> >> +		emit_16(ctx, 0xe288 | d_hi);				/* lsrl #1, d_hi */
> >> +		emit_16(ctx, 0xe290 | d_lo);				/* roxr.l #1, d_lo */
> >> +	}
> >> +}
> >> +
> >> +static inline void emit_arsh64(struct jit_ctx *ctx, s8 d_lo, s8 d_hi)
> >> +{
> >> +	if (CPU_IS_COLDFIRE) {
> >> +		emit_16(ctx, 0xe288 | d_lo);				/* lsr.l #1, d_lo */
> >> +		emit_16(ctx, 0xe280 | d_hi);				/* asr.l #1, d_hi */
> >> +		emit_16(ctx, 0x6400);					/* bcc 1f */
> >> +		emit_16(ctx, 0x0006);
> >> +		emit_16(ctx, 0x08c0 | d_lo);				/* bset #31, d_lo */
> >> +		emit_16(ctx, 0x001f);
> >> +	} else {
> >> +		emit_16(ctx, 0xe280 | d_hi);				/* asrl #1, d_hi */
> >> +		emit_16(ctx, 0xe290 | d_lo);				/* roxr.l #1, d_lo */
> >> +	}
> >> +}
> >> +
> >>  static void emit_alu64_shift(const struct bpf_insn *insn, struct jit_ctx *ctx, bool is_imm)
> >>  {
> >>  	const s8 *dst = bpf2m68k[insn->dst_reg];
> >> @@ -551,16 +592,12 @@
> >>  
> >>  	loop_start = ctx->idx;
> >>  
> >> -	if (BPF_OP(insn->code) == BPF_LSH) {
> >> -		emit_16(ctx, 0xe388 | d_lo);				/* lsll #1, d_lo */
> >> -		emit_16(ctx, 0xe390 | d_hi);				/* roxl.l #1, d_hi */
> >> -	} else if (BPF_OP(insn->code) == BPF_RSH) {
> >> -		emit_16(ctx, 0xe288 | d_hi);				/* lsrl #1, d_hi */
> >> -		emit_16(ctx, 0xe290 | d_lo);				/* roxr.l #1, d_lo */
> >> -	} else if (BPF_OP(insn->code) == BPF_ARSH) {
> >> -		emit_16(ctx, 0xe280 | d_hi);				/* asrl #1, d_hi */
> >> -		emit_16(ctx, 0xe290 | d_lo);				/* roxr.l #1, d_lo */
> >> -	}
> >> +	if (BPF_OP(insn->code) == BPF_LSH)
> >> +		emit_lsh64(ctx, d_lo, d_hi);
> >> +	else if (BPF_OP(insn->code) == BPF_RSH)
> >> +		emit_rsh64(ctx, d_lo, d_hi);
> >> +	else if (BPF_OP(insn->code) == BPF_ARSH)
> >> +		emit_arsh64(ctx, d_lo, d_hi);
> >>  
> >>  	emit_16(ctx, 0x5380 | count_reg);				/* subq.l #1, count_reg */
> >>  	emit_16(ctx, 0x6600);						/* bne.w loop_start */
> >> @@ -573,6 +610,107 @@
> >>  	bpf_put_reg32(dst[0], d_hi, ctx);
> >>  }
> >>  
> >> +static inline void emit_to_le16(struct jit_ctx *ctx, s8 d_lo, s8 d_hi)
> >> +{
> >> +	if (CPU_IS_COLDFIRE) {
> >> +		emit_16(ctx, 0x71c0 | (d_lo << 9) | d_lo);		/* mvz.w d_lo, d_lo */
> >> +		emit_16(ctx, 0x7180 | (d_hi << 9) | d_lo);		/* mvz.b d_lo, d_hi */
> >> +		emit_16(ctx, 0xe088 | d_lo);				/* lsr.l #8, d_lo */
> >> +		emit_16(ctx, 0xe188 | d_hi);				/* lsl.l #8, d_hi */
> >> +		emit_16(ctx, 0x8080 | (d_lo << 9) | d_hi);		/* or.l d_hi, d_lo */
> >> +	} else {
> >> +		emit_16(ctx, 0x0280 | d_lo);				/* andi.l #0xffff, d_lo */
> >> +		emit_32(ctx, 0xffff);
> >> +		emit_16(ctx, 0xe058 | d_lo);				/* ror.w #8, d_lo */
> >> +	}
> >> +
> >> +	emit_16(ctx, 0x7000 | (d_hi << 9));				/* moveq #0, d_hi */
> >> +}
> >> +
> >> +static inline void emit_to_le32(struct jit_ctx *ctx, s8 d_lo, s8 d_hi)
> >> +{
> >> +	if (CPU_IS_COLDFIRE) {
> >> +		emit_16(ctx, 0x2f00 | d_lo);				/* move.l d_lo, -(%sp) */
> >> +		emit_16(ctx, 0x4840 | d_lo);				/* swap d_lo */
> >> +		emit_16(ctx, 0x71c0 | (d_lo << 9) | d_lo);		/* mvz.w d_lo, d_lo */
> >> +		emit_16(ctx, 0x7180 | (d_hi << 9) | d_lo);		/* mvz.b d_lo, d_hi */
> >> +		emit_16(ctx, 0xe088 | d_lo);				/* lsr.l #8, d_lo */
> >> +		emit_16(ctx, 0xe188 | d_hi);				/* lsl.l #8, d_hi */
> >> +		emit_16(ctx, 0x8080 | (d_hi << 9) | d_lo);		/* or.l d_lo, d_hi */
> >> +		emit_16(ctx, 0x2017 | (d_lo << 9));			/* move.l (%sp), d_lo */
> >> +		emit_16(ctx, 0x2e80 | d_hi);				/* move.l d_hi, (%sp) */
> >> +		emit_16(ctx, 0x71c0 | (d_lo << 9) | d_lo);		/* mvz.w d_lo, d_lo */
> >> +		emit_16(ctx, 0x7180 | (d_hi << 9) | d_lo);		/* mvz.b d_lo, d_hi */
> >> +		emit_16(ctx, 0xe088 | d_lo);				/* lsr.l #8, d_lo */
> >> +		emit_16(ctx, 0xe188 | d_hi);				/* lsl.l #8, d_hi */
> >> +		emit_16(ctx, 0x8080 | (d_lo << 9) | d_hi);		/* or.l d_hi, d_lo */
> >> +		emit_16(ctx, 0x4840 | d_lo);				/* swap d_lo */
> >> +		emit_16(ctx, 0x809f | (d_lo << 9));			/* or.l (%sp)+, d_lo */
> >> +	} else {
> >> +		emit_16(ctx, 0xe058 | d_lo);				/* ror.w #8, d_lo */
> >> +		emit_16(ctx, 0x4840 | d_lo);				/* swap d_lo */
> >> +		emit_16(ctx, 0xe058 | d_lo);				/* ror.w #8, d_lo */
> >> +	}
> >> +
> >> +	emit_16(ctx, 0x7000 | (d_hi << 9));				/* moveq #0, d_hi */
> >> +}
> >> +
> >> +static inline void emit_to_le64(struct jit_ctx *ctx, s8 d_lo, s8 d_hi)
> >> +{
> >> +	if (CPU_IS_COLDFIRE) {
> >> +		emit_16(ctx, 0x2f00 | d_lo);				/* move.l d_lo, -(%sp) */
> >> +		emit_16(ctx, 0x2f00 | d_hi);				/* move.l d_hi, -(%sp) */
> >> +
> >> +		emit_16(ctx, 0x4840 | d_lo);				/* swap d_lo */
> >> +		emit_16(ctx, 0x71c0 | (d_lo << 9) | d_lo);		/* mvz.w d_lo, d_lo */
> >> +		emit_16(ctx, 0x7180 | (d_hi << 9) | d_lo);		/* mvz.b d_lo, d_hi */
> >> +		emit_16(ctx, 0xe088 | d_lo);				/* lsr.l #8, d_lo */
> >> +		emit_16(ctx, 0xe188 | d_hi);				/* lsl.l #8, d_hi */
> >> +		emit_16(ctx, 0x8080 | (d_hi << 9) | d_lo);		/* or.l d_lo, d_hi */
> >> +		emit_16(ctx, 0x202f | (d_lo << 9));			/* move.l 4(%sp), d_lo */
> >> +		emit_16(ctx, 0x0004);
> >> +		emit_16(ctx, 0x2f40 | d_hi);				/* move.l d_hi, 4(%sp) */
> >> +		emit_16(ctx, 0x0004);
> >> +		emit_16(ctx, 0x71c0 | (d_lo << 9) | d_lo);		/* mvz.w d_lo, d_lo */
> >> +		emit_16(ctx, 0x7180 | (d_hi << 9) | d_lo);		/* mvz.b d_lo, d_hi */
> >> +		emit_16(ctx, 0xe088 | d_lo);				/* lsr.l #8, d_lo */
> >> +		emit_16(ctx, 0xe188 | d_hi);				/* lsl.l #8, d_hi */
> >> +		emit_16(ctx, 0x8080 | (d_lo << 9) | d_hi);		/* or.l d_hi, d_lo */
> >> +		emit_16(ctx, 0x4840 | d_lo);				/* swap d_lo */
> >> +		emit_16(ctx, 0x81af | (d_lo << 9));			/* or.l d_lo, 4(%sp) */
> >> +		emit_16(ctx, 0x0004);
> >> +
> >> +		emit_16(ctx, 0x2017 | (d_lo << 9));			/* move.l (%sp), d_lo */
> >> +		emit_16(ctx, 0x4840 | d_lo);				/* swap d_lo */
> >> +		emit_16(ctx, 0x71c0 | (d_lo << 9) | d_lo);		/* mvz.w d_lo, d_lo */
> >> +		emit_16(ctx, 0x7180 | (d_hi << 9) | d_lo);		/* mvz.b d_lo, d_hi */
> >> +		emit_16(ctx, 0xe088 | d_lo);				/* lsr.l #8, d_lo */
> >> +		emit_16(ctx, 0xe188 | d_hi);				/* lsl.l #8, d_hi */
> >> +		emit_16(ctx, 0x8080 | (d_hi << 9) | d_lo);		/* or.l d_lo, d_hi */
> >> +		emit_16(ctx, 0x2017 | (d_lo << 9));			/* move.l (%sp), d_lo */
> >> +		emit_16(ctx, 0x2e80 | d_hi);				/* move.l d_hi, (%sp) */
> >> +		emit_16(ctx, 0x71c0 | (d_lo << 9) | d_lo);		/* mvz.w d_lo, d_lo */
> >> +		emit_16(ctx, 0x7180 | (d_hi << 9) | d_lo);		/* mvz.b d_lo, d_hi */
> >> +		emit_16(ctx, 0xe088 | d_lo);				/* lsr.l #8, d_lo */
> >> +		emit_16(ctx, 0xe188 | d_hi);				/* lsl.l #8, d_hi */
> >> +		emit_16(ctx, 0x8080 | (d_lo << 9) | d_hi);		/* or.l d_hi, d_lo */
> >> +		emit_16(ctx, 0x4840 | d_lo);				/* swap d_lo */
> >> +		emit_16(ctx, 0x809f | (d_lo << 9));			/* or.l (%sp)+, d_lo */
> >> +
> >> +		emit_16(ctx, 0x201f | (d_hi << 9));			/* move.l (%sp)+, d_hi */
> >> +	} else {
> >> +		emit_16(ctx, 0xe058 | d_lo);				/* ror.w #8, d_lo */
> >> +		emit_16(ctx, 0x4840 | d_lo);				/* swap d_lo */
> >> +		emit_16(ctx, 0xe058 | d_lo);				/* ror.w #8, d_lo */
> >> +
> >> +		emit_16(ctx, 0xe058 | d_hi);				/* ror.w #8, d_hi */
> >> +		emit_16(ctx, 0x4840 | d_hi);				/* swap d_hi */
> >> +		emit_16(ctx, 0xe058 | d_hi);				/* ror.w #8, d_hi */
> >> +
> >> +		emit_16(ctx, 0xc140 | (d_hi << 9) | d_lo);		/* exg d_lo, d_hi */
> >> +	}
> >> +}
> >> +
> >>  static void emit_bpf_end(const struct bpf_insn *insn, struct jit_ctx *ctx)
> >>  {
> >>  	const s8 *dst = bpf2m68k[insn->dst_reg];
> >> @@ -587,27 +725,13 @@
> >>  	if (to_le) {
> >>  		switch (imm) {
> >>  		case 16:
> >> -			emit_16(ctx, 0x0280 | d_lo);			/* andi.l #0xffff, d_lo */
> >> -			emit_32(ctx, 0xffff);
> >> -			emit_16(ctx, 0xe058 | d_lo);			/* ror.w #8, d_lo */
> >> -			emit_16(ctx, 0x7000 | (d_hi << 9));		/* moveq #0, d_hi */
> >> +			emit_to_le16(ctx, d_lo, d_hi);
> >>  			break;
> >>  		case 32:
> >> -			emit_16(ctx, 0xe058 | d_lo);			/* ror.w #8, d_lo */
> >> -			emit_16(ctx, 0x4840 | d_lo);			/* swap d_lo */
> >> -			emit_16(ctx, 0xe058 | d_lo);			/* ror.w #8, d_lo */
> >> -			emit_16(ctx, 0x7000 | (d_hi << 9));		/* moveq #0, d_hi */
> >> +			emit_to_le32(ctx, d_lo, d_hi);
> >>  			break;
> >>  		case 64:
> >> -			emit_16(ctx, 0xe058 | d_lo);			/* ror.w #8, d_lo */
> >> -			emit_16(ctx, 0x4840 | d_lo);			/* swap d_lo */
> >> -			emit_16(ctx, 0xe058 | d_lo);			/* ror.w #8, d_lo */
> >> -
> >> -			emit_16(ctx, 0xe058 | d_hi);			/* ror.w #8, d_hi */
> >> -			emit_16(ctx, 0x4840 | d_hi);			/* swap d_hi */
> >> -			emit_16(ctx, 0xe058 | d_hi);			/* ror.w #8, d_hi */
> >> -
> >> -			emit_16(ctx, 0xc140 | (d_hi << 9) | d_lo);	/* exg d_lo, d_hi */
> >> +			emit_to_le64(ctx, d_lo, d_hi);
> >>  			break;
> >>  		}
> >>  	} else {
> >> @@ -692,8 +816,8 @@
> >>  	}
> >>  
> >>  	if (is_64) {
> >> -		emit_16(ctx, 0x48e7);					/* movem.l d0-d1, -(%sp) */
> >> -		emit_16(ctx, 0xc000);
> >> +		emit_16(ctx, 0x2f01);					/* move.l d1, -(%sp) */
> >> +		emit_16(ctx, 0x2f00);					/* move.l d0, -(%sp) */
> >>  
> >>  		emit_16(ctx, 0x2f00 | s_lo);				/* move.l s_lo, -(%sp) */
> >>  		emit_16(ctx, 0x2f00 | s_hi);				/* move.l s_hi, -(%sp) */
> >> @@ -710,11 +834,11 @@
> >>  		emit_16(ctx, 0x2601);					/* move.l %d1, %d3 */
> >>  		emit_16(ctx, 0x2400);					/* move.l %d0, %d2 */
> >>  
> >> -		emit_16(ctx, 0x4cdf);					/* movem.l (%sp)+, d0-d1 */
> >> -		emit_16(ctx, 0x0003);
> >> +		emit_16(ctx, 0x201f);					/* move.l (%sp)+, d0 */
> >> +		emit_16(ctx, 0x221f);					/* move.l (%sp)+, d1 */
> >>  	} else {
> >> -		emit_16(ctx, 0x48e7);					/* movem.l d0-d1, -(%sp) */
> >> -		emit_16(ctx, 0xc000);
> >> +		emit_16(ctx, 0x2f01);					/* move.l d1, -(%sp) */
> >> +		emit_16(ctx, 0x2f00);					/* move.l d0, -(%sp) */
> >>  
> >>  		emit_16(ctx, 0x2f00 | s_lo);				/* move.l s_lo, -(%sp) */
> >>  		emit_16(ctx, 0x2f00 | d_lo);				/* move.l d_lo, -(%sp) */
> >> @@ -729,8 +853,8 @@
> >>  		emit_16(ctx, 0x2600);					/* move.l %d0, %d3 */
> >>  		emit_16(ctx, 0x7400);					/* moveq #0, %d2 */
> >>  
> >> -		emit_16(ctx, 0x4cdf);					/* movem.l (%sp)+, d0-d1 */
> >> -		emit_16(ctx, 0x0003);
> >> +		emit_16(ctx, 0x201f);					/* move.l (%sp)+, d0 */
> >> +		emit_16(ctx, 0x221f);					/* move.l (%sp)+, d1 */
> >>  	}
> >>  
> >>  	bpf_put_reg32(dst[1], M68K_D3, ctx);
> >> @@ -905,8 +1029,8 @@
> >>  		s8 s_lo = bpf_get_reg32(src[1], tmp2[1], ctx);
> >>  
> >>  		if (insn->imm != BPF_CMPXCHG) {
> >> -			emit_16(ctx, 0x48e7);			/* movem.l d0-d1, -(%sp) */
> >> -			emit_16(ctx, 0xc000);
> >> +			emit_16(ctx, 0x2f01);			/* move.l d1, -(%sp) */
> >> +			emit_16(ctx, 0x2f00);			/* move.l d0, -(%sp) */
> >>  		}
> >>  
> >>  		emit_16(ctx, 0x2f00 | M68K_D0);			/* move.l %d0, -(%sp) */
> >> @@ -930,8 +1054,8 @@
> >>  			if (is_fetch)
> >>  				emit_16(ctx, 0x2600);		/* move.l %d0, %d3 */
> >>  
> >> -			emit_16(ctx, 0x4cdf);			/* movem.l (%sp)+, d0-d1 */
> >> -			emit_16(ctx, 0x0003);
> >> +			emit_16(ctx, 0x201f);			/* move.l (%sp)+, d0 */
> >> +			emit_16(ctx, 0x221f);			/* move.l (%sp)+, d1 */
> >>  
> >>  			if (is_fetch) {
> >>  				bpf_put_reg32(src[1], M68K_D3, ctx);
> >> @@ -945,8 +1069,8 @@
> >>  		s8 s_hi = bpf_get_reg32(src[0], tmp2[0], ctx);
> >>  
> >>  		if (insn->imm != BPF_CMPXCHG) {
> >> -			emit_16(ctx, 0x48e7);			/* movem.l d0-d1, -(%sp) */
> >> -			emit_16(ctx, 0xc000);
> >> +			emit_16(ctx, 0x2f01);			/* move.l d1, -(%sp) */
> >> +			emit_16(ctx, 0x2f00);			/* move.l d0, -(%sp) */
> >>  		}
> >>  
> >>  		emit_16(ctx, 0x2f00 | M68K_D0);			/* move.l %d0, -(%sp) */
> >> @@ -965,7 +1089,13 @@
> >>  		emit_16(ctx, 24);
> >>  
> >>  		if (insn->imm == BPF_CMPXCHG) {
> >> -			emit_16(ctx, 0xc141);			/* exg %d0, %d1 */
> >> +			if (CPU_IS_COLDFIRE) {
> >> +				emit_16(ctx, 0x2f00);		/* move.l %d0, -(%sp) */
> >> +				emit_16(ctx, 0x2001);		/* move.l %d1, %d0 */
> >> +				emit_16(ctx, 0x221f);		/* move.l (%sp)+, %d1 */
> >> +			} else {
> >> +				emit_16(ctx, 0xc141);		/* exg %d0, %d1 */
> >> +			}
> >>  		} else {
> >>  			bool is_fetch = (insn->imm & BPF_FETCH) || insn->imm == BPF_XCHG;
> >>  
> >> @@ -974,8 +1104,8 @@
> >>  				emit_16(ctx, 0x2401);		/* move.l %d1, %d2 */
> >>  			}
> >>  
> >> -			emit_16(ctx, 0x4cdf);			/* movem.l (%sp)+, d0-d1 */
> >> -			emit_16(ctx, 0x0003);
> >> +			emit_16(ctx, 0x201f);			/* move.l (%sp)+, d0 */
> >> +			emit_16(ctx, 0x221f);			/* move.l (%sp)+, d1 */
> >>  
> >>  			if (is_fetch) {
> >>  				bpf_put_reg32(src[1], M68K_D2, ctx);
> >> @@ -1244,8 +1374,15 @@
> >>  	emit_16(ctx, 0x4fef);					/* lea 40(%sp), %sp */
> >>  	emit_16(ctx, 40);
> >>  
> >> -	if (insn->src_reg != BPF_PSEUDO_CALL)
> >> -		emit_16(ctx, 0xc340);					/* exg %d0, %d1 */
> >> +	if (insn->src_reg != BPF_PSEUDO_CALL) {
> >> +		if (CPU_IS_COLDFIRE) {
> >> +			emit_16(ctx, 0x2f00);			/* move.l %d0, -(%sp) */
> >> +			emit_16(ctx, 0x2001);			/* move.l %d1, %d0 */
> >> +			emit_16(ctx, 0x221f);			/* move.l (%sp)+, %d1 */
> >> +		} else {
> >> +			emit_16(ctx, 0xc340);			/* exg %d0, %d1 */
> >> +		}
> >> +	}
> >>  
> >>  	return 0;
> >>  }
> >> @@ -1261,8 +1398,15 @@
> >>  	emit_16(ctx, 0x4e56);					/* link %a6, #-total_stack */
> >>  	emit_16(ctx, -total_stack);
> >>  
> >> -	emit_16(ctx, 0x48e7);					/* movem.l d2-d5, -(%sp) */
> >> -	emit_16(ctx, 0x3c00);
> >> +	if (CPU_IS_COLDFIRE) {
> >> +		emit_16(ctx, 0x4fef);				/* lea -16(%sp), %sp */
> >> +		emit_16(ctx, 0xfff0);
> >> +		emit_16(ctx, 0x48d7);				/* movem.l d2-d5, (%sp) */
> >> +		emit_16(ctx, 0x003c);
> >> +	} else {
> >> +		emit_16(ctx, 0x48e7);				/* movem.l d2-d5, -(%sp) */
> >> +		emit_16(ctx, 0x3c00);
> >> +	}
> >>  
> >>  	emit_16(ctx, 0x2d40);					/* move.l %d0, off(%fp) */
> >>  	emit_16(ctx, (u16)STACK_OFFSET(BPF_TC_LO));
> >> @@ -1302,8 +1446,15 @@
> >>  
> >>  static void build_epilogue(struct jit_ctx *ctx)
> >>  {
> >> -	emit_16(ctx, 0x4cdf);					/* movem.l (%sp)+, d2-d5 */
> >> -	emit_16(ctx, 0x003c);
> >> +	if (CPU_IS_COLDFIRE) {
> >> +		emit_16(ctx, 0x4cd7);				/* movem.l (%sp), d2-d5 */
> >> +		emit_16(ctx, 0x003c);
> >> +		emit_16(ctx, 0x4fef);				/* lea 16(%sp), %sp */
> >> +		emit_16(ctx, 0x0010);
> >> +	} else {
> >> +		emit_16(ctx, 0x4cdf);				/* movem.l (%sp)+, d2-d5 */
> >> +		emit_16(ctx, 0x003c);
> >> +	}
> >>  
> >>  	emit_16(ctx, 0x4e5e);					/* unlk %fp */
> >>  	emit_16(ctx, 0x4e75);					/* rts */
> >> --- a/arch/m68k/Kconfig
> >> +++ b/arch/m68k/Kconfig
> >> @@ -8,7 +8,7 @@
> >>  	select ARCH_HAS_CPU_FINALIZE_INIT if MMU
> >>  	select ARCH_HAS_CURRENT_STACK_POINTER
> >>  	select ARCH_HAS_DMA_PREP_COHERENT if M68K_NONCOHERENT_DMA && !COLDFIRE
> >> -	select HAVE_EBPF_JIT if (!COLDFIRE && !M68000)
> >> +	select HAVE_EBPF_JIT if MMU
> >>  	select ARCH_HAS_SYNC_DMA_FOR_DEVICE if M68K_NONCOHERENT_DMA
> >>  	select ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS
> >>  	select ARCH_MIGHT_HAVE_PC_PARPORT if ISA
> > 
> 

  reply	other threads:[~2026-08-23 16:28 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-29  0:27 Kuan-Wei Chiu
2026-07-29 15:33 ` Andreas Schwab
2026-08-10 10:05   ` Kuan-Wei Chiu
2026-08-06 15:28 ` Greg Ungerer
2026-08-10 10:04   ` Kuan-Wei Chiu
2026-08-11 23:22     ` Greg Ungerer
2026-08-23 16:28       ` Kuan-Wei Chiu [this message]
2026-08-06 23:34 ` [PATCH bpf-next v4 RESEND] m68k, bpf: Add initial BPF JIT compiler support (resend) Greg Ungerer

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=aosfqVMeIISRiv4K@google.com \
    --to=visitorckw@gmail.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=daniel@thingy.jp \
    --cc=eddyz87@gmail.com \
    --cc=eleanor15x@gmail.com \
    --cc=geert@linux-m68k.org \
    --cc=gerg@polyxeno.com \
    --cc=jolsa@kernel.org \
    --cc=jserv@ccns.ncku.edu.tw \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-m68k@lists.linux-m68k.org \
    --cc=marscheng@google.com \
    --cc=martin.lau@linux.dev \
    --cc=memxor@gmail.com \
    --cc=song@kernel.org \
    --cc=yonghong.song@linux.dev \
    /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

all inboxes | Powered by JetHome®