From 7dfddd7f884b6dd2abf230d8fa6c7c83aab4f5ec Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Mon, 29 Sep 2014 22:21:45 -0300 Subject: [PATCH 01/28] smbios: Fix assertion on socket count calculation QEMU currently allows the number of VCPUs to not be a multiple of the number of threads per socket, but the smbios socket count calculation introduced by commit c97294ec1b9e36887e119589d456557d72ab37b5 doesn't take that into account, triggering an assertion. e.g.: $ ./x86_64-softmmu/qemu-system-x86_64 -smp 4,sockets=2,cores=6,threads=1 qemu-system-x86_64: /home/ehabkost/rh/proj/virt/qemu/hw/i386/smbios.c:825: smbios_get_tables: Assertion `smbios_smp_sockets >= 1' failed. Aborted (core dumped) Socket count calculation doesn't belong to smbios.c and should eventually be moved to the main SMP topology configuration code. But while we don't move the code, at least make it correct by rounding up the division. Cc: Gabriel Somlo Cc: qemu-stable@nongnu.org Signed-off-by: Eduardo Habkost Reviewed-By: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/smbios.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/i386/smbios.c b/hw/i386/smbios.c index e3fa1b2fc1..0ae5960b8c 100644 --- a/hw/i386/smbios.c +++ b/hw/i386/smbios.c @@ -821,7 +821,7 @@ void smbios_get_tables(uint8_t **tables, size_t *tables_len, smbios_build_type_2_table(); smbios_build_type_3_table(); - smbios_smp_sockets = smp_cpus / (smp_cores * smp_threads); + smbios_smp_sockets = DIV_ROUND_UP(smp_cpus, smp_cores * smp_threads); assert(smbios_smp_sockets >= 1); for (i = 0; i < smbios_smp_sockets; i++) { From 2709f263952bab66fc8f971c04d151216b177336 Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Mon, 22 Sep 2014 22:38:35 +0200 Subject: [PATCH 02/28] well-defined listing order for machine types Commit 261747f1 ("vl: Use MachineClass instead of global QEMUMachine list") broke the ordering of the machine types in the user-visible output of qemu-system-XXXX -M \? This occurred because registration was rebased from a manually maintained linked list to GLib hash tables: qemu_register_machine() type_register() type_register_internal() type_table_add() g_hash_table_insert() and because the listing was rebased accordingly, from the traversal of the list to the traversal of the hash table (rendered as an ad-hoc list): machine_parse() object_class_get_list(TYPE_MACHINE) object_class_foreach() g_hash_table_foreach() The current order is a "random" one, for practical purposes, which is annoying for users. Introduce new members QEMUMachine.family and MachineClass.family, allowing machine types to be "clustered". Introduce a comparator function that establishes a total ordering between machine types, ordering machine types in the same family next to each other. In machine_parse(), list the supported machine types sorted with the comparator function. The comparator function: - sorts whole families before standalone machine types, - sorts whole families between each other in alphabetically increasing order, - sorts machine types inside the same family in alphabetically decreasing order, - sorts standalone machine types between each other in alphabetically increasing order. After this patch, all machine types are considered standalone, and accordingly, the output is alphabetically ascending. This will be refined in the following patches. Effects on the x86_64 output: Before: > Supported machines are: > pc-0.13 Standard PC (i440FX + PIIX, 1996) > pc-i440fx-2.0 Standard PC (i440FX + PIIX, 1996) > pc-1.0 Standard PC (i440FX + PIIX, 1996) > pc-i440fx-2.1 Standard PC (i440FX + PIIX, 1996) > pc-q35-1.7 Standard PC (Q35 + ICH9, 2009) > pc-1.1 Standard PC (i440FX + PIIX, 1996) > pc-0.14 Standard PC (i440FX + PIIX, 1996) > pc-q35-2.0 Standard PC (Q35 + ICH9, 2009) > pc-i440fx-1.4 Standard PC (i440FX + PIIX, 1996) > pc-i440fx-1.5 Standard PC (i440FX + PIIX, 1996) > pc-0.15 Standard PC (i440FX + PIIX, 1996) > pc-q35-1.4 Standard PC (Q35 + ICH9, 2009) > isapc ISA-only PC > pc Standard PC (i440FX + PIIX, 1996) (alias of pc-i440fx-2.2) > pc-i440fx-2.2 Standard PC (i440FX + PIIX, 1996) (default) > pc-1.2 Standard PC (i440FX + PIIX, 1996) > pc-0.10 Standard PC (i440FX + PIIX, 1996) > pc-0.11 Standard PC (i440FX + PIIX, 1996) > pc-q35-2.1 Standard PC (Q35 + ICH9, 2009) > q35 Standard PC (Q35 + ICH9, 2009) (alias of pc-q35-2.2) > pc-q35-2.2 Standard PC (Q35 + ICH9, 2009) > pc-i440fx-1.6 Standard PC (i440FX + PIIX, 1996) > pc-i440fx-1.7 Standard PC (i440FX + PIIX, 1996) > none empty machine > pc-q35-1.5 Standard PC (Q35 + ICH9, 2009) > pc-q35-1.6 Standard PC (Q35 + ICH9, 2009) > pc-0.12 Standard PC (i440FX + PIIX, 1996) > pc-1.3 Standard PC (i440FX + PIIX, 1996) After: > Supported machines are: > isapc ISA-only PC > none empty machine > pc-0.10 Standard PC (i440FX + PIIX, 1996) > pc-0.11 Standard PC (i440FX + PIIX, 1996) > pc-0.12 Standard PC (i440FX + PIIX, 1996) > pc-0.13 Standard PC (i440FX + PIIX, 1996) > pc-0.14 Standard PC (i440FX + PIIX, 1996) > pc-0.15 Standard PC (i440FX + PIIX, 1996) > pc-1.0 Standard PC (i440FX + PIIX, 1996) > pc-1.1 Standard PC (i440FX + PIIX, 1996) > pc-1.2 Standard PC (i440FX + PIIX, 1996) > pc-1.3 Standard PC (i440FX + PIIX, 1996) > pc-i440fx-1.4 Standard PC (i440FX + PIIX, 1996) > pc-i440fx-1.5 Standard PC (i440FX + PIIX, 1996) > pc-i440fx-1.6 Standard PC (i440FX + PIIX, 1996) > pc-i440fx-1.7 Standard PC (i440FX + PIIX, 1996) > pc-i440fx-2.0 Standard PC (i440FX + PIIX, 1996) > pc-i440fx-2.1 Standard PC (i440FX + PIIX, 1996) > pc Standard PC (i440FX + PIIX, 1996) (alias of pc-i440fx-2.2) > pc-i440fx-2.2 Standard PC (i440FX + PIIX, 1996) (default) > pc-q35-1.4 Standard PC (Q35 + ICH9, 2009) > pc-q35-1.5 Standard PC (Q35 + ICH9, 2009) > pc-q35-1.6 Standard PC (Q35 + ICH9, 2009) > pc-q35-1.7 Standard PC (Q35 + ICH9, 2009) > pc-q35-2.0 Standard PC (Q35 + ICH9, 2009) > pc-q35-2.1 Standard PC (Q35 + ICH9, 2009) > q35 Standard PC (Q35 + ICH9, 2009) (alias of pc-q35-2.2) > pc-q35-2.2 Standard PC (Q35 + ICH9, 2009) Effects on the aarch64 output: Before: > Supported machines are: > lm3s811evb Stellaris LM3S811EVB > canon-a1100 Canon PowerShot A1100 IS > vexpress-a15 ARM Versatile Express for Cortex-A15 > vexpress-a9 ARM Versatile Express for Cortex-A9 > xilinx-zynq-a9 Xilinx Zynq Platform Baseboard for Cortex-A9 > connex Gumstix Connex (PXA255) > n800 Nokia N800 tablet aka. RX-34 (OMAP2420) > lm3s6965evb Stellaris LM3S6965EVB > versatileab ARM Versatile/AB (ARM926EJ-S) > borzoi Borzoi PDA (PXA270) > tosa Tosa PDA (PXA255) > cheetah Palm Tungsten|E aka. Cheetah PDA (OMAP310) > midway Calxeda Midway (ECX-2000) > mainstone Mainstone II (PXA27x) > n810 Nokia N810 tablet aka. RX-44 (OMAP2420) > terrier Terrier PDA (PXA270) > highbank Calxeda Highbank (ECX-1000) > cubieboard cubietech cubieboard > sx1-v1 Siemens SX1 (OMAP310) V1 > sx1 Siemens SX1 (OMAP310) V2 > realview-eb-mpcore ARM RealView Emulation Baseboard (ARM11MPCore) > kzm ARM KZM Emulation Baseboard (ARM1136) > akita Akita PDA (PXA270) > z2 Zipit Z2 (PXA27x) > musicpal Marvell 88w8618 / MusicPal (ARM926EJ-S) > realview-pb-a8 ARM RealView Platform Baseboard for Cortex-A8 > versatilepb ARM Versatile/PB (ARM926EJ-S) > realview-eb ARM RealView Emulation Baseboard (ARM926EJ-S) > realview-pbx-a9 ARM RealView Platform Baseboard Explore for Cortex-A9 > spitz Spitz PDA (PXA270) > none empty machine > virt ARM Virtual Machine > collie Collie PDA (SA-1110) > smdkc210 Samsung SMDKC210 board (Exynos4210) > verdex Gumstix Verdex (PXA270) > nuri Samsung NURI board (Exynos4210) > integratorcp ARM Integrator/CP (ARM926EJ-S) After: > Supported machines are: > akita Akita PDA (PXA270) > borzoi Borzoi PDA (PXA270) > canon-a1100 Canon PowerShot A1100 IS > cheetah Palm Tungsten|E aka. Cheetah PDA (OMAP310) > collie Collie PDA (SA-1110) > connex Gumstix Connex (PXA255) > cubieboard cubietech cubieboard > highbank Calxeda Highbank (ECX-1000) > integratorcp ARM Integrator/CP (ARM926EJ-S) > kzm ARM KZM Emulation Baseboard (ARM1136) > lm3s6965evb Stellaris LM3S6965EVB > lm3s811evb Stellaris LM3S811EVB > mainstone Mainstone II (PXA27x) > midway Calxeda Midway (ECX-2000) > musicpal Marvell 88w8618 / MusicPal (ARM926EJ-S) > n800 Nokia N800 tablet aka. RX-34 (OMAP2420) > n810 Nokia N810 tablet aka. RX-44 (OMAP2420) > none empty machine > nuri Samsung NURI board (Exynos4210) > realview-eb ARM RealView Emulation Baseboard (ARM926EJ-S) > realview-eb-mpcore ARM RealView Emulation Baseboard (ARM11MPCore) > realview-pb-a8 ARM RealView Platform Baseboard for Cortex-A8 > realview-pbx-a9 ARM RealView Platform Baseboard Explore for Cortex-A9 > smdkc210 Samsung SMDKC210 board (Exynos4210) > spitz Spitz PDA (PXA270) > sx1 Siemens SX1 (OMAP310) V2 > sx1-v1 Siemens SX1 (OMAP310) V1 > terrier Terrier PDA (PXA270) > tosa Tosa PDA (PXA255) > verdex Gumstix Verdex (PXA270) > versatileab ARM Versatile/AB (ARM926EJ-S) > versatilepb ARM Versatile/PB (ARM926EJ-S) > vexpress-a15 ARM Versatile Express for Cortex-A15 > vexpress-a9 ARM Versatile Express for Cortex-A9 > virt ARM Virtual Machine > xilinx-zynq-a9 Xilinx Zynq Platform Baseboard for Cortex-A9 > z2 Zipit Z2 (PXA27x) RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1145042 Signed-off-by: Laszlo Ersek Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Paolo Bonzini Reviewed-by: Marcel Apfelbaum Acked-by: David Gibson --- hw/i386/pc.c | 1 + include/hw/boards.h | 2 ++ vl.c | 38 +++++++++++++++++++++++++++++++++++++- 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 61aba9fc54..f70ff28c05 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1516,6 +1516,7 @@ static void pc_generic_machine_class_init(ObjectClass *oc, void *data) MachineClass *mc = MACHINE_CLASS(oc); QEMUMachine *qm = data; + mc->family = qm->family; mc->name = qm->name; mc->alias = qm->alias; mc->desc = qm->desc; diff --git a/include/hw/boards.h b/include/hw/boards.h index e07c03f846..4429a1e3a2 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -19,6 +19,7 @@ typedef void QEMUMachineHotAddCPUFunc(const int64_t id, Error **errp); typedef int QEMUMachineGetKvmtypeFunc(const char *arg); struct QEMUMachine { + const char *family; /* NULL iff @name identifies a standalone machtype */ const char *name; const char *alias; const char *desc; @@ -76,6 +77,7 @@ struct MachineClass { ObjectClass parent_class; /*< public >*/ + const char *family; /* NULL iff @name identifies a standalone machtype */ const char *name; const char *alias; const char *desc; diff --git a/vl.c b/vl.c index f6b3546942..d32efa0df0 100644 --- a/vl.c +++ b/vl.c @@ -1416,6 +1416,7 @@ static void machine_class_init(ObjectClass *oc, void *data) MachineClass *mc = MACHINE_CLASS(oc); QEMUMachine *qm = data; + mc->family = qm->family; mc->name = qm->name; mc->alias = qm->alias; mc->desc = qm->desc; @@ -2488,7 +2489,41 @@ static int debugcon_parse(const char *devname) return 0; } -static MachineClass *machine_parse(const char *name) +static gint machine_class_cmp(gconstpointer a, gconstpointer b) +{ + const MachineClass *mc1 = a, *mc2 = b; + int res; + + if (mc1->family == NULL) { + if (mc2->family == NULL) { + /* Compare standalone machine types against each other; they sort + * in increasing order. + */ + return strcmp(object_class_get_name(OBJECT_CLASS(mc1)), + object_class_get_name(OBJECT_CLASS(mc2))); + } + + /* Standalone machine types sort after families. */ + return 1; + } + + if (mc2->family == NULL) { + /* Families sort before standalone machine types. */ + return -1; + } + + /* Families sort between each other alphabetically increasingly. */ + res = strcmp(mc1->family, mc2->family); + if (res != 0) { + return res; + } + + /* Within the same family, machine types sort in decreasing order. */ + return strcmp(object_class_get_name(OBJECT_CLASS(mc2)), + object_class_get_name(OBJECT_CLASS(mc1))); +} + + static MachineClass *machine_parse(const char *name) { MachineClass *mc = NULL; GSList *el, *machines = object_class_get_list(TYPE_MACHINE, false); @@ -2504,6 +2539,7 @@ static MachineClass *machine_parse(const char *name) error_printf("Use -machine help to list supported machines!\n"); } else { printf("Supported machines are:\n"); + machines = g_slist_sort(machines, machine_class_cmp); for (el = machines; el; el = el->next) { MachineClass *mc = el->data; if (mc->alias) { From 562542b6aee2c6be5b6c411edc92c11905b4e9c9 Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Mon, 22 Sep 2014 22:38:36 +0200 Subject: [PATCH 03/28] i386/pc: add piix and q35 machtypes to sorting families for -M \? With this patch applied, the output of -M \? is > Supported machines are: > pc Standard PC (i440FX + PIIX, 1996) (alias of pc-i440fx-2.2) > pc-i440fx-2.2 Standard PC (i440FX + PIIX, 1996) (default) > pc-i440fx-2.1 Standard PC (i440FX + PIIX, 1996) > pc-i440fx-2.0 Standard PC (i440FX + PIIX, 1996) > pc-i440fx-1.7 Standard PC (i440FX + PIIX, 1996) > pc-i440fx-1.6 Standard PC (i440FX + PIIX, 1996) > pc-i440fx-1.5 Standard PC (i440FX + PIIX, 1996) > pc-i440fx-1.4 Standard PC (i440FX + PIIX, 1996) > pc-1.3 Standard PC (i440FX + PIIX, 1996) > pc-1.2 Standard PC (i440FX + PIIX, 1996) > pc-1.1 Standard PC (i440FX + PIIX, 1996) > pc-1.0 Standard PC (i440FX + PIIX, 1996) > pc-0.15 Standard PC (i440FX + PIIX, 1996) > pc-0.14 Standard PC (i440FX + PIIX, 1996) > pc-0.13 Standard PC (i440FX + PIIX, 1996) > pc-0.12 Standard PC (i440FX + PIIX, 1996) > pc-0.11 Standard PC (i440FX + PIIX, 1996) > pc-0.10 Standard PC (i440FX + PIIX, 1996) > q35 Standard PC (Q35 + ICH9, 2009) (alias of pc-q35-2.2) > pc-q35-2.2 Standard PC (Q35 + ICH9, 2009) > pc-q35-2.1 Standard PC (Q35 + ICH9, 2009) > pc-q35-2.0 Standard PC (Q35 + ICH9, 2009) > pc-q35-1.7 Standard PC (Q35 + ICH9, 2009) > pc-q35-1.6 Standard PC (Q35 + ICH9, 2009) > pc-q35-1.5 Standard PC (Q35 + ICH9, 2009) > pc-q35-1.4 Standard PC (Q35 + ICH9, 2009) > isapc ISA-only PC > none empty machine RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1145042 Signed-off-by: Laszlo Ersek Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Paolo Bonzini Reviewed-by: Marcel Apfelbaum Acked-by: David Gibson --- hw/i386/pc_piix.c | 1 + hw/i386/pc_q35.c | 1 + 2 files changed, 2 insertions(+) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 91a20cb8f4..e4e0beb75c 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -451,6 +451,7 @@ static void pc_xen_hvm_init(MachineState *machine) #define PC_I440FX_MACHINE_OPTIONS \ PC_DEFAULT_MACHINE_OPTIONS, \ + .family = "pc_piix", \ .desc = "Standard PC (i440FX + PIIX, 1996)", \ .hot_add_cpu = pc_hot_add_cpu diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index e225c6d110..9c44cd6e1d 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -347,6 +347,7 @@ static void pc_q35_init_1_4(MachineState *machine) #define PC_Q35_MACHINE_OPTIONS \ PC_DEFAULT_MACHINE_OPTIONS, \ + .family = "pc_q35", \ .desc = "Standard PC (Q35 + ICH9, 2009)", \ .hot_add_cpu = pc_hot_add_cpu, \ .units_per_default_bus = 1 From df1fd4b541b3ae0dc44843741363d00080775294 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Wed, 30 Jul 2014 09:01:59 +0200 Subject: [PATCH 04/28] pc: Fix disabling of vapic for compat PC models We used to be able to address both the QEMU and the KVM APIC via "apic". This doesn't work anymore. So we need to use their parent class to turn off the vapic on machines that should not expose them. Signed-off-by: Jan Kiszka Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/pc_piix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index e4e0beb75c..061f4d977a 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -662,7 +662,7 @@ static QEMUMachine pc_machine_v1_1 = { .property = "class",\ .value = stringify(PCI_CLASS_MEMORY_RAM),\ },{\ - .driver = "apic",\ + .driver = "apic-common",\ .property = "vapic",\ .value = "off",\ },{\ From 1c87d68c91dc91771a9189d518e75bf15babc33b Mon Sep 17 00:00:00 2001 From: Gal Hammer Date: Wed, 17 Sep 2014 14:39:51 +0300 Subject: [PATCH 05/28] i386: Add an ACPI_EXTRACT_NAME_BUFFER16 directive. Add a 16-bytes buffer to allow storing a 128-bit UUID value in an ACPI table. Signed-off-by: Gal Hammer Reviewed-by: Paolo Bonzini Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- scripts/acpi_extract.py | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/scripts/acpi_extract.py b/scripts/acpi_extract.py index 22ea468102..10c1ffb368 100755 --- a/scripts/acpi_extract.py +++ b/scripts/acpi_extract.py @@ -139,13 +139,16 @@ def aml_name_string(offset): offset += 1 return offset; -# Given data offset, find 8 byte buffer offset -def aml_data_buffer8(offset): - #0x08 NameOp NameString DataRef - expect = [0x11, 0x0B, 0x0A, 0x08] +# Given data offset, find variable length byte buffer offset +def aml_data_buffer(offset, length): + #0x11 PkgLength BufferSize ByteList + if (length > 63): + die( "Name offset 0x%x: expected a one byte PkgLength (length<=63)" % + (offset)); + expect = [0x11, length+3, 0x0A, length] if (aml[offset:offset+4] != expect): die( "Name offset 0x%x: expected %s actual %s" % - (offset, aml[offset:offset+4], expect)) + (offset, expect, aml[offset:offset+4])) return offset + len(expect) # Given data offset, find dword const offset @@ -172,9 +175,9 @@ def aml_data_byte_const(offset): (offset, aml[offset])); return offset + 1; -# Find name'd buffer8 -def aml_name_buffer8(offset): - return aml_data_buffer8(aml_name_string(offset) + 4) +# Find name'd buffer +def aml_name_buffer(offset, length): + return aml_data_buffer(aml_name_string(offset) + 4, length) # Given name offset, find dword const offset def aml_name_dword_const(offset): @@ -308,7 +311,9 @@ for i in range(len(asl)): output[array] = aml continue if (directive == "ACPI_EXTRACT_NAME_BUFFER8"): - offset = aml_name_buffer8(offset) + offset = aml_name_buffer(offset, 8) + elif (directive == "ACPI_EXTRACT_NAME_BUFFER16"): + offset = aml_name_buffer(offset, 16) elif (directive == "ACPI_EXTRACT_NAME_DWORD_CONST"): offset = aml_name_dword_const(offset) elif (directive == "ACPI_EXTRACT_NAME_WORD_CONST"): From 4d5e17a53b12bf48953aa486d71bd1f5549c0dea Mon Sep 17 00:00:00 2001 From: Gonglei Date: Tue, 7 Oct 2014 14:53:48 +0800 Subject: [PATCH 06/28] pcie: change confused comment clearer This comment applies to all functions below it. It is not appropriate that called capability allocation functions, change it into capability list management functions. Signed-off-by: Gonglei Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/pci/pcie.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c index b64a004631..58455bd854 100644 --- a/hw/pci/pcie.c +++ b/hw/pci/pcie.c @@ -529,7 +529,7 @@ bool pcie_cap_is_arifwd_enabled(const PCIDevice *dev) } /************************************************************************** - * pci express extended capability allocation functions + * pci express extended capability list management functions * uint16_t ext_cap_id (16 bit) * uint8_t cap_ver (4 bit) * uint16_t cap_offset (12 bit) From 68a27b208a2328653faa09bc7a13d7ef0e2710bb Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Tue, 14 Oct 2014 19:40:06 +0300 Subject: [PATCH 07/28] virtio-pci: fix migration for pci bus master Current support for bus master (clearing OK bit) together with the need to support guests which do not enable PCI bus mastering, leads to extra state in VIRTIO_PCI_FLAG_BUS_MASTER_BUG bit, which isn't robust in case of cross-version migration for the case when guests use the device before setting DRIVER_OK. Rip out this code, and replace it: - Modern QEMU doesn't need VIRTIO_PCI_FLAG_BUS_MASTER_BUG so just drop it for latest machine type. - For compat machine types, set PCI_COMMAND if DRIVER_OK is set. As this is needed for 2.1 for both pc and ppc, move PC_COMPAT macros from pc.h to a new common header. Cc: Greg Kurz Signed-off-by: Michael S. Tsirkin Reviewed-by: Alexander Graf --- hw/i386/pc_piix.c | 2 +- hw/i386/pc_q35.c | 2 +- hw/ppc/spapr.c | 7 +++++++ hw/virtio/virtio-pci.c | 29 +++++++++++------------------ hw/virtio/virtio-pci.h | 5 +++++ include/hw/compat.h | 35 +++++++++++++++++++++++++++++++++++ include/hw/i386/pc.h | 26 ++------------------------ 7 files changed, 62 insertions(+), 44 deletions(-) create mode 100644 include/hw/compat.h diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 061f4d977a..ddc885e4ae 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -474,7 +474,7 @@ static QEMUMachine pc_i440fx_machine_v2_1 = { .name = "pc-i440fx-2.1", .init = pc_init_pci, .compat_props = (GlobalProperty[]) { - PC_COMPAT_2_1, + HW_COMPAT_2_1, { /* end of list */ } }, }; diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 9c44cd6e1d..f533a940f0 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -370,7 +370,7 @@ static QEMUMachine pc_q35_machine_v2_1 = { .name = "pc-q35-2.1", .init = pc_q35_init, .compat_props = (GlobalProperty[]) { - PC_COMPAT_2_1, + HW_COMPAT_2_1, { /* end of list */ } }, }; diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 45764a7032..0a2bfe6565 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -57,6 +57,8 @@ #include "trace.h" #include "hw/nmi.h" +#include "hw/compat.h" + #include /* SLOF memory layout: @@ -1689,10 +1691,15 @@ static const TypeInfo spapr_machine_info = { static void spapr_machine_2_1_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); + static GlobalProperty compat_props[] = { + HW_COMPAT_2_1, + { /* end of list */ } + }; mc->name = "pseries-2.1"; mc->desc = "pSeries Logical Partition (PAPR compliant) v2.1"; mc->is_default = 0; + mc->compat_props = compat_props; } static const TypeInfo spapr_machine_2_1_info = { diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index e490adeb80..dde1d73b56 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -86,9 +86,6 @@ * 12 is historical, and due to x86 page size. */ #define VIRTIO_PCI_QUEUE_ADDR_SHIFT 12 -/* Flags track per-device state like workarounds for quirks in older guests. */ -#define VIRTIO_PCI_FLAG_BUS_MASTER_BUG (1 << 0) - static void virtio_pci_bus_new(VirtioBusState *bus, size_t bus_size, VirtIOPCIProxy *dev); @@ -323,14 +320,6 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val) proxy->pci_dev.config[PCI_COMMAND] | PCI_COMMAND_MASTER, 1); } - - /* Linux before 2.6.34 sets the device as OK without enabling - the PCI device bus master bit. In this case we need to disable - some safety checks. */ - if ((val & VIRTIO_CONFIG_S_DRIVER_OK) && - !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) { - proxy->flags |= VIRTIO_PCI_FLAG_BUS_MASTER_BUG; - } break; case VIRTIO_MSI_CONFIG_VECTOR: msix_vector_unuse(&proxy->pci_dev, vdev->config_vector); @@ -483,8 +472,7 @@ static void virtio_write_config(PCIDevice *pci_dev, uint32_t address, pci_default_write_config(pci_dev, address, val, len); if (range_covers_byte(address, len, PCI_COMMAND) && - !(pci_dev->config[PCI_COMMAND] & PCI_COMMAND_MASTER) && - !(proxy->flags & VIRTIO_PCI_FLAG_BUS_MASTER_BUG)) { + !(pci_dev->config[PCI_COMMAND] & PCI_COMMAND_MASTER)) { virtio_pci_stop_ioeventfd(proxy); virtio_set_status(vdev, vdev->status & ~VIRTIO_CONFIG_S_DRIVER_OK); } @@ -895,11 +883,15 @@ static void virtio_pci_vmstate_change(DeviceState *d, bool running) VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); if (running) { - /* Try to find out if the guest has bus master disabled, but is - in ready state. Then we have a buggy guest OS. */ - if ((vdev->status & VIRTIO_CONFIG_S_DRIVER_OK) && + /* Old QEMU versions did not set bus master enable on status write. + * Detect DRIVER set and enable it. + */ + if ((proxy->flags & VIRTIO_PCI_FLAG_BUS_MASTER_BUG_MIGRATION) && + (vdev->status & VIRTIO_CONFIG_S_DRIVER) && !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) { - proxy->flags |= VIRTIO_PCI_FLAG_BUS_MASTER_BUG; + pci_default_write_config(&proxy->pci_dev, PCI_COMMAND, + proxy->pci_dev.config[PCI_COMMAND] | + PCI_COMMAND_MASTER, 1); } virtio_pci_start_ioeventfd(proxy); } else { @@ -1040,10 +1032,11 @@ static void virtio_pci_reset(DeviceState *qdev) virtio_pci_stop_ioeventfd(proxy); virtio_bus_reset(bus); msix_unuse_all_vectors(&proxy->pci_dev); - proxy->flags &= ~VIRTIO_PCI_FLAG_BUS_MASTER_BUG; } static Property virtio_pci_properties[] = { + DEFINE_PROP_BIT("virtio-pci-bus-master-bug-migration", VirtIOPCIProxy, flags, + VIRTIO_PCI_FLAG_BUS_MASTER_BUG_MIGRATION_BIT, false), DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h index 1cea157a47..8873b6d138 100644 --- a/hw/virtio/virtio-pci.h +++ b/hw/virtio/virtio-pci.h @@ -53,6 +53,11 @@ typedef struct VirtioBusClass VirtioPCIBusClass; #define VIRTIO_PCI_BUS_CLASS(klass) \ OBJECT_CLASS_CHECK(VirtioPCIBusClass, klass, TYPE_VIRTIO_PCI_BUS) +/* Need to activate work-arounds for buggy guests at vmstate load. */ +#define VIRTIO_PCI_FLAG_BUS_MASTER_BUG_MIGRATION_BIT 0 +#define VIRTIO_PCI_FLAG_BUS_MASTER_BUG_MIGRATION \ + (1 << VIRTIO_PCI_FLAG_BUS_MASTER_BUG_MIGRATION_BIT) + /* Performance improves when virtqueue kick processing is decoupled from the * vcpu thread using ioeventfd for some devices. */ #define VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT 1 diff --git a/include/hw/compat.h b/include/hw/compat.h new file mode 100644 index 0000000000..313682a708 --- /dev/null +++ b/include/hw/compat.h @@ -0,0 +1,35 @@ +#ifndef HW_COMPAT_H +#define HW_COMPAT_H + +#define HW_COMPAT_2_1 \ + {\ + .driver = "intel-hda",\ + .property = "old_msi_addr",\ + .value = "on",\ + },{\ + .driver = "VGA",\ + .property = "qemu-extended-regs",\ + .value = "off",\ + },{\ + .driver = "secondary-vga",\ + .property = "qemu-extended-regs",\ + .value = "off",\ + },{\ + .driver = "virtio-scsi-pci",\ + .property = "any_layout",\ + .value = "off",\ + },{\ + .driver = "usb-mouse",\ + .property = "usb_version",\ + .value = stringify(1),\ + },{\ + .driver = "usb-kbd",\ + .property = "usb_version",\ + .value = stringify(1),\ + },{\ + .driver = "virtio-pci",\ + .property = "virtio-pci-bus-master-bug-migration",\ + .value = "on",\ + } + +#endif /* HW_COMPAT_H */ diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index c4ee520e20..02a1d615a6 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -14,6 +14,7 @@ #include "sysemu/sysemu.h" #include "hw/pci/pci.h" #include "hw/boards.h" +#include "hw/compat.h" #define HPET_INTCAP "hpet-intcap" @@ -301,31 +302,8 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t); int e820_get_num_entries(void); bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); -#define PC_COMPAT_2_1 \ - {\ - .driver = "intel-hda",\ - .property = "old_msi_addr",\ - .value = "on",\ - },{\ - .driver = "VGA",\ - .property = "qemu-extended-regs",\ - .value = "off",\ - },{\ - .driver = "secondary-vga",\ - .property = "qemu-extended-regs",\ - .value = "off",\ - },{\ - .driver = "usb-mouse",\ - .property = "usb_version",\ - .value = stringify(1),\ - },{\ - .driver = "usb-kbd",\ - .property = "usb_version",\ - .value = stringify(1),\ - } - #define PC_COMPAT_2_0 \ - PC_COMPAT_2_1, \ + HW_COMPAT_2_1, \ {\ .driver = "virtio-scsi-pci",\ .property = "any_layout",\ From 1e06f131fd9a44dd4af223875660802fd2a3441f Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 20 Oct 2014 12:37:23 +0300 Subject: [PATCH 08/28] intel_iommu: fix VTD_SID_TO_BUS (((sid) >> 8) && 0xff) makes no sense (((sid) >> 8) & 0xff) seems to be what was meant. https://bugs.launchpad.net/qemu/+bug/1382477 Signed-off-by: Michael S. Tsirkin --- include/hw/i386/intel_iommu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h index f4701e1c60..e321ee4fbc 100644 --- a/include/hw/i386/intel_iommu.h +++ b/include/hw/i386/intel_iommu.h @@ -37,7 +37,7 @@ #define VTD_PCI_DEVFN_MAX 256 #define VTD_PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f) #define VTD_PCI_FUNC(devfn) ((devfn) & 0x07) -#define VTD_SID_TO_BUS(sid) (((sid) >> 8) && 0xff) +#define VTD_SID_TO_BUS(sid) (((sid) >> 8) & 0xff) #define VTD_SID_TO_DEVFN(sid) ((sid) & 0xff) #define DMAR_REG_SIZE 0x230 From 904757916150574747683d3000c978cd30291096 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 15 Oct 2014 09:45:45 +0200 Subject: [PATCH 09/28] tests: fix rebuild-expected-aml.sh for acpi-test rename This is now called bios-tables-test. Signed-off-by: Paolo Bonzini Acked-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- tests/acpi-test-data/rebuild-expected-aml.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/acpi-test-data/rebuild-expected-aml.sh b/tests/acpi-test-data/rebuild-expected-aml.sh index ab98498884..11bf743914 100755 --- a/tests/acpi-test-data/rebuild-expected-aml.sh +++ b/tests/acpi-test-data/rebuild-expected-aml.sh @@ -23,13 +23,13 @@ else exit 1; fi -if [ ! -e "tests/acpi-test" ]; then - echo "Test: acpi-test is required! Run make check before this script." +if [ ! -e "tests/bios-tables-test" ]; then + echo "Test: bios-tables-test is required! Run make check before this script." echo "Run this script from the build directory." exit 1; fi -TEST_ACPI_REBUILD_AML=y QTEST_QEMU_BINARY=$qemu tests/acpi-test +TEST_ACPI_REBUILD_AML=y QTEST_QEMU_BINARY=$qemu tests/bios-tables-test echo "The files were rebuilt and can be added to git." echo "However, if new files were created, please copy them manually" \ From 42a5b30844207e5644ba3c2d30f719d5bad9ee72 Mon Sep 17 00:00:00 2001 From: Stefan Berger Date: Fri, 24 Oct 2014 13:21:04 -0400 Subject: [PATCH 10/28] acpi: create separate file for TCPA log Create the TCPA log in a separate file rather than allocating ACPI table memory for it. Signed-off-by: Stefan Berger Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/acpi-build.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 00be4bb12a..6bd2749982 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -249,6 +249,7 @@ static void acpi_get_pci_info(PcPciInfo *info) #define ACPI_BUILD_TABLE_FILE "etc/acpi/tables" #define ACPI_BUILD_RSDP_FILE "etc/acpi/rsdp" +#define ACPI_BUILD_TPMLOG_FILE "etc/tpm/log" static void build_header(GArray *linker, GArray *table_data, @@ -1214,27 +1215,28 @@ build_hpet(GArray *table_data, GArray *linker) } static void -build_tpm_tcpa(GArray *table_data, GArray *linker) +build_tpm_tcpa(GArray *table_data, GArray *linker, GArray *tcpalog) { Acpi20Tcpa *tcpa = acpi_data_push(table_data, sizeof *tcpa); - /* the log area will come right after the TCPA table */ - uint64_t log_area_start_address = acpi_data_len(table_data); + uint64_t log_area_start_address = acpi_data_len(tcpalog); tcpa->platform_class = cpu_to_le16(TPM_TCPA_ACPI_CLASS_CLIENT); tcpa->log_area_minimum_length = cpu_to_le32(TPM_LOG_AREA_MINIMUM_SIZE); tcpa->log_area_start_address = cpu_to_le64(log_area_start_address); + bios_linker_loader_alloc(linker, ACPI_BUILD_TPMLOG_FILE, 1, + false /* high memory */); + /* log area start address to be filled by Guest linker */ bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE, - ACPI_BUILD_TABLE_FILE, + ACPI_BUILD_TPMLOG_FILE, table_data, &tcpa->log_area_start_address, sizeof(tcpa->log_area_start_address)); build_header(linker, table_data, (void *)tcpa, "TCPA", sizeof(*tcpa), 2); - /* now only get the log area and with that modify table_data */ - acpi_data_push(table_data, TPM_LOG_AREA_MINIMUM_SIZE); + acpi_data_push(tcpalog, TPM_LOG_AREA_MINIMUM_SIZE); } static void @@ -1485,6 +1487,7 @@ typedef struct AcpiBuildTables { GArray *table_data; GArray *rsdp; + GArray *tcpalog; GArray *linker; } AcpiBuildTables; @@ -1492,6 +1495,7 @@ static inline void acpi_build_tables_init(AcpiBuildTables *tables) { tables->rsdp = g_array_new(false, true /* clear */, 1); tables->table_data = g_array_new(false, true /* clear */, 1); + tables->tcpalog = g_array_new(false, true /* clear */, 1); tables->linker = bios_linker_loader_init(); } @@ -1503,6 +1507,7 @@ static inline void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre) } g_array_free(tables->rsdp, mfre); g_array_free(tables->table_data, mfre); + g_array_free(tables->tcpalog, mfre); } typedef @@ -1612,7 +1617,7 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables) } if (misc.has_tpm) { acpi_add_table(table_offsets, tables->table_data); - build_tpm_tcpa(tables->table_data, tables->linker); + build_tpm_tcpa(tables->table_data, tables->linker, tables->tcpalog); acpi_add_table(table_offsets, tables->table_data); build_tpm_ssdt(tables->table_data, tables->linker); @@ -1778,6 +1783,9 @@ void acpi_setup(PcGuestInfo *guest_info) acpi_add_rom_blob(NULL, tables.linker, "etc/table-loader"); + fw_cfg_add_file(guest_info->fw_cfg, ACPI_BUILD_TPMLOG_FILE, + tables.tcpalog->data, acpi_data_len(tables.tcpalog)); + /* * RSDP is small so it's easy to keep it immutable, no need to * bother with ROM blobs. From 1be6b511a6a6f0d87b57725cf8d5caefcff3cc9a Mon Sep 17 00:00:00 2001 From: Gu Zheng Date: Wed, 22 Oct 2014 11:24:25 +0800 Subject: [PATCH 11/28] acpi/cpu: add cpu hotplug callback function to match hotplug_handler API Add cpu hotplug callback function (acpi_cpu_plug_cb) to match hotplug_handler API. Reviewed-by: Igor Mammedov Signed-off-by: Gu Zheng Acked-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Igor Mammedov --- hw/acpi/cpu_hotplug.c | 18 ++++++++++++++++++ include/hw/acpi/cpu_hotplug.h | 3 +++ 2 files changed, 21 insertions(+) diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c index 2ad83a0ede..06e9c6101c 100644 --- a/hw/acpi/cpu_hotplug.c +++ b/hw/acpi/cpu_hotplug.c @@ -36,6 +36,24 @@ static const MemoryRegionOps AcpiCpuHotplug_ops = { }, }; +void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq, + AcpiCpuHotplug *g, DeviceState *dev, Error **errp) +{ + CPUState *cpu = CPU(dev); + CPUClass *k = CPU_GET_CLASS(cpu); + int64_t cpu_id; + + cpu_id = k->get_arch_id(cpu); + if ((cpu_id / 8) >= ACPI_GPE_PROC_LEN) { + error_setg(errp, "acpi: invalid cpu id: %" PRIi64, cpu_id); + return; + } + + AcpiCpuHotplug_add(&ar->gpe, g, cpu); + + acpi_update_sci(ar, irq); +} + void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu) { CPUClass *k = CPU_GET_CLASS(cpu); diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h index 9e5d30c9df..5dca8d72e6 100644 --- a/include/hw/acpi/cpu_hotplug.h +++ b/include/hw/acpi/cpu_hotplug.h @@ -20,6 +20,9 @@ typedef struct AcpiCpuHotplug { uint8_t sts[ACPI_GPE_PROC_LEN]; } AcpiCpuHotplug; +void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq, + AcpiCpuHotplug *g, DeviceState *dev, Error **errp); + void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu); void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner, From c5171ed0cf9ca54d5f461cd6d08e99f324ba4c55 Mon Sep 17 00:00:00 2001 From: Gu Zheng Date: Wed, 22 Oct 2014 11:24:26 +0800 Subject: [PATCH 12/28] acpi:ich9: convert cpu hotplug to hotplug_handler API Convert notifier based hotplug to hotplug_handler API. Reviewed-by: Igor Mammedov Signed-off-by: Gu Zheng Acked-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Igor Mammedov --- hw/acpi/ich9.c | 13 ++----------- include/hw/acpi/ich9.h | 1 - 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c index 7b14bbbee1..758536427e 100644 --- a/hw/acpi/ich9.c +++ b/hw/acpi/ich9.c @@ -209,15 +209,6 @@ static void pm_powerdown_req(Notifier *n, void *opaque) acpi_pm1_evt_power_down(&pm->acpi_regs); } -static void ich9_cpu_added_req(Notifier *n, void *opaque) -{ - ICH9LPCPMRegs *pm = container_of(n, ICH9LPCPMRegs, cpu_added_notifier); - - assert(pm != NULL); - AcpiCpuHotplug_add(&pm->acpi_regs.gpe, &pm->gpe_cpu, CPU(opaque)); - acpi_update_sci(&pm->acpi_regs, pm->irq); -} - void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm, qemu_irq sci_irq) { @@ -246,8 +237,6 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm, AcpiCpuHotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci), &pm->gpe_cpu, ICH9_CPU_HOTPLUG_IO_BASE); - pm->cpu_added_notifier.notify = ich9_cpu_added_req; - qemu_register_cpu_added_notifier(&pm->cpu_added_notifier); if (pm->acpi_memory_hotplug.is_enabled) { acpi_memory_hotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci), @@ -304,6 +293,8 @@ void ich9_pm_device_plug_cb(ICH9LPCPMRegs *pm, DeviceState *dev, Error **errp) object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { acpi_memory_plug_cb(&pm->acpi_regs, pm->irq, &pm->acpi_memory_hotplug, dev, errp); + } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { + acpi_cpu_plug_cb(&pm->acpi_regs, pm->irq, &pm->gpe_cpu, dev, errp); } else { error_setg(errp, "acpi: device plug request for not supported device" " type: %s", object_get_typename(OBJECT(dev))); diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h index 7e42448ef9..fe975e6624 100644 --- a/include/hw/acpi/ich9.h +++ b/include/hw/acpi/ich9.h @@ -47,7 +47,6 @@ typedef struct ICH9LPCPMRegs { Notifier powerdown_notifier; AcpiCpuHotplug gpe_cpu; - Notifier cpu_added_notifier; MemHotplugState acpi_memory_hotplug; } ICH9LPCPMRegs; From 08bba95bd3782c74de9cac29e6f8f6b7a5d50392 Mon Sep 17 00:00:00 2001 From: Gu Zheng Date: Wed, 22 Oct 2014 11:24:27 +0800 Subject: [PATCH 13/28] acpi:piix4: convert cpu hotplug to hotplug_handler API Convert notifier based hotplug to hotplug_handler API, and remove the unused AcpiCpuHotplug_add(). Reviewed-by: Igor Mammedov Signed-off-by: Gu Zheng Acked-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Igor Mammedov --- hw/acpi/cpu_hotplug.c | 14 ++------------ hw/acpi/piix4.c | 14 ++------------ include/hw/acpi/cpu_hotplug.h | 2 -- 3 files changed, 4 insertions(+), 26 deletions(-) diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c index 06e9c6101c..b69b16c0e2 100644 --- a/hw/acpi/cpu_hotplug.c +++ b/hw/acpi/cpu_hotplug.c @@ -49,22 +49,12 @@ void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq, return; } - AcpiCpuHotplug_add(&ar->gpe, g, cpu); + ar->gpe.sts[0] |= ACPI_CPU_HOTPLUG_STATUS; + g->sts[cpu_id / 8] |= (1 << (cpu_id % 8)); acpi_update_sci(ar, irq); } -void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu) -{ - CPUClass *k = CPU_GET_CLASS(cpu); - int64_t cpu_id; - - *gpe->sts = *gpe->sts | ACPI_CPU_HOTPLUG_STATUS; - cpu_id = k->get_arch_id(CPU(cpu)); - g_assert((cpu_id / 8) < ACPI_GPE_PROC_LEN); - g->sts[cpu_id / 8] |= (1 << (cpu_id % 8)); -} - void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner, AcpiCpuHotplug *gpe_cpu, uint16_t base) { diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index 0bfa814f71..86a45f8ee4 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -83,7 +83,6 @@ typedef struct PIIX4PMState { uint8_t s4_val; AcpiCpuHotplug gpe_cpu; - Notifier cpu_added_notifier; MemHotplugState acpi_memory_hotplug; } PIIX4PMState; @@ -348,6 +347,8 @@ static void piix4_device_plug_cb(HotplugHandler *hotplug_dev, } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) { acpi_pcihp_device_plug_cb(&s->ar, s->irq, &s->acpi_pci_hotplug, dev, errp); + } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { + acpi_cpu_plug_cb(&s->ar, s->irq, &s->gpe_cpu, dev, errp); } else { error_setg(errp, "acpi: device plug request for not supported device" " type: %s", object_get_typename(OBJECT(dev))); @@ -544,15 +545,6 @@ static const MemoryRegionOps piix4_gpe_ops = { .endianness = DEVICE_LITTLE_ENDIAN, }; -static void piix4_cpu_added_req(Notifier *n, void *opaque) -{ - PIIX4PMState *s = container_of(n, PIIX4PMState, cpu_added_notifier); - - assert(s != NULL); - AcpiCpuHotplug_add(&s->ar.gpe, &s->gpe_cpu, CPU(opaque)); - acpi_update_sci(&s->ar, s->irq); -} - static void piix4_acpi_system_hot_add_init(MemoryRegion *parent, PCIBus *bus, PIIX4PMState *s) { @@ -565,8 +557,6 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion *parent, AcpiCpuHotplug_init(parent, OBJECT(s), &s->gpe_cpu, PIIX4_CPU_HOTPLUG_IO_BASE); - s->cpu_added_notifier.notify = piix4_cpu_added_req; - qemu_register_cpu_added_notifier(&s->cpu_added_notifier); if (s->acpi_memory_hotplug.is_enabled) { acpi_memory_hotplug_init(parent, OBJECT(s), &s->acpi_memory_hotplug); diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h index 5dca8d72e6..4657e71158 100644 --- a/include/hw/acpi/cpu_hotplug.h +++ b/include/hw/acpi/cpu_hotplug.h @@ -23,8 +23,6 @@ typedef struct AcpiCpuHotplug { void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq, AcpiCpuHotplug *g, DeviceState *dev, Error **errp); -void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu); - void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner, AcpiCpuHotplug *gpe_cpu, uint16_t base); #endif From 5279569eead697a41aa34b300ebbf13e4782f4f5 Mon Sep 17 00:00:00 2001 From: Gu Zheng Date: Wed, 22 Oct 2014 11:24:28 +0800 Subject: [PATCH 14/28] pc: add cpu hotplug handler to PC_MACHINE Add cpu hotplug handler to PC_MACHINE, which will perform the acpi cpu hotplug callback via hotplug_handler API. Reviewed-by: Igor Mammedov Signed-off-by: Gu Zheng Acked-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Igor Mammedov --- hw/i386/pc.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index f70ff28c05..7c50258d94 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1618,11 +1618,36 @@ out: error_propagate(errp, local_err); } +static void pc_cpu_plug(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) +{ + HotplugHandlerClass *hhc; + Error *local_err = NULL; + PCMachineState *pcms = PC_MACHINE(hotplug_dev); + + if (!dev->hotplugged) { + goto out; + } + + if (!pcms->acpi_dev) { + error_setg(&local_err, + "cpu hotplug is not enabled: missing acpi device"); + goto out; + } + + hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev); + hhc->plug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err); +out: + error_propagate(errp, local_err); +} + static void pc_machine_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { pc_dimm_plug(hotplug_dev, dev, errp); + } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { + pc_cpu_plug(hotplug_dev, dev, errp); } } @@ -1631,7 +1656,8 @@ static HotplugHandler *pc_get_hotpug_handler(MachineState *machine, { PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(machine); - if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { + if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) || + object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { return HOTPLUG_HANDLER(machine); } From 2d996150ed68edb8754b73b36a3db187c08f2ba7 Mon Sep 17 00:00:00 2001 From: Gu Zheng Date: Wed, 22 Oct 2014 11:24:29 +0800 Subject: [PATCH 15/28] pc: Update rtc_cmos in pc_cpu_plug Update rtc_cmos in pc_cpu_plug() directly, instead of the notifier. Reviewed-by: Igor Mammedov Signed-off-by: Gu Zheng Acked-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Igor Mammedov --- hw/i386/pc.c | 37 ++++++++++++++++--------------------- hw/i386/pc_piix.c | 2 +- hw/i386/pc_q35.c | 2 +- include/hw/i386/pc.h | 3 ++- 4 files changed, 20 insertions(+), 24 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 7c50258d94..a27a4b3279 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -355,30 +355,15 @@ static void pc_cmos_init_late(void *opaque) qemu_unregister_reset(pc_cmos_init_late, opaque); } -typedef struct RTCCPUHotplugArg { - Notifier cpu_added_notifier; - ISADevice *rtc_state; -} RTCCPUHotplugArg; - -static void rtc_notify_cpu_added(Notifier *notifier, void *data) -{ - RTCCPUHotplugArg *arg = container_of(notifier, RTCCPUHotplugArg, - cpu_added_notifier); - ISADevice *s = arg->rtc_state; - - /* increment the number of CPUs */ - rtc_set_memory(s, 0x5f, rtc_get_memory(s, 0x5f) + 1); -} - void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size, - const char *boot_device, + const char *boot_device, MachineState *machine, ISADevice *floppy, BusState *idebus0, BusState *idebus1, ISADevice *s) { int val, nb, i; FDriveType fd_type[2] = { FDRIVE_DRV_NONE, FDRIVE_DRV_NONE }; static pc_cmos_init_late_arg arg; - static RTCCPUHotplugArg cpu_hotplug_cb; + PCMachineState *pc_machine = PC_MACHINE(machine); /* various important CMOS locations needed by PC/Bochs bios */ @@ -417,10 +402,14 @@ void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size, /* set the number of CPU */ rtc_set_memory(s, 0x5f, smp_cpus - 1); - /* init CPU hotplug notifier */ - cpu_hotplug_cb.rtc_state = s; - cpu_hotplug_cb.cpu_added_notifier.notify = rtc_notify_cpu_added; - qemu_register_cpu_added_notifier(&cpu_hotplug_cb.cpu_added_notifier); + + object_property_add_link(OBJECT(machine), "rtc_state", + TYPE_ISA_DEVICE, + (Object **)&pc_machine->rtc, + object_property_allow_set_link, + OBJ_PROP_LINK_UNREF_ON_RELEASE, &error_abort); + object_property_set_link(OBJECT(machine), OBJECT(s), + "rtc_state", &error_abort); if (set_boot_dev(s, boot_device)) { exit(1); @@ -1637,6 +1626,12 @@ static void pc_cpu_plug(HotplugHandler *hotplug_dev, hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev); hhc->plug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err); + if (local_err) { + goto out; + } + + /* increment the number of CPUs */ + rtc_set_memory(pcms->rtc, 0x5f, rtc_get_memory(pcms->rtc, 0x5f) + 1); out: error_propagate(errp, local_err); } diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index ddc885e4ae..64da62412e 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -266,7 +266,7 @@ static void pc_init1(MachineState *machine, } pc_cmos_init(below_4g_mem_size, above_4g_mem_size, machine->boot_order, - floppy, idebus[0], idebus[1], rtc_state); + machine, floppy, idebus[0], idebus[1], rtc_state); if (pci_enabled && usb_enabled(false)) { pci_create_simple(pci_bus, piix3_devfn + 2, "piix3-usb-uhci"); diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index f533a940f0..2bb475a247 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -270,7 +270,7 @@ static void pc_q35_init(MachineState *machine) 8, NULL, 0); pc_cmos_init(below_4g_mem_size, above_4g_mem_size, machine->boot_order, - floppy, idebus[0], idebus[1], rtc_state); + machine, floppy, idebus[0], idebus[1], rtc_state); /* the rest devices to which pci devfn is automatically assigned */ pc_vga_init(isa_bus, host_bus); diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 02a1d615a6..d1011978e0 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -34,6 +34,7 @@ struct PCMachineState { MemoryRegion hotplug_memory; HotplugHandler *acpi_dev; + ISADevice *rtc; uint64_t max_ram_below_4g; }; @@ -211,7 +212,7 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, uint32 hpet_irqs); void pc_init_ne2k_isa(ISABus *bus, NICInfo *nd); void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size, - const char *boot_device, + const char *boot_device, MachineState *machine, ISADevice *floppy, BusState *ide0, BusState *ide1, ISADevice *s); void pc_nic_init(ISABus *isa_bus, PCIBus *pci_bus); From fcd702e17a4aad936c53881fcdac1d9b9eb98452 Mon Sep 17 00:00:00 2001 From: Gu Zheng Date: Wed, 22 Oct 2014 11:24:30 +0800 Subject: [PATCH 16/28] qom/cpu: remove the unused CPU hot-plug notifier Remove the unused CPU hot-plug notifier. Reviewed-by: Igor Mammedov Signed-off-by: Gu Zheng Acked-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Igor Mammedov --- include/sysemu/sysemu.h | 3 --- qom/cpu.c | 10 ---------- 2 files changed, 13 deletions(-) diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index 0037a695c1..6f9b82b6f3 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -184,9 +184,6 @@ void do_pci_device_hot_remove(Monitor *mon, const QDict *qdict); /* generic hotplug */ void drive_hot_add(Monitor *mon, const QDict *qdict); -/* CPU hotplug */ -void qemu_register_cpu_added_notifier(Notifier *notifier); - /* pcie aer error injection */ void pcie_aer_inject_error_print(Monitor *mon, const QObject *data); int do_pcie_aer_inject_error(Monitor *mon, diff --git a/qom/cpu.c b/qom/cpu.c index 0ec33377f2..79d22285f3 100644 --- a/qom/cpu.c +++ b/qom/cpu.c @@ -107,15 +107,6 @@ static void cpu_common_get_memory_mapping(CPUState *cpu, error_setg(errp, "Obtaining memory mappings is unsupported on this CPU."); } -/* CPU hot-plug notifiers */ -static NotifierList cpu_added_notifiers = - NOTIFIER_LIST_INITIALIZER(cpu_add_notifiers); - -void qemu_register_cpu_added_notifier(Notifier *notifier) -{ - notifier_list_add(&cpu_added_notifiers, notifier); -} - void cpu_reset_interrupt(CPUState *cpu, int mask) { cpu->interrupt_request &= ~mask; @@ -312,7 +303,6 @@ static void cpu_common_realizefn(DeviceState *dev, Error **errp) if (dev->hotplugged) { cpu_synchronize_post_init(cpu); - notifier_list_notify(&cpu_added_notifiers, dev); cpu_resume(cpu); } } From 411b5db8e51108f023d02ba7e37c6e5e2294b337 Mon Sep 17 00:00:00 2001 From: Gu Zheng Date: Wed, 22 Oct 2014 11:24:31 +0800 Subject: [PATCH 17/28] cpu-hotplug: rename function for better readability Rename: AcpiCpuHotplug_init --> acpi_cpu_hotplug_init AcpiCpuHotplug_ops --> acpi_cpu_hotplug_ops for better readability, just cleanup. Reviewed-by: Igor Mammedov Signed-off-by: Gu Zheng Acked-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Igor Mammedov --- hw/acpi/cpu_hotplug.c | 4 ++-- hw/acpi/ich9.c | 4 ++-- hw/acpi/piix4.c | 4 ++-- include/hw/acpi/cpu_hotplug.h | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c index b69b16c0e2..ae48b63208 100644 --- a/hw/acpi/cpu_hotplug.c +++ b/hw/acpi/cpu_hotplug.c @@ -55,8 +55,8 @@ void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq, acpi_update_sci(ar, irq); } -void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner, - AcpiCpuHotplug *gpe_cpu, uint16_t base) +void acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner, + AcpiCpuHotplug *gpe_cpu, uint16_t base) { CPUState *cpu; diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c index 758536427e..ea991a3c65 100644 --- a/hw/acpi/ich9.c +++ b/hw/acpi/ich9.c @@ -235,8 +235,8 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm, pm->powerdown_notifier.notify = pm_powerdown_req; qemu_register_powerdown_notifier(&pm->powerdown_notifier); - AcpiCpuHotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci), - &pm->gpe_cpu, ICH9_CPU_HOTPLUG_IO_BASE); + acpi_cpu_hotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci), + &pm->gpe_cpu, ICH9_CPU_HOTPLUG_IO_BASE); if (pm->acpi_memory_hotplug.is_enabled) { acpi_memory_hotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci), diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index 86a45f8ee4..78c0a6d323 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -555,8 +555,8 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion *parent, acpi_pcihp_init(&s->acpi_pci_hotplug, bus, parent, s->use_acpi_pci_hotplug); - AcpiCpuHotplug_init(parent, OBJECT(s), &s->gpe_cpu, - PIIX4_CPU_HOTPLUG_IO_BASE); + acpi_cpu_hotplug_init(parent, OBJECT(s), &s->gpe_cpu, + PIIX4_CPU_HOTPLUG_IO_BASE); if (s->acpi_memory_hotplug.is_enabled) { acpi_memory_hotplug_init(parent, OBJECT(s), &s->acpi_memory_hotplug); diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h index 4657e71158..f6d358def1 100644 --- a/include/hw/acpi/cpu_hotplug.h +++ b/include/hw/acpi/cpu_hotplug.h @@ -23,6 +23,6 @@ typedef struct AcpiCpuHotplug { void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq, AcpiCpuHotplug *g, DeviceState *dev, Error **errp); -void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner, - AcpiCpuHotplug *gpe_cpu, uint16_t base); +void acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner, + AcpiCpuHotplug *gpe_cpu, uint16_t base); #endif From cc43364de7773c9838cedf8f461b7788b8b4fd8e Mon Sep 17 00:00:00 2001 From: Gu Zheng Date: Wed, 22 Oct 2014 11:24:32 +0800 Subject: [PATCH 18/28] acpi/cpu-hotplug: introduce helper function to keep bit setting in one place Introduce helper function acpi_set_cpu_present_bit() to simplify acpi_cpu_plug_cb and acpi_cpu_hotplug_init, so that we can keep bit setting in one place. Signed-off-by: Gu Zheng Acked-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Igor Mammedov --- hw/acpi/cpu_hotplug.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c index ae48b63208..b8ebfadc30 100644 --- a/hw/acpi/cpu_hotplug.c +++ b/hw/acpi/cpu_hotplug.c @@ -36,10 +36,9 @@ static const MemoryRegionOps AcpiCpuHotplug_ops = { }, }; -void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq, - AcpiCpuHotplug *g, DeviceState *dev, Error **errp) +static void acpi_set_cpu_present_bit(AcpiCpuHotplug *g, CPUState *cpu, + Error **errp) { - CPUState *cpu = CPU(dev); CPUClass *k = CPU_GET_CLASS(cpu); int64_t cpu_id; @@ -49,9 +48,18 @@ void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq, return; } - ar->gpe.sts[0] |= ACPI_CPU_HOTPLUG_STATUS; g->sts[cpu_id / 8] |= (1 << (cpu_id % 8)); +} +void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq, + AcpiCpuHotplug *g, DeviceState *dev, Error **errp) +{ + acpi_set_cpu_present_bit(g, CPU(dev), errp); + if (*errp != NULL) { + return; + } + + ar->gpe.sts[0] |= ACPI_CPU_HOTPLUG_STATUS; acpi_update_sci(ar, irq); } @@ -61,11 +69,7 @@ void acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner, CPUState *cpu; CPU_FOREACH(cpu) { - CPUClass *cc = CPU_GET_CLASS(cpu); - int64_t id = cc->get_arch_id(cpu); - - g_assert((id / 8) < ACPI_GPE_PROC_LEN); - gpe_cpu->sts[id / 8] |= (1 << (id % 8)); + acpi_set_cpu_present_bit(gpe_cpu, cpu, &error_abort); } memory_region_init_io(&gpe_cpu->io, owner, &AcpiCpuHotplug_ops, gpe_cpu, "acpi-cpu-hotplug", ACPI_GPE_PROC_LEN); From 9b23cfb76b3a5e9eb5cc899eaf2f46bc46d33ba4 Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Fri, 3 Oct 2014 17:33:37 -0400 Subject: [PATCH 19/28] -machine vmport=off: Allow disabling of VMWare ioport emulation This is a pc & q35 only machine opt. VMWare apparently doesn't like running under QEMU due to our incomplete emulation of it's special IO Port. This adds a pc & q35 property to allow it to be turned off. Signed-off-by: Dr. David Alan Gilbert Signed-off-by: Don Slutz Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Paolo Bonzini Reviewed-by: Eduardo Habkost Reviewed-by: Richard W.M. Jones --- hw/i386/pc.c | 19 +++++++++++++++++++ hw/i386/pc_piix.c | 4 ++-- hw/i386/pc_q35.c | 3 ++- include/hw/i386/pc.h | 2 ++ qemu-options.hx | 3 +++ vl.c | 4 ++++ 6 files changed, 32 insertions(+), 3 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index a27a4b3279..dc2fe6a666 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1710,6 +1710,20 @@ static void pc_machine_set_max_ram_below_4g(Object *obj, Visitor *v, pcms->max_ram_below_4g = value; } +static bool pc_machine_get_vmport(Object *obj, Error **errp) +{ + PCMachineState *pcms = PC_MACHINE(obj); + + return pcms->vmport; +} + +static void pc_machine_set_vmport(Object *obj, bool value, Error **errp) +{ + PCMachineState *pcms = PC_MACHINE(obj); + + pcms->vmport = value; +} + static void pc_machine_initfn(Object *obj) { PCMachineState *pcms = PC_MACHINE(obj); @@ -1722,6 +1736,11 @@ static void pc_machine_initfn(Object *obj) pc_machine_get_max_ram_below_4g, pc_machine_set_max_ram_below_4g, NULL, NULL, NULL); + pcms->vmport = !xen_enabled(); + object_property_add_bool(obj, PC_MACHINE_VMPORT, + pc_machine_get_vmport, + pc_machine_set_vmport, + NULL); } static void pc_machine_class_init(ObjectClass *oc, void *data) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 64da62412e..bfa4edcbb8 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -234,8 +234,8 @@ static void pc_init1(MachineState *machine, pc_vga_init(isa_bus, pci_enabled ? pci_bus : NULL); /* init basic PC hardware */ - pc_basic_device_init(isa_bus, gsi, &rtc_state, &floppy, xen_enabled(), - 0x4); + pc_basic_device_init(isa_bus, gsi, &rtc_state, &floppy, + !pc_machine->vmport, 0x4); pc_nic_init(isa_bus, pci_bus); diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 2bb475a247..b61eb19ad4 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -242,7 +242,8 @@ static void pc_q35_init(MachineState *machine) pc_register_ferr_irq(gsi[13]); /* init basic PC hardware */ - pc_basic_device_init(isa_bus, gsi, &rtc_state, &floppy, false, 0xff0104); + pc_basic_device_init(isa_bus, gsi, &rtc_state, &floppy, + !pc_machine->vmport, 0xff0104); /* connect pm stuff to lpc */ ich9_lpc_pm_init(lpc); diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index d1011978e0..7c3731f1b0 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -37,11 +37,13 @@ struct PCMachineState { ISADevice *rtc; uint64_t max_ram_below_4g; + bool vmport; }; #define PC_MACHINE_ACPI_DEVICE_PROP "acpi-device" #define PC_MACHINE_MEMHP_REGION_SIZE "hotplug-memory-region-size" #define PC_MACHINE_MAX_RAM_BELOW_4G "max-ram-below-4g" +#define PC_MACHINE_VMPORT "vmport" /** * PCMachineClass: diff --git a/qemu-options.hx b/qemu-options.hx index 1e7d5b8362..da9851d483 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -33,6 +33,7 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \ " property accel=accel1[:accel2[:...]] selects accelerator\n" " supported accelerators are kvm, xen, tcg (default: tcg)\n" " kernel_irqchip=on|off controls accelerated irqchip support\n" + " vmport=on|off controls emulation of vmport (default: on)\n" " kvm_shadow_mem=size of KVM shadow MMU\n" " dump-guest-core=on|off include guest memory in a core dump (default=on)\n" " mem-merge=on|off controls memory merge support (default: on)\n" @@ -51,6 +52,8 @@ than one accelerator specified, the next one is used if the previous one fails to initialize. @item kernel_irqchip=on|off Enables in-kernel irqchip support for the chosen accelerator when available. +@item vmport=on|off +Enables emulation of VMWare IO port, for vmmouse etc. (enabled by default) @item kvm_shadow_mem=size Defines the size of the KVM shadow MMU. @item dump-guest-core=on|off diff --git a/vl.c b/vl.c index d32efa0df0..e113b5b5ba 100644 --- a/vl.c +++ b/vl.c @@ -376,6 +376,10 @@ static QemuOptsList qemu_machine_opts = { .name = PC_MACHINE_MAX_RAM_BELOW_4G, .type = QEMU_OPT_SIZE, .help = "maximum ram below the 4G boundary (32bit boundary)", + }, { + .name = PC_MACHINE_VMPORT, + .type = QEMU_OPT_BOOL, + .help = "Enable vmport (pc & q35)", },{ .name = "iommu", .type = QEMU_OPT_BOOL, From 178e785fb4507ec3462dc772bbe08303416ece47 Mon Sep 17 00:00:00 2001 From: Marcel Apfelbaum Date: Mon, 27 Oct 2014 19:34:41 +0200 Subject: [PATCH 20/28] hw/pci: fixed error flow in pci_qdev_init Verify return code for pci_add_option_rom. Signed-off-by: Marcel Apfelbaum Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Markus Armbruster --- hw/pci/pci.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/hw/pci/pci.c b/hw/pci/pci.c index 6ce75aa940..36226eb2c8 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -1776,7 +1776,12 @@ static int pci_qdev_init(DeviceState *qdev) pci_dev->romfile = g_strdup(pc->romfile); is_default_rom = true; } - pci_add_option_rom(pci_dev, is_default_rom); + + rc = pci_add_option_rom(pci_dev, is_default_rom); + if (rc != 0) { + pci_unregister_device(DEVICE(pci_dev)); + return rc; + } return 0; } From db80c7b974f4ccab56bd5e8ff2248c7339b00c73 Mon Sep 17 00:00:00 2001 From: Marcel Apfelbaum Date: Mon, 27 Oct 2014 19:34:42 +0200 Subject: [PATCH 21/28] hw/pci: fixed hotplug crash when using rombar=0 with devices having romfile Hot-plugging a device that has a romfile (either supplied by user or built-in) using rombar=0 option is a user error, do not allow the device to be hot-plugged. Reviewed-by: Eric Blake Signed-off-by: Marcel Apfelbaum Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/pci/pci.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/hw/pci/pci.c b/hw/pci/pci.c index 36226eb2c8..371699cf86 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -1942,6 +1942,15 @@ static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom) * for 0.11 compatibility. */ int class = pci_get_word(pdev->config + PCI_CLASS_DEVICE); + + /* + * Hot-plugged devices can't use the option ROM + * if the rom bar is disabled. + */ + if (DEVICE(pdev)->hotplugged) { + return -1; + } + if (class == 0x0300) { rom_add_vga(pdev->romfile); } else { From a3614c65cfc3ba2958b69befdc156101953f8a8c Mon Sep 17 00:00:00 2001 From: Bin Wu Date: Fri, 31 Oct 2014 00:40:16 +0000 Subject: [PATCH 22/28] hw/virtio/vring/event_idx: fix the vring_avail_event error The event idx in virtio is an effective way to reduce the number of interrupts and exits of the guest. When the guest puts an request into the virtio ring, it doesn't exit immediately to inform the backend. Instead, the guest checks the "avail" event idx to determine the notification. In virtqueue_pop, when a request is poped, the current avail event idx should be set to the number of vq->last_avail_idx. Signed-off-by: Bin Wu Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Stefan Hajnoczi --- hw/virtio/dataplane/vring.c | 8 ++++---- hw/virtio/virtio.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/hw/virtio/dataplane/vring.c b/hw/virtio/dataplane/vring.c index 372706a234..61f6d83686 100644 --- a/hw/virtio/dataplane/vring.c +++ b/hw/virtio/dataplane/vring.c @@ -352,10 +352,6 @@ int vring_pop(VirtIODevice *vdev, Vring *vring, goto out; } - if (vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) { - vring_avail_event(&vring->vr) = vring->vr.avail->idx; - } - i = head; do { if (unlikely(i >= num)) { @@ -392,6 +388,10 @@ int vring_pop(VirtIODevice *vdev, Vring *vring, /* On success, increment avail index. */ vring->last_avail_idx++; + if (vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) { + vring_avail_event(&vring->vr) = vring->last_avail_idx; + } + return head; out: diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 2c236bf271..013979a6b8 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -469,7 +469,7 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem) i = head = virtqueue_get_head(vq, vq->last_avail_idx++); if (vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) { - vring_avail_event(vq, vring_avail_idx(vq)); + vring_avail_event(vq, vq->last_avail_idx); } if (vring_desc_flags(vdev, desc_pa, i) & VRING_DESC_F_INDIRECT) { From 2cad57c7177766e2779f30fed9e4578bc7ad62ac Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Wed, 29 Oct 2014 11:26:07 -0200 Subject: [PATCH 23/28] pc: Add pc_compat_2_1() function Signed-off-by: Eduardo Habkost Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/pc_piix.c | 13 ++++++++++++- hw/i386/pc_q35.c | 13 ++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index bfa4edcbb8..ce8745df25 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -302,8 +302,13 @@ static void pc_init_pci(MachineState *machine) pc_init1(machine, 1, 1); } +static void pc_compat_2_1(MachineState *machine) +{ +} + static void pc_compat_2_0(MachineState *machine) { + pc_compat_2_1(machine); /* This value depends on the actual DSDT and SSDT compiled into * the source QEMU; unfortunately it depends on the binary and * not on the machine type, so we cannot make pc-i440fx-1.7 work on @@ -368,6 +373,12 @@ static void pc_compat_1_2(MachineState *machine) x86_cpu_compat_disable_kvm_features(FEAT_KVM, KVM_FEATURE_PV_EOI); } +static void pc_init_pci_2_1(MachineState *machine) +{ + pc_compat_2_1(machine); + pc_init_pci(machine); +} + static void pc_init_pci_2_0(MachineState *machine) { pc_compat_2_0(machine); @@ -472,7 +483,7 @@ static QEMUMachine pc_i440fx_machine_v2_2 = { static QEMUMachine pc_i440fx_machine_v2_1 = { PC_I440FX_2_1_MACHINE_OPTIONS, .name = "pc-i440fx-2.1", - .init = pc_init_pci, + .init = pc_init_pci_2_1, .compat_props = (GlobalProperty[]) { HW_COMPAT_2_1, { /* end of list */ } diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index b61eb19ad4..aef4628f92 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -281,8 +281,13 @@ static void pc_q35_init(MachineState *machine) } } +static void pc_compat_2_1(MachineState *machine) +{ +} + static void pc_compat_2_0(MachineState *machine) { + pc_compat_2_1(machine); smbios_legacy_mode = true; has_reserved_memory = false; pc_set_legacy_acpi_data_size(); @@ -316,6 +321,12 @@ static void pc_compat_1_4(MachineState *machine) x86_cpu_compat_set_features("Westmere", FEAT_1_ECX, 0, CPUID_EXT_PCLMULQDQ); } +static void pc_q35_init_2_1(MachineState *machine) +{ + pc_compat_2_1(machine); + pc_q35_init(machine); +} + static void pc_q35_init_2_0(MachineState *machine) { pc_compat_2_0(machine); @@ -369,7 +380,7 @@ static QEMUMachine pc_q35_machine_v2_2 = { static QEMUMachine pc_q35_machine_v2_1 = { PC_Q35_2_1_MACHINE_OPTIONS, .name = "pc-q35-2.1", - .init = pc_q35_init, + .init = pc_q35_init_2_1, .compat_props = (GlobalProperty[]) { HW_COMPAT_2_1, { /* end of list */ } From caad057bb6ce86a9cb71520af395fd0bd04a659f Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Wed, 29 Oct 2014 11:26:08 -0200 Subject: [PATCH 24/28] smbios: Encode UUID according to SMBIOS specification Differently from older versions, SMBIOS version 2.6 is explicit about the encoding of UUID fields: > Although RFC 4122 recommends network byte order for all fields, the PC > industry (including the ACPI, UEFI, and Microsoft specifications) has > consistently used little-endian byte encoding for the first three fields: > time_low, time_mid, time_hi_and_version. The same encoding, also known as > wire format, should also be used for the SMBIOS representation of the UUID. > > The UUID {00112233-4455-6677-8899-AABBCCDDEEFF} would thus be represented > as 33 22 11 00 55 44 77 66 88 99 AA BB CC DD EE FF. The dmidecode tool implements this and decodes the above "wire format" when SMBIOS version >= 2.6. We moved from SMBIOS version 2.4 to 2.8 when we started building the SMBIOS entry point inside QEMU, on commit c97294ec1b9e36887e119589d456557d72ab37b5. Change smbios_build_type_1_table() to encode the UUID as specified. To make sure we won't change the guest-visible UUID when upgrading to a newer QEMU version, keep the old behavior on pc-*-2.1 and older. Signed-off-by: Eduardo Habkost Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/pc_piix.c | 4 +++- hw/i386/pc_q35.c | 4 +++- hw/i386/smbios.c | 27 ++++++++++++++++++++++++--- include/hw/i386/smbios.h | 17 +++++++++++++++-- vl.c | 3 +++ 5 files changed, 48 insertions(+), 7 deletions(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index ce8745df25..200ea4f009 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -63,6 +63,7 @@ static bool has_acpi_build = true; static int legacy_acpi_table_size; static bool smbios_defaults = true; static bool smbios_legacy_mode; +static bool smbios_uuid_encoded = true; /* Make sure that guest addresses aligned at 1Gbyte boundaries get mapped to * host addresses aligned at 1Gbyte boundaries. This way we can use 1GByte * pages in the host. @@ -172,7 +173,7 @@ static void pc_init1(MachineState *machine, MachineClass *mc = MACHINE_GET_CLASS(machine); /* These values are guest ABI, do not change */ smbios_set_defaults("QEMU", "Standard PC (i440FX + PIIX, 1996)", - mc->name, smbios_legacy_mode); + mc->name, smbios_legacy_mode, smbios_uuid_encoded); } /* allocate ram and load rom/bios */ @@ -304,6 +305,7 @@ static void pc_init_pci(MachineState *machine) static void pc_compat_2_1(MachineState *machine) { + smbios_uuid_encoded = false; } static void pc_compat_2_0(MachineState *machine) diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index aef4628f92..f69e4a1bfa 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -52,6 +52,7 @@ static bool has_acpi_build = true; static bool smbios_defaults = true; static bool smbios_legacy_mode; +static bool smbios_uuid_encoded = true; /* Make sure that guest addresses aligned at 1Gbyte boundaries get mapped to * host addresses aligned at 1Gbyte boundaries. This way we can use 1GByte * pages in the host. @@ -163,7 +164,7 @@ static void pc_q35_init(MachineState *machine) MachineClass *mc = MACHINE_GET_CLASS(machine); /* These values are guest ABI, do not change */ smbios_set_defaults("QEMU", "Standard PC (Q35 + ICH9, 2009)", - mc->name, smbios_legacy_mode); + mc->name, smbios_legacy_mode, smbios_uuid_encoded); } /* allocate ram and load rom/bios */ @@ -283,6 +284,7 @@ static void pc_q35_init(MachineState *machine) static void pc_compat_2_1(MachineState *machine) { + smbios_uuid_encoded = false; } static void pc_compat_2_0(MachineState *machine) diff --git a/hw/i386/smbios.c b/hw/i386/smbios.c index 0ae5960b8c..8a7ad48921 100644 --- a/hw/i386/smbios.c +++ b/hw/i386/smbios.c @@ -48,6 +48,7 @@ struct smbios_table { static uint8_t *smbios_entries; static size_t smbios_entries_len; static bool smbios_legacy = true; +static bool smbios_uuid_encoded = true; /* end: legacy structures & constants for <= 2.0 machines */ @@ -391,6 +392,11 @@ static void smbios_build_type_1_fields(void) smbios_maybe_add_str(1, offsetof(struct smbios_type_1, family_str), type1.family); if (qemu_uuid_set) { + /* We don't encode the UUID in the "wire format" here because this + * function is for legacy mode and needs to keep the guest ABI, and + * because we don't know what's the SMBIOS version advertised by the + * BIOS. + */ smbios_add_field(1, offsetof(struct smbios_type_1, uuid), qemu_uuid, 16); } @@ -523,6 +529,19 @@ static void smbios_build_type_0_table(void) SMBIOS_BUILD_TABLE_POST; } +/* Encode UUID from the big endian encoding described on RFC4122 to the wire + * format specified by SMBIOS version 2.6. + */ +static void smbios_encode_uuid(struct smbios_uuid *uuid, const uint8_t *buf) +{ + memcpy(uuid, buf, 16); + if (smbios_uuid_encoded) { + uuid->time_low = bswap32(uuid->time_low); + uuid->time_mid = bswap16(uuid->time_mid); + uuid->time_hi_and_version = bswap16(uuid->time_hi_and_version); + } +} + static void smbios_build_type_1_table(void) { SMBIOS_BUILD_TABLE_PRE(1, 0x100, true); /* required */ @@ -532,9 +551,9 @@ static void smbios_build_type_1_table(void) SMBIOS_TABLE_SET_STR(1, version_str, type1.version); SMBIOS_TABLE_SET_STR(1, serial_number_str, type1.serial); if (qemu_uuid_set) { - memcpy(t->uuid, qemu_uuid, 16); + smbios_encode_uuid(&t->uuid, qemu_uuid); } else { - memset(t->uuid, 0, 16); + memset(&t->uuid, 0, 16); } t->wake_up_type = 0x06; /* power switch */ SMBIOS_TABLE_SET_STR(1, sku_number_str, type1.sku); @@ -746,10 +765,12 @@ void smbios_set_cpuid(uint32_t version, uint32_t features) } void smbios_set_defaults(const char *manufacturer, const char *product, - const char *version, bool legacy_mode) + const char *version, bool legacy_mode, + bool uuid_encoded) { smbios_have_defaults = true; smbios_legacy = legacy_mode; + smbios_uuid_encoded = uuid_encoded; /* drop unwanted version of command-line file blob(s) */ if (smbios_legacy) { diff --git a/include/hw/i386/smbios.h b/include/hw/i386/smbios.h index a3f4d88bf0..d2850bed2c 100644 --- a/include/hw/i386/smbios.h +++ b/include/hw/i386/smbios.h @@ -20,7 +20,8 @@ void smbios_entry_add(QemuOpts *opts); void smbios_set_cpuid(uint32_t version, uint32_t features); void smbios_set_defaults(const char *manufacturer, const char *product, - const char *version, bool legacy_mode); + const char *version, bool legacy_mode, + bool uuid_encoded); uint8_t *smbios_get_table_legacy(size_t *length); void smbios_get_tables(uint8_t **tables, size_t *tables_len, uint8_t **anchor, size_t *anchor_len); @@ -72,6 +73,18 @@ struct smbios_type_0 { uint8_t embedded_controller_minor_release; } QEMU_PACKED; +/* UUID encoding. The time_* fields are little-endian, as specified by SMBIOS + * version 2.6. + */ +struct smbios_uuid { + uint32_t time_low; + uint16_t time_mid; + uint16_t time_hi_and_version; + uint8_t clock_seq_hi_and_reserved; + uint8_t clock_seq_low; + uint8_t node[6]; +} QEMU_PACKED; + /* SMBIOS type 1 - System Information */ struct smbios_type_1 { struct smbios_structure_header header; @@ -79,7 +92,7 @@ struct smbios_type_1 { uint8_t product_name_str; uint8_t version_str; uint8_t serial_number_str; - uint8_t uuid[16]; + struct smbios_uuid uuid; uint8_t wake_up_type; uint8_t sku_number_str; uint8_t family_str; diff --git a/vl.c b/vl.c index e113b5b5ba..35c1333eee 100644 --- a/vl.c +++ b/vl.c @@ -190,6 +190,9 @@ int nb_numa_nodes; int max_numa_nodeid; NodeInfo numa_info[MAX_NODES]; +/* The bytes in qemu_uuid[] are in the order specified by RFC4122, _not_ in the + * little-endian "wire format" described in the SMBIOS 2.6 specification. + */ uint8_t qemu_uuid[16]; bool qemu_uuid_set; From ac369a77967d5dd984a5430505eaf24a380af1c0 Mon Sep 17 00:00:00 2001 From: Nikita Belov Date: Wed, 29 Oct 2014 18:07:02 +0400 Subject: [PATCH 25/28] hw/i386/acpi-build.c: Fix memory leak in acpi_build_tables_cleanup() There are three ACPI tables: 'linker_data', 'rsdp' and 'table_data'. They are used differently. Two of them are being copied before using and only the copy is used later. But the third is used directly. Because of that we need to free two tables completely and delete only wrapper for the third one. Valgrind output: ==23931== 131,072 bytes in 1 blocks are definitely lost in loss record 7,729 of 7,734 ==23931== at 0x4C2CE8E: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==23931== by 0x2EA920: realloc_and_trace (vl.c:2811) ==23931== by 0x509E6AE: g_realloc (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4000.0) ==23931== by 0x506DB32: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4000.0) ==23931== by 0x506E463: g_array_set_size (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4000.0) ==23931== by 0x256A4F: acpi_align_size (acpi-build.c:487) ==23931== by 0x259F92: acpi_build (acpi-build.c:1601) ==23931== by 0x25A212: acpi_setup (acpi-build.c:1682) ==23931== by 0x24F346: pc_guest_info_machine_done (pc.c:1110) ==23931== by 0x55FAAB: notifier_list_notify (notify.c:39) ==23931== by 0x2EA704: qemu_run_machine_init_done_notifiers (vl.c:2759) ==23931== by 0x2EEC3C: main (vl.c:4504) Signed-off-by: Nikita Belov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Acked-by: Christian Borntraeger --- hw/i386/acpi-build.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 6bd2749982..4003b6bf9b 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -1502,11 +1502,9 @@ static inline void acpi_build_tables_init(AcpiBuildTables *tables) static inline void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre) { void *linker_data = bios_linker_loader_cleanup(tables->linker); - if (mfre) { - g_free(linker_data); - } + g_free(linker_data); g_array_free(tables->rsdp, mfre); - g_array_free(tables->table_data, mfre); + g_array_free(tables->table_data, true); g_array_free(tables->tcpalog, mfre); } From d3f16ec887bb58b19eac94fcae139a39a7933e15 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Sun, 2 Nov 2014 20:00:28 +0200 Subject: [PATCH 26/28] vhost-user: fix mmap offset calculation qemu_get_ram_block_host_ptr should get ram_addr_t, vhost-user passes in GPA. That's very wrong. Reported-by: Linhaifeng Signed-off-by: Michael S. Tsirkin --- hw/virtio/vhost-user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c index 4e88d9c5e9..aefe0bbaaf 100644 --- a/hw/virtio/vhost-user.c +++ b/hw/virtio/vhost-user.c @@ -226,7 +226,7 @@ static int vhost_user_call(struct vhost_dev *dev, unsigned long int request, msg.memory.regions[fd_num].memory_size = reg->memory_size; msg.memory.regions[fd_num].guest_phys_addr = reg->guest_phys_addr; msg.memory.regions[fd_num].mmap_offset = reg->userspace_addr - - (uintptr_t) qemu_get_ram_block_host_ptr(reg->guest_phys_addr); + (uintptr_t) qemu_get_ram_block_host_ptr(ram_addr); assert(fd_num < VHOST_MEMORY_MAX_NREGIONS); fds[fd_num++] = fd; } From 6f00494abed261cdbfdd003fe45f671eb3a56d78 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 28 Oct 2014 10:09:11 +0100 Subject: [PATCH 27/28] vga: add default display to machine class This allows machine classes to specify which display device they want as default. If unspecified the current behavior (try cirrus, failing that try stdvga, failing that use no display) will be used. Signed-off-by: Gerd Hoffmann Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/pc.c | 1 + include/hw/boards.h | 2 ++ vl.c | 5 ++++- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index dc2fe6a666..1205db83bc 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1526,6 +1526,7 @@ static void pc_generic_machine_class_init(ObjectClass *oc, void *data) mc->is_default = qm->is_default; mc->default_machine_opts = qm->default_machine_opts; mc->default_boot_order = qm->default_boot_order; + mc->default_display = qm->default_display; mc->compat_props = qm->compat_props; mc->hw_version = qm->hw_version; } diff --git a/include/hw/boards.h b/include/hw/boards.h index 4429a1e3a2..99a172d652 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -40,6 +40,7 @@ struct QEMUMachine { int is_default; const char *default_machine_opts; const char *default_boot_order; + const char *default_display; GlobalProperty *compat_props; const char *hw_version; }; @@ -100,6 +101,7 @@ struct MachineClass { int is_default; const char *default_machine_opts; const char *default_boot_order; + const char *default_display; GlobalProperty *compat_props; const char *hw_version; diff --git a/vl.c b/vl.c index 35c1333eee..2c4ea510f1 100644 --- a/vl.c +++ b/vl.c @@ -1444,6 +1444,7 @@ static void machine_class_init(ObjectClass *oc, void *data) mc->is_default = qm->is_default; mc->default_machine_opts = qm->default_machine_opts; mc->default_boot_order = qm->default_boot_order; + mc->default_display = qm->default_display; mc->compat_props = qm->compat_props; mc->hw_version = qm->hw_version; } @@ -4223,7 +4224,9 @@ int main(int argc, char **argv, char **envp) /* If no default VGA is requested, the default is "none". */ if (default_vga) { - if (cirrus_vga_available()) { + if (machine_class->default_display) { + vga_model = machine_class->default_display; + } else if (cirrus_vga_available()) { vga_model = "cirrus"; } else if (vga_available()) { vga_model = "std"; From d43f0d641e366251bd9c63005241775f672bf3ec Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 28 Oct 2014 10:09:12 +0100 Subject: [PATCH 28/28] vga: flip qemu 2.2 pc machine types from cirrus to stdvga This patch switches the default display from cirrus to vga for the new (qemu 2.2+) machine types. Old machines types stay as-is for compatibility reasons. Signed-off-by: Gerd Hoffmann Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/pc_piix.c | 7 +++++-- hw/i386/pc_q35.c | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 200ea4f009..537bcf28da 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -470,7 +470,8 @@ static void pc_xen_hvm_init(MachineState *machine) #define PC_I440FX_2_2_MACHINE_OPTIONS \ PC_I440FX_MACHINE_OPTIONS, \ - .default_machine_opts = "firmware=bios-256k.bin" + .default_machine_opts = "firmware=bios-256k.bin", \ + .default_display = "std" static QEMUMachine pc_i440fx_machine_v2_2 = { PC_I440FX_2_2_MACHINE_OPTIONS, @@ -480,7 +481,9 @@ static QEMUMachine pc_i440fx_machine_v2_2 = { .is_default = 1, }; -#define PC_I440FX_2_1_MACHINE_OPTIONS PC_I440FX_2_2_MACHINE_OPTIONS +#define PC_I440FX_2_1_MACHINE_OPTIONS \ + PC_I440FX_MACHINE_OPTIONS, \ + .default_machine_opts = "firmware=bios-256k.bin" static QEMUMachine pc_i440fx_machine_v2_1 = { PC_I440FX_2_1_MACHINE_OPTIONS, diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index f69e4a1bfa..296bdecc80 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -368,7 +368,8 @@ static void pc_q35_init_1_4(MachineState *machine) #define PC_Q35_2_2_MACHINE_OPTIONS \ PC_Q35_MACHINE_OPTIONS, \ - .default_machine_opts = "firmware=bios-256k.bin" + .default_machine_opts = "firmware=bios-256k.bin", \ + .default_display = "std" static QEMUMachine pc_q35_machine_v2_2 = { PC_Q35_2_2_MACHINE_OPTIONS, @@ -377,7 +378,9 @@ static QEMUMachine pc_q35_machine_v2_2 = { .init = pc_q35_init, }; -#define PC_Q35_2_1_MACHINE_OPTIONS PC_Q35_2_2_MACHINE_OPTIONS +#define PC_Q35_2_1_MACHINE_OPTIONS \ + PC_Q35_MACHINE_OPTIONS, \ + .default_machine_opts = "firmware=bios-256k.bin" static QEMUMachine pc_q35_machine_v2_1 = { PC_Q35_2_1_MACHINE_OPTIONS,