aboutsummaryrefslogtreecommitdiff
path: root/accel
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2018-06-15 14:57:14 +0100
committerPeter Maydell <peter.maydell@linaro.org>2018-06-15 15:23:34 +0100
commit2d54f19401bc54b3b56d1cc44c96e4087b604b97 (patch)
treed284c1967616f8f77fc36226f64459c2bb362bba /accel
parentace4109011b4912b24e76f152e2cf010e78819c5 (diff)
downloadqemu-2d54f19401bc54b3b56d1cc44c96e4087b604b97.zip
qemu-2d54f19401bc54b3b56d1cc44c96e4087b604b97.tar.gz
qemu-2d54f19401bc54b3b56d1cc44c96e4087b604b97.tar.bz2
cputlb: Pass cpu_transaction_failed() the correct physaddr
The API for cpu_transaction_failed() says that it takes the physical address for the failed transaction. However we were actually passing it the offset within the target MemoryRegion. We don't currently have any target CPU implementations of this hook that require the physical address; fix this bug so we don't get confused if we ever do add one. Suggested-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20180611125633.32755-3-peter.maydell@linaro.org
Diffstat (limited to 'accel')
-rw-r--r--accel/tcg/cputlb.c44
1 files changed, 31 insertions, 13 deletions
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index 31f7695..1768fcd 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -777,13 +777,16 @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
target_ulong addr, uintptr_t retaddr, int size)
{
CPUState *cpu = ENV_GET_CPU(env);
- hwaddr physaddr = iotlbentry->addr;
- MemoryRegion *mr = iotlb_to_region(cpu, physaddr, iotlbentry->attrs);
+ hwaddr mr_offset;
+ MemoryRegionSection *section;
+ MemoryRegion *mr;
uint64_t val;
bool locked = false;
MemTxResult r;
- physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
+ section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
+ mr = section->mr;
+ mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
cpu->mem_io_pc = retaddr;
if (mr != &io_mem_rom && mr != &io_mem_notdirty && !cpu->can_do_io) {
cpu_io_recompile(cpu, retaddr);
@@ -795,9 +798,13 @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
qemu_mutex_lock_iothread();
locked = true;
}
- r = memory_region_dispatch_read(mr, physaddr,
+ r = memory_region_dispatch_read(mr, mr_offset,
&val, size, iotlbentry->attrs);
if (r != MEMTX_OK) {
+ hwaddr physaddr = mr_offset +
+ section->offset_within_address_space -
+ section->offset_within_region;
+
cpu_transaction_failed(cpu, physaddr, addr, size, MMU_DATA_LOAD,
mmu_idx, iotlbentry->attrs, r, retaddr);
}
@@ -814,12 +821,15 @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
uintptr_t retaddr, int size)
{
CPUState *cpu = ENV_GET_CPU(env);
- hwaddr physaddr = iotlbentry->addr;
- MemoryRegion *mr = iotlb_to_region(cpu, physaddr, iotlbentry->attrs);
+ hwaddr mr_offset;
+ MemoryRegionSection *section;
+ MemoryRegion *mr;
bool locked = false;
MemTxResult r;
- physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
+ section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
+ mr = section->mr;
+ mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
if (mr != &io_mem_rom && mr != &io_mem_notdirty && !cpu->can_do_io) {
cpu_io_recompile(cpu, retaddr);
}
@@ -830,9 +840,13 @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
qemu_mutex_lock_iothread();
locked = true;
}
- r = memory_region_dispatch_write(mr, physaddr,
+ r = memory_region_dispatch_write(mr, mr_offset,
val, size, iotlbentry->attrs);
if (r != MEMTX_OK) {
+ hwaddr physaddr = mr_offset +
+ section->offset_within_address_space -
+ section->offset_within_region;
+
cpu_transaction_failed(cpu, physaddr, addr, size, MMU_DATA_STORE,
mmu_idx, iotlbentry->attrs, r, retaddr);
}
@@ -880,12 +894,13 @@ static bool victim_tlb_hit(CPUArchState *env, size_t mmu_idx, size_t index,
*/
tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr)
{
- int mmu_idx, index, pd;
+ int mmu_idx, index;
void *p;
MemoryRegion *mr;
+ MemoryRegionSection *section;
CPUState *cpu = ENV_GET_CPU(env);
CPUIOTLBEntry *iotlbentry;
- hwaddr physaddr;
+ hwaddr physaddr, mr_offset;
index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
mmu_idx = cpu_mmu_index(env, true);
@@ -896,8 +911,8 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr)
}
}
iotlbentry = &env->iotlb[mmu_idx][index];
- pd = iotlbentry->addr & ~TARGET_PAGE_MASK;
- mr = iotlb_to_region(cpu, pd, iotlbentry->attrs);
+ section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
+ mr = section->mr;
if (memory_region_is_unassigned(mr)) {
qemu_mutex_lock_iothread();
if (memory_region_request_mmio_ptr(mr, addr)) {
@@ -918,7 +933,10 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr)
* and use the MemTXResult it produced). However it is the
* simplest place we have currently available for the check.
*/
- physaddr = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
+ mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
+ physaddr = mr_offset +
+ section->offset_within_address_space -
+ section->offset_within_region;
cpu_transaction_failed(cpu, physaddr, addr, 0, MMU_INST_FETCH, mmu_idx,
iotlbentry->attrs, MEMTX_DECODE_ERROR, 0);