Commit 2671377a10 for qemu.org

commit 2671377a10c4eb730dc789da69639d7d69812001
Author: Brian Cain <brian.cain@oss.qualcomm.com>
Date:   Tue Sep 1 10:33:52 2026 -0700

    target/hexagon: fix iassign{r, w} to cover all threads

    iassignw/iassignr were filtering CPU_FOREACH by MODECTL_E, the
    thread-enabled mask. That mask reflects whether a thread has been
    started, not whether it exists, so IMASK writes/reads never reached
    threads that hadn't been started yet, leaving their IMASK stale or
    unreadable. Drop the MODECTL_E filtering and operate on every thread.

    Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
    Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>

diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index f9e66acf84..2168c6361d 100644
--- a/target/hexagon/op_helper.c
+++ b/target/hexagon/op_helper.c
@@ -1635,61 +1635,39 @@ void HELPER(cswi)(CPUHexagonState *env, uint32_t mask)

 void HELPER(iassignw)(CPUHexagonState *env, uint32_t src)
 {
-    uint32_t modectl;
-    uint32_t thread_enabled_mask;
     CPUState *cpu;
-    HexagonCPU *hex_cpu;

     BQL_LOCK_GUARD();
-    hex_cpu = env_archcpu(env);
-    modectl = hex_cpu->globalregs ?
-        hexagon_globalreg_read(hex_cpu->globalregs, HEX_SREG_MODECTL,
-                               env->threadId) : 0;
-    thread_enabled_mask = GET_FIELD(MODECTL_E, modectl);

     CPU_FOREACH(cpu) {
         CPUHexagonState *thread_env = &(HEXAGON_CPU(cpu)->env);
-        uint32_t thread_id_mask = 0x1 << thread_env->threadId;
-        if (thread_enabled_mask & thread_id_mask) {
-            uint32_t imask = thread_env->t_sreg[HEX_SREG_IMASK];
-            uint32_t intbitpos = (src >> 16) & 0xF;
-            uint32_t val = (src >> thread_env->threadId) & 0x1;
-            imask = deposit32(imask, intbitpos, 1, val);
-            thread_env->t_sreg[HEX_SREG_IMASK] = imask;
-
-            qemu_log_mask(CPU_LOG_INT, "%s: thread " TARGET_FMT_ld
-               ", new imask 0x%" PRIx32 "\n", __func__,
-               thread_env->threadId, imask);
-        }
+        uint32_t imask = thread_env->t_sreg[HEX_SREG_IMASK];
+        uint32_t intbitpos = (src >> 16) & 0xF;
+        uint32_t val = (src >> thread_env->threadId) & 0x1;
+        imask = deposit32(imask, intbitpos, 1, val);
+        thread_env->t_sreg[HEX_SREG_IMASK] = imask;
+
+        qemu_log_mask(CPU_LOG_INT, "%s: thread " TARGET_FMT_ld
+           ", new imask 0x%" PRIx32 "\n", __func__,
+           thread_env->threadId, imask);
     }
     hex_interrupt_update(env);
 }

 uint32_t HELPER(iassignr)(CPUHexagonState *env, uint32_t src)
 {
-    uint32_t modectl;
-    uint32_t thread_enabled_mask;
     uint32_t intbitpos;
     uint32_t dest_reg;
     CPUState *cpu;
-    HexagonCPU *hex_cpu;

     BQL_LOCK_GUARD();
-    hex_cpu = env_archcpu(env);
-    modectl = hex_cpu->globalregs ?
-        hexagon_globalreg_read(hex_cpu->globalregs, HEX_SREG_MODECTL,
-                               env->threadId) : 0;
-    thread_enabled_mask = GET_FIELD(MODECTL_E, modectl);
     /* src fields are in same position as modectl, but mean different things */
     intbitpos = GET_FIELD(MODECTL_W, src);
     dest_reg = 0;
     CPU_FOREACH(cpu) {
         CPUHexagonState *thread_env = &(HEXAGON_CPU(cpu)->env);
-        uint32_t thread_id_mask = 0x1 << thread_env->threadId;
-        if (thread_enabled_mask & thread_id_mask) {
-            uint32_t imask = thread_env->t_sreg[HEX_SREG_IMASK];
-            dest_reg |= ((imask >> intbitpos) & 0x1) << thread_env->threadId;
-        }
+        uint32_t imask = thread_env->t_sreg[HEX_SREG_IMASK];
+        dest_reg |= ((imask >> intbitpos) & 0x1) << thread_env->threadId;
     }

     return dest_reg;