From f77543772dcd38fa438470d9b80bafbd3a3ebbd7 Mon Sep 17 00:00:00 2001 From: He Chen Date: Fri, 13 Jan 2017 09:53:31 +0800 Subject: [PATCH 01/13] x86: add AVX512_VPOPCNTDQ features AVX512_VPOPCNTDQ: Vector POPCNT instructions for word and qwords. variable precision. Signed-off-by: He Chen Message-Id: <1484272411-28073-1-git-send-email-he.chen@linux.intel.com> Reviewed-by: Eduardo Habkost Signed-off-by: Eduardo Habkost --- target/i386/cpu.c | 2 +- target/i386/cpu.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index aba11ae171..b6c8c5d65b 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -435,7 +435,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { NULL, "avx512vbmi", "umip", "pku", "ospke", NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, + NULL, NULL, "avx512-vpopcntdq", NULL, "la57", NULL, NULL, NULL, NULL, NULL, "rdpid", NULL, NULL, NULL, NULL, NULL, diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 6c1902b36e..10c5a3538d 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -630,6 +630,7 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS]; #define CPUID_7_0_ECX_UMIP (1U << 2) #define CPUID_7_0_ECX_PKU (1U << 3) #define CPUID_7_0_ECX_OSPKE (1U << 4) +#define CPUID_7_0_ECX_AVX512_VPOPCNTDQ (1U << 14) /* POPCNT for vectors of DW/QW */ #define CPUID_7_0_ECX_LA57 (1U << 16) #define CPUID_7_0_ECX_RDPID (1U << 22) From 2a923a293df95334fa22634016efdd138f49da7f Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Fri, 13 Jan 2017 17:00:57 -0200 Subject: [PATCH 02/13] i386: Remove AMD feature flag aliases from Opteron models When CPU vendor is set to AMD, the AMD feature alias bits on CPUID[0x80000001].EDX are already automatically copied from CPUID[1].EDX on x86_cpu_realizefn(). When CPU vendor is Intel, those bits are reserved and should be zero. On either case, those bits shouldn't be set in the CPU model table. Commit 726a8ff68677d8d5fba17eb0ffb85076bfb598dc removed those bits from most CPU models, but the Opteron_* entries still have them. Remove the alias bits from Opteron_* too. Add an assert() to x86_register_cpudef_type() to ensure we don't make the same mistake again. Signed-off-by: Eduardo Habkost Message-Id: <20170113190057.6327-1-ehabkost@redhat.com> Reviewed-by: Igor Mammedov Signed-off-by: Eduardo Habkost --- target/i386/cpu.c | 46 ++++++++++++---------------------------------- 1 file changed, 12 insertions(+), 34 deletions(-) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index b6c8c5d65b..0e5ecb3a0f 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -1339,12 +1339,7 @@ static X86CPUDefinition builtin_x86_defs[] = { .features[FEAT_1_ECX] = CPUID_EXT_SSE3, .features[FEAT_8000_0001_EDX] = - CPUID_EXT2_LM | CPUID_EXT2_FXSR | CPUID_EXT2_MMX | - CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT | - CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE | - CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC | - CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR | - CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU, + CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL, .xlevel = 0x80000008, .model_id = "AMD Opteron 240 (Gen 1 Class Opteron)", }, @@ -1365,13 +1360,7 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_EXT_CX16 | CPUID_EXT_SSE3, /* Missing: CPUID_EXT2_RDTSCP */ .features[FEAT_8000_0001_EDX] = - CPUID_EXT2_LM | CPUID_EXT2_FXSR | - CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 | - CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA | - CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | - CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE | - CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | CPUID_EXT2_PSE | - CPUID_EXT2_DE | CPUID_EXT2_FPU, + CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL, .features[FEAT_8000_0001_ECX] = CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM, .xlevel = 0x80000008, @@ -1395,13 +1384,7 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_EXT_SSE3, /* Missing: CPUID_EXT2_RDTSCP */ .features[FEAT_8000_0001_EDX] = - CPUID_EXT2_LM | CPUID_EXT2_FXSR | - CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 | - CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA | - CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | - CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE | - CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | CPUID_EXT2_PSE | - CPUID_EXT2_DE | CPUID_EXT2_FPU, + CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL, .features[FEAT_8000_0001_ECX] = CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM, @@ -1428,13 +1411,8 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_EXT_SSE3, /* Missing: CPUID_EXT2_RDTSCP */ .features[FEAT_8000_0001_EDX] = - CPUID_EXT2_LM | - CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX | - CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT | - CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE | - CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC | - CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR | - CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU, + CPUID_EXT2_LM | CPUID_EXT2_PDPE1GB | CPUID_EXT2_NX | + CPUID_EXT2_SYSCALL, .features[FEAT_8000_0001_ECX] = CPUID_EXT3_FMA4 | CPUID_EXT3_XOP | CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE | @@ -1464,13 +1442,8 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3, /* Missing: CPUID_EXT2_RDTSCP */ .features[FEAT_8000_0001_EDX] = - CPUID_EXT2_LM | - CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX | - CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT | - CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE | - CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC | - CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR | - CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU, + CPUID_EXT2_LM | CPUID_EXT2_PDPE1GB | CPUID_EXT2_NX | + CPUID_EXT2_SYSCALL, .features[FEAT_8000_0001_ECX] = CPUID_EXT3_TBM | CPUID_EXT3_FMA4 | CPUID_EXT3_XOP | CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE | @@ -2395,6 +2368,11 @@ static void x86_register_cpudef_type(X86CPUDefinition *def) .class_data = def, }; + /* AMD aliases are handled at runtime based on CPUID vendor, so + * they shouldn't be set on the CPU model table. + */ + assert(!(def->features[FEAT_8000_0001_EDX] & CPUID_EXT2_AMD_ALIASES)); + type_register(&ti); g_free(typename); } From bd72159db41d3d3c5f9afb1671d0320a77167569 Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Mon, 16 Jan 2017 16:12:12 -0200 Subject: [PATCH 03/13] i386: Return migration-safe field on query-cpu-definitions Return the migration-safe field on query-cpu-definitions. All CPU models in x86 are migration-safe except "host". Signed-off-by: Eduardo Habkost Message-Id: <20170116181212.31565-1-ehabkost@redhat.com> Acked-by: David Hildenbrand Signed-off-by: Eduardo Habkost --- target/i386/cpu-qom.h | 2 ++ target/i386/cpu.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/target/i386/cpu-qom.h b/target/i386/cpu-qom.h index 7c9a07ae65..8cd607e9a2 100644 --- a/target/i386/cpu-qom.h +++ b/target/i386/cpu-qom.h @@ -48,6 +48,7 @@ typedef struct X86CPUDefinition X86CPUDefinition; * X86CPUClass: * @cpu_def: CPU model definition * @kvm_required: Whether CPU model requires KVM to be enabled. + * @migration_safe: See CpuDefinitionInfo::migration_safe * @parent_realize: The parent class' realize handler. * @parent_reset: The parent class' reset handler. * @@ -62,6 +63,7 @@ typedef struct X86CPUClass { X86CPUDefinition *cpu_def; bool kvm_required; + bool migration_safe; /* Optional description of CPU model. * If unavailable, cpu_def->model_id is used */ diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 0e5ecb3a0f..cff23e129d 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -2209,6 +2209,8 @@ static void x86_cpu_definition_entry(gpointer data, gpointer user_data) x86_cpu_class_check_missing_features(cc, &info->unavailable_features); info->has_unavailable_features = true; info->q_typename = g_strdup(object_class_get_name(oc)); + info->migration_safe = cc->migration_safe; + info->has_migration_safe = true; entry = g_malloc0(sizeof(*entry)); entry->value = info; @@ -2356,6 +2358,7 @@ static void x86_cpu_cpudef_class_init(ObjectClass *oc, void *data) X86CPUClass *xcc = X86_CPU_CLASS(oc); xcc->cpu_def = cpudef; + xcc->migration_safe = true; } static void x86_register_cpudef_type(X86CPUDefinition *def) From 9c6703fe82b29909cf2cf35b192892327841f71a Mon Sep 17 00:00:00 2001 From: Dou Liyang Date: Tue, 17 Jan 2017 22:42:31 +0800 Subject: [PATCH 04/13] vl: Ensure the numa_post_machine_init func in the appropriate location In the numa_post_machine_init(), we use CPU_FOREACH macro to set all CPUs' namu_node. So, we should make sure that we call it after Qemu has already initialied all the CPUs. As we all know, the CPUs can be created by "-smp"(pc_new_cpu) or "-device"(qdev_device_add) command. But, before the device init, Qemu execute the numa_post_machine_init earlier. It makes the mapping of NUMA nodes and CPUs incorrect. The patch move the numa_post_machine_init func in the appropriate location. Signed-off-by: Dou Liyang Message-Id: <1484664152-24446-2-git-send-email-douly.fnst@cn.fujitsu.com> Reviewed-by: Eduardo Habkost Signed-off-by: Eduardo Habkost --- vl.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/vl.c b/vl.c index a260f30974..ed1cbe9c73 100644 --- a/vl.c +++ b/vl.c @@ -4513,8 +4513,6 @@ int main(int argc, char **argv, char **envp) cpu_synchronize_all_post_init(); - numa_post_machine_init(); - if (hax_enabled()) { hax_sync_vcpus(); } @@ -4539,6 +4537,9 @@ int main(int argc, char **argv, char **envp) device_init_func, NULL, NULL)) { exit(1); } + + numa_post_machine_init(); + rom_reset_order_override(); /* Did we create any drives that we failed to create a device for? */ From 726401be06c95cd66c91a60c702a524fdd1b6e9d Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Tue, 17 Jan 2017 16:00:51 -0200 Subject: [PATCH 05/13] arch_init: Remove unnecessary default_config_files table The existing default_config_files table in arch_init.c has a single entry, making it completely unnecessary. The whole code can be replaced by a single qemu_read_config_file() call in vl.c. Signed-off-by: Eduardo Habkost Message-Id: <20170117180051.11958-1-ehabkost@redhat.com> Reviewed-by: Paolo Bonzini Signed-off-by: Eduardo Habkost --- arch_init.c | 27 --------------------------- include/qemu/config-file.h | 4 ---- vl.c | 18 ++++++++++++++---- 3 files changed, 14 insertions(+), 35 deletions(-) diff --git a/arch_init.c b/arch_init.c index 6c4e287d57..c316ae1023 100644 --- a/arch_init.c +++ b/arch_init.c @@ -83,33 +83,6 @@ int graphic_depth = 32; const uint32_t arch_type = QEMU_ARCH; -static struct defconfig_file { - const char *filename; - /* Indicates it is an user config file (disabled by -no-user-config) */ - bool userconfig; -} default_config_files[] = { - { CONFIG_QEMU_CONFDIR "/qemu.conf", true }, - { NULL }, /* end of list */ -}; - -int qemu_read_default_config_files(bool userconfig) -{ - int ret; - struct defconfig_file *f; - - for (f = default_config_files; f->filename; f++) { - if (!userconfig && f->userconfig) { - continue; - } - ret = qemu_read_config_file(f->filename); - if (ret < 0 && ret != -ENOENT) { - return ret; - } - } - - return 0; -} - struct soundhw { const char *name; const char *descr; diff --git a/include/qemu/config-file.h b/include/qemu/config-file.h index 8d4b2b6d94..c80d5c8a33 100644 --- a/include/qemu/config-file.h +++ b/include/qemu/config-file.h @@ -23,8 +23,4 @@ int qemu_read_config_file(const char *filename); void qemu_config_parse_qdict(QDict *options, QemuOptsList **lists, Error **errp); -/* Read default QEMU config files - */ -int qemu_read_default_config_files(bool userconfig); - #endif /* QEMU_CONFIG_FILE_H */ diff --git a/vl.c b/vl.c index ed1cbe9c73..abb0900fe4 100644 --- a/vl.c +++ b/vl.c @@ -2950,6 +2950,18 @@ static int global_init_func(void *opaque, QemuOpts *opts, Error **errp) return 0; } +static int qemu_read_default_config_file(void) +{ + int ret; + + ret = qemu_read_config_file(CONFIG_QEMU_CONFDIR "/qemu.conf"); + if (ret < 0 && ret != -ENOENT) { + return ret; + } + + return 0; +} + int main(int argc, char **argv, char **envp) { int i; @@ -3077,10 +3089,8 @@ int main(int argc, char **argv, char **envp) } } - if (defconfig) { - int ret; - ret = qemu_read_default_config_files(userconfig); - if (ret < 0) { + if (defconfig && userconfig) { + if (qemu_read_default_config_file() < 0) { exit(1); } } From f2098f483589ed894f732acab0dde48c8822a5ac Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Jan 2017 18:13:18 +0100 Subject: [PATCH 06/13] pc: cleanup: move smbios_set_cpuid() into pc_build_smbios() move smbios_set_cpuid() close to the rest of smbios init code where it belongs to instead of calling it from pc_cpus_init(). Signed-off-by: Igor Mammedov Message-Id: <1484759609-264075-3-git-send-email-imammedo@redhat.com> Reviewed-by: Eduardo Habkost Signed-off-by: Eduardo Habkost --- hw/i386/pc.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index f721fde0c2..c0d0d2c6a1 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -701,16 +701,20 @@ static uint32_t x86_cpu_apic_id_from_index(unsigned int cpu_index) } } -static void pc_build_smbios(FWCfgState *fw_cfg) +static void pc_build_smbios(PCMachineState *pcms) { uint8_t *smbios_tables, *smbios_anchor; size_t smbios_tables_len, smbios_anchor_len; struct smbios_phys_mem_area *mem_array; unsigned i, array_count; + X86CPU *cpu = X86_CPU(pcms->possible_cpus->cpus[0].cpu); + + /* tell smbios about cpuid version and features */ + smbios_set_cpuid(cpu->env.cpuid_version, cpu->env.features[FEAT_1_EDX]); smbios_tables = smbios_get_table_legacy(&smbios_tables_len); if (smbios_tables) { - fw_cfg_add_bytes(fw_cfg, FW_CFG_SMBIOS_ENTRIES, + fw_cfg_add_bytes(pcms->fw_cfg, FW_CFG_SMBIOS_ENTRIES, smbios_tables, smbios_tables_len); } @@ -731,9 +735,9 @@ static void pc_build_smbios(FWCfgState *fw_cfg) g_free(mem_array); if (smbios_anchor) { - fw_cfg_add_file(fw_cfg, "etc/smbios/smbios-tables", + fw_cfg_add_file(pcms->fw_cfg, "etc/smbios/smbios-tables", smbios_tables, smbios_tables_len); - fw_cfg_add_file(fw_cfg, "etc/smbios/smbios-anchor", + fw_cfg_add_file(pcms->fw_cfg, "etc/smbios/smbios-anchor", smbios_anchor, smbios_anchor_len); } } @@ -1191,9 +1195,6 @@ void pc_cpus_init(PCMachineState *pcms) object_unref(OBJECT(cpu)); } } - - /* tell smbios about cpuid version and features */ - smbios_set_cpuid(cpu->env.cpuid_version, cpu->env.features[FEAT_1_EDX]); } static void pc_build_feature_control_file(PCMachineState *pcms) @@ -1266,7 +1267,7 @@ void pc_machine_done(Notifier *notifier, void *data) acpi_setup(); if (pcms->fw_cfg) { - pc_build_smbios(pcms->fw_cfg); + pc_build_smbios(pcms); pc_build_feature_control_file(pcms); /* update FW_CFG_NB_CPUS to account for -device added CPUs */ fw_cfg_modify_i16(pcms->fw_cfg, FW_CFG_NB_CPUS, pcms->boot_cpus); From 074281d62e62f3efab3b71161e9f0a5e8aebb0b3 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Jan 2017 18:13:19 +0100 Subject: [PATCH 07/13] pc: don't return cpu pointer from pc_new_cpu() as it's not needed anymore Signed-off-by: Igor Mammedov Message-Id: <1484759609-264075-4-git-send-email-imammedo@redhat.com> Reviewed-by: Eduardo Habkost Signed-off-by: Eduardo Habkost --- hw/i386/pc.c | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index c0d0d2c6a1..079346ac5d 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1092,28 +1092,24 @@ void pc_acpi_smi_interrupt(void *opaque, int irq, int level) } } -static X86CPU *pc_new_cpu(const char *typename, int64_t apic_id, - Error **errp) +static void pc_new_cpu(const char *typename, int64_t apic_id, Error **errp) { - X86CPU *cpu = NULL; + Object *cpu = NULL; Error *local_err = NULL; - cpu = X86_CPU(object_new(typename)); + cpu = object_new(typename); - object_property_set_int(OBJECT(cpu), apic_id, "apic-id", &local_err); - object_property_set_bool(OBJECT(cpu), true, "realized", &local_err); + object_property_set_int(cpu, apic_id, "apic-id", &local_err); + object_property_set_bool(cpu, true, "realized", &local_err); + object_unref(cpu); if (local_err) { error_propagate(errp, local_err); - object_unref(OBJECT(cpu)); - cpu = NULL; } - return cpu; } void pc_hot_add_cpu(const int64_t id, Error **errp) { - X86CPU *cpu; ObjectClass *oc; PCMachineState *pcms = PC_MACHINE(qdev_get_machine()); int64_t apic_id = x86_cpu_apic_id_from_index(id); @@ -1133,12 +1129,11 @@ void pc_hot_add_cpu(const int64_t id, Error **errp) assert(pcms->possible_cpus->cpus[0].cpu); /* BSP is always present */ oc = OBJECT_CLASS(CPU_GET_CLASS(pcms->possible_cpus->cpus[0].cpu)); - cpu = pc_new_cpu(object_class_get_name(oc), apic_id, &local_err); + pc_new_cpu(object_class_get_name(oc), apic_id, &local_err); if (local_err) { error_propagate(errp, local_err); return; } - object_unref(OBJECT(cpu)); } void pc_cpus_init(PCMachineState *pcms) @@ -1148,7 +1143,6 @@ void pc_cpus_init(PCMachineState *pcms) ObjectClass *oc; const char *typename; gchar **model_pieces; - X86CPU *cpu = NULL; MachineState *machine = MACHINE(pcms); /* init CPUs */ @@ -1190,9 +1184,7 @@ void pc_cpus_init(PCMachineState *pcms) pcms->possible_cpus->cpus[i].arch_id = x86_cpu_apic_id_from_index(i); pcms->possible_cpus->len++; if (i < smp_cpus) { - cpu = pc_new_cpu(typename, x86_cpu_apic_id_from_index(i), - &error_fatal); - object_unref(OBJECT(cpu)); + pc_new_cpu(typename, x86_cpu_apic_id_from_index(i), &error_fatal); } } } From 80e5db303dc82e357df923dc2bfcb858c20282a0 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Jan 2017 18:13:20 +0100 Subject: [PATCH 08/13] machine: Make possible_cpu_arch_ids() return const pointer make sure that external callers won't try to modify possible_cpus and owner of possible_cpus can access it directly when it modifies it. Signed-off-by: Igor Mammedov Message-Id: <1484759609-264075-5-git-send-email-imammedo@redhat.com> Reviewed-by: Eduardo Habkost Signed-off-by: Eduardo Habkost --- hw/acpi/cpu.c | 6 ++---- hw/acpi/cpu_hotplug.c | 4 +--- hw/i386/acpi-build.c | 8 +++----- hw/i386/pc.c | 10 +++------- include/hw/acpi/acpi_dev_interface.h | 2 +- include/hw/boards.h | 2 +- include/hw/i386/pc.h | 2 +- stubs/pc_madt_cpu_entry.c | 2 +- 8 files changed, 13 insertions(+), 23 deletions(-) diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c index 5ac89fefaf..6017ca04bf 100644 --- a/hw/acpi/cpu.c +++ b/hw/acpi/cpu.c @@ -190,7 +190,7 @@ void cpu_hotplug_hw_init(MemoryRegion *as, Object *owner, { MachineState *machine = MACHINE(qdev_get_machine()); MachineClass *mc = MACHINE_GET_CLASS(machine); - CPUArchIdList *id_list; + const CPUArchIdList *id_list; int i; assert(mc->possible_cpu_arch_ids); @@ -201,7 +201,6 @@ void cpu_hotplug_hw_init(MemoryRegion *as, Object *owner, state->devs[i].cpu = id_list->cpus[i].cpu; state->devs[i].arch_id = id_list->cpus[i].arch_id; } - g_free(id_list); memory_region_init_io(&state->ctrl_reg, owner, &cpu_hotplug_ops, state, "acpi-mem-hotplug", ACPI_CPU_HOTPLUG_REG_LEN); memory_region_add_subregion(as, base_addr, &state->ctrl_reg); @@ -325,7 +324,7 @@ void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts, Aml *one = aml_int(1); Aml *sb_scope = aml_scope("_SB"); MachineClass *mc = MACHINE_GET_CLASS(machine); - CPUArchIdList *arch_ids = mc->possible_cpu_arch_ids(machine); + const CPUArchIdList *arch_ids = mc->possible_cpu_arch_ids(machine); char *cphp_res_path = g_strdup_printf("%s." CPUHP_RES_DEVICE, res_root); Object *obj = object_resolve_path_type("", TYPE_ACPI_DEVICE_IF, NULL); AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_GET_CLASS(obj); @@ -574,5 +573,4 @@ void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts, aml_append(table, method); g_free(cphp_res_path); - g_free(arch_ids); } diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c index f15a2402fc..5243918125 100644 --- a/hw/acpi/cpu_hotplug.c +++ b/hw/acpi/cpu_hotplug.c @@ -128,7 +128,7 @@ void build_legacy_cpu_hotplug_aml(Aml *ctx, MachineState *machine, Aml *zero = aml_int(0); Aml *one = aml_int(1); MachineClass *mc = MACHINE_GET_CLASS(machine); - CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(machine); + const CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(machine); PCMachineState *pcms = PC_MACHINE(machine); /* @@ -329,8 +329,6 @@ void build_legacy_cpu_hotplug_aml(Aml *ctx, MachineState *machine, apic_idx = apic_id + 1; } aml_append(sb_scope, aml_name_decl(CPU_ON_BITMAP, pkg)); - g_free(apic_ids); - aml_append(ctx, sb_scope); method = aml_method("\\_GPE._E02", 0, AML_NOTSERIALIZED); diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index a1d781ae42..1c928abb28 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -332,7 +332,7 @@ build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm, } void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid, - CPUArchIdList *apic_ids, GArray *entry) + const CPUArchIdList *apic_ids, GArray *entry) { uint32_t apic_id = apic_ids->cpus[uid].arch_id; @@ -373,7 +373,7 @@ static void build_madt(GArray *table_data, BIOSLinker *linker, PCMachineState *pcms) { MachineClass *mc = MACHINE_GET_CLASS(pcms); - CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(MACHINE(pcms)); + const CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(MACHINE(pcms)); int madt_start = table_data->len; AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_GET_CLASS(pcms->acpi_dev); AcpiDeviceIf *adev = ACPI_DEVICE_IF(pcms->acpi_dev); @@ -394,7 +394,6 @@ build_madt(GArray *table_data, BIOSLinker *linker, PCMachineState *pcms) x2apic_mode = true; } } - g_free(apic_ids); io_apic = acpi_data_push(table_data, sizeof *io_apic); io_apic->type = ACPI_APIC_IO; @@ -2294,7 +2293,7 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine) int srat_start, numa_start, slots; uint64_t mem_len, mem_base, next_base; MachineClass *mc = MACHINE_GET_CLASS(machine); - CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(machine); + const CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(machine); PCMachineState *pcms = PC_MACHINE(machine); ram_addr_t hotplugabble_address_space_size = object_property_get_int(OBJECT(pcms), PC_MACHINE_MEMHP_REGION_SIZE, @@ -2393,7 +2392,6 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine) (void *)(table_data->data + srat_start), "SRAT", table_data->len - srat_start, 1, NULL, NULL); - g_free(apic_ids); } static void diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 079346ac5d..c949cf0ecc 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -2240,15 +2240,11 @@ static unsigned pc_cpu_index_to_socket_id(unsigned cpu_index) return topo.pkg_id; } -static CPUArchIdList *pc_possible_cpu_arch_ids(MachineState *machine) +static const CPUArchIdList *pc_possible_cpu_arch_ids(MachineState *machine) { PCMachineState *pcms = PC_MACHINE(machine); - int len = sizeof(CPUArchIdList) + - sizeof(CPUArchId) * (pcms->possible_cpus->len); - CPUArchIdList *list = g_malloc(len); - - memcpy(list, pcms->possible_cpus, len); - return list; + assert(pcms->possible_cpus); + return pcms->possible_cpus; } static HotpluggableCPUList *pc_query_hotpluggable_cpus(MachineState *machine) diff --git a/include/hw/acpi/acpi_dev_interface.h b/include/hw/acpi/acpi_dev_interface.h index 901a4ae876..71d3c48e7d 100644 --- a/include/hw/acpi/acpi_dev_interface.h +++ b/include/hw/acpi/acpi_dev_interface.h @@ -57,6 +57,6 @@ typedef struct AcpiDeviceIfClass { void (*ospm_status)(AcpiDeviceIf *adev, ACPIOSTInfoList ***list); void (*send_event)(AcpiDeviceIf *adev, AcpiEventStatusBits ev); void (*madt_cpu)(AcpiDeviceIf *adev, int uid, - CPUArchIdList *apic_ids, GArray *entry); + const CPUArchIdList *apic_ids, GArray *entry); } AcpiDeviceIfClass; #endif diff --git a/include/hw/boards.h b/include/hw/boards.h index a51da9c440..ac891a828b 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -135,7 +135,7 @@ struct MachineClass { HotplugHandler *(*get_hotplug_handler)(MachineState *machine, DeviceState *dev); unsigned (*cpu_index_to_socket_id)(unsigned cpu_index); - CPUArchIdList *(*possible_cpu_arch_ids)(MachineState *machine); + const CPUArchIdList *(*possible_cpu_arch_ids)(MachineState *machine); HotpluggableCPUList *(*query_hotpluggable_cpus)(MachineState *machine); }; diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 738bfd6c60..5a20c5e38e 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -361,7 +361,7 @@ uint16_t pvpanic_port(void); /* acpi-build.c */ void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid, - CPUArchIdList *apic_ids, GArray *entry); + const CPUArchIdList *apic_ids, GArray *entry); /* e820 types */ #define E820_RAM 1 diff --git a/stubs/pc_madt_cpu_entry.c b/stubs/pc_madt_cpu_entry.c index 427e772868..f88d6a090b 100644 --- a/stubs/pc_madt_cpu_entry.c +++ b/stubs/pc_madt_cpu_entry.c @@ -2,6 +2,6 @@ #include "hw/i386/pc.h" void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid, - CPUArchIdList *apic_ids, GArray *entry) + const CPUArchIdList *apic_ids, GArray *entry) { } From c1629c5ce3a23053abcfaf7760356b214a750e3c Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Mon, 23 Jan 2017 06:54:55 +0100 Subject: [PATCH 09/13] MAINTAINERS: Add an entry for hw/core/null-machine.c The "Machine core" section sounds like a good match for this file. Signed-off-by: Thomas Huth Message-Id: <1485150895-19753-1-git-send-email-thuth@redhat.com> Reviewed-by: Marcel Apfelbaum Signed-off-by: Eduardo Habkost --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index ad1000415d..57bd0276e3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -813,6 +813,7 @@ M: Eduardo Habkost M: Marcel Apfelbaum S: Supported F: hw/core/machine.c +F: hw/core/null-machine.c F: include/hw/boards.h Xtensa Machines From e0ee9fd0bd8544e65f978f78162048b68cfde514 Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Mon, 23 Jan 2017 16:06:31 -0200 Subject: [PATCH 10/13] qemu-options: Rename variables on the -numa "cpus" option Use @var{firstcpu} and @var{lastcpu} to make the metasyntatic variables a bit clearer. While doing this, use @var only around the metasyntatic variables, not including the square brackets and hyphen. The semantics of the "cpus" option will be clarified by rewriting the whole -numa documentation in a follow-up patch. Reported-by: Peter Maydell Signed-off-by: Eduardo Habkost Message-Id: <20170123180632.28942-2-ehabkost@redhat.com> Reviewed-by: Peter Maydell Signed-off-by: Eduardo Habkost --- qemu-options.hx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/qemu-options.hx b/qemu-options.hx index 80df52651a..780528d6ad 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -119,11 +119,11 @@ specifies the maximum number of hotpluggable CPUs. ETEXI DEF("numa", HAS_ARG, QEMU_OPTION_numa, - "-numa node[,mem=size][,cpus=cpu[-cpu]][,nodeid=node]\n" - "-numa node[,memdev=id][,cpus=cpu[-cpu]][,nodeid=node]\n", QEMU_ARCH_ALL) + "-numa node[,mem=size][,cpus=firstcpu[-lastcpu]][,nodeid=node]\n" + "-numa node[,memdev=id][,cpus=firstcpu[-lastcpu]][,nodeid=node]\n", QEMU_ARCH_ALL) STEXI -@item -numa node[,mem=@var{size}][,cpus=@var{cpu[-cpu]}][,nodeid=@var{node}] -@itemx -numa node[,memdev=@var{id}][,cpus=@var{cpu[-cpu]}][,nodeid=@var{node}] +@item -numa node[,mem=@var{size}][,cpus=@var{firstcpu}[-@var{lastcpu}]][,nodeid=@var{node}] +@itemx -numa node[,memdev=@var{id}][,cpus=@var{firstcpu}[-@var{lastcpu}]][,nodeid=@var{node}] @findex -numa Simulate a multi node NUMA system. If @samp{mem}, @samp{memdev} and @samp{cpus} are omitted, resources are split equally. Also, note From 3964ec6c0b49e4c2fa3e48fdbbb7d8ff0c1cb00b Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Wed, 18 Jan 2017 13:44:50 +0100 Subject: [PATCH 11/13] hw/core/null-machine: Add the possibility to instantiate a CPU and RAM Sometimes it is useful to have just a machine with CPU and RAM, without any further hardware in it, e.g. if you just want to do some instruction debugging for TCG with a remote GDB attached to QEMU, or run some embedded code with the "-semihosting" QEMU parameter. qemu-system-m68k already features a "dummy" machine, and xtensa a "sim" machine for exactly this purpose. All target architectures have nowadays also a "none" machine, which would be a perfect match for this, too - but it currently does not allow to add CPU and RAM yet. Thus let's add these possibilities in a generic way to the "none" machine, too, so that we hopefully do not need additional "dummy" machines in the future anymore (and maybe can also get rid of the already existing "dummy"/"sim" machines one day). Note that the default behaviour of the "none" machine is not changed, i.e. no CPU and no RAM is instantiated by default. You have explicitely got to specify the CPU model with "-cpu" and the amount of RAM with "-m" to get these new features. Signed-off-by: Thomas Huth Message-Id: <1484743490-24721-1-git-send-email-thuth@redhat.com> Reviewed-by: Eduardo Habkost Reviewed-by: Alistair Francis Signed-off-by: Eduardo Habkost --- hw/core/Makefile.objs | 2 +- hw/core/null-machine.c | 27 +++++++++++++++++++++++++-- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs index 833fd46897..7f8c9dc659 100644 --- a/hw/core/Makefile.objs +++ b/hw/core/Makefile.objs @@ -12,7 +12,6 @@ common-obj-$(CONFIG_XILINX_AXI) += stream.o common-obj-$(CONFIG_PTIMER) += ptimer.o common-obj-$(CONFIG_SOFTMMU) += sysbus.o common-obj-$(CONFIG_SOFTMMU) += machine.o -common-obj-$(CONFIG_SOFTMMU) += null-machine.o common-obj-$(CONFIG_SOFTMMU) += loader.o common-obj-$(CONFIG_SOFTMMU) += qdev-properties-system.o common-obj-$(CONFIG_SOFTMMU) += register.o @@ -20,3 +19,4 @@ common-obj-$(CONFIG_SOFTMMU) += or-irq.o common-obj-$(CONFIG_PLATFORM_BUS) += platform-bus.o obj-$(CONFIG_SOFTMMU) += generic-loader.o +obj-$(CONFIG_SOFTMMU) += null-machine.o diff --git a/hw/core/null-machine.c b/hw/core/null-machine.c index 0351ba7828..27c8369b57 100644 --- a/hw/core/null-machine.c +++ b/hw/core/null-machine.c @@ -13,18 +13,41 @@ #include "qemu/osdep.h" #include "qemu-common.h" +#include "qemu/error-report.h" #include "hw/hw.h" #include "hw/boards.h" +#include "sysemu/sysemu.h" +#include "exec/address-spaces.h" +#include "cpu.h" -static void machine_none_init(MachineState *machine) +static void machine_none_init(MachineState *mch) { + CPUState *cpu = NULL; + + /* Initialize CPU (if a model has been specified) */ + if (mch->cpu_model) { + cpu = cpu_init(mch->cpu_model); + if (!cpu) { + error_report("Unable to initialize CPU"); + exit(1); + } + } + + /* RAM at address zero */ + if (mch->ram_size) { + MemoryRegion *ram = g_new(MemoryRegion, 1); + + memory_region_allocate_system_memory(ram, NULL, "ram", mch->ram_size); + memory_region_add_subregion(get_system_memory(), 0, ram); + } } static void machine_none_machine_init(MachineClass *mc) { mc->desc = "empty machine"; mc->init = machine_none_init; - mc->max_cpus = 0; + mc->max_cpus = 1; + mc->default_ram_size = 0; } DEFINE_MACHINE("none", machine_none_machine_init) From d74460ec1bfaad740eee79bf7cb111b1125ffdef Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Sun, 8 Jan 2017 15:32:33 -0200 Subject: [PATCH 12/13] kvm: Simplify invtsc check Instead of searching the table we have just built, we can check the env->features field directly. Reviewed-by: Marcelo Tosatti Signed-off-by: Eduardo Habkost Message-Id: <20170108173234.25721-2-ehabkost@redhat.com> Signed-off-by: Eduardo Habkost --- target/i386/kvm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target/i386/kvm.c b/target/i386/kvm.c index e6c4f754ab..9744552b8a 100644 --- a/target/i386/kvm.c +++ b/target/i386/kvm.c @@ -963,8 +963,8 @@ int kvm_arch_init_vcpu(CPUState *cs) has_msr_mcg_ext_ctl = has_msr_feature_control = true; } - c = cpuid_find_entry(&cpuid_data.cpuid, 0x80000007, 0); - if (c && (c->edx & 1<<8) && invtsc_mig_blocker == NULL) { + if ((env->features[FEAT_8000_0007_EDX] & CPUID_APM_INVTSC) && + invtsc_mig_blocker == NULL) { /* for migration */ error_setg(&invtsc_mig_blocker, "State blocked by non-migratable CPU device" From d99569d9d8562c480e0befab601756b0b7b5d0e0 Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Sun, 8 Jan 2017 15:32:34 -0200 Subject: [PATCH 13/13] kvm: Allow invtsc migration if tsc-khz is set explicitly We can safely allow a VM to be migrated with invtsc enabled if tsc-khz is set explicitly, because: * QEMU already refuses to start if it can't set the TSC frequency to the configured value. * Management software is already required to keep device configuration (including CPU configuration) the same on migration source and destination. Signed-off-by: Eduardo Habkost Message-Id: <20170108173234.25721-3-ehabkost@redhat.com> Signed-off-by: Eduardo Habkost --- target/i386/kvm.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/target/i386/kvm.c b/target/i386/kvm.c index 9744552b8a..3b5282186c 100644 --- a/target/i386/kvm.c +++ b/target/i386/kvm.c @@ -963,15 +963,17 @@ int kvm_arch_init_vcpu(CPUState *cs) has_msr_mcg_ext_ctl = has_msr_feature_control = true; } - if ((env->features[FEAT_8000_0007_EDX] & CPUID_APM_INVTSC) && - invtsc_mig_blocker == NULL) { - /* for migration */ - error_setg(&invtsc_mig_blocker, - "State blocked by non-migratable CPU device" - " (invtsc flag)"); - migrate_add_blocker(invtsc_mig_blocker); - /* for savevm */ - vmstate_x86_cpu.unmigratable = 1; + if (!env->user_tsc_khz) { + if ((env->features[FEAT_8000_0007_EDX] & CPUID_APM_INVTSC) && + invtsc_mig_blocker == NULL) { + /* for migration */ + error_setg(&invtsc_mig_blocker, + "State blocked by non-migratable CPU device" + " (invtsc flag)"); + migrate_add_blocker(invtsc_mig_blocker); + /* for savevm */ + vmstate_x86_cpu.unmigratable = 1; + } } cpuid_data.cpuid.padding = 0;