Skip to content

Commit

Permalink
exec: make iotlb RCU-friendly
Browse files Browse the repository at this point in the history
After the previous patch, TLBs will be flushed on every change to
the memory mapping.  This patch augments that with synchronization
of the MemoryRegionSections referred to in the iotlb array.

With this change, it is guaranteed that iotlb_to_region will access
the correct memory map, even once the TLB will be accessed outside
the BQL.

Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
  • Loading branch information
bonzini committed Feb 16, 2015
1 parent 76e5c76 commit 9d82b5a
Show file tree
Hide file tree
Showing 7 changed files with 21 additions and 13 deletions.
6 changes: 5 additions & 1 deletion cpu-exec.c
Expand Up @@ -24,6 +24,8 @@
#include "qemu/atomic.h"
#include "sysemu/qtest.h"
#include "qemu/timer.h"
#include "exec/address-spaces.h"
#include "exec/memory-internal.h"

/* -icount align implementation. */

Expand Down Expand Up @@ -144,7 +146,9 @@ void cpu_resume_from_signal(CPUState *cpu, void *puc)

void cpu_reload_memory_map(CPUState *cpu)
{
/* The TLB is protected by the iothread lock. */
/* The CPU and TLB are protected by the iothread lock. */
AddressSpaceDispatch *d = cpu->as->dispatch;
cpu->memory_dispatch = d;
tlb_flush(cpu, 1);
}
#endif
Expand Down
5 changes: 2 additions & 3 deletions cputlb.c
Expand Up @@ -265,8 +265,7 @@ void tlb_set_page(CPUState *cpu, target_ulong vaddr,
}

sz = size;
section = address_space_translate_for_iotlb(cpu->as, paddr,
&xlat, &sz);
section = address_space_translate_for_iotlb(cpu, paddr, &xlat, &sz);
assert(sz >= TARGET_PAGE_SIZE);

#if defined(DEBUG_TLB)
Expand Down Expand Up @@ -347,7 +346,7 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr)
cpu_ldub_code(env1, addr);
}
pd = env1->iotlb[mmu_idx][page_index] & ~TARGET_PAGE_MASK;
mr = iotlb_to_region(cpu->as, pd);
mr = iotlb_to_region(cpu, pd);
if (memory_region_is_unassigned(mr)) {
CPUClass *cc = CPU_GET_CLASS(cpu);

Expand Down
13 changes: 8 additions & 5 deletions exec.c
Expand Up @@ -401,11 +401,12 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
}

MemoryRegionSection *
address_space_translate_for_iotlb(AddressSpace *as, hwaddr addr, hwaddr *xlat,
hwaddr *plen)
address_space_translate_for_iotlb(CPUState *cpu, hwaddr addr,
hwaddr *xlat, hwaddr *plen)
{
MemoryRegionSection *section;
section = address_space_translate_internal(as->dispatch, addr, xlat, plen, false);
section = address_space_translate_internal(cpu->memory_dispatch,
addr, xlat, plen, false);

assert(!section->mr->iommu_ops);
return section;
Expand Down Expand Up @@ -1961,9 +1962,11 @@ static uint16_t dummy_section(PhysPageMap *map, AddressSpace *as,
return phys_section_add(map, &section);
}

MemoryRegion *iotlb_to_region(AddressSpace *as, hwaddr index)
MemoryRegion *iotlb_to_region(CPUState *cpu, hwaddr index)
{
return as->dispatch->map.sections[index & ~TARGET_PAGE_MASK].mr;
MemoryRegionSection *sections = cpu->memory_dispatch->map.sections;

return sections[index & ~TARGET_PAGE_MASK].mr;
}

static void io_mem_init(void)
Expand Down
2 changes: 1 addition & 1 deletion include/exec/cputlb.h
Expand Up @@ -34,7 +34,7 @@ extern int tlb_flush_count;
void tb_flush_jmp_cache(CPUState *cpu, target_ulong addr);

MemoryRegionSection *
address_space_translate_for_iotlb(AddressSpace *as, hwaddr addr, hwaddr *xlat,
address_space_translate_for_iotlb(CPUState *cpu, hwaddr addr, hwaddr *xlat,
hwaddr *plen);
hwaddr memory_region_section_get_iotlb(CPUState *cpu,
MemoryRegionSection *section,
Expand Down
3 changes: 2 additions & 1 deletion include/exec/exec-all.h
Expand Up @@ -338,7 +338,8 @@ extern uintptr_t tci_tb_ptr;

void phys_mem_set_alloc(void *(*alloc)(size_t, uint64_t *align));

struct MemoryRegion *iotlb_to_region(AddressSpace *as, hwaddr index);
struct MemoryRegion *iotlb_to_region(CPUState *cpu,
hwaddr index);
bool io_mem_read(struct MemoryRegion *mr, hwaddr addr,
uint64_t *pvalue, unsigned size);
bool io_mem_write(struct MemoryRegion *mr, hwaddr addr,
Expand Down
1 change: 1 addition & 0 deletions include/qom/cpu.h
Expand Up @@ -256,6 +256,7 @@ struct CPUState {
sigjmp_buf jmp_env;

AddressSpace *as;
struct AddressSpaceDispatch *memory_dispatch;
MemoryListener *tcg_as_listener;

void *env_ptr; /* CPUArchState */
Expand Down
4 changes: 2 additions & 2 deletions softmmu_template.h
Expand Up @@ -149,7 +149,7 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env,
{
uint64_t val;
CPUState *cpu = ENV_GET_CPU(env);
MemoryRegion *mr = iotlb_to_region(cpu->as, physaddr);
MemoryRegion *mr = iotlb_to_region(cpu, physaddr);

physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
cpu->mem_io_pc = retaddr;
Expand Down Expand Up @@ -369,7 +369,7 @@ static inline void glue(io_write, SUFFIX)(CPUArchState *env,
uintptr_t retaddr)
{
CPUState *cpu = ENV_GET_CPU(env);
MemoryRegion *mr = iotlb_to_region(cpu->as, physaddr);
MemoryRegion *mr = iotlb_to_region(cpu, physaddr);

physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
if (mr != &io_mem_rom && mr != &io_mem_notdirty && !cpu_can_do_io(cpu)) {
Expand Down

0 comments on commit 9d82b5a

Please sign in to comment.