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é 34*8f8dbe04SPhilippe Mathieu-Daudé bool cpu_has_work(CPUState *cpu) 35*8f8dbe04SPhilippe Mathieu-Daudé { 36*8f8dbe04SPhilippe Mathieu-Daudé g_assert(cpu->cc->has_work); 37*8f8dbe04SPhilippe Mathieu-Daudé return cpu->cc->has_work(cpu); 38*8f8dbe04SPhilippe Mathieu-Daudé } 39*8f8dbe04SPhilippe Mathieu-Daudé 4077ba5d50SPhilippe Mathieu-Daudé bool cpu_paging_enabled(const CPUState *cpu) 4177ba5d50SPhilippe Mathieu-Daudé { 4230e76638SPhilippe Mathieu-Daudé if (cpu->cc->sysemu_ops->get_paging_enabled) { 4330e76638SPhilippe Mathieu-Daudé return cpu->cc->sysemu_ops->get_paging_enabled(cpu); 4477ba5d50SPhilippe Mathieu-Daudé } 4577ba5d50SPhilippe Mathieu-Daudé 4677ba5d50SPhilippe Mathieu-Daudé return false; 4777ba5d50SPhilippe Mathieu-Daudé } 4877ba5d50SPhilippe Mathieu-Daudé 498a5b974bSMarc-André Lureau bool cpu_get_memory_mapping(CPUState *cpu, MemoryMappingList *list, 5065c57115SPhilippe Mathieu-Daudé Error **errp) 5165c57115SPhilippe Mathieu-Daudé { 5230e76638SPhilippe Mathieu-Daudé if (cpu->cc->sysemu_ops->get_memory_mapping) { 5330e76638SPhilippe Mathieu-Daudé return cpu->cc->sysemu_ops->get_memory_mapping(cpu, list, errp); 5465c57115SPhilippe Mathieu-Daudé } 5565c57115SPhilippe Mathieu-Daudé 5665c57115SPhilippe Mathieu-Daudé error_setg(errp, "Obtaining memory mappings is unsupported on this CPU."); 578a5b974bSMarc-André Lureau return false; 5865c57115SPhilippe Mathieu-Daudé } 5965c57115SPhilippe Mathieu-Daudé 60a41d3aaeSPhilippe Mathieu-Daudé hwaddr cpu_get_phys_page_attrs_debug(CPUState *cpu, vaddr addr, 61a41d3aaeSPhilippe Mathieu-Daudé MemTxAttrs *attrs) 62a41d3aaeSPhilippe Mathieu-Daudé { 631cceedd7SDavid Hildenbrand hwaddr paddr; 64a41d3aaeSPhilippe Mathieu-Daudé 6530e76638SPhilippe Mathieu-Daudé if (cpu->cc->sysemu_ops->get_phys_page_attrs_debug) { 6630e76638SPhilippe Mathieu-Daudé paddr = cpu->cc->sysemu_ops->get_phys_page_attrs_debug(cpu, addr, 6730e76638SPhilippe Mathieu-Daudé attrs); 681cceedd7SDavid Hildenbrand } else { 69a41d3aaeSPhilippe Mathieu-Daudé /* Fallback for CPUs which don't implement the _attrs_ hook */ 70a41d3aaeSPhilippe Mathieu-Daudé *attrs = MEMTXATTRS_UNSPECIFIED; 7130e76638SPhilippe Mathieu-Daudé paddr = cpu->cc->sysemu_ops->get_phys_page_debug(cpu, addr); 721cceedd7SDavid Hildenbrand } 731cceedd7SDavid Hildenbrand /* Indicate that this is a debug access. */ 741cceedd7SDavid Hildenbrand attrs->debug = 1; 751cceedd7SDavid Hildenbrand return paddr; 76a41d3aaeSPhilippe Mathieu-Daudé } 77a41d3aaeSPhilippe Mathieu-Daudé 78a41d3aaeSPhilippe Mathieu-Daudé hwaddr cpu_get_phys_page_debug(CPUState *cpu, vaddr addr) 79a41d3aaeSPhilippe Mathieu-Daudé { 80a41d3aaeSPhilippe Mathieu-Daudé MemTxAttrs attrs = {}; 81a41d3aaeSPhilippe Mathieu-Daudé 82a41d3aaeSPhilippe Mathieu-Daudé return cpu_get_phys_page_attrs_debug(cpu, addr, &attrs); 83a41d3aaeSPhilippe Mathieu-Daudé } 84a41d3aaeSPhilippe Mathieu-Daudé 85a41d3aaeSPhilippe Mathieu-Daudé int cpu_asidx_from_attrs(CPUState *cpu, MemTxAttrs attrs) 86a41d3aaeSPhilippe Mathieu-Daudé { 87a41d3aaeSPhilippe Mathieu-Daudé int ret = 0; 88a41d3aaeSPhilippe Mathieu-Daudé 89b404ca37SAlex Bennée if (cpu->cc->sysemu_ops->asidx_from_attrs) { 90b404ca37SAlex Bennée ret = cpu->cc->sysemu_ops->asidx_from_attrs(cpu, attrs); 91a41d3aaeSPhilippe Mathieu-Daudé assert(ret < cpu->num_ases && ret >= 0); 92a41d3aaeSPhilippe Mathieu-Daudé } 93a41d3aaeSPhilippe Mathieu-Daudé return ret; 94a41d3aaeSPhilippe Mathieu-Daudé } 95a41d3aaeSPhilippe Mathieu-Daudé 965ef2d5a4SPhilippe Mathieu-Daudé int cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cpu, 975ef2d5a4SPhilippe Mathieu-Daudé void *opaque) 985ef2d5a4SPhilippe Mathieu-Daudé { 9930e76638SPhilippe Mathieu-Daudé if (!cpu->cc->sysemu_ops->write_elf32_qemunote) { 1005ef2d5a4SPhilippe Mathieu-Daudé return 0; 1015ef2d5a4SPhilippe Mathieu-Daudé } 10230e76638SPhilippe Mathieu-Daudé return (*cpu->cc->sysemu_ops->write_elf32_qemunote)(f, cpu, opaque); 1035ef2d5a4SPhilippe Mathieu-Daudé } 1045ef2d5a4SPhilippe Mathieu-Daudé 1055ef2d5a4SPhilippe Mathieu-Daudé int cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cpu, 1065ef2d5a4SPhilippe Mathieu-Daudé int cpuid, void *opaque) 1075ef2d5a4SPhilippe Mathieu-Daudé { 10830e76638SPhilippe Mathieu-Daudé if (!cpu->cc->sysemu_ops->write_elf32_note) { 1095ef2d5a4SPhilippe Mathieu-Daudé return -1; 1105ef2d5a4SPhilippe Mathieu-Daudé } 11130e76638SPhilippe Mathieu-Daudé return (*cpu->cc->sysemu_ops->write_elf32_note)(f, cpu, cpuid, opaque); 1125ef2d5a4SPhilippe Mathieu-Daudé } 1135ef2d5a4SPhilippe Mathieu-Daudé 1145ef2d5a4SPhilippe Mathieu-Daudé int cpu_write_elf64_qemunote(WriteCoreDumpFunction f, CPUState *cpu, 1155ef2d5a4SPhilippe Mathieu-Daudé void *opaque) 1165ef2d5a4SPhilippe Mathieu-Daudé { 11730e76638SPhilippe Mathieu-Daudé if (!cpu->cc->sysemu_ops->write_elf64_qemunote) { 1185ef2d5a4SPhilippe Mathieu-Daudé return 0; 1195ef2d5a4SPhilippe Mathieu-Daudé } 12030e76638SPhilippe Mathieu-Daudé return (*cpu->cc->sysemu_ops->write_elf64_qemunote)(f, cpu, opaque); 1215ef2d5a4SPhilippe Mathieu-Daudé } 1225ef2d5a4SPhilippe Mathieu-Daudé 1235ef2d5a4SPhilippe Mathieu-Daudé int cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cpu, 1245ef2d5a4SPhilippe Mathieu-Daudé int cpuid, void *opaque) 1255ef2d5a4SPhilippe Mathieu-Daudé { 12630e76638SPhilippe Mathieu-Daudé if (!cpu->cc->sysemu_ops->write_elf64_note) { 1275ef2d5a4SPhilippe Mathieu-Daudé return -1; 1285ef2d5a4SPhilippe Mathieu-Daudé } 12930e76638SPhilippe Mathieu-Daudé return (*cpu->cc->sysemu_ops->write_elf64_note)(f, cpu, cpuid, opaque); 1305ef2d5a4SPhilippe Mathieu-Daudé } 1315ef2d5a4SPhilippe Mathieu-Daudé 132cdba7e2fSPhilippe Mathieu-Daudé bool cpu_virtio_is_big_endian(CPUState *cpu) 133cdba7e2fSPhilippe Mathieu-Daudé { 13430e76638SPhilippe Mathieu-Daudé if (cpu->cc->sysemu_ops->virtio_is_big_endian) { 13530e76638SPhilippe Mathieu-Daudé return cpu->cc->sysemu_ops->virtio_is_big_endian(cpu); 136cdba7e2fSPhilippe Mathieu-Daudé } 137cdba7e2fSPhilippe Mathieu-Daudé return target_words_bigendian(); 138cdba7e2fSPhilippe Mathieu-Daudé } 139cdba7e2fSPhilippe Mathieu-Daudé 140df4fd7d5SPhilippe Mathieu-Daudé GuestPanicInformation *cpu_get_crash_info(CPUState *cpu) 141df4fd7d5SPhilippe Mathieu-Daudé { 142df4fd7d5SPhilippe Mathieu-Daudé GuestPanicInformation *res = NULL; 143df4fd7d5SPhilippe Mathieu-Daudé 14430e76638SPhilippe Mathieu-Daudé if (cpu->cc->sysemu_ops->get_crash_info) { 14530e76638SPhilippe Mathieu-Daudé res = cpu->cc->sysemu_ops->get_crash_info(cpu); 146df4fd7d5SPhilippe Mathieu-Daudé } 147df4fd7d5SPhilippe Mathieu-Daudé return res; 148df4fd7d5SPhilippe Mathieu-Daudé } 149e3a575f5SPhilippe Mathieu-Daudé 150e3a575f5SPhilippe Mathieu-Daudé static const Property cpu_system_props[] = { 151e3a575f5SPhilippe Mathieu-Daudé /* 152e3a575f5SPhilippe Mathieu-Daudé * Create a memory property for system CPU object, so users can 153e3a575f5SPhilippe Mathieu-Daudé * wire up its memory. The default if no link is set up is to use 154e3a575f5SPhilippe Mathieu-Daudé * the system address space. 155e3a575f5SPhilippe Mathieu-Daudé */ 156e3a575f5SPhilippe Mathieu-Daudé DEFINE_PROP_LINK("memory", CPUState, memory, TYPE_MEMORY_REGION, 157e3a575f5SPhilippe Mathieu-Daudé MemoryRegion *), 158e3a575f5SPhilippe Mathieu-Daudé }; 159e3a575f5SPhilippe Mathieu-Daudé 160e3a575f5SPhilippe Mathieu-Daudé static bool cpu_get_start_powered_off(Object *obj, Error **errp) 161e3a575f5SPhilippe Mathieu-Daudé { 162e3a575f5SPhilippe Mathieu-Daudé CPUState *cpu = CPU(obj); 163e3a575f5SPhilippe Mathieu-Daudé return cpu->start_powered_off; 164e3a575f5SPhilippe Mathieu-Daudé } 165e3a575f5SPhilippe Mathieu-Daudé 166e3a575f5SPhilippe Mathieu-Daudé static void cpu_set_start_powered_off(Object *obj, bool value, Error **errp) 167e3a575f5SPhilippe Mathieu-Daudé { 168e3a575f5SPhilippe Mathieu-Daudé CPUState *cpu = CPU(obj); 169e3a575f5SPhilippe Mathieu-Daudé cpu->start_powered_off = value; 170e3a575f5SPhilippe Mathieu-Daudé } 171e3a575f5SPhilippe Mathieu-Daudé 172e3a575f5SPhilippe Mathieu-Daudé void cpu_class_init_props(DeviceClass *dc) 173e3a575f5SPhilippe Mathieu-Daudé { 174e3a575f5SPhilippe Mathieu-Daudé ObjectClass *oc = OBJECT_CLASS(dc); 175e3a575f5SPhilippe Mathieu-Daudé 176e3a575f5SPhilippe Mathieu-Daudé /* 177e3a575f5SPhilippe Mathieu-Daudé * We can't use DEFINE_PROP_BOOL in the Property array for this 178e3a575f5SPhilippe Mathieu-Daudé * property, because we want this to be settable after realize. 179e3a575f5SPhilippe Mathieu-Daudé */ 180e3a575f5SPhilippe Mathieu-Daudé object_class_property_add_bool(oc, "start-powered-off", 181e3a575f5SPhilippe Mathieu-Daudé cpu_get_start_powered_off, 182e3a575f5SPhilippe Mathieu-Daudé cpu_set_start_powered_off); 183e3a575f5SPhilippe Mathieu-Daudé 184e3a575f5SPhilippe Mathieu-Daudé device_class_set_props(dc, cpu_system_props); 185e3a575f5SPhilippe Mathieu-Daudé } 186a86cf967SPhilippe Mathieu-Daudé 187a86cf967SPhilippe Mathieu-Daudé void cpu_exec_initfn(CPUState *cpu) 188a86cf967SPhilippe Mathieu-Daudé { 189a86cf967SPhilippe Mathieu-Daudé cpu->memory = get_system_memory(); 190a86cf967SPhilippe Mathieu-Daudé object_ref(OBJECT(cpu->memory)); 191a86cf967SPhilippe Mathieu-Daudé } 192ca05578fSPhilippe Mathieu-Daudé 193ca05578fSPhilippe Mathieu-Daudé static int cpu_common_post_load(void *opaque, int version_id) 194ca05578fSPhilippe Mathieu-Daudé { 195ca05578fSPhilippe Mathieu-Daudé if (tcg_enabled()) { 196ca05578fSPhilippe Mathieu-Daudé CPUState *cpu = opaque; 197ca05578fSPhilippe Mathieu-Daudé 198ca05578fSPhilippe Mathieu-Daudé /* 199ca05578fSPhilippe Mathieu-Daudé * 0x01 was CPU_INTERRUPT_EXIT. This line can be removed when the 200ca05578fSPhilippe Mathieu-Daudé * version_id is increased. 201ca05578fSPhilippe Mathieu-Daudé */ 202ca05578fSPhilippe Mathieu-Daudé cpu->interrupt_request &= ~0x01; 203ca05578fSPhilippe Mathieu-Daudé 204ca05578fSPhilippe Mathieu-Daudé tlb_flush(cpu); 205ca05578fSPhilippe Mathieu-Daudé 206ca05578fSPhilippe Mathieu-Daudé /* 207ca05578fSPhilippe Mathieu-Daudé * loadvm has just updated the content of RAM, bypassing the 208ca05578fSPhilippe Mathieu-Daudé * usual mechanisms that ensure we flush TBs for writes to 209ca05578fSPhilippe Mathieu-Daudé * memory we've translated code from. So we must flush all TBs, 210ca05578fSPhilippe Mathieu-Daudé * which will now be stale. 211ca05578fSPhilippe Mathieu-Daudé */ 212ca05578fSPhilippe Mathieu-Daudé tb_flush(cpu); 213ca05578fSPhilippe Mathieu-Daudé } 214ca05578fSPhilippe Mathieu-Daudé 215ca05578fSPhilippe Mathieu-Daudé return 0; 216ca05578fSPhilippe Mathieu-Daudé } 217ca05578fSPhilippe Mathieu-Daudé 218ca05578fSPhilippe Mathieu-Daudé static int cpu_common_pre_load(void *opaque) 219ca05578fSPhilippe Mathieu-Daudé { 220ca05578fSPhilippe Mathieu-Daudé CPUState *cpu = opaque; 221ca05578fSPhilippe Mathieu-Daudé 222ca05578fSPhilippe Mathieu-Daudé cpu->exception_index = -1; 223ca05578fSPhilippe Mathieu-Daudé 224ca05578fSPhilippe Mathieu-Daudé return 0; 225ca05578fSPhilippe Mathieu-Daudé } 226ca05578fSPhilippe Mathieu-Daudé 227ca05578fSPhilippe Mathieu-Daudé static bool cpu_common_exception_index_needed(void *opaque) 228ca05578fSPhilippe Mathieu-Daudé { 229ca05578fSPhilippe Mathieu-Daudé CPUState *cpu = opaque; 230ca05578fSPhilippe Mathieu-Daudé 231ca05578fSPhilippe Mathieu-Daudé return tcg_enabled() && cpu->exception_index != -1; 232ca05578fSPhilippe Mathieu-Daudé } 233ca05578fSPhilippe Mathieu-Daudé 234ca05578fSPhilippe Mathieu-Daudé static const VMStateDescription vmstate_cpu_common_exception_index = { 235ca05578fSPhilippe Mathieu-Daudé .name = "cpu_common/exception_index", 236ca05578fSPhilippe Mathieu-Daudé .version_id = 1, 237ca05578fSPhilippe Mathieu-Daudé .minimum_version_id = 1, 238ca05578fSPhilippe Mathieu-Daudé .needed = cpu_common_exception_index_needed, 239ca05578fSPhilippe Mathieu-Daudé .fields = (const VMStateField[]) { 240ca05578fSPhilippe Mathieu-Daudé VMSTATE_INT32(exception_index, CPUState), 241ca05578fSPhilippe Mathieu-Daudé VMSTATE_END_OF_LIST() 242ca05578fSPhilippe Mathieu-Daudé } 243ca05578fSPhilippe Mathieu-Daudé }; 244ca05578fSPhilippe Mathieu-Daudé 245ca05578fSPhilippe Mathieu-Daudé static bool cpu_common_crash_occurred_needed(void *opaque) 246ca05578fSPhilippe Mathieu-Daudé { 247ca05578fSPhilippe Mathieu-Daudé CPUState *cpu = opaque; 248ca05578fSPhilippe Mathieu-Daudé 249ca05578fSPhilippe Mathieu-Daudé return cpu->crash_occurred; 250ca05578fSPhilippe Mathieu-Daudé } 251ca05578fSPhilippe Mathieu-Daudé 252ca05578fSPhilippe Mathieu-Daudé static const VMStateDescription vmstate_cpu_common_crash_occurred = { 253ca05578fSPhilippe Mathieu-Daudé .name = "cpu_common/crash_occurred", 254ca05578fSPhilippe Mathieu-Daudé .version_id = 1, 255ca05578fSPhilippe Mathieu-Daudé .minimum_version_id = 1, 256ca05578fSPhilippe Mathieu-Daudé .needed = cpu_common_crash_occurred_needed, 257ca05578fSPhilippe Mathieu-Daudé .fields = (const VMStateField[]) { 258ca05578fSPhilippe Mathieu-Daudé VMSTATE_BOOL(crash_occurred, CPUState), 259ca05578fSPhilippe Mathieu-Daudé VMSTATE_END_OF_LIST() 260ca05578fSPhilippe Mathieu-Daudé } 261ca05578fSPhilippe Mathieu-Daudé }; 262ca05578fSPhilippe Mathieu-Daudé 263ca05578fSPhilippe Mathieu-Daudé const VMStateDescription vmstate_cpu_common = { 264ca05578fSPhilippe Mathieu-Daudé .name = "cpu_common", 265ca05578fSPhilippe Mathieu-Daudé .version_id = 1, 266ca05578fSPhilippe Mathieu-Daudé .minimum_version_id = 1, 267ca05578fSPhilippe Mathieu-Daudé .pre_load = cpu_common_pre_load, 268ca05578fSPhilippe Mathieu-Daudé .post_load = cpu_common_post_load, 269ca05578fSPhilippe Mathieu-Daudé .fields = (const VMStateField[]) { 270ca05578fSPhilippe Mathieu-Daudé VMSTATE_UINT32(halted, CPUState), 271ca05578fSPhilippe Mathieu-Daudé VMSTATE_UINT32(interrupt_request, CPUState), 272ca05578fSPhilippe Mathieu-Daudé VMSTATE_END_OF_LIST() 273ca05578fSPhilippe Mathieu-Daudé }, 274ca05578fSPhilippe Mathieu-Daudé .subsections = (const VMStateDescription * const []) { 275ca05578fSPhilippe Mathieu-Daudé &vmstate_cpu_common_exception_index, 276ca05578fSPhilippe Mathieu-Daudé &vmstate_cpu_common_crash_occurred, 277ca05578fSPhilippe Mathieu-Daudé NULL 278ca05578fSPhilippe Mathieu-Daudé } 279ca05578fSPhilippe Mathieu-Daudé }; 280ca05578fSPhilippe Mathieu-Daudé 281ca05578fSPhilippe Mathieu-Daudé void cpu_vmstate_register(CPUState *cpu) 282ca05578fSPhilippe Mathieu-Daudé { 283ca05578fSPhilippe Mathieu-Daudé if (qdev_get_vmsd(DEVICE(cpu)) == NULL) { 284ca05578fSPhilippe Mathieu-Daudé vmstate_register(NULL, cpu->cpu_index, &vmstate_cpu_common, cpu); 285ca05578fSPhilippe Mathieu-Daudé } 286ca05578fSPhilippe Mathieu-Daudé if (cpu->cc->sysemu_ops->legacy_vmsd != NULL) { 287ca05578fSPhilippe Mathieu-Daudé vmstate_register(NULL, cpu->cpu_index, 288ca05578fSPhilippe Mathieu-Daudé cpu->cc->sysemu_ops->legacy_vmsd, cpu); 289ca05578fSPhilippe Mathieu-Daudé } 290ca05578fSPhilippe Mathieu-Daudé } 291ca05578fSPhilippe Mathieu-Daudé 292ca05578fSPhilippe Mathieu-Daudé void cpu_vmstate_unregister(CPUState *cpu) 293ca05578fSPhilippe Mathieu-Daudé { 29430e76638SPhilippe Mathieu-Daudé if (cpu->cc->sysemu_ops->legacy_vmsd != NULL) { 29530e76638SPhilippe Mathieu-Daudé vmstate_unregister(NULL, cpu->cc->sysemu_ops->legacy_vmsd, cpu); 296ca05578fSPhilippe Mathieu-Daudé } 297ca05578fSPhilippe Mathieu-Daudé if (qdev_get_vmsd(DEVICE(cpu)) == NULL) { 298ca05578fSPhilippe Mathieu-Daudé vmstate_unregister(NULL, &vmstate_cpu_common, cpu); 299ca05578fSPhilippe Mathieu-Daudé } 300ca05578fSPhilippe Mathieu-Daudé } 301