diff options
| -rw-r--r-- | hw/core/cpu-common.c | 1 | ||||
| -rw-r--r-- | include/exec/cpu-common.h | 10 | ||||
| -rw-r--r-- | include/hw/core/cpu.h | 1 | ||||
| -rw-r--r-- | stubs/cpu-destroy-address-spaces.c | 15 | ||||
| -rw-r--r-- | stubs/meson.build | 1 | ||||
| -rw-r--r-- | system/physmem.c | 32 |
6 files changed, 37 insertions, 23 deletions
diff --git a/hw/core/cpu-common.c b/hw/core/cpu-common.c index 41a339903c..8c306c89e4 100644 --- a/hw/core/cpu-common.c +++ b/hw/core/cpu-common.c @@ -294,6 +294,7 @@ void cpu_exec_unrealizefn(CPUState *cpu) * accel_cpu_common_unrealize, which may free fields using call_rcu. */ accel_cpu_common_unrealize(cpu); + cpu_destroy_address_spaces(cpu); } static void cpu_common_initfn(Object *obj) diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h index f373781ae0..b96ac49844 100644 --- a/include/exec/cpu-common.h +++ b/include/exec/cpu-common.h @@ -123,13 +123,13 @@ size_t qemu_ram_pagesize_largest(void); void cpu_address_space_init(CPUState *cpu, int asidx, const char *prefix, MemoryRegion *mr); /** - * cpu_address_space_destroy: - * @cpu: CPU for which address space needs to be destroyed - * @asidx: integer index of this address space + * cpu_destroy_address_spaces: + * @cpu: CPU for which address spaces need to be destroyed * - * Note that with KVM only one address space is supported. + * Destroy all address spaces associated with this CPU; this + * is called as part of unrealizing the CPU. */ -void cpu_address_space_destroy(CPUState *cpu, int asidx); +void cpu_destroy_address_spaces(CPUState *cpu); void cpu_physical_memory_rw(hwaddr addr, void *buf, hwaddr len, bool is_write); diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h index c9f40c2539..0fcbc923f3 100644 --- a/include/hw/core/cpu.h +++ b/include/hw/core/cpu.h @@ -515,7 +515,6 @@ struct CPUState { QSIMPLEQ_HEAD(, qemu_work_item) work_list; struct CPUAddressSpace *cpu_ases; - int cpu_ases_count; int num_ases; AddressSpace *as; MemoryRegion *memory; diff --git a/stubs/cpu-destroy-address-spaces.c b/stubs/cpu-destroy-address-spaces.c new file mode 100644 index 0000000000..dc6813f5bd --- /dev/null +++ b/stubs/cpu-destroy-address-spaces.c @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "qemu/osdep.h" +#include "exec/cpu-common.h" + +/* + * user-mode CPUs never create address spaces with + * cpu_address_space_init(), so the cleanup function doesn't + * need to do anything. We need this stub because cpu-common.c + * is built-once so it can't #ifndef CONFIG_USER around the + * call; the real function is in physmem.c which is system-only. + */ +void cpu_destroy_address_spaces(CPUState *cpu) +{ +} diff --git a/stubs/meson.build b/stubs/meson.build index cef046e685..5d577467bf 100644 --- a/stubs/meson.build +++ b/stubs/meson.build @@ -55,6 +55,7 @@ endif if have_user # Symbols that are used by hw/core. stub_ss.add(files('cpu-synchronize-state.c')) + stub_ss.add(files('cpu-destroy-address-spaces.c')) # Stubs for QAPI events. Those can always be included in the build, but # they are not built at all for --disable-system builds. diff --git a/system/physmem.c b/system/physmem.c index ae8ecd50ea..dbb2a4e017 100644 --- a/system/physmem.c +++ b/system/physmem.c @@ -795,7 +795,6 @@ void cpu_address_space_init(CPUState *cpu, int asidx, if (!cpu->cpu_ases) { cpu->cpu_ases = g_new0(CPUAddressSpace, cpu->num_ases); - cpu->cpu_ases_count = cpu->num_ases; } newas = &cpu->cpu_ases[asidx]; @@ -809,30 +808,29 @@ void cpu_address_space_init(CPUState *cpu, int asidx, } } -void cpu_address_space_destroy(CPUState *cpu, int asidx) +void cpu_destroy_address_spaces(CPUState *cpu) { CPUAddressSpace *cpuas; + int asidx; assert(cpu->cpu_ases); - assert(asidx >= 0 && asidx < cpu->num_ases); - cpuas = &cpu->cpu_ases[asidx]; - if (tcg_enabled()) { - memory_listener_unregister(&cpuas->tcg_as_listener); - } + /* convenience alias just points to some cpu_ases[n] */ + cpu->as = NULL; - address_space_destroy(cpuas->as); - g_free_rcu(cpuas->as, rcu); - - if (asidx == 0) { - /* reset the convenience alias for address space 0 */ - cpu->as = NULL; + for (asidx = 0; asidx < cpu->num_ases; asidx++) { + cpuas = &cpu->cpu_ases[asidx]; + if (!cpuas->as) { + /* This index was never initialized; no deinit needed */ + continue; + } + if (tcg_enabled()) { + memory_listener_unregister(&cpuas->tcg_as_listener); + } + g_clear_pointer(&cpuas->as, address_space_destroy_free); } - if (--cpu->cpu_ases_count == 0) { - g_free(cpu->cpu_ases); - cpu->cpu_ases = NULL; - } + g_clear_pointer(&cpu->cpu_ases, g_free); } AddressSpace *cpu_get_address_space(CPUState *cpu, int asidx) |