On 9/22/26 10:04, Mikulas Patocka wrote:
I looked at the sh4 translator and it seems that it already tries to make
sure that the full gUSA region is translated into one TB - i.e. there is
"ctx->base.max_insns = max_insns" in sh4_tr_init_disas_context - that will
override the value "1" that is supplied by cpu_exec_step_atomic. The
comments suggest that the author is aware of the fact that the gUSA region
must be completed atomically.

So, the code that single-steps through the gUSA region is not needed.

It seems that the misbehavior is caused by the fact that if we exit from
the gUSA TB early, we execute the rest of the region in non-exclusive
context.

I simplified the patch, so that it adds just one method -
revert_uninterruptible. It tests whether we are in the unfinished gUSA
region, and if we are, it reverts PC and SP back to the beginning.

What good does that do?  You'll only restart the same block as before.

Is this really the case where you're encountering

        if (pc != pc_end + backup || max_insns < 2) {
            /* This is a malformed gUSA region.  Don't do anything special,
               since the interpreter is likely to get confused.  */
            ctx->envflags &= ~TB_FLAG_GUSA_MASK;

If you add an abort here, does it trigger?

+    /*
+     * If we are interrupted in the middle of the gUSA region, we must
+     * roll-back PC to the beginning of the region. Continuing halfway
+     * through the region would break atomicity guarantees.
+     *
+     * If we are interrupted after the final write instruction (i.e.
+     * cpu->env.pc == cpu->env.gregs[0]), we must not roll-back, because
+     * the atomic write is already committed in the memory.
+     */
Just know that you *can't* be interrupted in the middle of a gUSA region. Signals will always be delayed until the end of the TranslationBlock.

So this text is misleading at best.


r~

Reply via email to