[PATCH] tcg: Fix the overflow in indexing tcg_ctx->temps

Zhiwei Jiang posted 1 patch 1 week, 6 days ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20240418102747.27703-1-jiangzw@tecorigin.com
Maintainers: Richard Henderson <richard.henderson@linaro.org>, Paolo Bonzini <pbonzini@redhat.com>
include/tcg/tcg.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
[PATCH] tcg: Fix the overflow in indexing tcg_ctx->temps
Posted by Zhiwei Jiang 1 week, 6 days ago
Sometimes, when the address of the passed TCGTemp *ts variable is the same as tcg_ctx,
the index calculated in the temp_idx function, i.e., ts - tcg_ctx->temps,
can result in a particularly large value, causing overflow in the subsequent array access.

0  0x00007f79590132ac in test_bit (addr=<optimized out>, nr=<optimized out>)
    at /data/system/jiangzw/release_version/qemu8.2/include/qemu/bitops.h:135
1  init_ts_info (ctx=ctx@entry=0x7f794bffe460, ts=0x7f76fc000e00) at ../tcg/optimize.c:148
2  0x00007f7959014b50 in init_arguments (nb_args=2, op=0x7f76fc0101f8, ctx=0x7f794bffe460) at ../tcg/optimize.c:792
3  fold_call (op=0x7f76fc0101f8, ctx=0x7f794bffe460) at ../tcg/optimize.c:1348
4  tcg_optimize (s=<optimized out>) at ../tcg/optimize.c:2369
5  0x00007f7958ffa136 in tcg_gen_code (s=0x7f76fc000e00, tb=0x7f7904202380, pc_start=140741246462840) at ../tcg/tcg.c:6066

Signed-off-by: Zhiwei Jiang <jiangzw@tecorigin.com>
---
 include/tcg/tcg.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
index 05a1912f8a..4b38d2702d 100644
--- a/include/tcg/tcg.h
+++ b/include/tcg/tcg.h
@@ -629,7 +629,7 @@ static inline size_t temp_idx(TCGTemp *ts)
  */
 static inline TCGTemp *tcgv_i32_temp(TCGv_i32 v)
 {
-    return (void *)tcg_ctx + (uintptr_t)v;
+    return (void *)tcg_ctx->temps + (uintptr_t)v;
 }
 #endif
 
@@ -681,7 +681,7 @@ static inline TCGArg tcgv_vec_arg(TCGv_vec v)
 static inline TCGv_i32 temp_tcgv_i32(TCGTemp *t)
 {
     (void)temp_idx(t); /* trigger embedded assert */
-    return (TCGv_i32)((void *)t - (void *)tcg_ctx);
+    return (TCGv_i32)((void *)t - (void *)tcg_ctx->temps);
 }
 
 static inline TCGv_i64 temp_tcgv_i64(TCGTemp *t)
-- 
2.17.1
Re: [PATCH] tcg: Fix the overflow in indexing tcg_ctx->temps
Posted by Richard Henderson 1 week, 6 days ago
On 4/18/24 03:27, Zhiwei Jiang wrote:
> Sometimes, when the address of the passed TCGTemp *ts variable is the same as tcg_ctx,

Pardon?  When would TCGTemp *ts == TCGContext *tcg_ctx?


> the index calculated in the temp_idx function, i.e., ts - tcg_ctx->temps,
> can result in a particularly large value, causing overflow in the subsequent array access.

Or, assert:

size_t temp_idx(TCGTemp *ts)
{
     ptrdiff_t n = ts - tcg_ctx->temps;
     assert(n >= 0 && n < tcg_ctx->nb_temps);
     return n;
}

>   static inline TCGTemp *tcgv_i32_temp(TCGv_i32 v)
>   {
> -    return (void *)tcg_ctx + (uintptr_t)v;
> +    return (void *)tcg_ctx->temps + (uintptr_t)v;
>   }

This will generate 0 for the first temp, which will test as NULL.



r~
回复:[PATCH] tcg: Fix the overflow in indexing tcg_ctx->temps
Posted by 姜智伟 1 week, 5 days ago
> On 4/18/24 03:27, Zhiwei Jiang wrote:
> > Sometimes, when the address of the passed TCGTemp *ts variable is the same as tcg_ctx,
> 
> Pardon?  When would TCGTemp *ts == TCGContext *tcg_ctx?
> 
> 
> > the index calculated in the temp_idx function, i.e., ts - tcg_ctx->temps,
> > can result in a particularly large value, causing overflow in the subsequent array access.
> 
> Or, assert:
> 
> size_t temp_idx(TCGTemp *ts)
> {
>      ptrdiff_t n = ts - tcg_ctx->temps;
>      assert(n >= 0 && n < tcg_ctx->nb_temps);
>      return n;
> }
> 
> >   static inline TCGTemp *tcgv_i32_temp(TCGv_i32 v)
> >   {
> > -    return (void *)tcg_ctx + (uintptr_t)v;
> > +    return (void *)tcg_ctx->temps + (uintptr_t)v;
> >   }
> 
> This will generate 0 for the first temp, which will test as NULL.

Hi Richard:
You can reproduce this issue on the latest upstream QEMU version. Using the RISC-V QEMU version, 
if we compile a test program with the first instruction being '.insn r 0xf, 2, 0, x0, x0, x0',that is a RISC-V CBO instruction, 
qemu will crash with a segmentation fault upon execution.

When the first instruction in the program is a CBO instruction,  temp_idx in init_ts_info func returns a very large value, 
causing the subsequent test_bit function to access out-of-bounds memory.

static void init_ts_info(OptContext *ctx, TCGTemp *ts)
{
    size_t idx = temp_idx(ts);
    TempOptInfo *ti;

    if (test_bit(idx, ctx->temps_used.l)) {
        return;
    }
...
I can fix this segmentation fault by applying the modification above, 
and it seems more logical in terms of code logic to match the allocation and indexing of TCGTemp.

Ths
Re: [PATCH] tcg: Fix the overflow in indexing tcg_ctx->temps
Posted by Peter Maydell 1 week, 5 days ago
On Fri, 19 Apr 2024 at 04:49, 姜智伟 <jiangzw@tecorigin.com> wrote:
>
> > On 4/18/24 03:27, Zhiwei Jiang wrote:
> > > Sometimes, when the address of the passed TCGTemp *ts variable is the same as tcg_ctx,
> >
> > Pardon?  When would TCGTemp *ts == TCGContext *tcg_ctx?
> >
> >
> > > the index calculated in the temp_idx function, i.e., ts - tcg_ctx->temps,
> > > can result in a particularly large value, causing overflow in the subsequent array access.
> >
> > Or, assert:
> >
> > size_t temp_idx(TCGTemp *ts)
> > {
> >      ptrdiff_t n = ts - tcg_ctx->temps;
> >      assert(n >= 0 && n < tcg_ctx->nb_temps);
> >      return n;
> > }
> >
> > >   static inline TCGTemp *tcgv_i32_temp(TCGv_i32 v)
> > >   {
> > > -    return (void *)tcg_ctx + (uintptr_t)v;
> > > +    return (void *)tcg_ctx->temps + (uintptr_t)v;
> > >   }
> >
> > This will generate 0 for the first temp, which will test as NULL.
>
> Hi Richard:
> You can reproduce this issue on the latest upstream QEMU version. Using the RISC-V QEMU version,
> if we compile a test program with the first instruction being '.insn r 0xf, 2, 0, x0, x0, x0',that is a RISC-V CBO instruction,
> qemu will crash with a segmentation fault upon execution.
>
> When the first instruction in the program is a CBO instruction,  temp_idx in init_ts_info func returns a very large value,
> causing the subsequent test_bit function to access out-of-bounds memory.

I feel like this might be a bug elsewhere. Can you provide
a repro binary and command line?

thanks
-- PMM
回复:[PATCH] tcg: Fix the overflow in indexing tcg_ctx->temps
Posted by 姜智伟 1 week, 5 days ago
> > > On 4/18/24 03:27, Zhiwei Jiang wrote:
> > > > Sometimes, when the address of the passed TCGTemp *ts variable is the same as tcg_ctx,
> > >
> > > Pardon?  When would TCGTemp *ts == TCGContext *tcg_ctx?
> > >
> > >
> > > > the index calculated in the temp_idx function, i.e., ts - tcg_ctx->temps,
> > > > can result in a particularly large value, causing overflow in the subsequent array access.
> > >
> > > Or, assert:
> > >
> > > size_t temp_idx(TCGTemp *ts)
> > > {
> > >      ptrdiff_t n = ts - tcg_ctx->temps;
> > >      assert(n >= 0 && n < tcg_ctx->nb_temps);
> > >      return n;
> > > }
> > >
> > > >   static inline TCGTemp *tcgv_i32_temp(TCGv_i32 v)
> > > >   {
> > > > -    return (void *)tcg_ctx + (uintptr_t)v;
> > > > +    return (void *)tcg_ctx->temps + (uintptr_t)v;
> > > >   }
> > >
> > > This will generate 0 for the first temp, which will test as NULL.
> >
> > Hi Richard:
> > You can reproduce this issue on the latest upstream QEMU version. Using the RISC-V QEMU version,
> > if we compile a test program with the first instruction being '.insn r 0xf, 2, 0, x0, x0, x0',that is a RISC-V CBO instruction,
> > qemu will crash with a segmentation fault upon execution.
> >
> > When the first instruction in the program is a CBO instruction,  temp_idx in init_ts_info func returns a very large value,
> > causing the subsequent test_bit function to access out-of-bounds memory.
> 
> I feel like this might be a bug elsewhere. Can you provide
> a repro binary and command line?

The test file has been attached with RISCV CBO instruction as the first instruction to execute, with command-line arguments as 
./build/qemu-system-riscv64 -M virt -smp 1 -nographic -bios crash_test.bin ���������	�	
�
��
�
��s4s 4s4s%@���U����s�R0s#P0c�b�"����CC�#���B��b�7%s 0sP01��poPAsP�" 4c�s@4oUq��	#4��#0��#<��#8���#�#0�᫃G�����c�V�7����'������Gc��Z�����'�'���պ��C��'���Ժ����G#�����G#���7��#0��7��7�c|��7��7����#���7��#0��7��7�c|��7��7�����#���G������˃7���#8��c��7���#8��C#0���G������ýG��G#.�����'����'�'7��W�@�'��#.���7��#0��7��7�cr��'����Gc���'����������	��'�������w���7�}�6��6�#��'���7#.���'���'���#������G������˃7���#8��c��7���#8��C#8���7�c��7���@#8���7��#0��7��7�c|��7��7�����#���G#4���7�#0��1��7���#4��7��G�G�#0���7���7���'�7�'#.����'���7����7�c��7��G�g����&���7����6����w�#��7��G�G�#8���'���7#.���'���'����7��7���#0��#���
��7���#8��c#8��-��7��#0��7��7�c~��7��7����7�G#���7��#8���7�����#���ɬ�7��#0��7��7�cs��7���#8��C�7��7������#��#���A��7���#8��#'4���7��S�ӗ碅χ7��ӗ�"'4���7��#0��7��7�c|��7��7�����#���7��ӗ'�#0��#4�#8�#,�#.�-�7��G�g����'����#.��w����#���7��G�G�#0���7��B���'���'��'���#.�����#���=��7��#0��7��7�cu��'���7#.���7��7����'��A"�G��#���'���'�O���7��ӗ'���'�7��Sw�
�'��g��#�w�ӗ'�#8���7��ǃ7��#0��7��7�c|��7��7�����#��#8�#<�# �#&�-�7��G�g����'����#&��w����#���7��G�G�#8���7��B��)��'���#&�����#����'����G����=��7��#0��7��7�cu��'���7#&���7��7����'��A"�G�#���'���'�O��#������7���>��Pc��G�����7��#0��7��7�cp��7��7����7��G#����7��#<��7�����7��7�cz�7��7���#�!��7�˃7��7����#��7��'>�.dia��uq�����}sA"�#<�|�����#8#<�#0����v�|"���w����|"�c��#��~�w�����~�w���}w�~A"���}�@:���?���#.���w���~���#4��1��7�7��G#���7���#4���7�������'��>��`dIa��uq�����}sA"�#<�|�����#8#<���#0����v�|"���w����|"�c��#��~�w�����~�w���}w�~A"���}�@:������#.���w���~���#4�����7��Gv�C��7'u�>��7���7��G#���7��Gs�C>�����c���7���q#��7���#4���7�������'��>��`dIa��A�"�%^���7�e��UU��`dA��A�"�\����7�e��UU��`dA��q����*�#0��#<��6���>�†F��#&����#$����#*����#(����#&����#$���7��#<���7�#0���'����Gc��7�#<���7��#0��P��@�]�T�ُ'��'ُ'���'ُ'��'ُX�'ُ\�'ُ'D�G'ُ'��7']��'��ُ#4��H�L�ُPW�@'ُ#8���7���7��ُ#<���7��d�]�<@��w�G���ُ#0���7���B��7��B��7��C��7�C���b<@���'��#4�)���#4���7����>�ft�{	a��Yq�����*�#8��#4��6���>�†F��#.����#,����#"����# ����#.����#,��`�dُ#<��`�H���G���]��'���]��'��]��'���]��'D�����G���]��'���ُ#0���7����7�ُ#4���7����'���ُ#8���7���B��7��B��7��C��7�C���bH�'��#4�)���#4���7����>�&t�{ea��Yq�����#8��#4����:�#<��†F���#.����#,����#"����# ����#*��@���'D��]�D�ُH�'ُL�'ُ'��7']��'��ُ#<���'D���'��ُ@W�@'ُ#0���7���7��ُ#4���7���7���]�P��w�G���ُ#8���7���B��7��B��7��C��7�C���bP���'��#4�)���#4���7����>�&t�{ea��9q"��#<����6�#*����#(����#&���'���'��'D�#&��#&���#$�%��'��7������>���c��W���'���'#$���'��>��'��'�'�F���'��>��'����'>��7����#<���'���'#&���'D�>��'���G���'���'�����G>�bt!a��9q"��#<��#8����#&��#&�
��'���7�����C�'���7����C6�c��W��'���'#&���'��>��'��'�'�A���G>�bt!a��9q"��#<��#8����#&��#&����'���7������'���7������w�ӧ� S�B�����#ӗ碙��W��'���'#&���'��>��'��'�'�D���G>�bt!a��"���.�#&����#$���'��'����0#&��bda��"���.�#&����#$���'��'����2#&��bda��"���.�#&����#$���'��'����4#&��bda��A�"���E�����`dA��A�"���E�����`dA���"���#&���'����E����`Bda��9q"�^��#8��#<��#4���7�#0���7��#4���7��B��7���B��7����� bt�{!a��9q"�^��#8��#<��#4���7�#0���7��#4���7��B��7���B��7����� bt�{!a��9q"�^��#8��#<��#4���7�#0���7��#4���7��B��7���B��7����� bt�{!a��"�#4�����'7����bda��A"����g�c�W�A����3��g���>�������}����������G��c�'>�"dA��A"��7�����c�c7����@���'>�"dA���"�&���������g@������������'�7�����'���'>��`Bd�da��yq�"�&�J��7������c��7����c��7��G�G�c��7���cg���<����O#���<����O#�#.�%��7���c�'�����#��7��'�c�'�����#��'���'#.����_�>��'���'�������������'����쪇����'��@�'>��G��������7��������骇�g@'J�c�6���ݔb��g@�'���E�����?窇����'��@�'>��G��������7�������_䪇�g@'J�c�6���ؔb��g@�'���E����pt�dBiEa��]q����#4��#0����#.���7����#��7��g�#�#&���_ઇ#"��#$�բ# �#.�#,��'���7�����c>��02��# ���'���'�����#*���'D��'�˗7��gϜC'����'1��7��'ΜC7��Ã'D��'�Ã'���c��7��g˘C�'���'cQ��'D��'��'����W#&���'D��'��7��gȜC��G7��Ã'���7����c>��0*��#.���'���7�����c>���(��#,���'����c��'��>��'����'>��c��'���c�
�'��>��'��'�'c���'���'�'��g�''������7��G��Ã'��>��'����'>��c���'���c
��'��>��'����'����'��'��7ǸÃ'��>��'��'�'c���W��G#&��!���'���'#$���'��>��'D�'�'c\��7��'��C�'���'�N�ޗ7��粘C�'���'cD��G��W#(���'�>��`daa��]q����#4��#0����#.��������7��7��ǭ�×7��g�#�#&���_���#"���'D��7#$��բ# �#.�#,��'���7����c>���
��#.���'���'�����#*���'D��'�˗7����C'�����'1��7��ǥ�C7'�Ã'D��'�Ã'����c��7����C�'���'cQ��'D��'��'����W#&���'D��'��7����C��G7'�Ã'���7�����c>��~��# ���'���7����c>��`|��#,���'���c��'��>��'����'>��c��'����c�
�'�>��'��'�'c���'����g�''����'�7��7��甘Ã'��>��'����'>��c���'����c
��'��>��'����'����'��'�7g�Ã'�>��'��'�'c���W��G#&��!���'���7#$���'���'c��7��G��C�'���'�B���7����C�'���'cD��G��W#(���'�>��`daa��"���#&���7��Dž�c�'����g@�'����c�'������'>��W�3���7��炐c�'����g@�'���U���bda��"���.�#&����#$���'����c�'�����'�����'�7�'��g@�'����c�'��>��'�����'�7�'����'>��W�3���'��G{�c�'�����'�����'�7�'��g@�'���U���bda��9q�"����#&���'����g@�'#4���'�����#0���'��'u�c�7������c�7��'>��W��������'���r�c�7�����u���7���'��gq�c�7������c=��'��p�c�7������c�7��'�7�'���W�������#<��5����N��#*���'D����c���'��'k�c�7������c�'D�>��W��������'���h�c�7�����u��㭨�7���#4���'���f�c�7������c>��G��#*���'D�������'���c�c�7������c�'D�>��W��������'��Ga�c�7�����u����pBt!a��yq�"�#<���7��������#<���7������7������ÅG��G���'#&���'���Z�c�'���Z�c�&��6���:���_���#$���'����Wc��'��Y�C>���_З'��X�C'����>����ԗ'���V�C��g�'>����H�c����G>��ptEa��yq�"�#<���7��������#<���7������7������ÅG��G���'#&���'���N�c�'��gN�c�&��6���:���_���#$���'����Wc��'���L�C�'���7�'��@��'��K�×'��gJ�C>�����'��gI�C'����>���?Ɨ'��H�C��g�'>����g9�c����G>��ptEa���"�#4����#"���7��������#4���'D��'��5����?⪇1�5��������>��`Bda���"�#4��7������2�c������'���>�×'���=�C>���āG>��`Bda��A"�sP"dA��A"��cf��cfsP"dA��A"��SU��SUsP"dA���"���O����'>��������W�#&���'��>�����'����'�'�7�'>��`Bda��yq�"�E!��?�#&�#$�%���������&��F.�'������Ã'���'#$���'�����G������5�c#8��#"�# ���'��7����&��F)'�
6�C�Ã'D��'#"���'��'# ���'����@��#.�5��'���7����C'G$�'������C6�c��'���'#&���'���'#.���'�����M���'���'�����������������G>��ptEa���W�������3W�w�u��3U��������;�@��������@}��W�������3W�w�u�3U��*�E�=�����շp�������>�������>���>���>���>���>�������>���>���>�������>���>������>���>���>���>��� ���PASS
FAIL
spm test
��.A�h㈵��>�`yX`yp`y`y�������GCC: (gbb25a476796) 12.0.1 20220505 (prerelease)�F�q`y
Re: [PATCH] tcg: Fix the overflow in indexing tcg_ctx->temps
Posted by Peter Maydell 1 week, 5 days ago
On Fri, 19 Apr 2024 at 10:37, 姜智伟 <jiangzw@tecorigin.com> wrote:
> Peter Maydell wrote:
> > I feel like this might be a bug elsewhere. Can you provide
> > a repro binary and command line?
>
> The test file has been attached with RISCV CBO instruction as the first instruction to execute, with command-line arguments as
> ./build/qemu-system-riscv64 -M virt -smp 1 -nographic -bios crash_test.bin

It looks like you're building without --enable-debug. If you do
that then you'll find that we hit an assert in the debug version
of the function, which your patch doesn't touch:

#6  0x00007ffff4b90e96 in __GI___assert_fail
    (assertion=0x55555639a508 "o < sizeof(TCGTemp) *
tcg_ctx->nb_temps", file=0x5555563995d5 "../../tcg/tcg.c", line=1940,
function=0x55555639c000 <__PRETTY_FUNCTION__.60> "tcgv_i32_temp") at
./assert/assert.c:101
#7  0x000055555613104c in tcgv_i32_temp (v=0x0) at ../../tcg/tcg.c:1940
#8  0x0000555555d0882b in tcgv_i64_temp (v=0x0) at
/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/include/tcg/tcg.h:638
#9  0x0000555555d0c17b in gen_helper_cbo_inval (arg1=0x2a8, arg2=0x0)
at ../../target/riscv/helper.h:121
#10 0x0000555555d7be65 in trans_cbo_inval (ctx=0x7fffef1c8e50,
a=0x7fffef1c8cf0) at
../../target/riscv/insn_trans/trans_rvzicbo.c.inc:48
#11 0x0000555555d41f4f in decode_insn32 (ctx=0x7fffef1c8e50,
insn=8207) at libqemu-riscv64-softmmu.fa.p/decode-insn32.c.inc:2332
#12 0x0000555555d925f1 in decode_opc (env=0x555556d53e30,
ctx=0x7fffef1c8e50, opcode=8207) at
../../target/riscv/translate.c:1165
#13 0x0000555555d92ab4 in riscv_tr_translate_insn
(dcbase=0x7fffef1c8e50, cpu=0x555556d51670) at
../../target/riscv/translate.c:1236

This happens because we've been passed in 0 as our TCGv,
which isn't valid. That in turn is because trans_cbo_inval()
does:
           gen_helper_cbo_inval(tcg_env, cpu_gpr[a->rs1]);
but a->rs1 is 0.

The comment in riscv_translate_init() says:
    /*
     * cpu_gpr[0] is a placeholder for the zero register. Do not use it.
     * Use the gen_set_gpr and get_gpr helper functions when accessing regs,
     * unless you specifically block reads/writes to reg 0.
     */

trans_cbo_inval() doesn't do either of those things, so that is
where your bug is.

thanks
-- PMM
Re: [PATCH] tcg: Fix the overflow in indexing tcg_ctx->temps
Posted by Philippe Mathieu-Daudé 1 week, 5 days ago
On 19/4/24 12:21, Peter Maydell wrote:
> On Fri, 19 Apr 2024 at 10:37, 姜智伟 <jiangzw@tecorigin.com> wrote:
>> Peter Maydell wrote:
>>> I feel like this might be a bug elsewhere. Can you provide
>>> a repro binary and command line?
>>
>> The test file has been attached with RISCV CBO instruction as the first instruction to execute, with command-line arguments as
>> ./build/qemu-system-riscv64 -M virt -smp 1 -nographic -bios crash_test.bin
> 
> It looks like you're building without --enable-debug. If you do
> that then you'll find that we hit an assert in the debug version
> of the function, which your patch doesn't touch:
> 
> #6  0x00007ffff4b90e96 in __GI___assert_fail
>      (assertion=0x55555639a508 "o < sizeof(TCGTemp) *
> tcg_ctx->nb_temps", file=0x5555563995d5 "../../tcg/tcg.c", line=1940,
> function=0x55555639c000 <__PRETTY_FUNCTION__.60> "tcgv_i32_temp") at
> ./assert/assert.c:101
> #7  0x000055555613104c in tcgv_i32_temp (v=0x0) at ../../tcg/tcg.c:1940
> #8  0x0000555555d0882b in tcgv_i64_temp (v=0x0) at
> /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/include/tcg/tcg.h:638
> #9  0x0000555555d0c17b in gen_helper_cbo_inval (arg1=0x2a8, arg2=0x0)
> at ../../target/riscv/helper.h:121
> #10 0x0000555555d7be65 in trans_cbo_inval (ctx=0x7fffef1c8e50,
> a=0x7fffef1c8cf0) at
> ../../target/riscv/insn_trans/trans_rvzicbo.c.inc:48
> #11 0x0000555555d41f4f in decode_insn32 (ctx=0x7fffef1c8e50,
> insn=8207) at libqemu-riscv64-softmmu.fa.p/decode-insn32.c.inc:2332
> #12 0x0000555555d925f1 in decode_opc (env=0x555556d53e30,
> ctx=0x7fffef1c8e50, opcode=8207) at
> ../../target/riscv/translate.c:1165
> #13 0x0000555555d92ab4 in riscv_tr_translate_insn
> (dcbase=0x7fffef1c8e50, cpu=0x555556d51670) at
> ../../target/riscv/translate.c:1236
> 
> This happens because we've been passed in 0 as our TCGv,
> which isn't valid. That in turn is because trans_cbo_inval()
> does:
>             gen_helper_cbo_inval(tcg_env, cpu_gpr[a->rs1]);
> but a->rs1 is 0.
> 
> The comment in riscv_translate_init() says:
>      /*
>       * cpu_gpr[0] is a placeholder for the zero register. Do not use it.
>       * Use the gen_set_gpr and get_gpr helper functions when accessing regs,
>       * unless you specifically block reads/writes to reg 0.
>       */
> 
> trans_cbo_inval() doesn't do either of those things, so that is
> where your bug is.

Our minds crossed =)

We need to use get_address() to get an address from cpu_gpr[],
since $zero is "special" (NULL).

I'm about to post this fix:

-- >8 --
diff --git a/target/riscv/insn_trans/trans_rvzicbo.c.inc 
b/target/riscv/insn_trans/trans_rvzicbo.c.inc
index d5d7095903..6f6b29598d 100644
--- a/target/riscv/insn_trans/trans_rvzicbo.c.inc
+++ b/target/riscv/insn_trans/trans_rvzicbo.c.inc
@@ -31,27 +31,27 @@
  static bool trans_cbo_clean(DisasContext *ctx, arg_cbo_clean *a)
  {
      REQUIRE_ZICBOM(ctx);
-    gen_helper_cbo_clean_flush(tcg_env, cpu_gpr[a->rs1]);
+    gen_helper_cbo_clean_flush(tcg_env, get_address(ctx, a->rs1, 0));
      return true;
  }

  static bool trans_cbo_flush(DisasContext *ctx, arg_cbo_flush *a)
  {
      REQUIRE_ZICBOM(ctx);
-    gen_helper_cbo_clean_flush(tcg_env, cpu_gpr[a->rs1]);
+    gen_helper_cbo_clean_flush(tcg_env, get_address(ctx, a->rs1, 0));
      return true;
  }

  static bool trans_cbo_inval(DisasContext *ctx, arg_cbo_inval *a)
  {
      REQUIRE_ZICBOM(ctx);
-    gen_helper_cbo_inval(tcg_env, cpu_gpr[a->rs1]);
+    gen_helper_cbo_inval(tcg_env, get_address(ctx, a->rs1, 0));
      return true;
  }

  static bool trans_cbo_zero(DisasContext *ctx, arg_cbo_zero *a)
  {
      REQUIRE_ZICBOZ(ctx);
-    gen_helper_cbo_zero(tcg_env, cpu_gpr[a->rs1]);
+    gen_helper_cbo_zero(tcg_env, get_address(ctx, a->rs1, 0));
      return true;
  }
---