From 56943e8cc14b7eeeab67d1942fa5d8bcafe3e53f Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Thu, 21 Jan 2016 14:15:04 +0000 Subject: exec.c: Don't set cpu->as until cpu_address_space_init Rather than setting cpu->as unconditionally in cpu_exec_init (and then having target-i386 override this later), don't set it until the first call to cpu_address_space_init. This requires us to initialise the address space for both TCG and KVM (KVM doesn't need the AS listener but it does require cpu->as to be set). For target CPUs which don't set up any address spaces (currently everything except i386), add the default address_space_memory in qemu_init_vcpu(). Signed-off-by: Peter Maydell Reviewed-by: Edgar E. Iglesias Acked-by: Edgar E. Iglesias --- exec.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'exec.c') diff --git a/exec.c b/exec.c index 7f0ce42af0..f34d55698b 100644 --- a/exec.c +++ b/exec.c @@ -536,8 +536,13 @@ CPUState *qemu_get_cpu(int index) } #if !defined(CONFIG_USER_ONLY) -void tcg_cpu_address_space_init(CPUState *cpu, AddressSpace *as) +void cpu_address_space_init(CPUState *cpu, AddressSpace *as, int asidx) { + if (asidx == 0) { + /* address space 0 gets the convenience alias */ + cpu->as = as; + } + /* We only support one address space per cpu at the moment. */ assert(cpu->as == as); @@ -549,8 +554,10 @@ void tcg_cpu_address_space_init(CPUState *cpu, AddressSpace *as) cpu->cpu_ases = g_new0(CPUAddressSpace, 1); cpu->cpu_ases[0].cpu = cpu; cpu->cpu_ases[0].as = as; - cpu->cpu_ases[0].tcg_as_listener.commit = tcg_commit; - memory_listener_register(&cpu->cpu_ases[0].tcg_as_listener, as); + if (tcg_enabled()) { + cpu->cpu_ases[0].tcg_as_listener.commit = tcg_commit; + memory_listener_register(&cpu->cpu_ases[0].tcg_as_listener, as); + } } #endif @@ -605,8 +612,9 @@ void cpu_exec_init(CPUState *cpu, Error **errp) int cpu_index; Error *local_err = NULL; + cpu->as = NULL; + #ifndef CONFIG_USER_ONLY - cpu->as = &address_space_memory; cpu->thread_id = qemu_get_thread_id(); #endif -- cgit v1.2.3-55-g7522 From 12ebc9a76dd7702aef0a3618717a826c19c34ef4 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Thu, 21 Jan 2016 14:15:04 +0000 Subject: exec.c: Allow target CPUs to define multiple AddressSpaces Allow multiple calls to cpu_address_space_init(); each call adds an entry to the cpu->ases array at the specified index. It is up to the target-specific CPU code to actually use these extra address spaces. Since this multiple AddressSpace support won't work with KVM, add an assertion to avoid confusing failures. Signed-off-by: Peter Maydell Acked-by: Edgar E. Iglesias --- cpus.c | 1 + exec.c | 25 +++++++++++++++---------- include/exec/exec-all.h | 4 ++++ include/qom/cpu.h | 2 ++ target-i386/cpu.c | 1 + 5 files changed, 23 insertions(+), 10 deletions(-) (limited to 'exec.c') diff --git a/cpus.c b/cpus.c index 787877aa24..725a51dac9 100644 --- a/cpus.c +++ b/cpus.c @@ -1375,6 +1375,7 @@ void qemu_init_vcpu(CPUState *cpu) /* If the target cpu hasn't set up any address spaces itself, * give it the default one. */ + cpu->num_ases = 1; cpu_address_space_init(cpu, &address_space_memory, 0); } diff --git a/exec.c b/exec.c index f34d55698b..8bc3288105 100644 --- a/exec.c +++ b/exec.c @@ -538,25 +538,29 @@ CPUState *qemu_get_cpu(int index) #if !defined(CONFIG_USER_ONLY) void cpu_address_space_init(CPUState *cpu, AddressSpace *as, int asidx) { + CPUAddressSpace *newas; + + /* Target code should have set num_ases before calling us */ + assert(asidx < cpu->num_ases); + if (asidx == 0) { /* address space 0 gets the convenience alias */ cpu->as = as; } - /* We only support one address space per cpu at the moment. */ - assert(cpu->as == as); + /* KVM cannot currently support multiple address spaces. */ + assert(asidx == 0 || !kvm_enabled()); - if (cpu->cpu_ases) { - /* We've already registered the listener for our only AS */ - return; + if (!cpu->cpu_ases) { + cpu->cpu_ases = g_new0(CPUAddressSpace, cpu->num_ases); } - cpu->cpu_ases = g_new0(CPUAddressSpace, 1); - cpu->cpu_ases[0].cpu = cpu; - cpu->cpu_ases[0].as = as; + newas = &cpu->cpu_ases[asidx]; + newas->cpu = cpu; + newas->as = as; if (tcg_enabled()) { - cpu->cpu_ases[0].tcg_as_listener.commit = tcg_commit; - memory_listener_register(&cpu->cpu_ases[0].tcg_as_listener, as); + newas->tcg_as_listener.commit = tcg_commit; + memory_listener_register(&newas->tcg_as_listener, as); } } #endif @@ -613,6 +617,7 @@ void cpu_exec_init(CPUState *cpu, Error **errp) Error *local_err = NULL; cpu->as = NULL; + cpu->num_ases = 0; #ifndef CONFIG_USER_ONLY cpu->thread_id = qemu_get_thread_id(); diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index eb3890a389..9be0165e80 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -96,6 +96,10 @@ void cpu_reloading_memory_map(void); * The target-specific code which registers ASes is responsible * for defining what semantics address space 0, 1, 2, etc have. * + * Before the first call to this function, the caller must set + * cpu->num_ases to the total number of address spaces it needs + * to support. + * * Note that with KVM only one address space is supported. */ void cpu_address_space_init(CPUState *cpu, AddressSpace *as, int asidx); diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 51a1323ead..ae1793219b 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -236,6 +236,7 @@ struct kvm_run; * so that interrupts take effect immediately. * @cpu_ases: Pointer to array of CPUAddressSpaces (which define the * AddressSpaces this CPU has) + * @num_ases: number of CPUAddressSpaces in @cpu_ases * @as: Pointer to the first AddressSpace, for the convenience of targets which * only have a single AddressSpace * @env_ptr: Pointer to subclass-specific CPUArchState field. @@ -285,6 +286,7 @@ struct CPUState { struct qemu_work_item *queued_work_first, *queued_work_last; CPUAddressSpace *cpu_ases; + int num_ases; AddressSpace *as; void *env_ptr; /* CPUArchState */ diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 36fae2dc26..4430494085 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2878,6 +2878,7 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) memory_region_add_subregion_overlap(cpu->cpu_as_root, 0, cpu->cpu_as_mem, 0); memory_region_set_enabled(cpu->cpu_as_mem, true); address_space_init(newas, cpu->cpu_as_root, "CPU"); + cs->num_ases = 1; cpu_address_space_init(cs, newas, 0); /* ... SMRAM with higher priority, linked from /machine/smram. */ -- cgit v1.2.3-55-g7522 From d7898cda81b6efa6b2d7a749882695cdcf280eaa Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Thu, 21 Jan 2016 14:15:05 +0000 Subject: cputlb.c: Use correct address space when looking up MemoryRegionSection When looking up the MemoryRegionSection for the new TLB entry in tlb_set_page_with_attrs(), use cpu_asidx_from_attrs() to determine the correct address space index for the lookup, and pass it into address_space_translate_for_iotlb(). Signed-off-by: Peter Maydell Acked-by: Edgar E. Iglesias --- cputlb.c | 3 ++- exec.c | 7 ++++--- include/exec/exec-all.h | 4 ++-- 3 files changed, 8 insertions(+), 6 deletions(-) (limited to 'exec.c') diff --git a/cputlb.c b/cputlb.c index bf1d50adde..f1c1082069 100644 --- a/cputlb.c +++ b/cputlb.c @@ -356,6 +356,7 @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr, CPUTLBEntry *te; hwaddr iotlb, xlat, sz; unsigned vidx = env->vtlb_index++ % CPU_VTLB_SIZE; + int asidx = cpu_asidx_from_attrs(cpu, attrs); assert(size >= TARGET_PAGE_SIZE); if (size != TARGET_PAGE_SIZE) { @@ -363,7 +364,7 @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr, } sz = size; - section = address_space_translate_for_iotlb(cpu, paddr, &xlat, &sz); + section = address_space_translate_for_iotlb(cpu, asidx, paddr, &xlat, &sz); assert(sz >= TARGET_PAGE_SIZE); #if defined(DEBUG_TLB) diff --git a/exec.c b/exec.c index 8bc3288105..884586ad2f 100644 --- a/exec.c +++ b/exec.c @@ -431,12 +431,13 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr, /* Called from RCU critical section */ MemoryRegionSection * -address_space_translate_for_iotlb(CPUState *cpu, hwaddr addr, +address_space_translate_for_iotlb(CPUState *cpu, int asidx, hwaddr addr, hwaddr *xlat, hwaddr *plen) { MemoryRegionSection *section; - section = address_space_translate_internal(cpu->cpu_ases[0].memory_dispatch, - addr, xlat, plen, false); + AddressSpaceDispatch *d = cpu->cpu_ases[asidx].memory_dispatch; + + section = address_space_translate_internal(d, addr, xlat, plen, false); assert(!section->mr->iommu_ops); return section; diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index caa78a952b..ee9757f60d 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -432,8 +432,8 @@ void tlb_set_dirty(CPUState *cpu, target_ulong vaddr); void tb_flush_jmp_cache(CPUState *cpu, target_ulong addr); MemoryRegionSection * -address_space_translate_for_iotlb(CPUState *cpu, hwaddr addr, hwaddr *xlat, - hwaddr *plen); +address_space_translate_for_iotlb(CPUState *cpu, int asidx, hwaddr addr, + hwaddr *xlat, hwaddr *plen); hwaddr memory_region_section_get_iotlb(CPUState *cpu, MemoryRegionSection *section, target_ulong vaddr, -- cgit v1.2.3-55-g7522 From a54c87b68a0410d0cf6f8b84e42074a5cf463732 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Thu, 21 Jan 2016 14:15:05 +0000 Subject: exec.c: Pass MemTxAttrs to iotlb_to_region so it uses the right AS Pass the MemTxAttrs for the memory access to iotlb_to_region(); this allows it to determine the correct AddressSpace to use for the lookup. Signed-off-by: Peter Maydell Acked-by: Edgar E. Iglesias --- cputlb.c | 6 ++++-- exec.c | 5 +++-- include/exec/exec-all.h | 2 +- softmmu_template.h | 4 ++-- 4 files changed, 10 insertions(+), 7 deletions(-) (limited to 'exec.c') diff --git a/cputlb.c b/cputlb.c index f1c1082069..f6fb161d15 100644 --- a/cputlb.c +++ b/cputlb.c @@ -449,6 +449,7 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr) void *p; MemoryRegion *mr; CPUState *cpu = ENV_GET_CPU(env1); + CPUIOTLBEntry *iotlbentry; page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); mmu_idx = cpu_mmu_index(env1, true); @@ -456,8 +457,9 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr) (addr & TARGET_PAGE_MASK))) { cpu_ldub_code(env1, addr); } - pd = env1->iotlb[mmu_idx][page_index].addr & ~TARGET_PAGE_MASK; - mr = iotlb_to_region(cpu, pd); + iotlbentry = &env1->iotlb[mmu_idx][page_index]; + pd = iotlbentry->addr & ~TARGET_PAGE_MASK; + mr = iotlb_to_region(cpu, pd, iotlbentry->attrs); if (memory_region_is_unassigned(mr)) { CPUClass *cc = CPU_GET_CLASS(cpu); diff --git a/exec.c b/exec.c index 884586ad2f..5bd304584c 100644 --- a/exec.c +++ b/exec.c @@ -2238,9 +2238,10 @@ static uint16_t dummy_section(PhysPageMap *map, AddressSpace *as, return phys_section_add(map, §ion); } -MemoryRegion *iotlb_to_region(CPUState *cpu, hwaddr index) +MemoryRegion *iotlb_to_region(CPUState *cpu, hwaddr index, MemTxAttrs attrs) { - CPUAddressSpace *cpuas = &cpu->cpu_ases[0]; + int asidx = cpu_asidx_from_attrs(cpu, attrs); + CPUAddressSpace *cpuas = &cpu->cpu_ases[asidx]; AddressSpaceDispatch *d = atomic_rcu_read(&cpuas->memory_dispatch); MemoryRegionSection *sections = d->map.sections; diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index ee9757f60d..587736e9fb 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -403,7 +403,7 @@ extern uintptr_t tci_tb_ptr; #if !defined(CONFIG_USER_ONLY) struct MemoryRegion *iotlb_to_region(CPUState *cpu, - hwaddr index); + hwaddr index, MemTxAttrs attrs); void tlb_fill(CPUState *cpu, target_ulong addr, int is_write, int mmu_idx, uintptr_t retaddr); diff --git a/softmmu_template.h b/softmmu_template.h index 6803890e4f..208f808f3e 100644 --- a/softmmu_template.h +++ b/softmmu_template.h @@ -150,7 +150,7 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env, uint64_t val; CPUState *cpu = ENV_GET_CPU(env); hwaddr physaddr = iotlbentry->addr; - MemoryRegion *mr = iotlb_to_region(cpu, physaddr); + MemoryRegion *mr = iotlb_to_region(cpu, physaddr, iotlbentry->attrs); physaddr = (physaddr & TARGET_PAGE_MASK) + addr; cpu->mem_io_pc = retaddr; @@ -357,7 +357,7 @@ static inline void glue(io_write, SUFFIX)(CPUArchState *env, { CPUState *cpu = ENV_GET_CPU(env); hwaddr physaddr = iotlbentry->addr; - MemoryRegion *mr = iotlb_to_region(cpu, physaddr); + MemoryRegion *mr = iotlb_to_region(cpu, physaddr, iotlbentry->attrs); physaddr = (physaddr & TARGET_PAGE_MASK) + addr; if (mr != &io_mem_rom && mr != &io_mem_notdirty && !cpu->can_do_io) { -- cgit v1.2.3-55-g7522 From 651a5bc03705102de519ebf079a40ecc1da991db Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Thu, 21 Jan 2016 14:15:05 +0000 Subject: exec.c: Add cpu_get_address_space() Add a function to return the AddressSpace for a CPU based on its numerical index. (Callers outside exec.c don't have access to the CPUAddressSpace struct so can't just fish it out of the CPUState struct directly.) Signed-off-by: Peter Maydell Acked-by: Edgar E. Iglesias --- exec.c | 6 ++++++ include/exec/exec-all.h | 9 +++++++++ 2 files changed, 15 insertions(+) (limited to 'exec.c') diff --git a/exec.c b/exec.c index 5bd304584c..cbadca4b50 100644 --- a/exec.c +++ b/exec.c @@ -564,6 +564,12 @@ void cpu_address_space_init(CPUState *cpu, AddressSpace *as, int asidx) memory_listener_register(&newas->tcg_as_listener, as); } } + +AddressSpace *cpu_get_address_space(CPUState *cpu, int asidx) +{ + /* Return the AddressSpace corresponding to the specified index */ + return cpu->cpu_ases[asidx].as; +} #endif #ifndef CONFIG_USER_ONLY diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 587736e9fb..05a151da4a 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -103,6 +103,15 @@ void cpu_reloading_memory_map(void); * Note that with KVM only one address space is supported. */ void cpu_address_space_init(CPUState *cpu, AddressSpace *as, int asidx); +/** + * cpu_get_address_space: + * @cpu: CPU to get address space from + * @asidx: index identifying which address space to get + * + * Return the requested address space of this CPU. @asidx + * specifies which address space to read. + */ +AddressSpace *cpu_get_address_space(CPUState *cpu, int asidx); /* cputlb.c */ /** * tlb_flush_page: -- cgit v1.2.3-55-g7522 From 5232e4c798ba7a46261d3157b73d08fc598e7dcb Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Thu, 21 Jan 2016 14:15:06 +0000 Subject: exec.c: Use cpu_get_phys_page_attrs_debug Use cpu_get_phys_page_attrs_debug() when doing virtual-to-physical conversions in debug related code, so that we can obtain the right address space index and thus select the correct AddressSpace, rather than always using cpu->as. Signed-off-by: Peter Maydell Acked-by: Edgar E. Iglesias --- exec.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'exec.c') diff --git a/exec.c b/exec.c index cbadca4b50..590a018d95 100644 --- a/exec.c +++ b/exec.c @@ -667,9 +667,11 @@ static void breakpoint_invalidate(CPUState *cpu, target_ulong pc) #else static void breakpoint_invalidate(CPUState *cpu, target_ulong pc) { - hwaddr phys = cpu_get_phys_page_debug(cpu, pc); + MemTxAttrs attrs; + hwaddr phys = cpu_get_phys_page_attrs_debug(cpu, pc, &attrs); + int asidx = cpu_asidx_from_attrs(cpu, attrs); if (phys != -1) { - tb_invalidate_phys_addr(cpu->as, + tb_invalidate_phys_addr(cpu->cpu_ases[asidx].as, phys | (pc & ~TARGET_PAGE_MASK)); } } @@ -3586,8 +3588,12 @@ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr, target_ulong page; while (len > 0) { + int asidx; + MemTxAttrs attrs; + page = addr & TARGET_PAGE_MASK; - phys_addr = cpu_get_phys_page_debug(cpu, page); + phys_addr = cpu_get_phys_page_attrs_debug(cpu, page, &attrs); + asidx = cpu_asidx_from_attrs(cpu, attrs); /* if no physical page mapped, return an error */ if (phys_addr == -1) return -1; @@ -3596,9 +3602,11 @@ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr, l = len; phys_addr += (addr & ~TARGET_PAGE_MASK); if (is_write) { - cpu_physical_memory_write_rom(cpu->as, phys_addr, buf, l); + cpu_physical_memory_write_rom(cpu->cpu_ases[asidx].as, + phys_addr, buf, l); } else { - address_space_rw(cpu->as, phys_addr, MEMTXATTRS_UNSPECIFIED, + address_space_rw(cpu->cpu_ases[asidx].as, phys_addr, + MEMTXATTRS_UNSPECIFIED, buf, l, 0); } len -= l; -- cgit v1.2.3-55-g7522 From 79ed0416477440ccb6acf136d6808a4f5848bbdf Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Thu, 21 Jan 2016 14:15:06 +0000 Subject: exec.c: Use correct AddressSpace in watch_mem_read and watch_mem_write In the watchpoint access routines watch_mem_read and watch_mem_write, find the correct AddressSpace to use from current_cpu and the memory transaction attributes, rather than always assuming address_space_memory. Signed-off-by: Peter Maydell Acked-by: Edgar E. Iglesias --- exec.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'exec.c') diff --git a/exec.c b/exec.c index 590a018d95..0e4f681360 100644 --- a/exec.c +++ b/exec.c @@ -2056,17 +2056,19 @@ static MemTxResult watch_mem_read(void *opaque, hwaddr addr, uint64_t *pdata, { MemTxResult res; uint64_t data; + int asidx = cpu_asidx_from_attrs(current_cpu, attrs); + AddressSpace *as = current_cpu->cpu_ases[asidx].as; check_watchpoint(addr & ~TARGET_PAGE_MASK, size, attrs, BP_MEM_READ); switch (size) { case 1: - data = address_space_ldub(&address_space_memory, addr, attrs, &res); + data = address_space_ldub(as, addr, attrs, &res); break; case 2: - data = address_space_lduw(&address_space_memory, addr, attrs, &res); + data = address_space_lduw(as, addr, attrs, &res); break; case 4: - data = address_space_ldl(&address_space_memory, addr, attrs, &res); + data = address_space_ldl(as, addr, attrs, &res); break; default: abort(); } @@ -2079,17 +2081,19 @@ static MemTxResult watch_mem_write(void *opaque, hwaddr addr, MemTxAttrs attrs) { MemTxResult res; + int asidx = cpu_asidx_from_attrs(current_cpu, attrs); + AddressSpace *as = current_cpu->cpu_ases[asidx].as; check_watchpoint(addr & ~TARGET_PAGE_MASK, size, attrs, BP_MEM_WRITE); switch (size) { case 1: - address_space_stb(&address_space_memory, addr, val, attrs, &res); + address_space_stb(as, addr, val, attrs, &res); break; case 2: - address_space_stw(&address_space_memory, addr, val, attrs, &res); + address_space_stw(as, addr, val, attrs, &res); break; case 4: - address_space_stl(&address_space_memory, addr, val, attrs, &res); + address_space_stl(as, addr, val, attrs, &res); break; default: abort(); } -- cgit v1.2.3-55-g7522 From 6731d864f80938e404dc3e5eb7f6b76b891e3e43 Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Thu, 21 Jan 2016 14:15:06 +0000 Subject: qom/cpu: Add MemoryRegion property Add a MemoryRegion property, which if set is used to construct the CPU's initial (default) AddressSpace. Signed-off-by: Peter Crosthwaite [PMM: code is moved from qom/cpu.c to exec.c to avoid having to make qom/cpu.o be a non-common object file; code to use the MemoryRegion and to default it to system_memory added.] Signed-off-by: Peter Maydell Acked-by: Edgar E. Iglesias --- cpus.c | 4 +++- exec.c | 14 ++++++++++++++ include/qom/cpu.h | 1 + 3 files changed, 18 insertions(+), 1 deletion(-) (limited to 'exec.c') diff --git a/cpus.c b/cpus.c index 725a51dac9..3efff6b109 100644 --- a/cpus.c +++ b/cpus.c @@ -1375,8 +1375,10 @@ void qemu_init_vcpu(CPUState *cpu) /* If the target cpu hasn't set up any address spaces itself, * give it the default one. */ + AddressSpace *as = address_space_init_shareable(cpu->memory, + "cpu-memory"); cpu->num_ases = 1; - cpu_address_space_init(cpu, &address_space_memory, 0); + cpu_address_space_init(cpu, as, 0); } if (kvm_enabled()) { diff --git a/exec.c b/exec.c index 0e4f681360..5a1b208911 100644 --- a/exec.c +++ b/exec.c @@ -628,6 +628,20 @@ void cpu_exec_init(CPUState *cpu, Error **errp) #ifndef CONFIG_USER_ONLY cpu->thread_id = qemu_get_thread_id(); + + /* This is a softmmu CPU object, so create a property for it + * so users can wire up its memory. (This can't go in qom/cpu.c + * because that file is compiled only once for both user-mode + * and system builds.) The default if no link is set up is to use + * the system address space. + */ + object_property_add_link(OBJECT(cpu), "memory", TYPE_MEMORY_REGION, + (Object **)&cpu->memory, + qdev_prop_allow_set_link_before_realize, + OBJ_PROP_LINK_UNREF_ON_RELEASE, + &error_abort); + cpu->memory = system_memory; + object_ref(OBJECT(cpu->memory)); #endif #if defined(CONFIG_USER_ONLY) diff --git a/include/qom/cpu.h b/include/qom/cpu.h index ed232463d5..2e5229d280 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -297,6 +297,7 @@ struct CPUState { CPUAddressSpace *cpu_ases; int num_ases; AddressSpace *as; + MemoryRegion *memory; void *env_ptr; /* CPUArchState */ struct TranslationBlock *current_tb; -- cgit v1.2.3-55-g7522