qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

hw/ppc: Take QEMU lock when calling ppc_dcr_read/write()

The ppc_dcr_read() and ppc_dcr_write() functions call into callbacks
in device code, so we need to hold the QEMU iothread lock while
calling them. This is the case already for the callsites in
kvmppc_handle_dcr_read/write(), but we must also take the lock when
calling the helpers from TCG.

This fixes a bug where attempting to initialise the PPC405EP
SDRAM will cause an assertion when sdram_map_bcr() attempts
to remap memory regions.

Reported-by: Amit Lazar <abasarlaz@hotmail.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-Id: <20200322192258.14039-1-peter.maydell@linaro.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>

authored by

Peter Maydell and committed by
David Gibson
235352ee ce05fa0f

+26 -14
+26 -14
target/ppc/timebase_helper.c
··· 21 21 #include "exec/helper-proto.h" 22 22 #include "exec/exec-all.h" 23 23 #include "qemu/log.h" 24 + #include "qemu/main-loop.h" 24 25 25 26 /*****************************************************************************/ 26 27 /* SPR accesses */ ··· 167 168 raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, 168 169 POWERPC_EXCP_INVAL | 169 170 POWERPC_EXCP_INVAL_INVAL, GETPC()); 170 - } else if (unlikely(ppc_dcr_read(env->dcr_env, 171 - (uint32_t)dcrn, &val) != 0)) { 172 - qemu_log_mask(LOG_GUEST_ERROR, "DCR read error %d %03x\n", 173 - (uint32_t)dcrn, (uint32_t)dcrn); 174 - raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, 175 - POWERPC_EXCP_INVAL | 176 - POWERPC_EXCP_PRIV_REG, GETPC()); 171 + } else { 172 + int ret; 173 + 174 + qemu_mutex_lock_iothread(); 175 + ret = ppc_dcr_read(env->dcr_env, (uint32_t)dcrn, &val); 176 + qemu_mutex_unlock_iothread(); 177 + if (unlikely(ret != 0)) { 178 + qemu_log_mask(LOG_GUEST_ERROR, "DCR read error %d %03x\n", 179 + (uint32_t)dcrn, (uint32_t)dcrn); 180 + raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, 181 + POWERPC_EXCP_INVAL | 182 + POWERPC_EXCP_PRIV_REG, GETPC()); 183 + } 177 184 } 178 185 return val; 179 186 } ··· 185 192 raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, 186 193 POWERPC_EXCP_INVAL | 187 194 POWERPC_EXCP_INVAL_INVAL, GETPC()); 188 - } else if (unlikely(ppc_dcr_write(env->dcr_env, (uint32_t)dcrn, 189 - (uint32_t)val) != 0)) { 190 - qemu_log_mask(LOG_GUEST_ERROR, "DCR write error %d %03x\n", 191 - (uint32_t)dcrn, (uint32_t)dcrn); 192 - raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, 193 - POWERPC_EXCP_INVAL | 194 - POWERPC_EXCP_PRIV_REG, GETPC()); 195 + } else { 196 + int ret; 197 + qemu_mutex_lock_iothread(); 198 + ret = ppc_dcr_write(env->dcr_env, (uint32_t)dcrn, (uint32_t)val); 199 + qemu_mutex_unlock_iothread(); 200 + if (unlikely(ret != 0)) { 201 + qemu_log_mask(LOG_GUEST_ERROR, "DCR write error %d %03x\n", 202 + (uint32_t)dcrn, (uint32_t)dcrn); 203 + raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, 204 + POWERPC_EXCP_INVAL | 205 + POWERPC_EXCP_PRIV_REG, GETPC()); 206 + } 195 207 } 196 208 }