From: Alistair Francis <alistair.fran...@wdc.com> When performing atomic operations TCG will do a read operation then a write operation. This results in a MMU_DATA_LOAD fault if the address is invalid.
For some platforms (such as RISC-V) we should produce a store fault if an atomic operation fails. This patch adds a new MemOp (MO_WRITE_FAULT) that allows us to indicate that the operation should produce a MMU_DATA_STORE access type if the operation faults. Signed-off-by: Alistair Francis <alistair.fran...@wdc.com> --- include/exec/memop.h | 2 ++ accel/tcg/cputlb.c | 11 +++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/include/exec/memop.h b/include/exec/memop.h index 2a885f3917..93ae1b6a2e 100644 --- a/include/exec/memop.h +++ b/include/exec/memop.h @@ -81,6 +81,8 @@ typedef enum MemOp { MO_ALIGN_32 = 5 << MO_ASHIFT, MO_ALIGN_64 = 6 << MO_ASHIFT, + MO_WRITE_FAULT = 0x100, + /* Combinations of the above, for ease of use. */ MO_UB = MO_8, MO_UW = MO_16, diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c index 5e0d0eebc3..320555d5e9 100644 --- a/accel/tcg/cputlb.c +++ b/accel/tcg/cputlb.c @@ -1362,8 +1362,15 @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry, section->offset_within_address_space - section->offset_within_region; - cpu_transaction_failed(cpu, physaddr, addr, memop_size(op), access_type, - mmu_idx, iotlbentry->attrs, r, retaddr); + if (op & MO_WRITE_FAULT) { + cpu_transaction_failed(cpu, physaddr, addr, memop_size(op), + MMU_DATA_STORE, mmu_idx, iotlbentry->attrs, + r, retaddr); + } else { + cpu_transaction_failed(cpu, physaddr, addr, memop_size(op), + access_type, mmu_idx, iotlbentry->attrs, + r, retaddr); + } } if (locked) { qemu_mutex_unlock_iothread(); -- 2.31.1