Message ID | 20250221135735.85151-1-vladimir.isaev@syntacore.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | [v2] target/riscv: fix C extension disabling on misa write | expand |
On 2/21/25 10:57 AM, Vladimir Isaev wrote: > According to spec: > Writing misa may increase IALIGN, e.g., by disabling the "C" extension. If an instruction that would > write misa increases IALIGN, and the subsequent instruction’s address is not IALIGN-bit aligned, the > write to misa is suppressed, leaving misa unchanged. > > So we should suppress write to misa without "C" if it is enabled > and the subsequent instruction is not aligned to 4. > > Fixes: f18637cd611c ("RISC-V: Add misa runtime write support") > Signed-off-by: Vladimir Isaev <vladimir.isaev@syntacore.com> > --- > v2: > - use env->pc instead of GETPC() since GETPC() is a host pc; > - use !QEMU_IS_ALIGNED(env->pc, 4) instead of GETPC() & 3; > > --- Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> > target/riscv/csr.c | 10 ++++++---- > 1 file changed, 6 insertions(+), 4 deletions(-) > > diff --git a/target/riscv/csr.c b/target/riscv/csr.c > index afb7544f0780..8aa77c53a0db 100644 > --- a/target/riscv/csr.c > +++ b/target/riscv/csr.c > @@ -2067,11 +2067,13 @@ static RISCVException write_misa(CPURISCVState *env, int csrno, > val &= env->misa_ext_mask; > > /* > - * Suppress 'C' if next instruction is not aligned > - * TODO: this should check next_pc > + * Disabling 'C' increases IALIGN to 32. If subsequent instruction's address > + * is not 32-bit aligned, write to misa is suppressed. > + * > + * All csr-related instructions are 4-byte, so we can check current pc alignment. > */ > - if ((val & RVC) && (GETPC() & ~3) != 0) { > - val &= ~RVC; > + if (!(val & RVC) && (env->misa_ext & RVC) && !QEMU_IS_ALIGNED(env->pc, 4)) { > + return RISCV_EXCP_NONE; > } > > /* Disable RVG if any of its dependencies are disabled */
diff --git a/target/riscv/csr.c b/target/riscv/csr.c index afb7544f0780..8aa77c53a0db 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -2067,11 +2067,13 @@ static RISCVException write_misa(CPURISCVState *env, int csrno, val &= env->misa_ext_mask; /* - * Suppress 'C' if next instruction is not aligned - * TODO: this should check next_pc + * Disabling 'C' increases IALIGN to 32. If subsequent instruction's address + * is not 32-bit aligned, write to misa is suppressed. + * + * All csr-related instructions are 4-byte, so we can check current pc alignment. */ - if ((val & RVC) && (GETPC() & ~3) != 0) { - val &= ~RVC; + if (!(val & RVC) && (env->misa_ext & RVC) && !QEMU_IS_ALIGNED(env->pc, 4)) { + return RISCV_EXCP_NONE; } /* Disable RVG if any of its dependencies are disabled */
According to spec: Writing misa may increase IALIGN, e.g., by disabling the "C" extension. If an instruction that would write misa increases IALIGN, and the subsequent instruction’s address is not IALIGN-bit aligned, the write to misa is suppressed, leaving misa unchanged. So we should suppress write to misa without "C" if it is enabled and the subsequent instruction is not aligned to 4. Fixes: f18637cd611c ("RISC-V: Add misa runtime write support") Signed-off-by: Vladimir Isaev <vladimir.isaev@syntacore.com> --- v2: - use env->pc instead of GETPC() since GETPC() is a host pc; - use !QEMU_IS_ALIGNED(env->pc, 4) instead of GETPC() & 3; --- target/riscv/csr.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)