On Thu, Oct 22, 2026 at 03:06:57PM +0800, Anton Johansson wrote:
> mstatus and mstatus_hs are uint64_t but accessed through
>
> tcg_gen_[ld|st]_tl(..., offsetof(mstatus))
>
> which on a big-endian host running riscv32 incorrectly accesses the
> top 32 bits rather than the lower bits.
>
> Widen the operations to 64 bit so the lower bits are modified.
>
Please also add a `Fixes` tag pointing to the commit that introduced this bug.
The format is,
Fixes: <12+ hex SHA> ("<original commit subject>")
Thanks,
Chao
> Signed-off-by: Anton Johansson <[email protected]>
> ---
> target/riscv/tcg/translate.c | 32 ++++++++++++++++----------------
> 1 file changed, 16 insertions(+), 16 deletions(-)
>
> diff --git a/target/riscv/tcg/translate.c b/target/riscv/tcg/translate.c
> index ede9c2563f..79b0f444ef 100644
> --- a/target/riscv/tcg/translate.c
> +++ b/target/riscv/tcg/translate.c
> @@ -693,7 +693,7 @@ static TCGv get_address_indexed(DisasContext *ctx, int
> rs1, TCGv offs)
> */
> static void mark_fs_dirty(DisasContext *ctx)
> {
> - TCGv tmp;
> + TCGv_i64 tmp;
>
> if (!has_ext(ctx, RVF)) {
> return;
> @@ -703,15 +703,15 @@ static void mark_fs_dirty(DisasContext *ctx)
> /* Remember the state change for the rest of the TB. */
> ctx->mstatus_fs = EXT_STATUS_DIRTY;
>
> - tmp = tcg_temp_new();
> - tcg_gen_ld_tl(tmp, tcg_env, offsetof(CPURISCVState, mstatus));
> - tcg_gen_ori_tl(tmp, tmp, MSTATUS_FS);
> - tcg_gen_st_tl(tmp, tcg_env, offsetof(CPURISCVState, mstatus));
> + tmp = tcg_temp_new_i64();
> + tcg_gen_ld_i64(tmp, tcg_env, offsetof(CPURISCVState, mstatus));
> + tcg_gen_ori_i64(tmp, tmp, MSTATUS_FS);
> + tcg_gen_st_i64(tmp, tcg_env, offsetof(CPURISCVState, mstatus));
>
> if (ctx->virt_enabled) {
> - tcg_gen_ld_tl(tmp, tcg_env, offsetof(CPURISCVState, mstatus_hs));
> - tcg_gen_ori_tl(tmp, tmp, MSTATUS_FS);
> - tcg_gen_st_tl(tmp, tcg_env, offsetof(CPURISCVState, mstatus_hs));
> + tcg_gen_ld_i64(tmp, tcg_env, offsetof(CPURISCVState,
> mstatus_hs));
> + tcg_gen_ori_i64(tmp, tmp, MSTATUS_FS);
> + tcg_gen_st_i64(tmp, tcg_env, offsetof(CPURISCVState,
> mstatus_hs));
> }
> }
> }
> @@ -726,21 +726,21 @@ static inline void mark_fs_dirty(DisasContext *ctx) { }
> */
> static void mark_vs_dirty(DisasContext *ctx)
> {
> - TCGv tmp;
> + TCGv_i64 tmp;
>
> if (ctx->mstatus_vs != EXT_STATUS_DIRTY) {
> /* Remember the state change for the rest of the TB. */
> ctx->mstatus_vs = EXT_STATUS_DIRTY;
>
> - tmp = tcg_temp_new();
> - tcg_gen_ld_tl(tmp, tcg_env, offsetof(CPURISCVState, mstatus));
> - tcg_gen_ori_tl(tmp, tmp, MSTATUS_VS);
> - tcg_gen_st_tl(tmp, tcg_env, offsetof(CPURISCVState, mstatus));
> + tmp = tcg_temp_new_i64();
> + tcg_gen_ld_i64(tmp, tcg_env, offsetof(CPURISCVState, mstatus));
> + tcg_gen_ori_i64(tmp, tmp, MSTATUS_VS);
> + tcg_gen_st_i64(tmp, tcg_env, offsetof(CPURISCVState, mstatus));
>
> if (ctx->virt_enabled) {
> - tcg_gen_ld_tl(tmp, tcg_env, offsetof(CPURISCVState, mstatus_hs));
> - tcg_gen_ori_tl(tmp, tmp, MSTATUS_VS);
> - tcg_gen_st_tl(tmp, tcg_env, offsetof(CPURISCVState, mstatus_hs));
> + tcg_gen_ld_i64(tmp, tcg_env, offsetof(CPURISCVState,
> mstatus_hs));
> + tcg_gen_ori_i64(tmp, tmp, MSTATUS_VS);
> + tcg_gen_st_i64(tmp, tcg_env, offsetof(CPURISCVState,
> mstatus_hs));
> }
> }
> }
> --
> 2.52.0
>