[Bug 220795] riscv_hwprobe and AT_HWCAP diverge after PR_RISCV_V_VSTATE_CTRL_OFF

Paul Walmsley pjw at kernel.org
Mon Nov 24 17:39:33 PST 2025


Hi Conor,

On Mon, 24 Nov 2025, Conor Dooley wrote:

> I got added to some bugzilla thing last week about the vector prctl and
> how it interacts with hwprobe. I have no idea why I alone was chosen,
> since I didn't write this stuff, so I'm linking the issue here so that
> someone that does understand it can reply:
> https://bugzilla.kernel.org/show_bug.cgi?id=220795

Thanks for passing this along.

> The content of that is:
> | Overview:
> | 
> | On RISC-V systems with Vector support, invoking
> | 
> | prctl(PR_RISCV_V_SET_CONTROL, PR_RISCV_V_VSTATE_CTRL_OFF)
> | 
> | 
> | disables execution of V instructions for subsequently executed ELF programs, as expected.
> | 
> | However, after this call:
> | 
> | AT_HWCAP no longer reports the V bit, indicating that Vector execution is not allowed for new programs, while
> | 
> | riscv_hwprobe() continues to report RISCV_HWPROBE_IMA_V as present.
> | 
> | At the same time, multiple downstream user-space components (such as libgcc [1]) already treat riscv_hwprobe as the authoritative source of ISA capability information, since AT_HWCAP has historically been polluted by inconsistent vendor reporting for RVV and cannot represent multi-letter extensions (V, Zve*, Zvfh*, etc.).
> | 
> | As a result, downstream runtimes may select RVV-enabled code paths even when V has been disabled for the program by system policy.
> | 
> | To proceed with downstream libc RVV multiversioning work, we would like to confirm whether this divergence between AT_HWCAP and riscv_hwprobe() after PR_RISCV_V_VSTATE_CTRL_OFF is intended (by design), or if it should be considered an unintended semantic inconsistency.
> | 
> | Additional Context:
> | 
> | This concern has been raised before in prior discussions [2], noting that hwprobe reports capability while AT_HWCAP reflects availability, creating ambiguity about which interface user space should rely on.
> | 
> | Reproduce Log:
> | [init] ./rvv_check
> | AT_HWCAP = 0x000000000020112d
> | V via HWCAP:   yes
> | hwprobe KEY_IMA_EXT_0 = 0x038d2bf1200000ff
> | V via hwprobe: yes
> | [init] ./rvv_off rvv_check
> | PR_RISCV_V_GET_CONTROL = 0x16
> | AT_HWCAP = 0x000000000000112d
> | V via HWCAP:   no
> | hwprobe KEY_IMA_EXT_0 = 0x038d2bf1200000ff
> | V via hwprobe: yes
> | [init] poweroff
> | [    1.880906] reboot: Power down
> | 
> | References:
> | [1] https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=libgcc/config/riscv/feature_bits.c;h=157bcdcad69a939037f6faca3a90c2598dd61f89;hb=HEAD
> | [2] https://lists.infradead.org/pipermail/kvm-riscv/2023-June/003915.html

Will reply in more detail on the Bugzilla.  For the archives: the short 
version of the story is that, so far, this is the intended behavior.  This 
became possible because we wished to avoid a potential ABI break in a 
corner case when non-vector-supporting userspace code is mixed with 
vector-supporting userspace code.  Context:

    https://lore.kernel.org/all/87cz4048rp.fsf@all.your.base.are.belong.to.us/


- Paul



More information about the linux-riscv mailing list