Hi Salil, [...]
+void cpu_address_space_destroy(CPUState *cpu, int asidx) { + CPUAddressSpace *cpuas; + + assert(cpu->cpu_ases); + assert(asidx >= 0 && asidx < cpu->num_ases); + /* KVM cannot currently support multiple address spaces. */ + assert(asidx == 0 || !kvm_enabled()); + + cpuas = &cpu->cpu_ases[asidx]; + if (tcg_enabled()) { + memory_listener_unregister(&cpuas->tcg_as_listener); + } + + address_space_destroy(cpuas->as); + g_free_rcu(cpuas->as, rcu); In address_space_destroy(), it calls call_rcu1() on cpuas->as which will set do_address_space_destroy() as the rcu func. And g_free_rcu() also calls call_rcu1() on cpuas->as which will overwrite the rcu func as g_free(). Then I think the g_free() may be called twice in rcu thread, please verify that. The source code of call_rcu1: void call_rcu1(struct rcu_head *node, void (*func)(struct rcu_head *node)) { node->func = func; enqueue(node); qatomic_inc(&rcu_call_count); qemu_event_set(&rcu_call_ready_event); } Thanks, Keqian + + if (asidx == 0) { + /* reset the convenience alias for address space 0 */ + cpu->as = NULL; + } + + if (--cpu->cpu_ases_count == 0) { + g_free(cpu->cpu_ases); + cpu->cpu_ases = NULL; + } +} + AddressSpace *cpu_get_address_space(CPUState *cpu, int asidx) { /* Return the AddressSpace corresponding to the specified index */ -- 2.34.1