From 861e44a3ba8ea2ee702555f35ea77a6c1056c196 Mon Sep 17 00:00:00 2001 From: Baptiste Le Duc Date: Wed, 30 Sep 2026 15:00:48 +0200 Subject: [PATCH] xen/riscv: make Zihintpause no longer a required extension Zihintpause is in required_extensions[] so Xen panics when it is missing, while it does not strictly require hardware support for it. The PAUSE hint (Zihintpause extension) is encoded as FENCE W, 0 (0x0100000F). In accordance with the RISC-V Unprivileged ISA, HINTs are encoded in the space of valid standard instructions. On platforms without Zihintpause support, executing 0x0100000F is treated as a standard FENCE with an empty successor set, which acts as a NOP and never generates an illegal instruction trap. Zihintpause is therefore purely an optimization hint. Drop it from required_extensions[] so Xen can still boot on systems that don't advertise it, and print a warning in that case. Assisted-by: Claude:claude-opus-5 Signed-off-by: Baptiste Le Duc Reviewed-by: Oleksii Kurochko --- docs/misc/riscv/booting.txt | 3 --- xen/arch/riscv/cpufeature.c | 12 +++++++++++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/docs/misc/riscv/booting.txt b/docs/misc/riscv/booting.txt index c99ccafa74..14212ed62f 100644 --- a/docs/misc/riscv/booting.txt +++ b/docs/misc/riscv/booting.txt @@ -19,9 +19,6 @@ them is missing from the riscv,isa property of the CPU nodes: a very simple sequence. The similar issue occurs with other __builtin_, so it is needed to provide a generic version of bitops in RISC-V bitops.h -- Zihintpause: - On a system that doesn't have this extension, cpu_relax() should be - implemented properly. - Svpbmt: Mandatory to enable changing the memory attributes of a page. For platforms that do not support Svpbmt, it is necessary to introduce a diff --git a/xen/arch/riscv/cpufeature.c b/xen/arch/riscv/cpufeature.c index 2d12dffae7..3d5bbd2228 100644 --- a/xen/arch/riscv/cpufeature.c +++ b/xen/arch/riscv/cpufeature.c @@ -214,7 +214,6 @@ static const struct riscv_isa_ext_data __initconst required_extensions[] = { RISCV_ISA_EXT_DATA(h), RISCV_ISA_EXT_DATA(zicsr), RISCV_ISA_EXT_DATA(zifencei), - RISCV_ISA_EXT_DATA(zihintpause), RISCV_ISA_EXT_DATA(zbb), RISCV_ISA_EXT_DATA(svpbmt), }; @@ -664,6 +663,17 @@ void __init riscv_fill_hwcap(void) __set_bit(RISCV_ISA_EXT_sstc, riscv_isa); } + /* + * Zihintpause isn't mandatory: the encoding used by cpu_relax() is a + * HINT which executes as a no-op on hardware without the extension. + * Report it, as a platform may provide its own way to hint a spin-wait + * loop, which then has to be wired up in cpu_relax(). + */ + if ( !riscv_isa_extension_available(NULL, RISCV_ISA_EXT_zihintpause) ) + printk(XENLOG_WARNING + "Zihintpause unavailable: cpu_relax() gives the CPU no hint; " + "wire up this platform's pause equivalent in cpu_relax()\n"); + for ( i = 0; i < req_extns_amount; i++ ) { const struct riscv_isa_ext_data ext = required_extensions[i];