2023-02-22 16:12:39

by Jiaxun Yang

[permalink] [raw]
Subject: [PATCH 0/2] MIPS: Implement two workarounds for BPF JIT

Hi all,

Just noticed eBPF JIT is not working on R4000 when messing around with QEMU.

This patchset implements two workarounds that is blocking us from enabling eBPF
JIT on R4000.

Thanks.
- Jiaxun

Jiaxun Yang (2):
MIPS: ebpf jit: Implement DADDI workarounds
MIPS: ebpf jit: Implement R4000 workarounds

arch/mips/Kconfig | 5 +----
arch/mips/net/bpf_jit_comp.c | 8 ++++++++
arch/mips/net/bpf_jit_comp32.c | 4 ++++
arch/mips/net/bpf_jit_comp64.c | 3 +++
4 files changed, 16 insertions(+), 4 deletions(-)

--
2.37.1 (Apple Git-137.1)



2023-02-22 16:12:42

by Jiaxun Yang

[permalink] [raw]
Subject: [PATCH 1/2] MIPS: ebpf jit: Implement DADDI workarounds

For DADDI errata we just workaround by disable immediate operation
for BPF_ADD / BPF_SUB to avoid generation of DADDIU.

All other use cases in JIT won't cause overflow thus they are all safe.

Signed-off-by: Jiaxun Yang <[email protected]>
---
arch/mips/Kconfig | 1 -
arch/mips/net/bpf_jit_comp.c | 8 ++++++++
2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 37072e15b263..df0910e3895c 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -64,7 +64,6 @@ config MIPS
select HAVE_DMA_CONTIGUOUS
select HAVE_DYNAMIC_FTRACE
select HAVE_EBPF_JIT if !CPU_MICROMIPS && \
- !CPU_DADDI_WORKAROUNDS && \
!CPU_R4000_WORKAROUNDS && \
!CPU_R4400_WORKAROUNDS
select HAVE_EXIT_THREAD
diff --git a/arch/mips/net/bpf_jit_comp.c b/arch/mips/net/bpf_jit_comp.c
index b17130d510d4..7110a6687f7a 100644
--- a/arch/mips/net/bpf_jit_comp.c
+++ b/arch/mips/net/bpf_jit_comp.c
@@ -218,9 +218,17 @@ bool valid_alu_i(u8 op, s32 imm)
/* All legal eBPF values are valid */
return true;
case BPF_ADD:
+#ifdef CONFIG_64BIT
+ if (IS_ENABLED(CONFIG_CPU_DADDI_WORKAROUNDS))
+ return false;
+#endif
/* imm must be 16 bits */
return imm >= -0x8000 && imm <= 0x7fff;
case BPF_SUB:
+#ifdef CONFIG_64BIT
+ if (IS_ENABLED(CONFIG_CPU_DADDI_WORKAROUNDS))
+ return false;
+#endif
/* -imm must be 16 bits */
return imm >= -0x7fff && imm <= 0x8000;
case BPF_AND:
--
2.37.1 (Apple Git-137.1)


2023-02-22 16:12:44

by Jiaxun Yang

[permalink] [raw]
Subject: [PATCH 2/2] MIPS: ebpf jit: Implement R4000 workarounds

For R4000 erratas around multiplication and division instructions,
as our use of those instructions are always followed by mflo/mfhi
instructions, the only issue we need care is

"MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0" Errata 28:
"A double-word or a variable shift may give an incorrect result if
executed while an integer multiplication is in progress."

We just emit a mfhi $0 to ensure the operation is completed after
every multiplication instruction accorading to workaround suggestion
in the document.

Signed-off-by: Jiaxun Yang <[email protected]>
---
arch/mips/Kconfig | 4 +---
arch/mips/net/bpf_jit_comp32.c | 4 ++++
arch/mips/net/bpf_jit_comp64.c | 3 +++
3 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index df0910e3895c..5ea07c833c5b 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -63,9 +63,7 @@ config MIPS
select HAVE_DEBUG_STACKOVERFLOW
select HAVE_DMA_CONTIGUOUS
select HAVE_DYNAMIC_FTRACE
- select HAVE_EBPF_JIT if !CPU_MICROMIPS && \
- !CPU_R4000_WORKAROUNDS && \
- !CPU_R4400_WORKAROUNDS
+ select HAVE_EBPF_JIT if !CPU_MICROMIPS
select HAVE_EXIT_THREAD
select HAVE_FAST_GUP
select HAVE_FTRACE_MCOUNT_RECORD
diff --git a/arch/mips/net/bpf_jit_comp32.c b/arch/mips/net/bpf_jit_comp32.c
index ace5db3fbd17..fee334544d2f 100644
--- a/arch/mips/net/bpf_jit_comp32.c
+++ b/arch/mips/net/bpf_jit_comp32.c
@@ -446,6 +446,9 @@ static void emit_mul_i64(struct jit_context *ctx, const u8 dst[], s32 imm)
} else {
emit(ctx, multu, hi(dst), src);
emit(ctx, mflo, hi(dst));
+ /* Ensure multiplication is completed */
+ if (IS_ENABLED(CONFIG_CPU_R4000_WORKAROUNDS))
+ emit(ctx, mfhi, MIPS_R_ZERO);
}

/* hi(dst) = hi(dst) - lo(dst) */
@@ -504,6 +507,7 @@ static void emit_mul_r64(struct jit_context *ctx,
} else {
emit(ctx, multu, lo(dst), lo(src));
emit(ctx, mflo, lo(dst));
+ /* No need for workaround because we have this mfhi */
emit(ctx, mfhi, tmp);
}

diff --git a/arch/mips/net/bpf_jit_comp64.c b/arch/mips/net/bpf_jit_comp64.c
index 0e7c1bdcf914..5f5a93f997bc 100644
--- a/arch/mips/net/bpf_jit_comp64.c
+++ b/arch/mips/net/bpf_jit_comp64.c
@@ -228,6 +228,9 @@ static void emit_alu_r64(struct jit_context *ctx, u8 dst, u8 src, u8 op)
} else {
emit(ctx, dmultu, dst, src);
emit(ctx, mflo, dst);
+ /* Ensure multiplication is completed */
+ if (IS_ENABLED(CONFIG_CPU_R4000_WORKAROUNDS))
+ emit(ctx, mfhi, MIPS_R_ZERO);
}
break;
/* dst = dst / src */
--
2.37.1 (Apple Git-137.1)


2023-02-23 10:10:35

by Johan Almbladh

[permalink] [raw]
Subject: Re: [PATCH 1/2] MIPS: ebpf jit: Implement DADDI workarounds

On Wed, Feb 22, 2023 at 5:12 PM Jiaxun Yang <[email protected]> wrote:
>
> For DADDI errata we just workaround by disable immediate operation
> for BPF_ADD / BPF_SUB to avoid generation of DADDIU.

Good, this is an elegant solution to trigger fallback to the
register-only operation. Does the DADDI errata only affect the DADDIU,
not DADDI?

>
> All other use cases in JIT won't cause overflow thus they are all safe.

There are quite a few other places where DADDIU is emitted. How do you
know those are safe? I am interested in your reasoning here, as I
don't know what would be safe and not.

>
> Signed-off-by: Jiaxun Yang <[email protected]>
> ---
> arch/mips/Kconfig | 1 -
> arch/mips/net/bpf_jit_comp.c | 8 ++++++++
> 2 files changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
> index 37072e15b263..df0910e3895c 100644
> --- a/arch/mips/Kconfig
> +++ b/arch/mips/Kconfig
> @@ -64,7 +64,6 @@ config MIPS
> select HAVE_DMA_CONTIGUOUS
> select HAVE_DYNAMIC_FTRACE
> select HAVE_EBPF_JIT if !CPU_MICROMIPS && \
> - !CPU_DADDI_WORKAROUNDS && \
> !CPU_R4000_WORKAROUNDS && \
> !CPU_R4400_WORKAROUNDS
> select HAVE_EXIT_THREAD
> diff --git a/arch/mips/net/bpf_jit_comp.c b/arch/mips/net/bpf_jit_comp.c
> index b17130d510d4..7110a6687f7a 100644
> --- a/arch/mips/net/bpf_jit_comp.c
> +++ b/arch/mips/net/bpf_jit_comp.c
> @@ -218,9 +218,17 @@ bool valid_alu_i(u8 op, s32 imm)
> /* All legal eBPF values are valid */
> return true;
> case BPF_ADD:
> +#ifdef CONFIG_64BIT

DADDI/DADDIU are only available on 64-bit CPUs, so the errata would
only be applicable to that. No need for the CONFIG_64BIT conditional.

> + if (IS_ENABLED(CONFIG_CPU_DADDI_WORKAROUNDS))
> + return false;
> +#endif
> /* imm must be 16 bits */
> return imm >= -0x8000 && imm <= 0x7fff;
> case BPF_SUB:
> +#ifdef CONFIG_64BIT
> + if (IS_ENABLED(CONFIG_CPU_DADDI_WORKAROUNDS))
> + return false;
> +#endif
> /* -imm must be 16 bits */
> return imm >= -0x7fff && imm <= 0x8000;
> case BPF_AND:
> --
> 2.37.1 (Apple Git-137.1)
>

2023-02-23 10:23:41

by Johan Almbladh

[permalink] [raw]
Subject: Re: [PATCH 2/2] MIPS: ebpf jit: Implement R4000 workarounds

On Wed, Feb 22, 2023 at 5:12 PM Jiaxun Yang <[email protected]> wrote:
>
> For R4000 erratas around multiplication and division instructions,
> as our use of those instructions are always followed by mflo/mfhi
> instructions, the only issue we need care is
>
> "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0" Errata 28:
> "A double-word or a variable shift may give an incorrect result if
> executed while an integer multiplication is in progress."
>
> We just emit a mfhi $0 to ensure the operation is completed after
> every multiplication instruction accorading to workaround suggestion
> in the document.
>
> Signed-off-by: Jiaxun Yang <[email protected]>
> ---
> arch/mips/Kconfig | 4 +---
> arch/mips/net/bpf_jit_comp32.c | 4 ++++
> arch/mips/net/bpf_jit_comp64.c | 3 +++
> 3 files changed, 8 insertions(+), 3 deletions(-)
>
> diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
> index df0910e3895c..5ea07c833c5b 100644
> --- a/arch/mips/Kconfig
> +++ b/arch/mips/Kconfig
> @@ -63,9 +63,7 @@ config MIPS
> select HAVE_DEBUG_STACKOVERFLOW
> select HAVE_DMA_CONTIGUOUS
> select HAVE_DYNAMIC_FTRACE
> - select HAVE_EBPF_JIT if !CPU_MICROMIPS && \
> - !CPU_R4000_WORKAROUNDS && \
> - !CPU_R4400_WORKAROUNDS

Is the R4400 errata also covered by this workaround?

> + select HAVE_EBPF_JIT if !CPU_MICROMIPS
> select HAVE_EXIT_THREAD
> select HAVE_FAST_GUP
> select HAVE_FTRACE_MCOUNT_RECORD
> diff --git a/arch/mips/net/bpf_jit_comp32.c b/arch/mips/net/bpf_jit_comp32.c
> index ace5db3fbd17..fee334544d2f 100644
> --- a/arch/mips/net/bpf_jit_comp32.c
> +++ b/arch/mips/net/bpf_jit_comp32.c
> @@ -446,6 +446,9 @@ static void emit_mul_i64(struct jit_context *ctx, const u8 dst[], s32 imm)
> } else {
> emit(ctx, multu, hi(dst), src);
> emit(ctx, mflo, hi(dst));
> + /* Ensure multiplication is completed */
> + if (IS_ENABLED(CONFIG_CPU_R4000_WORKAROUNDS))
> + emit(ctx, mfhi, MIPS_R_ZERO);
> }
>
> /* hi(dst) = hi(dst) - lo(dst) */
> @@ -504,6 +507,7 @@ static void emit_mul_r64(struct jit_context *ctx,
> } else {
> emit(ctx, multu, lo(dst), lo(src));
> emit(ctx, mflo, lo(dst));
> + /* No need for workaround because we have this mfhi */
> emit(ctx, mfhi, tmp);
> }

R4000 is a 64-bit CPU, so the 32-bit JIT implementation will not be
used. From the Makefile:

ifeq ($(CONFIG_32BIT),y)
obj-$(CONFIG_BPF_JIT) += bpf_jit_comp32.o
else
obj-$(CONFIG_BPF_JIT) += bpf_jit_comp64.o
endif

>
> diff --git a/arch/mips/net/bpf_jit_comp64.c b/arch/mips/net/bpf_jit_comp64.c
> index 0e7c1bdcf914..5f5a93f997bc 100644
> --- a/arch/mips/net/bpf_jit_comp64.c
> +++ b/arch/mips/net/bpf_jit_comp64.c
> @@ -228,6 +228,9 @@ static void emit_alu_r64(struct jit_context *ctx, u8 dst, u8 src, u8 op)
> } else {
> emit(ctx, dmultu, dst, src);
> emit(ctx, mflo, dst);
> + /* Ensure multiplication is completed */
> + if (IS_ENABLED(CONFIG_CPU_R4000_WORKAROUNDS))
> + emit(ctx, mfhi, MIPS_R_ZERO);
> }
> break;
> /* dst = dst / src */
> --
> 2.37.1 (Apple Git-137.1)
>

2023-02-23 10:29:55

by Jiaxun Yang

[permalink] [raw]
Subject: Re: [PATCH 1/2] MIPS: ebpf jit: Implement DADDI workarounds



> 2023年2月23日 10:10,Johan Almbladh <[email protected]> 写道:
>
> On Wed, Feb 22, 2023 at 5:12 PM Jiaxun Yang <[email protected]> wrote:
>>
>> For DADDI errata we just workaround by disable immediate operation
>> for BPF_ADD / BPF_SUB to avoid generation of DADDIU.
>
> Good, this is an elegant solution to trigger fallback to the
> register-only operation. Does the DADDI errata only affect the DADDIU,
> not DADDI?

I didn’t see any place emitting DADDI.

>
>>
>> All other use cases in JIT won't cause overflow thus they are all safe.
>
> There are quite a few other places where DADDIU is emitted. How do you
> know those are safe? I am interested in your reasoning here, as I
> don't know what would be safe and not.

Yes I analysed all other place, most of them are just calculating memory
address offsets and they should never overflow. Other two is doing addition
to zero to load immediate, which should be still fine.

>
>>
>> Signed-off-by: Jiaxun Yang <[email protected]>
>> ---
>> arch/mips/Kconfig | 1 -
>> arch/mips/net/bpf_jit_comp.c | 8 ++++++++
>> 2 files changed, 8 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
>> index 37072e15b263..df0910e3895c 100644
>> --- a/arch/mips/Kconfig
>> +++ b/arch/mips/Kconfig
>> @@ -64,7 +64,6 @@ config MIPS
>> select HAVE_DMA_CONTIGUOUS
>> select HAVE_DYNAMIC_FTRACE
>> select HAVE_EBPF_JIT if !CPU_MICROMIPS && \
>> - !CPU_DADDI_WORKAROUNDS && \
>> !CPU_R4000_WORKAROUNDS && \
>> !CPU_R4400_WORKAROUNDS
>> select HAVE_EXIT_THREAD
>> diff --git a/arch/mips/net/bpf_jit_comp.c b/arch/mips/net/bpf_jit_comp.c
>> index b17130d510d4..7110a6687f7a 100644
>> --- a/arch/mips/net/bpf_jit_comp.c
>> +++ b/arch/mips/net/bpf_jit_comp.c
>> @@ -218,9 +218,17 @@ bool valid_alu_i(u8 op, s32 imm)
>> /* All legal eBPF values are valid */
>> return true;
>> case BPF_ADD:
>> +#ifdef CONFIG_64BIT
>
> DADDI/DADDIU are only available on 64-bit CPUs, so the errata would
> only be applicable to that. No need for the CONFIG_64BIT conditional.

It’s possible to compile a 32bit kernel for R4000 with CONFIG_CPU_DADDI_WORKAROUNDS
enabled.

Thanks
- Jiaxun




2023-02-23 10:32:12

by Jiaxun Yang

[permalink] [raw]
Subject: Re: [PATCH 2/2] MIPS: ebpf jit: Implement R4000 workarounds



> 2023年2月23日 10:22,Johan Almbladh <[email protected]> 写道:
>
> On Wed, Feb 22, 2023 at 5:12 PM Jiaxun Yang <[email protected]> wrote:
>>
>> For R4000 erratas around multiplication and division instructions,
>> as our use of those instructions are always followed by mflo/mfhi
>> instructions, the only issue we need care is
>>
>> "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0" Errata 28:
>> "A double-word or a variable shift may give an incorrect result if
>> executed while an integer multiplication is in progress."
>>
>> We just emit a mfhi $0 to ensure the operation is completed after
>> every multiplication instruction accorading to workaround suggestion
>> in the document.
>>
>> Signed-off-by: Jiaxun Yang <[email protected]>
>> ---
>> arch/mips/Kconfig | 4 +---
>> arch/mips/net/bpf_jit_comp32.c | 4 ++++
>> arch/mips/net/bpf_jit_comp64.c | 3 +++
>> 3 files changed, 8 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
>> index df0910e3895c..5ea07c833c5b 100644
>> --- a/arch/mips/Kconfig
>> +++ b/arch/mips/Kconfig
>> @@ -63,9 +63,7 @@ config MIPS
>> select HAVE_DEBUG_STACKOVERFLOW
>> select HAVE_DMA_CONTIGUOUS
>> select HAVE_DYNAMIC_FTRACE
>> - select HAVE_EBPF_JIT if !CPU_MICROMIPS && \
>> - !CPU_R4000_WORKAROUNDS && \
>> - !CPU_R4400_WORKAROUNDS
>
> Is the R4400 errata also covered by this workaround?

Yes, R4400 errata is basically a reduced version of R4000 one.
They managed to fix some parts of the issue but not all.

>
>> + select HAVE_EBPF_JIT if !CPU_MICROMIPS
>> select HAVE_EXIT_THREAD
>> select HAVE_FAST_GUP
>> select HAVE_FTRACE_MCOUNT_RECORD
>> diff --git a/arch/mips/net/bpf_jit_comp32.c b/arch/mips/net/bpf_jit_comp32.c
>> index ace5db3fbd17..fee334544d2f 100644
>> --- a/arch/mips/net/bpf_jit_comp32.c
>> +++ b/arch/mips/net/bpf_jit_comp32.c
>> @@ -446,6 +446,9 @@ static void emit_mul_i64(struct jit_context *ctx, const u8 dst[], s32 imm)
>> } else {
>> emit(ctx, multu, hi(dst), src);
>> emit(ctx, mflo, hi(dst));
>> + /* Ensure multiplication is completed */
>> + if (IS_ENABLED(CONFIG_CPU_R4000_WORKAROUNDS))
>> + emit(ctx, mfhi, MIPS_R_ZERO);
>> }
>>
>> /* hi(dst) = hi(dst) - lo(dst) */
>> @@ -504,6 +507,7 @@ static void emit_mul_r64(struct jit_context *ctx,
>> } else {
>> emit(ctx, multu, lo(dst), lo(src));
>> emit(ctx, mflo, lo(dst));
>> + /* No need for workaround because we have this mfhi */
>> emit(ctx, mfhi, tmp);
>> }
>
> R4000 is a 64-bit CPU, so the 32-bit JIT implementation will not be
> used. From the Makefile:
>
> ifeq ($(CONFIG_32BIT),y)
> obj-$(CONFIG_BPF_JIT) += bpf_jit_comp32.o
> else
> obj-$(CONFIG_BPF_JIT) += bpf_jit_comp64.o
> endif

It’s common practice to run 32-bit kernel on R4000 based systems to save some memory :-)

Thanks.
- Jiaxun

>
>>
>> diff --git a/arch/mips/net/bpf_jit_comp64.c b/arch/mips/net/bpf_jit_comp64.c
>> index 0e7c1bdcf914..5f5a93f997bc 100644
>> --- a/arch/mips/net/bpf_jit_comp64.c
>> +++ b/arch/mips/net/bpf_jit_comp64.c
>> @@ -228,6 +228,9 @@ static void emit_alu_r64(struct jit_context *ctx, u8 dst, u8 src, u8 op)
>> } else {
>> emit(ctx, dmultu, dst, src);
>> emit(ctx, mflo, dst);
>> + /* Ensure multiplication is completed */
>> + if (IS_ENABLED(CONFIG_CPU_R4000_WORKAROUNDS))
>> + emit(ctx, mfhi, MIPS_R_ZERO);
>> }
>> break;
>> /* dst = dst / src */
>> --
>> 2.37.1 (Apple Git-137.1)



2023-02-26 22:09:48

by Philippe Mathieu-Daudé

[permalink] [raw]
Subject: Re: [PATCH 2/2] MIPS: ebpf jit: Implement R4000 workarounds

On 22/2/23 17:12, Jiaxun Yang wrote:
> For R4000 erratas around multiplication and division instructions,
> as our use of those instructions are always followed by mflo/mfhi
> instructions, the only issue we need care is
>
> "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0" Errata 28:
> "A double-word or a variable shift may give an incorrect result if
> executed while an integer multiplication is in progress."
>
> We just emit a mfhi $0 to ensure the operation is completed after
> every multiplication instruction accorading to workaround suggestion

Typo "according"

> in the document.
>
> Signed-off-by: Jiaxun Yang <[email protected]>
> ---
> arch/mips/Kconfig | 4 +---
> arch/mips/net/bpf_jit_comp32.c | 4 ++++
> arch/mips/net/bpf_jit_comp64.c | 3 +++
> 3 files changed, 8 insertions(+), 3 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <[email protected]>


2023-02-27 12:18:10

by Johan Almbladh

[permalink] [raw]
Subject: Re: [PATCH 1/2] MIPS: ebpf jit: Implement DADDI workarounds

On Thu, Feb 23, 2023 at 11:29 AM Jiaxun Yang <[email protected]> wrote:
> I didn’t see any place emitting DADDI.

Right, the JIT only uses unsigned arithmetics :)

> Yes I analysed all other place, most of them are just calculating memory
> address offsets and they should never overflow. Other two is doing addition
> to zero to load immediate, which should be still fine.

Ok.

> >> --- a/arch/mips/net/bpf_jit_comp.c
> >> +++ b/arch/mips/net/bpf_jit_comp.c
> >> @@ -218,9 +218,17 @@ bool valid_alu_i(u8 op, s32 imm)
> >> /* All legal eBPF values are valid */
> >> return true;
> >> case BPF_ADD:
> >> +#ifdef CONFIG_64BIT
> >
> > DADDI/DADDIU are only available on 64-bit CPUs, so the errata would
> > only be applicable to that. No need for the CONFIG_64BIT conditional.
>
> It’s possible to compile a 32bit kernel for R4000 with CONFIG_CPU_DADDI_WORKAROUNDS
> enabled.

Yes, but DADDI/DADDIU are 64-bit instructions so they would not be
available when compiling the kernel in 32-bit mode for R4000, and
hence the workaround would not be applicable, right? If this is
correct, I would imagine CONFIG_CPU_DADDI_WORKAROUNDS itself to be
conditional on CONFIG_64BIT. That way the this relationship is
expressed once in the Kconfig file, instead of being spread out over
multiple places in the code.

2023-02-27 12:20:20

by Johan Almbladh

[permalink] [raw]
Subject: Re: [PATCH 2/2] MIPS: ebpf jit: Implement R4000 workarounds

On Thu, Feb 23, 2023 at 11:32 AM Jiaxun Yang <[email protected]> wrote:
> >> --- a/arch/mips/Kconfig
> >> +++ b/arch/mips/Kconfig
> >> @@ -63,9 +63,7 @@ config MIPS
> >> select HAVE_DEBUG_STACKOVERFLOW
> >> select HAVE_DMA_CONTIGUOUS
> >> select HAVE_DYNAMIC_FTRACE
> >> - select HAVE_EBPF_JIT if !CPU_MICROMIPS && \
> >> - !CPU_R4000_WORKAROUNDS && \
> >> - !CPU_R4400_WORKAROUNDS
> >
> > Is the R4400 errata also covered by this workaround?
>
> Yes, R4400 errata is basically a reduced version of R4000 one.
> They managed to fix some parts of the issue but not all.

Ok.

> >> --- a/arch/mips/net/bpf_jit_comp32.c
> >> +++ b/arch/mips/net/bpf_jit_comp32.c
> >> @@ -446,6 +446,9 @@ static void emit_mul_i64(struct jit_context *ctx, const u8 dst[], s32 imm)
> >> } else {
> >> emit(ctx, multu, hi(dst), src);
> >> emit(ctx, mflo, hi(dst));
> >> + /* Ensure multiplication is completed */
> >> + if (IS_ENABLED(CONFIG_CPU_R4000_WORKAROUNDS))
> >> + emit(ctx, mfhi, MIPS_R_ZERO);
> >> }
> >>
> >> /* hi(dst) = hi(dst) - lo(dst) */
> >> @@ -504,6 +507,7 @@ static void emit_mul_r64(struct jit_context *ctx,
> >> } else {
> >> emit(ctx, multu, lo(dst), lo(src));
> >> emit(ctx, mflo, lo(dst));
> >> + /* No need for workaround because we have this mfhi */

For context, please specify which workaround this comment refers to:
"workaround" -> "R4000 workaround".

> > R4000 is a 64-bit CPU, so the 32-bit JIT implementation will not be
> > used. From the Makefile:
> >
> > ifeq ($(CONFIG_32BIT),y)
> > obj-$(CONFIG_BPF_JIT) += bpf_jit_comp32.o
> > else
> > obj-$(CONFIG_BPF_JIT) += bpf_jit_comp64.o
> > endif
>
> It’s common practice to run 32-bit kernel on R4000 based systems to save some memory :-)

Ok, I understand.

Looks good! I have run the test_bpf.ko test suite on MIPS and MIPS64
in QEMU with and without the workarounds enabled.

With above comment fix:
Acked-by: Johan Almbladh <[email protected]>

2023-02-27 15:17:34

by Maciej W. Rozycki

[permalink] [raw]
Subject: Re: [PATCH 1/2] MIPS: ebpf jit: Implement DADDI workarounds

On Mon, 27 Feb 2023, Johan Almbladh wrote:

> > > DADDI/DADDIU are only available on 64-bit CPUs, so the errata would
> > > only be applicable to that. No need for the CONFIG_64BIT conditional.
> >
> > It’s possible to compile a 32bit kernel for R4000 with CONFIG_CPU_DADDI_WORKAROUNDS
> > enabled.
>
> Yes, but DADDI/DADDIU are 64-bit instructions so they would not be
> available when compiling the kernel in 32-bit mode for R4000, and
> hence the workaround would not be applicable, right? If this is
> correct, I would imagine CONFIG_CPU_DADDI_WORKAROUNDS itself to be
> conditional on CONFIG_64BIT. That way the this relationship is
> expressed once in the Kconfig file, instead of being spread out over
> multiple places in the code.

It is:

select CPU_DADDI_WORKAROUNDS if 64BIT

It only applies to 64-bit operations which are not used in 32-bit code.

Maciej

2023-02-27 15:18:57

by Maciej W. Rozycki

[permalink] [raw]
Subject: Re: [PATCH 2/2] MIPS: ebpf jit: Implement R4000 workarounds

On Mon, 27 Feb 2023, Johan Almbladh wrote:

> > > R4000 is a 64-bit CPU, so the 32-bit JIT implementation will not be
> > > used. From the Makefile:
> > >
> > > ifeq ($(CONFIG_32BIT),y)
> > > obj-$(CONFIG_BPF_JIT) += bpf_jit_comp32.o
> > > else
> > > obj-$(CONFIG_BPF_JIT) += bpf_jit_comp64.o
> > > endif
> >
> > It’s common practice to run 32-bit kernel on R4000 based systems to save some memory :-)
>
> Ok, I understand.

Likewise:

select CPU_R4000_WORKAROUNDS if 64BIT
select CPU_R4400_WORKAROUNDS if 64BIT

This only applies to 64-bit operations, which are not used in 32-bit code
(one reason why these early silicon revisions were originally used with
32-bit software only).

Maciej

2023-02-27 15:47:34

by Jiaxun Yang

[permalink] [raw]
Subject: Re: [PATCH 2/2] MIPS: ebpf jit: Implement R4000 workarounds



在2023年2月27日二月 下午3:18,Maciej W. Rozycki写道:
> On Mon, 27 Feb 2023, Johan Almbladh wrote:
>
>> > > R4000 is a 64-bit CPU, so the 32-bit JIT implementation will not be
>> > > used. From the Makefile:
>> > >
>> > > ifeq ($(CONFIG_32BIT),y)
>> > > obj-$(CONFIG_BPF_JIT) += bpf_jit_comp32.o
>> > > else
>> > > obj-$(CONFIG_BPF_JIT) += bpf_jit_comp64.o
>> > > endif
>> >
>> > It’s common practice to run 32-bit kernel on R4000 based systems to save some memory :-)
>>
>> Ok, I understand.
>
> Likewise:
>
> select CPU_R4000_WORKAROUNDS if 64BIT
> select CPU_R4400_WORKAROUNDS if 64BIT
>
> This only applies to 64-bit operations, which are not used in 32-bit code
> (one reason why these early silicon revisions were originally used with
> 32-bit software only).

Thanks for the info.
Will drop 32bit part from both patch.

>
> Maciej

--
- Jiaxun