qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] target/riscv: Call probe_write() before atomic operations


From: Richard Henderson
Subject: Re: [PATCH] target/riscv: Call probe_write() before atomic operations
Date: Wed, 9 Feb 2022 18:26:54 +1100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.5.0

On 2/9/22 16:48, Alistair Francis wrote:
Note that this only fixes the fault for memory regions. I/O and
non-existant regions will still trigger a load fault.
...
+void helper_atomic_check(CPURISCVState *env, target_ulong address,
+                         int width, int mmu_idx)
+{
+    probe_write(env, address, width, mmu_idx, GETPC());
+}

Note that you could use probe_access_flags, whose return value is a mask. If it includes TLB_MMIO, you know that the physical address does not contain ram, but you still do not know if it is unmapped or true mmio, since unmapped gets unassigned_io_ops. It's probably not *that* hard to find out one way or another, but it might also be reasonable to set a flag to communicate with your do_transaction_failed hook.


  static bool gen_amo(DisasContext *ctx, arg_atomic *a,
                      void(*func)(TCGv, TCGv, TCGv, TCGArg, MemOp),
-                    MemOp mop)
+                    TCGv_i32 width, MemOp mop)
  {
      TCGv dest = dest_gpr(ctx, a->rd);
      TCGv src1 = get_address(ctx, a->rs1, 0);
      TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);
+    TCGv_i32 mem_idx = tcg_constant_i32(ctx->mem_idx);
+
+    gen_helper_atomic_check(cpu_env, src1, width, mem_idx);
func(dest, src1, src2, ctx->mem_idx, mop); @@ -105,55 +108,64 @@ static bool trans_sc_w(DisasContext *ctx, arg_sc_w *a)
  static bool trans_amoswap_w(DisasContext *ctx, arg_amoswap_w *a)
  {
      REQUIRE_EXT(ctx, RVA);
-    return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, (MO_ALIGN | MO_TESL));
+    return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, tcg_constant_i32(4),
+                   (MO_ALIGN | MO_TESL));

The width is already stored in the MemOp argument that you're passing around.
I think you should do

    TCGv_i32 width = tcg_constant_i32(memop_size(mop));

there in gen_amo, and not change the callers at all.


r~



reply via email to

[Prev in Thread] Current Thread [Next in Thread]