[PATCH] riscv: Add ERRATA_MIPS_P8700_WFI to replace WFI with mips.pause

Aleksa Paunovic via B4 Relay posted 1 patch 1 month ago
There is a newer version of this series
arch/riscv/Kconfig.errata                    | 11 +++++++++++
arch/riscv/errata/mips/errata.c              | 14 ++++++++++++++
arch/riscv/include/asm/errata_list.h         | 27 +++++++++++++++++++++++++++
arch/riscv/include/asm/errata_list_vendors.h |  5 +++--
arch/riscv/include/asm/processor.h           |  3 ++-
arch/riscv/kernel/head.S                     |  4 +++-
6 files changed, 60 insertions(+), 4 deletions(-)
[PATCH] riscv: Add ERRATA_MIPS_P8700_WFI to replace WFI with mips.pause
Posted by Aleksa Paunovic via B4 Relay 1 month ago
From: Djordje Todorovic <djordje.todorovic@htecgroup.com>

The MIPS P8700 has bugs with the WFI instruction. This errata
uses the RISC-V alternatives framework to patch all WFI
instructions with the MIPS P8700 pause opcode (0x00501013)
at runtime when running on P8700 hardware.

Two call sites are patched:
 - arch/riscv/kernel/head.S: secondary hart parking loop
 - arch/riscv/include/asm/processor.h: wait_for_interrupt()

Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
Signed-off-by: Aleksa Paunovic <aleksa.paunovic@htecgroup.com>
---
This patch was tested on QEMU configured with eight P8700 harts,
as well as on the MIPS Boston board, configured with a single P8700 CPU.
Errata application was tested by disassembling with GDB on QEMU
and inserting an illegal instruction on the Boston board.
Correctness was tested with a combination of kselftests
and torture tests (rcu, locktorture), along with coremark testing.
---
 arch/riscv/Kconfig.errata                    | 11 +++++++++++
 arch/riscv/errata/mips/errata.c              | 14 ++++++++++++++
 arch/riscv/include/asm/errata_list.h         | 27 +++++++++++++++++++++++++++
 arch/riscv/include/asm/errata_list_vendors.h |  5 +++--
 arch/riscv/include/asm/processor.h           |  3 ++-
 arch/riscv/kernel/head.S                     |  4 +++-
 6 files changed, 60 insertions(+), 4 deletions(-)

diff --git a/arch/riscv/Kconfig.errata b/arch/riscv/Kconfig.errata
index 3c945d086c7d0266b685f9506d58b0662af071c4..cc75e6f70513d08afeedf650b14dba83eea84632 100644
--- a/arch/riscv/Kconfig.errata
+++ b/arch/riscv/Kconfig.errata
@@ -44,6 +44,17 @@ config ERRATA_MIPS_P8700_PAUSE_OPCODE
 
 	   If you are not using the P8700 processor, say n.
 
+config ERRATA_MIPS_P8700_WFI
+	bool "Replace WFI with mips.pause for MIPS P8700"
+	depends on ERRATA_MIPS && 64BIT
+	default n
+	help
+	   The RISCV MIPS P8700 has bugs with the WFI instruction.
+	   This errata replaces all WFI instructions with the MIPS
+	   P8700 pause opcode to avoid these issues.
+
+	   If you are not using the P8700 processor, say n.
+
 config ERRATA_SIFIVE
 	bool "SiFive errata"
 	depends on RISCV_ALTERNATIVE
diff --git a/arch/riscv/errata/mips/errata.c b/arch/riscv/errata/mips/errata.c
index e984a8152208c34690f89d8101571b097485c360..67b59f8c1708ea8b7a040f7939e111b8f30e6a75 100644
--- a/arch/riscv/errata/mips/errata.c
+++ b/arch/riscv/errata/mips/errata.c
@@ -23,6 +23,17 @@ static inline bool errata_probe_pause(void)
 	return true;
 }
 
+static inline bool errata_probe_wfi(void)
+{
+	if (!IS_ENABLED(CONFIG_ERRATA_MIPS_P8700_WFI))
+		return false;
+
+	if (!riscv_isa_vendor_extension_available(MIPS_VENDOR_ID, XMIPSEXECTL))
+		return false;
+
+	return true;
+}
+
 static u32 mips_errata_probe(void)
 {
 	u32 cpu_req_errata = 0;
@@ -30,6 +41,9 @@ static u32 mips_errata_probe(void)
 	if (errata_probe_pause())
 		cpu_req_errata |= BIT(ERRATA_MIPS_P8700_PAUSE_OPCODE);
 
+	if (errata_probe_wfi())
+		cpu_req_errata |= BIT(ERRATA_MIPS_P8700_WFI);
+
 	return cpu_req_errata;
 }
 
diff --git a/arch/riscv/include/asm/errata_list.h b/arch/riscv/include/asm/errata_list.h
index 6694b5ccdcf85cfe7e767ea4de981b34f2b17b04..cbe90b19556203e1462cfb345b164c9061887e74 100644
--- a/arch/riscv/include/asm/errata_list.h
+++ b/arch/riscv/include/asm/errata_list.h
@@ -25,6 +25,16 @@ ALTERNATIVE(__stringify(RISCV_PTR do_page_fault),			\
 	    __stringify(RISCV_PTR sifive_cip_453_page_fault_trp),	\
 	    SIFIVE_VENDOR_ID, ERRATA_SIFIVE_CIP_453,			\
 	    CONFIG_ERRATA_SIFIVE_CIP_453)
+
+#ifdef CONFIG_ERRATA_MIPS_P8700_WFI
+#define ALT_WFI								\
+ALTERNATIVE("wfi; .rept 7; nop; .endr;",				\
+	".rept 8; .insn 0x00501013; .endr;", MIPS_VENDOR_ID,		\
+	ERRATA_MIPS_P8700_WFI, CONFIG_ERRATA_MIPS_P8700_WFI)
+#else
+#define ALT_WFI	wfi
+#endif
+
 #else /* !__ASSEMBLER__ */
 
 #define ALT_SFENCE_VMA_ASID(asid)					\
@@ -53,6 +63,23 @@ asm(ALTERNATIVE(	\
 	: /* no inputs */	\
 	: "memory")
 
+#ifdef CONFIG_ERRATA_MIPS_P8700_WFI
+#define ALT_RISCV_WFI()										\
+asm volatile(ALTERNATIVE(									\
+		"wfi\n" /* Original RISC-V wfi insn */						\
+		__nops(7),									\
+		".rept 8;" MIPS_PAUSE ".endr;\n", /* Replacement: mips.pause for P8700 */	\
+		MIPS_VENDOR_ID, /* Vendor ID to match */					\
+		ERRATA_MIPS_P8700_WFI, /* patch_id */						\
+		CONFIG_ERRATA_MIPS_P8700_WFI)							\
+		: /* no outputs */								\
+		: /* no inputs */								\
+		: "memory")
+#else
+#define ALT_RISCV_WFI()		\
+	__asm__ __volatile__ ("wfi")
+#endif
+
 /*
  * _val is marked as "will be overwritten", so need to set it to 0
  * in the default case.
diff --git a/arch/riscv/include/asm/errata_list_vendors.h b/arch/riscv/include/asm/errata_list_vendors.h
index ec7eba3734371a2d8b68fbd4cbd88a8e7135a413..4505317a6b949be602f507547fc9cd495c923e32 100644
--- a/arch/riscv/include/asm/errata_list_vendors.h
+++ b/arch/riscv/include/asm/errata_list_vendors.h
@@ -22,8 +22,9 @@
 #endif
 
 #ifdef CONFIG_ERRATA_MIPS
-#define	ERRATA_MIPS_P8700_PAUSE_OPCODE 0
-#define	ERRATA_MIPS_NUMBER 1
+#define ERRATA_MIPS_P8700_PAUSE_OPCODE 0
+#define ERRATA_MIPS_P8700_WFI 1
+#define ERRATA_MIPS_NUMBER 2
 #endif
 
 #endif /* ASM_ERRATA_LIST_VENDORS_H */
diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h
index 4c3dd94d0f63844fecc32a7e2c1a184113ee49d9..ae4faed371c16ba33f31373561de03e89d35d04c 100644
--- a/arch/riscv/include/asm/processor.h
+++ b/arch/riscv/include/asm/processor.h
@@ -17,6 +17,7 @@
 #include <asm/alternative-macros.h>
 #include <asm/hwcap.h>
 #include <asm/usercfi.h>
+#include <asm/errata_list.h>
 
 #define arch_get_mmap_end(addr, len, flags)			\
 ({								\
@@ -176,7 +177,7 @@ extern unsigned long __get_wchan(struct task_struct *p);
 
 static inline void wait_for_interrupt(void)
 {
-	__asm__ __volatile__ ("wfi");
+	ALT_RISCV_WFI();
 }
 
 extern phys_addr_t dma32_phys_limit;
diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
index 9c99c5ad6fe8a32e24c8ce7e0badd63469d2c387..14935e8eec2639844c45bd37db29db74fee38a22 100644
--- a/arch/riscv/kernel/head.S
+++ b/arch/riscv/kernel/head.S
@@ -16,6 +16,8 @@
 #include <asm/scs.h>
 #include <asm/xip_fixup.h>
 #include <asm/usercfi.h>
+#include <asm/alternative.h>
+#include <asm/errata_list.h>
 #include "efi-header.S"
 
 __HEAD
@@ -196,7 +198,7 @@ secondary_start_sbi:
 	 *  - receive an early trap, before setup_trap_vector finished
 	 *  - fail in smp_callin(), as a successful one wouldn't return
 	 */
-	wfi
+	ALT_WFI
 	j .Lsecondary_park
 
 .align 2

---
base-commit: c369299895a591d96745d6492d4888259b004a9e
change-id: 20260415-p8700-wfi-9083b1d87d22

Best regards,
-- 
Aleksa Paunovic <aleksa.paunovic@htecgroup.com>
Re: [PATCH] riscv: Add ERRATA_MIPS_P8700_WFI to replace WFI with mips.pause
Posted by kernel test robot 4 weeks, 1 day ago
Hi Aleksa,

kernel test robot noticed the following build errors:

[auto build test ERROR on c369299895a591d96745d6492d4888259b004a9e]

url:    https://github.com/intel-lab-lkp/linux/commits/Aleksa-Paunovic-via-B4-Relay/riscv-Add-ERRATA_MIPS_P8700_WFI-to-replace-WFI-with-mips-pause/20260513-011847
base:   c369299895a591d96745d6492d4888259b004a9e
patch link:    https://lore.kernel.org/r/20260511-p8700-wfi-v1-1-099b1d10fcf2%40htecgroup.com
patch subject: [PATCH] riscv: Add ERRATA_MIPS_P8700_WFI to replace WFI with mips.pause
config: riscv-allyesconfig (https://download.01.org/0day-ci/archive/20260514/202605141021.Fw5Aqgfw-lkp@intel.com/config)
compiler: clang version 16.0.6 (https://github.com/llvm/llvm-project 7cbf1a2591520c2491aa35339f227775f4d3adf6)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260514/202605141021.Fw5Aqgfw-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202605141021.Fw5Aqgfw-lkp@intel.com/

All errors (new ones prefixed by >>):

>> <instantiation>:1:7: error: expected instruction format
   .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .endr
         ^
   <instantiation>:10:2: note: while in macro instantiation
    .rept 8; .insn 0x00501013; .endr;
    ^
   <instantiation>:8:2: note: while in macro instantiation
    ALT_NEW_CONTENT 0x127, 1, 1, ".rept 8; .insn 0x00501013; .endr;"
    ^
   arch/riscv/kernel/head.S:201:2: note: while in macro instantiation
    ALTERNATIVE_CFG "wfi; .rept 7; nop; .endr;", ".rept 8; .insn 0x00501013; .endr;", 0x127, 1, 1
    ^
   <instantiation>:1:25: error: expected instruction format
   .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .endr
                           ^
   <instantiation>:10:2: note: while in macro instantiation
    .rept 8; .insn 0x00501013; .endr;
    ^
   <instantiation>:8:2: note: while in macro instantiation
    ALT_NEW_CONTENT 0x127, 1, 1, ".rept 8; .insn 0x00501013; .endr;"
    ^
   arch/riscv/kernel/head.S:201:2: note: while in macro instantiation
    ALTERNATIVE_CFG "wfi; .rept 7; nop; .endr;", ".rept 8; .insn 0x00501013; .endr;", 0x127, 1, 1
    ^
   <instantiation>:1:43: error: expected instruction format
   .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .endr
                                             ^
   <instantiation>:10:2: note: while in macro instantiation
    .rept 8; .insn 0x00501013; .endr;
    ^
   <instantiation>:8:2: note: while in macro instantiation
    ALT_NEW_CONTENT 0x127, 1, 1, ".rept 8; .insn 0x00501013; .endr;"
    ^
   arch/riscv/kernel/head.S:201:2: note: while in macro instantiation
    ALTERNATIVE_CFG "wfi; .rept 7; nop; .endr;", ".rept 8; .insn 0x00501013; .endr;", 0x127, 1, 1
    ^
   <instantiation>:1:61: error: expected instruction format
   .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .endr
                                                               ^
   <instantiation>:10:2: note: while in macro instantiation
    .rept 8; .insn 0x00501013; .endr;
    ^
   <instantiation>:8:2: note: while in macro instantiation
    ALT_NEW_CONTENT 0x127, 1, 1, ".rept 8; .insn 0x00501013; .endr;"
    ^
   arch/riscv/kernel/head.S:201:2: note: while in macro instantiation
    ALTERNATIVE_CFG "wfi; .rept 7; nop; .endr;", ".rept 8; .insn 0x00501013; .endr;", 0x127, 1, 1
    ^
   <instantiation>:1:79: error: expected instruction format
   .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .endr
                                                                                 ^
   <instantiation>:10:2: note: while in macro instantiation
    .rept 8; .insn 0x00501013; .endr;
    ^
   <instantiation>:8:2: note: while in macro instantiation
    ALT_NEW_CONTENT 0x127, 1, 1, ".rept 8; .insn 0x00501013; .endr;"
    ^
   arch/riscv/kernel/head.S:201:2: note: while in macro instantiation
    ALTERNATIVE_CFG "wfi; .rept 7; nop; .endr;", ".rept 8; .insn 0x00501013; .endr;", 0x127, 1, 1
    ^
   <instantiation>:1:97: error: expected instruction format
   .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .endr
                                                                                                   ^
   <instantiation>:10:2: note: while in macro instantiation
    .rept 8; .insn 0x00501013; .endr;
    ^
   <instantiation>:8:2: note: while in macro instantiation
    ALT_NEW_CONTENT 0x127, 1, 1, ".rept 8; .insn 0x00501013; .endr;"
    ^
   arch/riscv/kernel/head.S:201:2: note: while in macro instantiation
    ALTERNATIVE_CFG "wfi; .rept 7; nop; .endr;", ".rept 8; .insn 0x00501013; .endr;", 0x127, 1, 1
    ^
   <instantiation>:1:115: error: expected instruction format
   .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .endr
                                                                                                                     ^
   <instantiation>:10:2: note: while in macro instantiation
    .rept 8; .insn 0x00501013; .endr;
    ^
   <instantiation>:8:2: note: while in macro instantiation
    ALT_NEW_CONTENT 0x127, 1, 1, ".rept 8; .insn 0x00501013; .endr;"
    ^
   arch/riscv/kernel/head.S:201:2: note: while in macro instantiation
    ALTERNATIVE_CFG "wfi; .rept 7; nop; .endr;", ".rept 8; .insn 0x00501013; .endr;", 0x127, 1, 1
    ^
   <instantiation>:1:133: error: expected instruction format
   .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .insn 0x00501013; .endr
                                                                                                                                       ^
   <instantiation>:10:2: note: while in macro instantiation
    .rept 8; .insn 0x00501013; .endr;
    ^
   <instantiation>:8:2: note: while in macro instantiation
    ALT_NEW_CONTENT 0x127, 1, 1, ".rept 8; .insn 0x00501013; .endr;"
    ^
   arch/riscv/kernel/head.S:201:2: note: while in macro instantiation
    ALTERNATIVE_CFG "wfi; .rept 7; nop; .endr;", ".rept 8; .insn 0x00501013; .endr;", 0x127, 1, 1
    ^

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Re: [PATCH] riscv: Add ERRATA_MIPS_P8700_WFI to replace WFI with mips.pause
Posted by Paul Walmsley 1 month ago
Hi,

On Mon, 11 May 2026, Aleksa Paunovic via B4 Relay wrote:

> From: Djordje Todorovic <djordje.todorovic@htecgroup.com>
> 
> The MIPS P8700 has bugs with the WFI instruction. 

Has MIPS published an erratum for this?   If so, could you add a link to 
it in the patch description?  If not, could you please briefly describe 
the impact of the bug in the patch description, when WFI is used?

> This errata uses the RISC-V alternatives framework to patch all WFI 
> instructions with the MIPS P8700 pause opcode (0x00501013) at runtime 
> when running on P8700 hardware.
> 
> Two call sites are patched:
>  - arch/riscv/kernel/head.S: secondary hart parking loop
>  - arch/riscv/include/asm/processor.h: wait_for_interrupt()
> 
> Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
> Signed-off-by: Aleksa Paunovic <aleksa.paunovic@htecgroup.com>
> ---
> This patch was tested on QEMU configured with eight P8700 harts,
> as well as on the MIPS Boston board, configured with a single P8700 CPU.
> Errata application was tested by disassembling with GDB on QEMU
> and inserting an illegal instruction on the Boston board.
> Correctness was tested with a combination of kselftests
> and torture tests (rcu, locktorture), along with coremark testing.

This kind of test report is very helpful!  Thank you.

> ---
>  arch/riscv/Kconfig.errata                    | 11 +++++++++++
>  arch/riscv/errata/mips/errata.c              | 14 ++++++++++++++
>  arch/riscv/include/asm/errata_list.h         | 27 +++++++++++++++++++++++++++
>  arch/riscv/include/asm/errata_list_vendors.h |  5 +++--
>  arch/riscv/include/asm/processor.h           |  3 ++-
>  arch/riscv/kernel/head.S                     |  4 +++-
>  6 files changed, 60 insertions(+), 4 deletions(-)
> 

[ ... ]

> diff --git a/arch/riscv/include/asm/errata_list.h b/arch/riscv/include/asm/errata_list.h
> index 6694b5ccdcf85cfe7e767ea4de981b34f2b17b04..cbe90b19556203e1462cfb345b164c9061887e74 100644
> --- a/arch/riscv/include/asm/errata_list.h
> +++ b/arch/riscv/include/asm/errata_list.h
> @@ -25,6 +25,16 @@ ALTERNATIVE(__stringify(RISCV_PTR do_page_fault),			\
>  	    __stringify(RISCV_PTR sifive_cip_453_page_fault_trp),	\
>  	    SIFIVE_VENDOR_ID, ERRATA_SIFIVE_CIP_453,			\
>  	    CONFIG_ERRATA_SIFIVE_CIP_453)
> +
> +#ifdef CONFIG_ERRATA_MIPS_P8700_WFI
> +#define ALT_WFI								\
> +ALTERNATIVE("wfi; .rept 7; nop; .endr;",				\
> +	".rept 8; .insn 0x00501013; .endr;", MIPS_VENDOR_ID,		\
> +	ERRATA_MIPS_P8700_WFI, CONFIG_ERRATA_MIPS_P8700_WFI)

.insn only works on newer toolchains/binutils versions - this is why 
CONFIG_AS_HAS_INSN was added.  See for example commit 
dc20452e6caf962f04ede7f364267b0c37784ab4 ("riscv: Fix CONFIG_AS_HAS_INSN 
for new .insn usage").  Can you please fix this?

Please add some sort of code comment to describe why 8 MIPS PAUSE 
instructions are needed, as opposed to a single MIPS PAUSE instruction.  
An event that causes the first PAUSE to exit would then encounter the 
subsequent PAUSEs, at which point, there could be additional latency 
before the core can return to doing real work.  The P8700 Programmer's 
Guide mentions a maximum number of cycles per PAUSE instruction, but 
doesn't state what it is precisely.  Could you please add a comment here 
to describe what it is?

> +#else
> +#define ALT_WFI	wfi
> +#endif
> +
>  #else /* !__ASSEMBLER__ */
>  
>  #define ALT_SFENCE_VMA_ASID(asid)					\
> @@ -53,6 +63,23 @@ asm(ALTERNATIVE(	\
>  	: /* no inputs */	\
>  	: "memory")
>  
> +#ifdef CONFIG_ERRATA_MIPS_P8700_WFI
> +#define ALT_RISCV_WFI()										\
> +asm volatile(ALTERNATIVE(									\
> +		"wfi\n" /* Original RISC-V wfi insn */						\
> +		__nops(7),									\
> +		".rept 8;" MIPS_PAUSE ".endr;\n", /* Replacement: mips.pause for P8700 */	\
> +		MIPS_VENDOR_ID, /* Vendor ID to match */					\
> +		ERRATA_MIPS_P8700_WFI, /* patch_id */						\
> +		CONFIG_ERRATA_MIPS_P8700_WFI)							\
> +		: /* no outputs */								\
> +		: /* no inputs */								\
> +		: "memory")
> +#else
> +#define ALT_RISCV_WFI()		\
> +	__asm__ __volatile__ ("wfi")
> +#endif
> +
>  /*
>   * _val is marked as "will be overwritten", so need to set it to 0
>   * in the default case.


thanks,

- Paul
Re: [PATCH] riscv: Add ERRATA_MIPS_P8700_WFI to replace WFI with mips.pause
Posted by Aleksa Paunovic 3 weeks, 2 days ago
Hi Paul,

Thank you for taking the time to review the patch!


On 5/13/26 20:25, Paul Walmsley wrote:
> Hi,
>
> On Mon, 11 May 2026, Aleksa Paunovic via B4 Relay wrote:
>
>> From: Djordje Todorovic <djordje.todorovic@htecgroup.com>
>>
>> The MIPS P8700 has bugs with the WFI instruction.
> Has MIPS published an erratum for this?   If so, could you add a link to
> it in the patch description?  If not, could you please briefly describe
> the impact of the bug in the patch description, when WFI is used?

MIPS has not published an erratum for this. Briefly, a WFI instruction
after a mispredicted branch can result in erroneous address translation.
>> This errata uses the RISC-V alternatives framework to patch all WFI
>> instructions with the MIPS P8700 pause opcode (0x00501013) at runtime
>> when running on P8700 hardware.
>>
>> Two call sites are patched:
>>  - arch/riscv/kernel/head.S: secondary hart parking loop
>>  - arch/riscv/include/asm/processor.h: wait_for_interrupt()
>>
>> Signed-off-by: Djordje Todorovic <djordje.todorovic@htecgroup.com>
>> Signed-off-by: Aleksa Paunovic <aleksa.paunovic@htecgroup.com>
>> ---
>> This patch was tested on QEMU configured with eight P8700 harts,
>> as well as on the MIPS Boston board, configured with a single P8700 CPU.
>> Errata application was tested by disassembling with GDB on QEMU
>> and inserting an illegal instruction on the Boston board.
>> Correctness was tested with a combination of kselftests
>> and torture tests (rcu, locktorture), along with coremark testing.
> This kind of test report is very helpful!  Thank you.
>
>> ---
>>  arch/riscv/Kconfig.errata                    | 11 +++++++++++
>>  arch/riscv/errata/mips/errata.c              | 14 ++++++++++++++
>>  arch/riscv/include/asm/errata_list.h         | 27 +++++++++++++++++++++++++++
>>  arch/riscv/include/asm/errata_list_vendors.h |  5 +++--
>>  arch/riscv/include/asm/processor.h           |  3 ++-
>>  arch/riscv/kernel/head.S                     |  4 +++-
>>  6 files changed, 60 insertions(+), 4 deletions(-)
>>
> [ ... ]
>
>> diff --git a/arch/riscv/include/asm/errata_list.h b/arch/riscv/include/asm/errata_list.h
>> index 6694b5ccdcf85cfe7e767ea4de981b34f2b17b04..cbe90b19556203e1462cfb345b164c9061887e74 100644
>> --- a/arch/riscv/include/asm/errata_list.h
>> +++ b/arch/riscv/include/asm/errata_list.h
>> @@ -25,6 +25,16 @@ ALTERNATIVE(__stringify(RISCV_PTR do_page_fault),                  \
>>           __stringify(RISCV_PTR sifive_cip_453_page_fault_trp),       \
>>           SIFIVE_VENDOR_ID, ERRATA_SIFIVE_CIP_453,                    \
>>           CONFIG_ERRATA_SIFIVE_CIP_453)
>> +
>> +#ifdef CONFIG_ERRATA_MIPS_P8700_WFI
>> +#define ALT_WFI                                                              \
>> +ALTERNATIVE("wfi; .rept 7; nop; .endr;",                             \
>> +     ".rept 8; .insn 0x00501013; .endr;", MIPS_VENDOR_ID,            \
>> +     ERRATA_MIPS_P8700_WFI, CONFIG_ERRATA_MIPS_P8700_WFI)
> .insn only works on newer toolchains/binutils versions - this is why
> CONFIG_AS_HAS_INSN was added.  See for example commit
> dc20452e6caf962f04ede7f364267b0c37784ab4 ("riscv: Fix CONFIG_AS_HAS_INSN
> for new .insn usage").  Can you please fix this

Will fix this in v2!

>
> Please add some sort of code comment to describe why 8 MIPS PAUSE
> instructions are needed, as opposed to a single MIPS PAUSE instruction.
> An event that causes the first PAUSE to exit would then encounter the
> subsequent PAUSEs, at which point, there could be additional latency
> before the core can return to doing real work.  The P8700 Programmer's
> Guide mentions a maximum number of cycles per PAUSE instruction, but
> doesn't state what it is precisely.  Could you please add a comment here
> to describe what it is?

The number of PAUSE instructions was determined by testing on the Palladium
board configured with a P8700 CPU. Coremark performance was measured on
a one-core, two-harts setup. Coremark performance with eight PAUSE instructions
was equivalent to what was measured with WFI.

Kind regards,
Aleksa Paunovic
Re: [PATCH] riscv: Add ERRATA_MIPS_P8700_WFI to replace WFI with mips.pause
Posted by Maciej W. Rozycki 3 weeks ago
On Wed, 20 May 2026, Aleksa Paunovic wrote:

> >> The MIPS P8700 has bugs with the WFI instruction.
> > Has MIPS published an erratum for this?   If so, could you add a link to
> > it in the patch description?  If not, could you please briefly describe
> > the impact of the bug in the patch description, when WFI is used?
> 
> MIPS has not published an erratum for this. Briefly, a WFI instruction
> after a mispredicted branch can result in erroneous address translation.

 Shouldn't this be recorded next to actual code rather just the commit 
description?

  Maciej
Re: [PATCH] riscv: Add ERRATA_MIPS_P8700_WFI to replace WFI with mips.pause
Posted by Aleksa Paunovic 4 days, 10 hours ago
Hi Maciej,

On 5/22/26 13:22, Maciej W. Rozycki wrote:
> On Wed, 20 May 2026, Aleksa Paunovic wrote:
>
>>>> The MIPS P8700 has bugs with the WFI instruction.
>>> Has MIPS published an erratum for this?   If so, could you add a link to
>>> it in the patch description?  If not, could you please briefly describe
>>> the impact of the bug in the patch description, when WFI is used?
>> MIPS has not published an erratum for this. Briefly, a WFI instruction
>> after a mispredicted branch can result in erroneous address translation.
>  Shouldn't this be recorded next to actual code rather just the commit
> description?
>
I added the full description of the issue in v2. 

Best regards,
Aleksa