static u32
 cs_etm_decoder__mem_access(const void *context,
                           const ocsd_vaddr_t address,
-                          const ocsd_mem_space_acc_t mem_space __maybe_unused,
+                          const ocsd_mem_space_acc_t mem_space,
                           const u8 trace_chan_id,
                           const u32 req_size,
                           u8 *buffer)
 {
        struct cs_etm_decoder *decoder = (struct cs_etm_decoder *) context;
 
-       return decoder->mem_access(decoder->data, trace_chan_id,
-                                  address, req_size, buffer);
+       return decoder->mem_access(decoder->data, trace_chan_id, address,
+                                  req_size, buffer, mem_space);
 }
 
 int cs_etm_decoder__add_mem_access_cb(struct cs_etm_decoder *decoder,
 
 }
 
 static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u8 trace_chan_id,
-                             u64 address, size_t size, u8 *buffer)
+                             u64 address, size_t size, u8 *buffer,
+                             const ocsd_mem_space_acc_t mem_space)
 {
        u8  cpumode;
        u64 offset;
        if (!tidq)
                goto out;
 
+       /*
+        * We've already tracked EL along side the PID in cs_etm__set_thread()
+        * so double check that it matches what OpenCSD thinks as well. It
+        * doesn't distinguish between EL0 and EL1 for this mem access callback
+        * so we had to do the extra tracking. Skip validation if it's any of
+        * the 'any' values.
+        */
+       if (!(mem_space == OCSD_MEM_SPACE_ANY ||
+             mem_space == OCSD_MEM_SPACE_N || mem_space == OCSD_MEM_SPACE_S)) {
+               if (mem_space & OCSD_MEM_SPACE_EL1N) {
+                       /* Includes both non secure EL1 and EL0 */
+                       assert(tidq->el == ocsd_EL1 || tidq->el == ocsd_EL0);
+               } else if (mem_space & OCSD_MEM_SPACE_EL2)
+                       assert(tidq->el == ocsd_EL2);
+               else if (mem_space & OCSD_MEM_SPACE_EL3)
+                       assert(tidq->el == ocsd_EL3);
+       }
+
        cpumode = cs_etm__cpu_mode(etmq, address, tidq->el);
 
        if (!thread__find_map(tidq->thread, cpumode, address, &al))
 {
        u8 instrBytes[2];
 
-       cs_etm__mem_access(etmq, trace_chan_id, addr,
-                          ARRAY_SIZE(instrBytes), instrBytes);
+       cs_etm__mem_access(etmq, trace_chan_id, addr, ARRAY_SIZE(instrBytes),
+                          instrBytes, 0);
        /*
         * T32 instruction size is indicated by bits[15:11] of the first
         * 16-bit word of the instruction: 0b11101, 0b11110 and 0b11111
        else
                sample->insn_len = 4;
 
-       cs_etm__mem_access(etmq, trace_chan_id, sample->ip,
-                          sample->insn_len, (void *)sample->insn);
+       cs_etm__mem_access(etmq, trace_chan_id, sample->ip, sample->insn_len,
+                          (void *)sample->insn, 0);
 }
 
 u64 cs_etm__convert_sample_time(struct cs_etm_queue *etmq, u64 cs_timestamp)
                 * so below only read 2 bytes as instruction size for T32.
                 */
                addr = end_addr - 2;
-               cs_etm__mem_access(etmq, trace_chan_id, addr,
-                                  sizeof(instr16), (u8 *)&instr16);
+               cs_etm__mem_access(etmq, trace_chan_id, addr, sizeof(instr16),
+                                  (u8 *)&instr16, 0);
                if ((instr16 & 0xFF00) == 0xDF00)
                        return true;
 
                 * +---------+---------+-------------------------+
                 */
                addr = end_addr - 4;
-               cs_etm__mem_access(etmq, trace_chan_id, addr,
-                                  sizeof(instr32), (u8 *)&instr32);
+               cs_etm__mem_access(etmq, trace_chan_id, addr, sizeof(instr32),
+                                  (u8 *)&instr32, 0);
                if ((instr32 & 0x0F000000) == 0x0F000000 &&
                    (instr32 & 0xF0000000) != 0xF0000000)
                        return true;
                 * +-----------------------+---------+-----------+
                 */
                addr = end_addr - 4;
-               cs_etm__mem_access(etmq, trace_chan_id, addr,
-                                  sizeof(instr32), (u8 *)&instr32);
+               cs_etm__mem_access(etmq, trace_chan_id, addr, sizeof(instr32),
+                                  (u8 *)&instr32, 0);
                if ((instr32 & 0xFFE0001F) == 0xd4000001)
                        return true;