1df4fd7d5SPhilippe Mathieu-Daudé /* 232cad1ffSPhilippe Mathieu-Daudé * QEMU CPU model (system specific) 3df4fd7d5SPhilippe Mathieu-Daudé * 4df4fd7d5SPhilippe Mathieu-Daudé * Copyright (c) 2012-2014 SUSE LINUX Products GmbH 5df4fd7d5SPhilippe Mathieu-Daudé * 6df4fd7d5SPhilippe Mathieu-Daudé * This program is free software; you can redistribute it and/or 7df4fd7d5SPhilippe Mathieu-Daudé * modify it under the terms of the GNU General Public License 8df4fd7d5SPhilippe Mathieu-Daudé * as published by the Free Software Foundation; either version 2 9df4fd7d5SPhilippe Mathieu-Daudé * of the License, or (at your option) any later version. 10df4fd7d5SPhilippe Mathieu-Daudé * 11df4fd7d5SPhilippe Mathieu-Daudé * This program is distributed in the hope that it will be useful, 12df4fd7d5SPhilippe Mathieu-Daudé * but WITHOUT ANY WARRANTY; without even the implied warranty of 13df4fd7d5SPhilippe Mathieu-Daudé * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14df4fd7d5SPhilippe Mathieu-Daudé * GNU General Public License for more details. 15df4fd7d5SPhilippe Mathieu-Daudé * 16df4fd7d5SPhilippe Mathieu-Daudé * You should have received a copy of the GNU General Public License 17df4fd7d5SPhilippe Mathieu-Daudé * along with this program; if not, see 18df4fd7d5SPhilippe Mathieu-Daudé * <http://www.gnu.org/licenses/gpl-2.0.html> 19df4fd7d5SPhilippe Mathieu-Daudé */ 20df4fd7d5SPhilippe Mathieu-Daudé 21df4fd7d5SPhilippe Mathieu-Daudé #include "qemu/osdep.h" 22df4fd7d5SPhilippe Mathieu-Daudé #include "qapi/error.h" 23a86cf967SPhilippe Mathieu-Daudé #include "exec/address-spaces.h" 24ca05578fSPhilippe Mathieu-Daudé #include "exec/cputlb.h" 25e3a575f5SPhilippe Mathieu-Daudé #include "exec/memory.h" 26ca05578fSPhilippe Mathieu-Daudé #include "exec/tb-flush.h" 2742508261SPhilippe Mathieu-Daudé #include "exec/tswap.h" 28e3a575f5SPhilippe Mathieu-Daudé #include "hw/qdev-core.h" 29e3a575f5SPhilippe Mathieu-Daudé #include "hw/qdev-properties.h" 30da383e02SPhilippe Mathieu-Daudé #include "hw/core/sysemu-cpu-ops.h" 31ca05578fSPhilippe Mathieu-Daudé #include "migration/vmstate.h" 32ca05578fSPhilippe Mathieu-Daudé #include "system/tcg.h" 33df4fd7d5SPhilippe Mathieu-Daudé 348f8dbe04SPhilippe Mathieu-Daudé bool cpu_has_work(CPUState *cpu) 358f8dbe04SPhilippe Mathieu-Daudé { 3672eacd62SPhilippe Mathieu-Daudé return cpu->cc->sysemu_ops->has_work(cpu); 3772eacd62SPhilippe Mathieu-Daudé } 3872eacd62SPhilippe Mathieu-Daudé 3977ba5d50SPhilippe Mathieu-Daudé bool cpu_paging_enabled(const CPUState *cpu) 4077ba5d50SPhilippe Mathieu-Daudé { 4130e76638SPhilippe Mathieu-Daudé if (cpu->cc->sysemu_ops->get_paging_enabled) { 4230e76638SPhilippe Mathieu-Daudé return cpu->cc->sysemu_ops->get_paging_enabled(cpu); 4377ba5d50SPhilippe Mathieu-Daudé } 4477ba5d50SPhilippe Mathieu-Daudé 4577ba5d50SPhilippe Mathieu-Daudé return false; 4677ba5d50SPhilippe Mathieu-Daudé } 4777ba5d50SPhilippe Mathieu-Daudé 488a5b974bSMarc-André Lureau bool cpu_get_memory_mapping(CPUState *cpu, MemoryMappingList *list, 4965c57115SPhilippe Mathieu-Daudé Error **errp) 5065c57115SPhilippe Mathieu-Daudé { 5130e76638SPhilippe Mathieu-Daudé if (cpu->cc->sysemu_ops->get_memory_mapping) { 5230e76638SPhilippe Mathieu-Daudé return cpu->cc->sysemu_ops->get_memory_mapping(cpu, list, errp); 5365c57115SPhilippe Mathieu-Daudé } 5465c57115SPhilippe Mathieu-Daudé 5565c57115SPhilippe Mathieu-Daudé error_setg(errp, "Obtaining memory mappings is unsupported on this CPU."); 568a5b974bSMarc-André Lureau return false; 5765c57115SPhilippe Mathieu-Daudé } 5865c57115SPhilippe Mathieu-Daudé 59a41d3aaeSPhilippe Mathieu-Daudé hwaddr cpu_get_phys_page_attrs_debug(CPUState *cpu, vaddr addr, 60a41d3aaeSPhilippe Mathieu-Daudé MemTxAttrs *attrs) 61a41d3aaeSPhilippe Mathieu-Daudé { 621cceedd7SDavid Hildenbrand hwaddr paddr; 63a41d3aaeSPhilippe Mathieu-Daudé 6430e76638SPhilippe Mathieu-Daudé if (cpu->cc->sysemu_ops->get_phys_page_attrs_debug) { 6530e76638SPhilippe Mathieu-Daudé paddr = cpu->cc->sysemu_ops->get_phys_page_attrs_debug(cpu, addr, 6630e76638SPhilippe Mathieu-Daudé attrs); 671cceedd7SDavid Hildenbrand } else { 68a41d3aaeSPhilippe Mathieu-Daudé /* Fallback for CPUs which don't implement the _attrs_ hook */ 69a41d3aaeSPhilippe Mathieu-Daudé *attrs = MEMTXATTRS_UNSPECIFIED; 7030e76638SPhilippe Mathieu-Daudé paddr = cpu->cc->sysemu_ops->get_phys_page_debug(cpu, addr); 711cceedd7SDavid Hildenbrand } 721cceedd7SDavid Hildenbrand /* Indicate that this is a debug access. */ 731cceedd7SDavid Hildenbrand attrs->debug = 1; 741cceedd7SDavid Hildenbrand return paddr; 75a41d3aaeSPhilippe Mathieu-Daudé } 76a41d3aaeSPhilippe Mathieu-Daudé 77a41d3aaeSPhilippe Mathieu-Daudé hwaddr cpu_get_phys_page_debug(CPUState *cpu, vaddr addr) 78a41d3aaeSPhilippe Mathieu-Daudé { 79a41d3aaeSPhilippe Mathieu-Daudé MemTxAttrs attrs = {}; 80a41d3aaeSPhilippe Mathieu-Daudé 81a41d3aaeSPhilippe Mathieu-Daudé return cpu_get_phys_page_attrs_debug(cpu, addr, &attrs); 82a41d3aaeSPhilippe Mathieu-Daudé } 83a41d3aaeSPhilippe Mathieu-Daudé 84a41d3aaeSPhilippe Mathieu-Daudé int cpu_asidx_from_attrs(CPUState *cpu, MemTxAttrs attrs) 85a41d3aaeSPhilippe Mathieu-Daudé { 86a41d3aaeSPhilippe Mathieu-Daudé int ret = 0; 87a41d3aaeSPhilippe Mathieu-Daudé 88b404ca37SAlex Bennée if (cpu->cc->sysemu_ops->asidx_from_attrs) { 89b404ca37SAlex Bennée ret = cpu->cc->sysemu_ops->asidx_from_attrs(cpu, attrs); 90a41d3aaeSPhilippe Mathieu-Daudé assert(ret < cpu->num_ases && ret >= 0); 91a41d3aaeSPhilippe Mathieu-Daudé } 92a41d3aaeSPhilippe Mathieu-Daudé return ret; 93a41d3aaeSPhilippe Mathieu-Daudé } 94a41d3aaeSPhilippe Mathieu-Daudé 955ef2d5a4SPhilippe Mathieu-Daudé int cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cpu, 965ef2d5a4SPhilippe Mathieu-Daudé void *opaque) 975ef2d5a4SPhilippe Mathieu-Daudé { 9830e76638SPhilippe Mathieu-Daudé if (!cpu->cc->sysemu_ops->write_elf32_qemunote) { 995ef2d5a4SPhilippe Mathieu-Daudé return 0; 1005ef2d5a4SPhilippe Mathieu-Daudé } 10130e76638SPhilippe Mathieu-Daudé return (*cpu->cc->sysemu_ops->write_elf32_qemunote)(f, cpu, opaque); 1025ef2d5a4SPhilippe Mathieu-Daudé } 1035ef2d5a4SPhilippe Mathieu-Daudé 1045ef2d5a4SPhilippe Mathieu-Daudé int cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cpu, 1055ef2d5a4SPhilippe Mathieu-Daudé int cpuid, void *opaque) 1065ef2d5a4SPhilippe Mathieu-Daudé { 10730e76638SPhilippe Mathieu-Daudé if (!cpu->cc->sysemu_ops->write_elf32_note) { 1085ef2d5a4SPhilippe Mathieu-Daudé return -1; 1095ef2d5a4SPhilippe Mathieu-Daudé } 11030e76638SPhilippe Mathieu-Daudé return (*cpu->cc->sysemu_ops->write_elf32_note)(f, cpu, cpuid, opaque); 1115ef2d5a4SPhilippe Mathieu-Daudé } 1125ef2d5a4SPhilippe Mathieu-Daudé 1135ef2d5a4SPhilippe Mathieu-Daudé int cpu_write_elf64_qemunote(WriteCoreDumpFunction f, CPUState *cpu, 1145ef2d5a4SPhilippe Mathieu-Daudé void *opaque) 1155ef2d5a4SPhilippe Mathieu-Daudé { 11630e76638SPhilippe Mathieu-Daudé if (!cpu->cc->sysemu_ops->write_elf64_qemunote) { 1175ef2d5a4SPhilippe Mathieu-Daudé return 0; 1185ef2d5a4SPhilippe Mathieu-Daudé } 11930e76638SPhilippe Mathieu-Daudé return (*cpu->cc->sysemu_ops->write_elf64_qemunote)(f, cpu, opaque); 1205ef2d5a4SPhilippe Mathieu-Daudé } 1215ef2d5a4SPhilippe Mathieu-Daudé 1225ef2d5a4SPhilippe Mathieu-Daudé int cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cpu, 1235ef2d5a4SPhilippe Mathieu-Daudé int cpuid, void *opaque) 1245ef2d5a4SPhilippe Mathieu-Daudé { 12530e76638SPhilippe Mathieu-Daudé if (!cpu->cc->sysemu_ops->write_elf64_note) { 1265ef2d5a4SPhilippe Mathieu-Daudé return -1; 1275ef2d5a4SPhilippe Mathieu-Daudé } 12830e76638SPhilippe Mathieu-Daudé return (*cpu->cc->sysemu_ops->write_elf64_note)(f, cpu, cpuid, opaque); 1295ef2d5a4SPhilippe Mathieu-Daudé } 1305ef2d5a4SPhilippe Mathieu-Daudé 131cdba7e2fSPhilippe Mathieu-Daudé bool cpu_virtio_is_big_endian(CPUState *cpu) 132cdba7e2fSPhilippe Mathieu-Daudé { 13330e76638SPhilippe Mathieu-Daudé if (cpu->cc->sysemu_ops->virtio_is_big_endian) { 13430e76638SPhilippe Mathieu-Daudé return cpu->cc->sysemu_ops->virtio_is_big_endian(cpu); 135cdba7e2fSPhilippe Mathieu-Daudé } 136cdba7e2fSPhilippe Mathieu-Daudé return target_words_bigendian(); 137cdba7e2fSPhilippe Mathieu-Daudé } 138cdba7e2fSPhilippe Mathieu-Daudé 139df4fd7d5SPhilippe Mathieu-Daudé GuestPanicInformation *cpu_get_crash_info(CPUState *cpu) 140df4fd7d5SPhilippe Mathieu-Daudé { 141df4fd7d5SPhilippe Mathieu-Daudé GuestPanicInformation *res = NULL; 142df4fd7d5SPhilippe Mathieu-Daudé 14330e76638SPhilippe Mathieu-Daudé if (cpu->cc->sysemu_ops->get_crash_info) { 14430e76638SPhilippe Mathieu-Daudé res = cpu->cc->sysemu_ops->get_crash_info(cpu); 145df4fd7d5SPhilippe Mathieu-Daudé } 146df4fd7d5SPhilippe Mathieu-Daudé return res; 147df4fd7d5SPhilippe Mathieu-Daudé } 148e3a575f5SPhilippe Mathieu-Daudé 149e3a575f5SPhilippe Mathieu-Daudé static const Property cpu_system_props[] = { 150e3a575f5SPhilippe Mathieu-Daudé /* 151e3a575f5SPhilippe Mathieu-Daudé * Create a memory property for system CPU object, so users can 152e3a575f5SPhilippe Mathieu-Daudé * wire up its memory. The default if no link is set up is to use 153e3a575f5SPhilippe Mathieu-Daudé * the system address space. 154e3a575f5SPhilippe Mathieu-Daudé */ 155e3a575f5SPhilippe Mathieu-Daudé DEFINE_PROP_LINK("memory", CPUState, memory, TYPE_MEMORY_REGION, 156e3a575f5SPhilippe Mathieu-Daudé MemoryRegion *), 157e3a575f5SPhilippe Mathieu-Daudé }; 158e3a575f5SPhilippe Mathieu-Daudé 159e3a575f5SPhilippe Mathieu-Daudé static bool cpu_get_start_powered_off(Object *obj, Error **errp) 160e3a575f5SPhilippe Mathieu-Daudé { 161e3a575f5SPhilippe Mathieu-Daudé CPUState *cpu = CPU(obj); 162e3a575f5SPhilippe Mathieu-Daudé return cpu->start_powered_off; 163e3a575f5SPhilippe Mathieu-Daudé } 164e3a575f5SPhilippe Mathieu-Daudé 165e3a575f5SPhilippe Mathieu-Daudé static void cpu_set_start_powered_off(Object *obj, bool value, Error **errp) 166e3a575f5SPhilippe Mathieu-Daudé { 167e3a575f5SPhilippe Mathieu-Daudé CPUState *cpu = CPU(obj); 168e3a575f5SPhilippe Mathieu-Daudé cpu->start_powered_off = value; 169e3a575f5SPhilippe Mathieu-Daudé } 170e3a575f5SPhilippe Mathieu-Daudé 171e3a575f5SPhilippe Mathieu-Daudé void cpu_class_init_props(DeviceClass *dc) 172e3a575f5SPhilippe Mathieu-Daudé { 173e3a575f5SPhilippe Mathieu-Daudé ObjectClass *oc = OBJECT_CLASS(dc); 174e3a575f5SPhilippe Mathieu-Daudé 175e3a575f5SPhilippe Mathieu-Daudé /* 176e3a575f5SPhilippe Mathieu-Daudé * We can't use DEFINE_PROP_BOOL in the Property array for this 177e3a575f5SPhilippe Mathieu-Daudé * property, because we want this to be settable after realize. 178e3a575f5SPhilippe Mathieu-Daudé */ 179e3a575f5SPhilippe Mathieu-Daudé object_class_property_add_bool(oc, "start-powered-off", 180e3a575f5SPhilippe Mathieu-Daudé cpu_get_start_powered_off, 181e3a575f5SPhilippe Mathieu-Daudé cpu_set_start_powered_off); 182e3a575f5SPhilippe Mathieu-Daudé 183e3a575f5SPhilippe Mathieu-Daudé device_class_set_props(dc, cpu_system_props); 184e3a575f5SPhilippe Mathieu-Daudé } 185a86cf967SPhilippe Mathieu-Daudé 186*d0a4ccaeSPhilippe Mathieu-Daudé void cpu_exec_class_post_init(CPUClass *cc) 187*d0a4ccaeSPhilippe Mathieu-Daudé { 188*d0a4ccaeSPhilippe Mathieu-Daudé /* Check mandatory SysemuCPUOps handlers */ 189*d0a4ccaeSPhilippe Mathieu-Daudé g_assert(cc->sysemu_ops->has_work); 190*d0a4ccaeSPhilippe Mathieu-Daudé } 191*d0a4ccaeSPhilippe Mathieu-Daudé 192a86cf967SPhilippe Mathieu-Daudé void cpu_exec_initfn(CPUState *cpu) 193a86cf967SPhilippe Mathieu-Daudé { 194a86cf967SPhilippe Mathieu-Daudé cpu->memory = get_system_memory(); 195a86cf967SPhilippe Mathieu-Daudé object_ref(OBJECT(cpu->memory)); 196a86cf967SPhilippe Mathieu-Daudé } 197ca05578fSPhilippe Mathieu-Daudé 198ca05578fSPhilippe Mathieu-Daudé static int cpu_common_post_load(void *opaque, int version_id) 199ca05578fSPhilippe Mathieu-Daudé { 200ca05578fSPhilippe Mathieu-Daudé if (tcg_enabled()) { 201ca05578fSPhilippe Mathieu-Daudé CPUState *cpu = opaque; 202ca05578fSPhilippe Mathieu-Daudé 203ca05578fSPhilippe Mathieu-Daudé /* 204ca05578fSPhilippe Mathieu-Daudé * 0x01 was CPU_INTERRUPT_EXIT. This line can be removed when the 205ca05578fSPhilippe Mathieu-Daudé * version_id is increased. 206ca05578fSPhilippe Mathieu-Daudé */ 207ca05578fSPhilippe Mathieu-Daudé cpu->interrupt_request &= ~0x01; 208ca05578fSPhilippe Mathieu-Daudé 209ca05578fSPhilippe Mathieu-Daudé tlb_flush(cpu); 210ca05578fSPhilippe Mathieu-Daudé 211ca05578fSPhilippe Mathieu-Daudé /* 212ca05578fSPhilippe Mathieu-Daudé * loadvm has just updated the content of RAM, bypassing the 213ca05578fSPhilippe Mathieu-Daudé * usual mechanisms that ensure we flush TBs for writes to 214ca05578fSPhilippe Mathieu-Daudé * memory we've translated code from. So we must flush all TBs, 215ca05578fSPhilippe Mathieu-Daudé * which will now be stale. 216ca05578fSPhilippe Mathieu-Daudé */ 217ca05578fSPhilippe Mathieu-Daudé tb_flush(cpu); 218ca05578fSPhilippe Mathieu-Daudé } 219ca05578fSPhilippe Mathieu-Daudé 220ca05578fSPhilippe Mathieu-Daudé return 0; 221ca05578fSPhilippe Mathieu-Daudé } 222ca05578fSPhilippe Mathieu-Daudé 223ca05578fSPhilippe Mathieu-Daudé static int cpu_common_pre_load(void *opaque) 224ca05578fSPhilippe Mathieu-Daudé { 225ca05578fSPhilippe Mathieu-Daudé CPUState *cpu = opaque; 226ca05578fSPhilippe Mathieu-Daudé 227ca05578fSPhilippe Mathieu-Daudé cpu->exception_index = -1; 228ca05578fSPhilippe Mathieu-Daudé 229ca05578fSPhilippe Mathieu-Daudé return 0; 230ca05578fSPhilippe Mathieu-Daudé } 231ca05578fSPhilippe Mathieu-Daudé 232ca05578fSPhilippe Mathieu-Daudé static bool cpu_common_exception_index_needed(void *opaque) 233ca05578fSPhilippe Mathieu-Daudé { 234ca05578fSPhilippe Mathieu-Daudé CPUState *cpu = opaque; 235ca05578fSPhilippe Mathieu-Daudé 236ca05578fSPhilippe Mathieu-Daudé return tcg_enabled() && cpu->exception_index != -1; 237ca05578fSPhilippe Mathieu-Daudé } 238ca05578fSPhilippe Mathieu-Daudé 239ca05578fSPhilippe Mathieu-Daudé static const VMStateDescription vmstate_cpu_common_exception_index = { 240ca05578fSPhilippe Mathieu-Daudé .name = "cpu_common/exception_index", 241ca05578fSPhilippe Mathieu-Daudé .version_id = 1, 242ca05578fSPhilippe Mathieu-Daudé .minimum_version_id = 1, 243ca05578fSPhilippe Mathieu-Daudé .needed = cpu_common_exception_index_needed, 244ca05578fSPhilippe Mathieu-Daudé .fields = (const VMStateField[]) { 245ca05578fSPhilippe Mathieu-Daudé VMSTATE_INT32(exception_index, CPUState), 246ca05578fSPhilippe Mathieu-Daudé VMSTATE_END_OF_LIST() 247ca05578fSPhilippe Mathieu-Daudé } 248ca05578fSPhilippe Mathieu-Daudé }; 249ca05578fSPhilippe Mathieu-Daudé 250ca05578fSPhilippe Mathieu-Daudé static bool cpu_common_crash_occurred_needed(void *opaque) 251ca05578fSPhilippe Mathieu-Daudé { 252ca05578fSPhilippe Mathieu-Daudé CPUState *cpu = opaque; 253ca05578fSPhilippe Mathieu-Daudé 254ca05578fSPhilippe Mathieu-Daudé return cpu->crash_occurred; 255ca05578fSPhilippe Mathieu-Daudé } 256ca05578fSPhilippe Mathieu-Daudé 257ca05578fSPhilippe Mathieu-Daudé static const VMStateDescription vmstate_cpu_common_crash_occurred = { 258ca05578fSPhilippe Mathieu-Daudé .name = "cpu_common/crash_occurred", 259ca05578fSPhilippe Mathieu-Daudé .version_id = 1, 260ca05578fSPhilippe Mathieu-Daudé .minimum_version_id = 1, 261ca05578fSPhilippe Mathieu-Daudé .needed = cpu_common_crash_occurred_needed, 262ca05578fSPhilippe Mathieu-Daudé .fields = (const VMStateField[]) { 263ca05578fSPhilippe Mathieu-Daudé VMSTATE_BOOL(crash_occurred, CPUState), 264ca05578fSPhilippe Mathieu-Daudé VMSTATE_END_OF_LIST() 265ca05578fSPhilippe Mathieu-Daudé } 266ca05578fSPhilippe Mathieu-Daudé }; 267ca05578fSPhilippe Mathieu-Daudé 268ca05578fSPhilippe Mathieu-Daudé const VMStateDescription vmstate_cpu_common = { 269ca05578fSPhilippe Mathieu-Daudé .name = "cpu_common", 270ca05578fSPhilippe Mathieu-Daudé .version_id = 1, 271ca05578fSPhilippe Mathieu-Daudé .minimum_version_id = 1, 272ca05578fSPhilippe Mathieu-Daudé .pre_load = cpu_common_pre_load, 273ca05578fSPhilippe Mathieu-Daudé .post_load = cpu_common_post_load, 274ca05578fSPhilippe Mathieu-Daudé .fields = (const VMStateField[]) { 275ca05578fSPhilippe Mathieu-Daudé VMSTATE_UINT32(halted, CPUState), 276ca05578fSPhilippe Mathieu-Daudé VMSTATE_UINT32(interrupt_request, CPUState), 277ca05578fSPhilippe Mathieu-Daudé VMSTATE_END_OF_LIST() 278ca05578fSPhilippe Mathieu-Daudé }, 279ca05578fSPhilippe Mathieu-Daudé .subsections = (const VMStateDescription * const []) { 280ca05578fSPhilippe Mathieu-Daudé &vmstate_cpu_common_exception_index, 281ca05578fSPhilippe Mathieu-Daudé &vmstate_cpu_common_crash_occurred, 282ca05578fSPhilippe Mathieu-Daudé NULL 283ca05578fSPhilippe Mathieu-Daudé } 284ca05578fSPhilippe Mathieu-Daudé }; 285ca05578fSPhilippe Mathieu-Daudé 286ca05578fSPhilippe Mathieu-Daudé void cpu_vmstate_register(CPUState *cpu) 287ca05578fSPhilippe Mathieu-Daudé { 288ca05578fSPhilippe Mathieu-Daudé if (qdev_get_vmsd(DEVICE(cpu)) == NULL) { 289ca05578fSPhilippe Mathieu-Daudé vmstate_register(NULL, cpu->cpu_index, &vmstate_cpu_common, cpu); 290ca05578fSPhilippe Mathieu-Daudé } 291ca05578fSPhilippe Mathieu-Daudé if (cpu->cc->sysemu_ops->legacy_vmsd != NULL) { 292ca05578fSPhilippe Mathieu-Daudé vmstate_register(NULL, cpu->cpu_index, 293ca05578fSPhilippe Mathieu-Daudé cpu->cc->sysemu_ops->legacy_vmsd, cpu); 294ca05578fSPhilippe Mathieu-Daudé } 295ca05578fSPhilippe Mathieu-Daudé } 296ca05578fSPhilippe Mathieu-Daudé 297ca05578fSPhilippe Mathieu-Daudé void cpu_vmstate_unregister(CPUState *cpu) 298ca05578fSPhilippe Mathieu-Daudé { 29930e76638SPhilippe Mathieu-Daudé if (cpu->cc->sysemu_ops->legacy_vmsd != NULL) { 30030e76638SPhilippe Mathieu-Daudé vmstate_unregister(NULL, cpu->cc->sysemu_ops->legacy_vmsd, cpu); 301ca05578fSPhilippe Mathieu-Daudé } 302ca05578fSPhilippe Mathieu-Daudé if (qdev_get_vmsd(DEVICE(cpu)) == NULL) { 303ca05578fSPhilippe Mathieu-Daudé vmstate_unregister(NULL, &vmstate_cpu_common, cpu); 304ca05578fSPhilippe Mathieu-Daudé } 305ca05578fSPhilippe Mathieu-Daudé } 306