1 /* 2 * Copyright (c) 2003-2004 Fabrice Bellard 3 * Copyright (c) 2019 Red Hat, Inc. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a copy 6 * of this software and associated documentation files (the "Software"), to deal 7 * in the Software without restriction, including without limitation the rights 8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 * copies of the Software, and to permit persons to whom the Software is 10 * furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be included in 13 * all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 * THE SOFTWARE. 22 */ 23 #include "qemu/osdep.h" 24 #include "qemu/error-report.h" 25 #include "qemu/units.h" 26 #include "qapi/error.h" 27 #include "qapi/qapi-visit-common.h" 28 #include "qapi/qapi-visit-machine.h" 29 #include "qapi/visitor.h" 30 #include "sysemu/qtest.h" 31 #include "sysemu/numa.h" 32 #include "trace.h" 33 34 #include "hw/acpi/aml-build.h" 35 #include "hw/i386/x86.h" 36 #include "hw/i386/topology.h" 37 38 #include "hw/nmi.h" 39 #include "kvm/kvm_i386.h" 40 41 42 void init_topo_info(X86CPUTopoInfo *topo_info, 43 const X86MachineState *x86ms) 44 { 45 MachineState *ms = MACHINE(x86ms); 46 47 topo_info->dies_per_pkg = ms->smp.dies; 48 /* 49 * Though smp.modules means the number of modules in one cluster, 50 * i386 doesn't support cluster level so that the smp.clusters 51 * always defaults to 1, therefore using smp.modules directly is 52 * fine here. 53 */ 54 topo_info->modules_per_die = ms->smp.modules; 55 topo_info->cores_per_module = ms->smp.cores; 56 topo_info->threads_per_core = ms->smp.threads; 57 } 58 59 /* 60 * Calculates initial APIC ID for a specific CPU index 61 * 62 * Currently we need to be able to calculate the APIC ID from the CPU index 63 * alone (without requiring a CPU object), as the QEMU<->Seabios interfaces have 64 * no concept of "CPU index", and the NUMA tables on fw_cfg need the APIC ID of 65 * all CPUs up to max_cpus. 66 */ 67 uint32_t x86_cpu_apic_id_from_index(X86MachineState *x86ms, 68 unsigned int cpu_index) 69 { 70 X86CPUTopoInfo topo_info; 71 72 init_topo_info(&topo_info, x86ms); 73 74 return x86_apicid_from_cpu_idx(&topo_info, cpu_index); 75 } 76 77 static CpuInstanceProperties 78 x86_cpu_index_to_props(MachineState *ms, unsigned cpu_index) 79 { 80 MachineClass *mc = MACHINE_GET_CLASS(ms); 81 const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(ms); 82 83 assert(cpu_index < possible_cpus->len); 84 return possible_cpus->cpus[cpu_index].props; 85 } 86 87 static int64_t x86_get_default_cpu_node_id(const MachineState *ms, int idx) 88 { 89 X86CPUTopoIDs topo_ids; 90 X86MachineState *x86ms = X86_MACHINE(ms); 91 X86CPUTopoInfo topo_info; 92 93 init_topo_info(&topo_info, x86ms); 94 95 assert(idx < ms->possible_cpus->len); 96 x86_topo_ids_from_apicid(ms->possible_cpus->cpus[idx].arch_id, 97 &topo_info, &topo_ids); 98 return topo_ids.pkg_id % ms->numa_state->num_nodes; 99 } 100 101 static const CPUArchIdList *x86_possible_cpu_arch_ids(MachineState *ms) 102 { 103 X86MachineState *x86ms = X86_MACHINE(ms); 104 unsigned int max_cpus = ms->smp.max_cpus; 105 X86CPUTopoInfo topo_info; 106 int i; 107 108 if (ms->possible_cpus) { 109 /* 110 * make sure that max_cpus hasn't changed since the first use, i.e. 111 * -smp hasn't been parsed after it 112 */ 113 assert(ms->possible_cpus->len == max_cpus); 114 return ms->possible_cpus; 115 } 116 117 ms->possible_cpus = g_malloc0(sizeof(CPUArchIdList) + 118 sizeof(CPUArchId) * max_cpus); 119 ms->possible_cpus->len = max_cpus; 120 121 init_topo_info(&topo_info, x86ms); 122 123 for (i = 0; i < ms->possible_cpus->len; i++) { 124 X86CPUTopoIDs topo_ids; 125 126 ms->possible_cpus->cpus[i].type = ms->cpu_type; 127 ms->possible_cpus->cpus[i].vcpus_count = 1; 128 ms->possible_cpus->cpus[i].arch_id = 129 x86_cpu_apic_id_from_index(x86ms, i); 130 x86_topo_ids_from_apicid(ms->possible_cpus->cpus[i].arch_id, 131 &topo_info, &topo_ids); 132 ms->possible_cpus->cpus[i].props.has_socket_id = true; 133 ms->possible_cpus->cpus[i].props.socket_id = topo_ids.pkg_id; 134 if (ms->smp.dies > 1) { 135 ms->possible_cpus->cpus[i].props.has_die_id = true; 136 ms->possible_cpus->cpus[i].props.die_id = topo_ids.die_id; 137 } 138 ms->possible_cpus->cpus[i].props.has_core_id = true; 139 ms->possible_cpus->cpus[i].props.core_id = topo_ids.core_id; 140 ms->possible_cpus->cpus[i].props.has_thread_id = true; 141 ms->possible_cpus->cpus[i].props.thread_id = topo_ids.smt_id; 142 } 143 return ms->possible_cpus; 144 } 145 146 static void x86_nmi(NMIState *n, int cpu_index, Error **errp) 147 { 148 /* cpu index isn't used */ 149 CPUState *cs; 150 151 CPU_FOREACH(cs) { 152 X86CPU *cpu = X86_CPU(cs); 153 154 if (cpu_is_apic_enabled(cpu->apic_state)) { 155 apic_deliver_nmi(cpu->apic_state); 156 } else { 157 cpu_interrupt(cs, CPU_INTERRUPT_NMI); 158 } 159 } 160 } 161 162 bool x86_machine_is_smm_enabled(const X86MachineState *x86ms) 163 { 164 bool smm_available = false; 165 166 if (x86ms->smm == ON_OFF_AUTO_OFF) { 167 return false; 168 } 169 170 if (tcg_enabled() || qtest_enabled()) { 171 smm_available = true; 172 } else if (kvm_enabled()) { 173 smm_available = kvm_has_smm(); 174 } 175 176 if (smm_available) { 177 return true; 178 } 179 180 if (x86ms->smm == ON_OFF_AUTO_ON) { 181 error_report("System Management Mode not supported by this hypervisor."); 182 exit(1); 183 } 184 return false; 185 } 186 187 static void x86_machine_get_smm(Object *obj, Visitor *v, const char *name, 188 void *opaque, Error **errp) 189 { 190 X86MachineState *x86ms = X86_MACHINE(obj); 191 OnOffAuto smm = x86ms->smm; 192 193 visit_type_OnOffAuto(v, name, &smm, errp); 194 } 195 196 static void x86_machine_set_smm(Object *obj, Visitor *v, const char *name, 197 void *opaque, Error **errp) 198 { 199 X86MachineState *x86ms = X86_MACHINE(obj); 200 201 visit_type_OnOffAuto(v, name, &x86ms->smm, errp); 202 } 203 204 bool x86_machine_is_acpi_enabled(const X86MachineState *x86ms) 205 { 206 if (x86ms->acpi == ON_OFF_AUTO_OFF) { 207 return false; 208 } 209 return true; 210 } 211 212 static void x86_machine_get_acpi(Object *obj, Visitor *v, const char *name, 213 void *opaque, Error **errp) 214 { 215 X86MachineState *x86ms = X86_MACHINE(obj); 216 OnOffAuto acpi = x86ms->acpi; 217 218 visit_type_OnOffAuto(v, name, &acpi, errp); 219 } 220 221 static void x86_machine_set_acpi(Object *obj, Visitor *v, const char *name, 222 void *opaque, Error **errp) 223 { 224 X86MachineState *x86ms = X86_MACHINE(obj); 225 226 visit_type_OnOffAuto(v, name, &x86ms->acpi, errp); 227 } 228 229 static void x86_machine_get_pit(Object *obj, Visitor *v, const char *name, 230 void *opaque, Error **errp) 231 { 232 X86MachineState *x86ms = X86_MACHINE(obj); 233 OnOffAuto pit = x86ms->pit; 234 235 visit_type_OnOffAuto(v, name, &pit, errp); 236 } 237 238 static void x86_machine_set_pit(Object *obj, Visitor *v, const char *name, 239 void *opaque, Error **errp) 240 { 241 X86MachineState *x86ms = X86_MACHINE(obj);; 242 243 visit_type_OnOffAuto(v, name, &x86ms->pit, errp); 244 } 245 246 static void x86_machine_get_pic(Object *obj, Visitor *v, const char *name, 247 void *opaque, Error **errp) 248 { 249 X86MachineState *x86ms = X86_MACHINE(obj); 250 OnOffAuto pic = x86ms->pic; 251 252 visit_type_OnOffAuto(v, name, &pic, errp); 253 } 254 255 static void x86_machine_set_pic(Object *obj, Visitor *v, const char *name, 256 void *opaque, Error **errp) 257 { 258 X86MachineState *x86ms = X86_MACHINE(obj); 259 260 visit_type_OnOffAuto(v, name, &x86ms->pic, errp); 261 } 262 263 static char *x86_machine_get_oem_id(Object *obj, Error **errp) 264 { 265 X86MachineState *x86ms = X86_MACHINE(obj); 266 267 return g_strdup(x86ms->oem_id); 268 } 269 270 static void x86_machine_set_oem_id(Object *obj, const char *value, Error **errp) 271 { 272 X86MachineState *x86ms = X86_MACHINE(obj); 273 size_t len = strlen(value); 274 275 if (len > 6) { 276 error_setg(errp, 277 "User specified "X86_MACHINE_OEM_ID" value is bigger than " 278 "6 bytes in size"); 279 return; 280 } 281 282 strncpy(x86ms->oem_id, value, 6); 283 } 284 285 static char *x86_machine_get_oem_table_id(Object *obj, Error **errp) 286 { 287 X86MachineState *x86ms = X86_MACHINE(obj); 288 289 return g_strdup(x86ms->oem_table_id); 290 } 291 292 static void x86_machine_set_oem_table_id(Object *obj, const char *value, 293 Error **errp) 294 { 295 X86MachineState *x86ms = X86_MACHINE(obj); 296 size_t len = strlen(value); 297 298 if (len > 8) { 299 error_setg(errp, 300 "User specified "X86_MACHINE_OEM_TABLE_ID 301 " value is bigger than " 302 "8 bytes in size"); 303 return; 304 } 305 strncpy(x86ms->oem_table_id, value, 8); 306 } 307 308 static void x86_machine_get_bus_lock_ratelimit(Object *obj, Visitor *v, 309 const char *name, void *opaque, Error **errp) 310 { 311 X86MachineState *x86ms = X86_MACHINE(obj); 312 uint64_t bus_lock_ratelimit = x86ms->bus_lock_ratelimit; 313 314 visit_type_uint64(v, name, &bus_lock_ratelimit, errp); 315 } 316 317 static void x86_machine_set_bus_lock_ratelimit(Object *obj, Visitor *v, 318 const char *name, void *opaque, Error **errp) 319 { 320 X86MachineState *x86ms = X86_MACHINE(obj); 321 322 visit_type_uint64(v, name, &x86ms->bus_lock_ratelimit, errp); 323 } 324 325 static void machine_get_sgx_epc(Object *obj, Visitor *v, const char *name, 326 void *opaque, Error **errp) 327 { 328 X86MachineState *x86ms = X86_MACHINE(obj); 329 SgxEPCList *list = x86ms->sgx_epc_list; 330 331 visit_type_SgxEPCList(v, name, &list, errp); 332 } 333 334 static void machine_set_sgx_epc(Object *obj, Visitor *v, const char *name, 335 void *opaque, Error **errp) 336 { 337 X86MachineState *x86ms = X86_MACHINE(obj); 338 SgxEPCList *list; 339 340 list = x86ms->sgx_epc_list; 341 visit_type_SgxEPCList(v, name, &x86ms->sgx_epc_list, errp); 342 343 qapi_free_SgxEPCList(list); 344 } 345 346 static int x86_kvm_type(MachineState *ms, const char *vm_type) 347 { 348 /* 349 * No x86 machine has a kvm-type property. If one is added that has 350 * it, it should call kvm_get_vm_type() directly or not use it at all. 351 */ 352 assert(vm_type == NULL); 353 return kvm_enabled() ? kvm_get_vm_type(ms) : 0; 354 } 355 356 static void x86_machine_initfn(Object *obj) 357 { 358 X86MachineState *x86ms = X86_MACHINE(obj); 359 360 x86ms->smm = ON_OFF_AUTO_AUTO; 361 x86ms->acpi = ON_OFF_AUTO_AUTO; 362 x86ms->pit = ON_OFF_AUTO_AUTO; 363 x86ms->pic = ON_OFF_AUTO_AUTO; 364 x86ms->pci_irq_mask = ACPI_BUILD_PCI_IRQS; 365 x86ms->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6); 366 x86ms->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8); 367 x86ms->bus_lock_ratelimit = 0; 368 x86ms->above_4g_mem_start = 4 * GiB; 369 } 370 371 static void x86_machine_class_init(ObjectClass *oc, void *data) 372 { 373 MachineClass *mc = MACHINE_CLASS(oc); 374 X86MachineClass *x86mc = X86_MACHINE_CLASS(oc); 375 NMIClass *nc = NMI_CLASS(oc); 376 377 mc->cpu_index_to_instance_props = x86_cpu_index_to_props; 378 mc->get_default_cpu_node_id = x86_get_default_cpu_node_id; 379 mc->possible_cpu_arch_ids = x86_possible_cpu_arch_ids; 380 mc->kvm_type = x86_kvm_type; 381 x86mc->save_tsc_khz = true; 382 x86mc->fwcfg_dma_enabled = true; 383 nc->nmi_monitor_handler = x86_nmi; 384 385 object_class_property_add(oc, X86_MACHINE_SMM, "OnOffAuto", 386 x86_machine_get_smm, x86_machine_set_smm, 387 NULL, NULL); 388 object_class_property_set_description(oc, X86_MACHINE_SMM, 389 "Enable SMM"); 390 391 object_class_property_add(oc, X86_MACHINE_ACPI, "OnOffAuto", 392 x86_machine_get_acpi, x86_machine_set_acpi, 393 NULL, NULL); 394 object_class_property_set_description(oc, X86_MACHINE_ACPI, 395 "Enable ACPI"); 396 397 object_class_property_add(oc, X86_MACHINE_PIT, "OnOffAuto", 398 x86_machine_get_pit, 399 x86_machine_set_pit, 400 NULL, NULL); 401 object_class_property_set_description(oc, X86_MACHINE_PIT, 402 "Enable i8254 PIT"); 403 404 object_class_property_add(oc, X86_MACHINE_PIC, "OnOffAuto", 405 x86_machine_get_pic, 406 x86_machine_set_pic, 407 NULL, NULL); 408 object_class_property_set_description(oc, X86_MACHINE_PIC, 409 "Enable i8259 PIC"); 410 411 object_class_property_add_str(oc, X86_MACHINE_OEM_ID, 412 x86_machine_get_oem_id, 413 x86_machine_set_oem_id); 414 object_class_property_set_description(oc, X86_MACHINE_OEM_ID, 415 "Override the default value of field OEMID " 416 "in ACPI table header." 417 "The string may be up to 6 bytes in size"); 418 419 420 object_class_property_add_str(oc, X86_MACHINE_OEM_TABLE_ID, 421 x86_machine_get_oem_table_id, 422 x86_machine_set_oem_table_id); 423 object_class_property_set_description(oc, X86_MACHINE_OEM_TABLE_ID, 424 "Override the default value of field OEM Table ID " 425 "in ACPI table header." 426 "The string may be up to 8 bytes in size"); 427 428 object_class_property_add(oc, X86_MACHINE_BUS_LOCK_RATELIMIT, "uint64_t", 429 x86_machine_get_bus_lock_ratelimit, 430 x86_machine_set_bus_lock_ratelimit, NULL, NULL); 431 object_class_property_set_description(oc, X86_MACHINE_BUS_LOCK_RATELIMIT, 432 "Set the ratelimit for the bus locks acquired in VMs"); 433 434 object_class_property_add(oc, "sgx-epc", "SgxEPC", 435 machine_get_sgx_epc, machine_set_sgx_epc, 436 NULL, NULL); 437 object_class_property_set_description(oc, "sgx-epc", 438 "SGX EPC device"); 439 } 440 441 static const TypeInfo x86_machine_info = { 442 .name = TYPE_X86_MACHINE, 443 .parent = TYPE_MACHINE, 444 .abstract = true, 445 .instance_size = sizeof(X86MachineState), 446 .instance_init = x86_machine_initfn, 447 .class_size = sizeof(X86MachineClass), 448 .class_init = x86_machine_class_init, 449 .interfaces = (InterfaceInfo[]) { 450 { TYPE_NMI }, 451 { } 452 }, 453 }; 454 455 static void x86_machine_register_types(void) 456 { 457 type_register_static(&x86_machine_info); 458 } 459 460 type_init(x86_machine_register_types) 461