RISC-V: U-mode hpmcounter* reads retire even with mcounteren=0
RISC-V: U-mode hpmcounter* reads retire even with mcounteren=0
Rechecked revision
The five reports were rechecked against the public Unicorn dev branch at
938efd13aeab73155f31cf707a2094c6ccaa36dd.
Problem
mcounteren gates S/U-mode reads of cycle/time/instret and
hpmcounter3..31 regardless of the privileged-spec version. mcountinhibit
controls counting, which is a separate behavior. Unicorn's ctr CSR
predicate returns success for every counter CSR on newer privileged-spec
versions, so a U-mode hpmcounter3 read retires with mcounteren=0.
Public reproducer
The self-contained witness and runner are available at
https://github.com/carlosqwqqwq/unicorn-riscv-repros/tree/main/u009.
After building the public dev checkout, run:
python3 -m pip install -r https://raw.githubusercontent.com/carlosqwqqwq/unicorn-riscv-repros/main/requirements.txt
LIBUNICORN_PATH=/path/to/unicorn/build ./u009/run.shThe affected path reaches the terminal ebreak; the corrected path returns
UC_ERR_EXCEPTION on the U-mode counter read.
Expected behavior
The access must trap when mcounteren=0; M-mode counter access remains
available. QEMU and native RISC-V controls reject the same U-mode access.
Root cause and proposed fix
qemu/target/riscv/csr.c:ctr() has an early-success branch keyed only on the
privileged-spec version. Removing that branch makes the existing
mcounteren/scounteren checks apply to every supported version.
The proposed change is limited to the CSR predicate and is accompanied by a focused unit test in PR #2392.
Source: unicorn-engine/unicorn