Skip to content

Commit 2d54f19

Browse files
committed
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
1 parent ace4109 commit 2d54f19

File tree

3 files changed

+45
-17
lines changed

3 files changed

+45
-17
lines changed

accel/tcg/cputlb.c

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -777,13 +777,16 @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
777777
target_ulong addr, uintptr_t retaddr, int size)
778778
{
779779
CPUState *cpu = ENV_GET_CPU(env);
780-
hwaddr physaddr = iotlbentry->addr;
781-
MemoryRegion *mr = iotlb_to_region(cpu, physaddr, iotlbentry->attrs);
780+
hwaddr mr_offset;
781+
MemoryRegionSection *section;
782+
MemoryRegion *mr;
782783
uint64_t val;
783784
bool locked = false;
784785
MemTxResult r;
785786

786-
physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
787+
section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
788+
mr = section->mr;
789+
mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
787790
cpu->mem_io_pc = retaddr;
788791
if (mr != &io_mem_rom && mr != &io_mem_notdirty && !cpu->can_do_io) {
789792
cpu_io_recompile(cpu, retaddr);
@@ -795,9 +798,13 @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
795798
qemu_mutex_lock_iothread();
796799
locked = true;
797800
}
798-
r = memory_region_dispatch_read(mr, physaddr,
801+
r = memory_region_dispatch_read(mr, mr_offset,
799802
&val, size, iotlbentry->attrs);
800803
if (r != MEMTX_OK) {
804+
hwaddr physaddr = mr_offset +
805+
section->offset_within_address_space -
806+
section->offset_within_region;
807+
801808
cpu_transaction_failed(cpu, physaddr, addr, size, MMU_DATA_LOAD,
802809
mmu_idx, iotlbentry->attrs, r, retaddr);
803810
}
@@ -814,12 +821,15 @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
814821
uintptr_t retaddr, int size)
815822
{
816823
CPUState *cpu = ENV_GET_CPU(env);
817-
hwaddr physaddr = iotlbentry->addr;
818-
MemoryRegion *mr = iotlb_to_region(cpu, physaddr, iotlbentry->attrs);
824+
hwaddr mr_offset;
825+
MemoryRegionSection *section;
826+
MemoryRegion *mr;
819827
bool locked = false;
820828
MemTxResult r;
821829

822-
physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
830+
section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
831+
mr = section->mr;
832+
mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
823833
if (mr != &io_mem_rom && mr != &io_mem_notdirty && !cpu->can_do_io) {
824834
cpu_io_recompile(cpu, retaddr);
825835
}
@@ -830,9 +840,13 @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
830840
qemu_mutex_lock_iothread();
831841
locked = true;
832842
}
833-
r = memory_region_dispatch_write(mr, physaddr,
843+
r = memory_region_dispatch_write(mr, mr_offset,
834844
val, size, iotlbentry->attrs);
835845
if (r != MEMTX_OK) {
846+
hwaddr physaddr = mr_offset +
847+
section->offset_within_address_space -
848+
section->offset_within_region;
849+
836850
cpu_transaction_failed(cpu, physaddr, addr, size, MMU_DATA_STORE,
837851
mmu_idx, iotlbentry->attrs, r, retaddr);
838852
}
@@ -880,12 +894,13 @@ static bool victim_tlb_hit(CPUArchState *env, size_t mmu_idx, size_t index,
880894
*/
881895
tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr)
882896
{
883-
int mmu_idx, index, pd;
897+
int mmu_idx, index;
884898
void *p;
885899
MemoryRegion *mr;
900+
MemoryRegionSection *section;
886901
CPUState *cpu = ENV_GET_CPU(env);
887902
CPUIOTLBEntry *iotlbentry;
888-
hwaddr physaddr;
903+
hwaddr physaddr, mr_offset;
889904

890905
index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
891906
mmu_idx = cpu_mmu_index(env, true);
@@ -896,8 +911,8 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr)
896911
}
897912
}
898913
iotlbentry = &env->iotlb[mmu_idx][index];
899-
pd = iotlbentry->addr & ~TARGET_PAGE_MASK;
900-
mr = iotlb_to_region(cpu, pd, iotlbentry->attrs);
914+
section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
915+
mr = section->mr;
901916
if (memory_region_is_unassigned(mr)) {
902917
qemu_mutex_lock_iothread();
903918
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)
918933
* and use the MemTXResult it produced). However it is the
919934
* simplest place we have currently available for the check.
920935
*/
921-
physaddr = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
936+
mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
937+
physaddr = mr_offset +
938+
section->offset_within_address_space -
939+
section->offset_within_region;
922940
cpu_transaction_failed(cpu, physaddr, addr, 0, MMU_INST_FETCH, mmu_idx,
923941
iotlbentry->attrs, MEMTX_DECODE_ERROR, 0);
924942

exec.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2897,14 +2897,15 @@ static const MemoryRegionOps readonly_mem_ops = {
28972897
},
28982898
};
28992899

2900-
MemoryRegion *iotlb_to_region(CPUState *cpu, hwaddr index, MemTxAttrs attrs)
2900+
MemoryRegionSection *iotlb_to_section(CPUState *cpu,
2901+
hwaddr index, MemTxAttrs attrs)
29012902
{
29022903
int asidx = cpu_asidx_from_attrs(cpu, attrs);
29032904
CPUAddressSpace *cpuas = &cpu->cpu_ases[asidx];
29042905
AddressSpaceDispatch *d = atomic_rcu_read(&cpuas->memory_dispatch);
29052906
MemoryRegionSection *sections = d->map.sections;
29062907

2907-
return sections[index & ~TARGET_PAGE_MASK].mr;
2908+
return &sections[index & ~TARGET_PAGE_MASK];
29082909
}
29092910

29102911
static void io_mem_init(void)

include/exec/exec-all.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -437,8 +437,17 @@ void tb_lock_reset(void);
437437

438438
#if !defined(CONFIG_USER_ONLY)
439439

440-
struct MemoryRegion *iotlb_to_region(CPUState *cpu,
441-
hwaddr index, MemTxAttrs attrs);
440+
/**
441+
* iotlb_to_section:
442+
* @cpu: CPU performing the access
443+
* @index: TCG CPU IOTLB entry
444+
*
445+
* Given a TCG CPU IOTLB entry, return the MemoryRegionSection that
446+
* it refers to. @index will have been initially created and returned
447+
* by memory_region_section_get_iotlb().
448+
*/
449+
struct MemoryRegionSection *iotlb_to_section(CPUState *cpu,
450+
hwaddr index, MemTxAttrs attrs);
442451

443452
void tlb_fill(CPUState *cpu, target_ulong addr, int size,
444453
MMUAccessType access_type, int mmu_idx, uintptr_t retaddr);

0 commit comments

Comments
 (0)