1549e984eSSergio Lopez /* 2549e984eSSergio Lopez * Copyright (c) 2003-2004 Fabrice Bellard 3549e984eSSergio Lopez * Copyright (c) 2019 Red Hat, Inc. 4549e984eSSergio Lopez * 5549e984eSSergio Lopez * Permission is hereby granted, free of charge, to any person obtaining a copy 6549e984eSSergio Lopez * of this software and associated documentation files (the "Software"), to deal 7549e984eSSergio Lopez * in the Software without restriction, including without limitation the rights 8549e984eSSergio Lopez * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9549e984eSSergio Lopez * copies of the Software, and to permit persons to whom the Software is 10549e984eSSergio Lopez * furnished to do so, subject to the following conditions: 11549e984eSSergio Lopez * 12549e984eSSergio Lopez * The above copyright notice and this permission notice shall be included in 13549e984eSSergio Lopez * all copies or substantial portions of the Software. 14549e984eSSergio Lopez * 15549e984eSSergio Lopez * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16549e984eSSergio Lopez * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17549e984eSSergio Lopez * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18549e984eSSergio Lopez * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19549e984eSSergio Lopez * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20549e984eSSergio Lopez * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21549e984eSSergio Lopez * THE SOFTWARE. 22549e984eSSergio Lopez */ 23549e984eSSergio Lopez #include "qemu/osdep.h" 24549e984eSSergio Lopez #include "qemu/error-report.h" 25549e984eSSergio Lopez #include "qemu/units.h" 26549e984eSSergio Lopez #include "qapi/error.h" 27549e984eSSergio Lopez #include "qapi/qapi-visit-common.h" 28dfce81f1SSean Christopherson #include "qapi/qapi-visit-machine.h" 29549e984eSSergio Lopez #include "qapi/visitor.h" 3032cad1ffSPhilippe Mathieu-Daudé #include "system/qtest.h" 3132cad1ffSPhilippe Mathieu-Daudé #include "system/numa.h" 3289a289c7SPaolo Bonzini #include "trace.h" 33549e984eSSergio Lopez 34b061f059SPaolo Bonzini #include "hw/acpi/aml-build.h" 35549e984eSSergio Lopez #include "hw/i386/x86.h" 36549e984eSSergio Lopez #include "hw/i386/topology.h" 37549e984eSSergio Lopez 38549e984eSSergio Lopez #include "hw/nmi.h" 39a9dc68d9SClaudio Fontana #include "kvm/kvm_i386.h" 40549e984eSSergio Lopez 414f81baa3SDavid Woodhouse 42b061f059SPaolo Bonzini void init_topo_info(X86CPUTopoInfo *topo_info, 4353a5e7bdSBabu Moger const X86MachineState *x86ms) 4453a5e7bdSBabu Moger { 4553a5e7bdSBabu Moger MachineState *ms = MACHINE(x86ms); 4653a5e7bdSBabu Moger 4767872eb8SPaolo Bonzini topo_info->dies_per_pkg = ms->smp.dies; 483568adc9SZhao Liu /* 493568adc9SZhao Liu * Though smp.modules means the number of modules in one cluster, 503568adc9SZhao Liu * i386 doesn't support cluster level so that the smp.clusters 513568adc9SZhao Liu * always defaults to 1, therefore using smp.modules directly is 523568adc9SZhao Liu * fine here. 533568adc9SZhao Liu */ 543568adc9SZhao Liu topo_info->modules_per_die = ms->smp.modules; 553568adc9SZhao Liu topo_info->cores_per_module = ms->smp.cores; 5653a5e7bdSBabu Moger topo_info->threads_per_core = ms->smp.threads; 5753a5e7bdSBabu Moger } 5853a5e7bdSBabu Moger 59549e984eSSergio Lopez /* 60549e984eSSergio Lopez * Calculates initial APIC ID for a specific CPU index 61549e984eSSergio Lopez * 62549e984eSSergio Lopez * Currently we need to be able to calculate the APIC ID from the CPU index 63549e984eSSergio Lopez * alone (without requiring a CPU object), as the QEMU<->Seabios interfaces have 64549e984eSSergio Lopez * no concept of "CPU index", and the NUMA tables on fw_cfg need the APIC ID of 65549e984eSSergio Lopez * all CPUs up to max_cpus. 66549e984eSSergio Lopez */ 67703a548aSSergio Lopez uint32_t x86_cpu_apic_id_from_index(X86MachineState *x86ms, 68549e984eSSergio Lopez unsigned int cpu_index) 69549e984eSSergio Lopez { 7053a5e7bdSBabu Moger X86CPUTopoInfo topo_info; 71549e984eSSergio Lopez 7253a5e7bdSBabu Moger init_topo_info(&topo_info, x86ms); 7353a5e7bdSBabu Moger 74e6895f04SIgor Mammedov return x86_apicid_from_cpu_idx(&topo_info, cpu_index); 75549e984eSSergio Lopez } 76549e984eSSergio Lopez 77b348fdcdSPaolo Bonzini static CpuInstanceProperties 78549e984eSSergio Lopez x86_cpu_index_to_props(MachineState *ms, unsigned cpu_index) 79549e984eSSergio Lopez { 80549e984eSSergio Lopez MachineClass *mc = MACHINE_GET_CLASS(ms); 81549e984eSSergio Lopez const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(ms); 82549e984eSSergio Lopez 83549e984eSSergio Lopez assert(cpu_index < possible_cpus->len); 84549e984eSSergio Lopez return possible_cpus->cpus[cpu_index].props; 85549e984eSSergio Lopez } 86549e984eSSergio Lopez 87b348fdcdSPaolo Bonzini static int64_t x86_get_default_cpu_node_id(const MachineState *ms, int idx) 88549e984eSSergio Lopez { 89dcf08bc6SBabu Moger X86CPUTopoIDs topo_ids; 90f0bb276bSPaolo Bonzini X86MachineState *x86ms = X86_MACHINE(ms); 9153a5e7bdSBabu Moger X86CPUTopoInfo topo_info; 9253a5e7bdSBabu Moger 9353a5e7bdSBabu Moger init_topo_info(&topo_info, x86ms); 94549e984eSSergio Lopez 95549e984eSSergio Lopez assert(idx < ms->possible_cpus->len); 96dfe7ed0aSBabu Moger x86_topo_ids_from_apicid(ms->possible_cpus->cpus[idx].arch_id, 97dfe7ed0aSBabu Moger &topo_info, &topo_ids); 98dcf08bc6SBabu Moger return topo_ids.pkg_id % ms->numa_state->num_nodes; 99549e984eSSergio Lopez } 100549e984eSSergio Lopez 101b348fdcdSPaolo Bonzini static const CPUArchIdList *x86_possible_cpu_arch_ids(MachineState *ms) 102549e984eSSergio Lopez { 103f0bb276bSPaolo Bonzini X86MachineState *x86ms = X86_MACHINE(ms); 104549e984eSSergio Lopez unsigned int max_cpus = ms->smp.max_cpus; 10553a5e7bdSBabu Moger X86CPUTopoInfo topo_info; 10653a5e7bdSBabu Moger int i; 107549e984eSSergio Lopez 108549e984eSSergio Lopez if (ms->possible_cpus) { 109549e984eSSergio Lopez /* 110549e984eSSergio Lopez * make sure that max_cpus hasn't changed since the first use, i.e. 111549e984eSSergio Lopez * -smp hasn't been parsed after it 112549e984eSSergio Lopez */ 113549e984eSSergio Lopez assert(ms->possible_cpus->len == max_cpus); 114549e984eSSergio Lopez return ms->possible_cpus; 115549e984eSSergio Lopez } 116549e984eSSergio Lopez 117549e984eSSergio Lopez ms->possible_cpus = g_malloc0(sizeof(CPUArchIdList) + 118549e984eSSergio Lopez sizeof(CPUArchId) * max_cpus); 119549e984eSSergio Lopez ms->possible_cpus->len = max_cpus; 12053a5e7bdSBabu Moger 12153a5e7bdSBabu Moger init_topo_info(&topo_info, x86ms); 12253a5e7bdSBabu Moger 123549e984eSSergio Lopez for (i = 0; i < ms->possible_cpus->len; i++) { 124dcf08bc6SBabu Moger X86CPUTopoIDs topo_ids; 125549e984eSSergio Lopez 126549e984eSSergio Lopez ms->possible_cpus->cpus[i].type = ms->cpu_type; 127549e984eSSergio Lopez ms->possible_cpus->cpus[i].vcpus_count = 1; 128dfe7ed0aSBabu Moger ms->possible_cpus->cpus[i].arch_id = 129dfe7ed0aSBabu Moger x86_cpu_apic_id_from_index(x86ms, i); 130dfe7ed0aSBabu Moger x86_topo_ids_from_apicid(ms->possible_cpus->cpus[i].arch_id, 131dfe7ed0aSBabu Moger &topo_info, &topo_ids); 132549e984eSSergio Lopez ms->possible_cpus->cpus[i].props.has_socket_id = true; 133dcf08bc6SBabu Moger ms->possible_cpus->cpus[i].props.socket_id = topo_ids.pkg_id; 13467872eb8SPaolo Bonzini if (ms->smp.dies > 1) { 135549e984eSSergio Lopez ms->possible_cpus->cpus[i].props.has_die_id = true; 136dcf08bc6SBabu Moger ms->possible_cpus->cpus[i].props.die_id = topo_ids.die_id; 137549e984eSSergio Lopez } 138b17a26bcSZhao Liu if (ms->smp.modules > 1) { 139b17a26bcSZhao Liu ms->possible_cpus->cpus[i].props.has_module_id = true; 140b17a26bcSZhao Liu ms->possible_cpus->cpus[i].props.module_id = topo_ids.module_id; 141b17a26bcSZhao Liu } 142549e984eSSergio Lopez ms->possible_cpus->cpus[i].props.has_core_id = true; 143dcf08bc6SBabu Moger ms->possible_cpus->cpus[i].props.core_id = topo_ids.core_id; 144549e984eSSergio Lopez ms->possible_cpus->cpus[i].props.has_thread_id = true; 145dcf08bc6SBabu Moger ms->possible_cpus->cpus[i].props.thread_id = topo_ids.smt_id; 146549e984eSSergio Lopez } 147549e984eSSergio Lopez return ms->possible_cpus; 148549e984eSSergio Lopez } 149549e984eSSergio Lopez 150f0bb276bSPaolo Bonzini static void x86_nmi(NMIState *n, int cpu_index, Error **errp) 151f0bb276bSPaolo Bonzini { 152f0bb276bSPaolo Bonzini /* cpu index isn't used */ 153f0bb276bSPaolo Bonzini CPUState *cs; 154f0bb276bSPaolo Bonzini 155f0bb276bSPaolo Bonzini CPU_FOREACH(cs) { 156f0bb276bSPaolo Bonzini X86CPU *cpu = X86_CPU(cs); 157f0bb276bSPaolo Bonzini 158c2e6d7d8SBernhard Beschow if (cpu_is_apic_enabled(cpu->apic_state)) { 159f0bb276bSPaolo Bonzini apic_deliver_nmi(cpu->apic_state); 160f22f3a92SBernhard Beschow } else { 161f22f3a92SBernhard Beschow cpu_interrupt(cs, CPU_INTERRUPT_NMI); 162f0bb276bSPaolo Bonzini } 163f0bb276bSPaolo Bonzini } 164f0bb276bSPaolo Bonzini } 165f0bb276bSPaolo Bonzini 1669927a632SGerd Hoffmann bool x86_machine_is_smm_enabled(const X86MachineState *x86ms) 167ed9e923cSPaolo Bonzini { 168ed9e923cSPaolo Bonzini bool smm_available = false; 169ed9e923cSPaolo Bonzini 170ed9e923cSPaolo Bonzini if (x86ms->smm == ON_OFF_AUTO_OFF) { 171ed9e923cSPaolo Bonzini return false; 172ed9e923cSPaolo Bonzini } 173ed9e923cSPaolo Bonzini 174ed9e923cSPaolo Bonzini if (tcg_enabled() || qtest_enabled()) { 175ed9e923cSPaolo Bonzini smm_available = true; 176ed9e923cSPaolo Bonzini } else if (kvm_enabled()) { 177ed9e923cSPaolo Bonzini smm_available = kvm_has_smm(); 178ed9e923cSPaolo Bonzini } 179ed9e923cSPaolo Bonzini 180ed9e923cSPaolo Bonzini if (smm_available) { 181ed9e923cSPaolo Bonzini return true; 182ed9e923cSPaolo Bonzini } 183ed9e923cSPaolo Bonzini 184ed9e923cSPaolo Bonzini if (x86ms->smm == ON_OFF_AUTO_ON) { 185ed9e923cSPaolo Bonzini error_report("System Management Mode not supported by this hypervisor."); 186ed9e923cSPaolo Bonzini exit(1); 187ed9e923cSPaolo Bonzini } 188ed9e923cSPaolo Bonzini return false; 189ed9e923cSPaolo Bonzini } 190ed9e923cSPaolo Bonzini 191ed9e923cSPaolo Bonzini static void x86_machine_get_smm(Object *obj, Visitor *v, const char *name, 192ed9e923cSPaolo Bonzini void *opaque, Error **errp) 193ed9e923cSPaolo Bonzini { 194ed9e923cSPaolo Bonzini X86MachineState *x86ms = X86_MACHINE(obj); 195ed9e923cSPaolo Bonzini OnOffAuto smm = x86ms->smm; 196ed9e923cSPaolo Bonzini 197ed9e923cSPaolo Bonzini visit_type_OnOffAuto(v, name, &smm, errp); 198ed9e923cSPaolo Bonzini } 199ed9e923cSPaolo Bonzini 200ed9e923cSPaolo Bonzini static void x86_machine_set_smm(Object *obj, Visitor *v, const char *name, 201ed9e923cSPaolo Bonzini void *opaque, Error **errp) 202ed9e923cSPaolo Bonzini { 203ed9e923cSPaolo Bonzini X86MachineState *x86ms = X86_MACHINE(obj); 204ed9e923cSPaolo Bonzini 205ed9e923cSPaolo Bonzini visit_type_OnOffAuto(v, name, &x86ms->smm, errp); 206ed9e923cSPaolo Bonzini } 207ed9e923cSPaolo Bonzini 2089927a632SGerd Hoffmann bool x86_machine_is_acpi_enabled(const X86MachineState *x86ms) 20917e89077SGerd Hoffmann { 21017e89077SGerd Hoffmann if (x86ms->acpi == ON_OFF_AUTO_OFF) { 21117e89077SGerd Hoffmann return false; 21217e89077SGerd Hoffmann } 21317e89077SGerd Hoffmann return true; 21417e89077SGerd Hoffmann } 21517e89077SGerd Hoffmann 21617e89077SGerd Hoffmann static void x86_machine_get_acpi(Object *obj, Visitor *v, const char *name, 21717e89077SGerd Hoffmann void *opaque, Error **errp) 21817e89077SGerd Hoffmann { 21917e89077SGerd Hoffmann X86MachineState *x86ms = X86_MACHINE(obj); 22017e89077SGerd Hoffmann OnOffAuto acpi = x86ms->acpi; 22117e89077SGerd Hoffmann 22217e89077SGerd Hoffmann visit_type_OnOffAuto(v, name, &acpi, errp); 22317e89077SGerd Hoffmann } 22417e89077SGerd Hoffmann 22517e89077SGerd Hoffmann static void x86_machine_set_acpi(Object *obj, Visitor *v, const char *name, 22617e89077SGerd Hoffmann void *opaque, Error **errp) 22717e89077SGerd Hoffmann { 22817e89077SGerd Hoffmann X86MachineState *x86ms = X86_MACHINE(obj); 22917e89077SGerd Hoffmann 23017e89077SGerd Hoffmann visit_type_OnOffAuto(v, name, &x86ms->acpi, errp); 23117e89077SGerd Hoffmann } 23217e89077SGerd Hoffmann 2339dee7e51SXiaoyao Li static void x86_machine_get_pit(Object *obj, Visitor *v, const char *name, 2349dee7e51SXiaoyao Li void *opaque, Error **errp) 2359dee7e51SXiaoyao Li { 2369dee7e51SXiaoyao Li X86MachineState *x86ms = X86_MACHINE(obj); 2379dee7e51SXiaoyao Li OnOffAuto pit = x86ms->pit; 2389dee7e51SXiaoyao Li 2399dee7e51SXiaoyao Li visit_type_OnOffAuto(v, name, &pit, errp); 2409dee7e51SXiaoyao Li } 2419dee7e51SXiaoyao Li 2429dee7e51SXiaoyao Li static void x86_machine_set_pit(Object *obj, Visitor *v, const char *name, 2439dee7e51SXiaoyao Li void *opaque, Error **errp) 2449dee7e51SXiaoyao Li { 245eed52398SZhao Liu X86MachineState *x86ms = X86_MACHINE(obj); 2469dee7e51SXiaoyao Li 2479dee7e51SXiaoyao Li visit_type_OnOffAuto(v, name, &x86ms->pit, errp); 2489dee7e51SXiaoyao Li } 2499dee7e51SXiaoyao Li 250c300bbe8SXiaoyao Li static void x86_machine_get_pic(Object *obj, Visitor *v, const char *name, 251c300bbe8SXiaoyao Li void *opaque, Error **errp) 252c300bbe8SXiaoyao Li { 253c300bbe8SXiaoyao Li X86MachineState *x86ms = X86_MACHINE(obj); 254c300bbe8SXiaoyao Li OnOffAuto pic = x86ms->pic; 255c300bbe8SXiaoyao Li 256c300bbe8SXiaoyao Li visit_type_OnOffAuto(v, name, &pic, errp); 257c300bbe8SXiaoyao Li } 258c300bbe8SXiaoyao Li 259c300bbe8SXiaoyao Li static void x86_machine_set_pic(Object *obj, Visitor *v, const char *name, 260c300bbe8SXiaoyao Li void *opaque, Error **errp) 261c300bbe8SXiaoyao Li { 262c300bbe8SXiaoyao Li X86MachineState *x86ms = X86_MACHINE(obj); 263c300bbe8SXiaoyao Li 264c300bbe8SXiaoyao Li visit_type_OnOffAuto(v, name, &x86ms->pic, errp); 265c300bbe8SXiaoyao Li } 266c300bbe8SXiaoyao Li 267d07b2286SMarian Postevca static char *x86_machine_get_oem_id(Object *obj, Error **errp) 268d07b2286SMarian Postevca { 269d07b2286SMarian Postevca X86MachineState *x86ms = X86_MACHINE(obj); 270d07b2286SMarian Postevca 271d07b2286SMarian Postevca return g_strdup(x86ms->oem_id); 272d07b2286SMarian Postevca } 273d07b2286SMarian Postevca 274d07b2286SMarian Postevca static void x86_machine_set_oem_id(Object *obj, const char *value, Error **errp) 275d07b2286SMarian Postevca { 276d07b2286SMarian Postevca X86MachineState *x86ms = X86_MACHINE(obj); 277d07b2286SMarian Postevca size_t len = strlen(value); 278d07b2286SMarian Postevca 279d07b2286SMarian Postevca if (len > 6) { 280d07b2286SMarian Postevca error_setg(errp, 281d07b2286SMarian Postevca "User specified "X86_MACHINE_OEM_ID" value is bigger than " 282d07b2286SMarian Postevca "6 bytes in size"); 283d07b2286SMarian Postevca return; 284d07b2286SMarian Postevca } 285d07b2286SMarian Postevca 286d07b2286SMarian Postevca strncpy(x86ms->oem_id, value, 6); 287d07b2286SMarian Postevca } 288d07b2286SMarian Postevca 289d07b2286SMarian Postevca static char *x86_machine_get_oem_table_id(Object *obj, Error **errp) 290d07b2286SMarian Postevca { 291d07b2286SMarian Postevca X86MachineState *x86ms = X86_MACHINE(obj); 292d07b2286SMarian Postevca 293d07b2286SMarian Postevca return g_strdup(x86ms->oem_table_id); 294d07b2286SMarian Postevca } 295d07b2286SMarian Postevca 296d07b2286SMarian Postevca static void x86_machine_set_oem_table_id(Object *obj, const char *value, 297d07b2286SMarian Postevca Error **errp) 298d07b2286SMarian Postevca { 299d07b2286SMarian Postevca X86MachineState *x86ms = X86_MACHINE(obj); 300d07b2286SMarian Postevca size_t len = strlen(value); 301d07b2286SMarian Postevca 302d07b2286SMarian Postevca if (len > 8) { 303d07b2286SMarian Postevca error_setg(errp, 304d07b2286SMarian Postevca "User specified "X86_MACHINE_OEM_TABLE_ID 305d07b2286SMarian Postevca " value is bigger than " 306d07b2286SMarian Postevca "8 bytes in size"); 307d07b2286SMarian Postevca return; 308d07b2286SMarian Postevca } 309d07b2286SMarian Postevca strncpy(x86ms->oem_table_id, value, 8); 310d07b2286SMarian Postevca } 311d07b2286SMarian Postevca 312035d1ef2SChenyi Qiang static void x86_machine_get_bus_lock_ratelimit(Object *obj, Visitor *v, 313035d1ef2SChenyi Qiang const char *name, void *opaque, Error **errp) 314035d1ef2SChenyi Qiang { 315035d1ef2SChenyi Qiang X86MachineState *x86ms = X86_MACHINE(obj); 316035d1ef2SChenyi Qiang uint64_t bus_lock_ratelimit = x86ms->bus_lock_ratelimit; 317035d1ef2SChenyi Qiang 318035d1ef2SChenyi Qiang visit_type_uint64(v, name, &bus_lock_ratelimit, errp); 319035d1ef2SChenyi Qiang } 320035d1ef2SChenyi Qiang 321035d1ef2SChenyi Qiang static void x86_machine_set_bus_lock_ratelimit(Object *obj, Visitor *v, 322035d1ef2SChenyi Qiang const char *name, void *opaque, Error **errp) 323035d1ef2SChenyi Qiang { 324035d1ef2SChenyi Qiang X86MachineState *x86ms = X86_MACHINE(obj); 325035d1ef2SChenyi Qiang 326035d1ef2SChenyi Qiang visit_type_uint64(v, name, &x86ms->bus_lock_ratelimit, errp); 327035d1ef2SChenyi Qiang } 328035d1ef2SChenyi Qiang 329dfce81f1SSean Christopherson static void machine_get_sgx_epc(Object *obj, Visitor *v, const char *name, 330dfce81f1SSean Christopherson void *opaque, Error **errp) 331dfce81f1SSean Christopherson { 332dfce81f1SSean Christopherson X86MachineState *x86ms = X86_MACHINE(obj); 333dfce81f1SSean Christopherson SgxEPCList *list = x86ms->sgx_epc_list; 334dfce81f1SSean Christopherson 335dfce81f1SSean Christopherson visit_type_SgxEPCList(v, name, &list, errp); 336dfce81f1SSean Christopherson } 337dfce81f1SSean Christopherson 338dfce81f1SSean Christopherson static void machine_set_sgx_epc(Object *obj, Visitor *v, const char *name, 339dfce81f1SSean Christopherson void *opaque, Error **errp) 340dfce81f1SSean Christopherson { 341dfce81f1SSean Christopherson X86MachineState *x86ms = X86_MACHINE(obj); 342dfce81f1SSean Christopherson SgxEPCList *list; 343dfce81f1SSean Christopherson 344dfce81f1SSean Christopherson list = x86ms->sgx_epc_list; 345dfce81f1SSean Christopherson visit_type_SgxEPCList(v, name, &x86ms->sgx_epc_list, errp); 346dfce81f1SSean Christopherson 347dfce81f1SSean Christopherson qapi_free_SgxEPCList(list); 348dfce81f1SSean Christopherson } 349dfce81f1SSean Christopherson 350ee88612dSPaolo Bonzini static int x86_kvm_type(MachineState *ms, const char *vm_type) 351ee88612dSPaolo Bonzini { 352ee88612dSPaolo Bonzini /* 353ee88612dSPaolo Bonzini * No x86 machine has a kvm-type property. If one is added that has 354ee88612dSPaolo Bonzini * it, it should call kvm_get_vm_type() directly or not use it at all. 355ee88612dSPaolo Bonzini */ 356ee88612dSPaolo Bonzini assert(vm_type == NULL); 357ee88612dSPaolo Bonzini return kvm_enabled() ? kvm_get_vm_type(ms) : 0; 358ee88612dSPaolo Bonzini } 359ee88612dSPaolo Bonzini 360f0bb276bSPaolo Bonzini static void x86_machine_initfn(Object *obj) 361f0bb276bSPaolo Bonzini { 362f0bb276bSPaolo Bonzini X86MachineState *x86ms = X86_MACHINE(obj); 363f0bb276bSPaolo Bonzini 364ed9e923cSPaolo Bonzini x86ms->smm = ON_OFF_AUTO_AUTO; 36517e89077SGerd Hoffmann x86ms->acpi = ON_OFF_AUTO_AUTO; 3669dee7e51SXiaoyao Li x86ms->pit = ON_OFF_AUTO_AUTO; 367c300bbe8SXiaoyao Li x86ms->pic = ON_OFF_AUTO_AUTO; 3681b2802c4SGerd Hoffmann x86ms->pci_irq_mask = ACPI_BUILD_PCI_IRQS; 369d07b2286SMarian Postevca x86ms->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6); 370d07b2286SMarian Postevca x86ms->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8); 371035d1ef2SChenyi Qiang x86ms->bus_lock_ratelimit = 0; 3724ab4c330SJoao Martins x86ms->above_4g_mem_start = 4 * GiB; 373f0bb276bSPaolo Bonzini } 374f0bb276bSPaolo Bonzini 37512d1a768SPhilippe Mathieu-Daudé static void x86_machine_class_init(ObjectClass *oc, const void *data) 376f0bb276bSPaolo Bonzini { 377f0bb276bSPaolo Bonzini MachineClass *mc = MACHINE_CLASS(oc); 378f0bb276bSPaolo Bonzini X86MachineClass *x86mc = X86_MACHINE_CLASS(oc); 379f0bb276bSPaolo Bonzini NMIClass *nc = NMI_CLASS(oc); 380f0bb276bSPaolo Bonzini 381f0bb276bSPaolo Bonzini mc->cpu_index_to_instance_props = x86_cpu_index_to_props; 382f0bb276bSPaolo Bonzini mc->get_default_cpu_node_id = x86_get_default_cpu_node_id; 383f0bb276bSPaolo Bonzini mc->possible_cpu_arch_ids = x86_possible_cpu_arch_ids; 384ee88612dSPaolo Bonzini mc->kvm_type = x86_kvm_type; 3852f34ebf2SLiam Merwick x86mc->save_tsc_khz = true; 386f014c974SPaolo Bonzini x86mc->fwcfg_dma_enabled = true; 387f0bb276bSPaolo Bonzini nc->nmi_monitor_handler = x86_nmi; 388f0bb276bSPaolo Bonzini 389ed9e923cSPaolo Bonzini object_class_property_add(oc, X86_MACHINE_SMM, "OnOffAuto", 390ed9e923cSPaolo Bonzini x86_machine_get_smm, x86_machine_set_smm, 391d2623129SMarkus Armbruster NULL, NULL); 392ed9e923cSPaolo Bonzini object_class_property_set_description(oc, X86_MACHINE_SMM, 3937eecec7dSMarkus Armbruster "Enable SMM"); 39417e89077SGerd Hoffmann 39517e89077SGerd Hoffmann object_class_property_add(oc, X86_MACHINE_ACPI, "OnOffAuto", 39617e89077SGerd Hoffmann x86_machine_get_acpi, x86_machine_set_acpi, 397d2623129SMarkus Armbruster NULL, NULL); 39817e89077SGerd Hoffmann object_class_property_set_description(oc, X86_MACHINE_ACPI, 3997eecec7dSMarkus Armbruster "Enable ACPI"); 400d07b2286SMarian Postevca 4019dee7e51SXiaoyao Li object_class_property_add(oc, X86_MACHINE_PIT, "OnOffAuto", 4029dee7e51SXiaoyao Li x86_machine_get_pit, 4039dee7e51SXiaoyao Li x86_machine_set_pit, 4049dee7e51SXiaoyao Li NULL, NULL); 4059dee7e51SXiaoyao Li object_class_property_set_description(oc, X86_MACHINE_PIT, 4069dee7e51SXiaoyao Li "Enable i8254 PIT"); 4079dee7e51SXiaoyao Li 408c300bbe8SXiaoyao Li object_class_property_add(oc, X86_MACHINE_PIC, "OnOffAuto", 409c300bbe8SXiaoyao Li x86_machine_get_pic, 410c300bbe8SXiaoyao Li x86_machine_set_pic, 411c300bbe8SXiaoyao Li NULL, NULL); 412c300bbe8SXiaoyao Li object_class_property_set_description(oc, X86_MACHINE_PIC, 413c300bbe8SXiaoyao Li "Enable i8259 PIC"); 414c300bbe8SXiaoyao Li 415d07b2286SMarian Postevca object_class_property_add_str(oc, X86_MACHINE_OEM_ID, 416d07b2286SMarian Postevca x86_machine_get_oem_id, 417d07b2286SMarian Postevca x86_machine_set_oem_id); 418d07b2286SMarian Postevca object_class_property_set_description(oc, X86_MACHINE_OEM_ID, 419d07b2286SMarian Postevca "Override the default value of field OEMID " 420d07b2286SMarian Postevca "in ACPI table header." 421d07b2286SMarian Postevca "The string may be up to 6 bytes in size"); 422d07b2286SMarian Postevca 423d07b2286SMarian Postevca 424d07b2286SMarian Postevca object_class_property_add_str(oc, X86_MACHINE_OEM_TABLE_ID, 425d07b2286SMarian Postevca x86_machine_get_oem_table_id, 426d07b2286SMarian Postevca x86_machine_set_oem_table_id); 427d07b2286SMarian Postevca object_class_property_set_description(oc, X86_MACHINE_OEM_TABLE_ID, 428d07b2286SMarian Postevca "Override the default value of field OEM Table ID " 429d07b2286SMarian Postevca "in ACPI table header." 430d07b2286SMarian Postevca "The string may be up to 8 bytes in size"); 431035d1ef2SChenyi Qiang 432035d1ef2SChenyi Qiang object_class_property_add(oc, X86_MACHINE_BUS_LOCK_RATELIMIT, "uint64_t", 433035d1ef2SChenyi Qiang x86_machine_get_bus_lock_ratelimit, 434035d1ef2SChenyi Qiang x86_machine_set_bus_lock_ratelimit, NULL, NULL); 435035d1ef2SChenyi Qiang object_class_property_set_description(oc, X86_MACHINE_BUS_LOCK_RATELIMIT, 436035d1ef2SChenyi Qiang "Set the ratelimit for the bus locks acquired in VMs"); 437dfce81f1SSean Christopherson 438dfce81f1SSean Christopherson object_class_property_add(oc, "sgx-epc", "SgxEPC", 439dfce81f1SSean Christopherson machine_get_sgx_epc, machine_set_sgx_epc, 440dfce81f1SSean Christopherson NULL, NULL); 441dfce81f1SSean Christopherson object_class_property_set_description(oc, "sgx-epc", 442dfce81f1SSean Christopherson "SGX EPC device"); 443f0bb276bSPaolo Bonzini } 444f0bb276bSPaolo Bonzini 445f0bb276bSPaolo Bonzini static const TypeInfo x86_machine_info = { 446f0bb276bSPaolo Bonzini .name = TYPE_X86_MACHINE, 447f0bb276bSPaolo Bonzini .parent = TYPE_MACHINE, 448f0bb276bSPaolo Bonzini .abstract = true, 449f0bb276bSPaolo Bonzini .instance_size = sizeof(X86MachineState), 450f0bb276bSPaolo Bonzini .instance_init = x86_machine_initfn, 451f0bb276bSPaolo Bonzini .class_size = sizeof(X86MachineClass), 452f0bb276bSPaolo Bonzini .class_init = x86_machine_class_init, 453*2cd09e47SPhilippe Mathieu-Daudé .interfaces = (const InterfaceInfo[]) { 454f0bb276bSPaolo Bonzini { TYPE_NMI }, 455f0bb276bSPaolo Bonzini { } 456f0bb276bSPaolo Bonzini }, 457f0bb276bSPaolo Bonzini }; 458f0bb276bSPaolo Bonzini 459f0bb276bSPaolo Bonzini static void x86_machine_register_types(void) 460f0bb276bSPaolo Bonzini { 461f0bb276bSPaolo Bonzini type_register_static(&x86_machine_info); 462f0bb276bSPaolo Bonzini } 463f0bb276bSPaolo Bonzini 464f0bb276bSPaolo Bonzini type_init(x86_machine_register_types) 465