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" 24*ca05578fSPhilippe Mathieu-Daudé #include "exec/cputlb.h" 25e3a575f5SPhilippe Mathieu-Daudé #include "exec/memory.h" 26*ca05578fSPhilippe 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" 31*ca05578fSPhilippe Mathieu-Daudé #include "migration/vmstate.h" 32*ca05578fSPhilippe Mathieu-Daudé #include "system/tcg.h" 33df4fd7d5SPhilippe Mathieu-Daudé 3477ba5d50SPhilippe Mathieu-Daudé bool cpu_paging_enabled(const CPUState *cpu) 3577ba5d50SPhilippe Mathieu-Daudé { 3677ba5d50SPhilippe Mathieu-Daudé CPUClass *cc = CPU_GET_CLASS(cpu); 3777ba5d50SPhilippe Mathieu-Daudé 386bc0d6a0SPhilippe Mathieu-Daudé if (cc->sysemu_ops->get_paging_enabled) { 396bc0d6a0SPhilippe Mathieu-Daudé return cc->sysemu_ops->get_paging_enabled(cpu); 4077ba5d50SPhilippe Mathieu-Daudé } 4177ba5d50SPhilippe Mathieu-Daudé 4277ba5d50SPhilippe Mathieu-Daudé return false; 4377ba5d50SPhilippe Mathieu-Daudé } 4477ba5d50SPhilippe Mathieu-Daudé 458a5b974bSMarc-André Lureau bool cpu_get_memory_mapping(CPUState *cpu, MemoryMappingList *list, 4665c57115SPhilippe Mathieu-Daudé Error **errp) 4765c57115SPhilippe Mathieu-Daudé { 4865c57115SPhilippe Mathieu-Daudé CPUClass *cc = CPU_GET_CLASS(cpu); 4965c57115SPhilippe Mathieu-Daudé 502b60b62eSPhilippe Mathieu-Daudé if (cc->sysemu_ops->get_memory_mapping) { 518a5b974bSMarc-André Lureau return cc->sysemu_ops->get_memory_mapping(cpu, list, errp); 5265c57115SPhilippe Mathieu-Daudé } 5365c57115SPhilippe Mathieu-Daudé 5465c57115SPhilippe Mathieu-Daudé error_setg(errp, "Obtaining memory mappings is unsupported on this CPU."); 558a5b974bSMarc-André Lureau return false; 5665c57115SPhilippe Mathieu-Daudé } 5765c57115SPhilippe Mathieu-Daudé 58a41d3aaeSPhilippe Mathieu-Daudé hwaddr cpu_get_phys_page_attrs_debug(CPUState *cpu, vaddr addr, 59a41d3aaeSPhilippe Mathieu-Daudé MemTxAttrs *attrs) 60a41d3aaeSPhilippe Mathieu-Daudé { 61a41d3aaeSPhilippe Mathieu-Daudé CPUClass *cc = CPU_GET_CLASS(cpu); 621cceedd7SDavid Hildenbrand hwaddr paddr; 63a41d3aaeSPhilippe Mathieu-Daudé 6408928c6dSPhilippe Mathieu-Daudé if (cc->sysemu_ops->get_phys_page_attrs_debug) { 651cceedd7SDavid Hildenbrand paddr = cc->sysemu_ops->get_phys_page_attrs_debug(cpu, addr, attrs); 661cceedd7SDavid Hildenbrand } else { 67a41d3aaeSPhilippe Mathieu-Daudé /* Fallback for CPUs which don't implement the _attrs_ hook */ 68a41d3aaeSPhilippe Mathieu-Daudé *attrs = MEMTXATTRS_UNSPECIFIED; 691cceedd7SDavid Hildenbrand paddr = cc->sysemu_ops->get_phys_page_debug(cpu, addr); 701cceedd7SDavid Hildenbrand } 711cceedd7SDavid Hildenbrand /* Indicate that this is a debug access. */ 721cceedd7SDavid Hildenbrand attrs->debug = 1; 731cceedd7SDavid Hildenbrand return paddr; 74a41d3aaeSPhilippe Mathieu-Daudé } 75a41d3aaeSPhilippe Mathieu-Daudé 76a41d3aaeSPhilippe Mathieu-Daudé hwaddr cpu_get_phys_page_debug(CPUState *cpu, vaddr addr) 77a41d3aaeSPhilippe Mathieu-Daudé { 78a41d3aaeSPhilippe Mathieu-Daudé MemTxAttrs attrs = {}; 79a41d3aaeSPhilippe Mathieu-Daudé 80a41d3aaeSPhilippe Mathieu-Daudé return cpu_get_phys_page_attrs_debug(cpu, addr, &attrs); 81a41d3aaeSPhilippe Mathieu-Daudé } 82a41d3aaeSPhilippe Mathieu-Daudé 83a41d3aaeSPhilippe Mathieu-Daudé int cpu_asidx_from_attrs(CPUState *cpu, MemTxAttrs attrs) 84a41d3aaeSPhilippe Mathieu-Daudé { 85a41d3aaeSPhilippe Mathieu-Daudé int ret = 0; 86a41d3aaeSPhilippe Mathieu-Daudé 87b404ca37SAlex Bennée if (cpu->cc->sysemu_ops->asidx_from_attrs) { 88b404ca37SAlex Bennée ret = cpu->cc->sysemu_ops->asidx_from_attrs(cpu, attrs); 89a41d3aaeSPhilippe Mathieu-Daudé assert(ret < cpu->num_ases && ret >= 0); 90a41d3aaeSPhilippe Mathieu-Daudé } 91a41d3aaeSPhilippe Mathieu-Daudé return ret; 92a41d3aaeSPhilippe Mathieu-Daudé } 93a41d3aaeSPhilippe Mathieu-Daudé 945ef2d5a4SPhilippe Mathieu-Daudé int cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cpu, 955ef2d5a4SPhilippe Mathieu-Daudé void *opaque) 965ef2d5a4SPhilippe Mathieu-Daudé { 975ef2d5a4SPhilippe Mathieu-Daudé CPUClass *cc = CPU_GET_CLASS(cpu); 985ef2d5a4SPhilippe Mathieu-Daudé 99715e3c1aSPhilippe Mathieu-Daudé if (!cc->sysemu_ops->write_elf32_qemunote) { 1005ef2d5a4SPhilippe Mathieu-Daudé return 0; 1015ef2d5a4SPhilippe Mathieu-Daudé } 102715e3c1aSPhilippe Mathieu-Daudé return (*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é { 1085ef2d5a4SPhilippe Mathieu-Daudé CPUClass *cc = CPU_GET_CLASS(cpu); 1095ef2d5a4SPhilippe Mathieu-Daudé 110715e3c1aSPhilippe Mathieu-Daudé if (!cc->sysemu_ops->write_elf32_note) { 1115ef2d5a4SPhilippe Mathieu-Daudé return -1; 1125ef2d5a4SPhilippe Mathieu-Daudé } 113715e3c1aSPhilippe Mathieu-Daudé return (*cc->sysemu_ops->write_elf32_note)(f, cpu, cpuid, opaque); 1145ef2d5a4SPhilippe Mathieu-Daudé } 1155ef2d5a4SPhilippe Mathieu-Daudé 1165ef2d5a4SPhilippe Mathieu-Daudé int cpu_write_elf64_qemunote(WriteCoreDumpFunction f, CPUState *cpu, 1175ef2d5a4SPhilippe Mathieu-Daudé void *opaque) 1185ef2d5a4SPhilippe Mathieu-Daudé { 1195ef2d5a4SPhilippe Mathieu-Daudé CPUClass *cc = CPU_GET_CLASS(cpu); 1205ef2d5a4SPhilippe Mathieu-Daudé 121715e3c1aSPhilippe Mathieu-Daudé if (!cc->sysemu_ops->write_elf64_qemunote) { 1225ef2d5a4SPhilippe Mathieu-Daudé return 0; 1235ef2d5a4SPhilippe Mathieu-Daudé } 124715e3c1aSPhilippe Mathieu-Daudé return (*cc->sysemu_ops->write_elf64_qemunote)(f, cpu, opaque); 1255ef2d5a4SPhilippe Mathieu-Daudé } 1265ef2d5a4SPhilippe Mathieu-Daudé 1275ef2d5a4SPhilippe Mathieu-Daudé int cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cpu, 1285ef2d5a4SPhilippe Mathieu-Daudé int cpuid, void *opaque) 1295ef2d5a4SPhilippe Mathieu-Daudé { 1305ef2d5a4SPhilippe Mathieu-Daudé CPUClass *cc = CPU_GET_CLASS(cpu); 1315ef2d5a4SPhilippe Mathieu-Daudé 132715e3c1aSPhilippe Mathieu-Daudé if (!cc->sysemu_ops->write_elf64_note) { 1335ef2d5a4SPhilippe Mathieu-Daudé return -1; 1345ef2d5a4SPhilippe Mathieu-Daudé } 135715e3c1aSPhilippe Mathieu-Daudé return (*cc->sysemu_ops->write_elf64_note)(f, cpu, cpuid, opaque); 1365ef2d5a4SPhilippe Mathieu-Daudé } 1375ef2d5a4SPhilippe Mathieu-Daudé 138cdba7e2fSPhilippe Mathieu-Daudé bool cpu_virtio_is_big_endian(CPUState *cpu) 139cdba7e2fSPhilippe Mathieu-Daudé { 140cdba7e2fSPhilippe Mathieu-Daudé CPUClass *cc = CPU_GET_CLASS(cpu); 141cdba7e2fSPhilippe Mathieu-Daudé 142da383e02SPhilippe Mathieu-Daudé if (cc->sysemu_ops->virtio_is_big_endian) { 143da383e02SPhilippe Mathieu-Daudé return cc->sysemu_ops->virtio_is_big_endian(cpu); 144cdba7e2fSPhilippe Mathieu-Daudé } 145cdba7e2fSPhilippe Mathieu-Daudé return target_words_bigendian(); 146cdba7e2fSPhilippe Mathieu-Daudé } 147cdba7e2fSPhilippe Mathieu-Daudé 148df4fd7d5SPhilippe Mathieu-Daudé GuestPanicInformation *cpu_get_crash_info(CPUState *cpu) 149df4fd7d5SPhilippe Mathieu-Daudé { 150df4fd7d5SPhilippe Mathieu-Daudé CPUClass *cc = CPU_GET_CLASS(cpu); 151df4fd7d5SPhilippe Mathieu-Daudé GuestPanicInformation *res = NULL; 152df4fd7d5SPhilippe Mathieu-Daudé 15383ec01b6SPhilippe Mathieu-Daudé if (cc->sysemu_ops->get_crash_info) { 15483ec01b6SPhilippe Mathieu-Daudé res = cc->sysemu_ops->get_crash_info(cpu); 155df4fd7d5SPhilippe Mathieu-Daudé } 156df4fd7d5SPhilippe Mathieu-Daudé return res; 157df4fd7d5SPhilippe Mathieu-Daudé } 158e3a575f5SPhilippe Mathieu-Daudé 159e3a575f5SPhilippe Mathieu-Daudé static const Property cpu_system_props[] = { 160e3a575f5SPhilippe Mathieu-Daudé /* 161e3a575f5SPhilippe Mathieu-Daudé * Create a memory property for system CPU object, so users can 162e3a575f5SPhilippe Mathieu-Daudé * wire up its memory. The default if no link is set up is to use 163e3a575f5SPhilippe Mathieu-Daudé * the system address space. 164e3a575f5SPhilippe Mathieu-Daudé */ 165e3a575f5SPhilippe Mathieu-Daudé DEFINE_PROP_LINK("memory", CPUState, memory, TYPE_MEMORY_REGION, 166e3a575f5SPhilippe Mathieu-Daudé MemoryRegion *), 167e3a575f5SPhilippe Mathieu-Daudé }; 168e3a575f5SPhilippe Mathieu-Daudé 169e3a575f5SPhilippe Mathieu-Daudé static bool cpu_get_start_powered_off(Object *obj, Error **errp) 170e3a575f5SPhilippe Mathieu-Daudé { 171e3a575f5SPhilippe Mathieu-Daudé CPUState *cpu = CPU(obj); 172e3a575f5SPhilippe Mathieu-Daudé return cpu->start_powered_off; 173e3a575f5SPhilippe Mathieu-Daudé } 174e3a575f5SPhilippe Mathieu-Daudé 175e3a575f5SPhilippe Mathieu-Daudé static void cpu_set_start_powered_off(Object *obj, bool value, Error **errp) 176e3a575f5SPhilippe Mathieu-Daudé { 177e3a575f5SPhilippe Mathieu-Daudé CPUState *cpu = CPU(obj); 178e3a575f5SPhilippe Mathieu-Daudé cpu->start_powered_off = value; 179e3a575f5SPhilippe Mathieu-Daudé } 180e3a575f5SPhilippe Mathieu-Daudé 181e3a575f5SPhilippe Mathieu-Daudé void cpu_class_init_props(DeviceClass *dc) 182e3a575f5SPhilippe Mathieu-Daudé { 183e3a575f5SPhilippe Mathieu-Daudé ObjectClass *oc = OBJECT_CLASS(dc); 184e3a575f5SPhilippe Mathieu-Daudé 185e3a575f5SPhilippe Mathieu-Daudé /* 186e3a575f5SPhilippe Mathieu-Daudé * We can't use DEFINE_PROP_BOOL in the Property array for this 187e3a575f5SPhilippe Mathieu-Daudé * property, because we want this to be settable after realize. 188e3a575f5SPhilippe Mathieu-Daudé */ 189e3a575f5SPhilippe Mathieu-Daudé object_class_property_add_bool(oc, "start-powered-off", 190e3a575f5SPhilippe Mathieu-Daudé cpu_get_start_powered_off, 191e3a575f5SPhilippe Mathieu-Daudé cpu_set_start_powered_off); 192e3a575f5SPhilippe Mathieu-Daudé 193e3a575f5SPhilippe Mathieu-Daudé device_class_set_props(dc, cpu_system_props); 194e3a575f5SPhilippe Mathieu-Daudé } 195a86cf967SPhilippe Mathieu-Daudé 196a86cf967SPhilippe Mathieu-Daudé void cpu_exec_initfn(CPUState *cpu) 197a86cf967SPhilippe Mathieu-Daudé { 198a86cf967SPhilippe Mathieu-Daudé cpu->memory = get_system_memory(); 199a86cf967SPhilippe Mathieu-Daudé object_ref(OBJECT(cpu->memory)); 200a86cf967SPhilippe Mathieu-Daudé } 201*ca05578fSPhilippe Mathieu-Daudé 202*ca05578fSPhilippe Mathieu-Daudé static int cpu_common_post_load(void *opaque, int version_id) 203*ca05578fSPhilippe Mathieu-Daudé { 204*ca05578fSPhilippe Mathieu-Daudé if (tcg_enabled()) { 205*ca05578fSPhilippe Mathieu-Daudé CPUState *cpu = opaque; 206*ca05578fSPhilippe Mathieu-Daudé 207*ca05578fSPhilippe Mathieu-Daudé /* 208*ca05578fSPhilippe Mathieu-Daudé * 0x01 was CPU_INTERRUPT_EXIT. This line can be removed when the 209*ca05578fSPhilippe Mathieu-Daudé * version_id is increased. 210*ca05578fSPhilippe Mathieu-Daudé */ 211*ca05578fSPhilippe Mathieu-Daudé cpu->interrupt_request &= ~0x01; 212*ca05578fSPhilippe Mathieu-Daudé 213*ca05578fSPhilippe Mathieu-Daudé tlb_flush(cpu); 214*ca05578fSPhilippe Mathieu-Daudé 215*ca05578fSPhilippe Mathieu-Daudé /* 216*ca05578fSPhilippe Mathieu-Daudé * loadvm has just updated the content of RAM, bypassing the 217*ca05578fSPhilippe Mathieu-Daudé * usual mechanisms that ensure we flush TBs for writes to 218*ca05578fSPhilippe Mathieu-Daudé * memory we've translated code from. So we must flush all TBs, 219*ca05578fSPhilippe Mathieu-Daudé * which will now be stale. 220*ca05578fSPhilippe Mathieu-Daudé */ 221*ca05578fSPhilippe Mathieu-Daudé tb_flush(cpu); 222*ca05578fSPhilippe Mathieu-Daudé } 223*ca05578fSPhilippe Mathieu-Daudé 224*ca05578fSPhilippe Mathieu-Daudé return 0; 225*ca05578fSPhilippe Mathieu-Daudé } 226*ca05578fSPhilippe Mathieu-Daudé 227*ca05578fSPhilippe Mathieu-Daudé static int cpu_common_pre_load(void *opaque) 228*ca05578fSPhilippe Mathieu-Daudé { 229*ca05578fSPhilippe Mathieu-Daudé CPUState *cpu = opaque; 230*ca05578fSPhilippe Mathieu-Daudé 231*ca05578fSPhilippe Mathieu-Daudé cpu->exception_index = -1; 232*ca05578fSPhilippe Mathieu-Daudé 233*ca05578fSPhilippe Mathieu-Daudé return 0; 234*ca05578fSPhilippe Mathieu-Daudé } 235*ca05578fSPhilippe Mathieu-Daudé 236*ca05578fSPhilippe Mathieu-Daudé static bool cpu_common_exception_index_needed(void *opaque) 237*ca05578fSPhilippe Mathieu-Daudé { 238*ca05578fSPhilippe Mathieu-Daudé CPUState *cpu = opaque; 239*ca05578fSPhilippe Mathieu-Daudé 240*ca05578fSPhilippe Mathieu-Daudé return tcg_enabled() && cpu->exception_index != -1; 241*ca05578fSPhilippe Mathieu-Daudé } 242*ca05578fSPhilippe Mathieu-Daudé 243*ca05578fSPhilippe Mathieu-Daudé static const VMStateDescription vmstate_cpu_common_exception_index = { 244*ca05578fSPhilippe Mathieu-Daudé .name = "cpu_common/exception_index", 245*ca05578fSPhilippe Mathieu-Daudé .version_id = 1, 246*ca05578fSPhilippe Mathieu-Daudé .minimum_version_id = 1, 247*ca05578fSPhilippe Mathieu-Daudé .needed = cpu_common_exception_index_needed, 248*ca05578fSPhilippe Mathieu-Daudé .fields = (const VMStateField[]) { 249*ca05578fSPhilippe Mathieu-Daudé VMSTATE_INT32(exception_index, CPUState), 250*ca05578fSPhilippe Mathieu-Daudé VMSTATE_END_OF_LIST() 251*ca05578fSPhilippe Mathieu-Daudé } 252*ca05578fSPhilippe Mathieu-Daudé }; 253*ca05578fSPhilippe Mathieu-Daudé 254*ca05578fSPhilippe Mathieu-Daudé static bool cpu_common_crash_occurred_needed(void *opaque) 255*ca05578fSPhilippe Mathieu-Daudé { 256*ca05578fSPhilippe Mathieu-Daudé CPUState *cpu = opaque; 257*ca05578fSPhilippe Mathieu-Daudé 258*ca05578fSPhilippe Mathieu-Daudé return cpu->crash_occurred; 259*ca05578fSPhilippe Mathieu-Daudé } 260*ca05578fSPhilippe Mathieu-Daudé 261*ca05578fSPhilippe Mathieu-Daudé static const VMStateDescription vmstate_cpu_common_crash_occurred = { 262*ca05578fSPhilippe Mathieu-Daudé .name = "cpu_common/crash_occurred", 263*ca05578fSPhilippe Mathieu-Daudé .version_id = 1, 264*ca05578fSPhilippe Mathieu-Daudé .minimum_version_id = 1, 265*ca05578fSPhilippe Mathieu-Daudé .needed = cpu_common_crash_occurred_needed, 266*ca05578fSPhilippe Mathieu-Daudé .fields = (const VMStateField[]) { 267*ca05578fSPhilippe Mathieu-Daudé VMSTATE_BOOL(crash_occurred, CPUState), 268*ca05578fSPhilippe Mathieu-Daudé VMSTATE_END_OF_LIST() 269*ca05578fSPhilippe Mathieu-Daudé } 270*ca05578fSPhilippe Mathieu-Daudé }; 271*ca05578fSPhilippe Mathieu-Daudé 272*ca05578fSPhilippe Mathieu-Daudé const VMStateDescription vmstate_cpu_common = { 273*ca05578fSPhilippe Mathieu-Daudé .name = "cpu_common", 274*ca05578fSPhilippe Mathieu-Daudé .version_id = 1, 275*ca05578fSPhilippe Mathieu-Daudé .minimum_version_id = 1, 276*ca05578fSPhilippe Mathieu-Daudé .pre_load = cpu_common_pre_load, 277*ca05578fSPhilippe Mathieu-Daudé .post_load = cpu_common_post_load, 278*ca05578fSPhilippe Mathieu-Daudé .fields = (const VMStateField[]) { 279*ca05578fSPhilippe Mathieu-Daudé VMSTATE_UINT32(halted, CPUState), 280*ca05578fSPhilippe Mathieu-Daudé VMSTATE_UINT32(interrupt_request, CPUState), 281*ca05578fSPhilippe Mathieu-Daudé VMSTATE_END_OF_LIST() 282*ca05578fSPhilippe Mathieu-Daudé }, 283*ca05578fSPhilippe Mathieu-Daudé .subsections = (const VMStateDescription * const []) { 284*ca05578fSPhilippe Mathieu-Daudé &vmstate_cpu_common_exception_index, 285*ca05578fSPhilippe Mathieu-Daudé &vmstate_cpu_common_crash_occurred, 286*ca05578fSPhilippe Mathieu-Daudé NULL 287*ca05578fSPhilippe Mathieu-Daudé } 288*ca05578fSPhilippe Mathieu-Daudé }; 289*ca05578fSPhilippe Mathieu-Daudé 290*ca05578fSPhilippe Mathieu-Daudé void cpu_vmstate_register(CPUState *cpu) 291*ca05578fSPhilippe Mathieu-Daudé { 292*ca05578fSPhilippe Mathieu-Daudé if (qdev_get_vmsd(DEVICE(cpu)) == NULL) { 293*ca05578fSPhilippe Mathieu-Daudé vmstate_register(NULL, cpu->cpu_index, &vmstate_cpu_common, cpu); 294*ca05578fSPhilippe Mathieu-Daudé } 295*ca05578fSPhilippe Mathieu-Daudé if (cpu->cc->sysemu_ops->legacy_vmsd != NULL) { 296*ca05578fSPhilippe Mathieu-Daudé vmstate_register(NULL, cpu->cpu_index, 297*ca05578fSPhilippe Mathieu-Daudé cpu->cc->sysemu_ops->legacy_vmsd, cpu); 298*ca05578fSPhilippe Mathieu-Daudé } 299*ca05578fSPhilippe Mathieu-Daudé } 300*ca05578fSPhilippe Mathieu-Daudé 301*ca05578fSPhilippe Mathieu-Daudé void cpu_vmstate_unregister(CPUState *cpu) 302*ca05578fSPhilippe Mathieu-Daudé { 303*ca05578fSPhilippe Mathieu-Daudé CPUClass *cc = CPU_GET_CLASS(cpu); 304*ca05578fSPhilippe Mathieu-Daudé 305*ca05578fSPhilippe Mathieu-Daudé if (cc->sysemu_ops->legacy_vmsd != NULL) { 306*ca05578fSPhilippe Mathieu-Daudé vmstate_unregister(NULL, cc->sysemu_ops->legacy_vmsd, cpu); 307*ca05578fSPhilippe Mathieu-Daudé } 308*ca05578fSPhilippe Mathieu-Daudé if (qdev_get_vmsd(DEVICE(cpu)) == NULL) { 309*ca05578fSPhilippe Mathieu-Daudé vmstate_unregister(NULL, &vmstate_cpu_common, cpu); 310*ca05578fSPhilippe Mathieu-Daudé } 311*ca05578fSPhilippe Mathieu-Daudé } 312