aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYong-Xuan Wang <yongxuan.wang@sifive.com>2026-10-05 19:02:38 -0600
committerPaul Walmsley <pjw@kernel.org>2026-10-05 19:02:38 -0600
commit148ab873d8194cb44f29474da3b4428fa2e100d1 (patch)
tree9d787f89fd2109d1771d659bb7deb1f22d8ddd6d
parentriscv: vector: Fix output operands in context save (diff)
RISC-V: errata: Add SiFive MAL-9092 workaround
SiFive cores with MAL-9092 require fence.rw instructions around HLV/HLVX/HSV hypervisor instructions to ensure proper memory ordering when accessing guest memory. Note that HSTATUS.HU is cleared during KVM initialization, restricting hypervisor instructions to HS-mode only. If future changes enable HSTATUS.HU for U-mode access, additional errata considerations will be needed. Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com> Reviewed-by: Samuel Holland <samuel.holland@sifive.com> Link: https://patch.msgid.link/20260817-sifive-errata-v1-1-6a80f1a2743d@sifive.com Signed-off-by: Paul Walmsley <pjw@kernel.org>
-rw-r--r--arch/riscv/Kconfig.errata14
-rw-r--r--arch/riscv/errata/sifive/errata.c20
-rw-r--r--arch/riscv/include/asm/errata_list_vendors.h3
-rw-r--r--arch/riscv/include/asm/insn-def.h16
4 files changed, 49 insertions, 4 deletions
diff --git a/arch/riscv/Kconfig.errata b/arch/riscv/Kconfig.errata
index 38ade0ea4e9c..a6aac8774f25 100644
--- a/arch/riscv/Kconfig.errata
+++ b/arch/riscv/Kconfig.errata
@@ -96,6 +96,20 @@ config ERRATA_STARFIVE_JH7100
Say "Y" if you want to support the BeagleV Starlight and/or
StarFive VisionFive V1 boards.
+config ERRATA_SIFIVE_MAL_9092
+ bool "Apply SiFive HLV/HLVX/HSV fence errata"
+ depends on ERRATA_SIFIVE && 64BIT
+ default y
+ help
+ This will apply the SiFive MAL-9092 errata to add fence.rw
+ instructions around all HLV/HLVX/HSV instructions.
+
+ Note: HSTATUS.HU is cleared during KVM initialization. If future
+ changes enable HSTATUS.HU to allow hypervisor instructions in
+ U-mode, additional errata handling may be required.
+
+ If you don't know what to do here, say "Y".
+
config ERRATA_THEAD
bool "T-HEAD errata"
depends on RISCV_ALTERNATIVE
diff --git a/arch/riscv/errata/sifive/errata.c b/arch/riscv/errata/sifive/errata.c
index df80c9614df1..1a5d223ebf35 100644
--- a/arch/riscv/errata/sifive/errata.c
+++ b/arch/riscv/errata/sifive/errata.c
@@ -51,6 +51,22 @@ static bool errata_cip_1200_check_func(unsigned long arch_id, unsigned long imp
return true;
}
+static bool errata_mal_9092_check_func(unsigned long arch_id, unsigned long impid)
+{
+ /*
+ * Affected cores:
+ * Architecture ID: 0x8000000000000109
+ * Implementation ID: 0x19251031, 0x19251217, 0x19260320
+ */
+
+ if (arch_id != 0x8000000000000109)
+ return false;
+ if (impid != 0x19251031 && impid != 0x19251217 && impid != 0x19260320)
+ return false;
+
+ return true;
+}
+
static struct errata_info_t errata_list[ERRATA_SIFIVE_NUMBER] = {
{
.name = "cip-453",
@@ -60,6 +76,10 @@ static struct errata_info_t errata_list[ERRATA_SIFIVE_NUMBER] = {
.name = "cip-1200",
.check_func = errata_cip_1200_check_func
},
+ {
+ .name = "mal-9092",
+ .check_func = errata_mal_9092_check_func
+ },
};
static u32 __init_or_module sifive_errata_probe(unsigned long archid,
diff --git a/arch/riscv/include/asm/errata_list_vendors.h b/arch/riscv/include/asm/errata_list_vendors.h
index ec7eba373437..c62a82f60468 100644
--- a/arch/riscv/include/asm/errata_list_vendors.h
+++ b/arch/riscv/include/asm/errata_list_vendors.h
@@ -11,7 +11,8 @@
#ifdef CONFIG_ERRATA_SIFIVE
#define ERRATA_SIFIVE_CIP_453 0
#define ERRATA_SIFIVE_CIP_1200 1
-#define ERRATA_SIFIVE_NUMBER 2
+#define ERRATA_SIFIVE_MAL_9092 2
+#define ERRATA_SIFIVE_NUMBER 3
#endif
#ifdef CONFIG_ERRATA_THEAD
diff --git a/arch/riscv/include/asm/insn-def.h b/arch/riscv/include/asm/insn-def.h
index 7c6daf116756..8fcc848c196e 100644
--- a/arch/riscv/include/asm/insn-def.h
+++ b/arch/riscv/include/asm/insn-def.h
@@ -192,18 +192,28 @@
INSN_R(OPCODE_SYSTEM, FUNC3(0), FUNC7(49), \
__RD(0), RS1(gaddr), RS2(vmid))
+#define ALT_SIFIVE_MAL_9092_FENCE \
+ALTERNATIVE("nop", "fence rw, rw", SIFIVE_VENDOR_ID, \
+ ERRATA_SIFIVE_MAL_9092, CONFIG_ERRATA_SIFIVE_MAL_9092)
+
#define HLVX_HU(dest, addr) \
+ ALT_SIFIVE_MAL_9092_FENCE "\n" \
INSN_R(OPCODE_SYSTEM, FUNC3(4), FUNC7(50), \
- RD(dest), RS1(addr), __RS2(3))
+ RD(dest), RS1(addr), __RS2(3)) "\n" \
+ ALT_SIFIVE_MAL_9092_FENCE
#define HLV_W(dest, addr) \
+ ALT_SIFIVE_MAL_9092_FENCE "\n" \
INSN_R(OPCODE_SYSTEM, FUNC3(4), FUNC7(52), \
- RD(dest), RS1(addr), __RS2(0))
+ RD(dest), RS1(addr), __RS2(0)) "\n" \
+ ALT_SIFIVE_MAL_9092_FENCE
#ifdef CONFIG_64BIT
#define HLV_D(dest, addr) \
+ ALT_SIFIVE_MAL_9092_FENCE "\n" \
INSN_R(OPCODE_SYSTEM, FUNC3(4), FUNC7(54), \
- RD(dest), RS1(addr), __RS2(0))
+ RD(dest), RS1(addr), __RS2(0)) "\n" \
+ ALT_SIFIVE_MAL_9092_FENCE
#else
#define HLV_D(dest, addr) \
__ASM_STR(.error "hlv.d requires 64-bit support")