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 <jiaxun.yang@flygoat.com>
---
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)
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 <jiaxun.yang@flygoat.com> > --- > 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é <philmd@linaro.org>
On Wed, Feb 22, 2023 at 5:12 PM Jiaxun Yang <jiaxun.yang@flygoat.com> 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 <jiaxun.yang@flygoat.com>
> ---
> 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年2月23日 10:22,Johan Almbladh <johan.almbladh@anyfinetworks.com> 写道:
>
> On Wed, Feb 22, 2023 at 5:12 PM Jiaxun Yang <jiaxun.yang@flygoat.com> 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 <jiaxun.yang@flygoat.com>
>> ---
>> 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)
On Thu, Feb 23, 2023 at 11:32 AM Jiaxun Yang <jiaxun.yang@flygoat.com> 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 <johan.almbladh@anyfinetworks.com>
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年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
© 2016 - 2026 Red Hat, Inc.