diff --git a/0003-Add-RHEL-machine-types.patch b/0003-Add-RHEL-machine-types.patch deleted file mode 100644 index 9e8b0db..0000000 --- a/0003-Add-RHEL-machine-types.patch +++ /dev/null @@ -1,3017 +0,0 @@ -From e145f88a1d3be0e12262c0b3dab80133778ab21a Mon Sep 17 00:00:00 2001 -From: Miroslav Rezanina -Date: Sun, 14 Dec 2014 18:32:18 +0100 -Subject: Add RHEL machine types - -This commit adds all changes related to machine types applied since -qemu-kvm-2.12.0-31.el8. - -Signed-off-by: Miroslav Rezanina -Signed-off-by: Danilo C. L. de Paula - --- -Rebase notes (3.0.0): -- spapr_cpu_init merged into spapr_realize_vcpu (upstream) -- Commented out virt_machine_device_plug_cb in hw/arm/virt.c -- ifdef virt_get_iommu and virt_set_iommu in hw/arm/virt.c -- test changes refactored and moved all to this patch - -Merged patches (3.0.0): -- 50dd601 s390x: add RHEL 7.6 machine type for ccw -- 8198c8d e1000: Fix tso_props compat for 82540em -- e924798 Use 4 MB vram for cirrus. -- 738561e Fix x-hv-max-vps compat value for 7.4 machine type -- 9cb37fd AArch64: Add virt-rhel7.6 machine type -- 2343d56 migration: introduce decompress-error-check (partialy) -- 188fa88 pc: rhel7.6.0 machine-types -- 88b4505 Remove rhel6* machine types -- 8a50b1c Remove rhel6_ctrl_guest_workaround -- 71562f4 Remove SeaBIOS shadowing -- 40a8867 Remove ich9_uhci123_irqpin_override -- 7574808 redhat: define pseries-rhel7.6.0 machine types -- 6c2f105 RHEL-8.0: Add pseries-rhel7.6.0-sxxm machine type -- 411b30b pc: pc-*-rhel75.5.0 compat code - -Signed-off-by: Miroslav Rezanina - -Conflicts: - tests/qom-test.c ---- - hw/acpi/ich9.c | 16 ++ - hw/acpi/piix4.c | 6 +- - hw/arm/virt.c | 126 ++++++++- - hw/char/serial.c | 16 ++ - hw/display/cirrus_vga.c | 2 +- - hw/display/vga-isa.c | 2 +- - hw/i386/acpi-build.c | 3 + - hw/i386/pc.c | 7 +- - hw/i386/pc_piix.c | 194 ++++++++++++- - hw/i386/pc_q35.c | 93 ++++++- - hw/net/e1000.c | 18 +- - hw/net/e1000e.c | 21 ++ - hw/net/rtl8139.c | 4 +- - hw/ppc/spapr.c | 252 +++++++++++++++++ - hw/ppc/spapr_cpu_core.c | 13 + - hw/s390x/s390-virtio-ccw.c | 46 +++- - hw/smbios/smbios.c | 1 + - hw/timer/i8254_common.c | 2 +- - hw/timer/mc146818rtc.c | 6 + - hw/usb/hcd-uhci.c | 4 +- - hw/usb/hcd-xhci.c | 20 ++ - hw/usb/hcd-xhci.h | 2 + - include/hw/acpi/ich9.h | 3 + - include/hw/arm/virt.h | 22 ++ - include/hw/compat.h | 229 ++++++++++++++++ - include/hw/i386/pc.h | 564 ++++++++++++++++++++++++++++++++++++++ - include/hw/ppc/spapr.h | 1 + - include/hw/usb.h | 4 + - migration/migration.c | 2 + - migration/migration.h | 5 + - qdev-monitor.c | 1 - - redhat/qemu-kvm.spec.template | 2 +- - scripts/vmstate-static-checker.py | 1 - - target/i386/cpu.c | 9 +- - target/i386/machine.c | 21 ++ - target/ppc/compat.c | 13 +- - target/ppc/cpu.h | 1 + - tests/Makefile.include | 124 ++++----- - tests/boot-serial-test.c | 6 +- - tests/cpu-plug-test.c | 3 +- - tests/e1000-test.c | 2 + - tests/endianness-test.c | 2 + - tests/prom-env-test.c | 2 + - tests/qemu-iotests/051 | 12 +- - tests/qemu-iotests/group | 4 +- - tests/qom-test.c | 2 +- - tests/test-x86-cpuid-compat.c | 2 + - tests/usb-hcd-xhci-test.c | 4 + - 48 files changed, 1800 insertions(+), 95 deletions(-) - -diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c -index a4e87b8..23a7baa 100644 ---- a/hw/acpi/ich9.c -+++ b/hw/acpi/ich9.c -@@ -441,6 +441,18 @@ static void ich9_pm_set_enable_tco(Object *obj, bool value, Error **errp) - s->pm.enable_tco = value; - } - -+static bool ich9_pm_get_force_rev1_fadt(Object *obj, Error **errp) -+{ -+ ICH9LPCState *s = ICH9_LPC_DEVICE(obj); -+ return s->pm.force_rev1_fadt; -+} -+ -+static void ich9_pm_set_force_rev1_fadt(Object *obj, bool value, Error **errp) -+{ -+ ICH9LPCState *s = ICH9_LPC_DEVICE(obj); -+ s->pm.force_rev1_fadt = value; -+} -+ - void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, Error **errp) - { - static const uint32_t gpe0_len = ICH9_PMIO_GPE0_LEN; -@@ -465,6 +477,10 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, Error **errp) - ich9_pm_get_cpu_hotplug_legacy, - ich9_pm_set_cpu_hotplug_legacy, - NULL); -+ object_property_add_bool(obj, "__com.redhat_force-rev1-fadt", -+ ich9_pm_get_force_rev1_fadt, -+ ich9_pm_set_force_rev1_fadt, -+ NULL); - object_property_add(obj, ACPI_PM_PROP_S3_DISABLED, "uint8", - ich9_pm_get_disable_s3, - ich9_pm_set_disable_s3, -diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c -index 6404af5..0f1f9e2 100644 ---- a/hw/acpi/piix4.c -+++ b/hw/acpi/piix4.c -@@ -310,7 +310,7 @@ static const VMStateDescription vmstate_cpuhp_state = { - static const VMStateDescription vmstate_acpi = { - .name = "piix4_pm", - .version_id = 3, -- .minimum_version_id = 3, -+ .minimum_version_id = 2, - .minimum_version_id_old = 1, - .load_state_old = acpi_load_old, - .post_load = vmstate_acpi_post_load, -@@ -670,8 +670,8 @@ static void piix4_send_gpe(AcpiDeviceIf *adev, AcpiEventStatusBits ev) - - static Property piix4_pm_properties[] = { - DEFINE_PROP_UINT32("smb_io_base", PIIX4PMState, smb_io_base, 0), -- DEFINE_PROP_UINT8(ACPI_PM_PROP_S3_DISABLED, PIIX4PMState, disable_s3, 0), -- DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_DISABLED, PIIX4PMState, disable_s4, 0), -+ DEFINE_PROP_UINT8(ACPI_PM_PROP_S3_DISABLED, PIIX4PMState, disable_s3, 1), -+ DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_DISABLED, PIIX4PMState, disable_s4, 1), - DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_VAL, PIIX4PMState, s4_val, 2), - DEFINE_PROP_BOOL("acpi-pci-hotplug-with-bridge-support", PIIX4PMState, - use_acpi_pci_hotplug, true), -diff --git a/hw/arm/virt.c b/hw/arm/virt.c -index 281ddcd..b02e4a0 100644 ---- a/hw/arm/virt.c -+++ b/hw/arm/virt.c -@@ -60,6 +60,7 @@ - #include "standard-headers/linux/input.h" - #include "hw/arm/smmuv3.h" - -+#if 0 /* disabled Red Hat Enterprise Linux */ - #define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \ - static void virt_##major##_##minor##_class_init(ObjectClass *oc, \ - void *data) \ -@@ -87,7 +88,36 @@ - DEFINE_VIRT_MACHINE_LATEST(major, minor, true) - #define DEFINE_VIRT_MACHINE(major, minor) \ - DEFINE_VIRT_MACHINE_LATEST(major, minor, false) -- -+#endif /* disabled for RHEL */ -+ -+#define DEFINE_RHEL_MACHINE_LATEST(m, n, s, latest) \ -+ static void rhel##m##n##s##_virt_class_init(ObjectClass *oc, \ -+ void *data) \ -+ { \ -+ MachineClass *mc = MACHINE_CLASS(oc); \ -+ rhel##m##n##s##_virt_options(mc); \ -+ mc->desc = "RHEL " # m "." # n "." # s " ARM Virtual Machine"; \ -+ if (latest) { \ -+ mc->alias = "virt"; \ -+ mc->is_default = 1; \ -+ } \ -+ } \ -+ static const TypeInfo rhel##m##n##s##_machvirt_info = { \ -+ .name = MACHINE_TYPE_NAME("virt-rhel" # m "." # n "." # s), \ -+ .parent = TYPE_RHEL_MACHINE, \ -+ .instance_init = rhel##m##n##s##_virt_instance_init, \ -+ .class_init = rhel##m##n##s##_virt_class_init, \ -+ }; \ -+ static void rhel##m##n##s##_machvirt_init(void) \ -+ { \ -+ type_register_static(&rhel##m##n##s##_machvirt_info); \ -+ } \ -+ type_init(rhel##m##n##s##_machvirt_init); -+ -+#define DEFINE_RHEL_MACHINE_AS_LATEST(major, minor, subminor) \ -+ DEFINE_RHEL_MACHINE_LATEST(major, minor, subminor, true) -+#define DEFINE_RHEL_MACHINE(major, minor, subminor) \ -+ DEFINE_RHEL_MACHINE_LATEST(major, minor, subminor, false) - - /* Number of external interrupt lines to configure the GIC with */ - #define NUM_IRQS 256 -@@ -1539,6 +1569,7 @@ static void machvirt_init(MachineState *machine) - qemu_add_machine_init_done_notifier(&vms->machine_done); - } - -+#if 0 /* disabled for RHEL */ - static bool virt_get_secure(Object *obj, Error **errp) - { - VirtMachineState *vms = VIRT_MACHINE(obj); -@@ -1567,6 +1598,7 @@ static void virt_set_virt(Object *obj, bool value, Error **errp) - vms->virt = value; - } - -+#endif /* disabled for RHEL */ - static bool virt_get_highmem(Object *obj, Error **errp) - { - VirtMachineState *vms = VIRT_MACHINE(obj); -@@ -1621,6 +1653,7 @@ static void virt_set_gic_version(Object *obj, const char *value, Error **errp) - } - } - -+#if 0 - static char *virt_get_iommu(Object *obj, Error **errp) - { - VirtMachineState *vms = VIRT_MACHINE(obj); -@@ -1648,6 +1681,7 @@ static void virt_set_iommu(Object *obj, const char *value, Error **errp) - error_append_hint(errp, "Valid values are none, smmuv3.\n"); - } - } -+#endif - - static CpuInstanceProperties - virt_cpu_index_to_props(MachineState *ms, unsigned cpu_index) -@@ -1687,6 +1721,7 @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms) - return ms->possible_cpus; - } - -+#if 0 /* disabled for RHEL */ - static void virt_machine_device_plug_cb(HotplugHandler *hotplug_dev, - DeviceState *dev, Error **errp) - { -@@ -1835,6 +1870,9 @@ static void virt_machine_3_0_options(MachineClass *mc) - } - DEFINE_VIRT_MACHINE_AS_LATEST(3, 0) - -+#define VIRT_COMPAT_2_12 \ -+ HW_COMPAT_2_12 -+ - static void virt_2_12_instance_init(Object *obj) - { - virt_3_0_instance_init(obj); -@@ -1960,3 +1998,89 @@ static void virt_machine_2_6_options(MachineClass *mc) - vmc->no_pmu = true; - } - DEFINE_VIRT_MACHINE(2, 6) -+#endif /* disabled for RHEL */ -+ -+static void rhel_machine_class_init(ObjectClass *oc, void *data) -+{ -+ MachineClass *mc = MACHINE_CLASS(oc); -+ -+ mc->family = "virt-rhel-Z"; -+ mc->init = machvirt_init; -+ /* Start max_cpus at the maximum QEMU supports. We'll further restrict -+ * it later in machvirt_init, where we have more information about the -+ * configuration of the particular instance. -+ */ -+ mc->max_cpus = 255; -+ mc->block_default_type = IF_VIRTIO; -+ mc->no_cdrom = 1; -+ mc->pci_allow_0_address = true; -+ /* We know we will never create a pre-ARMv7 CPU which needs 1K pages */ -+ mc->minimum_page_bits = 12; -+ mc->possible_cpu_arch_ids = virt_possible_cpu_arch_ids; -+ mc->cpu_index_to_instance_props = virt_cpu_index_to_props; -+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a57"); -+ mc->get_default_cpu_node_id = virt_get_default_cpu_node_id; -+} -+ -+static const TypeInfo rhel_machine_info = { -+ .name = TYPE_RHEL_MACHINE, -+ .parent = TYPE_MACHINE, -+ .abstract = true, -+ .instance_size = sizeof(VirtMachineState), -+ .class_size = sizeof(VirtMachineClass), -+ .class_init = rhel_machine_class_init, -+}; -+ -+static void rhel_machine_init(void) -+{ -+ type_register_static(&rhel_machine_info); -+} -+type_init(rhel_machine_init); -+ -+static void rhel760_virt_instance_init(Object *obj) -+{ -+ VirtMachineState *vms = VIRT_MACHINE(obj); -+ VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms); -+ -+ /* EL3 is disabled by default and non-configurable for RHEL */ -+ vms->secure = false; -+ /* EL2 is disabled by default and non-configurable for RHEL */ -+ vms->virt = false; -+ /* High memory is enabled by default for RHEL */ -+ vms->highmem = true; -+ object_property_add_bool(obj, "highmem", virt_get_highmem, -+ virt_set_highmem, NULL); -+ object_property_set_description(obj, "highmem", -+ "Set on/off to enable/disable using " -+ "physical address space above 32 bits", -+ NULL); -+ /* Default GIC type is still v2, but became configurable for RHEL */ -+ vms->gic_version = 2; -+ object_property_add_str(obj, "gic-version", virt_get_gic_version, -+ virt_set_gic_version, NULL); -+ object_property_set_description(obj, "gic-version", -+ "Set GIC version. " -+ "Valid values are 2, 3 and host", NULL); -+ -+ if (vmc->no_its) { -+ vms->its = false; -+ } else { -+ /* Default allows ITS instantiation */ -+ vms->its = true; -+ object_property_add_bool(obj, "its", virt_get_its, -+ virt_set_its, NULL); -+ object_property_set_description(obj, "its", -+ "Set on/off to enable/disable " -+ "ITS instantiation", -+ NULL); -+ } -+ -+ vms->memmap=a15memmap; -+ vms->irqmap=a15irqmap; -+} -+ -+static void rhel760_virt_options(MachineClass *mc) -+{ -+ SET_MACHINE_COMPAT(mc, ARM_RHEL_COMPAT); -+} -+DEFINE_RHEL_MACHINE_AS_LATEST(7, 6, 0) -diff --git a/hw/char/serial.c b/hw/char/serial.c -index 251f40f..8e3520c 100644 ---- a/hw/char/serial.c -+++ b/hw/char/serial.c -@@ -30,6 +30,7 @@ - #include "qemu/timer.h" - #include "qemu/error-report.h" - #include "trace.h" -+#include "migration/migration.h" - - //#define DEBUG_SERIAL - -@@ -699,6 +700,9 @@ static int serial_post_load(void *opaque, int version_id) - static bool serial_thr_ipending_needed(void *opaque) - { - SerialState *s = opaque; -+ if (migrate_pre_2_2) { -+ return false; -+ } - - if (s->ier & UART_IER_THRI) { - bool expected_value = ((s->iir & UART_IIR_ID) == UART_IIR_THRI); -@@ -780,6 +784,10 @@ static const VMStateDescription vmstate_serial_xmit_fifo = { - static bool serial_fifo_timeout_timer_needed(void *opaque) - { - SerialState *s = (SerialState *)opaque; -+ if (migrate_pre_2_2) { -+ return false; -+ } -+ - return timer_pending(s->fifo_timeout_timer); - } - -@@ -797,6 +805,10 @@ static const VMStateDescription vmstate_serial_fifo_timeout_timer = { - static bool serial_timeout_ipending_needed(void *opaque) - { - SerialState *s = (SerialState *)opaque; -+ if (migrate_pre_2_2) { -+ return false; -+ } -+ - return s->timeout_ipending != 0; - } - -@@ -814,6 +826,10 @@ static const VMStateDescription vmstate_serial_timeout_ipending = { - static bool serial_poll_needed(void *opaque) - { - SerialState *s = (SerialState *)opaque; -+ if (migrate_pre_2_2) { -+ return false; -+ } -+ - return s->poll_msl >= 0; - } - -diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c -index 9fd5665..6910014 100644 ---- a/hw/display/cirrus_vga.c -+++ b/hw/display/cirrus_vga.c -@@ -3061,7 +3061,7 @@ static void isa_cirrus_vga_realizefn(DeviceState *dev, Error **errp) - - static Property isa_cirrus_vga_properties[] = { - DEFINE_PROP_UINT32("vgamem_mb", struct ISACirrusVGAState, -- cirrus_vga.vga.vram_size_mb, 4), -+ cirrus_vga.vga.vram_size_mb, 16), - DEFINE_PROP_BOOL("blitter", struct ISACirrusVGAState, - cirrus_vga.enable_blitter, true), - DEFINE_PROP_END_OF_LIST(), -diff --git a/hw/display/vga-isa.c b/hw/display/vga-isa.c -index fa44242..7835c83 100644 ---- a/hw/display/vga-isa.c -+++ b/hw/display/vga-isa.c -@@ -80,7 +80,7 @@ static void vga_isa_realizefn(DeviceState *dev, Error **errp) - } - - static Property vga_isa_properties[] = { -- DEFINE_PROP_UINT32("vgamem_mb", ISAVGAState, state.vram_size_mb, 8), -+ DEFINE_PROP_UINT32("vgamem_mb", ISAVGAState, state.vram_size_mb, 16), - DEFINE_PROP_END_OF_LIST(), - }; - -diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c -index e1ee8ae..be9bdb5 100644 ---- a/hw/i386/acpi-build.c -+++ b/hw/i386/acpi-build.c -@@ -184,6 +184,9 @@ static void acpi_get_pm_info(AcpiPmInfo *pm) - pm->fadt.reset_reg = r; - pm->fadt.reset_val = 0xf; - pm->fadt.flags |= 1 << ACPI_FADT_F_RESET_REG_SUP; -+ if (object_property_get_bool(lpc, -+ "__com.redhat_force-rev1-fadt", NULL)) -+ pm->fadt.rev = 1; - pm->cpu_hp_io_base = ICH9_CPU_HOTPLUG_IO_BASE; - } - assert(obj); -diff --git a/hw/i386/pc.c b/hw/i386/pc.c -index 11c287e..253d48d 100644 ---- a/hw/i386/pc.c -+++ b/hw/i386/pc.c -@@ -1419,7 +1419,8 @@ void pc_memory_init(PCMachineState *pcms, - option_rom_mr = g_malloc(sizeof(*option_rom_mr)); - memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE, - &error_fatal); -- if (pcmc->pci_enabled) { -+ /* RH difference: See bz 1489800, explicitly make ROM ro */ -+ if (pcmc->pc_rom_ro) { - memory_region_set_readonly(option_rom_mr, true); - } - memory_region_add_subregion_overlap(rom_memory, -@@ -2387,6 +2388,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) - pcmc->save_tsc_khz = true; - pcmc->linuxboot_dma_enabled = true; - assert(!mc->get_hotplug_handler); -+ pcmc->pc_rom_ro = true; - mc->get_hotplug_handler = pc_get_hotpug_handler; - mc->cpu_index_to_instance_props = pc_cpu_index_to_props; - mc->get_default_cpu_node_id = pc_get_default_cpu_node_id; -@@ -2396,7 +2398,8 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) - mc->default_boot_order = "cad"; - mc->hot_add_cpu = pc_hot_add_cpu; - mc->block_default_type = IF_IDE; -- mc->max_cpus = 255; -+ /* 240: max CPU count for RHEL */ -+ mc->max_cpus = 240; - mc->reset = pc_machine_reset; - hc->pre_plug = pc_machine_device_pre_plug_cb; - hc->plug = pc_machine_device_plug_cb; -diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c -index dc09466..f0484ec 100644 ---- a/hw/i386/pc_piix.c -+++ b/hw/i386/pc_piix.c -@@ -50,6 +50,7 @@ - #include "cpu.h" - #include "qapi/error.h" - #include "qemu/error-report.h" -+#include "migration/migration.h" - #ifdef CONFIG_XEN - #include - #include "hw/xen/xen_pt.h" -@@ -170,8 +171,8 @@ static void pc_init1(MachineState *machine, - if (pcmc->smbios_defaults) { - 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, pcmc->smbios_legacy_mode, -+ smbios_set_defaults("Red Hat", "KVM", -+ mc->desc, pcmc->smbios_legacy_mode, - pcmc->smbios_uuid_encoded, - SMBIOS_ENTRY_POINT_21); - } -@@ -309,6 +310,7 @@ static void pc_init1(MachineState *machine, - * HW_COMPAT_*, PC_COMPAT_*, or * pc_*_machine_options(). - */ - -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - static void pc_compat_2_3(MachineState *machine) - { - PCMachineState *pcms = PC_MACHINE(machine); -@@ -433,6 +435,7 @@ static void pc_i440fx_3_0_machine_options(MachineClass *m) - pc_i440fx_machine_options(m); - m->alias = "pc"; - m->is_default = 1; -+ SET_MACHINE_COMPAT(m, PC_COMPAT_2_12); - } - - DEFINE_I440FX_MACHINE(v3_0, "pc-i440fx-3.0", NULL, -@@ -1148,3 +1151,190 @@ static void xenfv_machine_options(MachineClass *m) - DEFINE_PC_MACHINE(xenfv, "xenfv", pc_xen_hvm_init, - xenfv_machine_options); - #endif -+machine_init(pc_machine_init); -+ -+#endif /* Disabled for Red Hat Enterprise Linux */ -+ -+/* Red Hat Enterprise Linux machine types */ -+ -+/* Options for the latest rhel7 machine type */ -+static void pc_machine_rhel7_options(MachineClass *m) -+{ -+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); -+ m->family = "pc_piix_Y"; -+ m->default_machine_opts = "firmware=bios-256k.bin"; -+ pcmc->default_nic_model = "e1000"; -+ m->default_display = "std"; -+ SET_MACHINE_COMPAT(m, PC_RHEL_COMPAT); -+ m->alias = "pc"; -+ m->is_default = 1; -+} -+ -+static void pc_init_rhel760(MachineState *machine) -+{ -+ pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \ -+ TYPE_I440FX_PCI_DEVICE); -+} -+ -+static void pc_machine_rhel760_options(MachineClass *m) -+{ -+ pc_machine_rhel7_options(m); -+ m->desc = "RHEL 7.6.0 PC (i440FX + PIIX, 1996)"; -+} -+ -+DEFINE_PC_MACHINE(rhel760, "pc-i440fx-rhel7.6.0", pc_init_rhel760, -+ pc_machine_rhel760_options); -+ -+static void pc_init_rhel750(MachineState *machine) -+{ -+ pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \ -+ TYPE_I440FX_PCI_DEVICE); -+} -+ -+static void pc_machine_rhel750_options(MachineClass *m) -+{ -+ pc_machine_rhel760_options(m); -+ m->alias = NULL; -+ m->is_default = 0; -+ m->desc = "RHEL 7.5.0 PC (i440FX + PIIX, 1996)"; -+ m->auto_enable_numa_with_memhp = false; -+ SET_MACHINE_COMPAT(m, PC_RHEL7_5_COMPAT); -+} -+ -+DEFINE_PC_MACHINE(rhel750, "pc-i440fx-rhel7.5.0", pc_init_rhel750, -+ pc_machine_rhel750_options); -+ -+static void pc_init_rhel740(MachineState *machine) -+{ -+ pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \ -+ TYPE_I440FX_PCI_DEVICE); -+} -+ -+static void pc_machine_rhel740_options(MachineClass *m) -+{ -+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); -+ pc_machine_rhel750_options(m); -+ m->desc = "RHEL 7.4.0 PC (i440FX + PIIX, 1996)"; -+ m->numa_auto_assign_ram = numa_legacy_auto_assign_ram; -+ pcmc->pc_rom_ro = false; -+ SET_MACHINE_COMPAT(m, PC_RHEL7_4_COMPAT); -+} -+ -+DEFINE_PC_MACHINE(rhel740, "pc-i440fx-rhel7.4.0", pc_init_rhel740, -+ pc_machine_rhel740_options); -+ -+static void pc_init_rhel730(MachineState *machine) -+{ -+ pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \ -+ TYPE_I440FX_PCI_DEVICE); -+} -+ -+static void pc_machine_rhel730_options(MachineClass *m) -+{ -+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); -+ pc_machine_rhel740_options(m); -+ m->desc = "RHEL 7.3.0 PC (i440FX + PIIX, 1996)"; -+ pcmc->linuxboot_dma_enabled = false; -+ SET_MACHINE_COMPAT(m, PC_RHEL7_3_COMPAT); -+} -+ -+DEFINE_PC_MACHINE(rhel730, "pc-i440fx-rhel7.3.0", pc_init_rhel730, -+ pc_machine_rhel730_options); -+ -+ -+static void pc_init_rhel720(MachineState *machine) -+{ -+ pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \ -+ TYPE_I440FX_PCI_DEVICE); -+} -+ -+static void pc_machine_rhel720_options(MachineClass *m) -+{ -+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); -+ pc_machine_rhel730_options(m); -+ m->desc = "RHEL 7.2.0 PC (i440FX + PIIX, 1996)"; -+ /* From pc_i440fx_2_5_machine_options */ -+ pcmc->save_tsc_khz = false; -+ m->legacy_fw_cfg_order = 1; -+ /* Note: broken_reserved_end was already in 7.2 */ -+ /* From pc_i440fx_2_6_machine_options */ -+ pcmc->legacy_cpu_hotplug = true; -+ SET_MACHINE_COMPAT(m, PC_RHEL7_2_COMPAT); -+} -+ -+DEFINE_PC_MACHINE(rhel720, "pc-i440fx-rhel7.2.0", pc_init_rhel720, -+ pc_machine_rhel720_options); -+ -+static void pc_compat_rhel710(MachineState *machine) -+{ -+ PCMachineState *pcms = PC_MACHINE(machine); -+ PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms); -+ -+ /* From pc_compat_2_2 */ -+ pcmc->rsdp_in_ram = false; -+ machine->suppress_vmdesc = true; -+ -+ /* From pc_compat_2_1 */ -+ pcmc->smbios_uuid_encoded = false; -+ x86_cpu_change_kvm_default("svm", NULL); -+ pcmc->enforce_aligned_dimm = false; -+ -+ /* Disable all the extra subsections that were added in 2.2 */ -+ migrate_pre_2_2 = true; -+ -+ /* From pc_i440fx_2_4_machine_options */ -+ pcmc->broken_reserved_end = true; -+} -+ -+static void pc_init_rhel710(MachineState *machine) -+{ -+ pc_compat_rhel710(machine); -+ pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \ -+ TYPE_I440FX_PCI_DEVICE); -+} -+ -+static void pc_machine_rhel710_options(MachineClass *m) -+{ -+ pc_machine_rhel720_options(m); -+ m->family = "pc_piix_Y"; -+ m->desc = "RHEL 7.1.0 PC (i440FX + PIIX, 1996)"; -+ m->default_display = "cirrus"; -+ SET_MACHINE_COMPAT(m, PC_RHEL7_1_COMPAT); -+} -+ -+DEFINE_PC_MACHINE(rhel710, "pc-i440fx-rhel7.1.0", pc_init_rhel710, -+ pc_machine_rhel710_options); -+ -+static void pc_compat_rhel700(MachineState *machine) -+{ -+ PCMachineState *pcms = PC_MACHINE(machine); -+ PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms); -+ -+ pc_compat_rhel710(machine); -+ -+ /* Upstream enables it for everyone, we're a little more selective */ -+ x86_cpu_change_kvm_default("x2apic", NULL); -+ x86_cpu_change_kvm_default("svm", NULL); -+ pcmc->legacy_acpi_table_size = 6418; /* see pc_compat_2_0() */ -+ pcmc->smbios_legacy_mode = true; -+ pcmc->has_reserved_memory = false; -+ migrate_cve_2014_5263_xhci_fields = true; -+} -+ -+static void pc_init_rhel700(MachineState *machine) -+{ -+ pc_compat_rhel700(machine); -+ pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \ -+ TYPE_I440FX_PCI_DEVICE); -+} -+ -+static void pc_machine_rhel700_options(MachineClass *m) -+{ -+ pc_machine_rhel710_options(m); -+ m->family = "pc_piix_Y"; -+ m->desc = "RHEL 7.0.0 PC (i440FX + PIIX, 1996)"; -+ SET_MACHINE_COMPAT(m, PC_RHEL7_0_COMPAT); -+} -+ -+DEFINE_PC_MACHINE(rhel700, "pc-i440fx-rhel7.0.0", pc_init_rhel700, -+ pc_machine_rhel700_options); -diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c -index 532241e..c1024c5 100644 ---- a/hw/i386/pc_q35.c -+++ b/hw/i386/pc_q35.c -@@ -145,8 +145,8 @@ static void pc_q35_init(MachineState *machine) - - if (pcmc->smbios_defaults) { - /* These values are guest ABI, do not change */ -- smbios_set_defaults("QEMU", "Standard PC (Q35 + ICH9, 2009)", -- mc->name, pcmc->smbios_legacy_mode, -+ smbios_set_defaults("Red Hat", "KVM", -+ mc->desc, pcmc->smbios_legacy_mode, - pcmc->smbios_uuid_encoded, - SMBIOS_ENTRY_POINT_21); - } -@@ -294,6 +294,7 @@ static void pc_q35_init(MachineState *machine) - DEFINE_PC_MACHINE(suffix, name, pc_init_##suffix, optionfn) - - -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - static void pc_q35_machine_options(MachineClass *m) - { - PCMachineClass *pcmc = PC_MACHINE_CLASS(m); -@@ -315,6 +316,7 @@ static void pc_q35_3_0_machine_options(MachineClass *m) - { - pc_q35_machine_options(m); - m->alias = "q35"; -+ SET_MACHINE_COMPAT(m, PC_COMPAT_2_12); - } - - DEFINE_Q35_MACHINE(v3_0, "pc-q35-3.0", NULL, -@@ -416,3 +418,90 @@ static void pc_q35_2_4_machine_options(MachineClass *m) - - DEFINE_Q35_MACHINE(v2_4, "pc-q35-2.4", NULL, - pc_q35_2_4_machine_options); -+#endif /* Disabled for Red Hat Enterprise Linux */ -+ -+/* Red Hat Enterprise Linux machine types */ -+ -+/* Options for the latest rhel7 q35 machine type */ -+static void pc_q35_machine_rhel7_options(MachineClass *m) -+{ -+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); -+ pcmc->default_nic_model = "e1000e"; -+ m->family = "pc_q35_Z"; -+ m->default_machine_opts = "firmware=bios-256k.bin"; -+ m->default_display = "std"; -+ m->no_floppy = 1; -+ machine_class_allow_dynamic_sysbus_dev(m, TYPE_SYS_BUS_DEVICE); -+ m->alias = "q35"; -+ m->max_cpus = 384; -+ SET_MACHINE_COMPAT(m, PC_RHEL_COMPAT); -+} -+ -+static void pc_q35_init_rhel760(MachineState *machine) -+{ -+ pc_q35_init(machine); -+} -+ -+static void pc_q35_machine_rhel760_options(MachineClass *m) -+{ -+ pc_q35_machine_rhel7_options(m); -+ m->desc = "RHEL-7.6.0 PC (Q35 + ICH9, 2009)"; -+} -+ -+DEFINE_PC_MACHINE(q35_rhel760, "pc-q35-rhel7.6.0", pc_q35_init_rhel760, -+ pc_q35_machine_rhel760_options); -+ -+static void pc_q35_init_rhel750(MachineState *machine) -+{ -+ pc_q35_init(machine); -+} -+ -+static void pc_q35_machine_rhel750_options(MachineClass *m) -+{ -+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); -+ pc_q35_machine_rhel760_options(m); -+ m->alias = NULL; -+ m->desc = "RHEL-7.5.0 PC (Q35 + ICH9, 2009)"; -+ m->auto_enable_numa_with_memhp = false; -+ pcmc->default_nic_model = "e1000"; -+ SET_MACHINE_COMPAT(m, PC_RHEL7_5_COMPAT); -+} -+ -+DEFINE_PC_MACHINE(q35_rhel750, "pc-q35-rhel7.5.0", pc_q35_init_rhel750, -+ pc_q35_machine_rhel750_options); -+ -+static void pc_q35_init_rhel740(MachineState *machine) -+{ -+ pc_q35_init(machine); -+} -+ -+static void pc_q35_machine_rhel740_options(MachineClass *m) -+{ -+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); -+ pc_q35_machine_rhel750_options(m); -+ m->desc = "RHEL-7.4.0 PC (Q35 + ICH9, 2009)"; -+ m->numa_auto_assign_ram = numa_legacy_auto_assign_ram; -+ pcmc->pc_rom_ro = false; -+ SET_MACHINE_COMPAT(m, PC_RHEL7_4_COMPAT); -+} -+ -+DEFINE_PC_MACHINE(q35_rhel740, "pc-q35-rhel7.4.0", pc_q35_init_rhel740, -+ pc_q35_machine_rhel740_options); -+ -+static void pc_q35_init_rhel730(MachineState *machine) -+{ -+ pc_q35_init(machine); -+} -+ -+static void pc_q35_machine_rhel730_options(MachineClass *m) -+{ -+ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); -+ pc_q35_machine_rhel740_options(m); -+ m->desc = "RHEL-7.3.0 PC (Q35 + ICH9, 2009)"; -+ m->max_cpus = 255; -+ pcmc->linuxboot_dma_enabled = false; -+ SET_MACHINE_COMPAT(m, PC_RHEL7_3_COMPAT); -+} -+ -+DEFINE_PC_MACHINE(q35_rhel730, "pc-q35-rhel7.3.0", pc_q35_init_rhel730, -+ pc_q35_machine_rhel730_options); -diff --git a/hw/net/e1000.c b/hw/net/e1000.c -index 742cd0a..7d568da 100644 ---- a/hw/net/e1000.c -+++ b/hw/net/e1000.c -@@ -1663,6 +1663,16 @@ static void pci_e1000_realize(PCIDevice *pci_dev, Error **errp) - - pci_conf = pci_dev->config; - -+ if (!(d->compat_flags & E1000_FLAG_AUTONEG)) { -+ /* -+ * We have no capabilities, so capability list bit should normally be 0. -+ * Keep it on for compat machine types to avoid breaking migration. -+ * HACK: abuse E1000_FLAG_AUTONEG, which is off exactly for -+ * the machine types that need this. -+ */ -+ pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_CAP_LIST); -+ } -+ - /* TODO: RST# value should be 0, PCI spec 6.2.4 */ - pci_conf[PCI_CACHE_LINE_SIZE] = 0x10; - -@@ -1763,7 +1773,7 @@ static const TypeInfo e1000_base_info = { - - static const E1000Info e1000_devices[] = { - { -- .name = "e1000", -+ .name = "e1000-82540em", - .device_id = E1000_DEV_ID_82540EM, - .revision = 0x03, - .phy_id2 = E1000_PHY_ID2_8254xx_DEFAULT, -@@ -1784,6 +1794,11 @@ static const E1000Info e1000_devices[] = { - #endif - }; - -+static const TypeInfo e1000_default_info = { -+ .name = "e1000", -+ .parent = "e1000-82540em", -+}; -+ - static void e1000_register_types(void) - { - int i; -@@ -1801,6 +1816,7 @@ static void e1000_register_types(void) - - type_register(&type_info); - } -+ type_register_static(&e1000_default_info); - } - - type_init(e1000_register_types) -diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c -index 510ddb3..f1de9e5 100644 ---- a/hw/net/e1000e.c -+++ b/hw/net/e1000e.c -@@ -75,6 +75,11 @@ typedef struct E1000EState { - - E1000ECore core; - -+ /* 7.3 had the intr_state field that was in the original e1000e code -+ * but that was removed prior to 2.7's release -+ */ -+ bool redhat_7_3_intr_state_enable; -+ uint32_t redhat_7_3_intr_state; - } E1000EState; - - #define E1000E_MMIO_IDX 0 -@@ -90,6 +95,10 @@ typedef struct E1000EState { - #define E1000E_MSIX_TABLE (0x0000) - #define E1000E_MSIX_PBA (0x2000) - -+/* Values as in RHEL 7.3 build and original upstream */ -+#define RH_E1000E_USE_MSI BIT(0) -+#define RH_E1000E_USE_MSIX BIT(1) -+ - static uint64_t - e1000e_mmio_read(void *opaque, hwaddr addr, unsigned size) - { -@@ -301,6 +310,8 @@ e1000e_init_msix(E1000EState *s) - } else { - if (!e1000e_use_msix_vectors(s, E1000E_MSIX_VEC_NUM)) { - msix_uninit(d, &s->msix, &s->msix); -+ } else { -+ s->redhat_7_3_intr_state |= RH_E1000E_USE_MSIX; - } - } - } -@@ -472,6 +483,8 @@ static void e1000e_pci_realize(PCIDevice *pci_dev, Error **errp) - ret = msi_init(PCI_DEVICE(s), 0xD0, 1, true, false, NULL); - if (ret) { - trace_e1000e_msi_init_fail(ret); -+ } else { -+ s->redhat_7_3_intr_state |= RH_E1000E_USE_MSI; - } - - if (e1000e_add_pm_capability(pci_dev, e1000e_pmrb_offset, -@@ -595,6 +608,11 @@ static const VMStateDescription e1000e_vmstate_intr_timer = { - VMSTATE_STRUCT_ARRAY(_f, _s, _num, 0, \ - e1000e_vmstate_intr_timer, E1000IntrDelayTimer) - -+static bool rhel_7_3_check(void *opaque, int version_id) -+{ -+ return ((E1000EState *)opaque)->redhat_7_3_intr_state_enable; -+} -+ - static const VMStateDescription e1000e_vmstate = { - .name = "e1000e", - .version_id = 1, -@@ -606,6 +624,7 @@ static const VMStateDescription e1000e_vmstate = { - VMSTATE_MSIX(parent_obj, E1000EState), - - VMSTATE_UINT32(ioaddr, E1000EState), -+ VMSTATE_UINT32_TEST(redhat_7_3_intr_state, E1000EState, rhel_7_3_check), - VMSTATE_UINT32(core.rxbuf_min_shift, E1000EState), - VMSTATE_UINT8(core.rx_desc_len, E1000EState), - VMSTATE_UINT32_ARRAY(core.rxbuf_sizes, E1000EState, -@@ -654,6 +673,8 @@ static PropertyInfo e1000e_prop_disable_vnet, - - static Property e1000e_properties[] = { - DEFINE_NIC_PROPERTIES(E1000EState, conf), -+ DEFINE_PROP_BOOL("__redhat_e1000e_7_3_intr_state", E1000EState, -+ redhat_7_3_intr_state_enable, false), - DEFINE_PROP_SIGNED("disable_vnet_hdr", E1000EState, disable_vnet, false, - e1000e_prop_disable_vnet, bool), - DEFINE_PROP_SIGNED("subsys_ven", E1000EState, subsys_ven, -diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c -index 46daa16..05453e7 100644 ---- a/hw/net/rtl8139.c -+++ b/hw/net/rtl8139.c -@@ -3174,7 +3174,7 @@ static int rtl8139_pre_save(void *opaque) - - static const VMStateDescription vmstate_rtl8139 = { - .name = "rtl8139", -- .version_id = 5, -+ .version_id = 4, - .minimum_version_id = 3, - .post_load = rtl8139_post_load, - .pre_save = rtl8139_pre_save, -@@ -3255,7 +3255,9 @@ static const VMStateDescription vmstate_rtl8139 = { - VMSTATE_UINT32(tally_counters.TxMCol, RTL8139State), - VMSTATE_UINT64(tally_counters.RxOkPhy, RTL8139State), - VMSTATE_UINT64(tally_counters.RxOkBrd, RTL8139State), -+#if 0 /* Disabled for Red Hat Enterprise Linux bz 1420195 */ - VMSTATE_UINT32_V(tally_counters.RxOkMul, RTL8139State, 5), -+#endif - VMSTATE_UINT16(tally_counters.TxAbt, RTL8139State), - VMSTATE_UINT16(tally_counters.TxUndrn, RTL8139State), - -diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c -index 2f8c304..b8bdb69 100644 ---- a/hw/ppc/spapr.c -+++ b/hw/ppc/spapr.c -@@ -4009,6 +4009,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) - smc->default_caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_BROKEN; - smc->default_caps.caps[SPAPR_CAP_HPT_MAXPAGESIZE] = 16; /* 64kiB */ - spapr_caps_add_properties(smc, &error_abort); -+ smc->has_power9_support = true; - } - - static const TypeInfo spapr_machine_info = { -@@ -4059,6 +4060,7 @@ static const TypeInfo spapr_machine_info = { - } \ - type_init(spapr_machine_register_##suffix) - -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - /* - * pseries-3.0 - */ -@@ -4248,6 +4250,7 @@ DEFINE_SPAPR_MACHINE(2_8, "2.8", false); - .property = "pre-2.8-migration", \ - .value = "on", \ - }, -+#endif - - static void phb_placement_2_7(sPAPRMachineState *spapr, uint32_t index, - uint64_t *buid, hwaddr *pio, -@@ -4298,6 +4301,7 @@ static void phb_placement_2_7(sPAPRMachineState *spapr, uint32_t index, - */ - } - -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - static void spapr_machine_2_7_instance_options(MachineState *machine) - { - sPAPRMachineState *spapr = SPAPR_MACHINE(machine); -@@ -4457,6 +4461,254 @@ static void spapr_machine_2_1_class_options(MachineClass *mc) - SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_1); - } - DEFINE_SPAPR_MACHINE(2_1, "2.1", false); -+#endif -+ -+/* -+ * pseries-rhel7.6.0 -+ */ -+ -+static void spapr_machine_rhel760_instance_options(MachineState *machine) -+{ -+} -+ -+static void spapr_machine_rhel760_class_options(MachineClass *mc) -+{ -+ /* Defaults for the latest behaviour inherited from the base class */ -+} -+ -+DEFINE_SPAPR_MACHINE(rhel760, "rhel7.6.0", true); -+ -+/* -+ * pseries-rhel7.6.0-sxxm -+ * -+ * pseries-rhel7.6.0 with speculative execution exploit mitigations enabled by default -+ */ -+static void spapr_machine_rhel760sxxm_instance_options(MachineState *machine) -+{ -+ spapr_machine_rhel760_instance_options(machine); -+} -+ -+static void spapr_machine_rhel760sxxm_class_options(MachineClass *mc) -+{ -+ sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc); -+ -+ spapr_machine_rhel760_class_options(mc); -+ smc->default_caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_WORKAROUND; -+ smc->default_caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_WORKAROUND; -+ smc->default_caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_FIXED_CCD; -+} -+ -+DEFINE_SPAPR_MACHINE(rhel760sxxm, "rhel7.6.0-sxxm", false); -+ -+/* -+ * pseries-rhel7.5.0 -+ * like SPAPR_COMPAT_2_11 and SPAPR_COMPAT_2_10 -+ * SPAPR_CAP_HTM already enabled in 7.4 -+ * -+ */ -+#define SPAPR_COMPAT_RHEL7_5 \ -+ HW_COMPAT_RHEL7_5 \ -+ -+static void spapr_machine_rhel750_instance_options(MachineState *machine) -+{ -+ spapr_machine_rhel760_instance_options(machine); -+} -+ -+static void spapr_machine_rhel750_class_options(MachineClass *mc) -+{ -+ spapr_machine_rhel760_class_options(mc); -+ SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_RHEL7_5); -+} -+ -+DEFINE_SPAPR_MACHINE(rhel750, "rhel7.5.0", false); -+ -+/* -+ * pseries-rhel7.5.0-sxxm -+ * -+ * pseries-rhel7.5.0 with speculative execution exploit mitigations enabled by default -+ */ -+static void spapr_machine_rhel750sxxm_instance_options(MachineState *machine) -+{ -+ spapr_machine_rhel750_instance_options(machine); -+} -+ -+static void spapr_machine_rhel750sxxm_class_options(MachineClass *mc) -+{ -+ sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc); -+ -+ spapr_machine_rhel750_class_options(mc); -+ smc->default_caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_WORKAROUND; -+ smc->default_caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_WORKAROUND; -+ smc->default_caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_FIXED_CCD; -+} -+ -+DEFINE_SPAPR_MACHINE(rhel750sxxm, "rhel7.5.0-sxxm", false); -+ -+/* -+ * pseries-rhel7.4.0 -+ * like SPAPR_COMPAT_2_9 -+ */ -+ -+#define SPAPR_COMPAT_RHEL7_4 \ -+ HW_COMPAT_RHEL7_4 \ -+ { \ -+ .driver = TYPE_POWERPC_CPU, \ -+ .property = "pre-2.10-migration", \ -+ .value = "on", \ -+ }, \ -+ -+static void spapr_machine_rhel740_instance_options(MachineState *machine) -+{ -+ spapr_machine_rhel750_instance_options(machine); -+} -+ -+static void spapr_machine_rhel740_class_options(MachineClass *mc) -+{ -+ sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc); -+ -+ spapr_machine_rhel750_class_options(mc); -+ SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_RHEL7_4); -+ mc->numa_auto_assign_ram = numa_legacy_auto_assign_ram; -+ smc->has_power9_support = false; -+ smc->pre_2_10_has_unused_icps = true; -+ smc->resize_hpt_default = SPAPR_RESIZE_HPT_DISABLED; -+ smc->default_caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_ON; -+} -+ -+DEFINE_SPAPR_MACHINE(rhel740, "rhel7.4.0", false); -+ -+/* -+ * pseries-rhel7.4.0-sxxm -+ * -+ * pseries-rhel7.4.0 with speculative execution exploit mitigations enabled by default -+ */ -+static void spapr_machine_rhel740sxxm_instance_options(MachineState *machine) -+{ -+ spapr_machine_rhel740_instance_options(machine); -+} -+ -+static void spapr_machine_rhel740sxxm_class_options(MachineClass *mc) -+{ -+ sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc); -+ -+ spapr_machine_rhel740_class_options(mc); -+ smc->default_caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_WORKAROUND; -+ smc->default_caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_WORKAROUND; -+ smc->default_caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_FIXED_CCD; -+} -+ -+DEFINE_SPAPR_MACHINE(rhel740sxxm, "rhel7.4.0-sxxm", false); -+ -+/* -+ * pseries-rhel7.3.0 -+ * like SPAPR_COMPAT_2_6/_2_7/_2_8 but "ddw" has been backported to RHEL7_3 -+ */ -+#define SPAPR_COMPAT_RHEL7_3 \ -+ HW_COMPAT_RHEL7_3 \ -+ { \ -+ .driver = TYPE_SPAPR_PCI_HOST_BRIDGE, \ -+ .property = "mem_win_size", \ -+ .value = stringify(SPAPR_PCI_2_7_MMIO_WIN_SIZE),\ -+ }, \ -+ { \ -+ .driver = TYPE_SPAPR_PCI_HOST_BRIDGE, \ -+ .property = "mem64_win_size", \ -+ .value = "0", \ -+ }, \ -+ { \ -+ .driver = TYPE_POWERPC_CPU, \ -+ .property = "pre-2.8-migration", \ -+ .value = "on", \ -+ }, \ -+ { \ -+ .driver = TYPE_SPAPR_PCI_HOST_BRIDGE, \ -+ .property = "pre-2.8-migration", \ -+ .value = "on", \ -+ }, \ -+ { \ -+ .driver = TYPE_SPAPR_PCI_HOST_BRIDGE, \ -+ .property = "pcie-extended-configuration-space",\ -+ .value = "off", \ -+ }, -+ -+static void spapr_machine_rhel730_instance_options(MachineState *machine) -+{ -+ sPAPRMachineState *spapr = SPAPR_MACHINE(machine); -+ -+ spapr_machine_rhel740_instance_options(machine); -+ spapr->use_hotplug_event_source = false; -+} -+ -+static void spapr_machine_rhel730_class_options(MachineClass *mc) -+{ -+ sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc); -+ -+ spapr_machine_rhel740_class_options(mc); -+ mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power7_v2.3"); -+ SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_RHEL7_3); -+ smc->phb_placement = phb_placement_2_7; -+} -+ -+DEFINE_SPAPR_MACHINE(rhel730, "rhel7.3.0", false); -+ -+/* -+ * pseries-rhel7.3.0-sxxm -+ * -+ * pseries-rhel7.3.0 with speculative execution exploit mitigations enabled by default -+ */ -+static void spapr_machine_rhel730sxxm_instance_options(MachineState *machine) -+{ -+ spapr_machine_rhel730_instance_options(machine); -+} -+ -+static void spapr_machine_rhel730sxxm_class_options(MachineClass *mc) -+{ -+ sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc); -+ -+ spapr_machine_rhel730_class_options(mc); -+ smc->default_caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_WORKAROUND; -+ smc->default_caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_WORKAROUND; -+ smc->default_caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_FIXED_CCD; -+} -+ -+DEFINE_SPAPR_MACHINE(rhel730sxxm, "rhel7.3.0-sxxm", false); -+ -+/* -+ * pseries-rhel7.2.0 -+ */ -+/* Should be like SPAPR_COMPAT_2_5 + 2_4 + 2_3, but "dynamic-reconfiguration" -+ * has been backported to RHEL7_2 so we don't need it here. -+ */ -+ -+#define SPAPR_COMPAT_RHEL7_2 \ -+ HW_COMPAT_RHEL7_2 \ -+ { \ -+ .driver = "spapr-vlan", \ -+ .property = "use-rx-buffer-pools", \ -+ .value = "off", \ -+ },{ \ -+ .driver = TYPE_SPAPR_PCI_HOST_BRIDGE,\ -+ .property = "ddw",\ -+ .value = stringify(off),\ -+ }, -+ -+ -+static void spapr_machine_rhel720_instance_options(MachineState *machine) -+{ -+ spapr_machine_rhel730_instance_options(machine); -+} -+ -+static void spapr_machine_rhel720_class_options(MachineClass *mc) -+{ -+ sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc); -+ -+ spapr_machine_rhel730_class_options(mc); -+ smc->use_ohci_by_default = true; -+ mc->has_hotpluggable_cpus = NULL; -+ SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_RHEL7_2); -+} -+ -+DEFINE_SPAPR_MACHINE(rhel720, "rhel7.2.0", false); - - static void spapr_machine_register_types(void) - { -diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c -index fb29eec..a081b01 100644 ---- a/hw/ppc/spapr_cpu_core.c -+++ b/hw/ppc/spapr_cpu_core.c -@@ -21,6 +21,7 @@ - #include "sysemu/numa.h" - #include "sysemu/hw_accel.h" - #include "qemu/error-report.h" -+#include "cpu-models.h" - - static void spapr_cpu_reset(void *opaque) - { -@@ -212,6 +213,7 @@ static void spapr_realize_vcpu(PowerPCCPU *cpu, sPAPRMachineState *spapr, - { - CPUPPCState *env = &cpu->env; - Error *local_err = NULL; -+ sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr); - - object_property_set_bool(OBJECT(cpu), true, "realized", &local_err); - if (local_err) { -@@ -224,6 +226,17 @@ static void spapr_realize_vcpu(PowerPCCPU *cpu, sPAPRMachineState *spapr, - cpu_ppc_set_vhyp(cpu, PPC_VIRTUAL_HYPERVISOR(spapr)); - kvmppc_set_papr(cpu); - -+ if (!smc->has_power9_support && -+ (((spapr->max_compat_pvr && -+ ppc_compat_cmp(spapr->max_compat_pvr, -+ CPU_POWERPC_LOGICAL_3_00) >= 0)) || -+ (!spapr->max_compat_pvr && -+ ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_3_00, 0, 0)))) { -+ error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND, -+ "POWER9 CPU is not supported by this machine class"); -+ return; -+ } -+ - qemu_register_reset(spapr_cpu_reset, cpu); - spapr_cpu_reset(cpu); - -diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c -index 7983185..0f135c9 100644 ---- a/hw/s390x/s390-virtio-ccw.c -+++ b/hw/s390x/s390-virtio-ccw.c -@@ -649,7 +649,7 @@ bool css_migration_enabled(void) - { \ - MachineClass *mc = MACHINE_CLASS(oc); \ - ccw_machine_##suffix##_class_options(mc); \ -- mc->desc = "VirtIO-ccw based S390 machine v" verstr; \ -+ mc->desc = "VirtIO-ccw based S390 machine " verstr; \ - if (latest) { \ - mc->alias = "s390-ccw-virtio"; \ - mc->is_default = 1; \ -@@ -676,6 +676,8 @@ bool css_migration_enabled(void) - #define CCW_COMPAT_2_12 \ - HW_COMPAT_2_12 - -+#if 0 /* Disabled for Red Hat Enterprise Linux */ -+ - #define CCW_COMPAT_2_11 \ - HW_COMPAT_2_11 \ - {\ -@@ -898,6 +900,48 @@ static void ccw_machine_2_4_class_options(MachineClass *mc) - } - DEFINE_CCW_MACHINE(2_4, "2.4", false); - -+#else -+ -+/* -+ * like CCW_COMPAT_2_11, but includes HW_COMPAT_RHEL7_5 (derived from -+ * HW_COMPAT_2_11 and HW_COMPAT_2_10) instead of HW_COMPAT_2_11 -+ */ -+#define CCW_COMPAT_RHEL7_5 \ -+ HW_COMPAT_RHEL7_5 \ -+ {\ -+ .driver = TYPE_SCLP_EVENT_FACILITY,\ -+ .property = "allow_all_mask_sizes",\ -+ .value = "off",\ -+ }, -+ -+static void ccw_machine_rhel760_instance_options(MachineState *machine) -+{ -+} -+ -+static void ccw_machine_rhel760_class_options(MachineClass *mc) -+{ -+} -+DEFINE_CCW_MACHINE(rhel760, "rhel7.6.0", true); -+ -+static void ccw_machine_rhel750_instance_options(MachineState *machine) -+{ -+ static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V2_11 }; -+ ccw_machine_rhel760_instance_options(machine); -+ -+ /* before 2.12 we emulated the very first z900, and RHEL 7.5 is -+ based on 2.10 */ -+ s390_set_qemu_cpu_model(0x2064, 7, 1, qemu_cpu_feat); -+} -+ -+static void ccw_machine_rhel750_class_options(MachineClass *mc) -+{ -+ ccw_machine_rhel760_class_options(mc); -+ SET_MACHINE_COMPAT(mc, CCW_COMPAT_RHEL7_5); -+} -+DEFINE_CCW_MACHINE(rhel750, "rhel7.5.0", false); -+ -+#endif -+ - static void ccw_machine_register_types(void) - { - type_register_static(&ccw_machine_info); -diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c -index a27e54b..144e6e9 100644 ---- a/hw/smbios/smbios.c -+++ b/hw/smbios/smbios.c -@@ -775,6 +775,7 @@ void smbios_set_defaults(const char *manufacturer, const char *product, - SMBIOS_SET_DEFAULT(type1.manufacturer, manufacturer); - SMBIOS_SET_DEFAULT(type1.product, product); - SMBIOS_SET_DEFAULT(type1.version, version); -+ SMBIOS_SET_DEFAULT(type1.family, "Red Hat Enterprise Linux"); - SMBIOS_SET_DEFAULT(type2.manufacturer, manufacturer); - SMBIOS_SET_DEFAULT(type2.product, product); - SMBIOS_SET_DEFAULT(type2.version, version); -diff --git a/hw/timer/i8254_common.c b/hw/timer/i8254_common.c -index 6190b6f..ad2ad2d 100644 ---- a/hw/timer/i8254_common.c -+++ b/hw/timer/i8254_common.c -@@ -268,7 +268,7 @@ static const VMStateDescription vmstate_pit_common = { - .pre_save = pit_dispatch_pre_save, - .post_load = pit_dispatch_post_load, - .fields = (VMStateField[]) { -- VMSTATE_UINT32_V(channels[0].irq_disabled, PITCommonState, 3), -+ VMSTATE_UINT32(channels[0].irq_disabled, PITCommonState), /* qemu-kvm's v2 had 'flags' here */ - VMSTATE_STRUCT_ARRAY(channels, PITCommonState, 3, 2, - vmstate_pit_channel, PITChannelState), - VMSTATE_INT64(channels[0].next_transition_time, -diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c -index 6f1f723..68c353f 100644 ---- a/hw/timer/mc146818rtc.c -+++ b/hw/timer/mc146818rtc.c -@@ -34,6 +34,7 @@ - #include "qapi/qapi-commands-misc.h" - #include "qapi/qapi-events-misc.h" - #include "qapi/visitor.h" -+#include "migration/migration.h" - - #ifdef TARGET_I386 - #include "hw/i386/apic.h" -@@ -839,6 +840,11 @@ static int rtc_post_load(void *opaque, int version_id) - static bool rtc_irq_reinject_on_ack_count_needed(void *opaque) - { - RTCState *s = (RTCState *)opaque; -+ -+ if (migrate_pre_2_2) { -+ return false; -+ } -+ - return s->irq_reinject_on_ack_count != 0; - } - -diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c -index 836b11f..9d7b9df 100644 ---- a/hw/usb/hcd-uhci.c -+++ b/hw/usb/hcd-uhci.c -@@ -1214,12 +1214,14 @@ static void usb_uhci_common_realize(PCIDevice *dev, Error **errp) - UHCIState *s = UHCI(dev); - uint8_t *pci_conf = s->dev.config; - int i; -+ int irq_pin; - - pci_conf[PCI_CLASS_PROG] = 0x00; - /* TODO: reset value should be 0. */ - pci_conf[USB_SBRN] = USB_RELEASE_1; // release number - -- pci_config_set_interrupt_pin(pci_conf, u->info.irq_pin + 1); -+ irq_pin = u->info.irq_pin; -+ pci_config_set_interrupt_pin(pci_conf, irq_pin + 1); - - if (s->masterbus) { - USBPort *ports[NB_PORTS]; -diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c -index 8f1a01a..ca19474 100644 ---- a/hw/usb/hcd-xhci.c -+++ b/hw/usb/hcd-xhci.c -@@ -3560,9 +3560,27 @@ static const VMStateDescription vmstate_xhci_slot = { - } - }; - -+static int xhci_event_pre_save(void *opaque) -+{ -+ XHCIEvent *s = opaque; -+ -+ s->cve_2014_5263_a = ((uint8_t *)&s->type)[0]; -+ s->cve_2014_5263_b = ((uint8_t *)&s->type)[1]; -+ -+ return 0; -+} -+ -+bool migrate_cve_2014_5263_xhci_fields; -+ -+static bool xhci_event_cve_2014_5263(void *opaque, int version_id) -+{ -+ return migrate_cve_2014_5263_xhci_fields; -+} -+ - static const VMStateDescription vmstate_xhci_event = { - .name = "xhci-event", - .version_id = 1, -+ .pre_save = xhci_event_pre_save, - .fields = (VMStateField[]) { - VMSTATE_UINT32(type, XHCIEvent), - VMSTATE_UINT32(ccode, XHCIEvent), -@@ -3571,6 +3589,8 @@ static const VMStateDescription vmstate_xhci_event = { - VMSTATE_UINT32(flags, XHCIEvent), - VMSTATE_UINT8(slotid, XHCIEvent), - VMSTATE_UINT8(epid, XHCIEvent), -+ VMSTATE_UINT8_TEST(cve_2014_5263_a, XHCIEvent, xhci_event_cve_2014_5263), -+ VMSTATE_UINT8_TEST(cve_2014_5263_b, XHCIEvent, xhci_event_cve_2014_5263), - VMSTATE_END_OF_LIST() - } - }; -diff --git a/hw/usb/hcd-xhci.h b/hw/usb/hcd-xhci.h -index fc36a4c..89d4cf7 100644 ---- a/hw/usb/hcd-xhci.h -+++ b/hw/usb/hcd-xhci.h -@@ -153,6 +153,8 @@ typedef struct XHCIEvent { - uint32_t flags; - uint8_t slotid; - uint8_t epid; -+ uint8_t cve_2014_5263_a; -+ uint8_t cve_2014_5263_b; - } XHCIEvent; - - typedef struct XHCIInterrupter { -diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h -index 59aeb06..7b5cc25 100644 ---- a/include/hw/acpi/ich9.h -+++ b/include/hw/acpi/ich9.h -@@ -61,6 +61,9 @@ typedef struct ICH9LPCPMRegs { - uint8_t smm_enabled; - bool enable_tco; - TCOIORegs tco_regs; -+ -+ /* RH addition, see bz 1489800 */ -+ bool force_rev1_fadt; - } ICH9LPCPMRegs; - - #define ACPI_PM_PROP_TCO_ENABLED "enable_tco" -diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h -index 9a870cc..2293315 100644 ---- a/include/hw/arm/virt.h -+++ b/include/hw/arm/virt.h -@@ -128,6 +128,7 @@ typedef struct { - - #define VIRT_ECAM_ID(high) (high ? VIRT_PCIE_ECAM_HIGH : VIRT_PCIE_ECAM) - -+#if 0 /* disabled for Red Hat Enterprise Linux */ - #define TYPE_VIRT_MACHINE MACHINE_TYPE_NAME("virt") - #define VIRT_MACHINE(obj) \ - OBJECT_CHECK(VirtMachineState, (obj), TYPE_VIRT_MACHINE) -@@ -136,6 +137,27 @@ typedef struct { - #define VIRT_MACHINE_CLASS(klass) \ - OBJECT_CLASS_CHECK(VirtMachineClass, klass, TYPE_VIRT_MACHINE) - -+#else -+#define TYPE_RHEL_MACHINE MACHINE_TYPE_NAME("virt-rhel") -+#define VIRT_MACHINE(obj) \ -+ OBJECT_CHECK(VirtMachineState, (obj), TYPE_RHEL_MACHINE) -+#define VIRT_MACHINE_GET_CLASS(obj) \ -+ OBJECT_GET_CLASS(VirtMachineClass, obj, TYPE_RHEL_MACHINE) -+#define VIRT_MACHINE_CLASS(klass) \ -+ OBJECT_CLASS_CHECK(VirtMachineClass, klass, TYPE_RHEL_MACHINE) -+#endif -+ -+/* This macro is for changes to properties that are RHEL specific, -+ * different to the current upstream and to be applied to the latest -+ * machine type. -+ */ -+#define ARM_RHEL_COMPAT \ -+ {\ -+ .driver = "virtio-net-pci",\ -+ .property = "romfile",\ -+ .value = "",\ -+ }, -+ - void virt_acpi_setup(VirtMachineState *vms); - - /* Return the number of used redistributor regions */ -diff --git a/include/hw/compat.h b/include/hw/compat.h -index c08f404..22262c7 100644 ---- a/include/hw/compat.h -+++ b/include/hw/compat.h -@@ -282,4 +282,233 @@ - .value = "on",\ - }, - -+/* Mostly like HW_COMPAT_2_1 but: -+ * we don't need virtio-scsi-pci since 7.0 already had that on -+ * -+ * RH: Note, qemu-extended-regs should have been enabled in the 7.1 -+ * machine type, but was accidentally turned off in 7.2 onwards. -+ * -+ */ -+#define HW_COMPAT_RHEL7_1 \ -+ { /* COMPAT_RHEL7.1 */ \ -+ .driver = "intel-hda-generic",\ -+ .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),\ -+ },{\ -+ .driver = "virtio-pci",\ -+ .property = "virtio-pci-bus-master-bug-migration",\ -+ .value = "on",\ -+ },{\ -+ .driver = "virtio-blk-pci",\ -+ .property = "any_layout",\ -+ .value = "off",\ -+ },{\ -+ .driver = "virtio-balloon-pci",\ -+ .property = "any_layout",\ -+ .value = "off",\ -+ },{\ -+ .driver = "virtio-serial-pci",\ -+ .property = "any_layout",\ -+ .value = "off",\ -+ },{\ -+ .driver = "virtio-9p-pci",\ -+ .property = "any_layout",\ -+ .value = "off",\ -+ },{\ -+ .driver = "virtio-rng-pci",\ -+ .property = "any_layout",\ -+ .value = "off",\ -+ },{ /* HW_COMPAT_RHEL7_1 - introduced with 2.10.0 */ \ -+ .driver = "migration",\ -+ .property = "send-configuration",\ -+ .value = "off",\ -+ }, -+ -+/* Mostly like HW_COMPAT_2_4 + 2_3 but: -+ * we don't need "any_layout" as it has been backported to 7.2 -+ */ -+ -+#define HW_COMPAT_RHEL7_2 \ -+ {\ -+ .driver = "virtio-blk-device",\ -+ .property = "scsi",\ -+ .value = "true",\ -+ },{\ -+ .driver = "e1000-82540em",\ -+ .property = "extra_mac_registers",\ -+ .value = "off",\ -+ },{\ -+ .driver = "virtio-pci",\ -+ .property = "x-disable-pcie",\ -+ .value = "on",\ -+ },{\ -+ .driver = "virtio-pci",\ -+ .property = "migrate-extra",\ -+ .value = "off",\ -+ },{ /* HW_COMPAT_RHEL7_2 */ \ -+ .driver = "fw_cfg_mem",\ -+ .property = "dma_enabled",\ -+ .value = "off",\ -+ },{ /* HW_COMPAT_RHEL7_2 */ \ -+ .driver = "fw_cfg_io",\ -+ .property = "dma_enabled",\ -+ .value = "off",\ -+ },{ /* HW_COMPAT_RHEL7_2 */ \ -+ .driver = "isa-fdc",\ -+ .property = "fallback",\ -+ .value = "144",\ -+ },{ /* HW_COMPAT_RHEL7_2 */ \ -+ .driver = "virtio-pci",\ -+ .property = "disable-modern",\ -+ .value = "on",\ -+ },{ /* HW_COMPAT_RHEL7_2 */ \ -+ .driver = "virtio-pci",\ -+ .property = "disable-legacy",\ -+ .value = "off",\ -+ },{ /* HW_COMPAT_RHEL7_2 */ \ -+ .driver = TYPE_PCI_DEVICE,\ -+ .property = "x-pcie-lnksta-dllla",\ -+ .value = "off",\ -+ },{ /* HW_COMPAT_RHEL7_2 */ \ -+ .driver = "virtio-pci",\ -+ .property = "page-per-vq",\ -+ .value = "on",\ -+ },{ /* HW_COMPAT_RHEL7_2 - introduced with 2.10.0 */ \ -+ .driver = "migration",\ -+ .property = "send-section-footer",\ -+ .value = "off",\ -+ },{ /* HW_COMPAT_RHEL7_2 - introduced with 2.10.0 */ \ -+ .driver = "migration",\ -+ .property = "store-global-state",\ -+ .value = "off",\ -+ }, -+ -+/* Mostly like HW_COMPAT_2_6 + HW_COMPAT_2_7 + HW_COMPAT_2_8 except -+ * disable-modern, disable-legacy, page-per-vq have already been -+ * backported to RHEL7.3 -+ */ -+#define HW_COMPAT_RHEL7_3 \ -+ { /* HW_COMPAT_RHEL7_3 */ \ -+ .driver = "virtio-mmio",\ -+ .property = "format_transport_address",\ -+ .value = "off",\ -+ },{ /* HW_COMPAT_RHEL7_3 */ \ -+ .driver = "virtio-serial-device",\ -+ .property = "emergency-write",\ -+ .value = "off",\ -+ },{ /* HW_COMPAT_RHEL7_3 */ \ -+ .driver = "ioapic",\ -+ .property = "version",\ -+ .value = "0x11",\ -+ },{ /* HW_COMPAT_RHEL7_3 */ \ -+ .driver = "intel-iommu",\ -+ .property = "x-buggy-eim",\ -+ .value = "true",\ -+ },{ /* HW_COMPAT_RHEL7_3 */ \ -+ .driver = "virtio-pci",\ -+ .property = "x-ignore-backend-features",\ -+ .value = "on",\ -+ },{ /* HW_COMPAT_RHEL7_3 */ \ -+ .driver = "fw_cfg_mem",\ -+ .property = "x-file-slots",\ -+ .value = stringify(0x10),\ -+ },{ /* HW_COMPAT_RHEL7_3 */ \ -+ .driver = "fw_cfg_io",\ -+ .property = "x-file-slots",\ -+ .value = stringify(0x10),\ -+ },{ /* HW_COMPAT_RHEL7_3 */ \ -+ .driver = "pflash_cfi01",\ -+ .property = "old-multiple-chip-handling",\ -+ .value = "on",\ -+ },{ /* HW_COMPAT_RHEL7_3 */ \ -+ .driver = TYPE_PCI_DEVICE,\ -+ .property = "x-pcie-extcap-init",\ -+ .value = "off",\ -+ },{ /* HW_COMPAT_RHEL7_3 */ \ -+ .driver = "virtio-pci",\ -+ .property = "x-pcie-deverr-init",\ -+ .value = "off",\ -+ },{ /* HW_COMPAT_RHEL7_3 */ \ -+ .driver = "virtio-pci",\ -+ .property = "x-pcie-lnkctl-init",\ -+ .value = "off",\ -+ },{ /* HW_COMPAT_RHEL7_3 */ \ -+ .driver = "virtio-pci",\ -+ .property = "x-pcie-pm-init",\ -+ .value = "off",\ -+ },{ /* HW_COMPAT_RHEL7_3 */ \ -+ .driver = "virtio-net-device",\ -+ .property = "x-mtu-bypass-backend",\ -+ .value = "off",\ -+ },{ /* HW_COMPAT_RHEL7_3 */ \ -+ .driver = "e1000e",\ -+ .property = "__redhat_e1000e_7_3_intr_state",\ -+ .value = "on",\ -+ }, -+ -+/* Mostly like HW_COMPAT_2_9 except -+ * x-mtu-bypass-backend, x-migrate-msix has already been -+ * backported to RHEL7.4. shpc was already on in 7.4. -+ */ -+#define HW_COMPAT_RHEL7_4 \ -+ { /* HW_COMPAT_RHEL7_4 */ \ -+ .driver = "intel-iommu",\ -+ .property = "pt",\ -+ .value = "off",\ -+ }, -+ -+/* The same as HW_COMPAT_2_11 + HW_COMPAT_2_10 */ -+#define HW_COMPAT_RHEL7_5 \ -+ { /* HW_COMPAT_RHEL7_5 from HW_COMPAT_2_11 */ \ -+ .driver = "hpet",\ -+ .property = "hpet-offset-saved",\ -+ .value = "false",\ -+ },{ /* HW_COMPAT_RHEL7_5 from HW_COMPAT_2_11 */ \ -+ .driver = "virtio-blk-pci",\ -+ .property = "vectors",\ -+ .value = "2",\ -+ },{ /* HW_COMPAT_RHEL7_5 from HW_COMPAT_2_11 */ \ -+ .driver = "vhost-user-blk-pci",\ -+ .property = "vectors",\ -+ .value = "2",\ -+ },{ /* HW_COMPAT_RHEL7_5 from HW_COMPAT_2_11 but \ -+ bz 1608778 modified for our naming */ \ -+ .driver = "e1000-82540em",\ -+ .property = "migrate_tso_props",\ -+ .value = "off",\ -+ },{ /* HW_COMPAT_RHEL7_5 from HW_COMPAT_2_10 */ \ -+ .driver = "virtio-mouse-device",\ -+ .property = "wheel-axis",\ -+ .value = "false",\ -+ },{ /* HW_COMPAT_RHEL7_5 from HW_COMPAT_2_10 */ \ -+ .driver = "virtio-tablet-device",\ -+ .property = "wheel-axis",\ -+ .value = "false",\ -+ },{ /* HW_COMPAT_RHEL7_5 */ \ -+ .driver = "cirrus-vga",\ -+ .property = "vgamem_mb",\ -+ .value = "16",\ -+ },{ /* HW_COMPAT_RHEL7_5 */ \ -+ .driver = "migration",\ -+ .property = "decompress-error-check",\ -+ .value = "off",\ -+ }, -+ -+ - #endif /* HW_COMPAT_H */ -diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h -index 6894f37..ef82513 100644 ---- a/include/hw/i386/pc.h -+++ b/include/hw/i386/pc.h -@@ -134,6 +134,9 @@ struct PCMachineClass { - - /* use DMA capable linuxboot option rom */ - bool linuxboot_dma_enabled; -+ -+ /* RH only, see bz 1489800 */ -+ bool pc_rom_ro; - }; - - #define TYPE_PC_MACHINE "generic-pc-machine" -@@ -960,4 +963,565 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); - type_init(pc_machine_init_##suffix) - - extern void igd_passthrough_isa_bridge_create(PCIBus *bus, uint16_t gpu_dev_id); -+ -+/* See include/hw/compat.h for shared compatibility lists */ -+ -+/* This macro is for changes to properties that are RHEL specific, -+ * different to the current upstream and to be applied to the latest -+ * machine type. -+ */ -+#define PC_RHEL_COMPAT \ -+ { /* PC_RHEL_COMPAT */ \ -+ .driver = TYPE_X86_CPU,\ -+ .property = "host-phys-bits",\ -+ .value = "on",\ -+ },\ -+ { /* PC_RHEL_COMPAT bz 1508330 */ \ -+ .driver = "vfio-pci",\ -+ .property = "x-no-geforce-quirks",\ -+ .value = "on",\ -+ }, -+ -+/* Similar to PC_COMPAT_2_11 + PC_COMPAT_2_10, but: -+ * - x-hv-max-vps was backported to 7.5 -+ * - x-pci-hole64-fix was backported to 7.5 -+ */ -+#define PC_RHEL7_5_COMPAT \ -+ HW_COMPAT_RHEL7_5 \ -+ { /* PC_RHEL7_5_COMPAT from PC_COMPAT_2_11 */ \ -+ .driver = "Skylake-Server" "-" TYPE_X86_CPU,\ -+ .property = "clflushopt",\ -+ .value = "off",\ -+ }, -+ -+ -+#define PC_RHEL7_4_COMPAT \ -+ HW_COMPAT_RHEL7_4 \ -+ { /* PC_RHEL7_4_COMPAT from PC_COMPAT_2_9 */ \ -+ .driver = "mch",\ -+ .property = "extended-tseg-mbytes",\ -+ .value = stringify(0),\ -+ },\ -+ { /* PC_RHEL7_4_COMPAT bz 1489800 */ \ -+ .driver = "ICH9-LPC",\ -+ .property = "__com.redhat_force-rev1-fadt",\ -+ .value = "on",\ -+ },\ -+ { /* PC_RHEL7_4_COMPAT from PC_COMPAT_2_10 */ \ -+ .driver = "i440FX-pcihost",\ -+ .property = "x-pci-hole64-fix",\ -+ .value = "off",\ -+ },\ -+ { /* PC_RHEL7_4_COMPAT from PC_COMPAT_2_10 */ \ -+ .driver = "q35-pcihost",\ -+ .property = "x-pci-hole64-fix",\ -+ .value = "off",\ -+ },\ -+ { /* PC_RHEL7_4_COMPAT from PC_COMPAT_2_10 */ \ -+ .driver = TYPE_X86_CPU,\ -+ .property = "x-hv-max-vps",\ -+ .value = "0x40",\ -+ }, -+ -+#define PC_RHEL7_3_COMPAT \ -+ HW_COMPAT_RHEL7_3 \ -+ { /* PC_RHEL7_3_COMPAT from PC_COMPAT_2_8 */ \ -+ .driver = "kvmclock",\ -+ .property = "x-mach-use-reliable-get-clock",\ -+ .value = "off",\ -+ },\ -+ { /* PC_RHEL7_3_COMPAT from PC_COMPAT_2_7 */ \ -+ .driver = TYPE_X86_CPU,\ -+ .property = "l3-cache",\ -+ .value = "off",\ -+ },\ -+ { /* PC_RHEL7_3_COMPAT from PC_COMPAT_2_7 */ \ -+ .driver = TYPE_X86_CPU,\ -+ .property = "full-cpuid-auto-level",\ -+ .value = "off",\ -+ },\ -+ { /* PC_RHEL7_3_COMPAT from PC_COMPAT_2_7 */ \ -+ .driver = "Opteron_G3" "-" TYPE_X86_CPU,\ -+ .property = "family",\ -+ .value = "15",\ -+ },\ -+ { /* PC_RHEL7_3_COMPAT from PC_COMPAT_2_7 */ \ -+ .driver = "Opteron_G3" "-" TYPE_X86_CPU,\ -+ .property = "model",\ -+ .value = "6",\ -+ },\ -+ { /* PC_RHEL7_3_COMPAT from PC_COMPAT_2_7 */ \ -+ .driver = "Opteron_G3" "-" TYPE_X86_CPU,\ -+ .property = "stepping",\ -+ .value = "1",\ -+ },\ -+ { /* PC_RHEL7_3_COMPAT from PC_COMPAT_2_7 */ \ -+ .driver = "isa-pcspk",\ -+ .property = "migrate",\ -+ .value = "off",\ -+ },\ -+ { /* PC_RHEL7_3_COMPAT from PC_COMPAT_2_6 */ \ -+ .driver = TYPE_X86_CPU,\ -+ .property = "cpuid-0xb",\ -+ .value = "off",\ -+ },\ -+ { /* PC_RHEL7_3_COMPAT from PC_COMPAT_2_8 */ \ -+ .driver = "ICH9-LPC",\ -+ .property = "x-smi-broadcast",\ -+ .value = "off",\ -+ },\ -+ { /* PC_RHEL7_3_COMPAT from PC_COMPAT_2_8 */ \ -+ .driver = TYPE_X86_CPU,\ -+ .property = "vmware-cpuid-freq",\ -+ .value = "off",\ -+ },\ -+ { /* PC_RHEL7_3_COMPAT from PC_COMPAT_2_8 */ \ -+ .driver = "Haswell-" TYPE_X86_CPU,\ -+ .property = "stepping",\ -+ .value = "1",\ -+ },\ -+ { /* PC_RHEL7_3_COMPAT from PC_COMPAT_2_3 added in 2.9 */ \ -+ .driver = TYPE_X86_CPU,\ -+ .property = "kvm-no-smi-migration",\ -+ .value = "on",\ -+ }, -+ -+#define PC_RHEL7_2_COMPAT \ -+ HW_COMPAT_RHEL7_2 \ -+ {\ -+ .driver = "phenom" "-" TYPE_X86_CPU,\ -+ .property = "rdtscp",\ -+ .value = "off",\ -+ },\ -+ { /* PC_RHEL7_2_COMPAT */ \ -+ .driver = "qemu64" "-" TYPE_X86_CPU,\ -+ .property = "sse4a",\ -+ .value = "on",\ -+ },\ -+ { /* PC_RHEL7_2_COMPAT */ \ -+ .driver = "qemu64" "-" TYPE_X86_CPU,\ -+ .property = "abm",\ -+ .value = "on",\ -+ },\ -+ { /* PC_RHEL7_2_COMPAT */ \ -+ .driver = "Haswell-" TYPE_X86_CPU,\ -+ .property = "abm",\ -+ .value = "off",\ -+ },\ -+ { /* PC_RHEL7_2_COMPAT (copied from the entry above) */ \ -+ .driver = "Haswell-IBRS" "-" TYPE_X86_CPU,\ -+ .property = "abm",\ -+ .value = "off",\ -+ },\ -+ { /* PC_RHEL7_2_COMPAT */ \ -+ .driver = "Haswell-noTSX-" TYPE_X86_CPU,\ -+ .property = "abm",\ -+ .value = "off",\ -+ },\ -+ { /* PC_RHEL7_2_COMPAT (copied from the entry above) */ \ -+ .driver = "Haswell-noTSX-IBRS" "-" TYPE_X86_CPU,\ -+ .property = "abm",\ -+ .value = "off",\ -+ },\ -+ { /* PC_RHEL7_2_COMPAT */ \ -+ .driver = "Broadwell-" TYPE_X86_CPU,\ -+ .property = "abm",\ -+ .value = "off",\ -+ },\ -+ { /* PC_RHEL7_2_COMPAT (copied from the entry above) */ \ -+ .driver = "Broadwell-IBRS" "-" TYPE_X86_CPU,\ -+ .property = "abm",\ -+ .value = "off",\ -+ },\ -+ { /* PC_RHEL7_2_COMPAT */ \ -+ .driver = "Broadwell-noTSX-" TYPE_X86_CPU,\ -+ .property = "abm",\ -+ .value = "off",\ -+ },\ -+ { /* PC_RHEL7_2_COMPAT (copied from the entry above) */ \ -+ .driver = "Broadwell-noTSX-IBRS" "-" TYPE_X86_CPU,\ -+ .property = "abm",\ -+ .value = "off",\ -+ },\ -+ { /* PC_RHEL7_2_COMPAT */ \ -+ .driver = "host" "-" TYPE_X86_CPU,\ -+ .property = "host-cache-info",\ -+ .value = "on",\ -+ },\ -+ { /* PC_RHEL7_2_COMPAT */ \ -+ .driver = TYPE_X86_CPU,\ -+ .property = "check",\ -+ .value = "off",\ -+ },\ -+ { /* PC_RHEL7_2_COMPAT */ \ -+ .driver = "qemu32" "-" TYPE_X86_CPU,\ -+ .property = "popcnt",\ -+ .value = "on",\ -+ },\ -+ { /* PC_RHEL7_2_COMPAT */ \ -+ .driver = TYPE_X86_CPU,\ -+ .property = "arat",\ -+ .value = "off",\ -+ },\ -+ { /* PC_RHEL7_2_COMPAT */ \ -+ .driver = "usb-redir",\ -+ .property = "streams",\ -+ .value = "off",\ -+ },\ -+ { /* PC_RHEL7_2_COMPAT */ \ -+ .driver = TYPE_X86_CPU,\ -+ .property = "fill-mtrr-mask",\ -+ .value = "off",\ -+ },\ -+ { /* PC_RHEL7_2_COMPAT */ \ -+ .driver = "apic-common",\ -+ .property = "legacy-instance-id",\ -+ .value = "on",\ -+ }, -+ -+ -+ -+#define PC_RHEL7_1_COMPAT \ -+ HW_COMPAT_RHEL7_1 \ -+ {\ -+ .driver = "kvm64" "-" TYPE_X86_CPU,\ -+ .property = "vme",\ -+ .value = "off",\ -+ },\ -+ {\ -+ .driver = "kvm32" "-" TYPE_X86_CPU,\ -+ .property = "vme",\ -+ .value = "off",\ -+ },\ -+ {\ -+ .driver = "Conroe" "-" TYPE_X86_CPU,\ -+ .property = "vme",\ -+ .value = "off",\ -+ },\ -+ {\ -+ .driver = "Penryn" "-" TYPE_X86_CPU,\ -+ .property = "vme",\ -+ .value = "off",\ -+ },\ -+ {\ -+ .driver = "Nehalem" "-" TYPE_X86_CPU,\ -+ .property = "vme",\ -+ .value = "off",\ -+ },\ -+ { /* PC_RHEL7_1_COMPAT (copied from the entry above) */ \ -+ .driver = "Nehalem-IBRS" "-" TYPE_X86_CPU,\ -+ .property = "vme",\ -+ .value = "off",\ -+ },\ -+ {\ -+ .driver = "Westmere" "-" TYPE_X86_CPU,\ -+ .property = "vme",\ -+ .value = "off",\ -+ },\ -+ { /* PC_RHEL7_1_COMPAT (copied from the entry above) */ \ -+ .driver = "Westmere-IBRS" "-" TYPE_X86_CPU,\ -+ .property = "vme",\ -+ .value = "off",\ -+ },\ -+ {\ -+ .driver = "SandyBridge" "-" TYPE_X86_CPU,\ -+ .property = "vme",\ -+ .value = "off",\ -+ },\ -+ { /* PC_RHEL7_1_COMPAT (copied from the entry above) */ \ -+ .driver = "SandyBridge-IBRS" "-" TYPE_X86_CPU,\ -+ .property = "vme",\ -+ .value = "off",\ -+ },\ -+ {\ -+ .driver = "Haswell" "-" TYPE_X86_CPU,\ -+ .property = "vme",\ -+ .value = "off",\ -+ },\ -+ { /* PC_RHEL7_1_COMPAT (copied from the entry above) */ \ -+ .driver = "Haswell-IBRS" "-" TYPE_X86_CPU,\ -+ .property = "vme",\ -+ .value = "off",\ -+ },\ -+ {\ -+ .driver = "Broadwell" "-" TYPE_X86_CPU,\ -+ .property = "vme",\ -+ .value = "off",\ -+ },\ -+ { /* PC_RHEL7_1_COMPAT (copied from the entry above) */ \ -+ .driver = "Broadwell-IBRS" "-" TYPE_X86_CPU,\ -+ .property = "vme",\ -+ .value = "off",\ -+ },\ -+ {\ -+ .driver = "Opteron_G1" "-" TYPE_X86_CPU,\ -+ .property = "vme",\ -+ .value = "off",\ -+ },\ -+ {\ -+ .driver = "Opteron_G2" "-" TYPE_X86_CPU,\ -+ .property = "vme",\ -+ .value = "off",\ -+ },\ -+ {\ -+ .driver = "Opteron_G3" "-" TYPE_X86_CPU,\ -+ .property = "vme",\ -+ .value = "off",\ -+ },\ -+ {\ -+ .driver = "Opteron_G4" "-" TYPE_X86_CPU,\ -+ .property = "vme",\ -+ .value = "off",\ -+ },\ -+ {\ -+ .driver = "Opteron_G5" "-" TYPE_X86_CPU,\ -+ .property = "vme",\ -+ .value = "off",\ -+ },\ -+ {\ -+ .driver = "Haswell" "-" TYPE_X86_CPU,\ -+ .property = "f16c",\ -+ .value = "off",\ -+ },\ -+ { /* PC_RHEL7_1_COMPAT (copied from the entry above) */ \ -+ .driver = "Haswell-IBRS" "-" TYPE_X86_CPU,\ -+ .property = "f16c",\ -+ .value = "off",\ -+ },\ -+ {\ -+ .driver = "Haswell" "-" TYPE_X86_CPU,\ -+ .property = "rdrand",\ -+ .value = "off",\ -+ },\ -+ { /* PC_RHEL7_1_COMPAT (copied from the entry above) */ \ -+ .driver = "Haswell-IBRS" "-" TYPE_X86_CPU,\ -+ .property = "rdrand",\ -+ .value = "off",\ -+ },\ -+ {\ -+ .driver = "Broadwell" "-" TYPE_X86_CPU,\ -+ .property = "f16c",\ -+ .value = "off",\ -+ },\ -+ { /* PC_RHEL7_1_COMPAT (copied from the entry above) */ \ -+ .driver = "Broadwell-IBRS" "-" TYPE_X86_CPU,\ -+ .property = "f16c",\ -+ .value = "off",\ -+ },\ -+ {\ -+ .driver = "Broadwell" "-" TYPE_X86_CPU,\ -+ .property = "rdrand",\ -+ .value = "off",\ -+ },\ -+ { /* PC_RHEL7_1_COMPAT (copied from the entry above) */ \ -+ .driver = "Broadwell-IBRS" "-" TYPE_X86_CPU,\ -+ .property = "rdrand",\ -+ .value = "off",\ -+ },\ -+ {\ -+ .driver = "coreduo" "-" TYPE_X86_CPU,\ -+ .property = "vmx",\ -+ .value = "on",\ -+ },\ -+ {\ -+ .driver = "core2duo" "-" TYPE_X86_CPU,\ -+ .property = "vmx",\ -+ .value = "on",\ -+ },\ -+ { /* PC_RHEL7_1_COMPAT */ \ -+ .driver = "qemu64" "-" TYPE_X86_CPU,\ -+ .property = "min-level",\ -+ .value = stringify(4),\ -+ },{ /* PC_RHEL7_1_COMPAT */ \ -+ .driver = "kvm64" "-" TYPE_X86_CPU,\ -+ .property = "min-level",\ -+ .value = stringify(5),\ -+ },{ /* PC_RHEL7_1_COMPAT */ \ -+ .driver = "pentium3" "-" TYPE_X86_CPU,\ -+ .property = "min-level",\ -+ .value = stringify(2),\ -+ },{ /* PC_RHEL7_1_COMPAT */ \ -+ .driver = "n270" "-" TYPE_X86_CPU,\ -+ .property = "min-level",\ -+ .value = stringify(5),\ -+ },{ /* PC_RHEL7_1_COMPAT */ \ -+ .driver = "Conroe" "-" TYPE_X86_CPU,\ -+ .property = "min-level",\ -+ .value = stringify(4),\ -+ },{ /* PC_RHEL7_1_COMPAT */ \ -+ .driver = "Penryn" "-" TYPE_X86_CPU,\ -+ .property = "min-level",\ -+ .value = stringify(4),\ -+ },{ /* PC_RHEL7_1_COMPAT */ \ -+ .driver = "Nehalem" "-" TYPE_X86_CPU,\ -+ .property = "min-level",\ -+ .value = stringify(4),\ -+ },{ /* PC_RHEL7_1_COMPAT */ \ -+ .driver = "n270" "-" TYPE_X86_CPU,\ -+ .property = "min-xlevel",\ -+ .value = stringify(0x8000000a),\ -+ },{ /* PC_RHEL7_1_COMPAT */ \ -+ .driver = "Penryn" "-" TYPE_X86_CPU,\ -+ .property = "min-xlevel",\ -+ .value = stringify(0x8000000a),\ -+ },{ /* PC_RHEL7_1_COMPAT */ \ -+ .driver = "Conroe" "-" TYPE_X86_CPU,\ -+ .property = "min-xlevel",\ -+ .value = stringify(0x8000000a),\ -+ },{ /* PC_RHEL7_1_COMPAT */ \ -+ .driver = "Nehalem" "-" TYPE_X86_CPU,\ -+ .property = "min-xlevel",\ -+ .value = stringify(0x8000000a),\ -+ },{ /* PC_RHEL7_1_COMPAT */ \ -+ .driver = "Westmere" "-" TYPE_X86_CPU,\ -+ .property = "min-xlevel",\ -+ .value = stringify(0x8000000a),\ -+ },{ /* PC_RHEL7_1_COMPAT */ \ -+ .driver = "SandyBridge" "-" TYPE_X86_CPU,\ -+ .property = "min-xlevel",\ -+ .value = stringify(0x8000000a),\ -+ },{ /* PC_RHEL7_1_COMPAT */ \ -+ .driver = "IvyBridge" "-" TYPE_X86_CPU,\ -+ .property = "min-xlevel",\ -+ .value = stringify(0x8000000a),\ -+ },{ /* PC_RHEL7_1_COMPAT */ \ -+ .driver = "Haswell" "-" TYPE_X86_CPU,\ -+ .property = "min-xlevel",\ -+ .value = stringify(0x8000000a),\ -+ },{ /* PC_RHEL7_1_COMPAT */ \ -+ .driver = "Haswell-noTSX" "-" TYPE_X86_CPU,\ -+ .property = "min-xlevel",\ -+ .value = stringify(0x8000000a),\ -+ },{ /* PC_RHEL7_1_COMPAT */ \ -+ .driver = "Broadwell" "-" TYPE_X86_CPU,\ -+ .property = "min-xlevel",\ -+ .value = stringify(0x8000000a),\ -+ },{ /* PC_RHEL7_1_COMPAT */ \ -+ .driver = "Broadwell-noTSX" "-" TYPE_X86_CPU,\ -+ .property = "min-xlevel",\ -+ .value = stringify(0x8000000a),\ -+ }, -+ -+/* -+ * The PC_RHEL_*_COMPAT serve the same purpose for RHEL-7 machine -+ * types as the PC_COMPAT_* do for upstream types. -+ * PC_RHEL_7_*_COMPAT apply both to i440fx and q35 types. -+ */ -+ -+/* -+ * RHEL-7 is based on QEMU 1.5.3, so this needs the PC_COMPAT_* -+ * between our base and 1.5, less stuff backported to RHEL-7.0 -+ * (usb-device.msos-desc), less stuff for devices we changed -+ * (qemu64-x86_64-cpu) or don't support (hpet, pci-serial-2x, -+ * pci-serial-4x) in 7.0. -+ */ -+#define PC_RHEL7_0_COMPAT \ -+ {\ -+ .driver = "virtio-scsi-pci",\ -+ .property = "any_layout",\ -+ .value = "off",\ -+ },{\ -+ .driver = "PIIX4_PM",\ -+ .property = "memory-hotplug-support",\ -+ .value = "off",\ -+ },{\ -+ .driver = "apic",\ -+ .property = "version",\ -+ .value = stringify(0x11),\ -+ },{\ -+ .driver = "nec-usb-xhci",\ -+ .property = "superspeed-ports-first",\ -+ .value = "off",\ -+ },{\ -+ .driver = "nec-usb-xhci",\ -+ .property = "force-pcie-endcap",\ -+ .value = "on",\ -+ },{\ -+ .driver = "pci-serial",\ -+ .property = "prog_if",\ -+ .value = stringify(0),\ -+ },{\ -+ .driver = "virtio-net-pci",\ -+ .property = "guest_announce",\ -+ .value = "off",\ -+ },{\ -+ .driver = "ICH9-LPC",\ -+ .property = "memory-hotplug-support",\ -+ .value = "off",\ -+ },{\ -+ .driver = "xio3130-downstream",\ -+ .property = COMPAT_PROP_PCP,\ -+ .value = "off",\ -+ },{\ -+ .driver = "ioh3420",\ -+ .property = COMPAT_PROP_PCP,\ -+ .value = "off",\ -+ },{\ -+ .driver = "PIIX4_PM",\ -+ .property = "acpi-pci-hotplug-with-bridge-support",\ -+ .value = "off",\ -+ },{\ -+ .driver = "e1000",\ -+ .property = "mitigation",\ -+ .value = "off",\ -+ },{ \ -+ .driver = "virtio-net-pci", \ -+ .property = "ctrl_guest_offloads", \ -+ .value = "off", \ -+ },\ -+ {\ -+ .driver = "Conroe" "-" TYPE_X86_CPU,\ -+ .property = "x2apic",\ -+ .value = "on",\ -+ },\ -+ {\ -+ .driver = "Penryn" "-" TYPE_X86_CPU,\ -+ .property = "x2apic",\ -+ .value = "on",\ -+ },\ -+ {\ -+ .driver = "Nehalem" "-" TYPE_X86_CPU,\ -+ .property = "x2apic",\ -+ .value = "on",\ -+ },\ -+ { /* PC_RHEL7_0_COMPAT (copied from the entry above) */ \ -+ .driver = "Nehalem-IBRS" "-" TYPE_X86_CPU,\ -+ .property = "x2apic",\ -+ .value = "on",\ -+ },\ -+ {\ -+ .driver = "Westmere" "-" TYPE_X86_CPU,\ -+ .property = "x2apic",\ -+ .value = "on",\ -+ },\ -+ { /* PC_RHEL7_0_COMPAT (copied from the entry above) */ \ -+ .driver = "Westmere-IBRS" "-" TYPE_X86_CPU,\ -+ .property = "x2apic",\ -+ .value = "on",\ -+ },\ -+ {\ -+ .driver = "Opteron_G1" "-" TYPE_X86_CPU,\ -+ .property = "x2apic",\ -+ .value = "on",\ -+ },\ -+ {\ -+ .driver = "Opteron_G2" "-" TYPE_X86_CPU,\ -+ .property = "x2apic",\ -+ .value = "on",\ -+ },\ -+ {\ -+ .driver = "Opteron_G3" "-" TYPE_X86_CPU,\ -+ .property = "x2apic",\ -+ .value = "on",\ -+ },\ -+ {\ -+ .driver = "Opteron_G4" "-" TYPE_X86_CPU,\ -+ .property = "x2apic",\ -+ .value = "on",\ -+ },\ -+ {\ -+ .driver = "Opteron_G5" "-" TYPE_X86_CPU,\ -+ .property = "x2apic",\ -+ .value = "on",\ -+ }, - #endif -diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h -index 7e5de1a..330c370 100644 ---- a/include/hw/ppc/spapr.h -+++ b/include/hw/ppc/spapr.h -@@ -101,6 +101,7 @@ struct sPAPRMachineClass { - bool dr_lmb_enabled; /* enable dynamic-reconfig/hotplug of LMBs */ - bool use_ohci_by_default; /* use USB-OHCI instead of XHCI */ - bool pre_2_10_has_unused_icps; -+ bool has_power9_support; - void (*phb_placement)(sPAPRMachineState *spapr, uint32_t index, - uint64_t *buid, hwaddr *pio, - hwaddr *mmio32, hwaddr *mmio64, -diff --git a/include/hw/usb.h b/include/hw/usb.h -index a5080ad..b943ec9 100644 ---- a/include/hw/usb.h -+++ b/include/hw/usb.h -@@ -606,4 +606,8 @@ int usb_get_quirks(uint16_t vendor_id, uint16_t product_id, - uint8_t interface_class, uint8_t interface_subclass, - uint8_t interface_protocol); - -+ -+/* hcd-xhci.c -- rhel7.0.0 machine type compatibility */ -+extern bool migrate_cve_2014_5263_xhci_fields; -+ - #endif -diff --git a/migration/migration.c b/migration/migration.c -index b7d9854..381039c 100644 ---- a/migration/migration.c -+++ b/migration/migration.c -@@ -106,6 +106,8 @@ enum mig_rp_message_type { - MIG_RP_MSG_MAX - }; - -+bool migrate_pre_2_2; -+ - /* When we add fault tolerance, we could have several - migrations at once. For now we don't need to add - dynamic creation of migration */ -diff --git a/migration/migration.h b/migration/migration.h -index 64a7b33..405d984 100644 ---- a/migration/migration.h -+++ b/migration/migration.h -@@ -288,6 +288,11 @@ void migrate_send_rp_resume_ack(MigrationIncomingState *mis, uint32_t value); - - void dirty_bitmap_mig_before_vm_start(void); - void init_dirty_bitmap_incoming_migration(void); -+/* -+ * Disables a load of subsections that were added in 2.2/rh7.2 for backwards -+ * migration compatibility. -+ */ -+extern bool migrate_pre_2_2; - - #define qemu_ram_foreach_block \ - #warning "Use qemu_ram_foreach_block_migratable in migration code" -diff --git a/qdev-monitor.c b/qdev-monitor.c -index 61e0300..f439b83 100644 ---- a/qdev-monitor.c -+++ b/qdev-monitor.c -@@ -47,7 +47,6 @@ typedef struct QDevAlias - - /* Please keep this table sorted by typename. */ - static const QDevAlias qdev_alias_table[] = { -- { "e1000", "e1000-82540em" }, - { "ich9-ahci", "ahci" }, - { "lsi53c895a", "lsi" }, - { "virtio-9p-ccw", "virtio-9p", QEMU_ARCH_S390X }, -diff --git a/scripts/vmstate-static-checker.py b/scripts/vmstate-static-checker.py -index d346728..4bca2bf 100755 ---- a/scripts/vmstate-static-checker.py -+++ b/scripts/vmstate-static-checker.py -@@ -105,7 +105,6 @@ def get_changed_sec_name(sec): - # Section names can change -- see commit 292b1634 for an example. - changes = { - "ICH9 LPC": "ICH9-LPC", -- "e1000-82540em": "e1000", - } - - for item in changes: -diff --git a/target/i386/cpu.c b/target/i386/cpu.c -index 338ee37..051018a 100644 ---- a/target/i386/cpu.c -+++ b/target/i386/cpu.c -@@ -1360,11 +1360,17 @@ static CPUCaches epyc_cache_info = { - - static X86CPUDefinition builtin_x86_defs[] = { - { -+ /* qemu64 is the default CPU model for all *-rhel7.* machine-types. -+ * The default on RHEL-6 was cpu64-rhel6. -+ * libvirt assumes that qemu64 is the default for _all_ machine-types, -+ * so we should try to keep qemu64 and cpu64-rhel6 as similar as -+ * possible. -+ */ - .name = "qemu64", - .level = 0xd, - .vendor = CPUID_VENDOR_AMD, - .family = 6, -- .model = 6, -+ .model = 13, - .stepping = 3, - .features[FEAT_1_EDX] = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | - CPUID_MMX | CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | -@@ -2684,6 +2690,7 @@ static PropValue kvm_default_props[] = { - { "acpi", "off" }, - { "monitor", "off" }, - { "svm", "off" }, -+ { "kvm-pv-unhalt", "on" }, - { NULL, NULL }, - }; - -diff --git a/target/i386/machine.c b/target/i386/machine.c -index 084c2c7..0c57c26 100644 ---- a/target/i386/machine.c -+++ b/target/i386/machine.c -@@ -955,6 +955,26 @@ static const VMStateDescription vmstate_svm_npt = { - } - }; - -+static bool vmstate_xsave_needed(void *opaque) -+{ -+ /* The xsave state is already on the main "cpu" section */ -+ return false; -+} -+ -+static const VMStateDescription vmstate_xsave ={ -+ .name = "cpu/xsave", -+ .version_id = 1, -+ .minimum_version_id = 1, -+ .minimum_version_id_old = 1, -+ .needed = vmstate_xsave_needed, -+ .fields = (VMStateField []) { -+ VMSTATE_UINT64_V(env.xcr0, X86CPU, 1), -+ VMSTATE_UINT64_V(env.xstate_bv, X86CPU, 1), -+ VMSTATE_YMMH_REGS_VARS(env.xmm_regs, X86CPU, CPU_NB_REGS, 1), -+ VMSTATE_END_OF_LIST() -+ } -+}; -+ - VMStateDescription vmstate_x86_cpu = { - .name = "cpu", - .version_id = 12, -@@ -1080,6 +1100,7 @@ VMStateDescription vmstate_x86_cpu = { - &vmstate_msr_intel_pt, - &vmstate_msr_virt_ssbd, - &vmstate_svm_npt, -+ &vmstate_xsave, - NULL - } - }; -diff --git a/target/ppc/compat.c b/target/ppc/compat.c -index 7de4bf3..3e2e353 100644 ---- a/target/ppc/compat.c -+++ b/target/ppc/compat.c -@@ -105,8 +105,19 @@ static const CompatInfo *compat_by_pvr(uint32_t pvr) - return NULL; - } - -+long ppc_compat_cmp(uint32_t pvr1, uint32_t pvr2) -+{ -+ const CompatInfo *compat1 = compat_by_pvr(pvr1); -+ const CompatInfo *compat2 = compat_by_pvr(pvr2); -+ -+ g_assert(compat1); -+ g_assert(compat2); -+ -+ return compat1 - compat2; -+} -+ - static bool pcc_compat(PowerPCCPUClass *pcc, uint32_t compat_pvr, -- uint32_t min_compat_pvr, uint32_t max_compat_pvr) -+ uint32_t min_compat_pvr, uint32_t max_compat_pvr) - { - const CompatInfo *compat = compat_by_pvr(compat_pvr); - const CompatInfo *min = compat_by_pvr(min_compat_pvr); -diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h -index 4edcf62..532f0d5 100644 ---- a/target/ppc/cpu.h -+++ b/target/ppc/cpu.h -@@ -1365,6 +1365,7 @@ static inline int cpu_mmu_index (CPUPPCState *env, bool ifetch) - - /* Compatibility modes */ - #if defined(TARGET_PPC64) -+long ppc_compat_cmp(uint32_t pvr1, uint32_t pvr2); - bool ppc_check_compat(PowerPCCPU *cpu, uint32_t compat_pvr, - uint32_t min_compat_pvr, uint32_t max_compat_pvr); - bool ppc_type_check_compat(const char *cputype, uint32_t compat_pvr, -diff --git a/tests/Makefile.include b/tests/Makefile.include -index a492827..6016df2 100644 ---- a/tests/Makefile.include -+++ b/tests/Makefile.include -@@ -184,8 +184,8 @@ gcov-files-generic-y = qdev-monitor.c qmp.c - check-qtest-generic-y += tests/cdrom-test$(EXESUF) - - gcov-files-ipack-y += hw/ipack/ipack.c --check-qtest-ipack-y += tests/ipoctal232-test$(EXESUF) --gcov-files-ipack-y += hw/char/ipoctal232.c -+#check-qtest-ipack-y += tests/ipoctal232-test$(EXESUF) -+#gcov-files-ipack-y += hw/char/ipoctal232.c - - check-qtest-virtioserial-y += tests/virtio-console-test$(EXESUF) - gcov-files-virtioserial-y += hw/char/virtio-console.c -@@ -217,23 +217,23 @@ check-qtest-pci-y += tests/e1000e-test$(EXESUF) - gcov-files-pci-y += hw/net/e1000e.c hw/net/e1000e_core.c - check-qtest-pci-y += tests/rtl8139-test$(EXESUF) - gcov-files-pci-y += hw/net/rtl8139.c --check-qtest-pci-y += tests/pcnet-test$(EXESUF) --gcov-files-pci-y += hw/net/pcnet.c --gcov-files-pci-y += hw/net/pcnet-pci.c --check-qtest-pci-y += tests/eepro100-test$(EXESUF) --gcov-files-pci-y += hw/net/eepro100.c --check-qtest-pci-y += tests/ne2000-test$(EXESUF) --gcov-files-pci-y += hw/net/ne2000.c --check-qtest-pci-y += tests/nvme-test$(EXESUF) --gcov-files-pci-y += hw/block/nvme.c -+#check-qtest-pci-y += tests/pcnet-test$(EXESUF) -+#gcov-files-pci-y += hw/net/pcnet.c -+#gcov-files-pci-y += hw/net/pcnet-pci.c -+#check-qtest-pci-y += tests/eepro100-test$(EXESUF) -+#gcov-files-pci-y += hw/net/eepro100.c -+#check-qtest-pci-y += tests/ne2000-test$(EXESUF) -+#gcov-files-pci-y += hw/net/ne2000.c -+#check-qtest-pci-y += tests/nvme-test$(EXESUF) -+#gcov-files-pci-y += hw/block/nvme.c - check-qtest-pci-y += tests/ac97-test$(EXESUF) - gcov-files-pci-y += hw/audio/ac97.c --check-qtest-pci-y += tests/es1370-test$(EXESUF) --gcov-files-pci-y += hw/audio/es1370.c -+#check-qtest-pci-y += tests/es1370-test$(EXESUF) -+#gcov-files-pci-y += hw/audio/es1370.c - check-qtest-pci-y += $(check-qtest-virtio-y) - gcov-files-pci-y += $(gcov-files-virtio-y) hw/virtio/virtio-pci.c --check-qtest-pci-y += tests/tpci200-test$(EXESUF) --gcov-files-pci-y += hw/ipack/tpci200.c -+#check-qtest-pci-y += tests/tpci200-test$(EXESUF) -+#gcov-files-pci-y += hw/ipack/tpci200.c - check-qtest-pci-y += $(check-qtest-ipack-y) - gcov-files-pci-y += $(gcov-files-ipack-y) - check-qtest-pci-y += tests/display-vga-test$(EXESUF) -@@ -245,25 +245,25 @@ gcov-files-pci-y += hw/display/virtio-gpu-pci.c - gcov-files-pci-$(CONFIG_VIRTIO_VGA) += hw/display/virtio-vga.c - check-qtest-pci-y += tests/intel-hda-test$(EXESUF) - gcov-files-pci-y += hw/audio/intel-hda.c hw/audio/hda-codec.c --check-qtest-pci-$(CONFIG_IVSHMEM) += tests/ivshmem-test$(EXESUF) --gcov-files-pci-y += hw/misc/ivshmem.c --check-qtest-pci-y += tests/megasas-test$(EXESUF) --gcov-files-pci-y += hw/scsi/megasas.c -+#check-qtest-pci-$(CONFIG_IVSHMEM) += tests/ivshmem-test$(EXESUF) -+#gcov-files-pci-y += hw/misc/ivshmem.c -+#check-qtest-pci-y += tests/megasas-test$(EXESUF) -+#gcov-files-pci-y += hw/scsi/megasas.c - - check-qtest-i386-y = tests/endianness-test$(EXESUF) --check-qtest-i386-y += tests/fdc-test$(EXESUF) --gcov-files-i386-y = hw/block/fdc.c -+#check-qtest-i386-y += tests/fdc-test$(EXESUF) -+#gcov-files-i386-y = hw/block/fdc.c - check-qtest-i386-y += tests/ide-test$(EXESUF) - check-qtest-i386-y += tests/ahci-test$(EXESUF) - check-qtest-i386-y += tests/hd-geo-test$(EXESUF) - gcov-files-i386-y += hw/block/hd-geometry.c - check-qtest-i386-y += tests/boot-order-test$(EXESUF) --check-qtest-i386-y += tests/bios-tables-test$(EXESUF) -+#check-qtest-i386-y += tests/bios-tables-test$(EXESUF) - check-qtest-i386-y += tests/boot-serial-test$(EXESUF) - check-qtest-i386-$(CONFIG_SLIRP) += tests/pxe-test$(EXESUF) - check-qtest-i386-y += tests/rtc-test$(EXESUF) --check-qtest-i386-y += tests/ipmi-kcs-test$(EXESUF) --check-qtest-i386-y += tests/ipmi-bt-test$(EXESUF) -+#check-qtest-i386-y += tests/ipmi-kcs-test$(EXESUF) -+#check-qtest-i386-y += tests/ipmi-bt-test$(EXESUF) - check-qtest-i386-y += tests/i440fx-test$(EXESUF) - check-qtest-i386-y += tests/fw_cfg-test$(EXESUF) - check-qtest-i386-y += tests/drive_del-test$(EXESUF) -@@ -272,8 +272,8 @@ check-qtest-i386-y += tests/tco-test$(EXESUF) - gcov-files-i386-y += hw/watchdog/watchdog.c hw/watchdog/wdt_ib700.c - check-qtest-i386-y += $(check-qtest-pci-y) - gcov-files-i386-y += $(gcov-files-pci-y) --check-qtest-i386-y += tests/vmxnet3-test$(EXESUF) --gcov-files-i386-y += hw/net/vmxnet3.c -+#check-qtest-i386-y += tests/vmxnet3-test$(EXESUF) -+#gcov-files-i386-y += hw/net/vmxnet3.c - gcov-files-i386-y += hw/net/net_rx_pkt.c - gcov-files-i386-y += hw/net/net_tx_pkt.c - check-qtest-i386-y += tests/pvpanic-test$(EXESUF) -@@ -282,8 +282,8 @@ check-qtest-i386-y += tests/i82801b11-test$(EXESUF) - gcov-files-i386-y += hw/pci-bridge/i82801b11.c - check-qtest-i386-y += tests/ioh3420-test$(EXESUF) - gcov-files-i386-y += hw/pci-bridge/ioh3420.c --check-qtest-i386-y += tests/usb-hcd-ohci-test$(EXESUF) --gcov-files-i386-y += hw/usb/hcd-ohci.c -+#check-qtest-i386-y += tests/usb-hcd-ohci-test$(EXESUF) -+#gcov-files-i386-y += hw/usb/hcd-ohci.c - check-qtest-i386-y += tests/usb-hcd-uhci-test$(EXESUF) - gcov-files-i386-y += hw/usb/hcd-uhci.c - check-qtest-i386-y += tests/usb-hcd-ehci-test$(EXESUF) -@@ -311,7 +311,7 @@ check-qtest-i386-y += tests/migration-test$(EXESUF) - check-qtest-i386-y += tests/test-x86-cpuid-compat$(EXESUF) - check-qtest-i386-y += tests/numa-test$(EXESUF) - check-qtest-x86_64-y += $(check-qtest-i386-y) --check-qtest-x86_64-y += tests/sdhci-test$(EXESUF) -+#check-qtest-x86_64-y += tests/sdhci-test$(EXESUF) - gcov-files-i386-y += i386-softmmu/hw/timer/mc146818rtc.c - gcov-files-x86_64-y = $(subst i386-softmmu/,x86_64-softmmu/,$(gcov-files-i386-y)) - -@@ -332,34 +332,34 @@ check-qtest-mips64el-y = tests/endianness-test$(EXESUF) - check-qtest-moxie-y = tests/boot-serial-test$(EXESUF) - - check-qtest-ppc-y = tests/endianness-test$(EXESUF) --check-qtest-ppc-y += tests/boot-order-test$(EXESUF) -+#check-qtest-ppc-y += tests/boot-order-test$(EXESUF) - check-qtest-ppc-y += tests/prom-env-test$(EXESUF) - check-qtest-ppc-y += tests/drive_del-test$(EXESUF) - check-qtest-ppc-y += tests/boot-serial-test$(EXESUF) --check-qtest-ppc-y += tests/m48t59-test$(EXESUF) --gcov-files-ppc-y += hw/timer/m48t59.c -+#check-qtest-ppc-y += tests/m48t59-test$(EXESUF) -+#gcov-files-ppc-y += hw/timer/m48t59.c - - check-qtest-ppc64-y = $(check-qtest-ppc-y) - gcov-files-ppc64-y = $(subst ppc-softmmu/,ppc64-softmmu/,$(gcov-files-ppc-y)) - check-qtest-ppc64-y += tests/spapr-phb-test$(EXESUF) - gcov-files-ppc64-y += ppc64-softmmu/hw/ppc/spapr_pci.c --check-qtest-ppc64-y += tests/pnv-xscom-test$(EXESUF) -+#check-qtest-ppc64-y += tests/pnv-xscom-test$(EXESUF) - check-qtest-ppc64-y += tests/migration-test$(EXESUF) - check-qtest-ppc64-y += tests/rtas-test$(EXESUF) - check-qtest-ppc64-$(CONFIG_SLIRP) += tests/pxe-test$(EXESUF) --check-qtest-ppc64-y += tests/usb-hcd-ohci-test$(EXESUF) --gcov-files-ppc64-y += hw/usb/hcd-ohci.c --check-qtest-ppc64-y += tests/usb-hcd-uhci-test$(EXESUF) --gcov-files-ppc64-y += hw/usb/hcd-uhci.c -+#check-qtest-ppc64-y += tests/usb-hcd-ohci-test$(EXESUF) -+#gcov-files-ppc64-y += hw/usb/hcd-ohci.c -+#check-qtest-ppc64-y += tests/usb-hcd-uhci-test$(EXESUF) -+#gcov-files-ppc64-y += hw/usb/hcd-uhci.c - check-qtest-ppc64-y += tests/usb-hcd-xhci-test$(EXESUF) - gcov-files-ppc64-y += hw/usb/hcd-xhci.c - check-qtest-ppc64-y += $(check-qtest-virtio-y) --check-qtest-ppc64-$(CONFIG_SLIRP) += tests/test-netfilter$(EXESUF) --check-qtest-ppc64-$(CONFIG_POSIX) += tests/test-filter-mirror$(EXESUF) --check-qtest-ppc64-$(CONFIG_POSIX) += tests/test-filter-redirector$(EXESUF) -+#check-qtest-ppc64-$(CONFIG_SLIRP) += tests/test-netfilter$(EXESUF) -+#check-qtest-ppc64-$(CONFIG_POSIX) += tests/test-filter-mirror$(EXESUF) -+#check-qtest-ppc64-$(CONFIG_POSIX) += tests/test-filter-redirector$(EXESUF) - check-qtest-ppc64-y += tests/display-vga-test$(EXESUF) - check-qtest-ppc64-y += tests/numa-test$(EXESUF) --check-qtest-ppc64-$(CONFIG_IVSHMEM) += tests/ivshmem-test$(EXESUF) -+#check-qtest-ppc64-$(CONFIG_IVSHMEM) += tests/ivshmem-test$(EXESUF) - check-qtest-ppc64-y += tests/cpu-plug-test$(EXESUF) - - check-qtest-sh4-y = tests/endianness-test$(EXESUF) -@@ -388,7 +388,7 @@ check-qtest-arm-y += tests/boot-serial-test$(EXESUF) - check-qtest-arm-y += tests/sdhci-test$(EXESUF) - - check-qtest-aarch64-y = tests/numa-test$(EXESUF) --check-qtest-aarch64-y += tests/sdhci-test$(EXESUF) -+#check-qtest-aarch64-y += tests/sdhci-test$(EXESUF) - check-qtest-aarch64-y += tests/boot-serial-test$(EXESUF) - - check-qtest-microblazeel-y = $(check-qtest-microblaze-y) -@@ -777,15 +777,15 @@ tests/endianness-test$(EXESUF): tests/endianness-test.o - tests/spapr-phb-test$(EXESUF): tests/spapr-phb-test.o $(libqos-obj-y) - tests/prom-env-test$(EXESUF): tests/prom-env-test.o $(libqos-obj-y) - tests/rtas-test$(EXESUF): tests/rtas-test.o $(libqos-spapr-obj-y) --tests/fdc-test$(EXESUF): tests/fdc-test.o -+#tests/fdc-test$(EXESUF): tests/fdc-test.o - tests/ide-test$(EXESUF): tests/ide-test.o $(libqos-pc-obj-y) - tests/ahci-test$(EXESUF): tests/ahci-test.o $(libqos-pc-obj-y) --tests/ipmi-kcs-test$(EXESUF): tests/ipmi-kcs-test.o --tests/ipmi-bt-test$(EXESUF): tests/ipmi-bt-test.o -+#tests/ipmi-kcs-test$(EXESUF): tests/ipmi-kcs-test.o -+#tests/ipmi-bt-test$(EXESUF): tests/ipmi-bt-test.o - tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o - tests/boot-order-test$(EXESUF): tests/boot-order-test.o $(libqos-obj-y) - tests/boot-serial-test$(EXESUF): tests/boot-serial-test.o $(libqos-obj-y) --tests/bios-tables-test$(EXESUF): tests/bios-tables-test.o \ -+#tests/bios-tables-test$(EXESUF): tests/bios-tables-test.o \ - tests/boot-sector.o tests/acpi-utils.o $(libqos-obj-y) - tests/pxe-test$(EXESUF): tests/pxe-test.o tests/boot-sector.o $(libqos-obj-y) - tests/tmp105-test$(EXESUF): tests/tmp105-test.o $(libqos-omap-obj-y) -@@ -798,11 +798,11 @@ tests/fw_cfg-test$(EXESUF): tests/fw_cfg-test.o $(libqos-pc-obj-y) - tests/e1000-test$(EXESUF): tests/e1000-test.o - tests/e1000e-test$(EXESUF): tests/e1000e-test.o $(libqos-pc-obj-y) - tests/rtl8139-test$(EXESUF): tests/rtl8139-test.o $(libqos-pc-obj-y) --tests/pcnet-test$(EXESUF): tests/pcnet-test.o --tests/pnv-xscom-test$(EXESUF): tests/pnv-xscom-test.o --tests/eepro100-test$(EXESUF): tests/eepro100-test.o --tests/vmxnet3-test$(EXESUF): tests/vmxnet3-test.o --tests/ne2000-test$(EXESUF): tests/ne2000-test.o -+#tests/pcnet-test$(EXESUF): tests/pcnet-test.o -+#tests/pnv-xscom-test$(EXESUF): tests/pnv-xscom-test.o -+#tests/eepro100-test$(EXESUF): tests/eepro100-test.o -+#tests/vmxnet3-test$(EXESUF): tests/vmxnet3-test.o -+#tests/ne2000-test$(EXESUF): tests/ne2000-test.o - tests/wdt_ib700-test$(EXESUF): tests/wdt_ib700-test.o - tests/tco-test$(EXESUF): tests/tco-test.o $(libqos-pc-obj-y) - tests/virtio-balloon-test$(EXESUF): tests/virtio-balloon-test.o $(libqos-virtio-obj-y) -@@ -813,22 +813,22 @@ tests/virtio-scsi-test$(EXESUF): tests/virtio-scsi-test.o $(libqos-virtio-obj-y) - tests/virtio-9p-test$(EXESUF): tests/virtio-9p-test.o $(libqos-virtio-obj-y) - tests/virtio-serial-test$(EXESUF): tests/virtio-serial-test.o $(libqos-virtio-obj-y) - tests/virtio-console-test$(EXESUF): tests/virtio-console-test.o $(libqos-virtio-obj-y) --tests/tpci200-test$(EXESUF): tests/tpci200-test.o -+#tests/tpci200-test$(EXESUF): tests/tpci200-test.o - tests/display-vga-test$(EXESUF): tests/display-vga-test.o --tests/ipoctal232-test$(EXESUF): tests/ipoctal232-test.o -+#tests/ipoctal232-test$(EXESUF): tests/ipoctal232-test.o - tests/qom-test$(EXESUF): tests/qom-test.o - tests/test-hmp$(EXESUF): tests/test-hmp.o - tests/machine-none-test$(EXESUF): tests/machine-none-test.o - tests/drive_del-test$(EXESUF): tests/drive_del-test.o $(libqos-virtio-obj-y) - tests/qdev-monitor-test$(EXESUF): tests/qdev-monitor-test.o $(libqos-pc-obj-y) --tests/nvme-test$(EXESUF): tests/nvme-test.o -+#tests/nvme-test$(EXESUF): tests/nvme-test.o - tests/pvpanic-test$(EXESUF): tests/pvpanic-test.o - tests/i82801b11-test$(EXESUF): tests/i82801b11-test.o - tests/ac97-test$(EXESUF): tests/ac97-test.o --tests/es1370-test$(EXESUF): tests/es1370-test.o -+#tests/es1370-test$(EXESUF): tests/es1370-test.o - tests/intel-hda-test$(EXESUF): tests/intel-hda-test.o - tests/ioh3420-test$(EXESUF): tests/ioh3420-test.o --tests/usb-hcd-ohci-test$(EXESUF): tests/usb-hcd-ohci-test.o $(libqos-usb-obj-y) -+#tests/usb-hcd-ohci-test$(EXESUF): tests/usb-hcd-ohci-test.o $(libqos-usb-obj-y) - tests/usb-hcd-uhci-test$(EXESUF): tests/usb-hcd-uhci-test.o $(libqos-usb-obj-y) - tests/usb-hcd-ehci-test$(EXESUF): tests/usb-hcd-ehci-test.o $(libqos-usb-obj-y) - tests/usb-hcd-xhci-test$(EXESUF): tests/usb-hcd-xhci-test.o $(libqos-usb-obj-y) -@@ -841,19 +841,19 @@ tests/qemu-iotests/socket_scm_helper$(EXESUF): tests/qemu-iotests/socket_scm_hel - tests/test-qemu-opts$(EXESUF): tests/test-qemu-opts.o $(test-util-obj-y) - tests/test-keyval$(EXESUF): tests/test-keyval.o $(test-util-obj-y) $(test-qapi-obj-y) - tests/test-write-threshold$(EXESUF): tests/test-write-threshold.o $(test-block-obj-y) --tests/test-netfilter$(EXESUF): tests/test-netfilter.o $(qtest-obj-y) --tests/test-filter-mirror$(EXESUF): tests/test-filter-mirror.o $(qtest-obj-y) --tests/test-filter-redirector$(EXESUF): tests/test-filter-redirector.o $(qtest-obj-y) -+#tests/test-netfilter$(EXESUF): tests/test-netfilter.o $(qtest-obj-y) -+#tests/test-filter-mirror$(EXESUF): tests/test-filter-mirror.o $(qtest-obj-y) -+#tests/test-filter-redirector$(EXESUF): tests/test-filter-redirector.o $(qtest-obj-y) - tests/test-x86-cpuid-compat$(EXESUF): tests/test-x86-cpuid-compat.o $(qtest-obj-y) --tests/ivshmem-test$(EXESUF): tests/ivshmem-test.o contrib/ivshmem-server/ivshmem-server.o $(libqos-pc-obj-y) $(libqos-spapr-obj-y) --tests/megasas-test$(EXESUF): tests/megasas-test.o $(libqos-spapr-obj-y) $(libqos-pc-obj-y) -+#tests/ivshmem-test$(EXESUF): tests/ivshmem-test.o contrib/ivshmem-server/ivshmem-server.o $(libqos-pc-obj-y) $(libqos-spapr-obj-y) -+#tests/megasas-test$(EXESUF): tests/megasas-test.o $(libqos-spapr-obj-y) $(libqos-pc-obj-y) - tests/vhost-user-bridge$(EXESUF): tests/vhost-user-bridge.o $(test-util-obj-y) libvhost-user.a - tests/test-uuid$(EXESUF): tests/test-uuid.o $(test-util-obj-y) - tests/test-arm-mptimer$(EXESUF): tests/test-arm-mptimer.o - tests/test-qapi-util$(EXESUF): tests/test-qapi-util.o $(test-util-obj-y) - tests/numa-test$(EXESUF): tests/numa-test.o - tests/vmgenid-test$(EXESUF): tests/vmgenid-test.o tests/boot-sector.o tests/acpi-utils.o --tests/sdhci-test$(EXESUF): tests/sdhci-test.o $(libqos-pc-obj-y) -+#tests/sdhci-test$(EXESUF): tests/sdhci-test.o $(libqos-pc-obj-y) - tests/cdrom-test$(EXESUF): tests/cdrom-test.o tests/boot-sector.o $(libqos-obj-y) - - tests/migration/stress$(EXESUF): tests/migration/stress.o -diff --git a/tests/boot-serial-test.c b/tests/boot-serial-test.c -index 952a2e7..5217a39 100644 ---- a/tests/boot-serial-test.c -+++ b/tests/boot-serial-test.c -@@ -80,17 +80,21 @@ static testdef_t tests[] = { - { "ppc", "g3beige", "", "PowerPC,750" }, - { "ppc", "mac99", "", "PowerPC,G4" }, - { "ppc", "sam460ex", "-m 256", "DRAM: 256 MiB" }, -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - { "ppc64", "ppce500", "", "U-Boot" }, - { "ppc64", "prep", "-boot e", "Booting from device e" }, - { "ppc64", "40p", "-m 192", "Memory size: 192 MB" }, - { "ppc64", "mac99", "", "PowerPC,970FX" }, -+#endif - { "ppc64", "pseries", "", "Open Firmware" }, -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - { "ppc64", "powernv", "-cpu POWER8", "OPAL" }, - { "ppc64", "sam460ex", "-device e1000", "8086 100e" }, -+#endif - { "i386", "isapc", "-cpu qemu32 -device sga", "SGABIOS" }, - { "i386", "pc", "-device sga", "SGABIOS" }, - { "i386", "q35", "-device sga", "SGABIOS" }, -- { "x86_64", "isapc", "-cpu qemu32 -device sga", "SGABIOS" }, -+ { "x86_64", "pc", "-cpu qemu32 -device sga", "SGABIOS" }, - { "x86_64", "q35", "-device sga", "SGABIOS" }, - { "sparc", "LX", "", "TMS390S10" }, - { "sparc", "SS-4", "", "MB86904" }, -diff --git a/tests/cpu-plug-test.c b/tests/cpu-plug-test.c -index 5f39ba0..48b8d09 100644 ---- a/tests/cpu-plug-test.c -+++ b/tests/cpu-plug-test.c -@@ -192,7 +192,8 @@ static void add_pseries_test_case(const char *mname) - PlugTestData *data; - - if (!g_str_has_prefix(mname, "pseries-") || -- (g_str_has_prefix(mname, "pseries-2.") && atoi(&mname[10]) < 7)) { -+ (g_str_has_prefix(mname, "pseries-2.") && atoi(&mname[10]) < 7) || -+ strcmp(mname,"pseries-rhel7.2.0") == 0) { - return; - } - data = g_new(PlugTestData, 1); -diff --git a/tests/e1000-test.c b/tests/e1000-test.c -index 0c5fcdc..b830432 100644 ---- a/tests/e1000-test.c -+++ b/tests/e1000-test.c -@@ -29,8 +29,10 @@ static void test_device(gconstpointer data) - static const char *models[] = { - "e1000", - "e1000-82540em", -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - "e1000-82544gc", - "e1000-82545em", -+#endif - }; - - int main(int argc, char **argv) -diff --git a/tests/endianness-test.c b/tests/endianness-test.c -index 546e096..440353d 100644 ---- a/tests/endianness-test.c -+++ b/tests/endianness-test.c -@@ -37,10 +37,12 @@ static const TestCase test_cases[] = { - { "ppc", "g3beige", 0xfe000000, .bswap = true, .superio = "i82378" }, - { "ppc", "prep", 0x80000000, .bswap = true }, - { "ppc", "bamboo", 0xe8000000, .bswap = true, .superio = "i82378" }, -+#if 0 /* Disabled for RHEL, since ISA is not enabled */ - { "ppc64", "mac99", 0xf2000000, .bswap = true, .superio = "i82378" }, - { "ppc64", "pseries", (1ULL << 45), .bswap = true, .superio = "i82378" }, - { "ppc64", "pseries-2.7", 0x10080000000ULL, - .bswap = true, .superio = "i82378" }, -+#endif /* Disabled for RHEL, since ISA is not enabled */ - { "sh4", "r2d", 0xfe240000, .superio = "i82378" }, - { "sh4eb", "r2d", 0xfe240000, .bswap = true, .superio = "i82378" }, - { "sparc64", "sun4u", 0x1fe02000000LL, .bswap = true }, -diff --git a/tests/prom-env-test.c b/tests/prom-env-test.c -index 8c867e6..cc9b6ec 100644 ---- a/tests/prom-env-test.c -+++ b/tests/prom-env-test.c -@@ -82,7 +82,9 @@ int main(int argc, char *argv[]) - if (!strcmp(arch, "ppc")) { - add_tests(ppc_machines); - } else if (!strcmp(arch, "ppc64")) { -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - add_tests(ppc_machines); -+#endif - if (g_test_slow()) { - qtest_add_data_func("prom-env/pseries", "pseries", test_machine); - } -diff --git a/tests/qemu-iotests/051 b/tests/qemu-iotests/051 -index ee9c820..c5cc0ee 100755 ---- a/tests/qemu-iotests/051 -+++ b/tests/qemu-iotests/051 -@@ -183,11 +183,11 @@ run_qemu -drive if=virtio - case "$QEMU_DEFAULT_MACHINE" in - pc) - run_qemu -drive if=none,id=disk -device ide-cd,drive=disk -- run_qemu -drive if=none,id=disk -device lsi53c895a -device scsi-cd,drive=disk -+# run_qemu -drive if=none,id=disk -device lsi53c895a -device scsi-cd,drive=disk - run_qemu -drive if=none,id=disk -device ide-drive,drive=disk - run_qemu -drive if=none,id=disk -device ide-hd,drive=disk -- run_qemu -drive if=none,id=disk -device lsi53c895a -device scsi-disk,drive=disk -- run_qemu -drive if=none,id=disk -device lsi53c895a -device scsi-hd,drive=disk -+# run_qemu -drive if=none,id=disk -device lsi53c895a -device scsi-disk,drive=disk -+# run_qemu -drive if=none,id=disk -device lsi53c895a -device scsi-hd,drive=disk - ;; - *) - ;; -@@ -212,11 +212,11 @@ run_qemu -drive file="$TEST_IMG",if=virtio,readonly=on - case "$QEMU_DEFAULT_MACHINE" in - pc) - run_qemu -drive file="$TEST_IMG",if=none,id=disk,readonly=on -device ide-cd,drive=disk -- run_qemu -drive file="$TEST_IMG",if=none,id=disk,readonly=on -device lsi53c895a -device scsi-cd,drive=disk -+# run_qemu -drive file="$TEST_IMG",if=none,id=disk,readonly=on -device lsi53c895a -device scsi-cd,drive=disk - run_qemu -drive file="$TEST_IMG",if=none,id=disk,readonly=on -device ide-drive,drive=disk - run_qemu -drive file="$TEST_IMG",if=none,id=disk,readonly=on -device ide-hd,drive=disk -- run_qemu -drive file="$TEST_IMG",if=none,id=disk,readonly=on -device lsi53c895a -device scsi-disk,drive=disk -- run_qemu -drive file="$TEST_IMG",if=none,id=disk,readonly=on -device lsi53c895a -device scsi-hd,drive=disk -+# run_qemu -drive file="$TEST_IMG",if=none,id=disk,readonly=on -device lsi53c895a -device scsi-disk,drive=disk -+# run_qemu -drive file="$TEST_IMG",if=none,id=disk,readonly=on -device lsi53c895a -device scsi-hd,drive=disk - ;; - *) - ;; -diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group -index b973dc8..f1059f6 100644 ---- a/tests/qemu-iotests/group -+++ b/tests/qemu-iotests/group -@@ -77,7 +77,7 @@ - 068 rw auto quick - 069 rw auto quick - 070 rw auto quick --071 rw auto quick -+# 071 rw auto quick -- requires whitelisted blkverify - 072 rw auto quick - 073 rw auto quick - 074 rw auto quick -@@ -105,7 +105,7 @@ - 096 rw auto quick - 097 rw auto backing - 098 rw auto backing quick --099 rw auto quick -+# 099 rw auto quick -- requires whitelisted blkverify - # 100 was removed, do not reuse - 101 rw auto quick - 102 rw auto quick -diff --git a/tests/qom-test.c b/tests/qom-test.c -index e6f712c..ebd15fd 100644 ---- a/tests/qom-test.c -+++ b/tests/qom-test.c -@@ -16,7 +16,7 @@ - #include "libqtest.h" - - static const char *blacklist_x86[] = { -- "xenfv", "xenpv", NULL -+ "xenfv", "xenpv", "isapc", NULL - }; - - static const struct { -diff --git a/tests/test-x86-cpuid-compat.c b/tests/test-x86-cpuid-compat.c -index 84ce9c7..c1ee197 100644 ---- a/tests/test-x86-cpuid-compat.c -+++ b/tests/test-x86-cpuid-compat.c -@@ -306,6 +306,7 @@ int main(int argc, char **argv) - "-cpu 486,xlevel2=0xC0000002,+xstore", - "xlevel2", 0xC0000002); - -+#if 0 /* Disabled in Red Hat Enterprise Linux */ - /* Check compatibility of old machine-types that didn't - * auto-increase level/xlevel/xlevel2: */ - -@@ -356,6 +357,7 @@ int main(int argc, char **argv) - add_cpuid_test("x86/cpuid/xlevel-compat/pc-i440fx-2.4/npt-on", - "-machine pc-i440fx-2.4 -cpu SandyBridge,+npt", - "xlevel", 0x80000008); -+#endif - - /* Test feature parsing */ - add_feature_test("x86/cpuid/features/plus", -diff --git a/tests/usb-hcd-xhci-test.c b/tests/usb-hcd-xhci-test.c -index 5b1b681..85fa150 100644 ---- a/tests/usb-hcd-xhci-test.c -+++ b/tests/usb-hcd-xhci-test.c -@@ -21,6 +21,7 @@ static void test_xhci_hotplug(void) - usb_test_hotplug("xhci", 1, NULL); - } - -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - static void test_usb_uas_hotplug(void) - { - qtest_qmp_device_add("usb-uas", "uas", NULL); -@@ -34,6 +35,7 @@ static void test_usb_uas_hotplug(void) - qtest_qmp_device_del("scsihd"); - qtest_qmp_device_del("uas"); - } -+#endif - - static void test_usb_ccid_hotplug(void) - { -@@ -52,7 +54,9 @@ int main(int argc, char **argv) - - qtest_add_func("/xhci/pci/init", test_xhci_init); - qtest_add_func("/xhci/pci/hotplug", test_xhci_hotplug); -+#if 0 /* Disabled for Red Hat Enterprise Linux */ - qtest_add_func("/xhci/pci/hotplug/usb-uas", test_usb_uas_hotplug); -+#endif - qtest_add_func("/xhci/pci/hotplug/usb-ccid", test_usb_ccid_hotplug); - - qtest_start("-device nec-usb-xhci,id=xhci" --- -1.8.3.1 - diff --git a/0001-Initial-redhat-build.patch b/0004-Initial-redhat-build.patch similarity index 62% rename from 0001-Initial-redhat-build.patch rename to 0004-Initial-redhat-build.patch index a901328..06670c5 100644 --- a/0001-Initial-redhat-build.patch +++ b/0004-Initial-redhat-build.patch @@ -1,10 +1,10 @@ -From f03d3b79bc1908b0b6e257ee7aaa6567ecb91e38 Mon Sep 17 00:00:00 2001 +From a1f1313c0c96b2a159647aabc6a4b0f3a3f4424a Mon Sep 17 00:00:00 2001 From: Miroslav Rezanina -Date: Mon, 11 Sep 2017 07:11:00 +0200 +Date: Thu, 8 Nov 2018 11:17:08 +0100 Subject: Initial redhat build -This patch introduces redhat build structure in redhat subdirectory. -In addition, several issues are fixed in QEMU tree: +This patch introduces redhat build structure in redhat subdirectory. In addition, +several issues are fixed in QEMU tree: - Change of app name for sasl_server_init in VNC code from qemu to qemu-kvm - As we use qemu-kvm as name in all places, this is updated to be consistent @@ -12,134 +12,24 @@ In addition, several issues are fixed in QEMU tree: - man page is installed using make install so we have to fix it in qemu tree - Use "/share/qemu-kvm" as SHARE_SUFFIX - We reconfigured our share to qemu-kvm to be consistent with used name -- Added .gitpublish configuration file - - Support for git publish has to be stored in repository root -Rebase changes (3.0.0): -- python detection changed -- added --disable-debug-mutex +This commit is synchronized with qemu-kvm-2.12.0-42.el8 build. -Merged patches (3.0.0): -- 9997a46 Fix annocheck issues -- 35230f9 redhat: remove extra % in rhel_rhev_conflicts macro( -- c747d3f redhat: syncronizing specfile -- e6abfc4 rpm: Add nvme VFIO driver to rw whitelist -- 7043465 rpm: Whitelist copy-on-read block driver -- f9a897c rpm: add throttle driver to rw whitelist -- b9ea80f redhat: replacing %pkname by %name -- eeeea85 redhat: Remove unused ApplyPatch macro -- b42c578 redhat:removing disable code for libcacard -- cee6bd5 redhat: improve packaging layout with modularization of the block layer -- 0cb4c60 redhat: Introducing qemu-kvm-core package -- 1ff4106 Add qemu-keymap to qemu-kvm-common -- 47838a5 redhat: Make gitpublish profile the default one -- a82f87b redhat: s390x: add hpage=1 to kvm.conf -- 3d52169 Enabling vhost_user -- 57aa228 spec: Enable Native Ceph support on all architectures -- 5f9ea03 Thu Jun 21 2018 Danilo C. L. de Paula - 2.12.0-13.el8 -- ed4d62a spec: Fix ambiguous 'python' interpreter name -- 74b3e6c qemu-ga: blacklisting guest-exec and guest-exec-status RPCs -- 2fd2cf7 redhat: rewrap "build_configure.sh" cmdline for the "rh-env-prep" target -- f48dc7f redhat: remove the VTD, LIVE_BLOCK_OPS, and RHV options in local builds too -- ccdf46b redhat: fix the "rh-env-prep" target's dependency on the SRPM_NAME macro -- f258fbf redhat: remove dead code related to s390 (not s390x) -- d186100 redhat: sync compiler flags from the spec file to "rh-env-prep" -- 727aa86 redhat: sync guest agent enablement and tcmalloc usage from spec to local -- b5d47e2 redhat: fix up Python 3 dependency for building QEMU -- 70c64dd redhat: fix up Python dependency for SRPM generation -- 96aca9f redhat: disable glusterfs dependency/support temporarily -- e9aff9d block/vxhs: modularize VXHS via g_module -- ecf40bf Defining a shebang for python scripts -- 55e3177 redhat: changing the prefix and blurb scheme to support rhel8-like handling -- 571e4ac Removing "rh-srpm-rhel" make target -- 9db09ef redhat: enforce python3 usage -- 56cda0b spec: Re-add dependency to seavgabios and ipxe for ppc64 architectures -- c780848 Drop build_configure.sh and Makefile.local files -- cca9118 Fix subject line in .gitpublish -- 9745e27 redhat: Update build configuration -- 193830c redhat: Disable vhost crypto -- 9dc30cb redhat: Make rh-local actually work in a RHEL-8 environment -- 99011c9 redhat: enable opengl, add build and runtime deps -- 7290e3f redhat: Improve python check +Signed-off-by: Miroslav Rezanina --- - .gitpublish | 61 +- - Makefile | 3 +- - block/Makefile.objs | 2 +- - block/vxhs.c | 119 ++- - configure | 33 +- - os-posix.c | 2 +- - redhat/.gitignore | 5 + - redhat/85-kvm.preset | 5 + - redhat/95-kvm-memlock.conf | 10 + - redhat/99-qemu-guest-agent.rules | 2 + - redhat/Makefile | 82 ++ - redhat/Makefile.common | 47 ++ - redhat/bridge.conf | 1 + - redhat/ksm.service | 13 + - redhat/ksm.sysconfig | 4 + - redhat/ksmctl.c | 77 ++ - redhat/ksmtuned | 139 ++++ - redhat/ksmtuned.conf | 21 + - redhat/ksmtuned.service | 12 + - redhat/kvm-s390x.conf | 19 + - redhat/kvm-setup | 40 + - redhat/kvm-setup.service | 14 + - redhat/kvm-x86.conf | 12 + - redhat/kvm.conf | 3 + - redhat/kvm.modules | 18 + - redhat/qemu-ga.sysconfig | 19 + - redhat/qemu-guest-agent.service | 20 + - redhat/qemu-kvm.spec.template | 1531 ++++++++++++++++++++++++++++++++++++ - redhat/qemu-pr-helper.service | 15 + - redhat/qemu-pr-helper.socket | 9 + - redhat/rpmbuild/BUILD/.gitignore | 2 + - redhat/rpmbuild/RPMS/.gitignore | 2 + - redhat/rpmbuild/SOURCES/.gitignore | 2 + - redhat/rpmbuild/SPECS/.gitignore | 2 + - redhat/rpmbuild/SRPMS/.gitignore | 2 + - redhat/scripts/frh.py | 24 + - redhat/scripts/git-backport-diff | 327 ++++++++ - redhat/scripts/git-compile-check | 215 +++++ - redhat/scripts/process-patches.sh | 92 +++ - redhat/scripts/tarball_checksum.sh | 3 + - redhat/vhost.conf | 3 + - ui/vnc.c | 2 +- - 42 files changed, 2921 insertions(+), 93 deletions(-) - create mode 100644 redhat/.gitignore - create mode 100644 redhat/85-kvm.preset - create mode 100644 redhat/95-kvm-memlock.conf - create mode 100644 redhat/99-qemu-guest-agent.rules + Makefile | 3 +- + block/Makefile.objs | 2 +- + block/vxhs.c | 119 ++- + configure | 40 +- + os-posix.c | 2 +- + redhat/Makefile | 82 ++ + redhat/Makefile.common | 49 ++ + redhat/qemu-kvm.spec.template | 1721 +++++++++++++++++++++++++++++++++++++++++ + ui/vnc.c | 2 +- + 9 files changed, 1972 insertions(+), 48 deletions(-) create mode 100644 redhat/Makefile create mode 100644 redhat/Makefile.common - create mode 100644 redhat/bridge.conf - create mode 100644 redhat/ksm.service - create mode 100644 redhat/ksm.sysconfig - create mode 100644 redhat/ksmctl.c - create mode 100644 redhat/ksmtuned - create mode 100644 redhat/ksmtuned.conf - create mode 100644 redhat/ksmtuned.service - create mode 100644 redhat/kvm-s390x.conf - create mode 100644 redhat/kvm-setup - create mode 100644 redhat/kvm-setup.service - create mode 100644 redhat/kvm-x86.conf - create mode 100644 redhat/kvm.conf - create mode 100644 redhat/kvm.modules - create mode 100644 redhat/qemu-ga.sysconfig - create mode 100644 redhat/qemu-guest-agent.service create mode 100644 redhat/qemu-kvm.spec.template - create mode 100644 redhat/qemu-pr-helper.service - create mode 100644 redhat/qemu-pr-helper.socket - create mode 100644 redhat/rpmbuild/BUILD/.gitignore - create mode 100644 redhat/rpmbuild/RPMS/.gitignore - create mode 100644 redhat/rpmbuild/SOURCES/.gitignore - create mode 100644 redhat/rpmbuild/SPECS/.gitignore - create mode 100644 redhat/rpmbuild/SRPMS/.gitignore - create mode 100755 redhat/scripts/frh.py - create mode 100755 redhat/scripts/git-backport-diff - create mode 100755 redhat/scripts/git-compile-check - create mode 100755 redhat/scripts/process-patches.sh - create mode 100755 redhat/scripts/tarball_checksum.sh - create mode 100644 redhat/vhost.conf diff --git a/Makefile b/Makefile index 2da686b..eb4c57a 100644 @@ -367,10 +257,26 @@ index 0cb0a00..9164b3e 100644 trace_vxhs_get_vdisk_stat_err(s->vdisk_guid, ret, errno); return -EIO; diff --git a/configure b/configure -index 2a7796e..0314d53 100755 +index 2a7796e..0a27137 100755 --- a/configure +++ b/configure -@@ -3460,7 +3460,7 @@ fi +@@ -2216,13 +2216,10 @@ fi + ########################################## + # libseccomp check + ++libseccomp_minver="2.2.0" + if test "$seccomp" != "no" ; then + case "$cpu" in +- i386|x86_64) +- libseccomp_minver="2.1.0" +- ;; +- mips) +- libseccomp_minver="2.2.0" ++ i386|x86_64|mips) + ;; + arm|aarch64) + libseccomp_minver="2.2.3" +@@ -3460,7 +3457,7 @@ fi glib_req_ver=2.40 glib_modules=gthread-2.0 @@ -379,7 +285,7 @@ index 2a7796e..0314d53 100755 glib_modules="$glib_modules gmodule-export-2.0" fi -@@ -5435,33 +5435,6 @@ if compile_prog "" "" ; then +@@ -5435,33 +5432,6 @@ if compile_prog "" "" ; then fi ########################################## @@ -413,7 +319,7 @@ index 2a7796e..0314d53 100755 # check for _Static_assert() have_static_assert=no -@@ -6759,8 +6732,8 @@ if test "$pthread_setname_np" = "yes" ; then +@@ -6759,8 +6729,8 @@ if test "$pthread_setname_np" = "yes" ; then fi if test "$vxhs" = "yes" ; then diff --git a/0002-Enable-disable-devices-for-RHEL-7.patch b/0005-Enable-disable-devices-for-RHEL-7.patch similarity index 98% rename from 0002-Enable-disable-devices-for-RHEL-7.patch rename to 0005-Enable-disable-devices-for-RHEL-7.patch index de0276f..ec26beb 100644 --- a/0002-Enable-disable-devices-for-RHEL-7.patch +++ b/0005-Enable-disable-devices-for-RHEL-7.patch @@ -1,10 +1,10 @@ -From 7472ed73f89c81f1ca4c86129eed0f5874d82c41 Mon Sep 17 00:00:00 2001 +From b4a5b95153ca86eba72ff4a368a24ac31b77bbe5 Mon Sep 17 00:00:00 2001 From: Miroslav Rezanina Date: Mon, 11 Jan 2016 11:53:33 +0100 Subject: Enable/disable devices for RHEL 7 This commit adds all changes related to changes in supported devices -up to qemu-kvm-2.12.0-32.el8. +up to qemu-kvm-2.12.0-42.el8. Signed-off-by: Miroslav Rezanina @@ -28,15 +28,16 @@ Merged patches (3.0.0): - 747643c Disable new pvrdma device - 0d4f38c s390x: Re-enable CONFIG_TERMINAL3270 - 0f725e9 AArch64: Enable CONFIG_FW_CFG_DMA for aarch64 +- 67c5a8c Disable ivshmem --- - default-configs/aarch64-softmmu.mak | 37 +++++++++++++++++++++++++++++-------- - default-configs/pci.mak | 36 ++++++++++++++++++------------------ - default-configs/ppc64-softmmu.mak | 25 +++++++++++++++++++------ + default-configs/aarch64-softmmu.mak | 37 ++++++++++++++++++++++++++++-------- + default-configs/pci.mak | 38 ++++++++++++++++++------------------- + default-configs/ppc64-softmmu.mak | 25 ++++++++++++++++++------ default-configs/s390x-softmmu.mak | 5 +++-- default-configs/sound.mak | 8 ++++---- default-configs/usb.mak | 14 +++++++------- default-configs/virtio.mak | 5 ++--- - default-configs/x86_64-softmmu.mak | 28 ++++++++++++++-------------- + default-configs/x86_64-softmmu.mak | 28 +++++++++++++-------------- hw/acpi/ich9.c | 4 ++-- hw/arm/Makefile.objs | 2 +- hw/block/fdc.c | 1 + @@ -67,12 +68,12 @@ Merged patches (3.0.0): stubs/Makefile.objs | 1 + stubs/ide-isa.c | 13 +++++++++++++ target/arm/cpu.c | 4 +++- - target/i386/cpu.c | 35 +++++++++++++++++++++++++++-------- + target/i386/cpu.c | 35 ++++++++++++++++++++++++++-------- target/ppc/cpu-models.c | 17 ++++++++++++++++- target/s390x/cpu_models.c | 3 +++ target/s390x/kvm.c | 8 ++++++++ vl.c | 2 +- - 43 files changed, 240 insertions(+), 98 deletions(-) + 43 files changed, 241 insertions(+), 99 deletions(-) create mode 100644 stubs/ide-isa.c diff --git a/default-configs/aarch64-softmmu.mak b/default-configs/aarch64-softmmu.mak @@ -121,7 +122,7 @@ index 6f790f0..3f27540 100644 +CONFIG_I2C=y +CONFIG_FW_CFG_DMA=y diff --git a/default-configs/pci.mak b/default-configs/pci.mak -index de53d20..5cbe3e4 100644 +index de53d20..70e40ad 100644 --- a/default-configs/pci.mak +++ b/default-configs/pci.mak @@ -4,22 +4,22 @@ CONFIG_ISA_BUS=y @@ -185,8 +186,9 @@ index de53d20..5cbe3e4 100644 CONFIG_EDU=y CONFIG_VGA=y CONFIG_VGA_PCI=y - CONFIG_IVSHMEM_DEVICE=$(CONFIG_IVSHMEM) +-CONFIG_IVSHMEM_DEVICE=$(CONFIG_IVSHMEM) -CONFIG_ROCKER=y ++#CONFIG_IVSHMEM_DEVICE=$(CONFIG_IVSHMEM) +#CONFIG_ROCKER=y diff --git a/default-configs/ppc64-softmmu.mak b/default-configs/ppc64-softmmu.mak index b94af6c..30ca76d 100644 diff --git a/0006-Machine-type-related-general-changes.patch b/0006-Machine-type-related-general-changes.patch new file mode 100644 index 0000000..7693f8a --- /dev/null +++ b/0006-Machine-type-related-general-changes.patch @@ -0,0 +1,764 @@ +From e34179d713443601a16936e2e80b8fbd044429be Mon Sep 17 00:00:00 2001 +From: Miroslav Rezanina +Date: Thu, 8 Nov 2018 11:59:55 +0100 +Subject: Machine type related general changes + +This patch is first part of original "Add RHEL machine types" patch we +split to allow easier review. It contains changes not related to any +architecture. + +Signed-off-by: Miroslav Rezanina +--- + hw/acpi/ich9.c | 16 +++ + hw/acpi/piix4.c | 6 +- + hw/char/serial.c | 16 +++ + hw/display/cirrus_vga.c | 2 +- + hw/display/vga-isa.c | 2 +- + hw/net/e1000.c | 18 ++- + hw/net/e1000e.c | 21 ++++ + hw/net/rtl8139.c | 4 +- + hw/smbios/smbios.c | 1 + + hw/timer/i8254_common.c | 2 +- + hw/timer/mc146818rtc.c | 6 + + hw/usb/hcd-uhci.c | 4 +- + hw/usb/hcd-xhci.c | 20 ++++ + hw/usb/hcd-xhci.h | 2 + + include/hw/acpi/ich9.h | 3 + + include/hw/compat.h | 229 ++++++++++++++++++++++++++++++++++++++ + include/hw/usb.h | 4 + + migration/migration.c | 2 + + migration/migration.h | 5 + + qdev-monitor.c | 1 - + scripts/vmstate-static-checker.py | 1 - + 21 files changed, 354 insertions(+), 11 deletions(-) + +diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c +index a4e87b8..23a7baa 100644 +--- a/hw/acpi/ich9.c ++++ b/hw/acpi/ich9.c +@@ -441,6 +441,18 @@ static void ich9_pm_set_enable_tco(Object *obj, bool value, Error **errp) + s->pm.enable_tco = value; + } + ++static bool ich9_pm_get_force_rev1_fadt(Object *obj, Error **errp) ++{ ++ ICH9LPCState *s = ICH9_LPC_DEVICE(obj); ++ return s->pm.force_rev1_fadt; ++} ++ ++static void ich9_pm_set_force_rev1_fadt(Object *obj, bool value, Error **errp) ++{ ++ ICH9LPCState *s = ICH9_LPC_DEVICE(obj); ++ s->pm.force_rev1_fadt = value; ++} ++ + void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, Error **errp) + { + static const uint32_t gpe0_len = ICH9_PMIO_GPE0_LEN; +@@ -465,6 +477,10 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, Error **errp) + ich9_pm_get_cpu_hotplug_legacy, + ich9_pm_set_cpu_hotplug_legacy, + NULL); ++ object_property_add_bool(obj, "__com.redhat_force-rev1-fadt", ++ ich9_pm_get_force_rev1_fadt, ++ ich9_pm_set_force_rev1_fadt, ++ NULL); + object_property_add(obj, ACPI_PM_PROP_S3_DISABLED, "uint8", + ich9_pm_get_disable_s3, + ich9_pm_set_disable_s3, +diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c +index 6404af5..0f1f9e2 100644 +--- a/hw/acpi/piix4.c ++++ b/hw/acpi/piix4.c +@@ -310,7 +310,7 @@ static const VMStateDescription vmstate_cpuhp_state = { + static const VMStateDescription vmstate_acpi = { + .name = "piix4_pm", + .version_id = 3, +- .minimum_version_id = 3, ++ .minimum_version_id = 2, + .minimum_version_id_old = 1, + .load_state_old = acpi_load_old, + .post_load = vmstate_acpi_post_load, +@@ -670,8 +670,8 @@ static void piix4_send_gpe(AcpiDeviceIf *adev, AcpiEventStatusBits ev) + + static Property piix4_pm_properties[] = { + DEFINE_PROP_UINT32("smb_io_base", PIIX4PMState, smb_io_base, 0), +- DEFINE_PROP_UINT8(ACPI_PM_PROP_S3_DISABLED, PIIX4PMState, disable_s3, 0), +- DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_DISABLED, PIIX4PMState, disable_s4, 0), ++ DEFINE_PROP_UINT8(ACPI_PM_PROP_S3_DISABLED, PIIX4PMState, disable_s3, 1), ++ DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_DISABLED, PIIX4PMState, disable_s4, 1), + DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_VAL, PIIX4PMState, s4_val, 2), + DEFINE_PROP_BOOL("acpi-pci-hotplug-with-bridge-support", PIIX4PMState, + use_acpi_pci_hotplug, true), +diff --git a/hw/char/serial.c b/hw/char/serial.c +index 251f40f..8e3520c 100644 +--- a/hw/char/serial.c ++++ b/hw/char/serial.c +@@ -30,6 +30,7 @@ + #include "qemu/timer.h" + #include "qemu/error-report.h" + #include "trace.h" ++#include "migration/migration.h" + + //#define DEBUG_SERIAL + +@@ -699,6 +700,9 @@ static int serial_post_load(void *opaque, int version_id) + static bool serial_thr_ipending_needed(void *opaque) + { + SerialState *s = opaque; ++ if (migrate_pre_2_2) { ++ return false; ++ } + + if (s->ier & UART_IER_THRI) { + bool expected_value = ((s->iir & UART_IIR_ID) == UART_IIR_THRI); +@@ -780,6 +784,10 @@ static const VMStateDescription vmstate_serial_xmit_fifo = { + static bool serial_fifo_timeout_timer_needed(void *opaque) + { + SerialState *s = (SerialState *)opaque; ++ if (migrate_pre_2_2) { ++ return false; ++ } ++ + return timer_pending(s->fifo_timeout_timer); + } + +@@ -797,6 +805,10 @@ static const VMStateDescription vmstate_serial_fifo_timeout_timer = { + static bool serial_timeout_ipending_needed(void *opaque) + { + SerialState *s = (SerialState *)opaque; ++ if (migrate_pre_2_2) { ++ return false; ++ } ++ + return s->timeout_ipending != 0; + } + +@@ -814,6 +826,10 @@ static const VMStateDescription vmstate_serial_timeout_ipending = { + static bool serial_poll_needed(void *opaque) + { + SerialState *s = (SerialState *)opaque; ++ if (migrate_pre_2_2) { ++ return false; ++ } ++ + return s->poll_msl >= 0; + } + +diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c +index 9fd5665..6910014 100644 +--- a/hw/display/cirrus_vga.c ++++ b/hw/display/cirrus_vga.c +@@ -3061,7 +3061,7 @@ static void isa_cirrus_vga_realizefn(DeviceState *dev, Error **errp) + + static Property isa_cirrus_vga_properties[] = { + DEFINE_PROP_UINT32("vgamem_mb", struct ISACirrusVGAState, +- cirrus_vga.vga.vram_size_mb, 4), ++ cirrus_vga.vga.vram_size_mb, 16), + DEFINE_PROP_BOOL("blitter", struct ISACirrusVGAState, + cirrus_vga.enable_blitter, true), + DEFINE_PROP_END_OF_LIST(), +diff --git a/hw/display/vga-isa.c b/hw/display/vga-isa.c +index fa44242..7835c83 100644 +--- a/hw/display/vga-isa.c ++++ b/hw/display/vga-isa.c +@@ -80,7 +80,7 @@ static void vga_isa_realizefn(DeviceState *dev, Error **errp) + } + + static Property vga_isa_properties[] = { +- DEFINE_PROP_UINT32("vgamem_mb", ISAVGAState, state.vram_size_mb, 8), ++ DEFINE_PROP_UINT32("vgamem_mb", ISAVGAState, state.vram_size_mb, 16), + DEFINE_PROP_END_OF_LIST(), + }; + +diff --git a/hw/net/e1000.c b/hw/net/e1000.c +index 742cd0a..7d568da 100644 +--- a/hw/net/e1000.c ++++ b/hw/net/e1000.c +@@ -1663,6 +1663,16 @@ static void pci_e1000_realize(PCIDevice *pci_dev, Error **errp) + + pci_conf = pci_dev->config; + ++ if (!(d->compat_flags & E1000_FLAG_AUTONEG)) { ++ /* ++ * We have no capabilities, so capability list bit should normally be 0. ++ * Keep it on for compat machine types to avoid breaking migration. ++ * HACK: abuse E1000_FLAG_AUTONEG, which is off exactly for ++ * the machine types that need this. ++ */ ++ pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_CAP_LIST); ++ } ++ + /* TODO: RST# value should be 0, PCI spec 6.2.4 */ + pci_conf[PCI_CACHE_LINE_SIZE] = 0x10; + +@@ -1763,7 +1773,7 @@ static const TypeInfo e1000_base_info = { + + static const E1000Info e1000_devices[] = { + { +- .name = "e1000", ++ .name = "e1000-82540em", + .device_id = E1000_DEV_ID_82540EM, + .revision = 0x03, + .phy_id2 = E1000_PHY_ID2_8254xx_DEFAULT, +@@ -1784,6 +1794,11 @@ static const E1000Info e1000_devices[] = { + #endif + }; + ++static const TypeInfo e1000_default_info = { ++ .name = "e1000", ++ .parent = "e1000-82540em", ++}; ++ + static void e1000_register_types(void) + { + int i; +@@ -1801,6 +1816,7 @@ static void e1000_register_types(void) + + type_register(&type_info); + } ++ type_register_static(&e1000_default_info); + } + + type_init(e1000_register_types) +diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c +index 510ddb3..f1de9e5 100644 +--- a/hw/net/e1000e.c ++++ b/hw/net/e1000e.c +@@ -75,6 +75,11 @@ typedef struct E1000EState { + + E1000ECore core; + ++ /* 7.3 had the intr_state field that was in the original e1000e code ++ * but that was removed prior to 2.7's release ++ */ ++ bool redhat_7_3_intr_state_enable; ++ uint32_t redhat_7_3_intr_state; + } E1000EState; + + #define E1000E_MMIO_IDX 0 +@@ -90,6 +95,10 @@ typedef struct E1000EState { + #define E1000E_MSIX_TABLE (0x0000) + #define E1000E_MSIX_PBA (0x2000) + ++/* Values as in RHEL 7.3 build and original upstream */ ++#define RH_E1000E_USE_MSI BIT(0) ++#define RH_E1000E_USE_MSIX BIT(1) ++ + static uint64_t + e1000e_mmio_read(void *opaque, hwaddr addr, unsigned size) + { +@@ -301,6 +310,8 @@ e1000e_init_msix(E1000EState *s) + } else { + if (!e1000e_use_msix_vectors(s, E1000E_MSIX_VEC_NUM)) { + msix_uninit(d, &s->msix, &s->msix); ++ } else { ++ s->redhat_7_3_intr_state |= RH_E1000E_USE_MSIX; + } + } + } +@@ -472,6 +483,8 @@ static void e1000e_pci_realize(PCIDevice *pci_dev, Error **errp) + ret = msi_init(PCI_DEVICE(s), 0xD0, 1, true, false, NULL); + if (ret) { + trace_e1000e_msi_init_fail(ret); ++ } else { ++ s->redhat_7_3_intr_state |= RH_E1000E_USE_MSI; + } + + if (e1000e_add_pm_capability(pci_dev, e1000e_pmrb_offset, +@@ -595,6 +608,11 @@ static const VMStateDescription e1000e_vmstate_intr_timer = { + VMSTATE_STRUCT_ARRAY(_f, _s, _num, 0, \ + e1000e_vmstate_intr_timer, E1000IntrDelayTimer) + ++static bool rhel_7_3_check(void *opaque, int version_id) ++{ ++ return ((E1000EState *)opaque)->redhat_7_3_intr_state_enable; ++} ++ + static const VMStateDescription e1000e_vmstate = { + .name = "e1000e", + .version_id = 1, +@@ -606,6 +624,7 @@ static const VMStateDescription e1000e_vmstate = { + VMSTATE_MSIX(parent_obj, E1000EState), + + VMSTATE_UINT32(ioaddr, E1000EState), ++ VMSTATE_UINT32_TEST(redhat_7_3_intr_state, E1000EState, rhel_7_3_check), + VMSTATE_UINT32(core.rxbuf_min_shift, E1000EState), + VMSTATE_UINT8(core.rx_desc_len, E1000EState), + VMSTATE_UINT32_ARRAY(core.rxbuf_sizes, E1000EState, +@@ -654,6 +673,8 @@ static PropertyInfo e1000e_prop_disable_vnet, + + static Property e1000e_properties[] = { + DEFINE_NIC_PROPERTIES(E1000EState, conf), ++ DEFINE_PROP_BOOL("__redhat_e1000e_7_3_intr_state", E1000EState, ++ redhat_7_3_intr_state_enable, false), + DEFINE_PROP_SIGNED("disable_vnet_hdr", E1000EState, disable_vnet, false, + e1000e_prop_disable_vnet, bool), + DEFINE_PROP_SIGNED("subsys_ven", E1000EState, subsys_ven, +diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c +index 46daa16..05453e7 100644 +--- a/hw/net/rtl8139.c ++++ b/hw/net/rtl8139.c +@@ -3174,7 +3174,7 @@ static int rtl8139_pre_save(void *opaque) + + static const VMStateDescription vmstate_rtl8139 = { + .name = "rtl8139", +- .version_id = 5, ++ .version_id = 4, + .minimum_version_id = 3, + .post_load = rtl8139_post_load, + .pre_save = rtl8139_pre_save, +@@ -3255,7 +3255,9 @@ static const VMStateDescription vmstate_rtl8139 = { + VMSTATE_UINT32(tally_counters.TxMCol, RTL8139State), + VMSTATE_UINT64(tally_counters.RxOkPhy, RTL8139State), + VMSTATE_UINT64(tally_counters.RxOkBrd, RTL8139State), ++#if 0 /* Disabled for Red Hat Enterprise Linux bz 1420195 */ + VMSTATE_UINT32_V(tally_counters.RxOkMul, RTL8139State, 5), ++#endif + VMSTATE_UINT16(tally_counters.TxAbt, RTL8139State), + VMSTATE_UINT16(tally_counters.TxUndrn, RTL8139State), + +diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c +index a27e54b..144e6e9 100644 +--- a/hw/smbios/smbios.c ++++ b/hw/smbios/smbios.c +@@ -775,6 +775,7 @@ void smbios_set_defaults(const char *manufacturer, const char *product, + SMBIOS_SET_DEFAULT(type1.manufacturer, manufacturer); + SMBIOS_SET_DEFAULT(type1.product, product); + SMBIOS_SET_DEFAULT(type1.version, version); ++ SMBIOS_SET_DEFAULT(type1.family, "Red Hat Enterprise Linux"); + SMBIOS_SET_DEFAULT(type2.manufacturer, manufacturer); + SMBIOS_SET_DEFAULT(type2.product, product); + SMBIOS_SET_DEFAULT(type2.version, version); +diff --git a/hw/timer/i8254_common.c b/hw/timer/i8254_common.c +index 6190b6f..ad2ad2d 100644 +--- a/hw/timer/i8254_common.c ++++ b/hw/timer/i8254_common.c +@@ -268,7 +268,7 @@ static const VMStateDescription vmstate_pit_common = { + .pre_save = pit_dispatch_pre_save, + .post_load = pit_dispatch_post_load, + .fields = (VMStateField[]) { +- VMSTATE_UINT32_V(channels[0].irq_disabled, PITCommonState, 3), ++ VMSTATE_UINT32(channels[0].irq_disabled, PITCommonState), /* qemu-kvm's v2 had 'flags' here */ + VMSTATE_STRUCT_ARRAY(channels, PITCommonState, 3, 2, + vmstate_pit_channel, PITChannelState), + VMSTATE_INT64(channels[0].next_transition_time, +diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c +index 6f1f723..68c353f 100644 +--- a/hw/timer/mc146818rtc.c ++++ b/hw/timer/mc146818rtc.c +@@ -34,6 +34,7 @@ + #include "qapi/qapi-commands-misc.h" + #include "qapi/qapi-events-misc.h" + #include "qapi/visitor.h" ++#include "migration/migration.h" + + #ifdef TARGET_I386 + #include "hw/i386/apic.h" +@@ -839,6 +840,11 @@ static int rtc_post_load(void *opaque, int version_id) + static bool rtc_irq_reinject_on_ack_count_needed(void *opaque) + { + RTCState *s = (RTCState *)opaque; ++ ++ if (migrate_pre_2_2) { ++ return false; ++ } ++ + return s->irq_reinject_on_ack_count != 0; + } + +diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c +index 836b11f..9d7b9df 100644 +--- a/hw/usb/hcd-uhci.c ++++ b/hw/usb/hcd-uhci.c +@@ -1214,12 +1214,14 @@ static void usb_uhci_common_realize(PCIDevice *dev, Error **errp) + UHCIState *s = UHCI(dev); + uint8_t *pci_conf = s->dev.config; + int i; ++ int irq_pin; + + pci_conf[PCI_CLASS_PROG] = 0x00; + /* TODO: reset value should be 0. */ + pci_conf[USB_SBRN] = USB_RELEASE_1; // release number + +- pci_config_set_interrupt_pin(pci_conf, u->info.irq_pin + 1); ++ irq_pin = u->info.irq_pin; ++ pci_config_set_interrupt_pin(pci_conf, irq_pin + 1); + + if (s->masterbus) { + USBPort *ports[NB_PORTS]; +diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c +index 8f1a01a..ca19474 100644 +--- a/hw/usb/hcd-xhci.c ++++ b/hw/usb/hcd-xhci.c +@@ -3560,9 +3560,27 @@ static const VMStateDescription vmstate_xhci_slot = { + } + }; + ++static int xhci_event_pre_save(void *opaque) ++{ ++ XHCIEvent *s = opaque; ++ ++ s->cve_2014_5263_a = ((uint8_t *)&s->type)[0]; ++ s->cve_2014_5263_b = ((uint8_t *)&s->type)[1]; ++ ++ return 0; ++} ++ ++bool migrate_cve_2014_5263_xhci_fields; ++ ++static bool xhci_event_cve_2014_5263(void *opaque, int version_id) ++{ ++ return migrate_cve_2014_5263_xhci_fields; ++} ++ + static const VMStateDescription vmstate_xhci_event = { + .name = "xhci-event", + .version_id = 1, ++ .pre_save = xhci_event_pre_save, + .fields = (VMStateField[]) { + VMSTATE_UINT32(type, XHCIEvent), + VMSTATE_UINT32(ccode, XHCIEvent), +@@ -3571,6 +3589,8 @@ static const VMStateDescription vmstate_xhci_event = { + VMSTATE_UINT32(flags, XHCIEvent), + VMSTATE_UINT8(slotid, XHCIEvent), + VMSTATE_UINT8(epid, XHCIEvent), ++ VMSTATE_UINT8_TEST(cve_2014_5263_a, XHCIEvent, xhci_event_cve_2014_5263), ++ VMSTATE_UINT8_TEST(cve_2014_5263_b, XHCIEvent, xhci_event_cve_2014_5263), + VMSTATE_END_OF_LIST() + } + }; +diff --git a/hw/usb/hcd-xhci.h b/hw/usb/hcd-xhci.h +index fc36a4c..89d4cf7 100644 +--- a/hw/usb/hcd-xhci.h ++++ b/hw/usb/hcd-xhci.h +@@ -153,6 +153,8 @@ typedef struct XHCIEvent { + uint32_t flags; + uint8_t slotid; + uint8_t epid; ++ uint8_t cve_2014_5263_a; ++ uint8_t cve_2014_5263_b; + } XHCIEvent; + + typedef struct XHCIInterrupter { +diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h +index 59aeb06..7b5cc25 100644 +--- a/include/hw/acpi/ich9.h ++++ b/include/hw/acpi/ich9.h +@@ -61,6 +61,9 @@ typedef struct ICH9LPCPMRegs { + uint8_t smm_enabled; + bool enable_tco; + TCOIORegs tco_regs; ++ ++ /* RH addition, see bz 1489800 */ ++ bool force_rev1_fadt; + } ICH9LPCPMRegs; + + #define ACPI_PM_PROP_TCO_ENABLED "enable_tco" +diff --git a/include/hw/compat.h b/include/hw/compat.h +index c08f404..22262c7 100644 +--- a/include/hw/compat.h ++++ b/include/hw/compat.h +@@ -282,4 +282,233 @@ + .value = "on",\ + }, + ++/* Mostly like HW_COMPAT_2_1 but: ++ * we don't need virtio-scsi-pci since 7.0 already had that on ++ * ++ * RH: Note, qemu-extended-regs should have been enabled in the 7.1 ++ * machine type, but was accidentally turned off in 7.2 onwards. ++ * ++ */ ++#define HW_COMPAT_RHEL7_1 \ ++ { /* COMPAT_RHEL7.1 */ \ ++ .driver = "intel-hda-generic",\ ++ .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),\ ++ },{\ ++ .driver = "virtio-pci",\ ++ .property = "virtio-pci-bus-master-bug-migration",\ ++ .value = "on",\ ++ },{\ ++ .driver = "virtio-blk-pci",\ ++ .property = "any_layout",\ ++ .value = "off",\ ++ },{\ ++ .driver = "virtio-balloon-pci",\ ++ .property = "any_layout",\ ++ .value = "off",\ ++ },{\ ++ .driver = "virtio-serial-pci",\ ++ .property = "any_layout",\ ++ .value = "off",\ ++ },{\ ++ .driver = "virtio-9p-pci",\ ++ .property = "any_layout",\ ++ .value = "off",\ ++ },{\ ++ .driver = "virtio-rng-pci",\ ++ .property = "any_layout",\ ++ .value = "off",\ ++ },{ /* HW_COMPAT_RHEL7_1 - introduced with 2.10.0 */ \ ++ .driver = "migration",\ ++ .property = "send-configuration",\ ++ .value = "off",\ ++ }, ++ ++/* Mostly like HW_COMPAT_2_4 + 2_3 but: ++ * we don't need "any_layout" as it has been backported to 7.2 ++ */ ++ ++#define HW_COMPAT_RHEL7_2 \ ++ {\ ++ .driver = "virtio-blk-device",\ ++ .property = "scsi",\ ++ .value = "true",\ ++ },{\ ++ .driver = "e1000-82540em",\ ++ .property = "extra_mac_registers",\ ++ .value = "off",\ ++ },{\ ++ .driver = "virtio-pci",\ ++ .property = "x-disable-pcie",\ ++ .value = "on",\ ++ },{\ ++ .driver = "virtio-pci",\ ++ .property = "migrate-extra",\ ++ .value = "off",\ ++ },{ /* HW_COMPAT_RHEL7_2 */ \ ++ .driver = "fw_cfg_mem",\ ++ .property = "dma_enabled",\ ++ .value = "off",\ ++ },{ /* HW_COMPAT_RHEL7_2 */ \ ++ .driver = "fw_cfg_io",\ ++ .property = "dma_enabled",\ ++ .value = "off",\ ++ },{ /* HW_COMPAT_RHEL7_2 */ \ ++ .driver = "isa-fdc",\ ++ .property = "fallback",\ ++ .value = "144",\ ++ },{ /* HW_COMPAT_RHEL7_2 */ \ ++ .driver = "virtio-pci",\ ++ .property = "disable-modern",\ ++ .value = "on",\ ++ },{ /* HW_COMPAT_RHEL7_2 */ \ ++ .driver = "virtio-pci",\ ++ .property = "disable-legacy",\ ++ .value = "off",\ ++ },{ /* HW_COMPAT_RHEL7_2 */ \ ++ .driver = TYPE_PCI_DEVICE,\ ++ .property = "x-pcie-lnksta-dllla",\ ++ .value = "off",\ ++ },{ /* HW_COMPAT_RHEL7_2 */ \ ++ .driver = "virtio-pci",\ ++ .property = "page-per-vq",\ ++ .value = "on",\ ++ },{ /* HW_COMPAT_RHEL7_2 - introduced with 2.10.0 */ \ ++ .driver = "migration",\ ++ .property = "send-section-footer",\ ++ .value = "off",\ ++ },{ /* HW_COMPAT_RHEL7_2 - introduced with 2.10.0 */ \ ++ .driver = "migration",\ ++ .property = "store-global-state",\ ++ .value = "off",\ ++ }, ++ ++/* Mostly like HW_COMPAT_2_6 + HW_COMPAT_2_7 + HW_COMPAT_2_8 except ++ * disable-modern, disable-legacy, page-per-vq have already been ++ * backported to RHEL7.3 ++ */ ++#define HW_COMPAT_RHEL7_3 \ ++ { /* HW_COMPAT_RHEL7_3 */ \ ++ .driver = "virtio-mmio",\ ++ .property = "format_transport_address",\ ++ .value = "off",\ ++ },{ /* HW_COMPAT_RHEL7_3 */ \ ++ .driver = "virtio-serial-device",\ ++ .property = "emergency-write",\ ++ .value = "off",\ ++ },{ /* HW_COMPAT_RHEL7_3 */ \ ++ .driver = "ioapic",\ ++ .property = "version",\ ++ .value = "0x11",\ ++ },{ /* HW_COMPAT_RHEL7_3 */ \ ++ .driver = "intel-iommu",\ ++ .property = "x-buggy-eim",\ ++ .value = "true",\ ++ },{ /* HW_COMPAT_RHEL7_3 */ \ ++ .driver = "virtio-pci",\ ++ .property = "x-ignore-backend-features",\ ++ .value = "on",\ ++ },{ /* HW_COMPAT_RHEL7_3 */ \ ++ .driver = "fw_cfg_mem",\ ++ .property = "x-file-slots",\ ++ .value = stringify(0x10),\ ++ },{ /* HW_COMPAT_RHEL7_3 */ \ ++ .driver = "fw_cfg_io",\ ++ .property = "x-file-slots",\ ++ .value = stringify(0x10),\ ++ },{ /* HW_COMPAT_RHEL7_3 */ \ ++ .driver = "pflash_cfi01",\ ++ .property = "old-multiple-chip-handling",\ ++ .value = "on",\ ++ },{ /* HW_COMPAT_RHEL7_3 */ \ ++ .driver = TYPE_PCI_DEVICE,\ ++ .property = "x-pcie-extcap-init",\ ++ .value = "off",\ ++ },{ /* HW_COMPAT_RHEL7_3 */ \ ++ .driver = "virtio-pci",\ ++ .property = "x-pcie-deverr-init",\ ++ .value = "off",\ ++ },{ /* HW_COMPAT_RHEL7_3 */ \ ++ .driver = "virtio-pci",\ ++ .property = "x-pcie-lnkctl-init",\ ++ .value = "off",\ ++ },{ /* HW_COMPAT_RHEL7_3 */ \ ++ .driver = "virtio-pci",\ ++ .property = "x-pcie-pm-init",\ ++ .value = "off",\ ++ },{ /* HW_COMPAT_RHEL7_3 */ \ ++ .driver = "virtio-net-device",\ ++ .property = "x-mtu-bypass-backend",\ ++ .value = "off",\ ++ },{ /* HW_COMPAT_RHEL7_3 */ \ ++ .driver = "e1000e",\ ++ .property = "__redhat_e1000e_7_3_intr_state",\ ++ .value = "on",\ ++ }, ++ ++/* Mostly like HW_COMPAT_2_9 except ++ * x-mtu-bypass-backend, x-migrate-msix has already been ++ * backported to RHEL7.4. shpc was already on in 7.4. ++ */ ++#define HW_COMPAT_RHEL7_4 \ ++ { /* HW_COMPAT_RHEL7_4 */ \ ++ .driver = "intel-iommu",\ ++ .property = "pt",\ ++ .value = "off",\ ++ }, ++ ++/* The same as HW_COMPAT_2_11 + HW_COMPAT_2_10 */ ++#define HW_COMPAT_RHEL7_5 \ ++ { /* HW_COMPAT_RHEL7_5 from HW_COMPAT_2_11 */ \ ++ .driver = "hpet",\ ++ .property = "hpet-offset-saved",\ ++ .value = "false",\ ++ },{ /* HW_COMPAT_RHEL7_5 from HW_COMPAT_2_11 */ \ ++ .driver = "virtio-blk-pci",\ ++ .property = "vectors",\ ++ .value = "2",\ ++ },{ /* HW_COMPAT_RHEL7_5 from HW_COMPAT_2_11 */ \ ++ .driver = "vhost-user-blk-pci",\ ++ .property = "vectors",\ ++ .value = "2",\ ++ },{ /* HW_COMPAT_RHEL7_5 from HW_COMPAT_2_11 but \ ++ bz 1608778 modified for our naming */ \ ++ .driver = "e1000-82540em",\ ++ .property = "migrate_tso_props",\ ++ .value = "off",\ ++ },{ /* HW_COMPAT_RHEL7_5 from HW_COMPAT_2_10 */ \ ++ .driver = "virtio-mouse-device",\ ++ .property = "wheel-axis",\ ++ .value = "false",\ ++ },{ /* HW_COMPAT_RHEL7_5 from HW_COMPAT_2_10 */ \ ++ .driver = "virtio-tablet-device",\ ++ .property = "wheel-axis",\ ++ .value = "false",\ ++ },{ /* HW_COMPAT_RHEL7_5 */ \ ++ .driver = "cirrus-vga",\ ++ .property = "vgamem_mb",\ ++ .value = "16",\ ++ },{ /* HW_COMPAT_RHEL7_5 */ \ ++ .driver = "migration",\ ++ .property = "decompress-error-check",\ ++ .value = "off",\ ++ }, ++ ++ + #endif /* HW_COMPAT_H */ +diff --git a/include/hw/usb.h b/include/hw/usb.h +index a5080ad..b943ec9 100644 +--- a/include/hw/usb.h ++++ b/include/hw/usb.h +@@ -606,4 +606,8 @@ int usb_get_quirks(uint16_t vendor_id, uint16_t product_id, + uint8_t interface_class, uint8_t interface_subclass, + uint8_t interface_protocol); + ++ ++/* hcd-xhci.c -- rhel7.0.0 machine type compatibility */ ++extern bool migrate_cve_2014_5263_xhci_fields; ++ + #endif +diff --git a/migration/migration.c b/migration/migration.c +index b7d9854..381039c 100644 +--- a/migration/migration.c ++++ b/migration/migration.c +@@ -106,6 +106,8 @@ enum mig_rp_message_type { + MIG_RP_MSG_MAX + }; + ++bool migrate_pre_2_2; ++ + /* When we add fault tolerance, we could have several + migrations at once. For now we don't need to add + dynamic creation of migration */ +diff --git a/migration/migration.h b/migration/migration.h +index 64a7b33..405d984 100644 +--- a/migration/migration.h ++++ b/migration/migration.h +@@ -288,6 +288,11 @@ void migrate_send_rp_resume_ack(MigrationIncomingState *mis, uint32_t value); + + void dirty_bitmap_mig_before_vm_start(void); + void init_dirty_bitmap_incoming_migration(void); ++/* ++ * Disables a load of subsections that were added in 2.2/rh7.2 for backwards ++ * migration compatibility. ++ */ ++extern bool migrate_pre_2_2; + + #define qemu_ram_foreach_block \ + #warning "Use qemu_ram_foreach_block_migratable in migration code" +diff --git a/qdev-monitor.c b/qdev-monitor.c +index 61e0300..f439b83 100644 +--- a/qdev-monitor.c ++++ b/qdev-monitor.c +@@ -47,7 +47,6 @@ typedef struct QDevAlias + + /* Please keep this table sorted by typename. */ + static const QDevAlias qdev_alias_table[] = { +- { "e1000", "e1000-82540em" }, + { "ich9-ahci", "ahci" }, + { "lsi53c895a", "lsi" }, + { "virtio-9p-ccw", "virtio-9p", QEMU_ARCH_S390X }, +diff --git a/scripts/vmstate-static-checker.py b/scripts/vmstate-static-checker.py +index d346728..4bca2bf 100755 +--- a/scripts/vmstate-static-checker.py ++++ b/scripts/vmstate-static-checker.py +@@ -105,7 +105,6 @@ def get_changed_sec_name(sec): + # Section names can change -- see commit 292b1634 for an example. + changes = { + "ICH9 LPC": "ICH9-LPC", +- "e1000-82540em": "e1000", + } + + for item in changes: +-- +1.8.3.1 + diff --git a/0007-Add-aarch64-machine-types.patch b/0007-Add-aarch64-machine-types.patch new file mode 100644 index 0000000..c546843 --- /dev/null +++ b/0007-Add-aarch64-machine-types.patch @@ -0,0 +1,246 @@ +From 2c0d79871ccb5383b1a91e5fc9139b6f8e8ed8e0 Mon Sep 17 00:00:00 2001 +From: Miroslav Rezanina +Date: Thu, 8 Nov 2018 12:00:54 +0100 +Subject: Add aarch64 machine types + +Adding changes to add RHEL machine types for aarch64 architecture. + +Signed-off-by: Miroslav Rezanina +--- + hw/arm/virt.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++- + include/hw/arm/virt.h | 22 +++++++++ + 2 files changed, 147 insertions(+), 1 deletion(-) + +diff --git a/hw/arm/virt.c b/hw/arm/virt.c +index 281ddcd..b02e4a0 100644 +--- a/hw/arm/virt.c ++++ b/hw/arm/virt.c +@@ -60,6 +60,7 @@ + #include "standard-headers/linux/input.h" + #include "hw/arm/smmuv3.h" + ++#if 0 /* disabled Red Hat Enterprise Linux */ + #define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \ + static void virt_##major##_##minor##_class_init(ObjectClass *oc, \ + void *data) \ +@@ -87,7 +88,36 @@ + DEFINE_VIRT_MACHINE_LATEST(major, minor, true) + #define DEFINE_VIRT_MACHINE(major, minor) \ + DEFINE_VIRT_MACHINE_LATEST(major, minor, false) +- ++#endif /* disabled for RHEL */ ++ ++#define DEFINE_RHEL_MACHINE_LATEST(m, n, s, latest) \ ++ static void rhel##m##n##s##_virt_class_init(ObjectClass *oc, \ ++ void *data) \ ++ { \ ++ MachineClass *mc = MACHINE_CLASS(oc); \ ++ rhel##m##n##s##_virt_options(mc); \ ++ mc->desc = "RHEL " # m "." # n "." # s " ARM Virtual Machine"; \ ++ if (latest) { \ ++ mc->alias = "virt"; \ ++ mc->is_default = 1; \ ++ } \ ++ } \ ++ static const TypeInfo rhel##m##n##s##_machvirt_info = { \ ++ .name = MACHINE_TYPE_NAME("virt-rhel" # m "." # n "." # s), \ ++ .parent = TYPE_RHEL_MACHINE, \ ++ .instance_init = rhel##m##n##s##_virt_instance_init, \ ++ .class_init = rhel##m##n##s##_virt_class_init, \ ++ }; \ ++ static void rhel##m##n##s##_machvirt_init(void) \ ++ { \ ++ type_register_static(&rhel##m##n##s##_machvirt_info); \ ++ } \ ++ type_init(rhel##m##n##s##_machvirt_init); ++ ++#define DEFINE_RHEL_MACHINE_AS_LATEST(major, minor, subminor) \ ++ DEFINE_RHEL_MACHINE_LATEST(major, minor, subminor, true) ++#define DEFINE_RHEL_MACHINE(major, minor, subminor) \ ++ DEFINE_RHEL_MACHINE_LATEST(major, minor, subminor, false) + + /* Number of external interrupt lines to configure the GIC with */ + #define NUM_IRQS 256 +@@ -1539,6 +1569,7 @@ static void machvirt_init(MachineState *machine) + qemu_add_machine_init_done_notifier(&vms->machine_done); + } + ++#if 0 /* disabled for RHEL */ + static bool virt_get_secure(Object *obj, Error **errp) + { + VirtMachineState *vms = VIRT_MACHINE(obj); +@@ -1567,6 +1598,7 @@ static void virt_set_virt(Object *obj, bool value, Error **errp) + vms->virt = value; + } + ++#endif /* disabled for RHEL */ + static bool virt_get_highmem(Object *obj, Error **errp) + { + VirtMachineState *vms = VIRT_MACHINE(obj); +@@ -1621,6 +1653,7 @@ static void virt_set_gic_version(Object *obj, const char *value, Error **errp) + } + } + ++#if 0 + static char *virt_get_iommu(Object *obj, Error **errp) + { + VirtMachineState *vms = VIRT_MACHINE(obj); +@@ -1648,6 +1681,7 @@ static void virt_set_iommu(Object *obj, const char *value, Error **errp) + error_append_hint(errp, "Valid values are none, smmuv3.\n"); + } + } ++#endif + + static CpuInstanceProperties + virt_cpu_index_to_props(MachineState *ms, unsigned cpu_index) +@@ -1687,6 +1721,7 @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms) + return ms->possible_cpus; + } + ++#if 0 /* disabled for RHEL */ + static void virt_machine_device_plug_cb(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) + { +@@ -1835,6 +1870,9 @@ static void virt_machine_3_0_options(MachineClass *mc) + } + DEFINE_VIRT_MACHINE_AS_LATEST(3, 0) + ++#define VIRT_COMPAT_2_12 \ ++ HW_COMPAT_2_12 ++ + static void virt_2_12_instance_init(Object *obj) + { + virt_3_0_instance_init(obj); +@@ -1960,3 +1998,89 @@ static void virt_machine_2_6_options(MachineClass *mc) + vmc->no_pmu = true; + } + DEFINE_VIRT_MACHINE(2, 6) ++#endif /* disabled for RHEL */ ++ ++static void rhel_machine_class_init(ObjectClass *oc, void *data) ++{ ++ MachineClass *mc = MACHINE_CLASS(oc); ++ ++ mc->family = "virt-rhel-Z"; ++ mc->init = machvirt_init; ++ /* Start max_cpus at the maximum QEMU supports. We'll further restrict ++ * it later in machvirt_init, where we have more information about the ++ * configuration of the particular instance. ++ */ ++ mc->max_cpus = 255; ++ mc->block_default_type = IF_VIRTIO; ++ mc->no_cdrom = 1; ++ mc->pci_allow_0_address = true; ++ /* We know we will never create a pre-ARMv7 CPU which needs 1K pages */ ++ mc->minimum_page_bits = 12; ++ mc->possible_cpu_arch_ids = virt_possible_cpu_arch_ids; ++ mc->cpu_index_to_instance_props = virt_cpu_index_to_props; ++ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a57"); ++ mc->get_default_cpu_node_id = virt_get_default_cpu_node_id; ++} ++ ++static const TypeInfo rhel_machine_info = { ++ .name = TYPE_RHEL_MACHINE, ++ .parent = TYPE_MACHINE, ++ .abstract = true, ++ .instance_size = sizeof(VirtMachineState), ++ .class_size = sizeof(VirtMachineClass), ++ .class_init = rhel_machine_class_init, ++}; ++ ++static void rhel_machine_init(void) ++{ ++ type_register_static(&rhel_machine_info); ++} ++type_init(rhel_machine_init); ++ ++static void rhel760_virt_instance_init(Object *obj) ++{ ++ VirtMachineState *vms = VIRT_MACHINE(obj); ++ VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms); ++ ++ /* EL3 is disabled by default and non-configurable for RHEL */ ++ vms->secure = false; ++ /* EL2 is disabled by default and non-configurable for RHEL */ ++ vms->virt = false; ++ /* High memory is enabled by default for RHEL */ ++ vms->highmem = true; ++ object_property_add_bool(obj, "highmem", virt_get_highmem, ++ virt_set_highmem, NULL); ++ object_property_set_description(obj, "highmem", ++ "Set on/off to enable/disable using " ++ "physical address space above 32 bits", ++ NULL); ++ /* Default GIC type is still v2, but became configurable for RHEL */ ++ vms->gic_version = 2; ++ object_property_add_str(obj, "gic-version", virt_get_gic_version, ++ virt_set_gic_version, NULL); ++ object_property_set_description(obj, "gic-version", ++ "Set GIC version. " ++ "Valid values are 2, 3 and host", NULL); ++ ++ if (vmc->no_its) { ++ vms->its = false; ++ } else { ++ /* Default allows ITS instantiation */ ++ vms->its = true; ++ object_property_add_bool(obj, "its", virt_get_its, ++ virt_set_its, NULL); ++ object_property_set_description(obj, "its", ++ "Set on/off to enable/disable " ++ "ITS instantiation", ++ NULL); ++ } ++ ++ vms->memmap=a15memmap; ++ vms->irqmap=a15irqmap; ++} ++ ++static void rhel760_virt_options(MachineClass *mc) ++{ ++ SET_MACHINE_COMPAT(mc, ARM_RHEL_COMPAT); ++} ++DEFINE_RHEL_MACHINE_AS_LATEST(7, 6, 0) +diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h +index 9a870cc..2293315 100644 +--- a/include/hw/arm/virt.h ++++ b/include/hw/arm/virt.h +@@ -128,6 +128,7 @@ typedef struct { + + #define VIRT_ECAM_ID(high) (high ? VIRT_PCIE_ECAM_HIGH : VIRT_PCIE_ECAM) + ++#if 0 /* disabled for Red Hat Enterprise Linux */ + #define TYPE_VIRT_MACHINE MACHINE_TYPE_NAME("virt") + #define VIRT_MACHINE(obj) \ + OBJECT_CHECK(VirtMachineState, (obj), TYPE_VIRT_MACHINE) +@@ -136,6 +137,27 @@ typedef struct { + #define VIRT_MACHINE_CLASS(klass) \ + OBJECT_CLASS_CHECK(VirtMachineClass, klass, TYPE_VIRT_MACHINE) + ++#else ++#define TYPE_RHEL_MACHINE MACHINE_TYPE_NAME("virt-rhel") ++#define VIRT_MACHINE(obj) \ ++ OBJECT_CHECK(VirtMachineState, (obj), TYPE_RHEL_MACHINE) ++#define VIRT_MACHINE_GET_CLASS(obj) \ ++ OBJECT_GET_CLASS(VirtMachineClass, obj, TYPE_RHEL_MACHINE) ++#define VIRT_MACHINE_CLASS(klass) \ ++ OBJECT_CLASS_CHECK(VirtMachineClass, klass, TYPE_RHEL_MACHINE) ++#endif ++ ++/* This macro is for changes to properties that are RHEL specific, ++ * different to the current upstream and to be applied to the latest ++ * machine type. ++ */ ++#define ARM_RHEL_COMPAT \ ++ {\ ++ .driver = "virtio-net-pci",\ ++ .property = "romfile",\ ++ .value = "",\ ++ }, ++ + void virt_acpi_setup(VirtMachineState *vms); + + /* Return the number of used redistributor regions */ +-- +1.8.3.1 + diff --git a/0008-Add-ppc64-machine-types.patch b/0008-Add-ppc64-machine-types.patch new file mode 100644 index 0000000..dbe223e --- /dev/null +++ b/0008-Add-ppc64-machine-types.patch @@ -0,0 +1,397 @@ +From b6c41d9cfe7ae58455737c967f2e47d6bc99d21e Mon Sep 17 00:00:00 2001 +From: Miroslav Rezanina +Date: Thu, 8 Nov 2018 12:01:38 +0100 +Subject: Add ppc64 machine types + +Adding changes to add RHEL machine types for ppc64 architecture. + +Signed-off-by: Miroslav Rezanina +--- + hw/ppc/spapr.c | 252 ++++++++++++++++++++++++++++++++++++++++++++++++ + hw/ppc/spapr_cpu_core.c | 13 +++ + include/hw/ppc/spapr.h | 1 + + target/ppc/compat.c | 13 ++- + target/ppc/cpu.h | 1 + + 5 files changed, 279 insertions(+), 1 deletion(-) + +diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c +index 2f8c304..b8bdb69 100644 +--- a/hw/ppc/spapr.c ++++ b/hw/ppc/spapr.c +@@ -4009,6 +4009,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) + smc->default_caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_BROKEN; + smc->default_caps.caps[SPAPR_CAP_HPT_MAXPAGESIZE] = 16; /* 64kiB */ + spapr_caps_add_properties(smc, &error_abort); ++ smc->has_power9_support = true; + } + + static const TypeInfo spapr_machine_info = { +@@ -4059,6 +4060,7 @@ static const TypeInfo spapr_machine_info = { + } \ + type_init(spapr_machine_register_##suffix) + ++#if 0 /* Disabled for Red Hat Enterprise Linux */ + /* + * pseries-3.0 + */ +@@ -4248,6 +4250,7 @@ DEFINE_SPAPR_MACHINE(2_8, "2.8", false); + .property = "pre-2.8-migration", \ + .value = "on", \ + }, ++#endif + + static void phb_placement_2_7(sPAPRMachineState *spapr, uint32_t index, + uint64_t *buid, hwaddr *pio, +@@ -4298,6 +4301,7 @@ static void phb_placement_2_7(sPAPRMachineState *spapr, uint32_t index, + */ + } + ++#if 0 /* Disabled for Red Hat Enterprise Linux */ + static void spapr_machine_2_7_instance_options(MachineState *machine) + { + sPAPRMachineState *spapr = SPAPR_MACHINE(machine); +@@ -4457,6 +4461,254 @@ static void spapr_machine_2_1_class_options(MachineClass *mc) + SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_1); + } + DEFINE_SPAPR_MACHINE(2_1, "2.1", false); ++#endif ++ ++/* ++ * pseries-rhel7.6.0 ++ */ ++ ++static void spapr_machine_rhel760_instance_options(MachineState *machine) ++{ ++} ++ ++static void spapr_machine_rhel760_class_options(MachineClass *mc) ++{ ++ /* Defaults for the latest behaviour inherited from the base class */ ++} ++ ++DEFINE_SPAPR_MACHINE(rhel760, "rhel7.6.0", true); ++ ++/* ++ * pseries-rhel7.6.0-sxxm ++ * ++ * pseries-rhel7.6.0 with speculative execution exploit mitigations enabled by default ++ */ ++static void spapr_machine_rhel760sxxm_instance_options(MachineState *machine) ++{ ++ spapr_machine_rhel760_instance_options(machine); ++} ++ ++static void spapr_machine_rhel760sxxm_class_options(MachineClass *mc) ++{ ++ sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc); ++ ++ spapr_machine_rhel760_class_options(mc); ++ smc->default_caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_WORKAROUND; ++ smc->default_caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_WORKAROUND; ++ smc->default_caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_FIXED_CCD; ++} ++ ++DEFINE_SPAPR_MACHINE(rhel760sxxm, "rhel7.6.0-sxxm", false); ++ ++/* ++ * pseries-rhel7.5.0 ++ * like SPAPR_COMPAT_2_11 and SPAPR_COMPAT_2_10 ++ * SPAPR_CAP_HTM already enabled in 7.4 ++ * ++ */ ++#define SPAPR_COMPAT_RHEL7_5 \ ++ HW_COMPAT_RHEL7_5 \ ++ ++static void spapr_machine_rhel750_instance_options(MachineState *machine) ++{ ++ spapr_machine_rhel760_instance_options(machine); ++} ++ ++static void spapr_machine_rhel750_class_options(MachineClass *mc) ++{ ++ spapr_machine_rhel760_class_options(mc); ++ SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_RHEL7_5); ++} ++ ++DEFINE_SPAPR_MACHINE(rhel750, "rhel7.5.0", false); ++ ++/* ++ * pseries-rhel7.5.0-sxxm ++ * ++ * pseries-rhel7.5.0 with speculative execution exploit mitigations enabled by default ++ */ ++static void spapr_machine_rhel750sxxm_instance_options(MachineState *machine) ++{ ++ spapr_machine_rhel750_instance_options(machine); ++} ++ ++static void spapr_machine_rhel750sxxm_class_options(MachineClass *mc) ++{ ++ sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc); ++ ++ spapr_machine_rhel750_class_options(mc); ++ smc->default_caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_WORKAROUND; ++ smc->default_caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_WORKAROUND; ++ smc->default_caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_FIXED_CCD; ++} ++ ++DEFINE_SPAPR_MACHINE(rhel750sxxm, "rhel7.5.0-sxxm", false); ++ ++/* ++ * pseries-rhel7.4.0 ++ * like SPAPR_COMPAT_2_9 ++ */ ++ ++#define SPAPR_COMPAT_RHEL7_4 \ ++ HW_COMPAT_RHEL7_4 \ ++ { \ ++ .driver = TYPE_POWERPC_CPU, \ ++ .property = "pre-2.10-migration", \ ++ .value = "on", \ ++ }, \ ++ ++static void spapr_machine_rhel740_instance_options(MachineState *machine) ++{ ++ spapr_machine_rhel750_instance_options(machine); ++} ++ ++static void spapr_machine_rhel740_class_options(MachineClass *mc) ++{ ++ sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc); ++ ++ spapr_machine_rhel750_class_options(mc); ++ SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_RHEL7_4); ++ mc->numa_auto_assign_ram = numa_legacy_auto_assign_ram; ++ smc->has_power9_support = false; ++ smc->pre_2_10_has_unused_icps = true; ++ smc->resize_hpt_default = SPAPR_RESIZE_HPT_DISABLED; ++ smc->default_caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_ON; ++} ++ ++DEFINE_SPAPR_MACHINE(rhel740, "rhel7.4.0", false); ++ ++/* ++ * pseries-rhel7.4.0-sxxm ++ * ++ * pseries-rhel7.4.0 with speculative execution exploit mitigations enabled by default ++ */ ++static void spapr_machine_rhel740sxxm_instance_options(MachineState *machine) ++{ ++ spapr_machine_rhel740_instance_options(machine); ++} ++ ++static void spapr_machine_rhel740sxxm_class_options(MachineClass *mc) ++{ ++ sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc); ++ ++ spapr_machine_rhel740_class_options(mc); ++ smc->default_caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_WORKAROUND; ++ smc->default_caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_WORKAROUND; ++ smc->default_caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_FIXED_CCD; ++} ++ ++DEFINE_SPAPR_MACHINE(rhel740sxxm, "rhel7.4.0-sxxm", false); ++ ++/* ++ * pseries-rhel7.3.0 ++ * like SPAPR_COMPAT_2_6/_2_7/_2_8 but "ddw" has been backported to RHEL7_3 ++ */ ++#define SPAPR_COMPAT_RHEL7_3 \ ++ HW_COMPAT_RHEL7_3 \ ++ { \ ++ .driver = TYPE_SPAPR_PCI_HOST_BRIDGE, \ ++ .property = "mem_win_size", \ ++ .value = stringify(SPAPR_PCI_2_7_MMIO_WIN_SIZE),\ ++ }, \ ++ { \ ++ .driver = TYPE_SPAPR_PCI_HOST_BRIDGE, \ ++ .property = "mem64_win_size", \ ++ .value = "0", \ ++ }, \ ++ { \ ++ .driver = TYPE_POWERPC_CPU, \ ++ .property = "pre-2.8-migration", \ ++ .value = "on", \ ++ }, \ ++ { \ ++ .driver = TYPE_SPAPR_PCI_HOST_BRIDGE, \ ++ .property = "pre-2.8-migration", \ ++ .value = "on", \ ++ }, \ ++ { \ ++ .driver = TYPE_SPAPR_PCI_HOST_BRIDGE, \ ++ .property = "pcie-extended-configuration-space",\ ++ .value = "off", \ ++ }, ++ ++static void spapr_machine_rhel730_instance_options(MachineState *machine) ++{ ++ sPAPRMachineState *spapr = SPAPR_MACHINE(machine); ++ ++ spapr_machine_rhel740_instance_options(machine); ++ spapr->use_hotplug_event_source = false; ++} ++ ++static void spapr_machine_rhel730_class_options(MachineClass *mc) ++{ ++ sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc); ++ ++ spapr_machine_rhel740_class_options(mc); ++ mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power7_v2.3"); ++ SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_RHEL7_3); ++ smc->phb_placement = phb_placement_2_7; ++} ++ ++DEFINE_SPAPR_MACHINE(rhel730, "rhel7.3.0", false); ++ ++/* ++ * pseries-rhel7.3.0-sxxm ++ * ++ * pseries-rhel7.3.0 with speculative execution exploit mitigations enabled by default ++ */ ++static void spapr_machine_rhel730sxxm_instance_options(MachineState *machine) ++{ ++ spapr_machine_rhel730_instance_options(machine); ++} ++ ++static void spapr_machine_rhel730sxxm_class_options(MachineClass *mc) ++{ ++ sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc); ++ ++ spapr_machine_rhel730_class_options(mc); ++ smc->default_caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_WORKAROUND; ++ smc->default_caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_WORKAROUND; ++ smc->default_caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_FIXED_CCD; ++} ++ ++DEFINE_SPAPR_MACHINE(rhel730sxxm, "rhel7.3.0-sxxm", false); ++ ++/* ++ * pseries-rhel7.2.0 ++ */ ++/* Should be like SPAPR_COMPAT_2_5 + 2_4 + 2_3, but "dynamic-reconfiguration" ++ * has been backported to RHEL7_2 so we don't need it here. ++ */ ++ ++#define SPAPR_COMPAT_RHEL7_2 \ ++ HW_COMPAT_RHEL7_2 \ ++ { \ ++ .driver = "spapr-vlan", \ ++ .property = "use-rx-buffer-pools", \ ++ .value = "off", \ ++ },{ \ ++ .driver = TYPE_SPAPR_PCI_HOST_BRIDGE,\ ++ .property = "ddw",\ ++ .value = stringify(off),\ ++ }, ++ ++ ++static void spapr_machine_rhel720_instance_options(MachineState *machine) ++{ ++ spapr_machine_rhel730_instance_options(machine); ++} ++ ++static void spapr_machine_rhel720_class_options(MachineClass *mc) ++{ ++ sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc); ++ ++ spapr_machine_rhel730_class_options(mc); ++ smc->use_ohci_by_default = true; ++ mc->has_hotpluggable_cpus = NULL; ++ SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_RHEL7_2); ++} ++ ++DEFINE_SPAPR_MACHINE(rhel720, "rhel7.2.0", false); + + static void spapr_machine_register_types(void) + { +diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c +index fb29eec..a081b01 100644 +--- a/hw/ppc/spapr_cpu_core.c ++++ b/hw/ppc/spapr_cpu_core.c +@@ -21,6 +21,7 @@ + #include "sysemu/numa.h" + #include "sysemu/hw_accel.h" + #include "qemu/error-report.h" ++#include "cpu-models.h" + + static void spapr_cpu_reset(void *opaque) + { +@@ -212,6 +213,7 @@ static void spapr_realize_vcpu(PowerPCCPU *cpu, sPAPRMachineState *spapr, + { + CPUPPCState *env = &cpu->env; + Error *local_err = NULL; ++ sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr); + + object_property_set_bool(OBJECT(cpu), true, "realized", &local_err); + if (local_err) { +@@ -224,6 +226,17 @@ static void spapr_realize_vcpu(PowerPCCPU *cpu, sPAPRMachineState *spapr, + cpu_ppc_set_vhyp(cpu, PPC_VIRTUAL_HYPERVISOR(spapr)); + kvmppc_set_papr(cpu); + ++ if (!smc->has_power9_support && ++ (((spapr->max_compat_pvr && ++ ppc_compat_cmp(spapr->max_compat_pvr, ++ CPU_POWERPC_LOGICAL_3_00) >= 0)) || ++ (!spapr->max_compat_pvr && ++ ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_3_00, 0, 0)))) { ++ error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND, ++ "POWER9 CPU is not supported by this machine class"); ++ return; ++ } ++ + qemu_register_reset(spapr_cpu_reset, cpu); + spapr_cpu_reset(cpu); + +diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h +index 7e5de1a..330c370 100644 +--- a/include/hw/ppc/spapr.h ++++ b/include/hw/ppc/spapr.h +@@ -101,6 +101,7 @@ struct sPAPRMachineClass { + bool dr_lmb_enabled; /* enable dynamic-reconfig/hotplug of LMBs */ + bool use_ohci_by_default; /* use USB-OHCI instead of XHCI */ + bool pre_2_10_has_unused_icps; ++ bool has_power9_support; + void (*phb_placement)(sPAPRMachineState *spapr, uint32_t index, + uint64_t *buid, hwaddr *pio, + hwaddr *mmio32, hwaddr *mmio64, +diff --git a/target/ppc/compat.c b/target/ppc/compat.c +index 7de4bf3..3e2e353 100644 +--- a/target/ppc/compat.c ++++ b/target/ppc/compat.c +@@ -105,8 +105,19 @@ static const CompatInfo *compat_by_pvr(uint32_t pvr) + return NULL; + } + ++long ppc_compat_cmp(uint32_t pvr1, uint32_t pvr2) ++{ ++ const CompatInfo *compat1 = compat_by_pvr(pvr1); ++ const CompatInfo *compat2 = compat_by_pvr(pvr2); ++ ++ g_assert(compat1); ++ g_assert(compat2); ++ ++ return compat1 - compat2; ++} ++ + static bool pcc_compat(PowerPCCPUClass *pcc, uint32_t compat_pvr, +- uint32_t min_compat_pvr, uint32_t max_compat_pvr) ++ uint32_t min_compat_pvr, uint32_t max_compat_pvr) + { + const CompatInfo *compat = compat_by_pvr(compat_pvr); + const CompatInfo *min = compat_by_pvr(min_compat_pvr); +diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h +index 4edcf62..532f0d5 100644 +--- a/target/ppc/cpu.h ++++ b/target/ppc/cpu.h +@@ -1365,6 +1365,7 @@ static inline int cpu_mmu_index (CPUPPCState *env, bool ifetch) + + /* Compatibility modes */ + #if defined(TARGET_PPC64) ++long ppc_compat_cmp(uint32_t pvr1, uint32_t pvr2); + bool ppc_check_compat(PowerPCCPU *cpu, uint32_t compat_pvr, + uint32_t min_compat_pvr, uint32_t max_compat_pvr); + bool ppc_type_check_compat(const char *cputype, uint32_t compat_pvr, +-- +1.8.3.1 + diff --git a/0009-Add-s390x-machine-types.patch b/0009-Add-s390x-machine-types.patch new file mode 100644 index 0000000..92b5cbd --- /dev/null +++ b/0009-Add-s390x-machine-types.patch @@ -0,0 +1,86 @@ +From 05b950dccdf9e8f58f3358730aa4705642d0196f Mon Sep 17 00:00:00 2001 +From: Miroslav Rezanina +Date: Thu, 8 Nov 2018 12:02:37 +0100 +Subject: Add s390x machine types + +Adding changes to add RHEL machine types for s390x architecture. + +Signed-off-by: Miroslav Rezanina +--- + hw/s390x/s390-virtio-ccw.c | 46 +++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 45 insertions(+), 1 deletion(-) + +diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c +index 7983185..0f135c9 100644 +--- a/hw/s390x/s390-virtio-ccw.c ++++ b/hw/s390x/s390-virtio-ccw.c +@@ -649,7 +649,7 @@ bool css_migration_enabled(void) + { \ + MachineClass *mc = MACHINE_CLASS(oc); \ + ccw_machine_##suffix##_class_options(mc); \ +- mc->desc = "VirtIO-ccw based S390 machine v" verstr; \ ++ mc->desc = "VirtIO-ccw based S390 machine " verstr; \ + if (latest) { \ + mc->alias = "s390-ccw-virtio"; \ + mc->is_default = 1; \ +@@ -676,6 +676,8 @@ bool css_migration_enabled(void) + #define CCW_COMPAT_2_12 \ + HW_COMPAT_2_12 + ++#if 0 /* Disabled for Red Hat Enterprise Linux */ ++ + #define CCW_COMPAT_2_11 \ + HW_COMPAT_2_11 \ + {\ +@@ -898,6 +900,48 @@ static void ccw_machine_2_4_class_options(MachineClass *mc) + } + DEFINE_CCW_MACHINE(2_4, "2.4", false); + ++#else ++ ++/* ++ * like CCW_COMPAT_2_11, but includes HW_COMPAT_RHEL7_5 (derived from ++ * HW_COMPAT_2_11 and HW_COMPAT_2_10) instead of HW_COMPAT_2_11 ++ */ ++#define CCW_COMPAT_RHEL7_5 \ ++ HW_COMPAT_RHEL7_5 \ ++ {\ ++ .driver = TYPE_SCLP_EVENT_FACILITY,\ ++ .property = "allow_all_mask_sizes",\ ++ .value = "off",\ ++ }, ++ ++static void ccw_machine_rhel760_instance_options(MachineState *machine) ++{ ++} ++ ++static void ccw_machine_rhel760_class_options(MachineClass *mc) ++{ ++} ++DEFINE_CCW_MACHINE(rhel760, "rhel7.6.0", true); ++ ++static void ccw_machine_rhel750_instance_options(MachineState *machine) ++{ ++ static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V2_11 }; ++ ccw_machine_rhel760_instance_options(machine); ++ ++ /* before 2.12 we emulated the very first z900, and RHEL 7.5 is ++ based on 2.10 */ ++ s390_set_qemu_cpu_model(0x2064, 7, 1, qemu_cpu_feat); ++} ++ ++static void ccw_machine_rhel750_class_options(MachineClass *mc) ++{ ++ ccw_machine_rhel760_class_options(mc); ++ SET_MACHINE_COMPAT(mc, CCW_COMPAT_RHEL7_5); ++} ++DEFINE_CCW_MACHINE(rhel750, "rhel7.5.0", false); ++ ++#endif ++ + static void ccw_machine_register_types(void) + { + type_register_static(&ccw_machine_info); +-- +1.8.3.1 + diff --git a/0010-Add-x86_64-machine-types.patch b/0010-Add-x86_64-machine-types.patch new file mode 100644 index 0000000..30ec2d5 --- /dev/null +++ b/0010-Add-x86_64-machine-types.patch @@ -0,0 +1,1069 @@ +From b95483e9a18050c7dac0e6c17b049f0733a409cd Mon Sep 17 00:00:00 2001 +From: Miroslav Rezanina +Date: Thu, 8 Nov 2018 12:03:11 +0100 +Subject: Add x86_64 machine types + +Adding changes to add RHEL machine types for x86_64 architecture. + +Signed-off-by: Miroslav Rezanina +--- + hw/i386/acpi-build.c | 3 + + hw/i386/pc.c | 7 +- + hw/i386/pc_piix.c | 194 ++++++++++++++++- + hw/i386/pc_q35.c | 93 ++++++++- + include/hw/i386/pc.h | 564 ++++++++++++++++++++++++++++++++++++++++++++++++++ + target/i386/cpu.c | 9 +- + target/i386/machine.c | 21 ++ + 7 files changed, 884 insertions(+), 7 deletions(-) + +diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c +index e1ee8ae..be9bdb5 100644 +--- a/hw/i386/acpi-build.c ++++ b/hw/i386/acpi-build.c +@@ -184,6 +184,9 @@ static void acpi_get_pm_info(AcpiPmInfo *pm) + pm->fadt.reset_reg = r; + pm->fadt.reset_val = 0xf; + pm->fadt.flags |= 1 << ACPI_FADT_F_RESET_REG_SUP; ++ if (object_property_get_bool(lpc, ++ "__com.redhat_force-rev1-fadt", NULL)) ++ pm->fadt.rev = 1; + pm->cpu_hp_io_base = ICH9_CPU_HOTPLUG_IO_BASE; + } + assert(obj); +diff --git a/hw/i386/pc.c b/hw/i386/pc.c +index 11c287e..253d48d 100644 +--- a/hw/i386/pc.c ++++ b/hw/i386/pc.c +@@ -1419,7 +1419,8 @@ void pc_memory_init(PCMachineState *pcms, + option_rom_mr = g_malloc(sizeof(*option_rom_mr)); + memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE, + &error_fatal); +- if (pcmc->pci_enabled) { ++ /* RH difference: See bz 1489800, explicitly make ROM ro */ ++ if (pcmc->pc_rom_ro) { + memory_region_set_readonly(option_rom_mr, true); + } + memory_region_add_subregion_overlap(rom_memory, +@@ -2387,6 +2388,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) + pcmc->save_tsc_khz = true; + pcmc->linuxboot_dma_enabled = true; + assert(!mc->get_hotplug_handler); ++ pcmc->pc_rom_ro = true; + mc->get_hotplug_handler = pc_get_hotpug_handler; + mc->cpu_index_to_instance_props = pc_cpu_index_to_props; + mc->get_default_cpu_node_id = pc_get_default_cpu_node_id; +@@ -2396,7 +2398,8 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) + mc->default_boot_order = "cad"; + mc->hot_add_cpu = pc_hot_add_cpu; + mc->block_default_type = IF_IDE; +- mc->max_cpus = 255; ++ /* 240: max CPU count for RHEL */ ++ mc->max_cpus = 240; + mc->reset = pc_machine_reset; + hc->pre_plug = pc_machine_device_pre_plug_cb; + hc->plug = pc_machine_device_plug_cb; +diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c +index dc09466..f0484ec 100644 +--- a/hw/i386/pc_piix.c ++++ b/hw/i386/pc_piix.c +@@ -50,6 +50,7 @@ + #include "cpu.h" + #include "qapi/error.h" + #include "qemu/error-report.h" ++#include "migration/migration.h" + #ifdef CONFIG_XEN + #include + #include "hw/xen/xen_pt.h" +@@ -170,8 +171,8 @@ static void pc_init1(MachineState *machine, + if (pcmc->smbios_defaults) { + 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, pcmc->smbios_legacy_mode, ++ smbios_set_defaults("Red Hat", "KVM", ++ mc->desc, pcmc->smbios_legacy_mode, + pcmc->smbios_uuid_encoded, + SMBIOS_ENTRY_POINT_21); + } +@@ -309,6 +310,7 @@ static void pc_init1(MachineState *machine, + * HW_COMPAT_*, PC_COMPAT_*, or * pc_*_machine_options(). + */ + ++#if 0 /* Disabled for Red Hat Enterprise Linux */ + static void pc_compat_2_3(MachineState *machine) + { + PCMachineState *pcms = PC_MACHINE(machine); +@@ -433,6 +435,7 @@ static void pc_i440fx_3_0_machine_options(MachineClass *m) + pc_i440fx_machine_options(m); + m->alias = "pc"; + m->is_default = 1; ++ SET_MACHINE_COMPAT(m, PC_COMPAT_2_12); + } + + DEFINE_I440FX_MACHINE(v3_0, "pc-i440fx-3.0", NULL, +@@ -1148,3 +1151,190 @@ static void xenfv_machine_options(MachineClass *m) + DEFINE_PC_MACHINE(xenfv, "xenfv", pc_xen_hvm_init, + xenfv_machine_options); + #endif ++machine_init(pc_machine_init); ++ ++#endif /* Disabled for Red Hat Enterprise Linux */ ++ ++/* Red Hat Enterprise Linux machine types */ ++ ++/* Options for the latest rhel7 machine type */ ++static void pc_machine_rhel7_options(MachineClass *m) ++{ ++ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); ++ m->family = "pc_piix_Y"; ++ m->default_machine_opts = "firmware=bios-256k.bin"; ++ pcmc->default_nic_model = "e1000"; ++ m->default_display = "std"; ++ SET_MACHINE_COMPAT(m, PC_RHEL_COMPAT); ++ m->alias = "pc"; ++ m->is_default = 1; ++} ++ ++static void pc_init_rhel760(MachineState *machine) ++{ ++ pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \ ++ TYPE_I440FX_PCI_DEVICE); ++} ++ ++static void pc_machine_rhel760_options(MachineClass *m) ++{ ++ pc_machine_rhel7_options(m); ++ m->desc = "RHEL 7.6.0 PC (i440FX + PIIX, 1996)"; ++} ++ ++DEFINE_PC_MACHINE(rhel760, "pc-i440fx-rhel7.6.0", pc_init_rhel760, ++ pc_machine_rhel760_options); ++ ++static void pc_init_rhel750(MachineState *machine) ++{ ++ pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \ ++ TYPE_I440FX_PCI_DEVICE); ++} ++ ++static void pc_machine_rhel750_options(MachineClass *m) ++{ ++ pc_machine_rhel760_options(m); ++ m->alias = NULL; ++ m->is_default = 0; ++ m->desc = "RHEL 7.5.0 PC (i440FX + PIIX, 1996)"; ++ m->auto_enable_numa_with_memhp = false; ++ SET_MACHINE_COMPAT(m, PC_RHEL7_5_COMPAT); ++} ++ ++DEFINE_PC_MACHINE(rhel750, "pc-i440fx-rhel7.5.0", pc_init_rhel750, ++ pc_machine_rhel750_options); ++ ++static void pc_init_rhel740(MachineState *machine) ++{ ++ pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \ ++ TYPE_I440FX_PCI_DEVICE); ++} ++ ++static void pc_machine_rhel740_options(MachineClass *m) ++{ ++ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); ++ pc_machine_rhel750_options(m); ++ m->desc = "RHEL 7.4.0 PC (i440FX + PIIX, 1996)"; ++ m->numa_auto_assign_ram = numa_legacy_auto_assign_ram; ++ pcmc->pc_rom_ro = false; ++ SET_MACHINE_COMPAT(m, PC_RHEL7_4_COMPAT); ++} ++ ++DEFINE_PC_MACHINE(rhel740, "pc-i440fx-rhel7.4.0", pc_init_rhel740, ++ pc_machine_rhel740_options); ++ ++static void pc_init_rhel730(MachineState *machine) ++{ ++ pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \ ++ TYPE_I440FX_PCI_DEVICE); ++} ++ ++static void pc_machine_rhel730_options(MachineClass *m) ++{ ++ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); ++ pc_machine_rhel740_options(m); ++ m->desc = "RHEL 7.3.0 PC (i440FX + PIIX, 1996)"; ++ pcmc->linuxboot_dma_enabled = false; ++ SET_MACHINE_COMPAT(m, PC_RHEL7_3_COMPAT); ++} ++ ++DEFINE_PC_MACHINE(rhel730, "pc-i440fx-rhel7.3.0", pc_init_rhel730, ++ pc_machine_rhel730_options); ++ ++ ++static void pc_init_rhel720(MachineState *machine) ++{ ++ pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \ ++ TYPE_I440FX_PCI_DEVICE); ++} ++ ++static void pc_machine_rhel720_options(MachineClass *m) ++{ ++ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); ++ pc_machine_rhel730_options(m); ++ m->desc = "RHEL 7.2.0 PC (i440FX + PIIX, 1996)"; ++ /* From pc_i440fx_2_5_machine_options */ ++ pcmc->save_tsc_khz = false; ++ m->legacy_fw_cfg_order = 1; ++ /* Note: broken_reserved_end was already in 7.2 */ ++ /* From pc_i440fx_2_6_machine_options */ ++ pcmc->legacy_cpu_hotplug = true; ++ SET_MACHINE_COMPAT(m, PC_RHEL7_2_COMPAT); ++} ++ ++DEFINE_PC_MACHINE(rhel720, "pc-i440fx-rhel7.2.0", pc_init_rhel720, ++ pc_machine_rhel720_options); ++ ++static void pc_compat_rhel710(MachineState *machine) ++{ ++ PCMachineState *pcms = PC_MACHINE(machine); ++ PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms); ++ ++ /* From pc_compat_2_2 */ ++ pcmc->rsdp_in_ram = false; ++ machine->suppress_vmdesc = true; ++ ++ /* From pc_compat_2_1 */ ++ pcmc->smbios_uuid_encoded = false; ++ x86_cpu_change_kvm_default("svm", NULL); ++ pcmc->enforce_aligned_dimm = false; ++ ++ /* Disable all the extra subsections that were added in 2.2 */ ++ migrate_pre_2_2 = true; ++ ++ /* From pc_i440fx_2_4_machine_options */ ++ pcmc->broken_reserved_end = true; ++} ++ ++static void pc_init_rhel710(MachineState *machine) ++{ ++ pc_compat_rhel710(machine); ++ pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \ ++ TYPE_I440FX_PCI_DEVICE); ++} ++ ++static void pc_machine_rhel710_options(MachineClass *m) ++{ ++ pc_machine_rhel720_options(m); ++ m->family = "pc_piix_Y"; ++ m->desc = "RHEL 7.1.0 PC (i440FX + PIIX, 1996)"; ++ m->default_display = "cirrus"; ++ SET_MACHINE_COMPAT(m, PC_RHEL7_1_COMPAT); ++} ++ ++DEFINE_PC_MACHINE(rhel710, "pc-i440fx-rhel7.1.0", pc_init_rhel710, ++ pc_machine_rhel710_options); ++ ++static void pc_compat_rhel700(MachineState *machine) ++{ ++ PCMachineState *pcms = PC_MACHINE(machine); ++ PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms); ++ ++ pc_compat_rhel710(machine); ++ ++ /* Upstream enables it for everyone, we're a little more selective */ ++ x86_cpu_change_kvm_default("x2apic", NULL); ++ x86_cpu_change_kvm_default("svm", NULL); ++ pcmc->legacy_acpi_table_size = 6418; /* see pc_compat_2_0() */ ++ pcmc->smbios_legacy_mode = true; ++ pcmc->has_reserved_memory = false; ++ migrate_cve_2014_5263_xhci_fields = true; ++} ++ ++static void pc_init_rhel700(MachineState *machine) ++{ ++ pc_compat_rhel700(machine); ++ pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \ ++ TYPE_I440FX_PCI_DEVICE); ++} ++ ++static void pc_machine_rhel700_options(MachineClass *m) ++{ ++ pc_machine_rhel710_options(m); ++ m->family = "pc_piix_Y"; ++ m->desc = "RHEL 7.0.0 PC (i440FX + PIIX, 1996)"; ++ SET_MACHINE_COMPAT(m, PC_RHEL7_0_COMPAT); ++} ++ ++DEFINE_PC_MACHINE(rhel700, "pc-i440fx-rhel7.0.0", pc_init_rhel700, ++ pc_machine_rhel700_options); +diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c +index 532241e..c1024c5 100644 +--- a/hw/i386/pc_q35.c ++++ b/hw/i386/pc_q35.c +@@ -145,8 +145,8 @@ static void pc_q35_init(MachineState *machine) + + if (pcmc->smbios_defaults) { + /* These values are guest ABI, do not change */ +- smbios_set_defaults("QEMU", "Standard PC (Q35 + ICH9, 2009)", +- mc->name, pcmc->smbios_legacy_mode, ++ smbios_set_defaults("Red Hat", "KVM", ++ mc->desc, pcmc->smbios_legacy_mode, + pcmc->smbios_uuid_encoded, + SMBIOS_ENTRY_POINT_21); + } +@@ -294,6 +294,7 @@ static void pc_q35_init(MachineState *machine) + DEFINE_PC_MACHINE(suffix, name, pc_init_##suffix, optionfn) + + ++#if 0 /* Disabled for Red Hat Enterprise Linux */ + static void pc_q35_machine_options(MachineClass *m) + { + PCMachineClass *pcmc = PC_MACHINE_CLASS(m); +@@ -315,6 +316,7 @@ static void pc_q35_3_0_machine_options(MachineClass *m) + { + pc_q35_machine_options(m); + m->alias = "q35"; ++ SET_MACHINE_COMPAT(m, PC_COMPAT_2_12); + } + + DEFINE_Q35_MACHINE(v3_0, "pc-q35-3.0", NULL, +@@ -416,3 +418,90 @@ static void pc_q35_2_4_machine_options(MachineClass *m) + + DEFINE_Q35_MACHINE(v2_4, "pc-q35-2.4", NULL, + pc_q35_2_4_machine_options); ++#endif /* Disabled for Red Hat Enterprise Linux */ ++ ++/* Red Hat Enterprise Linux machine types */ ++ ++/* Options for the latest rhel7 q35 machine type */ ++static void pc_q35_machine_rhel7_options(MachineClass *m) ++{ ++ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); ++ pcmc->default_nic_model = "e1000e"; ++ m->family = "pc_q35_Z"; ++ m->default_machine_opts = "firmware=bios-256k.bin"; ++ m->default_display = "std"; ++ m->no_floppy = 1; ++ machine_class_allow_dynamic_sysbus_dev(m, TYPE_SYS_BUS_DEVICE); ++ m->alias = "q35"; ++ m->max_cpus = 384; ++ SET_MACHINE_COMPAT(m, PC_RHEL_COMPAT); ++} ++ ++static void pc_q35_init_rhel760(MachineState *machine) ++{ ++ pc_q35_init(machine); ++} ++ ++static void pc_q35_machine_rhel760_options(MachineClass *m) ++{ ++ pc_q35_machine_rhel7_options(m); ++ m->desc = "RHEL-7.6.0 PC (Q35 + ICH9, 2009)"; ++} ++ ++DEFINE_PC_MACHINE(q35_rhel760, "pc-q35-rhel7.6.0", pc_q35_init_rhel760, ++ pc_q35_machine_rhel760_options); ++ ++static void pc_q35_init_rhel750(MachineState *machine) ++{ ++ pc_q35_init(machine); ++} ++ ++static void pc_q35_machine_rhel750_options(MachineClass *m) ++{ ++ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); ++ pc_q35_machine_rhel760_options(m); ++ m->alias = NULL; ++ m->desc = "RHEL-7.5.0 PC (Q35 + ICH9, 2009)"; ++ m->auto_enable_numa_with_memhp = false; ++ pcmc->default_nic_model = "e1000"; ++ SET_MACHINE_COMPAT(m, PC_RHEL7_5_COMPAT); ++} ++ ++DEFINE_PC_MACHINE(q35_rhel750, "pc-q35-rhel7.5.0", pc_q35_init_rhel750, ++ pc_q35_machine_rhel750_options); ++ ++static void pc_q35_init_rhel740(MachineState *machine) ++{ ++ pc_q35_init(machine); ++} ++ ++static void pc_q35_machine_rhel740_options(MachineClass *m) ++{ ++ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); ++ pc_q35_machine_rhel750_options(m); ++ m->desc = "RHEL-7.4.0 PC (Q35 + ICH9, 2009)"; ++ m->numa_auto_assign_ram = numa_legacy_auto_assign_ram; ++ pcmc->pc_rom_ro = false; ++ SET_MACHINE_COMPAT(m, PC_RHEL7_4_COMPAT); ++} ++ ++DEFINE_PC_MACHINE(q35_rhel740, "pc-q35-rhel7.4.0", pc_q35_init_rhel740, ++ pc_q35_machine_rhel740_options); ++ ++static void pc_q35_init_rhel730(MachineState *machine) ++{ ++ pc_q35_init(machine); ++} ++ ++static void pc_q35_machine_rhel730_options(MachineClass *m) ++{ ++ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); ++ pc_q35_machine_rhel740_options(m); ++ m->desc = "RHEL-7.3.0 PC (Q35 + ICH9, 2009)"; ++ m->max_cpus = 255; ++ pcmc->linuxboot_dma_enabled = false; ++ SET_MACHINE_COMPAT(m, PC_RHEL7_3_COMPAT); ++} ++ ++DEFINE_PC_MACHINE(q35_rhel730, "pc-q35-rhel7.3.0", pc_q35_init_rhel730, ++ pc_q35_machine_rhel730_options); +diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h +index 6894f37..ef82513 100644 +--- a/include/hw/i386/pc.h ++++ b/include/hw/i386/pc.h +@@ -134,6 +134,9 @@ struct PCMachineClass { + + /* use DMA capable linuxboot option rom */ + bool linuxboot_dma_enabled; ++ ++ /* RH only, see bz 1489800 */ ++ bool pc_rom_ro; + }; + + #define TYPE_PC_MACHINE "generic-pc-machine" +@@ -960,4 +963,565 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); + type_init(pc_machine_init_##suffix) + + extern void igd_passthrough_isa_bridge_create(PCIBus *bus, uint16_t gpu_dev_id); ++ ++/* See include/hw/compat.h for shared compatibility lists */ ++ ++/* This macro is for changes to properties that are RHEL specific, ++ * different to the current upstream and to be applied to the latest ++ * machine type. ++ */ ++#define PC_RHEL_COMPAT \ ++ { /* PC_RHEL_COMPAT */ \ ++ .driver = TYPE_X86_CPU,\ ++ .property = "host-phys-bits",\ ++ .value = "on",\ ++ },\ ++ { /* PC_RHEL_COMPAT bz 1508330 */ \ ++ .driver = "vfio-pci",\ ++ .property = "x-no-geforce-quirks",\ ++ .value = "on",\ ++ }, ++ ++/* Similar to PC_COMPAT_2_11 + PC_COMPAT_2_10, but: ++ * - x-hv-max-vps was backported to 7.5 ++ * - x-pci-hole64-fix was backported to 7.5 ++ */ ++#define PC_RHEL7_5_COMPAT \ ++ HW_COMPAT_RHEL7_5 \ ++ { /* PC_RHEL7_5_COMPAT from PC_COMPAT_2_11 */ \ ++ .driver = "Skylake-Server" "-" TYPE_X86_CPU,\ ++ .property = "clflushopt",\ ++ .value = "off",\ ++ }, ++ ++ ++#define PC_RHEL7_4_COMPAT \ ++ HW_COMPAT_RHEL7_4 \ ++ { /* PC_RHEL7_4_COMPAT from PC_COMPAT_2_9 */ \ ++ .driver = "mch",\ ++ .property = "extended-tseg-mbytes",\ ++ .value = stringify(0),\ ++ },\ ++ { /* PC_RHEL7_4_COMPAT bz 1489800 */ \ ++ .driver = "ICH9-LPC",\ ++ .property = "__com.redhat_force-rev1-fadt",\ ++ .value = "on",\ ++ },\ ++ { /* PC_RHEL7_4_COMPAT from PC_COMPAT_2_10 */ \ ++ .driver = "i440FX-pcihost",\ ++ .property = "x-pci-hole64-fix",\ ++ .value = "off",\ ++ },\ ++ { /* PC_RHEL7_4_COMPAT from PC_COMPAT_2_10 */ \ ++ .driver = "q35-pcihost",\ ++ .property = "x-pci-hole64-fix",\ ++ .value = "off",\ ++ },\ ++ { /* PC_RHEL7_4_COMPAT from PC_COMPAT_2_10 */ \ ++ .driver = TYPE_X86_CPU,\ ++ .property = "x-hv-max-vps",\ ++ .value = "0x40",\ ++ }, ++ ++#define PC_RHEL7_3_COMPAT \ ++ HW_COMPAT_RHEL7_3 \ ++ { /* PC_RHEL7_3_COMPAT from PC_COMPAT_2_8 */ \ ++ .driver = "kvmclock",\ ++ .property = "x-mach-use-reliable-get-clock",\ ++ .value = "off",\ ++ },\ ++ { /* PC_RHEL7_3_COMPAT from PC_COMPAT_2_7 */ \ ++ .driver = TYPE_X86_CPU,\ ++ .property = "l3-cache",\ ++ .value = "off",\ ++ },\ ++ { /* PC_RHEL7_3_COMPAT from PC_COMPAT_2_7 */ \ ++ .driver = TYPE_X86_CPU,\ ++ .property = "full-cpuid-auto-level",\ ++ .value = "off",\ ++ },\ ++ { /* PC_RHEL7_3_COMPAT from PC_COMPAT_2_7 */ \ ++ .driver = "Opteron_G3" "-" TYPE_X86_CPU,\ ++ .property = "family",\ ++ .value = "15",\ ++ },\ ++ { /* PC_RHEL7_3_COMPAT from PC_COMPAT_2_7 */ \ ++ .driver = "Opteron_G3" "-" TYPE_X86_CPU,\ ++ .property = "model",\ ++ .value = "6",\ ++ },\ ++ { /* PC_RHEL7_3_COMPAT from PC_COMPAT_2_7 */ \ ++ .driver = "Opteron_G3" "-" TYPE_X86_CPU,\ ++ .property = "stepping",\ ++ .value = "1",\ ++ },\ ++ { /* PC_RHEL7_3_COMPAT from PC_COMPAT_2_7 */ \ ++ .driver = "isa-pcspk",\ ++ .property = "migrate",\ ++ .value = "off",\ ++ },\ ++ { /* PC_RHEL7_3_COMPAT from PC_COMPAT_2_6 */ \ ++ .driver = TYPE_X86_CPU,\ ++ .property = "cpuid-0xb",\ ++ .value = "off",\ ++ },\ ++ { /* PC_RHEL7_3_COMPAT from PC_COMPAT_2_8 */ \ ++ .driver = "ICH9-LPC",\ ++ .property = "x-smi-broadcast",\ ++ .value = "off",\ ++ },\ ++ { /* PC_RHEL7_3_COMPAT from PC_COMPAT_2_8 */ \ ++ .driver = TYPE_X86_CPU,\ ++ .property = "vmware-cpuid-freq",\ ++ .value = "off",\ ++ },\ ++ { /* PC_RHEL7_3_COMPAT from PC_COMPAT_2_8 */ \ ++ .driver = "Haswell-" TYPE_X86_CPU,\ ++ .property = "stepping",\ ++ .value = "1",\ ++ },\ ++ { /* PC_RHEL7_3_COMPAT from PC_COMPAT_2_3 added in 2.9 */ \ ++ .driver = TYPE_X86_CPU,\ ++ .property = "kvm-no-smi-migration",\ ++ .value = "on",\ ++ }, ++ ++#define PC_RHEL7_2_COMPAT \ ++ HW_COMPAT_RHEL7_2 \ ++ {\ ++ .driver = "phenom" "-" TYPE_X86_CPU,\ ++ .property = "rdtscp",\ ++ .value = "off",\ ++ },\ ++ { /* PC_RHEL7_2_COMPAT */ \ ++ .driver = "qemu64" "-" TYPE_X86_CPU,\ ++ .property = "sse4a",\ ++ .value = "on",\ ++ },\ ++ { /* PC_RHEL7_2_COMPAT */ \ ++ .driver = "qemu64" "-" TYPE_X86_CPU,\ ++ .property = "abm",\ ++ .value = "on",\ ++ },\ ++ { /* PC_RHEL7_2_COMPAT */ \ ++ .driver = "Haswell-" TYPE_X86_CPU,\ ++ .property = "abm",\ ++ .value = "off",\ ++ },\ ++ { /* PC_RHEL7_2_COMPAT (copied from the entry above) */ \ ++ .driver = "Haswell-IBRS" "-" TYPE_X86_CPU,\ ++ .property = "abm",\ ++ .value = "off",\ ++ },\ ++ { /* PC_RHEL7_2_COMPAT */ \ ++ .driver = "Haswell-noTSX-" TYPE_X86_CPU,\ ++ .property = "abm",\ ++ .value = "off",\ ++ },\ ++ { /* PC_RHEL7_2_COMPAT (copied from the entry above) */ \ ++ .driver = "Haswell-noTSX-IBRS" "-" TYPE_X86_CPU,\ ++ .property = "abm",\ ++ .value = "off",\ ++ },\ ++ { /* PC_RHEL7_2_COMPAT */ \ ++ .driver = "Broadwell-" TYPE_X86_CPU,\ ++ .property = "abm",\ ++ .value = "off",\ ++ },\ ++ { /* PC_RHEL7_2_COMPAT (copied from the entry above) */ \ ++ .driver = "Broadwell-IBRS" "-" TYPE_X86_CPU,\ ++ .property = "abm",\ ++ .value = "off",\ ++ },\ ++ { /* PC_RHEL7_2_COMPAT */ \ ++ .driver = "Broadwell-noTSX-" TYPE_X86_CPU,\ ++ .property = "abm",\ ++ .value = "off",\ ++ },\ ++ { /* PC_RHEL7_2_COMPAT (copied from the entry above) */ \ ++ .driver = "Broadwell-noTSX-IBRS" "-" TYPE_X86_CPU,\ ++ .property = "abm",\ ++ .value = "off",\ ++ },\ ++ { /* PC_RHEL7_2_COMPAT */ \ ++ .driver = "host" "-" TYPE_X86_CPU,\ ++ .property = "host-cache-info",\ ++ .value = "on",\ ++ },\ ++ { /* PC_RHEL7_2_COMPAT */ \ ++ .driver = TYPE_X86_CPU,\ ++ .property = "check",\ ++ .value = "off",\ ++ },\ ++ { /* PC_RHEL7_2_COMPAT */ \ ++ .driver = "qemu32" "-" TYPE_X86_CPU,\ ++ .property = "popcnt",\ ++ .value = "on",\ ++ },\ ++ { /* PC_RHEL7_2_COMPAT */ \ ++ .driver = TYPE_X86_CPU,\ ++ .property = "arat",\ ++ .value = "off",\ ++ },\ ++ { /* PC_RHEL7_2_COMPAT */ \ ++ .driver = "usb-redir",\ ++ .property = "streams",\ ++ .value = "off",\ ++ },\ ++ { /* PC_RHEL7_2_COMPAT */ \ ++ .driver = TYPE_X86_CPU,\ ++ .property = "fill-mtrr-mask",\ ++ .value = "off",\ ++ },\ ++ { /* PC_RHEL7_2_COMPAT */ \ ++ .driver = "apic-common",\ ++ .property = "legacy-instance-id",\ ++ .value = "on",\ ++ }, ++ ++ ++ ++#define PC_RHEL7_1_COMPAT \ ++ HW_COMPAT_RHEL7_1 \ ++ {\ ++ .driver = "kvm64" "-" TYPE_X86_CPU,\ ++ .property = "vme",\ ++ .value = "off",\ ++ },\ ++ {\ ++ .driver = "kvm32" "-" TYPE_X86_CPU,\ ++ .property = "vme",\ ++ .value = "off",\ ++ },\ ++ {\ ++ .driver = "Conroe" "-" TYPE_X86_CPU,\ ++ .property = "vme",\ ++ .value = "off",\ ++ },\ ++ {\ ++ .driver = "Penryn" "-" TYPE_X86_CPU,\ ++ .property = "vme",\ ++ .value = "off",\ ++ },\ ++ {\ ++ .driver = "Nehalem" "-" TYPE_X86_CPU,\ ++ .property = "vme",\ ++ .value = "off",\ ++ },\ ++ { /* PC_RHEL7_1_COMPAT (copied from the entry above) */ \ ++ .driver = "Nehalem-IBRS" "-" TYPE_X86_CPU,\ ++ .property = "vme",\ ++ .value = "off",\ ++ },\ ++ {\ ++ .driver = "Westmere" "-" TYPE_X86_CPU,\ ++ .property = "vme",\ ++ .value = "off",\ ++ },\ ++ { /* PC_RHEL7_1_COMPAT (copied from the entry above) */ \ ++ .driver = "Westmere-IBRS" "-" TYPE_X86_CPU,\ ++ .property = "vme",\ ++ .value = "off",\ ++ },\ ++ {\ ++ .driver = "SandyBridge" "-" TYPE_X86_CPU,\ ++ .property = "vme",\ ++ .value = "off",\ ++ },\ ++ { /* PC_RHEL7_1_COMPAT (copied from the entry above) */ \ ++ .driver = "SandyBridge-IBRS" "-" TYPE_X86_CPU,\ ++ .property = "vme",\ ++ .value = "off",\ ++ },\ ++ {\ ++ .driver = "Haswell" "-" TYPE_X86_CPU,\ ++ .property = "vme",\ ++ .value = "off",\ ++ },\ ++ { /* PC_RHEL7_1_COMPAT (copied from the entry above) */ \ ++ .driver = "Haswell-IBRS" "-" TYPE_X86_CPU,\ ++ .property = "vme",\ ++ .value = "off",\ ++ },\ ++ {\ ++ .driver = "Broadwell" "-" TYPE_X86_CPU,\ ++ .property = "vme",\ ++ .value = "off",\ ++ },\ ++ { /* PC_RHEL7_1_COMPAT (copied from the entry above) */ \ ++ .driver = "Broadwell-IBRS" "-" TYPE_X86_CPU,\ ++ .property = "vme",\ ++ .value = "off",\ ++ },\ ++ {\ ++ .driver = "Opteron_G1" "-" TYPE_X86_CPU,\ ++ .property = "vme",\ ++ .value = "off",\ ++ },\ ++ {\ ++ .driver = "Opteron_G2" "-" TYPE_X86_CPU,\ ++ .property = "vme",\ ++ .value = "off",\ ++ },\ ++ {\ ++ .driver = "Opteron_G3" "-" TYPE_X86_CPU,\ ++ .property = "vme",\ ++ .value = "off",\ ++ },\ ++ {\ ++ .driver = "Opteron_G4" "-" TYPE_X86_CPU,\ ++ .property = "vme",\ ++ .value = "off",\ ++ },\ ++ {\ ++ .driver = "Opteron_G5" "-" TYPE_X86_CPU,\ ++ .property = "vme",\ ++ .value = "off",\ ++ },\ ++ {\ ++ .driver = "Haswell" "-" TYPE_X86_CPU,\ ++ .property = "f16c",\ ++ .value = "off",\ ++ },\ ++ { /* PC_RHEL7_1_COMPAT (copied from the entry above) */ \ ++ .driver = "Haswell-IBRS" "-" TYPE_X86_CPU,\ ++ .property = "f16c",\ ++ .value = "off",\ ++ },\ ++ {\ ++ .driver = "Haswell" "-" TYPE_X86_CPU,\ ++ .property = "rdrand",\ ++ .value = "off",\ ++ },\ ++ { /* PC_RHEL7_1_COMPAT (copied from the entry above) */ \ ++ .driver = "Haswell-IBRS" "-" TYPE_X86_CPU,\ ++ .property = "rdrand",\ ++ .value = "off",\ ++ },\ ++ {\ ++ .driver = "Broadwell" "-" TYPE_X86_CPU,\ ++ .property = "f16c",\ ++ .value = "off",\ ++ },\ ++ { /* PC_RHEL7_1_COMPAT (copied from the entry above) */ \ ++ .driver = "Broadwell-IBRS" "-" TYPE_X86_CPU,\ ++ .property = "f16c",\ ++ .value = "off",\ ++ },\ ++ {\ ++ .driver = "Broadwell" "-" TYPE_X86_CPU,\ ++ .property = "rdrand",\ ++ .value = "off",\ ++ },\ ++ { /* PC_RHEL7_1_COMPAT (copied from the entry above) */ \ ++ .driver = "Broadwell-IBRS" "-" TYPE_X86_CPU,\ ++ .property = "rdrand",\ ++ .value = "off",\ ++ },\ ++ {\ ++ .driver = "coreduo" "-" TYPE_X86_CPU,\ ++ .property = "vmx",\ ++ .value = "on",\ ++ },\ ++ {\ ++ .driver = "core2duo" "-" TYPE_X86_CPU,\ ++ .property = "vmx",\ ++ .value = "on",\ ++ },\ ++ { /* PC_RHEL7_1_COMPAT */ \ ++ .driver = "qemu64" "-" TYPE_X86_CPU,\ ++ .property = "min-level",\ ++ .value = stringify(4),\ ++ },{ /* PC_RHEL7_1_COMPAT */ \ ++ .driver = "kvm64" "-" TYPE_X86_CPU,\ ++ .property = "min-level",\ ++ .value = stringify(5),\ ++ },{ /* PC_RHEL7_1_COMPAT */ \ ++ .driver = "pentium3" "-" TYPE_X86_CPU,\ ++ .property = "min-level",\ ++ .value = stringify(2),\ ++ },{ /* PC_RHEL7_1_COMPAT */ \ ++ .driver = "n270" "-" TYPE_X86_CPU,\ ++ .property = "min-level",\ ++ .value = stringify(5),\ ++ },{ /* PC_RHEL7_1_COMPAT */ \ ++ .driver = "Conroe" "-" TYPE_X86_CPU,\ ++ .property = "min-level",\ ++ .value = stringify(4),\ ++ },{ /* PC_RHEL7_1_COMPAT */ \ ++ .driver = "Penryn" "-" TYPE_X86_CPU,\ ++ .property = "min-level",\ ++ .value = stringify(4),\ ++ },{ /* PC_RHEL7_1_COMPAT */ \ ++ .driver = "Nehalem" "-" TYPE_X86_CPU,\ ++ .property = "min-level",\ ++ .value = stringify(4),\ ++ },{ /* PC_RHEL7_1_COMPAT */ \ ++ .driver = "n270" "-" TYPE_X86_CPU,\ ++ .property = "min-xlevel",\ ++ .value = stringify(0x8000000a),\ ++ },{ /* PC_RHEL7_1_COMPAT */ \ ++ .driver = "Penryn" "-" TYPE_X86_CPU,\ ++ .property = "min-xlevel",\ ++ .value = stringify(0x8000000a),\ ++ },{ /* PC_RHEL7_1_COMPAT */ \ ++ .driver = "Conroe" "-" TYPE_X86_CPU,\ ++ .property = "min-xlevel",\ ++ .value = stringify(0x8000000a),\ ++ },{ /* PC_RHEL7_1_COMPAT */ \ ++ .driver = "Nehalem" "-" TYPE_X86_CPU,\ ++ .property = "min-xlevel",\ ++ .value = stringify(0x8000000a),\ ++ },{ /* PC_RHEL7_1_COMPAT */ \ ++ .driver = "Westmere" "-" TYPE_X86_CPU,\ ++ .property = "min-xlevel",\ ++ .value = stringify(0x8000000a),\ ++ },{ /* PC_RHEL7_1_COMPAT */ \ ++ .driver = "SandyBridge" "-" TYPE_X86_CPU,\ ++ .property = "min-xlevel",\ ++ .value = stringify(0x8000000a),\ ++ },{ /* PC_RHEL7_1_COMPAT */ \ ++ .driver = "IvyBridge" "-" TYPE_X86_CPU,\ ++ .property = "min-xlevel",\ ++ .value = stringify(0x8000000a),\ ++ },{ /* PC_RHEL7_1_COMPAT */ \ ++ .driver = "Haswell" "-" TYPE_X86_CPU,\ ++ .property = "min-xlevel",\ ++ .value = stringify(0x8000000a),\ ++ },{ /* PC_RHEL7_1_COMPAT */ \ ++ .driver = "Haswell-noTSX" "-" TYPE_X86_CPU,\ ++ .property = "min-xlevel",\ ++ .value = stringify(0x8000000a),\ ++ },{ /* PC_RHEL7_1_COMPAT */ \ ++ .driver = "Broadwell" "-" TYPE_X86_CPU,\ ++ .property = "min-xlevel",\ ++ .value = stringify(0x8000000a),\ ++ },{ /* PC_RHEL7_1_COMPAT */ \ ++ .driver = "Broadwell-noTSX" "-" TYPE_X86_CPU,\ ++ .property = "min-xlevel",\ ++ .value = stringify(0x8000000a),\ ++ }, ++ ++/* ++ * The PC_RHEL_*_COMPAT serve the same purpose for RHEL-7 machine ++ * types as the PC_COMPAT_* do for upstream types. ++ * PC_RHEL_7_*_COMPAT apply both to i440fx and q35 types. ++ */ ++ ++/* ++ * RHEL-7 is based on QEMU 1.5.3, so this needs the PC_COMPAT_* ++ * between our base and 1.5, less stuff backported to RHEL-7.0 ++ * (usb-device.msos-desc), less stuff for devices we changed ++ * (qemu64-x86_64-cpu) or don't support (hpet, pci-serial-2x, ++ * pci-serial-4x) in 7.0. ++ */ ++#define PC_RHEL7_0_COMPAT \ ++ {\ ++ .driver = "virtio-scsi-pci",\ ++ .property = "any_layout",\ ++ .value = "off",\ ++ },{\ ++ .driver = "PIIX4_PM",\ ++ .property = "memory-hotplug-support",\ ++ .value = "off",\ ++ },{\ ++ .driver = "apic",\ ++ .property = "version",\ ++ .value = stringify(0x11),\ ++ },{\ ++ .driver = "nec-usb-xhci",\ ++ .property = "superspeed-ports-first",\ ++ .value = "off",\ ++ },{\ ++ .driver = "nec-usb-xhci",\ ++ .property = "force-pcie-endcap",\ ++ .value = "on",\ ++ },{\ ++ .driver = "pci-serial",\ ++ .property = "prog_if",\ ++ .value = stringify(0),\ ++ },{\ ++ .driver = "virtio-net-pci",\ ++ .property = "guest_announce",\ ++ .value = "off",\ ++ },{\ ++ .driver = "ICH9-LPC",\ ++ .property = "memory-hotplug-support",\ ++ .value = "off",\ ++ },{\ ++ .driver = "xio3130-downstream",\ ++ .property = COMPAT_PROP_PCP,\ ++ .value = "off",\ ++ },{\ ++ .driver = "ioh3420",\ ++ .property = COMPAT_PROP_PCP,\ ++ .value = "off",\ ++ },{\ ++ .driver = "PIIX4_PM",\ ++ .property = "acpi-pci-hotplug-with-bridge-support",\ ++ .value = "off",\ ++ },{\ ++ .driver = "e1000",\ ++ .property = "mitigation",\ ++ .value = "off",\ ++ },{ \ ++ .driver = "virtio-net-pci", \ ++ .property = "ctrl_guest_offloads", \ ++ .value = "off", \ ++ },\ ++ {\ ++ .driver = "Conroe" "-" TYPE_X86_CPU,\ ++ .property = "x2apic",\ ++ .value = "on",\ ++ },\ ++ {\ ++ .driver = "Penryn" "-" TYPE_X86_CPU,\ ++ .property = "x2apic",\ ++ .value = "on",\ ++ },\ ++ {\ ++ .driver = "Nehalem" "-" TYPE_X86_CPU,\ ++ .property = "x2apic",\ ++ .value = "on",\ ++ },\ ++ { /* PC_RHEL7_0_COMPAT (copied from the entry above) */ \ ++ .driver = "Nehalem-IBRS" "-" TYPE_X86_CPU,\ ++ .property = "x2apic",\ ++ .value = "on",\ ++ },\ ++ {\ ++ .driver = "Westmere" "-" TYPE_X86_CPU,\ ++ .property = "x2apic",\ ++ .value = "on",\ ++ },\ ++ { /* PC_RHEL7_0_COMPAT (copied from the entry above) */ \ ++ .driver = "Westmere-IBRS" "-" TYPE_X86_CPU,\ ++ .property = "x2apic",\ ++ .value = "on",\ ++ },\ ++ {\ ++ .driver = "Opteron_G1" "-" TYPE_X86_CPU,\ ++ .property = "x2apic",\ ++ .value = "on",\ ++ },\ ++ {\ ++ .driver = "Opteron_G2" "-" TYPE_X86_CPU,\ ++ .property = "x2apic",\ ++ .value = "on",\ ++ },\ ++ {\ ++ .driver = "Opteron_G3" "-" TYPE_X86_CPU,\ ++ .property = "x2apic",\ ++ .value = "on",\ ++ },\ ++ {\ ++ .driver = "Opteron_G4" "-" TYPE_X86_CPU,\ ++ .property = "x2apic",\ ++ .value = "on",\ ++ },\ ++ {\ ++ .driver = "Opteron_G5" "-" TYPE_X86_CPU,\ ++ .property = "x2apic",\ ++ .value = "on",\ ++ }, + #endif +diff --git a/target/i386/cpu.c b/target/i386/cpu.c +index 338ee37..051018a 100644 +--- a/target/i386/cpu.c ++++ b/target/i386/cpu.c +@@ -1360,11 +1360,17 @@ static CPUCaches epyc_cache_info = { + + static X86CPUDefinition builtin_x86_defs[] = { + { ++ /* qemu64 is the default CPU model for all *-rhel7.* machine-types. ++ * The default on RHEL-6 was cpu64-rhel6. ++ * libvirt assumes that qemu64 is the default for _all_ machine-types, ++ * so we should try to keep qemu64 and cpu64-rhel6 as similar as ++ * possible. ++ */ + .name = "qemu64", + .level = 0xd, + .vendor = CPUID_VENDOR_AMD, + .family = 6, +- .model = 6, ++ .model = 13, + .stepping = 3, + .features[FEAT_1_EDX] = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | + CPUID_MMX | CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | +@@ -2684,6 +2690,7 @@ static PropValue kvm_default_props[] = { + { "acpi", "off" }, + { "monitor", "off" }, + { "svm", "off" }, ++ { "kvm-pv-unhalt", "on" }, + { NULL, NULL }, + }; + +diff --git a/target/i386/machine.c b/target/i386/machine.c +index 084c2c7..0c57c26 100644 +--- a/target/i386/machine.c ++++ b/target/i386/machine.c +@@ -955,6 +955,26 @@ static const VMStateDescription vmstate_svm_npt = { + } + }; + ++static bool vmstate_xsave_needed(void *opaque) ++{ ++ /* The xsave state is already on the main "cpu" section */ ++ return false; ++} ++ ++static const VMStateDescription vmstate_xsave ={ ++ .name = "cpu/xsave", ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .minimum_version_id_old = 1, ++ .needed = vmstate_xsave_needed, ++ .fields = (VMStateField []) { ++ VMSTATE_UINT64_V(env.xcr0, X86CPU, 1), ++ VMSTATE_UINT64_V(env.xstate_bv, X86CPU, 1), ++ VMSTATE_YMMH_REGS_VARS(env.xmm_regs, X86CPU, CPU_NB_REGS, 1), ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ + VMStateDescription vmstate_x86_cpu = { + .name = "cpu", + .version_id = 12, +@@ -1080,6 +1100,7 @@ VMStateDescription vmstate_x86_cpu = { + &vmstate_msr_intel_pt, + &vmstate_msr_virt_ssbd, + &vmstate_svm_npt, ++ &vmstate_xsave, + NULL + } + }; +-- +1.8.3.1 + diff --git a/0011-Enable-make-check.patch b/0011-Enable-make-check.patch new file mode 100644 index 0000000..1be86ed --- /dev/null +++ b/0011-Enable-make-check.patch @@ -0,0 +1,498 @@ +From f4e3d697cb6a18301b1279c0b07896eb5b228aa9 Mon Sep 17 00:00:00 2001 +From: Miroslav Rezanina +Date: Thu, 8 Nov 2018 12:03:48 +0100 +Subject: Enable make check + +Fixing tests after device disabling and machine types changes and enabling +make check run during build. + +Signed-off-by: Miroslav Rezanina +--- + redhat/qemu-kvm.spec.template | 2 +- + tests/Makefile.include | 123 +++++++++++++++++++++--------------------- + tests/boot-serial-test.c | 6 ++- + tests/cpu-plug-test.c | 3 +- + tests/e1000-test.c | 2 + + tests/endianness-test.c | 2 + + tests/prom-env-test.c | 2 + + tests/qemu-iotests/051 | 12 ++--- + tests/qemu-iotests/group | 4 +- + tests/qom-test.c | 2 +- + tests/test-x86-cpuid-compat.c | 2 + + tests/usb-hcd-xhci-test.c | 4 ++ + 12 files changed, 91 insertions(+), 73 deletions(-) + +diff --git a/tests/Makefile.include b/tests/Makefile.include +index a492827..4b78396 100644 +--- a/tests/Makefile.include ++++ b/tests/Makefile.include +@@ -184,8 +184,8 @@ gcov-files-generic-y = qdev-monitor.c qmp.c + check-qtest-generic-y += tests/cdrom-test$(EXESUF) + + gcov-files-ipack-y += hw/ipack/ipack.c +-check-qtest-ipack-y += tests/ipoctal232-test$(EXESUF) +-gcov-files-ipack-y += hw/char/ipoctal232.c ++#check-qtest-ipack-y += tests/ipoctal232-test$(EXESUF) ++#gcov-files-ipack-y += hw/char/ipoctal232.c + + check-qtest-virtioserial-y += tests/virtio-console-test$(EXESUF) + gcov-files-virtioserial-y += hw/char/virtio-console.c +@@ -217,23 +217,23 @@ check-qtest-pci-y += tests/e1000e-test$(EXESUF) + gcov-files-pci-y += hw/net/e1000e.c hw/net/e1000e_core.c + check-qtest-pci-y += tests/rtl8139-test$(EXESUF) + gcov-files-pci-y += hw/net/rtl8139.c +-check-qtest-pci-y += tests/pcnet-test$(EXESUF) +-gcov-files-pci-y += hw/net/pcnet.c +-gcov-files-pci-y += hw/net/pcnet-pci.c +-check-qtest-pci-y += tests/eepro100-test$(EXESUF) +-gcov-files-pci-y += hw/net/eepro100.c +-check-qtest-pci-y += tests/ne2000-test$(EXESUF) +-gcov-files-pci-y += hw/net/ne2000.c +-check-qtest-pci-y += tests/nvme-test$(EXESUF) +-gcov-files-pci-y += hw/block/nvme.c ++#check-qtest-pci-y += tests/pcnet-test$(EXESUF) ++#gcov-files-pci-y += hw/net/pcnet.c ++#gcov-files-pci-y += hw/net/pcnet-pci.c ++#check-qtest-pci-y += tests/eepro100-test$(EXESUF) ++#gcov-files-pci-y += hw/net/eepro100.c ++#check-qtest-pci-y += tests/ne2000-test$(EXESUF) ++#gcov-files-pci-y += hw/net/ne2000.c ++#check-qtest-pci-y += tests/nvme-test$(EXESUF) ++#gcov-files-pci-y += hw/block/nvme.c + check-qtest-pci-y += tests/ac97-test$(EXESUF) + gcov-files-pci-y += hw/audio/ac97.c +-check-qtest-pci-y += tests/es1370-test$(EXESUF) +-gcov-files-pci-y += hw/audio/es1370.c ++#check-qtest-pci-y += tests/es1370-test$(EXESUF) ++#gcov-files-pci-y += hw/audio/es1370.c + check-qtest-pci-y += $(check-qtest-virtio-y) + gcov-files-pci-y += $(gcov-files-virtio-y) hw/virtio/virtio-pci.c +-check-qtest-pci-y += tests/tpci200-test$(EXESUF) +-gcov-files-pci-y += hw/ipack/tpci200.c ++#check-qtest-pci-y += tests/tpci200-test$(EXESUF) ++#gcov-files-pci-y += hw/ipack/tpci200.c + check-qtest-pci-y += $(check-qtest-ipack-y) + gcov-files-pci-y += $(gcov-files-ipack-y) + check-qtest-pci-y += tests/display-vga-test$(EXESUF) +@@ -245,25 +245,25 @@ gcov-files-pci-y += hw/display/virtio-gpu-pci.c + gcov-files-pci-$(CONFIG_VIRTIO_VGA) += hw/display/virtio-vga.c + check-qtest-pci-y += tests/intel-hda-test$(EXESUF) + gcov-files-pci-y += hw/audio/intel-hda.c hw/audio/hda-codec.c +-check-qtest-pci-$(CONFIG_IVSHMEM) += tests/ivshmem-test$(EXESUF) +-gcov-files-pci-y += hw/misc/ivshmem.c +-check-qtest-pci-y += tests/megasas-test$(EXESUF) +-gcov-files-pci-y += hw/scsi/megasas.c ++check-qtest-pci-$(CONFIG_IVSHMEM_DEVICE) += tests/ivshmem-test$(EXESUF) ++gcov-files-pci-$(CONFIG_IVSHMEM_DEVICE) += hw/misc/ivshmem.c ++#check-qtest-pci-y += tests/megasas-test$(EXESUF) ++#gcov-files-pci-y += hw/scsi/megasas.c + + check-qtest-i386-y = tests/endianness-test$(EXESUF) +-check-qtest-i386-y += tests/fdc-test$(EXESUF) +-gcov-files-i386-y = hw/block/fdc.c ++#check-qtest-i386-y += tests/fdc-test$(EXESUF) ++#gcov-files-i386-y = hw/block/fdc.c + check-qtest-i386-y += tests/ide-test$(EXESUF) + check-qtest-i386-y += tests/ahci-test$(EXESUF) + check-qtest-i386-y += tests/hd-geo-test$(EXESUF) + gcov-files-i386-y += hw/block/hd-geometry.c + check-qtest-i386-y += tests/boot-order-test$(EXESUF) +-check-qtest-i386-y += tests/bios-tables-test$(EXESUF) ++#check-qtest-i386-y += tests/bios-tables-test$(EXESUF) + check-qtest-i386-y += tests/boot-serial-test$(EXESUF) + check-qtest-i386-$(CONFIG_SLIRP) += tests/pxe-test$(EXESUF) + check-qtest-i386-y += tests/rtc-test$(EXESUF) +-check-qtest-i386-y += tests/ipmi-kcs-test$(EXESUF) +-check-qtest-i386-y += tests/ipmi-bt-test$(EXESUF) ++#check-qtest-i386-y += tests/ipmi-kcs-test$(EXESUF) ++#check-qtest-i386-y += tests/ipmi-bt-test$(EXESUF) + check-qtest-i386-y += tests/i440fx-test$(EXESUF) + check-qtest-i386-y += tests/fw_cfg-test$(EXESUF) + check-qtest-i386-y += tests/drive_del-test$(EXESUF) +@@ -272,8 +272,8 @@ check-qtest-i386-y += tests/tco-test$(EXESUF) + gcov-files-i386-y += hw/watchdog/watchdog.c hw/watchdog/wdt_ib700.c + check-qtest-i386-y += $(check-qtest-pci-y) + gcov-files-i386-y += $(gcov-files-pci-y) +-check-qtest-i386-y += tests/vmxnet3-test$(EXESUF) +-gcov-files-i386-y += hw/net/vmxnet3.c ++#check-qtest-i386-y += tests/vmxnet3-test$(EXESUF) ++#gcov-files-i386-y += hw/net/vmxnet3.c + gcov-files-i386-y += hw/net/net_rx_pkt.c + gcov-files-i386-y += hw/net/net_tx_pkt.c + check-qtest-i386-y += tests/pvpanic-test$(EXESUF) +@@ -282,8 +282,8 @@ check-qtest-i386-y += tests/i82801b11-test$(EXESUF) + gcov-files-i386-y += hw/pci-bridge/i82801b11.c + check-qtest-i386-y += tests/ioh3420-test$(EXESUF) + gcov-files-i386-y += hw/pci-bridge/ioh3420.c +-check-qtest-i386-y += tests/usb-hcd-ohci-test$(EXESUF) +-gcov-files-i386-y += hw/usb/hcd-ohci.c ++#check-qtest-i386-y += tests/usb-hcd-ohci-test$(EXESUF) ++#gcov-files-i386-y += hw/usb/hcd-ohci.c + check-qtest-i386-y += tests/usb-hcd-uhci-test$(EXESUF) + gcov-files-i386-y += hw/usb/hcd-uhci.c + check-qtest-i386-y += tests/usb-hcd-ehci-test$(EXESUF) +@@ -311,7 +311,7 @@ check-qtest-i386-y += tests/migration-test$(EXESUF) + check-qtest-i386-y += tests/test-x86-cpuid-compat$(EXESUF) + check-qtest-i386-y += tests/numa-test$(EXESUF) + check-qtest-x86_64-y += $(check-qtest-i386-y) +-check-qtest-x86_64-y += tests/sdhci-test$(EXESUF) ++#check-qtest-x86_64-y += tests/sdhci-test$(EXESUF) + gcov-files-i386-y += i386-softmmu/hw/timer/mc146818rtc.c + gcov-files-x86_64-y = $(subst i386-softmmu/,x86_64-softmmu/,$(gcov-files-i386-y)) + +@@ -332,34 +332,35 @@ check-qtest-mips64el-y = tests/endianness-test$(EXESUF) + check-qtest-moxie-y = tests/boot-serial-test$(EXESUF) + + check-qtest-ppc-y = tests/endianness-test$(EXESUF) +-check-qtest-ppc-y += tests/boot-order-test$(EXESUF) ++#check-qtest-ppc-y += tests/boot-order-test$(EXESUF) + check-qtest-ppc-y += tests/prom-env-test$(EXESUF) + check-qtest-ppc-y += tests/drive_del-test$(EXESUF) + check-qtest-ppc-y += tests/boot-serial-test$(EXESUF) +-check-qtest-ppc-y += tests/m48t59-test$(EXESUF) +-gcov-files-ppc-y += hw/timer/m48t59.c ++#check-qtest-ppc-y += tests/m48t59-test$(EXESUF) ++#gcov-files-ppc-y += hw/timer/m48t59.c + + check-qtest-ppc64-y = $(check-qtest-ppc-y) + gcov-files-ppc64-y = $(subst ppc-softmmu/,ppc64-softmmu/,$(gcov-files-ppc-y)) + check-qtest-ppc64-y += tests/spapr-phb-test$(EXESUF) + gcov-files-ppc64-y += ppc64-softmmu/hw/ppc/spapr_pci.c +-check-qtest-ppc64-y += tests/pnv-xscom-test$(EXESUF) ++#check-qtest-ppc64-y += tests/pnv-xscom-test$(EXESUF) + check-qtest-ppc64-y += tests/migration-test$(EXESUF) + check-qtest-ppc64-y += tests/rtas-test$(EXESUF) + check-qtest-ppc64-$(CONFIG_SLIRP) += tests/pxe-test$(EXESUF) +-check-qtest-ppc64-y += tests/usb-hcd-ohci-test$(EXESUF) +-gcov-files-ppc64-y += hw/usb/hcd-ohci.c +-check-qtest-ppc64-y += tests/usb-hcd-uhci-test$(EXESUF) +-gcov-files-ppc64-y += hw/usb/hcd-uhci.c ++#check-qtest-ppc64-y += tests/usb-hcd-ohci-test$(EXESUF) ++#gcov-files-ppc64-y += hw/usb/hcd-ohci.c ++#check-qtest-ppc64-y += tests/usb-hcd-uhci-test$(EXESUF) ++#gcov-files-ppc64-y += hw/usb/hcd-uhci.c + check-qtest-ppc64-y += tests/usb-hcd-xhci-test$(EXESUF) + gcov-files-ppc64-y += hw/usb/hcd-xhci.c + check-qtest-ppc64-y += $(check-qtest-virtio-y) +-check-qtest-ppc64-$(CONFIG_SLIRP) += tests/test-netfilter$(EXESUF) +-check-qtest-ppc64-$(CONFIG_POSIX) += tests/test-filter-mirror$(EXESUF) +-check-qtest-ppc64-$(CONFIG_POSIX) += tests/test-filter-redirector$(EXESUF) ++#check-qtest-ppc64-$(CONFIG_SLIRP) += tests/test-netfilter$(EXESUF) ++#check-qtest-ppc64-$(CONFIG_POSIX) += tests/test-filter-mirror$(EXESUF) ++#check-qtest-ppc64-$(CONFIG_POSIX) += tests/test-filter-redirector$(EXESUF) + check-qtest-ppc64-y += tests/display-vga-test$(EXESUF) + check-qtest-ppc64-y += tests/numa-test$(EXESUF) +-check-qtest-ppc64-$(CONFIG_IVSHMEM) += tests/ivshmem-test$(EXESUF) ++check-qtest-ppc64-$(CONFIG_IVSHMEM_DEVICE) += tests/ivshmem-test$(EXESUF) ++gcov-files-ppc64-$(CONFIG_IVSHMEM_DEVICE) += hw/misc/ivshmem.c + check-qtest-ppc64-y += tests/cpu-plug-test$(EXESUF) + + check-qtest-sh4-y = tests/endianness-test$(EXESUF) +@@ -388,7 +389,7 @@ check-qtest-arm-y += tests/boot-serial-test$(EXESUF) + check-qtest-arm-y += tests/sdhci-test$(EXESUF) + + check-qtest-aarch64-y = tests/numa-test$(EXESUF) +-check-qtest-aarch64-y += tests/sdhci-test$(EXESUF) ++#check-qtest-aarch64-y += tests/sdhci-test$(EXESUF) + check-qtest-aarch64-y += tests/boot-serial-test$(EXESUF) + + check-qtest-microblazeel-y = $(check-qtest-microblaze-y) +@@ -777,15 +778,15 @@ tests/endianness-test$(EXESUF): tests/endianness-test.o + tests/spapr-phb-test$(EXESUF): tests/spapr-phb-test.o $(libqos-obj-y) + tests/prom-env-test$(EXESUF): tests/prom-env-test.o $(libqos-obj-y) + tests/rtas-test$(EXESUF): tests/rtas-test.o $(libqos-spapr-obj-y) +-tests/fdc-test$(EXESUF): tests/fdc-test.o ++#tests/fdc-test$(EXESUF): tests/fdc-test.o + tests/ide-test$(EXESUF): tests/ide-test.o $(libqos-pc-obj-y) + tests/ahci-test$(EXESUF): tests/ahci-test.o $(libqos-pc-obj-y) +-tests/ipmi-kcs-test$(EXESUF): tests/ipmi-kcs-test.o +-tests/ipmi-bt-test$(EXESUF): tests/ipmi-bt-test.o ++#tests/ipmi-kcs-test$(EXESUF): tests/ipmi-kcs-test.o ++#tests/ipmi-bt-test$(EXESUF): tests/ipmi-bt-test.o + tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o + tests/boot-order-test$(EXESUF): tests/boot-order-test.o $(libqos-obj-y) + tests/boot-serial-test$(EXESUF): tests/boot-serial-test.o $(libqos-obj-y) +-tests/bios-tables-test$(EXESUF): tests/bios-tables-test.o \ ++#tests/bios-tables-test$(EXESUF): tests/bios-tables-test.o \ + tests/boot-sector.o tests/acpi-utils.o $(libqos-obj-y) + tests/pxe-test$(EXESUF): tests/pxe-test.o tests/boot-sector.o $(libqos-obj-y) + tests/tmp105-test$(EXESUF): tests/tmp105-test.o $(libqos-omap-obj-y) +@@ -798,11 +799,11 @@ tests/fw_cfg-test$(EXESUF): tests/fw_cfg-test.o $(libqos-pc-obj-y) + tests/e1000-test$(EXESUF): tests/e1000-test.o + tests/e1000e-test$(EXESUF): tests/e1000e-test.o $(libqos-pc-obj-y) + tests/rtl8139-test$(EXESUF): tests/rtl8139-test.o $(libqos-pc-obj-y) +-tests/pcnet-test$(EXESUF): tests/pcnet-test.o +-tests/pnv-xscom-test$(EXESUF): tests/pnv-xscom-test.o +-tests/eepro100-test$(EXESUF): tests/eepro100-test.o +-tests/vmxnet3-test$(EXESUF): tests/vmxnet3-test.o +-tests/ne2000-test$(EXESUF): tests/ne2000-test.o ++#tests/pcnet-test$(EXESUF): tests/pcnet-test.o ++#tests/pnv-xscom-test$(EXESUF): tests/pnv-xscom-test.o ++#tests/eepro100-test$(EXESUF): tests/eepro100-test.o ++#tests/vmxnet3-test$(EXESUF): tests/vmxnet3-test.o ++#tests/ne2000-test$(EXESUF): tests/ne2000-test.o + tests/wdt_ib700-test$(EXESUF): tests/wdt_ib700-test.o + tests/tco-test$(EXESUF): tests/tco-test.o $(libqos-pc-obj-y) + tests/virtio-balloon-test$(EXESUF): tests/virtio-balloon-test.o $(libqos-virtio-obj-y) +@@ -813,22 +814,22 @@ tests/virtio-scsi-test$(EXESUF): tests/virtio-scsi-test.o $(libqos-virtio-obj-y) + tests/virtio-9p-test$(EXESUF): tests/virtio-9p-test.o $(libqos-virtio-obj-y) + tests/virtio-serial-test$(EXESUF): tests/virtio-serial-test.o $(libqos-virtio-obj-y) + tests/virtio-console-test$(EXESUF): tests/virtio-console-test.o $(libqos-virtio-obj-y) +-tests/tpci200-test$(EXESUF): tests/tpci200-test.o ++#tests/tpci200-test$(EXESUF): tests/tpci200-test.o + tests/display-vga-test$(EXESUF): tests/display-vga-test.o +-tests/ipoctal232-test$(EXESUF): tests/ipoctal232-test.o ++#tests/ipoctal232-test$(EXESUF): tests/ipoctal232-test.o + tests/qom-test$(EXESUF): tests/qom-test.o + tests/test-hmp$(EXESUF): tests/test-hmp.o + tests/machine-none-test$(EXESUF): tests/machine-none-test.o + tests/drive_del-test$(EXESUF): tests/drive_del-test.o $(libqos-virtio-obj-y) + tests/qdev-monitor-test$(EXESUF): tests/qdev-monitor-test.o $(libqos-pc-obj-y) +-tests/nvme-test$(EXESUF): tests/nvme-test.o ++#tests/nvme-test$(EXESUF): tests/nvme-test.o + tests/pvpanic-test$(EXESUF): tests/pvpanic-test.o + tests/i82801b11-test$(EXESUF): tests/i82801b11-test.o + tests/ac97-test$(EXESUF): tests/ac97-test.o +-tests/es1370-test$(EXESUF): tests/es1370-test.o ++#tests/es1370-test$(EXESUF): tests/es1370-test.o + tests/intel-hda-test$(EXESUF): tests/intel-hda-test.o + tests/ioh3420-test$(EXESUF): tests/ioh3420-test.o +-tests/usb-hcd-ohci-test$(EXESUF): tests/usb-hcd-ohci-test.o $(libqos-usb-obj-y) ++#tests/usb-hcd-ohci-test$(EXESUF): tests/usb-hcd-ohci-test.o $(libqos-usb-obj-y) + tests/usb-hcd-uhci-test$(EXESUF): tests/usb-hcd-uhci-test.o $(libqos-usb-obj-y) + tests/usb-hcd-ehci-test$(EXESUF): tests/usb-hcd-ehci-test.o $(libqos-usb-obj-y) + tests/usb-hcd-xhci-test$(EXESUF): tests/usb-hcd-xhci-test.o $(libqos-usb-obj-y) +@@ -841,19 +842,19 @@ tests/qemu-iotests/socket_scm_helper$(EXESUF): tests/qemu-iotests/socket_scm_hel + tests/test-qemu-opts$(EXESUF): tests/test-qemu-opts.o $(test-util-obj-y) + tests/test-keyval$(EXESUF): tests/test-keyval.o $(test-util-obj-y) $(test-qapi-obj-y) + tests/test-write-threshold$(EXESUF): tests/test-write-threshold.o $(test-block-obj-y) +-tests/test-netfilter$(EXESUF): tests/test-netfilter.o $(qtest-obj-y) +-tests/test-filter-mirror$(EXESUF): tests/test-filter-mirror.o $(qtest-obj-y) +-tests/test-filter-redirector$(EXESUF): tests/test-filter-redirector.o $(qtest-obj-y) ++#tests/test-netfilter$(EXESUF): tests/test-netfilter.o $(qtest-obj-y) ++#tests/test-filter-mirror$(EXESUF): tests/test-filter-mirror.o $(qtest-obj-y) ++#tests/test-filter-redirector$(EXESUF): tests/test-filter-redirector.o $(qtest-obj-y) + tests/test-x86-cpuid-compat$(EXESUF): tests/test-x86-cpuid-compat.o $(qtest-obj-y) + tests/ivshmem-test$(EXESUF): tests/ivshmem-test.o contrib/ivshmem-server/ivshmem-server.o $(libqos-pc-obj-y) $(libqos-spapr-obj-y) +-tests/megasas-test$(EXESUF): tests/megasas-test.o $(libqos-spapr-obj-y) $(libqos-pc-obj-y) ++#tests/megasas-test$(EXESUF): tests/megasas-test.o $(libqos-spapr-obj-y) $(libqos-pc-obj-y) + tests/vhost-user-bridge$(EXESUF): tests/vhost-user-bridge.o $(test-util-obj-y) libvhost-user.a + tests/test-uuid$(EXESUF): tests/test-uuid.o $(test-util-obj-y) + tests/test-arm-mptimer$(EXESUF): tests/test-arm-mptimer.o + tests/test-qapi-util$(EXESUF): tests/test-qapi-util.o $(test-util-obj-y) + tests/numa-test$(EXESUF): tests/numa-test.o + tests/vmgenid-test$(EXESUF): tests/vmgenid-test.o tests/boot-sector.o tests/acpi-utils.o +-tests/sdhci-test$(EXESUF): tests/sdhci-test.o $(libqos-pc-obj-y) ++#tests/sdhci-test$(EXESUF): tests/sdhci-test.o $(libqos-pc-obj-y) + tests/cdrom-test$(EXESUF): tests/cdrom-test.o tests/boot-sector.o $(libqos-obj-y) + + tests/migration/stress$(EXESUF): tests/migration/stress.o +diff --git a/tests/boot-serial-test.c b/tests/boot-serial-test.c +index 952a2e7..5217a39 100644 +--- a/tests/boot-serial-test.c ++++ b/tests/boot-serial-test.c +@@ -80,17 +80,21 @@ static testdef_t tests[] = { + { "ppc", "g3beige", "", "PowerPC,750" }, + { "ppc", "mac99", "", "PowerPC,G4" }, + { "ppc", "sam460ex", "-m 256", "DRAM: 256 MiB" }, ++#if 0 /* Disabled for Red Hat Enterprise Linux */ + { "ppc64", "ppce500", "", "U-Boot" }, + { "ppc64", "prep", "-boot e", "Booting from device e" }, + { "ppc64", "40p", "-m 192", "Memory size: 192 MB" }, + { "ppc64", "mac99", "", "PowerPC,970FX" }, ++#endif + { "ppc64", "pseries", "", "Open Firmware" }, ++#if 0 /* Disabled for Red Hat Enterprise Linux */ + { "ppc64", "powernv", "-cpu POWER8", "OPAL" }, + { "ppc64", "sam460ex", "-device e1000", "8086 100e" }, ++#endif + { "i386", "isapc", "-cpu qemu32 -device sga", "SGABIOS" }, + { "i386", "pc", "-device sga", "SGABIOS" }, + { "i386", "q35", "-device sga", "SGABIOS" }, +- { "x86_64", "isapc", "-cpu qemu32 -device sga", "SGABIOS" }, ++ { "x86_64", "pc", "-cpu qemu32 -device sga", "SGABIOS" }, + { "x86_64", "q35", "-device sga", "SGABIOS" }, + { "sparc", "LX", "", "TMS390S10" }, + { "sparc", "SS-4", "", "MB86904" }, +diff --git a/tests/cpu-plug-test.c b/tests/cpu-plug-test.c +index 5f39ba0..48b8d09 100644 +--- a/tests/cpu-plug-test.c ++++ b/tests/cpu-plug-test.c +@@ -192,7 +192,8 @@ static void add_pseries_test_case(const char *mname) + PlugTestData *data; + + if (!g_str_has_prefix(mname, "pseries-") || +- (g_str_has_prefix(mname, "pseries-2.") && atoi(&mname[10]) < 7)) { ++ (g_str_has_prefix(mname, "pseries-2.") && atoi(&mname[10]) < 7) || ++ strcmp(mname,"pseries-rhel7.2.0") == 0) { + return; + } + data = g_new(PlugTestData, 1); +diff --git a/tests/e1000-test.c b/tests/e1000-test.c +index 0c5fcdc..b830432 100644 +--- a/tests/e1000-test.c ++++ b/tests/e1000-test.c +@@ -29,8 +29,10 @@ static void test_device(gconstpointer data) + static const char *models[] = { + "e1000", + "e1000-82540em", ++#if 0 /* Disabled for Red Hat Enterprise Linux */ + "e1000-82544gc", + "e1000-82545em", ++#endif + }; + + int main(int argc, char **argv) +diff --git a/tests/endianness-test.c b/tests/endianness-test.c +index 546e096..440353d 100644 +--- a/tests/endianness-test.c ++++ b/tests/endianness-test.c +@@ -37,10 +37,12 @@ static const TestCase test_cases[] = { + { "ppc", "g3beige", 0xfe000000, .bswap = true, .superio = "i82378" }, + { "ppc", "prep", 0x80000000, .bswap = true }, + { "ppc", "bamboo", 0xe8000000, .bswap = true, .superio = "i82378" }, ++#if 0 /* Disabled for RHEL, since ISA is not enabled */ + { "ppc64", "mac99", 0xf2000000, .bswap = true, .superio = "i82378" }, + { "ppc64", "pseries", (1ULL << 45), .bswap = true, .superio = "i82378" }, + { "ppc64", "pseries-2.7", 0x10080000000ULL, + .bswap = true, .superio = "i82378" }, ++#endif /* Disabled for RHEL, since ISA is not enabled */ + { "sh4", "r2d", 0xfe240000, .superio = "i82378" }, + { "sh4eb", "r2d", 0xfe240000, .bswap = true, .superio = "i82378" }, + { "sparc64", "sun4u", 0x1fe02000000LL, .bswap = true }, +diff --git a/tests/prom-env-test.c b/tests/prom-env-test.c +index 8c867e6..cc9b6ec 100644 +--- a/tests/prom-env-test.c ++++ b/tests/prom-env-test.c +@@ -82,7 +82,9 @@ int main(int argc, char *argv[]) + if (!strcmp(arch, "ppc")) { + add_tests(ppc_machines); + } else if (!strcmp(arch, "ppc64")) { ++#if 0 /* Disabled for Red Hat Enterprise Linux */ + add_tests(ppc_machines); ++#endif + if (g_test_slow()) { + qtest_add_data_func("prom-env/pseries", "pseries", test_machine); + } +diff --git a/tests/qemu-iotests/051 b/tests/qemu-iotests/051 +index ee9c820..c5cc0ee 100755 +--- a/tests/qemu-iotests/051 ++++ b/tests/qemu-iotests/051 +@@ -183,11 +183,11 @@ run_qemu -drive if=virtio + case "$QEMU_DEFAULT_MACHINE" in + pc) + run_qemu -drive if=none,id=disk -device ide-cd,drive=disk +- run_qemu -drive if=none,id=disk -device lsi53c895a -device scsi-cd,drive=disk ++# run_qemu -drive if=none,id=disk -device lsi53c895a -device scsi-cd,drive=disk + run_qemu -drive if=none,id=disk -device ide-drive,drive=disk + run_qemu -drive if=none,id=disk -device ide-hd,drive=disk +- run_qemu -drive if=none,id=disk -device lsi53c895a -device scsi-disk,drive=disk +- run_qemu -drive if=none,id=disk -device lsi53c895a -device scsi-hd,drive=disk ++# run_qemu -drive if=none,id=disk -device lsi53c895a -device scsi-disk,drive=disk ++# run_qemu -drive if=none,id=disk -device lsi53c895a -device scsi-hd,drive=disk + ;; + *) + ;; +@@ -212,11 +212,11 @@ run_qemu -drive file="$TEST_IMG",if=virtio,readonly=on + case "$QEMU_DEFAULT_MACHINE" in + pc) + run_qemu -drive file="$TEST_IMG",if=none,id=disk,readonly=on -device ide-cd,drive=disk +- run_qemu -drive file="$TEST_IMG",if=none,id=disk,readonly=on -device lsi53c895a -device scsi-cd,drive=disk ++# run_qemu -drive file="$TEST_IMG",if=none,id=disk,readonly=on -device lsi53c895a -device scsi-cd,drive=disk + run_qemu -drive file="$TEST_IMG",if=none,id=disk,readonly=on -device ide-drive,drive=disk + run_qemu -drive file="$TEST_IMG",if=none,id=disk,readonly=on -device ide-hd,drive=disk +- run_qemu -drive file="$TEST_IMG",if=none,id=disk,readonly=on -device lsi53c895a -device scsi-disk,drive=disk +- run_qemu -drive file="$TEST_IMG",if=none,id=disk,readonly=on -device lsi53c895a -device scsi-hd,drive=disk ++# run_qemu -drive file="$TEST_IMG",if=none,id=disk,readonly=on -device lsi53c895a -device scsi-disk,drive=disk ++# run_qemu -drive file="$TEST_IMG",if=none,id=disk,readonly=on -device lsi53c895a -device scsi-hd,drive=disk + ;; + *) + ;; +diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group +index b973dc8..f1059f6 100644 +--- a/tests/qemu-iotests/group ++++ b/tests/qemu-iotests/group +@@ -77,7 +77,7 @@ + 068 rw auto quick + 069 rw auto quick + 070 rw auto quick +-071 rw auto quick ++# 071 rw auto quick -- requires whitelisted blkverify + 072 rw auto quick + 073 rw auto quick + 074 rw auto quick +@@ -105,7 +105,7 @@ + 096 rw auto quick + 097 rw auto backing + 098 rw auto backing quick +-099 rw auto quick ++# 099 rw auto quick -- requires whitelisted blkverify + # 100 was removed, do not reuse + 101 rw auto quick + 102 rw auto quick +diff --git a/tests/qom-test.c b/tests/qom-test.c +index e6f712c..ebd15fd 100644 +--- a/tests/qom-test.c ++++ b/tests/qom-test.c +@@ -16,7 +16,7 @@ + #include "libqtest.h" + + static const char *blacklist_x86[] = { +- "xenfv", "xenpv", NULL ++ "xenfv", "xenpv", "isapc", NULL + }; + + static const struct { +diff --git a/tests/test-x86-cpuid-compat.c b/tests/test-x86-cpuid-compat.c +index 84ce9c7..c1ee197 100644 +--- a/tests/test-x86-cpuid-compat.c ++++ b/tests/test-x86-cpuid-compat.c +@@ -306,6 +306,7 @@ int main(int argc, char **argv) + "-cpu 486,xlevel2=0xC0000002,+xstore", + "xlevel2", 0xC0000002); + ++#if 0 /* Disabled in Red Hat Enterprise Linux */ + /* Check compatibility of old machine-types that didn't + * auto-increase level/xlevel/xlevel2: */ + +@@ -356,6 +357,7 @@ int main(int argc, char **argv) + add_cpuid_test("x86/cpuid/xlevel-compat/pc-i440fx-2.4/npt-on", + "-machine pc-i440fx-2.4 -cpu SandyBridge,+npt", + "xlevel", 0x80000008); ++#endif + + /* Test feature parsing */ + add_feature_test("x86/cpuid/features/plus", +diff --git a/tests/usb-hcd-xhci-test.c b/tests/usb-hcd-xhci-test.c +index 5b1b681..85fa150 100644 +--- a/tests/usb-hcd-xhci-test.c ++++ b/tests/usb-hcd-xhci-test.c +@@ -21,6 +21,7 @@ static void test_xhci_hotplug(void) + usb_test_hotplug("xhci", 1, NULL); + } + ++#if 0 /* Disabled for Red Hat Enterprise Linux */ + static void test_usb_uas_hotplug(void) + { + qtest_qmp_device_add("usb-uas", "uas", NULL); +@@ -34,6 +35,7 @@ static void test_usb_uas_hotplug(void) + qtest_qmp_device_del("scsihd"); + qtest_qmp_device_del("uas"); + } ++#endif + + static void test_usb_ccid_hotplug(void) + { +@@ -52,7 +54,9 @@ int main(int argc, char **argv) + + qtest_add_func("/xhci/pci/init", test_xhci_init); + qtest_add_func("/xhci/pci/hotplug", test_xhci_hotplug); ++#if 0 /* Disabled for Red Hat Enterprise Linux */ + qtest_add_func("/xhci/pci/hotplug/usb-uas", test_usb_uas_hotplug); ++#endif + qtest_add_func("/xhci/pci/hotplug/usb-ccid", test_usb_ccid_hotplug); + + qtest_start("-device nec-usb-xhci,id=xhci" +-- +1.8.3.1 + diff --git a/0004-Use-kvm-by-default.patch b/0012-Use-kvm-by-default.patch similarity index 92% rename from 0004-Use-kvm-by-default.patch rename to 0012-Use-kvm-by-default.patch index f19a64e..d6e2835 100644 --- a/0004-Use-kvm-by-default.patch +++ b/0012-Use-kvm-by-default.patch @@ -1,4 +1,4 @@ -From 5a441b820faa4e6e9e6fc80cccc813a3c333b6c2 Mon Sep 17 00:00:00 2001 +From ce4cd21e28e1511e056877e3cc8dcf6f0b8c7baa Mon Sep 17 00:00:00 2001 From: Miroslav Rezanina Date: Thu, 18 Dec 2014 06:27:49 +0100 Subject: Use kvm by default diff --git a/0005-vfio-cap-number-of-devices-that-can-be-assigned.patch b/0013-vfio-cap-number-of-devices-that-can-be-assigned.patch similarity index 96% rename from 0005-vfio-cap-number-of-devices-that-can-be-assigned.patch rename to 0013-vfio-cap-number-of-devices-that-can-be-assigned.patch index 0d40ae5..9e22d48 100644 --- a/0005-vfio-cap-number-of-devices-that-can-be-assigned.patch +++ b/0013-vfio-cap-number-of-devices-that-can-be-assigned.patch @@ -1,4 +1,4 @@ -From 0c57186334ab4ef7f04de604a8f13b39ad6578c8 Mon Sep 17 00:00:00 2001 +From 43a09e06e76cba94c6ecd448f51912362b42f94d Mon Sep 17 00:00:00 2001 From: Bandan Das Date: Tue, 3 Dec 2013 20:05:13 +0100 Subject: vfio: cap number of devices that can be assigned diff --git a/0006-Add-support-statement-to-help-output.patch b/0014-Add-support-statement-to-help-output.patch similarity index 96% rename from 0006-Add-support-statement-to-help-output.patch rename to 0014-Add-support-statement-to-help-output.patch index b6ecf11..ea0d9ea 100644 --- a/0006-Add-support-statement-to-help-output.patch +++ b/0014-Add-support-statement-to-help-output.patch @@ -1,4 +1,4 @@ -From c2858d09461c6f69553e8b9d69804f243c2d08bb Mon Sep 17 00:00:00 2001 +From f8e7911bb97eb942a4eadad1731b7c59c43fd2eb Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Wed, 4 Dec 2013 18:53:17 +0100 Subject: Add support statement to -help output diff --git a/0007-globally-limit-the-maximum-number-of-CPUs.patch b/0015-globally-limit-the-maximum-number-of-CPUs.patch similarity index 97% rename from 0007-globally-limit-the-maximum-number-of-CPUs.patch rename to 0015-globally-limit-the-maximum-number-of-CPUs.patch index b8af753..3543fec 100644 --- a/0007-globally-limit-the-maximum-number-of-CPUs.patch +++ b/0015-globally-limit-the-maximum-number-of-CPUs.patch @@ -1,4 +1,4 @@ -From 36dda20ae7312b1db0b4060bb2420ab18e5f5483 Mon Sep 17 00:00:00 2001 +From 8413778453742aeb3ad6b38d5f4440a0dbabca7d Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 21 Jan 2014 10:46:52 +0100 Subject: globally limit the maximum number of CPUs diff --git a/0008-Add-support-for-simpletrace.patch b/0016-Add-support-for-simpletrace.patch similarity index 98% rename from 0008-Add-support-for-simpletrace.patch rename to 0016-Add-support-for-simpletrace.patch index 2c660b8..4b945c5 100644 --- a/0008-Add-support-for-simpletrace.patch +++ b/0016-Add-support-for-simpletrace.patch @@ -1,4 +1,4 @@ -From 84763026a2e71d7b9f7fc9249ba25771724c272d Mon Sep 17 00:00:00 2001 +From f262acdee88f36b625fcbd5eb1cd66739428cca3 Mon Sep 17 00:00:00 2001 From: Miroslav Rezanina Date: Thu, 8 Oct 2015 09:50:17 +0200 Subject: Add support for simpletrace diff --git a/0009-Use-qemu-kvm-in-documentation-instead-of-qemu-system.patch b/0017-Use-qemu-kvm-in-documentation-instead-of-qemu-system.patch similarity index 99% rename from 0009-Use-qemu-kvm-in-documentation-instead-of-qemu-system.patch rename to 0017-Use-qemu-kvm-in-documentation-instead-of-qemu-system.patch index 93e2343..aca5827 100644 --- a/0009-Use-qemu-kvm-in-documentation-instead-of-qemu-system.patch +++ b/0017-Use-qemu-kvm-in-documentation-instead-of-qemu-system.patch @@ -1,4 +1,4 @@ -From 7f5450ae0077f13427a54bd2868c1986284839d2 Mon Sep 17 00:00:00 2001 +From 33e2c01c1b0b64a76d5193b60378d2329a86626b Mon Sep 17 00:00:00 2001 From: Miroslav Rezanina Date: Fri, 14 Nov 2014 08:51:50 +0100 Subject: Use qemu-kvm in documentation instead of qemu-system- diff --git a/0010-usb-xhci-Fix-PCI-capability-order.patch b/0018-usb-xhci-Fix-PCI-capability-order.patch similarity index 97% rename from 0010-usb-xhci-Fix-PCI-capability-order.patch rename to 0018-usb-xhci-Fix-PCI-capability-order.patch index a3e6795..a44ef20 100644 --- a/0010-usb-xhci-Fix-PCI-capability-order.patch +++ b/0018-usb-xhci-Fix-PCI-capability-order.patch @@ -1,4 +1,4 @@ -From 268966c530da2d8e07e2c9034a82acd01335e2c2 Mon Sep 17 00:00:00 2001 +From 69912b533a88bda6377292231fb94475a674a90d Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Fri, 5 May 2017 19:06:14 +0200 Subject: usb-xhci: Fix PCI capability order diff --git a/0011-virtio-scsi-Reject-scsi-cd-if-data-plane-enabled-RHE.patch b/0019-virtio-scsi-Reject-scsi-cd-if-data-plane-enabled-RHE.patch similarity index 97% rename from 0011-virtio-scsi-Reject-scsi-cd-if-data-plane-enabled-RHE.patch rename to 0019-virtio-scsi-Reject-scsi-cd-if-data-plane-enabled-RHE.patch index 886de8e..e5e93ce 100644 --- a/0011-virtio-scsi-Reject-scsi-cd-if-data-plane-enabled-RHE.patch +++ b/0019-virtio-scsi-Reject-scsi-cd-if-data-plane-enabled-RHE.patch @@ -1,4 +1,4 @@ -From 126cb3f3717b266f27dc7c657da833779f9f3b54 Mon Sep 17 00:00:00 2001 +From a883dbcc1c55cab189ff4a48cbdd12c4b4246b9c Mon Sep 17 00:00:00 2001 From: Fam Zheng Date: Wed, 14 Jun 2017 15:37:01 +0200 Subject: virtio-scsi: Reject scsi-cd if data plane enabled [RHEL only] diff --git a/0012-linux-headers-asm-s390-kvm.h-header-sync.patch b/0020-linux-headers-asm-s390-kvm.h-header-sync.patch similarity index 97% rename from 0012-linux-headers-asm-s390-kvm.h-header-sync.patch rename to 0020-linux-headers-asm-s390-kvm.h-header-sync.patch index c0b4e09..cb0ee04 100644 --- a/0012-linux-headers-asm-s390-kvm.h-header-sync.patch +++ b/0020-linux-headers-asm-s390-kvm.h-header-sync.patch @@ -1,4 +1,4 @@ -From 811173cac3e80b6235de885b7b2ec4f9be3b4e31 Mon Sep 17 00:00:00 2001 +From f3d0b355f946ab87b281ef75ebfb52f7b7592f2a Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Thu, 9 Aug 2018 10:15:08 +0000 Subject: linux-headers: asm-s390/kvm.h header sync diff --git a/0013-s390x-Enable-KVM-huge-page-backing-support.patch b/0021-s390x-Enable-KVM-huge-page-backing-support.patch similarity index 98% rename from 0013-s390x-Enable-KVM-huge-page-backing-support.patch rename to 0021-s390x-Enable-KVM-huge-page-backing-support.patch index 926fb13..636c94d 100644 --- a/0013-s390x-Enable-KVM-huge-page-backing-support.patch +++ b/0021-s390x-Enable-KVM-huge-page-backing-support.patch @@ -1,4 +1,4 @@ -From fa8eda01f21298e6bc50abb78775390b4bf3f954 Mon Sep 17 00:00:00 2001 +From 3b4526245dcb2daad3a6393b6b129f85f9e2c7a2 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Mon, 6 Aug 2018 14:18:41 +0100 Subject: s390x: Enable KVM huge page backing support diff --git a/0014-s390x-kvm-add-etoken-facility.patch b/0022-s390x-kvm-add-etoken-facility.patch similarity index 99% rename from 0014-s390x-kvm-add-etoken-facility.patch rename to 0022-s390x-kvm-add-etoken-facility.patch index e035dbc..d56ba50 100644 --- a/0014-s390x-kvm-add-etoken-facility.patch +++ b/0022-s390x-kvm-add-etoken-facility.patch @@ -1,4 +1,4 @@ -From 4b36866031e559bc895e64ecb20417323cb03e3d Mon Sep 17 00:00:00 2001 +From 8eacbf0e8e26b2a8aa3de955a57a7a3cb680d922 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Thu, 9 Aug 2018 10:15:09 +0000 Subject: s390x/kvm: add etoken facility diff --git a/0015-s390x-cpumodel-default-enable-bpb-and-ppa15-for-z196.patch b/0023-s390x-cpumodel-default-enable-bpb-and-ppa15-for-z196.patch similarity index 96% rename from 0015-s390x-cpumodel-default-enable-bpb-and-ppa15-for-z196.patch rename to 0023-s390x-cpumodel-default-enable-bpb-and-ppa15-for-z196.patch index 988124d..01227d7 100644 --- a/0015-s390x-cpumodel-default-enable-bpb-and-ppa15-for-z196.patch +++ b/0023-s390x-cpumodel-default-enable-bpb-and-ppa15-for-z196.patch @@ -1,4 +1,4 @@ -From 79d0599b21b64f8a8107855e844b347d2cc138d9 Mon Sep 17 00:00:00 2001 +From 29df663d045345a8c498dc3966cc59dcf091a50d Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Tue, 7 Aug 2018 09:05:54 +0000 Subject: s390x/cpumodel: default enable bpb and ppa15 for z196 and later diff --git a/0016-i386-Fix-arch_query_cpu_model_expansion-leak.patch b/0024-i386-Fix-arch_query_cpu_model_expansion-leak.patch similarity index 98% rename from 0016-i386-Fix-arch_query_cpu_model_expansion-leak.patch rename to 0024-i386-Fix-arch_query_cpu_model_expansion-leak.patch index 5bed305..e2570c5 100644 --- a/0016-i386-Fix-arch_query_cpu_model_expansion-leak.patch +++ b/0024-i386-Fix-arch_query_cpu_model_expansion-leak.patch @@ -1,4 +1,4 @@ -From 786fb991b644eddb9f52fd04d377cc7a62685d59 Mon Sep 17 00:00:00 2001 +From 43b08a1e4bc47d810212f569cc0fc30eebfd7036 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Fri, 31 Aug 2018 13:59:22 +0100 Subject: i386: Fix arch_query_cpu_model_expansion() leak diff --git a/0017-i386-Disable-TOPOEXT-by-default-on-cpu-host.patch b/0025-i386-Disable-TOPOEXT-by-default-on-cpu-host.patch similarity index 96% rename from 0017-i386-Disable-TOPOEXT-by-default-on-cpu-host.patch rename to 0025-i386-Disable-TOPOEXT-by-default-on-cpu-host.patch index a731164..12692e8 100644 --- a/0017-i386-Disable-TOPOEXT-by-default-on-cpu-host.patch +++ b/0025-i386-Disable-TOPOEXT-by-default-on-cpu-host.patch @@ -1,4 +1,4 @@ -From 25abf99ebc7004999e79fa5e5b1370e4dfdaeed2 Mon Sep 17 00:00:00 2001 +From 628b10cd4d5cd8fde97dab66f143db78fe03398a Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Tue, 21 Aug 2018 19:15:41 +0100 Subject: i386: Disable TOPOEXT by default on "-cpu host" diff --git a/0018-curl-Make-sslverify-off-disable-host-as-well-as-peer.patch b/0026-curl-Make-sslverify-off-disable-host-as-well-as-peer.patch similarity index 98% rename from 0018-curl-Make-sslverify-off-disable-host-as-well-as-peer.patch rename to 0026-curl-Make-sslverify-off-disable-host-as-well-as-peer.patch index fc5784f..3f2736c 100644 --- a/0018-curl-Make-sslverify-off-disable-host-as-well-as-peer.patch +++ b/0026-curl-Make-sslverify-off-disable-host-as-well-as-peer.patch @@ -1,4 +1,4 @@ -From 49d4861ffc56cb233dacc1abcb2a5ec608e599ab Mon Sep 17 00:00:00 2001 +From 1ed2bb0d831983b68bcdecd057c2c5bfd419c304 Mon Sep 17 00:00:00 2001 From: Jeffrey Cody Date: Wed, 26 Sep 2018 04:08:14 +0100 Subject: curl: Make sslverify=off disable host as well as peer verification. diff --git a/0019-migration-postcopy-Clear-have_listen_thread.patch b/0027-migration-postcopy-Clear-have_listen_thread.patch similarity index 96% rename from 0019-migration-postcopy-Clear-have_listen_thread.patch rename to 0027-migration-postcopy-Clear-have_listen_thread.patch index f220ad4..86157d9 100644 --- a/0019-migration-postcopy-Clear-have_listen_thread.patch +++ b/0027-migration-postcopy-Clear-have_listen_thread.patch @@ -1,4 +1,4 @@ -From 324493e716a2e5fa60b6b013d5df831b03f2a678 Mon Sep 17 00:00:00 2001 +From 096b7abf1d2755ad469e4bcb3dc6302021979814 Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Mon, 1 Oct 2018 10:54:48 +0100 Subject: migration/postcopy: Clear have_listen_thread diff --git a/0020-migration-cleanup-in-error-paths-in-loadvm.patch b/0028-migration-cleanup-in-error-paths-in-loadvm.patch similarity index 96% rename from 0020-migration-cleanup-in-error-paths-in-loadvm.patch rename to 0028-migration-cleanup-in-error-paths-in-loadvm.patch index a0fea63..f576c82 100644 --- a/0020-migration-cleanup-in-error-paths-in-loadvm.patch +++ b/0028-migration-cleanup-in-error-paths-in-loadvm.patch @@ -1,4 +1,4 @@ -From 005c4cb023ffdcb8888c7453d263cab95d5b1b1c Mon Sep 17 00:00:00 2001 +From bff052b89b0c32c179d858bd8eed91e0d9f98db4 Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Mon, 1 Oct 2018 10:54:49 +0100 Subject: migration: cleanup in error paths in loadvm diff --git a/0021-jobs-change-start-callback-to-run-callback.patch b/0029-jobs-change-start-callback-to-run-callback.patch similarity index 99% rename from 0021-jobs-change-start-callback-to-run-callback.patch rename to 0029-jobs-change-start-callback-to-run-callback.patch index 93e8b27..0955ee2 100644 --- a/0021-jobs-change-start-callback-to-run-callback.patch +++ b/0029-jobs-change-start-callback-to-run-callback.patch @@ -1,4 +1,4 @@ -From 287cb50c08d64773470732be8a6a566bcdde4b75 Mon Sep 17 00:00:00 2001 +From 2999207ffd4de9f139922b444edba07b051d4a67 Mon Sep 17 00:00:00 2001 From: John Snow Date: Tue, 25 Sep 2018 22:34:07 +0100 Subject: jobs: change start callback to run callback diff --git a/0022-jobs-canonize-Error-object.patch b/0030-jobs-canonize-Error-object.patch similarity index 99% rename from 0022-jobs-canonize-Error-object.patch rename to 0030-jobs-canonize-Error-object.patch index ba09278..92dc0b8 100644 --- a/0022-jobs-canonize-Error-object.patch +++ b/0030-jobs-canonize-Error-object.patch @@ -1,4 +1,4 @@ -From 9dff1ec5bdde5e8bd8745d2e0697cc6e28c87214 Mon Sep 17 00:00:00 2001 +From df9702d737eea1720a10d350c24bdcc3f54bcba9 Mon Sep 17 00:00:00 2001 From: John Snow Date: Wed, 29 Aug 2018 21:57:27 -0400 Subject: jobs: canonize Error object diff --git a/0023-jobs-add-exit-shim.patch b/0031-jobs-add-exit-shim.patch similarity index 98% rename from 0023-jobs-add-exit-shim.patch rename to 0031-jobs-add-exit-shim.patch index e8493e5..2a0ccb0 100644 --- a/0023-jobs-add-exit-shim.patch +++ b/0031-jobs-add-exit-shim.patch @@ -1,4 +1,4 @@ -From 29ae3509885eaa6d24ee82aa4cae47ddeda086db Mon Sep 17 00:00:00 2001 +From 17511eb281e005da6e617acd12c81a0a1fa1771d Mon Sep 17 00:00:00 2001 From: John Snow Date: Tue, 25 Sep 2018 22:34:09 +0100 Subject: jobs: add exit shim diff --git a/0024-block-commit-utilize-job_exit-shim.patch b/0032-block-commit-utilize-job_exit-shim.patch similarity index 98% rename from 0024-block-commit-utilize-job_exit-shim.patch rename to 0032-block-commit-utilize-job_exit-shim.patch index 2d4e3b9..3994481 100644 --- a/0024-block-commit-utilize-job_exit-shim.patch +++ b/0032-block-commit-utilize-job_exit-shim.patch @@ -1,4 +1,4 @@ -From 2207ab7e71d5d3c3806d60b3f483988a62566292 Mon Sep 17 00:00:00 2001 +From 912e8eaa87f8dab40466cf0d45c3290d02e6a9d5 Mon Sep 17 00:00:00 2001 From: John Snow Date: Tue, 25 Sep 2018 22:34:10 +0100 Subject: block/commit: utilize job_exit shim diff --git a/0025-block-mirror-utilize-job_exit-shim.patch b/0033-block-mirror-utilize-job_exit-shim.patch similarity index 98% rename from 0025-block-mirror-utilize-job_exit-shim.patch rename to 0033-block-mirror-utilize-job_exit-shim.patch index 833eead..65eb25a 100644 --- a/0025-block-mirror-utilize-job_exit-shim.patch +++ b/0033-block-mirror-utilize-job_exit-shim.patch @@ -1,4 +1,4 @@ -From f96869810df10ac28030a31d8cb1e39825133e94 Mon Sep 17 00:00:00 2001 +From 2322917770da98e175e7ae8bf0bb1a624ec3cebc Mon Sep 17 00:00:00 2001 From: John Snow Date: Wed, 29 Aug 2018 21:57:30 -0400 Subject: block/mirror: utilize job_exit shim diff --git a/0026-jobs-utilize-job_exit-shim.patch b/0034-jobs-utilize-job_exit-shim.patch similarity index 99% rename from 0026-jobs-utilize-job_exit-shim.patch rename to 0034-jobs-utilize-job_exit-shim.patch index d5ca8e5..8b765d8 100644 --- a/0026-jobs-utilize-job_exit-shim.patch +++ b/0034-jobs-utilize-job_exit-shim.patch @@ -1,4 +1,4 @@ -From 5947e8781d9dffb069fcc570402f775f80068e63 Mon Sep 17 00:00:00 2001 +From 83d2840eeadd8a55b796eae5454783d42913963c Mon Sep 17 00:00:00 2001 From: John Snow Date: Tue, 25 Sep 2018 22:34:12 +0100 Subject: jobs: utilize job_exit shim diff --git a/0027-block-backup-make-function-variables-consistently-na.patch b/0035-block-backup-make-function-variables-consistently-na.patch similarity index 99% rename from 0027-block-backup-make-function-variables-consistently-na.patch rename to 0035-block-backup-make-function-variables-consistently-na.patch index 2923dac..ab0af70 100644 --- a/0027-block-backup-make-function-variables-consistently-na.patch +++ b/0035-block-backup-make-function-variables-consistently-na.patch @@ -1,4 +1,4 @@ -From 3e86b802541a7230eda88a6bd7f17b411deab9fa Mon Sep 17 00:00:00 2001 +From b5532575bb8aa748dc066834d7ac150bbb6575a7 Mon Sep 17 00:00:00 2001 From: John Snow Date: Tue, 25 Sep 2018 22:34:13 +0100 Subject: block/backup: make function variables consistently named diff --git a/0028-jobs-remove-ret-argument-to-job_completed-privatize-.patch b/0036-jobs-remove-ret-argument-to-job_completed-privatize-.patch similarity index 98% rename from 0028-jobs-remove-ret-argument-to-job_completed-privatize-.patch rename to 0036-jobs-remove-ret-argument-to-job_completed-privatize-.patch index 070c907..6d2791c 100644 --- a/0028-jobs-remove-ret-argument-to-job_completed-privatize-.patch +++ b/0036-jobs-remove-ret-argument-to-job_completed-privatize-.patch @@ -1,4 +1,4 @@ -From 3141614c15fbcf6aee7af19069380aa6d186656b Mon Sep 17 00:00:00 2001 +From 7fe6d53387852907871d82997fbccc2cf774bdb4 Mon Sep 17 00:00:00 2001 From: John Snow Date: Tue, 25 Sep 2018 22:34:14 +0100 Subject: jobs: remove ret argument to job_completed; privatize it diff --git a/0029-jobs-remove-job_defer_to_main_loop.patch b/0037-jobs-remove-job_defer_to_main_loop.patch similarity index 98% rename from 0029-jobs-remove-job_defer_to_main_loop.patch rename to 0037-jobs-remove-job_defer_to_main_loop.patch index 3c302ce..2b0fec4 100644 --- a/0029-jobs-remove-job_defer_to_main_loop.patch +++ b/0037-jobs-remove-job_defer_to_main_loop.patch @@ -1,4 +1,4 @@ -From 73694b41a7e96fb364bdfd6fbad89c69dc2d1f73 Mon Sep 17 00:00:00 2001 +From 1827993a08cc8c86cc40ca9ccb7ef668261b2bc4 Mon Sep 17 00:00:00 2001 From: John Snow Date: Tue, 25 Sep 2018 22:34:15 +0100 Subject: jobs: remove job_defer_to_main_loop diff --git a/0030-block-commit-add-block-job-creation-flags.patch b/0038-block-commit-add-block-job-creation-flags.patch similarity index 98% rename from 0030-block-commit-add-block-job-creation-flags.patch rename to 0038-block-commit-add-block-job-creation-flags.patch index 315a78f..b145fc1 100644 --- a/0030-block-commit-add-block-job-creation-flags.patch +++ b/0038-block-commit-add-block-job-creation-flags.patch @@ -1,4 +1,4 @@ -From 8141d5f8ab70551c59fae63373a9562c99c8e00d Mon Sep 17 00:00:00 2001 +From 6c8da2ba018d7546a15c3917f52ad1cc2b5b133c Mon Sep 17 00:00:00 2001 From: John Snow Date: Tue, 25 Sep 2018 22:34:16 +0100 Subject: block/commit: add block job creation flags diff --git a/0031-block-mirror-add-block-job-creation-flags.patch b/0039-block-mirror-add-block-job-creation-flags.patch similarity index 98% rename from 0031-block-mirror-add-block-job-creation-flags.patch rename to 0039-block-mirror-add-block-job-creation-flags.patch index 088c370..fec813e 100644 --- a/0031-block-mirror-add-block-job-creation-flags.patch +++ b/0039-block-mirror-add-block-job-creation-flags.patch @@ -1,4 +1,4 @@ -From 8ac0fb4e4202e6321d57f1be01f4ca6e51a98687 Mon Sep 17 00:00:00 2001 +From d4f6cfe194df3236bf53b1093e0a7f98f0a5da0e Mon Sep 17 00:00:00 2001 From: John Snow Date: Tue, 25 Sep 2018 22:34:17 +0100 Subject: block/mirror: add block job creation flags diff --git a/0032-block-stream-add-block-job-creation-flags.patch b/0040-block-stream-add-block-job-creation-flags.patch similarity index 98% rename from 0032-block-stream-add-block-job-creation-flags.patch rename to 0040-block-stream-add-block-job-creation-flags.patch index 1dda670..224be80 100644 --- a/0032-block-stream-add-block-job-creation-flags.patch +++ b/0040-block-stream-add-block-job-creation-flags.patch @@ -1,4 +1,4 @@ -From 64569465b360642820193586116aa51ed0b356bd Mon Sep 17 00:00:00 2001 +From 4fd98648eb0df8157c1238a1cee36373278d44a5 Mon Sep 17 00:00:00 2001 From: John Snow Date: Tue, 25 Sep 2018 22:34:18 +0100 Subject: block/stream: add block job creation flags diff --git a/0033-block-commit-refactor-commit-to-use-job-callbacks.patch b/0041-block-commit-refactor-commit-to-use-job-callbacks.patch similarity index 99% rename from 0033-block-commit-refactor-commit-to-use-job-callbacks.patch rename to 0041-block-commit-refactor-commit-to-use-job-callbacks.patch index 2a5f69b..212513e 100644 --- a/0033-block-commit-refactor-commit-to-use-job-callbacks.patch +++ b/0041-block-commit-refactor-commit-to-use-job-callbacks.patch @@ -1,4 +1,4 @@ -From b0ac95edde586e808a1118c4b04c1608de8b5b6c Mon Sep 17 00:00:00 2001 +From b0b7d48f97dd97efacf93e5529d7597bd2280095 Mon Sep 17 00:00:00 2001 From: John Snow Date: Tue, 25 Sep 2018 22:34:19 +0100 Subject: block/commit: refactor commit to use job callbacks diff --git a/0034-block-mirror-don-t-install-backing-chain-on-abort.patch b/0042-block-mirror-don-t-install-backing-chain-on-abort.patch similarity index 96% rename from 0034-block-mirror-don-t-install-backing-chain-on-abort.patch rename to 0042-block-mirror-don-t-install-backing-chain-on-abort.patch index 241ae5f..8a2f14f 100644 --- a/0034-block-mirror-don-t-install-backing-chain-on-abort.patch +++ b/0042-block-mirror-don-t-install-backing-chain-on-abort.patch @@ -1,4 +1,4 @@ -From 7f155f96e9db0be97501f90e482a29d51779f887 Mon Sep 17 00:00:00 2001 +From e849bf276e59b282f3288b42abe9d6dff51dc678 Mon Sep 17 00:00:00 2001 From: John Snow Date: Tue, 25 Sep 2018 22:34:20 +0100 Subject: block/mirror: don't install backing chain on abort diff --git a/0035-block-mirror-conservative-mirror_exit-refactor.patch b/0043-block-mirror-conservative-mirror_exit-refactor.patch similarity index 98% rename from 0035-block-mirror-conservative-mirror_exit-refactor.patch rename to 0043-block-mirror-conservative-mirror_exit-refactor.patch index 1c34fec..b964981 100644 --- a/0035-block-mirror-conservative-mirror_exit-refactor.patch +++ b/0043-block-mirror-conservative-mirror_exit-refactor.patch @@ -1,4 +1,4 @@ -From 8b394ff523e607060c80c6b647dbb89a2f73571d Mon Sep 17 00:00:00 2001 +From 430c298d6bf9a7c8b90ad30bc2cd445e5cd6dd50 Mon Sep 17 00:00:00 2001 From: John Snow Date: Thu, 6 Sep 2018 09:02:15 -0400 Subject: block/mirror: conservative mirror_exit refactor diff --git a/0036-block-stream-refactor-stream-to-use-job-callbacks.patch b/0044-block-stream-refactor-stream-to-use-job-callbacks.patch similarity index 97% rename from 0036-block-stream-refactor-stream-to-use-job-callbacks.patch rename to 0044-block-stream-refactor-stream-to-use-job-callbacks.patch index 4ff194d..c798419 100644 --- a/0036-block-stream-refactor-stream-to-use-job-callbacks.patch +++ b/0044-block-stream-refactor-stream-to-use-job-callbacks.patch @@ -1,4 +1,4 @@ -From 533c77ee076c0050b4c4deb26fda54c085a994ce Mon Sep 17 00:00:00 2001 +From 57ede8577bbecac73a2945ca5278662dfc019dca Mon Sep 17 00:00:00 2001 From: John Snow Date: Tue, 25 Sep 2018 22:34:22 +0100 Subject: block/stream: refactor stream to use job callbacks diff --git a/0037-tests-blockjob-replace-Blockjob-with-Job.patch b/0045-tests-blockjob-replace-Blockjob-with-Job.patch similarity index 98% rename from 0037-tests-blockjob-replace-Blockjob-with-Job.patch rename to 0045-tests-blockjob-replace-Blockjob-with-Job.patch index f408d83..3d9bf41 100644 --- a/0037-tests-blockjob-replace-Blockjob-with-Job.patch +++ b/0045-tests-blockjob-replace-Blockjob-with-Job.patch @@ -1,4 +1,4 @@ -From ac945e63cca25c453d472834c64aa3a4192729f9 Mon Sep 17 00:00:00 2001 +From 3817b0c67fb4636bacd9c4ebdef39f51b18e05c1 Mon Sep 17 00:00:00 2001 From: John Snow Date: Tue, 25 Sep 2018 22:34:23 +0100 Subject: tests/blockjob: replace Blockjob with Job diff --git a/0038-tests-test-blockjob-remove-exit-callback.patch b/0046-tests-test-blockjob-remove-exit-callback.patch similarity index 97% rename from 0038-tests-test-blockjob-remove-exit-callback.patch rename to 0046-tests-test-blockjob-remove-exit-callback.patch index 9bd1a7c..81856fb 100644 --- a/0038-tests-test-blockjob-remove-exit-callback.patch +++ b/0046-tests-test-blockjob-remove-exit-callback.patch @@ -1,4 +1,4 @@ -From 62fd56870fb6296f795c9fc7f5965d83a72dabac Mon Sep 17 00:00:00 2001 +From f641d3f6946af31724c578aa6f09ba883bb5fab3 Mon Sep 17 00:00:00 2001 From: John Snow Date: Tue, 25 Sep 2018 22:34:24 +0100 Subject: tests/test-blockjob: remove exit callback diff --git a/0039-tests-test-blockjob-txn-move-.exit-to-.clean.patch b/0047-tests-test-blockjob-txn-move-.exit-to-.clean.patch similarity index 96% rename from 0039-tests-test-blockjob-txn-move-.exit-to-.clean.patch rename to 0047-tests-test-blockjob-txn-move-.exit-to-.clean.patch index ef6db4f..b6cc4fd 100644 --- a/0039-tests-test-blockjob-txn-move-.exit-to-.clean.patch +++ b/0047-tests-test-blockjob-txn-move-.exit-to-.clean.patch @@ -1,4 +1,4 @@ -From 6247c4b10e3fb6c677947a503ddad961cb71faff Mon Sep 17 00:00:00 2001 +From 43b1e07411d06cd676f3f55e14e0ac1082a679d0 Mon Sep 17 00:00:00 2001 From: John Snow Date: Tue, 25 Sep 2018 22:34:25 +0100 Subject: tests/test-blockjob-txn: move .exit to .clean diff --git a/0040-jobs-remove-.exit-callback.patch b/0048-jobs-remove-.exit-callback.patch similarity index 98% rename from 0040-jobs-remove-.exit-callback.patch rename to 0048-jobs-remove-.exit-callback.patch index 00704a6..b4ece99 100644 --- a/0040-jobs-remove-.exit-callback.patch +++ b/0048-jobs-remove-.exit-callback.patch @@ -1,4 +1,4 @@ -From c2c10f4fac6757d292f8b3d9ac7723a718e596aa Mon Sep 17 00:00:00 2001 +From ea31341d12bc2080f7a1b606dcf578376d6a4637 Mon Sep 17 00:00:00 2001 From: John Snow Date: Tue, 25 Sep 2018 22:34:26 +0100 Subject: jobs: remove .exit callback diff --git a/0041-qapi-block-commit-expose-new-job-properties.patch b/0049-qapi-block-commit-expose-new-job-properties.patch similarity index 98% rename from 0041-qapi-block-commit-expose-new-job-properties.patch rename to 0049-qapi-block-commit-expose-new-job-properties.patch index a5ec394..97a192c 100644 --- a/0041-qapi-block-commit-expose-new-job-properties.patch +++ b/0049-qapi-block-commit-expose-new-job-properties.patch @@ -1,4 +1,4 @@ -From ce81bd3fa7316bcdee5e121e6ea71c7b2e1e81e1 Mon Sep 17 00:00:00 2001 +From 756c3ccf83d5612ca2b326a8fed8fdf1f7958adb Mon Sep 17 00:00:00 2001 From: John Snow Date: Tue, 25 Sep 2018 22:34:27 +0100 Subject: qapi/block-commit: expose new job properties diff --git a/0042-qapi-block-mirror-expose-new-job-properties.patch b/0050-qapi-block-mirror-expose-new-job-properties.patch similarity index 98% rename from 0042-qapi-block-mirror-expose-new-job-properties.patch rename to 0050-qapi-block-mirror-expose-new-job-properties.patch index 52f77cd..7f6443a 100644 --- a/0042-qapi-block-mirror-expose-new-job-properties.patch +++ b/0050-qapi-block-mirror-expose-new-job-properties.patch @@ -1,4 +1,4 @@ -From 318445193efc33c06e63e021a988814d49658a0f Mon Sep 17 00:00:00 2001 +From 254a2b41a647cf39abaa5d94f17aef62f035d30f Mon Sep 17 00:00:00 2001 From: John Snow Date: Thu, 6 Sep 2018 09:02:22 -0400 Subject: qapi/block-mirror: expose new job properties diff --git a/0043-qapi-block-stream-expose-new-job-properties.patch b/0051-qapi-block-stream-expose-new-job-properties.patch similarity index 98% rename from 0043-qapi-block-stream-expose-new-job-properties.patch rename to 0051-qapi-block-stream-expose-new-job-properties.patch index 4e5a8fa..c55039a 100644 --- a/0043-qapi-block-stream-expose-new-job-properties.patch +++ b/0051-qapi-block-stream-expose-new-job-properties.patch @@ -1,4 +1,4 @@ -From 67fa4ccaffcd7e2698d30597f51093903aef4a5d Mon Sep 17 00:00:00 2001 +From 50990953696a8803f6b2b7ad71901c58c375eb8c Mon Sep 17 00:00:00 2001 From: John Snow Date: Tue, 25 Sep 2018 22:34:29 +0100 Subject: qapi/block-stream: expose new job properties diff --git a/0044-block-backup-qapi-documentation-fixup.patch b/0052-block-backup-qapi-documentation-fixup.patch similarity index 98% rename from 0044-block-backup-qapi-documentation-fixup.patch rename to 0052-block-backup-qapi-documentation-fixup.patch index c8b3273..fb695b0 100644 --- a/0044-block-backup-qapi-documentation-fixup.patch +++ b/0052-block-backup-qapi-documentation-fixup.patch @@ -1,4 +1,4 @@ -From c104ce571b585040ca4d0c77419d2ca06c2087b8 Mon Sep 17 00:00:00 2001 +From 6ecfc87059e78892c868227319a91adea909e09e Mon Sep 17 00:00:00 2001 From: John Snow Date: Tue, 25 Sep 2018 22:34:30 +0100 Subject: block/backup: qapi documentation fixup diff --git a/0045-blockdev-document-transactional-shortcomings.patch b/0053-blockdev-document-transactional-shortcomings.patch similarity index 96% rename from 0045-blockdev-document-transactional-shortcomings.patch rename to 0053-blockdev-document-transactional-shortcomings.patch index 7562949..50e40af 100644 --- a/0045-blockdev-document-transactional-shortcomings.patch +++ b/0053-blockdev-document-transactional-shortcomings.patch @@ -1,4 +1,4 @@ -From 53dc1dce0b91a7ebb1c32d10a7482461c01326d6 Mon Sep 17 00:00:00 2001 +From 00a437d87c6bd8ec956b25fc0dffe8397ce475b8 Mon Sep 17 00:00:00 2001 From: John Snow Date: Tue, 25 Sep 2018 22:34:31 +0100 Subject: blockdev: document transactional shortcomings diff --git a/0054-seccomp-use-SIGSYS-signal-instead-of-killing-the-thr.patch b/0054-seccomp-use-SIGSYS-signal-instead-of-killing-the-thr.patch new file mode 100644 index 0000000..f7a741f --- /dev/null +++ b/0054-seccomp-use-SIGSYS-signal-instead-of-killing-the-thr.patch @@ -0,0 +1,67 @@ +From 5b9ccef27363b61223b31312062cde1210216985 Mon Sep 17 00:00:00 2001 +From: Eduardo Otubo +Date: Fri, 28 Sep 2018 07:56:36 +0100 +Subject: seccomp: use SIGSYS signal instead of killing the thread +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Eduardo Otubo +Message-id: <20180928075639.16746-3-otubo@redhat.com> +Patchwork-id: 82314 +O-Subject: [RHEL-8 qemu-kvm PATCH 2/5] seccomp: use SIGSYS signal instead of killing the thread +Bugzilla: 1618356 +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: Marc-André Lureau +RH-Acked-by: Thomas Huth + +From: Marc-André Lureau + +commit 6f2231e9b0931e1998d9ed0c509adf7aedc02db2 +Author: Marc-André Lureau +Date: Wed Aug 22 19:02:47 2018 +0200 + + seccomp: use SIGSYS signal instead of killing the thread + + The seccomp action SCMP_ACT_KILL results in immediate termination of + the thread that made the bad system call. However, qemu being + multi-threaded, it keeps running. There is no easy way for parent + process / management layer (libvirt) to know about that situation. + + Instead, the default SIGSYS handler when invoked with SCMP_ACT_TRAP + will terminate the program and core dump. + + This may not be the most secure solution, but probably better than + just killing the offending thread. SCMP_ACT_KILL_PROCESS has been + added in Linux 4.14 to improve the situation, which I propose to use + by default if available in the next patch. + + Related to: + https://bugzilla.redhat.com/show_bug.cgi?id=1594456 + + Signed-off-by: Marc-André Lureau + Reviewed-by: Daniel P. Berrangé + Acked-by: Eduardo Otubo + +Signed-off-by: Eduardo Otubo +Signed-off-by: Danilo C. L. de Paula +--- + qemu-seccomp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/qemu-seccomp.c b/qemu-seccomp.c +index 9cd8eb9..b117a92 100644 +--- a/qemu-seccomp.c ++++ b/qemu-seccomp.c +@@ -125,7 +125,7 @@ static int seccomp_start(uint32_t seccomp_opts) + continue; + } + +- rc = seccomp_rule_add_array(ctx, SCMP_ACT_KILL, blacklist[i].num, ++ rc = seccomp_rule_add_array(ctx, SCMP_ACT_TRAP, blacklist[i].num, + blacklist[i].narg, blacklist[i].arg_cmp); + if (rc < 0) { + goto seccomp_return; +-- +1.8.3.1 + diff --git a/0055-seccomp-prefer-SCMP_ACT_KILL_PROCESS-if-available.patch b/0055-seccomp-prefer-SCMP_ACT_KILL_PROCESS-if-available.patch new file mode 100644 index 0000000..809c9c2 --- /dev/null +++ b/0055-seccomp-prefer-SCMP_ACT_KILL_PROCESS-if-available.patch @@ -0,0 +1,110 @@ +From 80574fd1c226ca5c8555b3bb37bc3fe121bbf69f Mon Sep 17 00:00:00 2001 +From: Eduardo Otubo +Date: Fri, 28 Sep 2018 07:56:37 +0100 +Subject: seccomp: prefer SCMP_ACT_KILL_PROCESS if available +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Eduardo Otubo +Message-id: <20180928075639.16746-4-otubo@redhat.com> +Patchwork-id: 82315 +O-Subject: [RHEL-8 qemu-kvm PATCH 3/5] seccomp: prefer SCMP_ACT_KILL_PROCESS if available +Bugzilla: 1618356 +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: Marc-André Lureau +RH-Acked-by: Thomas Huth + +From: Marc-André Lureau + +commit bda08a5764d470f101fa38635d30b41179a313e1 +Author: Marc-André Lureau +Date: Wed Aug 22 19:02:48 2018 +0200 + + seccomp: prefer SCMP_ACT_KILL_PROCESS if available + + The upcoming libseccomp release should have SCMP_ACT_KILL_PROCESS + action (https://github.com/seccomp/libseccomp/issues/96). + + SCMP_ACT_KILL_PROCESS is preferable to immediately terminate the + offending process, rather than having the SIGSYS handler running. + + Use SECCOMP_GET_ACTION_AVAIL to check availability of kernel support, + as libseccomp will fallback on SCMP_ACT_KILL otherwise, and we still + prefer SCMP_ACT_TRAP. + + Signed-off-by: Marc-André Lureau + Reviewed-by: Daniel P. Berrangé + Acked-by: Eduardo Otubo + +Signed-off-by: Eduardo Otubo +Signed-off-by: Danilo C. L. de Paula +--- + qemu-seccomp.c | 31 ++++++++++++++++++++++++++++++- + 1 file changed, 30 insertions(+), 1 deletion(-) + +diff --git a/qemu-seccomp.c b/qemu-seccomp.c +index b117a92..f0c833f 100644 +--- a/qemu-seccomp.c ++++ b/qemu-seccomp.c +@@ -20,6 +20,7 @@ + #include + #include + #include "sysemu/seccomp.h" ++#include + + /* For some architectures (notably ARM) cacheflush is not supported until + * libseccomp 2.2.3, but configure enforces that we are using a more recent +@@ -107,12 +108,40 @@ static const struct QemuSeccompSyscall blacklist[] = { + { SCMP_SYS(sched_get_priority_min), QEMU_SECCOMP_SET_RESOURCECTL }, + }; + ++static inline __attribute__((unused)) int ++qemu_seccomp(unsigned int operation, unsigned int flags, void *args) ++{ ++#ifdef __NR_seccomp ++ return syscall(__NR_seccomp, operation, flags, args); ++#else ++ errno = ENOSYS; ++ return -1; ++#endif ++} ++ ++static uint32_t qemu_seccomp_get_kill_action(void) ++{ ++#if defined(SECCOMP_GET_ACTION_AVAIL) && defined(SCMP_ACT_KILL_PROCESS) && \ ++ defined(SECCOMP_RET_KILL_PROCESS) ++ { ++ uint32_t action = SECCOMP_RET_KILL_PROCESS; ++ ++ if (qemu_seccomp(SECCOMP_GET_ACTION_AVAIL, 0, &action) == 0) { ++ return SCMP_ACT_KILL_PROCESS; ++ } ++ } ++#endif ++ ++ return SCMP_ACT_TRAP; ++} ++ + + static int seccomp_start(uint32_t seccomp_opts) + { + int rc = 0; + unsigned int i = 0; + scmp_filter_ctx ctx; ++ uint32_t action = qemu_seccomp_get_kill_action(); + + ctx = seccomp_init(SCMP_ACT_ALLOW); + if (ctx == NULL) { +@@ -125,7 +154,7 @@ static int seccomp_start(uint32_t seccomp_opts) + continue; + } + +- rc = seccomp_rule_add_array(ctx, SCMP_ACT_TRAP, blacklist[i].num, ++ rc = seccomp_rule_add_array(ctx, action, blacklist[i].num, + blacklist[i].narg, blacklist[i].arg_cmp); + if (rc < 0) { + goto seccomp_return; +-- +1.8.3.1 + diff --git a/0056-seccomp-set-the-seccomp-filter-to-all-threads.patch b/0056-seccomp-set-the-seccomp-filter-to-all-threads.patch new file mode 100644 index 0000000..b1e37ad --- /dev/null +++ b/0056-seccomp-set-the-seccomp-filter-to-all-threads.patch @@ -0,0 +1,77 @@ +From ef8bae877ca544af956f8314cdd702d1c62a9b15 Mon Sep 17 00:00:00 2001 +From: Eduardo Otubo +Date: Fri, 28 Sep 2018 07:56:39 +0100 +Subject: seccomp: set the seccomp filter to all threads +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Eduardo Otubo +Message-id: <20180928075639.16746-6-otubo@redhat.com> +Patchwork-id: 82316 +O-Subject: [RHEL-8 qemu-kvm PATCH 5/5] seccomp: set the seccomp filter to all threads +Bugzilla: 1618356 +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: Marc-André Lureau +RH-Acked-by: Thomas Huth + +From: Marc-André Lureau + +commit 70dfabeaa79ba4d7a3b699abe1a047c8012db114 +Author: Marc-André Lureau +Date: Wed Aug 22 19:02:50 2018 +0200 + + seccomp: set the seccomp filter to all threads + + When using "-seccomp on", the seccomp policy is only applied to the + main thread, the vcpu worker thread and other worker threads created + after seccomp policy is applied; the seccomp policy is not applied to + e.g. the RCU thread because it is created before the seccomp policy is + applied and SECCOMP_FILTER_FLAG_TSYNC isn't used. + + This can be verified with + for task in /proc/`pidof qemu`/task/*; do cat $task/status | grep Secc ; done + Seccomp: 2 + Seccomp: 0 + Seccomp: 0 + Seccomp: 2 + Seccomp: 2 + Seccomp: 2 + + Starting with libseccomp 2.2.0 and kernel >= 3.17, we can use + seccomp_attr_set(ctx, > SCMP_FLTATR_CTL_TSYNC, 1) to update the policy + on all threads. + + libseccomp requirement was bumped to 2.2.0 in previous patch. + libseccomp should fail to set the filter if it can't honour + SCMP_FLTATR_CTL_TSYNC (untested), and thus -sandbox will now fail on + kernel < 3.17. + + Signed-off-by: Marc-André Lureau + Acked-by: Eduardo Otubo + +Signed-off-by: Eduardo Otubo +Signed-off-by: Danilo C. L. de Paula +--- + qemu-seccomp.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/qemu-seccomp.c b/qemu-seccomp.c +index f0c833f..4729eb1 100644 +--- a/qemu-seccomp.c ++++ b/qemu-seccomp.c +@@ -149,6 +149,11 @@ static int seccomp_start(uint32_t seccomp_opts) + goto seccomp_return; + } + ++ rc = seccomp_attr_set(ctx, SCMP_FLTATR_CTL_TSYNC, 1); ++ if (rc != 0) { ++ goto seccomp_return; ++ } ++ + for (i = 0; i < ARRAY_SIZE(blacklist); i++) { + if (!(seccomp_opts & blacklist[i].set)) { + continue; +-- +1.8.3.1 + diff --git a/0057-memory-cleanup-side-effects-of-memory_region_init_fo.patch b/0057-memory-cleanup-side-effects-of-memory_region_init_fo.patch new file mode 100644 index 0000000..e866c28 --- /dev/null +++ b/0057-memory-cleanup-side-effects-of-memory_region_init_fo.patch @@ -0,0 +1,185 @@ +From da9c980b19783915f8675894b88da631f27dd34d Mon Sep 17 00:00:00 2001 +From: Igor Mammedov +Date: Fri, 5 Oct 2018 12:59:47 +0100 +Subject: memory: cleanup side effects of memory_region_init_foo() on failure + +RH-Author: Igor Mammedov +Message-id: <1538744387-84898-1-git-send-email-imammedo@redhat.com> +Patchwork-id: 82391 +O-Subject: [RHEL-8 qemu-kvm PATCH] memory: cleanup side effects of memory_region_init_foo() on failure +Bugzilla: 1600365 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Dr. David Alan Gilbert +RH-Acked-by: Pankaj Gupta +RH-Acked-by: Laszlo Ersek + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1600365 +Brew: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=18658506 + +if MemoryRegion intialization fails it's left in semi-initialized state, +where it's size is not 0 and attached as child to owner object. +And this leds to crash in following use-case: + (monitor) object_add memory-backend-file,id=mem1,size=99999G,mem-path=/tmp/foo,discard-data=yes + memory.c:2083: memory_region_get_ram_ptr: Assertion `mr->ram_block' failed + Aborted (core dumped) +it happens due to assumption that memory region is intialized when + memory_region_size() != 0 +and therefore it's ok to access it in + file_backend_unparent() + if (memory_region_size() != 0) + memory_region_get_ram_ptr() + +which happens when object_add fails and unparents failed backend making +file_backend_unparent() access invalid memory region. + +Fix it by making sure that memory_region_init_foo() APIs cleanup externally +visible side effects on failure (like set size to 0 and unparenting object) + +Signed-off-by: Igor Mammedov +Message-Id: <1536064777-42312-1-git-send-email-imammedo@redhat.com> +Signed-off-by: Paolo Bonzini +(cherry picked from commit 1cd3d492624da399d66c4c3e6a5eabb8f96bb0a2) +Signed-off-by: Igor Mammedov +Signed-off-by: Danilo C. L. de Paula + +Conflicts: + memory.c + due missing (cbfc01710 "memory, exec: switch file ram allocation functions to 'flags' parameters") + not related to the patch signature mismatch of + qemu_ram_alloc_from_file()/qemu_ram_alloc_from_fd() +--- + memory.c | 48 ++++++++++++++++++++++++++++++++++++++++++------ + 1 file changed, 42 insertions(+), 6 deletions(-) + +diff --git a/memory.c b/memory.c +index e9cd446..88c75d8 100644 +--- a/memory.c ++++ b/memory.c +@@ -1518,12 +1518,18 @@ void memory_region_init_ram_shared_nomigrate(MemoryRegion *mr, + bool share, + Error **errp) + { ++ Error *err = NULL; + memory_region_init(mr, owner, name, size); + mr->ram = true; + mr->terminates = true; + mr->destructor = memory_region_destructor_ram; +- mr->ram_block = qemu_ram_alloc(size, share, mr, errp); ++ mr->ram_block = qemu_ram_alloc(size, share, mr, &err); + mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0; ++ if (err) { ++ mr->size = int128_zero(); ++ object_unparent(OBJECT(mr)); ++ error_propagate(errp, err); ++ } + } + + void memory_region_init_resizeable_ram(MemoryRegion *mr, +@@ -1536,13 +1542,19 @@ void memory_region_init_resizeable_ram(MemoryRegion *mr, + void *host), + Error **errp) + { ++ Error *err = NULL; + memory_region_init(mr, owner, name, size); + mr->ram = true; + mr->terminates = true; + mr->destructor = memory_region_destructor_ram; + mr->ram_block = qemu_ram_alloc_resizeable(size, max_size, resized, +- mr, errp); ++ mr, &err); + mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0; ++ if (err) { ++ mr->size = int128_zero(); ++ object_unparent(OBJECT(mr)); ++ error_propagate(errp, err); ++ } + } + + #ifdef __linux__ +@@ -1555,13 +1567,19 @@ void memory_region_init_ram_from_file(MemoryRegion *mr, + const char *path, + Error **errp) + { ++ Error *err = NULL; + memory_region_init(mr, owner, name, size); + mr->ram = true; + mr->terminates = true; + mr->destructor = memory_region_destructor_ram; + mr->align = align; +- mr->ram_block = qemu_ram_alloc_from_file(size, mr, share, path, errp); ++ mr->ram_block = qemu_ram_alloc_from_file(size, mr, share, path, &err); + mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0; ++ if (err) { ++ mr->size = int128_zero(); ++ object_unparent(OBJECT(mr)); ++ error_propagate(errp, err); ++ } + } + + void memory_region_init_ram_from_fd(MemoryRegion *mr, +@@ -1572,12 +1590,18 @@ void memory_region_init_ram_from_fd(MemoryRegion *mr, + int fd, + Error **errp) + { ++ Error *err = NULL; + memory_region_init(mr, owner, name, size); + mr->ram = true; + mr->terminates = true; + mr->destructor = memory_region_destructor_ram; +- mr->ram_block = qemu_ram_alloc_from_fd(size, mr, share, fd, errp); ++ mr->ram_block = qemu_ram_alloc_from_fd(size, mr, share, fd, &err); + mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0; ++ if (err) { ++ mr->size = int128_zero(); ++ object_unparent(OBJECT(mr)); ++ error_propagate(errp, err); ++ } + } + #endif + +@@ -1628,13 +1652,19 @@ void memory_region_init_rom_nomigrate(MemoryRegion *mr, + uint64_t size, + Error **errp) + { ++ Error *err = NULL; + memory_region_init(mr, owner, name, size); + mr->ram = true; + mr->readonly = true; + mr->terminates = true; + mr->destructor = memory_region_destructor_ram; +- mr->ram_block = qemu_ram_alloc(size, false, mr, errp); ++ mr->ram_block = qemu_ram_alloc(size, false, mr, &err); + mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0; ++ if (err) { ++ mr->size = int128_zero(); ++ object_unparent(OBJECT(mr)); ++ error_propagate(errp, err); ++ } + } + + void memory_region_init_rom_device_nomigrate(MemoryRegion *mr, +@@ -1645,6 +1675,7 @@ void memory_region_init_rom_device_nomigrate(MemoryRegion *mr, + uint64_t size, + Error **errp) + { ++ Error *err = NULL; + assert(ops); + memory_region_init(mr, owner, name, size); + mr->ops = ops; +@@ -1652,7 +1683,12 @@ void memory_region_init_rom_device_nomigrate(MemoryRegion *mr, + mr->terminates = true; + mr->rom_device = true; + mr->destructor = memory_region_destructor_ram; +- mr->ram_block = qemu_ram_alloc(size, false, mr, errp); ++ mr->ram_block = qemu_ram_alloc(size, false, mr, &err); ++ if (err) { ++ mr->size = int128_zero(); ++ object_unparent(OBJECT(mr)); ++ error_propagate(errp, err); ++ } + } + + void memory_region_init_iommu(void *_iommu_mr, +-- +1.8.3.1 + diff --git a/0058-mirror-Fail-gracefully-for-source-target.patch b/0058-mirror-Fail-gracefully-for-source-target.patch new file mode 100644 index 0000000..56c3baf --- /dev/null +++ b/0058-mirror-Fail-gracefully-for-source-target.patch @@ -0,0 +1,87 @@ +From a96ed7a8374891516e626b797321d4be69cb071d Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Wed, 10 Oct 2018 13:19:57 +0100 +Subject: mirror: Fail gracefully for source == target + +RH-Author: Kevin Wolf +Message-id: <20181010131957.23198-2-kwolf@redhat.com> +Patchwork-id: 82564 +O-Subject: [RHEL-8 qemu-kvm PATCH 1/1] mirror: Fail gracefully for source == target +Bugzilla: 1637963 +RH-Acked-by: John Snow +RH-Acked-by: Fam Zheng +RH-Acked-by: Stefan Hajnoczi + +blockdev-mirror with the same node for source and target segfaults +today: A node is in its own backing chain, so mirror_start_job() decides +that this is an active commit. When adding the intermediate nodes with +block_job_add_bdrv(), it starts the iteration through the subchain with +the backing file of source, though, so it never reaches target and +instead runs into NULL at the base. + +While we could fix that by starting with source itself, there is no +point in allowing mirroring a node into itself and I wouldn't be +surprised if this caused more problems later. + +So just check for this scenario and error out. + +Cc: qemu-stable@nongnu.org +Signed-off-by: Kevin Wolf +Reviewed-by: Eric Blake +(cherry picked from commit 86fae10c64d642256cf019e6829929fa0d259c7a) +Signed-off-by: Kevin Wolf +Signed-off-by: Danilo C. L. de Paula +--- + block/mirror.c | 5 +++++ + tests/qemu-iotests/041 | 6 ++++++ + tests/qemu-iotests/041.out | 4 ++-- + 3 files changed, 13 insertions(+), 2 deletions(-) + +diff --git a/block/mirror.c b/block/mirror.c +index 7efba77..b61f99b 100644 +--- a/block/mirror.c ++++ b/block/mirror.c +@@ -1516,6 +1516,11 @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs, + buf_size = DEFAULT_MIRROR_BUF_SIZE; + } + ++ if (bs == target) { ++ error_setg(errp, "Can't mirror node into itself"); ++ return; ++ } ++ + /* In the case of active commit, add dummy driver to provide consistent + * reads on the top, while disabling it in the intermediate nodes, and make + * the backing chain writable. */ +diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041 +index c20ac7d..9336ab6 100755 +--- a/tests/qemu-iotests/041 ++++ b/tests/qemu-iotests/041 +@@ -234,6 +234,12 @@ class TestSingleBlockdev(TestSingleDrive): + result = self.vm.qmp("blockdev-add", **args) + self.assert_qmp(result, 'return', {}) + ++ def test_mirror_to_self(self): ++ result = self.vm.qmp(self.qmp_cmd, job_id='job0', ++ device=self.qmp_target, sync='full', ++ target=self.qmp_target) ++ self.assert_qmp(result, 'error/class', 'GenericError') ++ + test_large_cluster = None + test_image_not_found = None + test_small_buffer2 = None +diff --git a/tests/qemu-iotests/041.out b/tests/qemu-iotests/041.out +index c28b392..e071d0b 100644 +--- a/tests/qemu-iotests/041.out ++++ b/tests/qemu-iotests/041.out +@@ -1,5 +1,5 @@ +-..................................................................................... ++........................................................................................ + ---------------------------------------------------------------------- +-Ran 85 tests ++Ran 88 tests + + OK +-- +1.8.3.1 + diff --git a/0059-commit-Add-top-node-base-node-options.patch b/0059-commit-Add-top-node-base-node-options.patch new file mode 100644 index 0000000..c3cde82 --- /dev/null +++ b/0059-commit-Add-top-node-base-node-options.patch @@ -0,0 +1,141 @@ +From 0086e14eef7fc78bc1254ee888bd7d720d6ee5b9 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Wed, 10 Oct 2018 13:50:54 +0100 +Subject: commit: Add top-node/base-node options + +RH-Author: Kevin Wolf +Message-id: <20181010135055.3874-2-kwolf@redhat.com> +Patchwork-id: 82569 +O-Subject: [RHEL-8 qemu-kvm PATCH 1/2] commit: Add top-node/base-node options +Bugzilla: 1637970 +RH-Acked-by: John Snow +RH-Acked-by: Fam Zheng +RH-Acked-by: Stefan Hajnoczi + +The block-commit QMP command required specifying the top and base nodes +of the commit jobs using the file name of that node. While this works +in simple cases (local files with absolute paths), the file names +generated for more complicated setups can be hard to predict. + +The block-commit command has more problems than just this, so we want to +replace it altogether in the long run, but libvirt needs a reliable way +to address nodes now. So we don't want to wait for a new, cleaner +command, but just add the minimal thing needed right now. + +This adds two new options top-node and base-node to the command, which +allow specifying node names instead. They are mutually exclusive with +the old options. + +Signed-off-by: Kevin Wolf +(cherry picked from commit 3c605f4074ebeb97970eb660fb56a9cb06525923) +Signed-off-by: Kevin Wolf +Signed-off-by: Danilo C. L. de Paula +--- + blockdev.c | 32 ++++++++++++++++++++++++++++++-- + qapi/block-core.json | 24 ++++++++++++++++++------ + 2 files changed, 48 insertions(+), 8 deletions(-) + +diff --git a/blockdev.c b/blockdev.c +index d97202a..df256e6 100644 +--- a/blockdev.c ++++ b/blockdev.c +@@ -3324,7 +3324,9 @@ out: + } + + void qmp_block_commit(bool has_job_id, const char *job_id, const char *device, ++ bool has_base_node, const char *base_node, + bool has_base, const char *base, ++ bool has_top_node, const char *top_node, + bool has_top, const char *top, + bool has_backing_file, const char *backing_file, + bool has_speed, int64_t speed, +@@ -3385,7 +3387,20 @@ void qmp_block_commit(bool has_job_id, const char *job_id, const char *device, + /* default top_bs is the active layer */ + top_bs = bs; + +- if (has_top && top) { ++ if (has_top_node && has_top) { ++ error_setg(errp, "'top-node' and 'top' are mutually exclusive"); ++ goto out; ++ } else if (has_top_node) { ++ top_bs = bdrv_lookup_bs(NULL, top_node, errp); ++ if (top_bs == NULL) { ++ goto out; ++ } ++ if (!bdrv_chain_contains(bs, top_bs)) { ++ error_setg(errp, "'%s' is not in this backing file chain", ++ top_node); ++ goto out; ++ } ++ } else if (has_top && top) { + if (strcmp(bs->filename, top) != 0) { + top_bs = bdrv_find_backing_image(bs, top); + } +@@ -3398,7 +3413,20 @@ void qmp_block_commit(bool has_job_id, const char *job_id, const char *device, + + assert(bdrv_get_aio_context(top_bs) == aio_context); + +- if (has_base && base) { ++ if (has_base_node && has_base) { ++ error_setg(errp, "'base-node' and 'base' are mutually exclusive"); ++ goto out; ++ } else if (has_base_node) { ++ base_bs = bdrv_lookup_bs(NULL, base_node, errp); ++ if (base_bs == NULL) { ++ goto out; ++ } ++ if (!bdrv_chain_contains(top_bs, base_bs)) { ++ error_setg(errp, "'%s' is not in this backing file chain", ++ base_node); ++ goto out; ++ } ++ } else if (has_base && base) { + base_bs = bdrv_find_backing_image(top_bs, base); + } else { + base_bs = bdrv_find_base(top_bs); +diff --git a/qapi/block-core.json b/qapi/block-core.json +index 2953991..6f38dc0 100644 +--- a/qapi/block-core.json ++++ b/qapi/block-core.json +@@ -1457,12 +1457,23 @@ + # + # @device: the device name or node-name of a root node + # +-# @base: The file name of the backing image to write data into. +-# If not specified, this is the deepest backing image. ++# @base-node: The node name of the backing image to write data into. ++# If not specified, this is the deepest backing image. ++# (since: 3.1) + # +-# @top: The file name of the backing image within the image chain, +-# which contains the topmost data to be committed down. If +-# not specified, this is the active layer. ++# @base: Same as @base-node, except that it is a file name rather than a node ++# name. This must be the exact filename string that was used to open the ++# node; other strings, even if addressing the same file, are not ++# accepted (deprecated, use @base-node instead) ++# ++# @top-node: The node name of the backing image within the image chain ++# which contains the topmost data to be committed down. If ++# not specified, this is the active layer. (since: 3.1) ++# ++# @top: Same as @top-node, except that it is a file name rather than a node ++# name. This must be the exact filename string that was used to open the ++# node; other strings, even if addressing the same file, are not ++# accepted (deprecated, use @base-node instead) + # + # @backing-file: The backing file string to write into the overlay + # image of 'top'. If 'top' is the active layer, +@@ -1531,7 +1542,8 @@ + # + ## + { 'command': 'block-commit', +- 'data': { '*job-id': 'str', 'device': 'str', '*base': 'str', '*top': 'str', ++ 'data': { '*job-id': 'str', 'device': 'str', '*base-node': 'str', ++ '*base': 'str', '*top-node': 'str', '*top': 'str', + '*backing-file': 'str', '*speed': 'int', + '*filter-node-name': 'str', + '*auto-finalize': 'bool', '*auto-dismiss': 'bool' } } +-- +1.8.3.1 + diff --git a/0060-qemu-iotests-Test-commit-with-top-node-base-node.patch b/0060-qemu-iotests-Test-commit-with-top-node-base-node.patch new file mode 100644 index 0000000..a593117 --- /dev/null +++ b/0060-qemu-iotests-Test-commit-with-top-node-base-node.patch @@ -0,0 +1,127 @@ +From bb9687c8dadef42d11f3606e68e956a7c60b2487 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Wed, 10 Oct 2018 13:50:55 +0100 +Subject: qemu-iotests: Test commit with top-node/base-node + +RH-Author: Kevin Wolf +Message-id: <20181010135055.3874-3-kwolf@redhat.com> +Patchwork-id: 82568 +O-Subject: [RHEL-8 qemu-kvm PATCH 2/2] qemu-iotests: Test commit with top-node/base-node +Bugzilla: 1637970 +RH-Acked-by: John Snow +RH-Acked-by: Fam Zheng +RH-Acked-by: Stefan Hajnoczi + +This adds some tests for block-commit with the new options top-node and +base-node (taking node names) instead of top and base (taking file +names). + +Signed-off-by: Kevin Wolf +(cherry picked from commit d57177a48fc604e5427921bf20b22ee0e6d578b3) +Signed-off-by: Kevin Wolf +Signed-off-by: Danilo C. L. de Paula +--- + tests/qemu-iotests/040 | 52 ++++++++++++++++++++++++++++++++++++++++++++-- + tests/qemu-iotests/040.out | 4 ++-- + 2 files changed, 52 insertions(+), 4 deletions(-) + +diff --git a/tests/qemu-iotests/040 b/tests/qemu-iotests/040 +index 1beb5e6..1cb1cee 100755 +--- a/tests/qemu-iotests/040 ++++ b/tests/qemu-iotests/040 +@@ -57,9 +57,12 @@ class ImageCommitTestCase(iotests.QMPTestCase): + self.assert_no_active_block_jobs() + self.vm.shutdown() + +- def run_commit_test(self, top, base, need_ready=False): ++ def run_commit_test(self, top, base, need_ready=False, node_names=False): + self.assert_no_active_block_jobs() +- result = self.vm.qmp('block-commit', device='drive0', top=top, base=base) ++ if node_names: ++ result = self.vm.qmp('block-commit', device='drive0', top_node=top, base_node=base) ++ else: ++ result = self.vm.qmp('block-commit', device='drive0', top=top, base=base) + self.assert_qmp(result, 'return', {}) + self.wait_for_complete(need_ready) + +@@ -101,6 +104,11 @@ class TestSingleDrive(ImageCommitTestCase): + self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xab 0 524288', backing_img).find("verification failed")) + self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xef 524288 524288', backing_img).find("verification failed")) + ++ def test_commit_node(self): ++ self.run_commit_test("mid", "base", node_names=True) ++ self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xab 0 524288', backing_img).find("verification failed")) ++ self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xef 524288 524288', backing_img).find("verification failed")) ++ + def test_device_not_found(self): + result = self.vm.qmp('block-commit', device='nonexistent', top='%s' % mid_img) + self.assert_qmp(result, 'error/class', 'DeviceNotFound') +@@ -123,6 +131,30 @@ class TestSingleDrive(ImageCommitTestCase): + self.assert_qmp(result, 'error/class', 'GenericError') + self.assert_qmp(result, 'error/desc', 'Base \'badfile\' not found') + ++ def test_top_node_invalid(self): ++ self.assert_no_active_block_jobs() ++ result = self.vm.qmp('block-commit', device='drive0', top_node='badfile', base_node='base') ++ self.assert_qmp(result, 'error/class', 'GenericError') ++ self.assert_qmp(result, 'error/desc', "Cannot find device= nor node_name=badfile") ++ ++ def test_base_node_invalid(self): ++ self.assert_no_active_block_jobs() ++ result = self.vm.qmp('block-commit', device='drive0', top_node='mid', base_node='badfile') ++ self.assert_qmp(result, 'error/class', 'GenericError') ++ self.assert_qmp(result, 'error/desc', "Cannot find device= nor node_name=badfile") ++ ++ def test_top_path_and_node(self): ++ self.assert_no_active_block_jobs() ++ result = self.vm.qmp('block-commit', device='drive0', top_node='mid', base_node='base', top='%s' % mid_img) ++ self.assert_qmp(result, 'error/class', 'GenericError') ++ self.assert_qmp(result, 'error/desc', "'top-node' and 'top' are mutually exclusive") ++ ++ def test_base_path_and_node(self): ++ self.assert_no_active_block_jobs() ++ result = self.vm.qmp('block-commit', device='drive0', top_node='mid', base_node='base', base='%s' % backing_img) ++ self.assert_qmp(result, 'error/class', 'GenericError') ++ self.assert_qmp(result, 'error/desc', "'base-node' and 'base' are mutually exclusive") ++ + def test_top_is_active(self): + self.run_commit_test(test_img, backing_img, need_ready=True) + self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xab 0 524288', backing_img).find("verification failed")) +@@ -139,6 +171,22 @@ class TestSingleDrive(ImageCommitTestCase): + self.assert_qmp(result, 'error/class', 'GenericError') + self.assert_qmp(result, 'error/desc', 'Base \'%s\' not found' % mid_img) + ++ def test_top_and_base_node_reversed(self): ++ self.assert_no_active_block_jobs() ++ result = self.vm.qmp('block-commit', device='drive0', top_node='base', base_node='top') ++ self.assert_qmp(result, 'error/class', 'GenericError') ++ self.assert_qmp(result, 'error/desc', "'top' is not in this backing file chain") ++ ++ def test_top_node_in_wrong_chain(self): ++ self.assert_no_active_block_jobs() ++ ++ result = self.vm.qmp('blockdev-add', driver='null-co', node_name='null') ++ self.assert_qmp(result, 'return', {}) ++ ++ result = self.vm.qmp('block-commit', device='drive0', top_node='null', base_node='base') ++ self.assert_qmp(result, 'error/class', 'GenericError') ++ self.assert_qmp(result, 'error/desc', "'null' is not in this backing file chain") ++ + # When the job is running on a BB that is automatically deleted on hot + # unplug, the job is cancelled when the device disappears + def test_hot_unplug(self): +diff --git a/tests/qemu-iotests/040.out b/tests/qemu-iotests/040.out +index e20a75c..802ffaa 100644 +--- a/tests/qemu-iotests/040.out ++++ b/tests/qemu-iotests/040.out +@@ -1,5 +1,5 @@ +-............................. ++........................................... + ---------------------------------------------------------------------- +-Ran 29 tests ++Ran 43 tests + + OK +-- +1.8.3.1 + diff --git a/0061-block-for-jobs-do-not-clear-user_paused-until-after-.patch b/0061-block-for-jobs-do-not-clear-user_paused-until-after-.patch new file mode 100644 index 0000000..f3c3385 --- /dev/null +++ b/0061-block-for-jobs-do-not-clear-user_paused-until-after-.patch @@ -0,0 +1,59 @@ +From 0908cd5291828eca03bbba206f133a37b87c8b41 Mon Sep 17 00:00:00 2001 +From: John Snow +Date: Wed, 10 Oct 2018 20:50:58 +0100 +Subject: block: for jobs, do not clear user_paused until after the resume + +RH-Author: John Snow +Message-id: <20181010205100.17689-2-jsnow@redhat.com> +Patchwork-id: 82631 +O-Subject: [RHEL8/rhel qemu-kvm PATCH 1/3] block: for jobs, do not clear user_paused until after the resume +Bugzilla: 1635583 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Max Reitz +RH-Acked-by: Kevin Wolf + +From: Jeff Cody + +The function job_cancel_async() will always cause an assert for blockjob +user resume. We set job->user_paused to false, and then call +job->driver->user_resume(). In the case of blockjobs, this is the +block_job_user_resume() function. + +In that function, we assert that job.user_paused is set to true. +Unfortunately, right before calling this function, it has explicitly +been set to false. + +The fix is pretty simple: set job->user_paused to false only after the +job user_resume() function has been called. + +Reviewed-by: John Snow +Reviewed-by: Eric Blake +Signed-off-by: Jeff Cody +Message-id: bb183b77d8f2dd6bd67b8da559a90ac1e74b2052.1534868459.git.jcody@redhat.com +Signed-off-by: Jeff Cody +(cherry picked from commit e321c0597c7590499bacab239d7f86e257f96bcd) +Signed-off-by: John Snow +Signed-off-by: Danilo C. L. de Paula +--- + job.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/job.c b/job.c +index 87c9aa4..bb322de 100644 +--- a/job.c ++++ b/job.c +@@ -705,10 +705,10 @@ static void job_cancel_async(Job *job, bool force) + { + if (job->user_paused) { + /* Do not call job_enter here, the caller will handle it. */ +- job->user_paused = false; + if (job->driver->user_resume) { + job->driver->user_resume(job); + } ++ job->user_paused = false; + assert(job->pause_count > 0); + job->pause_count--; + } +-- +1.8.3.1 + diff --git a/0062-block-iotest-to-catch-abort-on-forced-blockjob-cance.patch b/0062-block-iotest-to-catch-abort-on-forced-blockjob-cance.patch new file mode 100644 index 0000000..5c30cf9 --- /dev/null +++ b/0062-block-iotest-to-catch-abort-on-forced-blockjob-cance.patch @@ -0,0 +1,173 @@ +From d26430360b5996c99c0e1dd95b4dbb48bd894944 Mon Sep 17 00:00:00 2001 +From: John Snow +Date: Wed, 10 Oct 2018 20:51:00 +0100 +Subject: block: iotest to catch abort on forced blockjob cancel + +RH-Author: John Snow +Message-id: <20181010205100.17689-4-jsnow@redhat.com> +Patchwork-id: 82632 +O-Subject: [RHEL8/rhel qemu-kvm PATCH 3/3] block: iotest to catch abort on forced blockjob cancel +Bugzilla: 1635583 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Max Reitz +RH-Acked-by: Kevin Wolf + +From: Jeff Cody + +Signed-off-by: Jeff Cody +Reviewed-by: John Snow +Message-id: df317f617fbe5affcf699cb8560e7b0c2e028a64.1534868459.git.jcody@redhat.com +Signed-off-by: Jeff Cody +(cherry picked from commit 26bf474ba92c76e61bea51726e22da6dfd185296) +Signed-off-by: John Snow +Signed-off-by: Danilo C. L. de Paula +--- + tests/qemu-iotests/229 | 95 ++++++++++++++++++++++++++++++++++++++++++++++ + tests/qemu-iotests/229.out | 23 +++++++++++ + tests/qemu-iotests/group | 1 + + 3 files changed, 119 insertions(+) + create mode 100755 tests/qemu-iotests/229 + create mode 100644 tests/qemu-iotests/229.out + +diff --git a/tests/qemu-iotests/229 b/tests/qemu-iotests/229 +new file mode 100755 +index 0000000..ff851ec +--- /dev/null ++++ b/tests/qemu-iotests/229 +@@ -0,0 +1,95 @@ ++#!/bin/bash ++# ++# Test for force canceling a running blockjob that is paused in ++# an error state. ++# ++# Copyright (C) 2018 Red Hat, Inc. ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++# ++ ++# creator ++owner=jcody@redhat.com ++ ++seq="$(basename $0)" ++echo "QA output created by $seq" ++ ++here="$PWD" ++status=1 # failure is the default! ++ ++_cleanup() ++{ ++ _cleanup_qemu ++ _cleanup_test_img ++ rm -f "$TEST_IMG" "$DEST_IMG" ++} ++trap "_cleanup; exit \$status" 0 1 2 3 15 ++ ++# get standard environment, filters and checks ++. ./common.rc ++. ./common.filter ++. ./common.qemu ++ ++# Needs backing file and backing format support ++_supported_fmt qcow2 qed ++_supported_proto file ++_supported_os Linux ++ ++ ++DEST_IMG="$TEST_DIR/d.$IMGFMT" ++TEST_IMG="$TEST_DIR/b.$IMGFMT" ++ ++_make_test_img 2M ++ ++# destination for mirror will be too small, causing error ++TEST_IMG=$DEST_IMG _make_test_img 1M ++ ++$QEMU_IO -c 'write 0 2M' "$TEST_IMG" | _filter_qemu_io ++ ++_launch_qemu -drive id=testdisk,file="$TEST_IMG",format="$IMGFMT" ++ ++_send_qemu_cmd $QEMU_HANDLE \ ++ "{'execute': 'qmp_capabilities'}" \ ++ 'return' ++ ++echo ++echo '=== Starting drive-mirror, causing error & stop ===' ++echo ++ ++_send_qemu_cmd $QEMU_HANDLE \ ++ "{'execute': 'drive-mirror', ++ 'arguments': {'device': 'testdisk', ++ 'mode': 'absolute-paths', ++ 'format': '$IMGFMT', ++ 'target': '$DEST_IMG', ++ 'sync': 'full', ++ 'mode': 'existing', ++ 'on-source-error': 'stop', ++ 'on-target-error': 'stop' }}" \ ++ "JOB_STATUS_CHANGE.*pause" ++ ++echo ++echo '=== Force cancel job paused in error state ===' ++echo ++ ++success_or_failure="y" _send_qemu_cmd $QEMU_HANDLE \ ++ "{'execute': 'block-job-cancel', ++ 'arguments': { 'device': 'testdisk', ++ 'force': true}}" \ ++ "BLOCK_JOB_CANCELLED" "Assertion" ++ ++# success, all done ++echo "*** done" ++rm -f $seq.full ++status=0 +diff --git a/tests/qemu-iotests/229.out b/tests/qemu-iotests/229.out +new file mode 100644 +index 0000000..4c41128 +--- /dev/null ++++ b/tests/qemu-iotests/229.out +@@ -0,0 +1,23 @@ ++QA output created by 229 ++Formatting 'TEST_DIR/b.IMGFMT', fmt=IMGFMT size=2097152 ++Formatting 'TEST_DIR/d.IMGFMT', fmt=IMGFMT size=1048576 ++wrote 2097152/2097152 bytes at offset 0 ++2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) ++{"return": {}} ++ ++=== Starting drive-mirror, causing error & stop === ++ ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "testdisk"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "testdisk"}} ++{"return": {}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "testdisk", "operation": "write", "action": "stop"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "paused", "id": "testdisk"}} ++ ++=== Force cancel job paused in error state === ++ ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "testdisk"}} ++{"return": {}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "testdisk", "operation": "write", "action": "stop"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "testdisk"}} ++{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_CANCELLED", "data": {"device": "testdisk", "len": 2097152, "offset": 1048576, "speed": 0, "type": "mirror"}} ++*** done +diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group +index f1059f6..23ab4d3 100644 +--- a/tests/qemu-iotests/group ++++ b/tests/qemu-iotests/group +@@ -225,3 +225,4 @@ + 225 rw auto quick + 226 auto quick + 227 auto quick ++229 auto quick +-- +1.8.3.1 + diff --git a/0063-Revert-hw-acpi-build-build-SRAT-memory-affinity-stru.patch b/0063-Revert-hw-acpi-build-build-SRAT-memory-affinity-stru.patch new file mode 100644 index 0000000..9776c47 --- /dev/null +++ b/0063-Revert-hw-acpi-build-build-SRAT-memory-affinity-stru.patch @@ -0,0 +1,117 @@ +From c0bedad9bd133c14096eeeae49877fbb9eb179c3 Mon Sep 17 00:00:00 2001 +From: Igor Mammedov +Date: Thu, 4 Oct 2018 10:31:31 +0100 +Subject: Revert "hw/acpi-build: build SRAT memory affinity structures for DIMM + devices" + +RH-Author: Igor Mammedov +Message-id: <1538649091-70517-1-git-send-email-imammedo@redhat.com> +Patchwork-id: 82373 +O-Subject: [RHEL8/virt-8.0.0 qemu-kvm PATCH] Revert "hw/acpi-build: build SRAT memory affinity structures for DIMM devices" +Bugzilla: 1609235 +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Michael S. Tsirkin +RH-Acked-by: Thomas Huth + +Since upstream commits + (0efd7e108 "pc: acpi: fix memory hotplug regression by reducing stub SRAT entry size") + (dbb6da8ba7 "pc: acpi: revert back to 1 SRAT entry for hotpluggable area") +hasn't been backported to RHEL8, it's sufficient to revert commit + (848a1cc1e8 "hw/acpi-build: build SRAT memory affinity structures for DIMM devices") +for the result to match the current upstream state and fix the bug. + +Signed-off-by: Igor Mammedov +Signed-off-by: Danilo C. L. de Paula + +Rebase notes (3.0.0): +- Replace hotplug_memory with device_memory in PCMachineState +--- + hw/i386/acpi-build.c | 65 ++++------------------------------------------------ + 1 file changed, 4 insertions(+), 61 deletions(-) + +diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c +index be9bdb5..f95516c 100644 +--- a/hw/i386/acpi-build.c ++++ b/hw/i386/acpi-build.c +@@ -2254,64 +2254,6 @@ build_tpm2(GArray *table_data, BIOSLinker *linker, GArray *tcpalog) + #define HOLE_640K_START (640 * KiB) + #define HOLE_640K_END (1 * MiB) + +-static void build_srat_hotpluggable_memory(GArray *table_data, uint64_t base, +- uint64_t len, int default_node) +-{ +- MemoryDeviceInfoList *info_list = qmp_memory_device_list(); +- MemoryDeviceInfoList *info; +- MemoryDeviceInfo *mi; +- PCDIMMDeviceInfo *di; +- uint64_t end = base + len, cur, size; +- bool is_nvdimm; +- AcpiSratMemoryAffinity *numamem; +- MemoryAffinityFlags flags; +- +- for (cur = base, info = info_list; +- cur < end; +- cur += size, info = info->next) { +- numamem = acpi_data_push(table_data, sizeof *numamem); +- +- if (!info) { +- /* +- * Entry is required for Windows to enable memory hotplug in OS +- * and for Linux to enable SWIOTLB when booted with less than +- * 4G of RAM. Windows works better if the entry sets proximity +- * to the highest NUMA node in the machine at the end of the +- * reserved space. +- * Memory devices may override proximity set by this entry, +- * providing _PXM method if necessary. +- */ +- build_srat_memory(numamem, end - 1, 1, default_node, +- MEM_AFFINITY_HOTPLUGGABLE | MEM_AFFINITY_ENABLED); +- break; +- } +- +- mi = info->value; +- is_nvdimm = (mi->type == MEMORY_DEVICE_INFO_KIND_NVDIMM); +- di = !is_nvdimm ? mi->u.dimm.data : mi->u.nvdimm.data; +- +- if (cur < di->addr) { +- build_srat_memory(numamem, cur, di->addr - cur, default_node, +- MEM_AFFINITY_HOTPLUGGABLE | MEM_AFFINITY_ENABLED); +- numamem = acpi_data_push(table_data, sizeof *numamem); +- } +- +- size = di->size; +- +- flags = MEM_AFFINITY_ENABLED; +- if (di->hotpluggable) { +- flags |= MEM_AFFINITY_HOTPLUGGABLE; +- } +- if (is_nvdimm) { +- flags |= MEM_AFFINITY_NON_VOLATILE; +- } +- +- build_srat_memory(numamem, di->addr, size, di->node, flags); +- } +- +- qapi_free_MemoryDeviceInfoList(info_list); +-} +- + static void + build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine) + { +@@ -2418,9 +2360,10 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine) + } + + if (hotplugabble_address_space_size) { +- build_srat_hotpluggable_memory(table_data, machine->device_memory->base, +- hotplugabble_address_space_size, +- pcms->numa_nodes - 1); ++ numamem = acpi_data_push(table_data, sizeof *numamem); ++ build_srat_memory(numamem, machine->device_memory->base, ++ hotplugabble_address_space_size, pcms->numa_nodes - 1, ++ MEM_AFFINITY_HOTPLUGGABLE | MEM_AFFINITY_ENABLED); + } + + build_header(linker, table_data, +-- +1.8.3.1 + diff --git a/0064-aio-posix-Don-t-count-ctx-notifier-as-progress-when-.patch b/0064-aio-posix-Don-t-count-ctx-notifier-as-progress-when-.patch new file mode 100644 index 0000000..3fc21dd --- /dev/null +++ b/0064-aio-posix-Don-t-count-ctx-notifier-as-progress-when-.patch @@ -0,0 +1,48 @@ +From c476cf6c76298803fe896eb7c597085af3b73c12 Mon Sep 17 00:00:00 2001 +From: Fam Zheng +Date: Tue, 9 Oct 2018 08:16:47 +0100 +Subject: aio-posix: Don't count ctx->notifier as progress when polling + +RH-Author: Fam Zheng +Message-id: <20181009081651.15463-2-famz@redhat.com> +Patchwork-id: 82454 +O-Subject: [RHEL8/rhel qemu-kvm PATCH 1/5] aio-posix: Don't count ctx->notifier as progress when polling +Bugzilla: 1623085 +RH-Acked-by: Thomas Huth +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Danilo de Paula + +BZ: 1623085 + +The same logic exists in fd polling. This change is especially important +to avoid busy loop once we limit aio_notify_accept() to blocking +aio_poll(). + +Cc: qemu-stable@nongnu.org +Signed-off-by: Fam Zheng +Message-Id: <20180809132259.18402-2-famz@redhat.com> +Signed-off-by: Fam Zheng +(cherry picked from commit 70232b5253a3c4e03ed1ac47ef9246a8ac66c6fa) +Signed-off-by: Fam Zheng +Signed-off-by: Danilo C. L. de Paula +--- + util/aio-posix.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/util/aio-posix.c b/util/aio-posix.c +index 118bf57..b5c7f46 100644 +--- a/util/aio-posix.c ++++ b/util/aio-posix.c +@@ -494,7 +494,8 @@ static bool run_poll_handlers_once(AioContext *ctx) + QLIST_FOREACH_RCU(node, &ctx->aio_handlers, node) { + if (!node->deleted && node->io_poll && + aio_node_check(ctx, node->is_external) && +- node->io_poll(node->opaque)) { ++ node->io_poll(node->opaque) && ++ node->opaque != &ctx->notifier) { + progress = true; + } + +-- +1.8.3.1 + diff --git a/0065-aio-Do-aio_notify_accept-only-during-blocking-aio_po.patch b/0065-aio-Do-aio_notify_accept-only-during-blocking-aio_po.patch new file mode 100644 index 0000000..7b815ae --- /dev/null +++ b/0065-aio-Do-aio_notify_accept-only-during-blocking-aio_po.patch @@ -0,0 +1,124 @@ +From 1580d01151ceea428dc9a25dd3d83990a594e286 Mon Sep 17 00:00:00 2001 +From: Fam Zheng +Date: Tue, 9 Oct 2018 08:16:48 +0100 +Subject: aio: Do aio_notify_accept only during blocking aio_poll + +RH-Author: Fam Zheng +Message-id: <20181009081651.15463-3-famz@redhat.com> +Patchwork-id: 82450 +O-Subject: [RHEL8/rhel qemu-kvm PATCH 2/5] aio: Do aio_notify_accept only during blocking aio_poll +Bugzilla: 1623085 +RH-Acked-by: Thomas Huth +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Danilo de Paula + +BZ: 1623085 + +An aio_notify() pairs with an aio_notify_accept(). The former should +happen in the main thread or a vCPU thread, and the latter should be +done in the IOThread. + +There is one rare case that the main thread or vCPU thread may "steal" +the aio_notify() event just raised by itself, in bdrv_set_aio_context() +[1]. The sequence is like this: + + main thread IO Thread + =============================================================== + bdrv_drained_begin() + aio_disable_external(ctx) + aio_poll(ctx, true) + ctx->notify_me += 2 + ... + bdrv_drained_end() + ... + aio_notify() + ... + bdrv_set_aio_context() + aio_poll(ctx, false) +[1] aio_notify_accept(ctx) + ppoll() /* Hang! */ + +[1] is problematic. It will clear the ctx->notifier event so that +the blocked ppoll() will not return. + +(For the curious, this bug was noticed when booting a number of VMs +simultaneously in RHV. One or two of the VMs will hit this race +condition, making the VIRTIO device unresponsive to I/O commands. When +it hangs, Seabios is busy waiting for a read request to complete (read +MBR), right after initializing the virtio-blk-pci device, using 100% +guest CPU. See also https://bugzilla.redhat.com/show_bug.cgi?id=1562750 +for the original bug analysis.) + +aio_notify() only injects an event when ctx->notify_me is set, +correspondingly aio_notify_accept() is only useful when ctx->notify_me +_was_ set. Move the call to it into the "blocking" branch. This will +effectively skip [1] and fix the hang. + +Furthermore, blocking aio_poll is only allowed on home thread +(in_aio_context_home_thread), because otherwise two blocking +aio_poll()'s can steal each other's ctx->notifier event and cause +hanging just like described above. + +Cc: qemu-stable@nongnu.org +Suggested-by: Paolo Bonzini +Signed-off-by: Fam Zheng +Message-Id: <20180809132259.18402-3-famz@redhat.com> +Signed-off-by: Fam Zheng +(cherry picked from commit b37548fcd1b8ac2e88e185a395bef851f3fc4e65) +Signed-off-by: Fam Zheng +Signed-off-by: Danilo C. L. de Paula +--- + util/aio-posix.c | 4 ++-- + util/aio-win32.c | 3 ++- + 2 files changed, 4 insertions(+), 3 deletions(-) + +diff --git a/util/aio-posix.c b/util/aio-posix.c +index b5c7f46..b5c609b 100644 +--- a/util/aio-posix.c ++++ b/util/aio-posix.c +@@ -591,6 +591,7 @@ bool aio_poll(AioContext *ctx, bool blocking) + * so disable the optimization now. + */ + if (blocking) { ++ assert(in_aio_context_home_thread(ctx)); + atomic_add(&ctx->notify_me, 2); + } + +@@ -633,6 +634,7 @@ bool aio_poll(AioContext *ctx, bool blocking) + + if (blocking) { + atomic_sub(&ctx->notify_me, 2); ++ aio_notify_accept(ctx); + } + + /* Adjust polling time */ +@@ -676,8 +678,6 @@ bool aio_poll(AioContext *ctx, bool blocking) + } + } + +- aio_notify_accept(ctx); +- + /* if we have any readable fds, dispatch event */ + if (ret > 0) { + for (i = 0; i < npfd; i++) { +diff --git a/util/aio-win32.c b/util/aio-win32.c +index e676a8d..c58957c 100644 +--- a/util/aio-win32.c ++++ b/util/aio-win32.c +@@ -373,11 +373,12 @@ bool aio_poll(AioContext *ctx, bool blocking) + ret = WaitForMultipleObjects(count, events, FALSE, timeout); + if (blocking) { + assert(first); ++ assert(in_aio_context_home_thread(ctx)); + atomic_sub(&ctx->notify_me, 2); ++ aio_notify_accept(ctx); + } + + if (first) { +- aio_notify_accept(ctx); + progress |= aio_bh_poll(ctx); + first = false; + } +-- +1.8.3.1 + diff --git a/0066-aio-posix-fix-concurrent-access-to-poll_disable_cnt.patch b/0066-aio-posix-fix-concurrent-access-to-poll_disable_cnt.patch new file mode 100644 index 0000000..b1c677f --- /dev/null +++ b/0066-aio-posix-fix-concurrent-access-to-poll_disable_cnt.patch @@ -0,0 +1,122 @@ +From 07bbb6779b2a628b3e83b5474be550009aae034d Mon Sep 17 00:00:00 2001 +From: Fam Zheng +Date: Tue, 9 Oct 2018 08:16:49 +0100 +Subject: aio-posix: fix concurrent access to poll_disable_cnt + +RH-Author: Fam Zheng +Message-id: <20181009081651.15463-4-famz@redhat.com> +Patchwork-id: 82452 +O-Subject: [RHEL8/rhel qemu-kvm PATCH 3/5] aio-posix: fix concurrent access to poll_disable_cnt +Bugzilla: 1632622 +RH-Acked-by: Thomas Huth +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Danilo de Paula + +From: Paolo Bonzini + +BZ: 1632622 + +It is valid for an aio_set_fd_handler to happen concurrently with +aio_poll. In that case, poll_disable_cnt can change under the heels +of aio_poll, and the assertion on poll_disable_cnt can fail in +run_poll_handlers. + +Therefore, this patch simply checks the counter on every polling +iteration. There are no particular needs for ordering, since the +polling loop is terminated anyway by aio_notify at the end of +aio_set_fd_handler. + +Signed-off-by: Paolo Bonzini +Message-Id: <20180912171040.1732-2-pbonzini@redhat.com> +Reviewed-by: Fam Zheng +Signed-off-by: Fam Zheng +(cherry picked from commit d7be5dd19c0df7f76e1b42f0c2cbbabefa1974cb) +Signed-off-by: Fam Zheng +Signed-off-by: Danilo C. L. de Paula +--- + util/aio-posix.c | 26 +++++++++++++++----------- + 1 file changed, 15 insertions(+), 11 deletions(-) + +diff --git a/util/aio-posix.c b/util/aio-posix.c +index b5c609b..9189033 100644 +--- a/util/aio-posix.c ++++ b/util/aio-posix.c +@@ -211,6 +211,7 @@ void aio_set_fd_handler(AioContext *ctx, + AioHandler *node; + bool is_new = false; + bool deleted = false; ++ int poll_disable_change; + + qemu_lockcnt_lock(&ctx->list_lock); + +@@ -244,11 +245,9 @@ void aio_set_fd_handler(AioContext *ctx, + QLIST_REMOVE(node, node); + deleted = true; + } +- +- if (!node->io_poll) { +- ctx->poll_disable_cnt--; +- } ++ poll_disable_change = -!node->io_poll; + } else { ++ poll_disable_change = !io_poll - (node && !node->io_poll); + if (node == NULL) { + /* Alloc and insert if it's not already there */ + node = g_new0(AioHandler, 1); +@@ -257,10 +256,6 @@ void aio_set_fd_handler(AioContext *ctx, + + g_source_add_poll(&ctx->source, &node->pfd); + is_new = true; +- +- ctx->poll_disable_cnt += !io_poll; +- } else { +- ctx->poll_disable_cnt += !io_poll - !node->io_poll; + } + + /* Update handler with latest information */ +@@ -274,6 +269,15 @@ void aio_set_fd_handler(AioContext *ctx, + node->pfd.events |= (io_write ? G_IO_OUT | G_IO_ERR : 0); + } + ++ /* No need to order poll_disable_cnt writes against other updates; ++ * the counter is only used to avoid wasting time and latency on ++ * iterated polling when the system call will be ultimately necessary. ++ * Changing handlers is a rare event, and a little wasted polling until ++ * the aio_notify below is not an issue. ++ */ ++ atomic_set(&ctx->poll_disable_cnt, ++ atomic_read(&ctx->poll_disable_cnt) + poll_disable_change); ++ + aio_epoll_update(ctx, node, is_new); + qemu_lockcnt_unlock(&ctx->list_lock); + aio_notify(ctx); +@@ -525,7 +529,6 @@ static bool run_poll_handlers(AioContext *ctx, int64_t max_ns) + + assert(ctx->notify_me); + assert(qemu_lockcnt_count(&ctx->list_lock) > 0); +- assert(ctx->poll_disable_cnt == 0); + + trace_run_poll_handlers_begin(ctx, max_ns); + +@@ -533,7 +536,8 @@ static bool run_poll_handlers(AioContext *ctx, int64_t max_ns) + + do { + progress = run_poll_handlers_once(ctx); +- } while (!progress && qemu_clock_get_ns(QEMU_CLOCK_REALTIME) < end_time); ++ } while (!progress && qemu_clock_get_ns(QEMU_CLOCK_REALTIME) < end_time ++ && !atomic_read(&ctx->poll_disable_cnt)); + + trace_run_poll_handlers_end(ctx, progress); + +@@ -552,7 +556,7 @@ static bool run_poll_handlers(AioContext *ctx, int64_t max_ns) + */ + static bool try_poll_mode(AioContext *ctx, bool blocking) + { +- if (blocking && ctx->poll_max_ns && ctx->poll_disable_cnt == 0) { ++ if (blocking && ctx->poll_max_ns && !atomic_read(&ctx->poll_disable_cnt)) { + /* See qemu_soonest_timeout() uint64_t hack */ + int64_t max_ns = MIN((uint64_t)aio_compute_timeout(ctx), + (uint64_t)ctx->poll_ns); +-- +1.8.3.1 + diff --git a/0067-aio-posix-compute-timeout-before-polling.patch b/0067-aio-posix-compute-timeout-before-polling.patch new file mode 100644 index 0000000..3a5c4fe --- /dev/null +++ b/0067-aio-posix-compute-timeout-before-polling.patch @@ -0,0 +1,186 @@ +From 44bb29739a1cfa471447d6c5880e7527399b146f Mon Sep 17 00:00:00 2001 +From: Fam Zheng +Date: Tue, 9 Oct 2018 08:16:50 +0100 +Subject: aio-posix: compute timeout before polling + +RH-Author: Fam Zheng +Message-id: <20181009081651.15463-5-famz@redhat.com> +Patchwork-id: 82453 +O-Subject: [RHEL8/rhel qemu-kvm PATCH 4/5] aio-posix: compute timeout before polling +Bugzilla: 1632622 +RH-Acked-by: Thomas Huth +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Danilo de Paula + +From: Paolo Bonzini + +BZ: 1632622 + +This is a preparation for the next patch, and also a very small +optimization. Compute the timeout only once, before invoking +try_poll_mode, and adjust it in run_poll_handlers. The adjustment +is the polling time when polling fails, or zero (non-blocking) if +polling succeeds. + +Fixes: 70232b5253a3c4e03ed1ac47ef9246a8ac66c6fa +Signed-off-by: Paolo Bonzini +Message-Id: <20180912171040.1732-3-pbonzini@redhat.com> +Reviewed-by: Fam Zheng +Signed-off-by: Fam Zheng +(cherry picked from commit e30cffa04d52e35996569f1cfac111be19576bde) +Signed-off-by: Fam Zheng +Signed-off-by: Danilo C. L. de Paula +--- + util/aio-posix.c | 59 ++++++++++++++++++++++++++++++++----------------------- + util/trace-events | 4 ++-- + 2 files changed, 36 insertions(+), 27 deletions(-) + +diff --git a/util/aio-posix.c b/util/aio-posix.c +index 9189033..bb862e1 100644 +--- a/util/aio-posix.c ++++ b/util/aio-posix.c +@@ -490,7 +490,7 @@ static void add_pollfd(AioHandler *node) + npfd++; + } + +-static bool run_poll_handlers_once(AioContext *ctx) ++static bool run_poll_handlers_once(AioContext *ctx, int64_t *timeout) + { + bool progress = false; + AioHandler *node; +@@ -500,6 +500,7 @@ static bool run_poll_handlers_once(AioContext *ctx) + aio_node_check(ctx, node->is_external) && + node->io_poll(node->opaque) && + node->opaque != &ctx->notifier) { ++ *timeout = 0; + progress = true; + } + +@@ -522,31 +523,38 @@ static bool run_poll_handlers_once(AioContext *ctx) + * + * Returns: true if progress was made, false otherwise + */ +-static bool run_poll_handlers(AioContext *ctx, int64_t max_ns) ++static bool run_poll_handlers(AioContext *ctx, int64_t max_ns, int64_t *timeout) + { + bool progress; +- int64_t end_time; ++ int64_t start_time, elapsed_time; + + assert(ctx->notify_me); + assert(qemu_lockcnt_count(&ctx->list_lock) > 0); + +- trace_run_poll_handlers_begin(ctx, max_ns); +- +- end_time = qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + max_ns; ++ trace_run_poll_handlers_begin(ctx, max_ns, *timeout); + ++ start_time = qemu_clock_get_ns(QEMU_CLOCK_REALTIME); + do { +- progress = run_poll_handlers_once(ctx); +- } while (!progress && qemu_clock_get_ns(QEMU_CLOCK_REALTIME) < end_time ++ progress = run_poll_handlers_once(ctx, timeout); ++ elapsed_time = qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - start_time; ++ } while (!progress && elapsed_time < max_ns + && !atomic_read(&ctx->poll_disable_cnt)); + +- trace_run_poll_handlers_end(ctx, progress); ++ /* If time has passed with no successful polling, adjust *timeout to ++ * keep the same ending time. ++ */ ++ if (*timeout != -1) { ++ *timeout -= MIN(*timeout, elapsed_time); ++ } + ++ trace_run_poll_handlers_end(ctx, progress, *timeout); + return progress; + } + + /* try_poll_mode: + * @ctx: the AioContext +- * @blocking: busy polling is only attempted when blocking is true ++ * @timeout: timeout for blocking wait, computed by the caller and updated if ++ * polling succeeds. + * + * ctx->notify_me must be non-zero so this function can detect aio_notify(). + * +@@ -554,19 +562,16 @@ static bool run_poll_handlers(AioContext *ctx, int64_t max_ns) + * + * Returns: true if progress was made, false otherwise + */ +-static bool try_poll_mode(AioContext *ctx, bool blocking) ++static bool try_poll_mode(AioContext *ctx, int64_t *timeout) + { +- if (blocking && ctx->poll_max_ns && !atomic_read(&ctx->poll_disable_cnt)) { +- /* See qemu_soonest_timeout() uint64_t hack */ +- int64_t max_ns = MIN((uint64_t)aio_compute_timeout(ctx), +- (uint64_t)ctx->poll_ns); ++ /* See qemu_soonest_timeout() uint64_t hack */ ++ int64_t max_ns = MIN((uint64_t)*timeout, (uint64_t)ctx->poll_ns); + +- if (max_ns) { +- poll_set_started(ctx, true); ++ if (max_ns && !atomic_read(&ctx->poll_disable_cnt)) { ++ poll_set_started(ctx, true); + +- if (run_poll_handlers(ctx, max_ns)) { +- return true; +- } ++ if (run_poll_handlers(ctx, max_ns, timeout)) { ++ return true; + } + } + +@@ -575,7 +580,7 @@ static bool try_poll_mode(AioContext *ctx, bool blocking) + /* Even if we don't run busy polling, try polling once in case it can make + * progress and the caller will be able to avoid ppoll(2)/epoll_wait(2). + */ +- return run_poll_handlers_once(ctx); ++ return run_poll_handlers_once(ctx, timeout); + } + + bool aio_poll(AioContext *ctx, bool blocking) +@@ -605,8 +610,14 @@ bool aio_poll(AioContext *ctx, bool blocking) + start = qemu_clock_get_ns(QEMU_CLOCK_REALTIME); + } + +- progress = try_poll_mode(ctx, blocking); +- if (!progress) { ++ timeout = blocking ? aio_compute_timeout(ctx) : 0; ++ progress = try_poll_mode(ctx, &timeout); ++ assert(!(timeout && progress)); ++ ++ /* If polling is allowed, non-blocking aio_poll does not need the ++ * system call---a single round of run_poll_handlers_once suffices. ++ */ ++ if (timeout || atomic_read(&ctx->poll_disable_cnt)) { + assert(npfd == 0); + + /* fill pollfds */ +@@ -620,8 +631,6 @@ bool aio_poll(AioContext *ctx, bool blocking) + } + } + +- timeout = blocking ? aio_compute_timeout(ctx) : 0; +- + /* wait until next event */ + if (aio_epoll_check_poll(ctx, pollfds, npfd, timeout)) { + AioHandler epoll_handler; +diff --git a/util/trace-events b/util/trace-events +index 4822434..79569b7 100644 +--- a/util/trace-events ++++ b/util/trace-events +@@ -1,8 +1,8 @@ + # See docs/devel/tracing.txt for syntax documentation. + + # util/aio-posix.c +-run_poll_handlers_begin(void *ctx, int64_t max_ns) "ctx %p max_ns %"PRId64 +-run_poll_handlers_end(void *ctx, bool progress) "ctx %p progress %d" ++run_poll_handlers_begin(void *ctx, int64_t max_ns, int64_t timeout) "ctx %p max_ns %"PRId64 " timeout %"PRId64 ++run_poll_handlers_end(void *ctx, bool progress, int64_t timeout) "ctx %p progress %d new timeout %"PRId64 + poll_shrink(void *ctx, int64_t old, int64_t new) "ctx %p old %"PRId64" new %"PRId64 + poll_grow(void *ctx, int64_t old, int64_t new) "ctx %p old %"PRId64" new %"PRId64 + +-- +1.8.3.1 + diff --git a/0068-aio-posix-do-skip-system-call-if-ctx-notifier-pollin.patch b/0068-aio-posix-do-skip-system-call-if-ctx-notifier-pollin.patch new file mode 100644 index 0000000..cf50d42 --- /dev/null +++ b/0068-aio-posix-do-skip-system-call-if-ctx-notifier-pollin.patch @@ -0,0 +1,64 @@ +From ea1db6ad3fcbcda2068d3aeb21c384d42004aaaf Mon Sep 17 00:00:00 2001 +From: Fam Zheng +Date: Tue, 9 Oct 2018 08:16:51 +0100 +Subject: aio-posix: do skip system call if ctx->notifier polling succeeds + +RH-Author: Fam Zheng +Message-id: <20181009081651.15463-6-famz@redhat.com> +Patchwork-id: 82449 +O-Subject: [RHEL8/rhel qemu-kvm PATCH 5/5] aio-posix: do skip system call if ctx->notifier polling succeeds +Bugzilla: 1632622 +RH-Acked-by: Thomas Huth +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Danilo de Paula + +From: Paolo Bonzini + +BZ: 1632622 + +Commit 70232b5253 ("aio-posix: Don't count ctx->notifier as progress when +2018-08-15), by not reporting progress, causes aio_poll to execute the +system call when polling succeeds because of ctx->notifier. This introduces +latency before the call to aio_bh_poll() and negates the advantages of +polling, unfortunately. + +The fix builds on the previous patch, separating the effect of polling on +the timeout from the progress reported to aio_poll(). ctx->notifier +does zero the timeout, causing the caller to skip the system call, +but it does not report progress, so that the bug fix of commit 70232b5253 +still stands. + +Fixes: 70232b5253a3c4e03ed1ac47ef9246a8ac66c6fa +Signed-off-by: Paolo Bonzini +Message-Id: <20180912171040.1732-4-pbonzini@redhat.com> +Reviewed-by: Fam Zheng +Signed-off-by: Fam Zheng +(cherry picked from commit cfeb35d6774b2e936046aa9923217818bd160299) +Signed-off-by: Fam Zheng +Signed-off-by: Danilo C. L. de Paula +--- + util/aio-posix.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/util/aio-posix.c b/util/aio-posix.c +index bb862e1..a959ff6 100644 +--- a/util/aio-posix.c ++++ b/util/aio-posix.c +@@ -498,10 +498,11 @@ static bool run_poll_handlers_once(AioContext *ctx, int64_t *timeout) + QLIST_FOREACH_RCU(node, &ctx->aio_handlers, node) { + if (!node->deleted && node->io_poll && + aio_node_check(ctx, node->is_external) && +- node->io_poll(node->opaque) && +- node->opaque != &ctx->notifier) { ++ node->io_poll(node->opaque)) { + *timeout = 0; +- progress = true; ++ if (node->opaque != &ctx->notifier) { ++ progress = true; ++ } + } + + /* Caller handles freeing deleted nodes. Don't do it here. */ +-- +1.8.3.1 + diff --git a/0069-linux-headers-update.patch b/0069-linux-headers-update.patch new file mode 100644 index 0000000..a48ddbc --- /dev/null +++ b/0069-linux-headers-update.patch @@ -0,0 +1,202 @@ +From 7e13447e23269939c3d1267a957187a60fef36e9 Mon Sep 17 00:00:00 2001 +From: Thomas Huth +Date: Mon, 15 Oct 2018 10:19:26 +0100 +Subject: linux-headers: update + +RH-Author: Thomas Huth +Message-id: <1539598771-16223-2-git-send-email-thuth@redhat.com> +Patchwork-id: 82696 +O-Subject: [RHEL-8 qemu-kvm PATCH 1/6] linux-headers: update +Bugzilla: 1508142 +RH-Acked-by: David Hildenbrand +RH-Acked-by: Cornelia Huck +RH-Acked-by: Jens Freimann + +From: Cornelia Huck + +Update to kvm/next commit dd5bd0a65ff6 ("Merge tag 'kvm-s390-next-4.20-1' +of git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux into HEAD") + +Signed-off-by: Cornelia Huck +(cherry picked from commit 8f3cd250a897213d39e621e3d824507b48158d42) +Signed-off-by: Danilo C. L. de Paula + +Conflicts: + linux-headers/linux/kvm.h + linux-headers/linux/vhost.h + (simple contextual conflicts due to some missing patches in downstream) + +Signed-off-by: Thomas Huth +--- + include/standard-headers/linux/input.h | 9 +++++---- + linux-headers/asm-arm/kvm.h | 13 +++++++++++++ + linux-headers/asm-arm64/kvm.h | 13 +++++++++++++ + linux-headers/asm-s390/kvm.h | 2 ++ + linux-headers/asm-x86/kvm.h | 1 + + linux-headers/linux/kvm.h | 3 +++ + linux-headers/linux/vfio.h | 2 ++ + linux-headers/linux/vhost.h | 8 ++++++++ + 8 files changed, 47 insertions(+), 4 deletions(-) + +diff --git a/include/standard-headers/linux/input.h b/include/standard-headers/linux/input.h +index 6d6128c..c0ad9fc 100644 +--- a/include/standard-headers/linux/input.h ++++ b/include/standard-headers/linux/input.h +@@ -267,10 +267,11 @@ struct input_mask { + /* + * MT_TOOL types + */ +-#define MT_TOOL_FINGER 0 +-#define MT_TOOL_PEN 1 +-#define MT_TOOL_PALM 2 +-#define MT_TOOL_MAX 2 ++#define MT_TOOL_FINGER 0x00 ++#define MT_TOOL_PEN 0x01 ++#define MT_TOOL_PALM 0x02 ++#define MT_TOOL_DIAL 0x0a ++#define MT_TOOL_MAX 0x0f + + /* + * Values describing the status of a force-feedback effect +diff --git a/linux-headers/asm-arm/kvm.h b/linux-headers/asm-arm/kvm.h +index 72aa226..e1f8b74 100644 +--- a/linux-headers/asm-arm/kvm.h ++++ b/linux-headers/asm-arm/kvm.h +@@ -27,6 +27,7 @@ + #define __KVM_HAVE_GUEST_DEBUG + #define __KVM_HAVE_IRQ_LINE + #define __KVM_HAVE_READONLY_MEM ++#define __KVM_HAVE_VCPU_EVENTS + + #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 + +@@ -125,6 +126,18 @@ struct kvm_sync_regs { + struct kvm_arch_memory_slot { + }; + ++/* for KVM_GET/SET_VCPU_EVENTS */ ++struct kvm_vcpu_events { ++ struct { ++ __u8 serror_pending; ++ __u8 serror_has_esr; ++ /* Align it to 8 bytes */ ++ __u8 pad[6]; ++ __u64 serror_esr; ++ } exception; ++ __u32 reserved[12]; ++}; ++ + /* If you need to interpret the index values, here is the key: */ + #define KVM_REG_ARM_COPROC_MASK 0x000000000FFF0000 + #define KVM_REG_ARM_COPROC_SHIFT 16 +diff --git a/linux-headers/asm-arm64/kvm.h b/linux-headers/asm-arm64/kvm.h +index 99cb9ad..e6a98c1 100644 +--- a/linux-headers/asm-arm64/kvm.h ++++ b/linux-headers/asm-arm64/kvm.h +@@ -39,6 +39,7 @@ + #define __KVM_HAVE_GUEST_DEBUG + #define __KVM_HAVE_IRQ_LINE + #define __KVM_HAVE_READONLY_MEM ++#define __KVM_HAVE_VCPU_EVENTS + + #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 + +@@ -154,6 +155,18 @@ struct kvm_sync_regs { + struct kvm_arch_memory_slot { + }; + ++/* for KVM_GET/SET_VCPU_EVENTS */ ++struct kvm_vcpu_events { ++ struct { ++ __u8 serror_pending; ++ __u8 serror_has_esr; ++ /* Align it to 8 bytes */ ++ __u8 pad[6]; ++ __u64 serror_esr; ++ } exception; ++ __u32 reserved[12]; ++}; ++ + /* If you need to interpret the index values, here is the key: */ + #define KVM_REG_ARM_COPROC_MASK 0x000000000FFF0000 + #define KVM_REG_ARM_COPROC_SHIFT 16 +diff --git a/linux-headers/asm-s390/kvm.h b/linux-headers/asm-s390/kvm.h +index 1ab9901..0265482 100644 +--- a/linux-headers/asm-s390/kvm.h ++++ b/linux-headers/asm-s390/kvm.h +@@ -160,6 +160,8 @@ struct kvm_s390_vm_cpu_subfunc { + #define KVM_S390_VM_CRYPTO_ENABLE_DEA_KW 1 + #define KVM_S390_VM_CRYPTO_DISABLE_AES_KW 2 + #define KVM_S390_VM_CRYPTO_DISABLE_DEA_KW 3 ++#define KVM_S390_VM_CRYPTO_ENABLE_APIE 4 ++#define KVM_S390_VM_CRYPTO_DISABLE_APIE 5 + + /* kvm attributes for migration mode */ + #define KVM_S390_VM_MIGRATION_STOP 0 +diff --git a/linux-headers/asm-x86/kvm.h b/linux-headers/asm-x86/kvm.h +index c535c2f..9bba973 100644 +--- a/linux-headers/asm-x86/kvm.h ++++ b/linux-headers/asm-x86/kvm.h +@@ -377,5 +377,6 @@ struct kvm_sync_regs { + + #define KVM_X86_QUIRK_LINT0_REENABLED (1 << 0) + #define KVM_X86_QUIRK_CD_NW_CLEARED (1 << 1) ++#define KVM_X86_QUIRK_LAPIC_MMIO_HOLE (1 << 2) + + #endif /* _ASM_X86_KVM_H */ +diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h +index 2aae948..c4a5542 100644 +--- a/linux-headers/linux/kvm.h ++++ b/linux-headers/linux/kvm.h +@@ -950,6 +950,9 @@ struct kvm_ppc_resize_hpt { + #define KVM_CAP_HYPERV_EVENTFD 154 + #define KVM_CAP_HYPERV_TLBFLUSH 155 + #define KVM_CAP_S390_HPAGE_1M 156 ++#define KVM_CAP_NESTED_STATE 157 ++#define KVM_CAP_ARM_INJECT_SERROR_ESR 158 ++#define KVM_CAP_MSR_PLATFORM_INFO 159 + + #ifdef KVM_CAP_IRQ_ROUTING + +diff --git a/linux-headers/linux/vfio.h b/linux-headers/linux/vfio.h +index 3615a26..ceb6453 100644 +--- a/linux-headers/linux/vfio.h ++++ b/linux-headers/linux/vfio.h +@@ -200,6 +200,7 @@ struct vfio_device_info { + #define VFIO_DEVICE_FLAGS_PLATFORM (1 << 2) /* vfio-platform device */ + #define VFIO_DEVICE_FLAGS_AMBA (1 << 3) /* vfio-amba device */ + #define VFIO_DEVICE_FLAGS_CCW (1 << 4) /* vfio-ccw device */ ++#define VFIO_DEVICE_FLAGS_AP (1 << 5) /* vfio-ap device */ + __u32 num_regions; /* Max region index + 1 */ + __u32 num_irqs; /* Max IRQ index + 1 */ + }; +@@ -215,6 +216,7 @@ struct vfio_device_info { + #define VFIO_DEVICE_API_PLATFORM_STRING "vfio-platform" + #define VFIO_DEVICE_API_AMBA_STRING "vfio-amba" + #define VFIO_DEVICE_API_CCW_STRING "vfio-ccw" ++#define VFIO_DEVICE_API_AP_STRING "vfio-ap" + + /** + * VFIO_DEVICE_GET_REGION_INFO - _IOWR(VFIO_TYPE, VFIO_BASE + 8, +diff --git a/linux-headers/linux/vhost.h b/linux-headers/linux/vhost.h +index e336395..3421624 100644 +--- a/linux-headers/linux/vhost.h ++++ b/linux-headers/linux/vhost.h +@@ -160,6 +160,14 @@ struct vhost_memory { + #define VHOST_GET_VRING_BUSYLOOP_TIMEOUT _IOW(VHOST_VIRTIO, 0x24, \ + struct vhost_vring_state) + ++/* Set or get vhost backend capability */ ++ ++/* Use message type V2 */ ++#define VHOST_BACKEND_F_IOTLB_MSG_V2 0x1 ++ ++#define VHOST_SET_BACKEND_FEATURES _IOW(VHOST_VIRTIO, 0x25, __u64) ++#define VHOST_GET_BACKEND_FEATURES _IOR(VHOST_VIRTIO, 0x26, __u64) ++ + /* VHOST_NET specific defines */ + + /* Attach virtio net ring to a raw socket, or tap device. +-- +1.8.3.1 + diff --git a/0070-s390x-cpumodel-Set-up-CPU-model-for-AP-device-suppor.patch b/0070-s390x-cpumodel-Set-up-CPU-model-for-AP-device-suppor.patch new file mode 100644 index 0000000..dea147b --- /dev/null +++ b/0070-s390x-cpumodel-Set-up-CPU-model-for-AP-device-suppor.patch @@ -0,0 +1,148 @@ +From 9ceba72eb99b073a86b0aa529154de3e06330720 Mon Sep 17 00:00:00 2001 +From: Thomas Huth +Date: Mon, 15 Oct 2018 10:19:27 +0100 +Subject: s390x/cpumodel: Set up CPU model for AP device support + +RH-Author: Thomas Huth +Message-id: <1539598771-16223-3-git-send-email-thuth@redhat.com> +Patchwork-id: 82694 +O-Subject: [RHEL-8 qemu-kvm PATCH 2/6] s390x/cpumodel: Set up CPU model for AP device support +Bugzilla: 1508142 +RH-Acked-by: David Hildenbrand +RH-Acked-by: Cornelia Huck +RH-Acked-by: Jens Freimann + +From: Tony Krowiak + +A new CPU model feature and two new CPU model facilities are +introduced to support AP devices for a KVM guest. + +CPU model features: + +1. The S390_FEAT_AP CPU model feature indicates whether AP + instructions are available to the guest. This feature will + be enabled only if the AP instructions are available on the + linux host as determined by the availability of the + KVM_S390_VM_CRYPTO_ENABLE_APIE VM attribute which is exposed + by KVM only if the AP instructions are available on the + host. + + This feature must be turned on from userspace to execute AP + instructions on the KVM guest. The QEMU command line to turn + this feature on looks something like this: + + qemu-system-s390x ... -cpu xxx,ap=on ... + + This feature will be supported for zEC12 and newer CPU models. + The feature will not be supported for older models because + there are few older systems on which to test and the older + crypto cards will be going out of service in the relatively + near future. + +CPU model facilities: + +1. The S390_FEAT_AP_QUERY_CONFIG_INFO feature indicates whether the + AP Query Configuration Information (QCI) facility is available + to the guest as determined by whether the facility is available + on the host. This feature will be exposed by KVM only if the + QCI facility is installed on the host. + +2. The S390_FEAT_AP_FACILITY_TEST feature indicates whether the AP + Facility Test (APFT) facility is available to the guest as + determined by whether the facility is available on the host. + This feature will be exposed by KVM only if APFT is installed + on the host. + +Signed-off-by: Tony Krowiak +Tested-by: Pierre Morel +Reviewed-by: David Hildenbrand +Reviewed-by: Halil Pasic +Reviewed-by: Christian Borntraeger +Tested-by: Christian Borntraeger +Message-Id: <20181010170309.12045-3-akrowiak@linux.ibm.com> +Signed-off-by: Cornelia Huck +(cherry picked from commit c5cd17afddda89376712b315a41ede96b034e4c2) +Signed-off-by: Danilo C. L. de Paula +--- + target/s390x/cpu_features.c | 3 +++ + target/s390x/cpu_features_def.h | 3 +++ + target/s390x/cpu_models.c | 2 ++ + target/s390x/gen-features.c | 3 +++ + 4 files changed, 11 insertions(+) + +diff --git a/target/s390x/cpu_features.c b/target/s390x/cpu_features.c +index e05e6aa..0fbee27 100644 +--- a/target/s390x/cpu_features.c ++++ b/target/s390x/cpu_features.c +@@ -40,8 +40,10 @@ static const S390FeatDef s390_features[] = { + FEAT_INIT("srs", S390_FEAT_TYPE_STFL, 9, "Sense-running-status facility"), + FEAT_INIT("csske", S390_FEAT_TYPE_STFL, 10, "Conditional-SSKE facility"), + FEAT_INIT("ctop", S390_FEAT_TYPE_STFL, 11, "Configuration-topology facility"), ++ FEAT_INIT("apqci", S390_FEAT_TYPE_STFL, 12, "Query AP Configuration Information facility"), + FEAT_INIT("ipter", S390_FEAT_TYPE_STFL, 13, "IPTE-range facility"), + FEAT_INIT("nonqks", S390_FEAT_TYPE_STFL, 14, "Nonquiescing key-setting facility"), ++ FEAT_INIT("apft", S390_FEAT_TYPE_STFL, 15, "AP Facilities Test facility"), + FEAT_INIT("etf2", S390_FEAT_TYPE_STFL, 16, "Extended-translation facility 2"), + FEAT_INIT("msa-base", S390_FEAT_TYPE_STFL, 17, "Message-security-assist facility (excluding subfunctions)"), + FEAT_INIT("ldisp", S390_FEAT_TYPE_STFL, 18, "Long-displacement facility"), +@@ -130,6 +132,7 @@ static const S390FeatDef s390_features[] = { + + FEAT_INIT_MISC("dateh2", "DAT-enhancement facility 2"), + FEAT_INIT_MISC("cmm", "Collaborative-memory-management facility"), ++ FEAT_INIT_MISC("ap", "AP instructions installed"), + + FEAT_INIT("plo-cl", S390_FEAT_TYPE_PLO, 0, "PLO Compare and load (32 bit in general registers)"), + FEAT_INIT("plo-clg", S390_FEAT_TYPE_PLO, 1, "PLO Compare and load (64 bit in parameter list)"), +diff --git a/target/s390x/cpu_features_def.h b/target/s390x/cpu_features_def.h +index ac2c947..5fc7e7b 100644 +--- a/target/s390x/cpu_features_def.h ++++ b/target/s390x/cpu_features_def.h +@@ -27,8 +27,10 @@ typedef enum { + S390_FEAT_SENSE_RUNNING_STATUS, + S390_FEAT_CONDITIONAL_SSKE, + S390_FEAT_CONFIGURATION_TOPOLOGY, ++ S390_FEAT_AP_QUERY_CONFIG_INFO, + S390_FEAT_IPTE_RANGE, + S390_FEAT_NONQ_KEY_SETTING, ++ S390_FEAT_AP_FACILITIES_TEST, + S390_FEAT_EXTENDED_TRANSLATION_2, + S390_FEAT_MSA, + S390_FEAT_LONG_DISPLACEMENT, +@@ -119,6 +121,7 @@ typedef enum { + /* Misc */ + S390_FEAT_DAT_ENH_2, + S390_FEAT_CMM, ++ S390_FEAT_AP, + + /* PLO */ + S390_FEAT_PLO_CL, +diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c +index 9c469ff..a8722cd 100644 +--- a/target/s390x/cpu_models.c ++++ b/target/s390x/cpu_models.c +@@ -782,6 +782,8 @@ static void check_consistency(const S390CPUModel *model) + { S390_FEAT_PRNO_TRNG_QRTCR, S390_FEAT_MSA_EXT_5 }, + { S390_FEAT_PRNO_TRNG, S390_FEAT_MSA_EXT_5 }, + { S390_FEAT_SIE_KSS, S390_FEAT_SIE_F2 }, ++ { S390_FEAT_AP_QUERY_CONFIG_INFO, S390_FEAT_AP }, ++ { S390_FEAT_AP_FACILITIES_TEST, S390_FEAT_AP }, + }; + int i; + +diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c +index 5af042c..7302269 100644 +--- a/target/s390x/gen-features.c ++++ b/target/s390x/gen-features.c +@@ -447,6 +447,9 @@ static uint16_t full_GEN12_GA1[] = { + S390_FEAT_ADAPTER_INT_SUPPRESSION, + S390_FEAT_EDAT_2, + S390_FEAT_SIDE_EFFECT_ACCESS_ESOP2, ++ S390_FEAT_AP_QUERY_CONFIG_INFO, ++ S390_FEAT_AP_FACILITIES_TEST, ++ S390_FEAT_AP, + }; + + static uint16_t full_GEN12_GA2[] = { +-- +1.8.3.1 + diff --git a/0071-s390x-kvm-enable-AP-instruction-interpretation-for-g.patch b/0071-s390x-kvm-enable-AP-instruction-interpretation-for-g.patch new file mode 100644 index 0000000..47012cd --- /dev/null +++ b/0071-s390x-kvm-enable-AP-instruction-interpretation-for-g.patch @@ -0,0 +1,89 @@ +From ef6a15cefa04a4f29d0d800d17caa9a37c40b05c Mon Sep 17 00:00:00 2001 +From: Thomas Huth +Date: Mon, 15 Oct 2018 10:19:28 +0100 +Subject: s390x/kvm: enable AP instruction interpretation for guest + +RH-Author: Thomas Huth +Message-id: <1539598771-16223-4-git-send-email-thuth@redhat.com> +Patchwork-id: 82697 +O-Subject: [RHEL-8 qemu-kvm PATCH 3/6] s390x/kvm: enable AP instruction interpretation for guest +Bugzilla: 1508142 +RH-Acked-by: David Hildenbrand +RH-Acked-by: Cornelia Huck +RH-Acked-by: Jens Freimann + +From: Tony Krowiak + +Let's use the KVM_SET_DEVICE_ATTR ioctl to enable hardware +interpretation of AP instructions executed on the guest. +If the S390_FEAT_AP feature is switched on for the guest, +AP instructions must be interpreted by default; otherwise, +they will be intercepted. + +This attribute setting may be overridden by a device. For example, +a device may want to provide AP instructions to the guest (i.e., +S390_FEAT_AP turned on), but it may want to emulate them. In this +case, the AP instructions executed on the guest must be +intercepted; so when the device is realized, it must disable +interpretation. + +Signed-off-by: Tony Krowiak +Tested-by: Pierre Morel +Reviewed-by: David Hildenbrand +Reviewed-by: Thomas Huth +Reviewed-by: Christian Borntraeger +Acked-by: Halil Pasic +Tested-by: Christian Borntraeger +Message-Id: <20181010170309.12045-4-akrowiak@linux.ibm.com> +Signed-off-by: Cornelia Huck +(cherry picked from commit 1d7db85b61cb9888b8ed8c8923343b468405b7a0) +Signed-off-by: Danilo C. L. de Paula +--- + target/s390x/kvm.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c +index 71d90f2..d25e2e2 100644 +--- a/target/s390x/kvm.c ++++ b/target/s390x/kvm.c +@@ -2290,11 +2290,26 @@ void kvm_s390_get_host_cpu_model(S390CPUModel *model, Error **errp) + error_setg(errp, "KVM: host CPU model could not be identified"); + return; + } ++ /* for now, we can only provide the AP feature with HW support */ ++ if (kvm_vm_check_attr(kvm_state, KVM_S390_VM_CRYPTO, ++ KVM_S390_VM_CRYPTO_ENABLE_APIE)) { ++ set_bit(S390_FEAT_AP, model->features); ++ } + /* strip of features that are not part of the maximum model */ + bitmap_and(model->features, model->features, model->def->full_feat, + S390_FEAT_MAX); + } + ++static void kvm_s390_configure_apie(bool interpret) ++{ ++ uint64_t attr = interpret ? KVM_S390_VM_CRYPTO_ENABLE_APIE : ++ KVM_S390_VM_CRYPTO_DISABLE_APIE; ++ ++ if (kvm_vm_check_attr(kvm_state, KVM_S390_VM_CRYPTO, attr)) { ++ kvm_s390_set_attr(attr); ++ } ++} ++ + void kvm_s390_apply_cpu_model(const S390CPUModel *model, Error **errp) + { + struct kvm_s390_vm_cpu_processor prop = { +@@ -2352,6 +2367,10 @@ void kvm_s390_apply_cpu_model(const S390CPUModel *model, Error **errp) + if (test_bit(S390_FEAT_CMM, model->features)) { + kvm_s390_enable_cmma(); + } ++ ++ if (test_bit(S390_FEAT_AP, model->features)) { ++ kvm_s390_configure_apie(true); ++ } + } + + void kvm_s390_restart_interrupt(S390CPU *cpu) +-- +1.8.3.1 + diff --git a/0072-s390x-ap-base-Adjunct-Processor-AP-object-model.patch b/0072-s390x-ap-base-Adjunct-Processor-AP-object-model.patch new file mode 100644 index 0000000..9059681 --- /dev/null +++ b/0072-s390x-ap-base-Adjunct-Processor-AP-object-model.patch @@ -0,0 +1,281 @@ +From a57558fc97a82853d0c5e1e190297f7677598d5a Mon Sep 17 00:00:00 2001 +From: Thomas Huth +Date: Mon, 15 Oct 2018 10:19:29 +0100 +Subject: s390x/ap: base Adjunct Processor (AP) object model + +RH-Author: Thomas Huth +Message-id: <1539598771-16223-5-git-send-email-thuth@redhat.com> +Patchwork-id: 82695 +O-Subject: [RHEL-8 qemu-kvm PATCH 4/6] s390x/ap: base Adjunct Processor (AP) object model +Bugzilla: 1508142 +RH-Acked-by: David Hildenbrand +RH-Acked-by: Cornelia Huck +RH-Acked-by: Jens Freimann + +From: Tony Krowiak + +Introduces the base object model for virtualizing AP devices. + +Signed-off-by: Tony Krowiak +Tested-by: Pierre Morel +Acked-by: David Hildenbrand +Reviewed-by: Thomas Huth +Reviewed-by: Halil Pasic +Tested-by: Christian Borntraeger +Message-Id: <20181010170309.12045-5-akrowiak@linux.ibm.com> +Signed-off-by: Cornelia Huck +(cherry picked from commit a51b31535a8ec13997de29b357f7cc1dcd8a7f9c) +Signed-off-by: Danilo C. L. de Paula +--- + MAINTAINERS | 12 +++++++ + hw/s390x/Makefile.objs | 2 ++ + hw/s390x/ap-bridge.c | 78 ++++++++++++++++++++++++++++++++++++++++++++ + hw/s390x/ap-device.c | 38 +++++++++++++++++++++ + hw/s390x/s390-virtio-ccw.c | 4 +++ + include/hw/s390x/ap-bridge.h | 19 +++++++++++ + include/hw/s390x/ap-device.h | 22 +++++++++++++ + 7 files changed, 175 insertions(+) + create mode 100644 hw/s390x/ap-bridge.c + create mode 100644 hw/s390x/ap-device.c + create mode 100644 include/hw/s390x/ap-bridge.h + create mode 100644 include/hw/s390x/ap-device.h + +diff --git a/MAINTAINERS b/MAINTAINERS +index 666e936..d5b3c18 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -1184,6 +1184,18 @@ F: include/hw/s390x/s390-ccw.h + T: git git://github.com/cohuck/qemu.git s390-next + L: qemu-s390x@nongnu.org + ++vfio-ap ++M: Christian Borntraeger ++M: Tony Krowiak ++M: Halil Pasic ++M: Pierre Morel ++S: Supported ++F: hw/s390x/ap-device.c ++F: hw/s390x/ap-bridge.c ++F: include/hw/s390x/ap-device.h ++F: include/hw/s390x/ap-bridge.h ++L: qemu-s390x@nongnu.org ++ + vhost + M: Michael S. Tsirkin + S: Supported +diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs +index 93282f7..add89b1 100644 +--- a/hw/s390x/Makefile.objs ++++ b/hw/s390x/Makefile.objs +@@ -20,3 +20,5 @@ obj-$(CONFIG_TCG) += tod-qemu.o + obj-$(CONFIG_KVM) += s390-skeys-kvm.o + obj-$(CONFIG_KVM) += s390-stattrib-kvm.o + obj-y += s390-ccw.o ++obj-y += ap-device.o ++obj-y += ap-bridge.o +diff --git a/hw/s390x/ap-bridge.c b/hw/s390x/ap-bridge.c +new file mode 100644 +index 0000000..3795d30 +--- /dev/null ++++ b/hw/s390x/ap-bridge.c +@@ -0,0 +1,78 @@ ++/* ++ * ap bridge ++ * ++ * Copyright 2018 IBM Corp. ++ * ++ * This work is licensed under the terms of the GNU GPL, version 2 or (at ++ * your option) any later version. See the COPYING file in the top-level ++ * directory. ++ */ ++#include "qemu/osdep.h" ++#include "qapi/error.h" ++#include "hw/sysbus.h" ++#include "qemu/bitops.h" ++#include "hw/s390x/ap-bridge.h" ++#include "cpu.h" ++ ++static char *ap_bus_get_dev_path(DeviceState *dev) ++{ ++ /* at most one */ ++ return g_strdup_printf("/1"); ++} ++ ++static void ap_bus_class_init(ObjectClass *oc, void *data) ++{ ++ BusClass *k = BUS_CLASS(oc); ++ ++ k->get_dev_path = ap_bus_get_dev_path; ++ /* More than one ap device does not make sense */ ++ k->max_dev = 1; ++} ++ ++static const TypeInfo ap_bus_info = { ++ .name = TYPE_AP_BUS, ++ .parent = TYPE_BUS, ++ .instance_size = 0, ++ .class_init = ap_bus_class_init, ++}; ++ ++void s390_init_ap(void) ++{ ++ DeviceState *dev; ++ ++ /* If no AP instructions then no need for AP bridge */ ++ if (!s390_has_feat(S390_FEAT_AP)) { ++ return; ++ } ++ ++ /* Create bridge device */ ++ dev = qdev_create(NULL, TYPE_AP_BRIDGE); ++ object_property_add_child(qdev_get_machine(), TYPE_AP_BRIDGE, ++ OBJECT(dev), NULL); ++ qdev_init_nofail(dev); ++ ++ /* Create bus on bridge device */ ++ qbus_create(TYPE_AP_BUS, dev, TYPE_AP_BUS); ++ } ++ ++static void ap_bridge_class_init(ObjectClass *oc, void *data) ++{ ++ DeviceClass *dc = DEVICE_CLASS(oc); ++ ++ set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); ++} ++ ++static const TypeInfo ap_bridge_info = { ++ .name = TYPE_AP_BRIDGE, ++ .parent = TYPE_SYS_BUS_DEVICE, ++ .instance_size = 0, ++ .class_init = ap_bridge_class_init, ++}; ++ ++static void ap_register(void) ++{ ++ type_register_static(&ap_bridge_info); ++ type_register_static(&ap_bus_info); ++} ++ ++type_init(ap_register) +diff --git a/hw/s390x/ap-device.c b/hw/s390x/ap-device.c +new file mode 100644 +index 0000000..f5ac8db +--- /dev/null ++++ b/hw/s390x/ap-device.c +@@ -0,0 +1,38 @@ ++/* ++ * Adjunct Processor (AP) matrix device ++ * ++ * Copyright 2018 IBM Corp. ++ * ++ * This work is licensed under the terms of the GNU GPL, version 2 or (at ++ * your option) any later version. See the COPYING file in the top-level ++ * directory. ++ */ ++#include "qemu/osdep.h" ++#include "qemu/module.h" ++#include "qapi/error.h" ++#include "hw/qdev.h" ++#include "hw/s390x/ap-device.h" ++ ++static void ap_class_init(ObjectClass *klass, void *data) ++{ ++ DeviceClass *dc = DEVICE_CLASS(klass); ++ ++ dc->desc = "AP device class"; ++ dc->hotpluggable = false; ++} ++ ++static const TypeInfo ap_device_info = { ++ .name = AP_DEVICE_TYPE, ++ .parent = TYPE_DEVICE, ++ .instance_size = sizeof(APDevice), ++ .class_size = sizeof(DeviceClass), ++ .class_init = ap_class_init, ++ .abstract = true, ++}; ++ ++static void ap_device_register(void) ++{ ++ type_register_static(&ap_device_info); ++} ++ ++type_init(ap_device_register) +diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c +index cdf4558..a4b8b62 100644 +--- a/hw/s390x/s390-virtio-ccw.c ++++ b/hw/s390x/s390-virtio-ccw.c +@@ -32,6 +32,7 @@ + #include "ipl.h" + #include "hw/s390x/s390-virtio-ccw.h" + #include "hw/s390x/css-bridge.h" ++#include "hw/s390x/ap-bridge.h" + #include "migration/register.h" + #include "cpu_models.h" + #include "hw/nmi.h" +@@ -263,6 +264,9 @@ static void ccw_init(MachineState *machine) + /* init the SIGP facility */ + s390_init_sigp(); + ++ /* create AP bridge and bus(es) */ ++ s390_init_ap(); ++ + /* get a BUS */ + css_bus = virtual_css_bus_init(); + s390_init_ipl_dev(machine->kernel_filename, machine->kernel_cmdline, +diff --git a/include/hw/s390x/ap-bridge.h b/include/hw/s390x/ap-bridge.h +new file mode 100644 +index 0000000..470e439 +--- /dev/null ++++ b/include/hw/s390x/ap-bridge.h +@@ -0,0 +1,19 @@ ++/* ++ * ap bridge ++ * ++ * Copyright 2018 IBM Corp. ++ * ++ * This work is licensed under the terms of the GNU GPL, version 2 or (at ++ * your option) any later version. See the COPYING file in the top-level ++ * directory. ++ */ ++ ++#ifndef HW_S390X_AP_BRIDGE_H ++#define HW_S390X_AP_BRIDGE_H ++ ++#define TYPE_AP_BRIDGE "ap-bridge" ++#define TYPE_AP_BUS "ap-bus" ++ ++void s390_init_ap(void); ++ ++#endif +diff --git a/include/hw/s390x/ap-device.h b/include/hw/s390x/ap-device.h +new file mode 100644 +index 0000000..765e908 +--- /dev/null ++++ b/include/hw/s390x/ap-device.h +@@ -0,0 +1,22 @@ ++/* ++ * Adjunct Processor (AP) matrix device interfaces ++ * ++ * Copyright 2018 IBM Corp. ++ * ++ * This work is licensed under the terms of the GNU GPL, version 2 or (at ++ * your option) any later version. See the COPYING file in the top-level ++ * directory. ++ */ ++#ifndef HW_S390X_AP_DEVICE_H ++#define HW_S390X_AP_DEVICE_H ++ ++#define AP_DEVICE_TYPE "ap-device" ++ ++typedef struct APDevice { ++ DeviceState parent_obj; ++} APDevice; ++ ++#define AP_DEVICE(obj) \ ++ OBJECT_CHECK(APDevice, (obj), AP_DEVICE_TYPE) ++ ++#endif /* HW_S390X_AP_DEVICE_H */ +-- +1.8.3.1 + diff --git a/0073-s390x-vfio-ap-Introduce-VFIO-AP-device.patch b/0073-s390x-vfio-ap-Introduce-VFIO-AP-device.patch new file mode 100644 index 0000000..d4e8441 --- /dev/null +++ b/0073-s390x-vfio-ap-Introduce-VFIO-AP-device.patch @@ -0,0 +1,305 @@ +From 9f3a3325bb6859b1d3b46818a7d5b75c5d609f32 Mon Sep 17 00:00:00 2001 +From: Thomas Huth +Date: Mon, 15 Oct 2018 10:19:30 +0100 +Subject: s390x/vfio: ap: Introduce VFIO AP device + +RH-Author: Thomas Huth +Message-id: <1539598771-16223-6-git-send-email-thuth@redhat.com> +Patchwork-id: 82700 +O-Subject: [RHEL-8 qemu-kvm PATCH 5/6] s390x/vfio: ap: Introduce VFIO AP device +Bugzilla: 1508142 +RH-Acked-by: David Hildenbrand +RH-Acked-by: Cornelia Huck +RH-Acked-by: Jens Freimann + +From: Tony Krowiak + +Introduces a VFIO based AP device. The device is defined via +the QEMU command line by specifying: + + -device vfio-ap,sysfsdev= + +There may be only one vfio-ap device configured for a guest. + +The mediated matrix device is created by the VFIO AP device +driver by writing a UUID to a sysfs attribute file (see +docs/vfio-ap.txt). The mediated matrix device will be named +after the UUID. Symbolic links to the $uuid are created in +many places, so the path to the mediated matrix device $uuid +can be specified in any of the following ways: + +/sys/devices/vfio_ap/matrix/$uuid +/sys/devices/vfio_ap/matrix/mdev_supported_types/vfio_ap-passthrough/devices/$uuid +/sys/bus/mdev/devices/$uuid +/sys/bus/mdev/drivers/vfio_mdev/$uuid + +When the vfio-ap device is realized, it acquires and opens the +VFIO iommu group to which the mediated matrix device is +bound. This causes a VFIO group notification event to be +signaled. The vfio_ap device driver's group notification +handler will get called at which time the device driver +will configure the the AP devices to which the guest will +be granted access. + +Signed-off-by: Tony Krowiak +Tested-by: Pierre Morel +Acked-by: Halil Pasic +Tested-by: Pierre Morel +Tested-by: Christian Borntraeger +Message-Id: <20181010170309.12045-6-akrowiak@linux.ibm.com> +Reviewed-by: Thomas Huth +[CH: added missing g_free and device category] +Signed-off-by: Cornelia Huck + +(cherry picked from commit 2fe2942cd6ddad8ddd40fe5d16d67599c28959d7) +Signed-off-by: Danilo C. L. de Paula +--- + MAINTAINERS | 2 + + default-configs/s390x-softmmu.mak | 1 + + hw/vfio/Makefile.objs | 1 + + hw/vfio/ap.c | 181 ++++++++++++++++++++++++++++++++++++++ + include/hw/vfio/vfio-common.h | 1 + + 5 files changed, 186 insertions(+) + create mode 100644 hw/vfio/ap.c + +diff --git a/MAINTAINERS b/MAINTAINERS +index d5b3c18..f2fa1b8 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -88,6 +88,7 @@ F: hw/char/terminal3270.c + F: hw/intc/s390_flic.c + F: hw/intc/s390_flic_kvm.c + F: hw/s390x/ ++F: hw/vfio/ap.c + F: hw/vfio/ccw.c + F: hw/watchdog/wdt_diag288.c + F: include/hw/s390x/ +@@ -1194,6 +1195,7 @@ F: hw/s390x/ap-device.c + F: hw/s390x/ap-bridge.c + F: include/hw/s390x/ap-device.h + F: include/hw/s390x/ap-bridge.h ++F: hw/vfio/ap.c + L: qemu-s390x@nongnu.org + + vhost +diff --git a/default-configs/s390x-softmmu.mak b/default-configs/s390x-softmmu.mak +index 8b2db3e..49a59fc 100644 +--- a/default-configs/s390x-softmmu.mak ++++ b/default-configs/s390x-softmmu.mak +@@ -8,3 +8,4 @@ CONFIG_S390_FLIC_KVM=$(CONFIG_KVM) + # Disabled for Red Hat Enterprise Linux: + # CONFIG_VFIO_CCW=$(CONFIG_LINUX) + CONFIG_WDT_DIAG288=y ++CONFIG_VFIO_AP=$(CONFIG_LINUX) +diff --git a/hw/vfio/Makefile.objs b/hw/vfio/Makefile.objs +index d38205b..53b4cbe 100644 +--- a/hw/vfio/Makefile.objs ++++ b/hw/vfio/Makefile.objs +@@ -5,4 +5,5 @@ obj-$(CONFIG_VFIO_CCW) += ccw.o + obj-$(CONFIG_VFIO_XGMAC) += calxeda-xgmac.o + obj-$(CONFIG_VFIO_AMD_XGBE) += amd-xgbe.o + obj-$(CONFIG_SOFTMMU) += spapr.o ++obj-$(CONFIG_VFIO_AP) += ap.o + endif +diff --git a/hw/vfio/ap.c b/hw/vfio/ap.c +new file mode 100644 +index 0000000..3962bb7 +--- /dev/null ++++ b/hw/vfio/ap.c +@@ -0,0 +1,181 @@ ++/* ++ * VFIO based AP matrix device assignment ++ * ++ * Copyright 2018 IBM Corp. ++ * Author(s): Tony Krowiak ++ * Halil Pasic ++ * ++ * This work is licensed under the terms of the GNU GPL, version 2 or (at ++ * your option) any later version. See the COPYING file in the top-level ++ * directory. ++ */ ++ ++#include ++#include ++#include "qemu/osdep.h" ++#include "qapi/error.h" ++#include "hw/sysbus.h" ++#include "hw/vfio/vfio.h" ++#include "hw/vfio/vfio-common.h" ++#include "hw/s390x/ap-device.h" ++#include "qemu/error-report.h" ++#include "qemu/queue.h" ++#include "qemu/option.h" ++#include "qemu/config-file.h" ++#include "cpu.h" ++#include "kvm_s390x.h" ++#include "sysemu/sysemu.h" ++#include "hw/s390x/ap-bridge.h" ++#include "exec/address-spaces.h" ++ ++#define VFIO_AP_DEVICE_TYPE "vfio-ap" ++ ++typedef struct VFIOAPDevice { ++ APDevice apdev; ++ VFIODevice vdev; ++} VFIOAPDevice; ++ ++#define VFIO_AP_DEVICE(obj) \ ++ OBJECT_CHECK(VFIOAPDevice, (obj), VFIO_AP_DEVICE_TYPE) ++ ++static void vfio_ap_compute_needs_reset(VFIODevice *vdev) ++{ ++ vdev->needs_reset = false; ++} ++ ++/* ++ * We don't need vfio_hot_reset_multi and vfio_eoi operations for ++ * vfio-ap device now. ++ */ ++struct VFIODeviceOps vfio_ap_ops = { ++ .vfio_compute_needs_reset = vfio_ap_compute_needs_reset, ++}; ++ ++static void vfio_ap_put_device(VFIOAPDevice *vapdev) ++{ ++ g_free(vapdev->vdev.name); ++ vfio_put_base_device(&vapdev->vdev); ++} ++ ++static VFIOGroup *vfio_ap_get_group(VFIOAPDevice *vapdev, Error **errp) ++{ ++ GError *gerror = NULL; ++ char *symlink, *group_path; ++ int groupid; ++ ++ symlink = g_strdup_printf("%s/iommu_group", vapdev->vdev.sysfsdev); ++ group_path = g_file_read_link(symlink, &gerror); ++ g_free(symlink); ++ ++ if (!group_path) { ++ error_setg(errp, "%s: no iommu_group found for %s: %s", ++ VFIO_AP_DEVICE_TYPE, vapdev->vdev.sysfsdev, gerror->message); ++ return NULL; ++ } ++ ++ if (sscanf(basename(group_path), "%d", &groupid) != 1) { ++ error_setg(errp, "vfio: failed to read %s", group_path); ++ g_free(group_path); ++ return NULL; ++ } ++ ++ g_free(group_path); ++ ++ return vfio_get_group(groupid, &address_space_memory, errp); ++} ++ ++static void vfio_ap_realize(DeviceState *dev, Error **errp) ++{ ++ int ret; ++ char *mdevid; ++ Error *local_err = NULL; ++ VFIOGroup *vfio_group; ++ APDevice *apdev = AP_DEVICE(dev); ++ VFIOAPDevice *vapdev = VFIO_AP_DEVICE(apdev); ++ ++ vfio_group = vfio_ap_get_group(vapdev, &local_err); ++ if (!vfio_group) { ++ goto out_err; ++ } ++ ++ vapdev->vdev.ops = &vfio_ap_ops; ++ vapdev->vdev.type = VFIO_DEVICE_TYPE_AP; ++ mdevid = basename(vapdev->vdev.sysfsdev); ++ vapdev->vdev.name = g_strdup_printf("%s", mdevid); ++ vapdev->vdev.dev = dev; ++ ++ ret = vfio_get_device(vfio_group, mdevid, &vapdev->vdev, &local_err); ++ if (ret) { ++ goto out_get_dev_err; ++ } ++ ++ return; ++ ++out_get_dev_err: ++ vfio_ap_put_device(vapdev); ++ vfio_put_group(vfio_group); ++out_err: ++ error_propagate(errp, local_err); ++} ++ ++static void vfio_ap_unrealize(DeviceState *dev, Error **errp) ++{ ++ APDevice *apdev = AP_DEVICE(dev); ++ VFIOAPDevice *vapdev = VFIO_AP_DEVICE(apdev); ++ VFIOGroup *group = vapdev->vdev.group; ++ ++ vfio_ap_put_device(vapdev); ++ vfio_put_group(group); ++} ++ ++static Property vfio_ap_properties[] = { ++ DEFINE_PROP_STRING("sysfsdev", VFIOAPDevice, vdev.sysfsdev), ++ DEFINE_PROP_END_OF_LIST(), ++}; ++ ++static void vfio_ap_reset(DeviceState *dev) ++{ ++ int ret; ++ APDevice *apdev = AP_DEVICE(dev); ++ VFIOAPDevice *vapdev = VFIO_AP_DEVICE(apdev); ++ ++ ret = ioctl(vapdev->vdev.fd, VFIO_DEVICE_RESET); ++ if (ret) { ++ error_report("%s: failed to reset %s device: %s", __func__, ++ vapdev->vdev.name, strerror(ret)); ++ } ++} ++ ++static const VMStateDescription vfio_ap_vmstate = { ++ .name = VFIO_AP_DEVICE_TYPE, ++ .unmigratable = 1, ++}; ++ ++static void vfio_ap_class_init(ObjectClass *klass, void *data) ++{ ++ DeviceClass *dc = DEVICE_CLASS(klass); ++ ++ dc->props = vfio_ap_properties; ++ dc->vmsd = &vfio_ap_vmstate; ++ dc->desc = "VFIO-based AP device assignment"; ++ set_bit(DEVICE_CATEGORY_MISC, dc->categories); ++ dc->realize = vfio_ap_realize; ++ dc->unrealize = vfio_ap_unrealize; ++ dc->hotpluggable = false; ++ dc->reset = vfio_ap_reset; ++ dc->bus_type = TYPE_AP_BUS; ++} ++ ++static const TypeInfo vfio_ap_info = { ++ .name = VFIO_AP_DEVICE_TYPE, ++ .parent = AP_DEVICE_TYPE, ++ .instance_size = sizeof(VFIOAPDevice), ++ .class_init = vfio_ap_class_init, ++}; ++ ++static void vfio_ap_type_init(void) ++{ ++ type_register_static(&vfio_ap_info); ++} ++ ++type_init(vfio_ap_type_init) +diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h +index a903692..1389da4 100644 +--- a/include/hw/vfio/vfio-common.h ++++ b/include/hw/vfio/vfio-common.h +@@ -37,6 +37,7 @@ enum { + VFIO_DEVICE_TYPE_PCI = 0, + VFIO_DEVICE_TYPE_PLATFORM = 1, + VFIO_DEVICE_TYPE_CCW = 2, ++ VFIO_DEVICE_TYPE_AP = 3, + }; + + typedef struct VFIOMmap { +-- +1.8.3.1 + diff --git a/0074-s390-doc-detailed-specifications-for-AP-virtualizati.patch b/0074-s390-doc-detailed-specifications-for-AP-virtualizati.patch new file mode 100644 index 0000000..166fbc5 --- /dev/null +++ b/0074-s390-doc-detailed-specifications-for-AP-virtualizati.patch @@ -0,0 +1,889 @@ +From 8f59c31a8b0c4cde4bc92126d7102c1be9da97d4 Mon Sep 17 00:00:00 2001 +From: Thomas Huth +Date: Mon, 15 Oct 2018 10:19:31 +0100 +Subject: s390: doc: detailed specifications for AP virtualization + +RH-Author: Thomas Huth +Message-id: <1539598771-16223-7-git-send-email-thuth@redhat.com> +Patchwork-id: 82699 +O-Subject: [RHEL-8 qemu-kvm PATCH 6/6] s390: doc: detailed specifications for AP virtualization +Bugzilla: 1508142 +RH-Acked-by: David Hildenbrand +RH-Acked-by: Cornelia Huck +RH-Acked-by: Jens Freimann + +From: Tony Krowiak + +This patch provides documentation describing the AP architecture and +design concepts behind the virtualization of AP devices. It also +includes an example of how to configure AP devices for exclusive +use of KVM guests. + +Signed-off-by: Tony Krowiak +Reviewed-by: Pierre Morel +Tested-by: Pierre Morel +Tested-by: Christian Borntraeger +Message-Id: <20181010170309.12045-7-akrowiak@linux.ibm.com> +Signed-off-by: Cornelia Huck +(cherry picked from commit 694a8d703bfe06226a0574f5ec4af17a2b7060ef) +Signed-off-by: Danilo C. L. de Paula +--- + MAINTAINERS | 2 + + docs/vfio-ap.txt | 825 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 827 insertions(+) + create mode 100644 docs/vfio-ap.txt + +diff --git a/MAINTAINERS b/MAINTAINERS +index f2fa1b8..fdbfc04 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -96,6 +96,7 @@ F: include/hw/watchdog/wdt_diag288.h + F: pc-bios/s390-ccw/ + F: pc-bios/s390-ccw.img + F: target/s390x/ ++F: docs/vfio-ap.txt + K: ^Subject:.*(?i)s390x? + T: git git://github.com/cohuck/qemu.git s390-next + L: qemu-s390x@nongnu.org +@@ -1196,6 +1197,7 @@ F: hw/s390x/ap-bridge.c + F: include/hw/s390x/ap-device.h + F: include/hw/s390x/ap-bridge.h + F: hw/vfio/ap.c ++F: docs/vfio-ap.txt + L: qemu-s390x@nongnu.org + + vhost +diff --git a/docs/vfio-ap.txt b/docs/vfio-ap.txt +new file mode 100644 +index 0000000..1233968 +--- /dev/null ++++ b/docs/vfio-ap.txt +@@ -0,0 +1,825 @@ ++Adjunct Processor (AP) Device ++============================= ++ ++Contents: ++========= ++* Introduction ++* AP Architectural Overview ++* Start Interpretive Execution (SIE) Instruction ++* AP Matrix Configuration on Linux Host ++* Starting a Linux Guest Configured with an AP Matrix ++* Example: Configure AP Matrices for Three Linux Guests ++ ++Introduction: ++============ ++The IBM Adjunct Processor (AP) Cryptographic Facility is comprised ++of three AP instructions and from 1 to 256 PCIe cryptographic adapter cards. ++These AP devices provide cryptographic functions to all CPUs assigned to a ++linux system running in an IBM Z system LPAR. ++ ++On s390x, AP adapter cards are exposed via the AP bus. This document ++describes how those cards may be made available to KVM guests using the ++VFIO mediated device framework. ++ ++AP Architectural Overview: ++========================= ++In order understand the terminology used in the rest of this document, let's ++start with some definitions: ++ ++* AP adapter ++ ++ An AP adapter is an IBM Z adapter card that can perform cryptographic ++ functions. There can be from 0 to 256 adapters assigned to an LPAR depending ++ on the machine model. Adapters assigned to the LPAR in which a linux host is ++ running will be available to the linux host. Each adapter is identified by a ++ number from 0 to 255; however, the maximum adapter number allowed is ++ determined by machine model. When installed, an AP adapter is accessed by ++ AP instructions executed by any CPU. ++ ++* AP domain ++ ++ An adapter is partitioned into domains. Each domain can be thought of as ++ a set of hardware registers for processing AP instructions. An adapter can ++ hold up to 256 domains; however, the maximum domain number allowed is ++ determined by machine model. Each domain is identified by a number from 0 to ++ 255. Domains can be further classified into two types: ++ ++ * Usage domains are domains that can be accessed directly to process AP ++ commands ++ ++ * Control domains are domains that are accessed indirectly by AP ++ commands sent to a usage domain to control or change the domain; for ++ example, to set a secure private key for the domain. ++ ++* AP Queue ++ ++ An AP queue is the means by which an AP command-request message is sent to an ++ AP usage domain inside a specific AP. An AP queue is identified by a tuple ++ comprised of an AP adapter ID (APID) and an AP queue index (APQI). The ++ APQI corresponds to a given usage domain number within the adapter. This tuple ++ forms an AP Queue Number (APQN) uniquely identifying an AP queue. AP ++ instructions include a field containing the APQN to identify the AP queue to ++ which the AP command-request message is to be sent for processing. ++ ++* AP Instructions: ++ ++ There are three AP instructions: ++ ++ * NQAP: to enqueue an AP command-request message to a queue ++ * DQAP: to dequeue an AP command-reply message from a queue ++ * PQAP: to administer the queues ++ ++ AP instructions identify the domain that is targeted to process the AP ++ command; this must be one of the usage domains. An AP command may modify a ++ domain that is not one of the usage domains, but the modified domain ++ must be one of the control domains. ++ ++Start Interpretive Execution (SIE) Instruction ++============================================== ++A KVM guest is started by executing the Start Interpretive Execution (SIE) ++instruction. The SIE state description is a control block that contains the ++state information for a KVM guest and is supplied as input to the SIE ++instruction. The SIE state description contains a satellite control block called ++the Crypto Control Block (CRYCB). The CRYCB contains three fields to identify ++the adapters, usage domains and control domains assigned to the KVM guest: ++ ++* The AP Mask (APM) field is a bit mask that identifies the AP adapters assigned ++ to the KVM guest. Each bit in the mask, from left to right, corresponds to ++ an APID from 0-255. If a bit is set, the corresponding adapter is valid for ++ use by the KVM guest. ++ ++* The AP Queue Mask (AQM) field is a bit mask identifying the AP usage domains ++ assigned to the KVM guest. Each bit in the mask, from left to right, ++ corresponds to an AP queue index (APQI) from 0-255. If a bit is set, the ++ corresponding queue is valid for use by the KVM guest. ++ ++* The AP Domain Mask field is a bit mask that identifies the AP control domains ++ assigned to the KVM guest. The ADM bit mask controls which domains can be ++ changed by an AP command-request message sent to a usage domain from the ++ guest. Each bit in the mask, from left to right, corresponds to a domain from ++ 0-255. If a bit is set, the corresponding domain can be modified by an AP ++ command-request message sent to a usage domain. ++ ++If you recall from the description of an AP Queue, AP instructions include ++an APQN to identify the AP adapter and AP queue to which an AP command-request ++message is to be sent (NQAP and PQAP instructions), or from which a ++command-reply message is to be received (DQAP instruction). The validity of an ++APQN is defined by the matrix calculated from the APM and AQM; it is the ++cross product of all assigned adapter numbers (APM) with all assigned queue ++indexes (AQM). For example, if adapters 1 and 2 and usage domains 5 and 6 are ++assigned to a guest, the APQNs (1,5), (1,6), (2,5) and (2,6) will be valid for ++the guest. ++ ++The APQNs can provide secure key functionality - i.e., a private key is stored ++on the adapter card for each of its domains - so each APQN must be assigned to ++at most one guest or the linux host. ++ ++ Example 1: Valid configuration: ++ ------------------------------ ++ Guest1: adapters 1,2 domains 5,6 ++ Guest2: adapter 1,2 domain 7 ++ ++ This is valid because both guests have a unique set of APQNs: Guest1 has ++ APQNs (1,5), (1,6), (2,5) and (2,6); Guest2 has APQNs (1,7) and (2,7). ++ ++ Example 2: Valid configuration: ++ ------------------------------ ++ Guest1: adapters 1,2 domains 5,6 ++ Guest2: adapters 3,4 domains 5,6 ++ ++ This is also valid because both guests have a unique set of APQNs: ++ Guest1 has APQNs (1,5), (1,6), (2,5), (2,6); ++ Guest2 has APQNs (3,5), (3,6), (4,5), (4,6) ++ ++ Example 3: Invalid configuration: ++ -------------------------------- ++ Guest1: adapters 1,2 domains 5,6 ++ Guest2: adapter 1 domains 6,7 ++ ++ This is an invalid configuration because both guests have access to ++ APQN (1,6). ++ ++AP Matrix Configuration on Linux Host: ++===================================== ++A linux system is a guest of the LPAR in which it is running and has access to ++the AP resources configured for the LPAR. The LPAR's AP matrix is ++configured via its Activation Profile which can be edited on the HMC. When the ++linux system is started, the AP bus will detect the AP devices assigned to the ++LPAR and create the following in sysfs: ++ ++/sys/bus/ap ++... [devices] ++...... xx.yyyy ++...... ... ++...... cardxx ++...... ... ++ ++Where: ++ cardxx is AP adapter number xx (in hex) ++....xx.yyyy is an APQN with xx specifying the APID and yyyy specifying the ++ APQI ++ ++For example, if AP adapters 5 and 6 and domains 4, 71 (0x47), 171 (0xab) and ++255 (0xff) are configured for the LPAR, the sysfs representation on the linux ++host system would look like this: ++ ++/sys/bus/ap ++... [devices] ++...... 05.0004 ++...... 05.0047 ++...... 05.00ab ++...... 05.00ff ++...... 06.0004 ++...... 06.0047 ++...... 06.00ab ++...... 06.00ff ++...... card05 ++...... card06 ++ ++A set of default device drivers are also created to control each type of AP ++device that can be assigned to the LPAR on which a linux host is running: ++ ++/sys/bus/ap ++... [drivers] ++...... [cex2acard] for Crypto Express 2/3 accelerator cards ++...... [cex2aqueue] for AP queues served by Crypto Express 2/3 ++ accelerator cards ++...... [cex4card] for Crypto Express 4/5/6 accelerator and coprocessor ++ cards ++...... [cex4queue] for AP queues served by Crypto Express 4/5/6 ++ accelerator and coprocessor cards ++...... [pcixcccard] for Crypto Express 2/3 coprocessor cards ++...... [pcixccqueue] for AP queues served by Crypto Express 2/3 ++ coprocessor cards ++ ++Binding AP devices to device drivers ++------------------------------------ ++There are two sysfs files that specify bitmasks marking a subset of the APQN ++range as 'usable by the default AP queue device drivers' or 'not usable by the ++default device drivers' and thus available for use by the alternate device ++driver(s). The sysfs locations of the masks are: ++ ++ /sys/bus/ap/apmask ++ /sys/bus/ap/aqmask ++ ++ The 'apmask' is a 256-bit mask that identifies a set of AP adapter IDs ++ (APID). Each bit in the mask, from left to right (i.e., from most significant ++ to least significant bit in big endian order), corresponds to an APID from ++ 0-255. If a bit is set, the APID is marked as usable only by the default AP ++ queue device drivers; otherwise, the APID is usable by the vfio_ap ++ device driver. ++ ++ The 'aqmask' is a 256-bit mask that identifies a set of AP queue indexes ++ (APQI). Each bit in the mask, from left to right (i.e., from most significant ++ to least significant bit in big endian order), corresponds to an APQI from ++ 0-255. If a bit is set, the APQI is marked as usable only by the default AP ++ queue device drivers; otherwise, the APQI is usable by the vfio_ap device ++ driver. ++ ++ Take, for example, the following mask: ++ ++ 0x7dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ++ ++ It indicates: ++ ++ 1, 2, 3, 4, 5, and 7-255 belong to the default drivers' pool, and 0 and 6 ++ belong to the vfio_ap device driver's pool. ++ ++ The APQN of each AP queue device assigned to the linux host is checked by the ++ AP bus against the set of APQNs derived from the cross product of APIDs ++ and APQIs marked as usable only by the default AP queue device drivers. If a ++ match is detected, only the default AP queue device drivers will be probed; ++ otherwise, the vfio_ap device driver will be probed. ++ ++ By default, the two masks are set to reserve all APQNs for use by the default ++ AP queue device drivers. There are two ways the default masks can be changed: ++ ++ 1. The sysfs mask files can be edited by echoing a string into the ++ respective sysfs mask file in one of two formats: ++ ++ * An absolute hex string starting with 0x - like "0x12345678" - sets ++ the mask. If the given string is shorter than the mask, it is padded ++ with 0s on the right; for example, specifying a mask value of 0x41 is ++ the same as specifying: ++ ++ 0x4100000000000000000000000000000000000000000000000000000000000000 ++ ++ Keep in mind that the mask reads from left to right (i.e., most ++ significant to least significant bit in big endian order), so the mask ++ above identifies device numbers 1 and 7 (01000001). ++ ++ If the string is longer than the mask, the operation is terminated with ++ an error (EINVAL). ++ ++ * Individual bits in the mask can be switched on and off by specifying ++ each bit number to be switched in a comma separated list. Each bit ++ number string must be prepended with a ('+') or minus ('-') to indicate ++ the corresponding bit is to be switched on ('+') or off ('-'). Some ++ valid values are: ++ ++ "+0" switches bit 0 on ++ "-13" switches bit 13 off ++ "+0x41" switches bit 65 on ++ "-0xff" switches bit 255 off ++ ++ The following example: ++ +0,-6,+0x47,-0xf0 ++ ++ Switches bits 0 and 71 (0x47) on ++ Switches bits 6 and 240 (0xf0) off ++ ++ Note that the bits not specified in the list remain as they were before ++ the operation. ++ ++ 2. The masks can also be changed at boot time via parameters on the kernel ++ command line like this: ++ ++ ap.apmask=0xffff ap.aqmask=0x40 ++ ++ This would create the following masks: ++ ++ apmask: ++ 0xffff000000000000000000000000000000000000000000000000000000000000 ++ ++ aqmask: ++ 0x4000000000000000000000000000000000000000000000000000000000000000 ++ ++ Resulting in these two pools: ++ ++ default drivers pool: adapter 0-15, domain 1 ++ alternate drivers pool: adapter 16-255, domains 0, 2-255 ++ ++Configuring an AP matrix for a linux guest. ++------------------------------------------ ++The sysfs interfaces for configuring an AP matrix for a guest are built on the ++VFIO mediated device framework. To configure an AP matrix for a guest, a ++mediated matrix device must first be created for the /sys/devices/vfio_ap/matrix ++device. When the vfio_ap device driver is loaded, it registers with the VFIO ++mediated device framework. When the driver registers, the sysfs interfaces for ++creating mediated matrix devices is created: ++ ++/sys/devices ++... [vfio_ap] ++......[matrix] ++......... [mdev_supported_types] ++............ [vfio_ap-passthrough] ++............... create ++............... [devices] ++ ++A mediated AP matrix device is created by writing a UUID to the attribute file ++named 'create', for example: ++ ++ uuidgen > create ++ ++ or ++ ++ echo $uuid > create ++ ++When a mediated AP matrix device is created, a sysfs directory named after ++the UUID is created in the 'devices' subdirectory: ++ ++/sys/devices ++... [vfio_ap] ++......[matrix] ++......... [mdev_supported_types] ++............ [vfio_ap-passthrough] ++............... create ++............... [devices] ++.................. [$uuid] ++ ++There will also be three sets of attribute files created in the mediated ++matrix device's sysfs directory to configure an AP matrix for the ++KVM guest: ++ ++/sys/devices ++... [vfio_ap] ++......[matrix] ++......... [mdev_supported_types] ++............ [vfio_ap-passthrough] ++............... create ++............... [devices] ++.................. [$uuid] ++..................... assign_adapter ++..................... assign_control_domain ++..................... assign_domain ++..................... matrix ++..................... unassign_adapter ++..................... unassign_control_domain ++..................... unassign_domain ++ ++assign_adapter ++ To assign an AP adapter to the mediated matrix device, its APID is written ++ to the 'assign_adapter' file. This may be done multiple times to assign more ++ than one adapter. The APID may be specified using conventional semantics ++ as a decimal, hexadecimal, or octal number. For example, to assign adapters ++ 4, 5 and 16 to a mediated matrix device in decimal, hexadecimal and octal ++ respectively: ++ ++ echo 4 > assign_adapter ++ echo 0x5 > assign_adapter ++ echo 020 > assign_adapter ++ ++ In order to successfully assign an adapter: ++ ++ * The adapter number specified must represent a value from 0 up to the ++ maximum adapter number allowed by the machine model. If an adapter number ++ higher than the maximum is specified, the operation will terminate with ++ an error (ENODEV). ++ ++ * All APQNs that can be derived from the adapter ID being assigned and the ++ IDs of the previously assigned domains must be bound to the vfio_ap device ++ driver. If no domains have yet been assigned, then there must be at least ++ one APQN with the specified APID bound to the vfio_ap driver. If no such ++ APQNs are bound to the driver, the operation will terminate with an ++ error (EADDRNOTAVAIL). ++ ++ No APQN that can be derived from the adapter ID and the IDs of the ++ previously assigned domains can be assigned to another mediated matrix ++ device. If an APQN is assigned to another mediated matrix device, the ++ operation will terminate with an error (EADDRINUSE). ++ ++unassign_adapter ++ To unassign an AP adapter, its APID is written to the 'unassign_adapter' ++ file. This may also be done multiple times to unassign more than one adapter. ++ ++assign_domain ++ To assign a usage domain, the domain number is written into the ++ 'assign_domain' file. This may be done multiple times to assign more than one ++ usage domain. The domain number is specified using conventional semantics as ++ a decimal, hexadecimal, or octal number. For example, to assign usage domains ++ 4, 8, and 71 to a mediated matrix device in decimal, hexadecimal and octal ++ respectively: ++ ++ echo 4 > assign_domain ++ echo 0x8 > assign_domain ++ echo 0107 > assign_domain ++ ++ In order to successfully assign a domain: ++ ++ * The domain number specified must represent a value from 0 up to the ++ maximum domain number allowed by the machine model. If a domain number ++ higher than the maximum is specified, the operation will terminate with ++ an error (ENODEV). ++ ++ * All APQNs that can be derived from the domain ID being assigned and the IDs ++ of the previously assigned adapters must be bound to the vfio_ap device ++ driver. If no domains have yet been assigned, then there must be at least ++ one APQN with the specified APQI bound to the vfio_ap driver. If no such ++ APQNs are bound to the driver, the operation will terminate with an ++ error (EADDRNOTAVAIL). ++ ++ No APQN that can be derived from the domain ID being assigned and the IDs ++ of the previously assigned adapters can be assigned to another mediated ++ matrix device. If an APQN is assigned to another mediated matrix device, ++ the operation will terminate with an error (EADDRINUSE). ++ ++unassign_domain ++ To unassign a usage domain, the domain number is written into the ++ 'unassign_domain' file. This may be done multiple times to unassign more than ++ one usage domain. ++ ++assign_control_domain ++ To assign a control domain, the domain number is written into the ++ 'assign_control_domain' file. This may be done multiple times to ++ assign more than one control domain. The domain number may be specified using ++ conventional semantics as a decimal, hexadecimal, or octal number. For ++ example, to assign control domains 4, 8, and 71 to a mediated matrix device ++ in decimal, hexadecimal and octal respectively: ++ ++ echo 4 > assign_domain ++ echo 0x8 > assign_domain ++ echo 0107 > assign_domain ++ ++ In order to successfully assign a control domain, the domain number ++ specified must represent a value from 0 up to the maximum domain number ++ allowed by the machine model. If a control domain number higher than the ++ maximum is specified, the operation will terminate with an error (ENODEV). ++ ++unassign_control_domain ++ To unassign a control domain, the domain number is written into the ++ 'unassign_domain' file. This may be done multiple times to unassign more than ++ one control domain. ++ ++Notes: Hot plug/unplug is not currently supported for mediated AP matrix ++devices, so no changes to the AP matrix will be allowed while a guest using ++the mediated matrix device is running. Attempts to assign an adapter, ++domain or control domain will be rejected and an error (EBUSY) returned. ++ ++Starting a Linux Guest Configured with an AP Matrix: ++=================================================== ++To provide a mediated matrix device for use by a guest, the following option ++must be specified on the QEMU command line: ++ ++ -device vfio_ap,sysfsdev=$path-to-mdev ++ ++The sysfsdev parameter specifies the path to the mediated matrix device. ++There are a number of ways to specify this path: ++ ++/sys/devices/vfio_ap/matrix/$uuid ++/sys/bus/mdev/devices/$uuid ++/sys/bus/mdev/drivers/vfio_mdev/$uuid ++/sys/devices/vfio_ap/matrix/mdev_supported_types/vfio_ap-passthrough/devices/$uuid ++ ++When the linux guest is started, the guest will open the mediated ++matrix device's file descriptor to get information about the mediated matrix ++device. The vfio_ap device driver will update the APM, AQM, and ADM fields in ++the guest's CRYCB with the adapter, usage domain and control domains assigned ++via the mediated matrix device's sysfs attribute files. Programs running on the ++linux guest will then: ++ ++1. Have direct access to the APQNs derived from the cross product of the AP ++ adapter numbers (APID) and queue indexes (APQI) specified in the APM and AQM ++ fields of the guests's CRYCB respectively. These APQNs identify the AP queues ++ that are valid for use by the guest; meaning, AP commands can be sent by the ++ guest to any of these queues for processing. ++ ++2. Have authorization to process AP commands to change a control domain ++ identified in the ADM field of the guest's CRYCB. The AP command must be sent ++ to a valid APQN (see 1 above). ++ ++CPU model features: ++ ++Three CPU model features are available for controlling guest access to AP ++facilities: ++ ++1. AP facilities feature ++ ++ The AP facilities feature indicates that AP facilities are installed on the ++ guest. This feature will be exposed for use only if the AP facilities ++ are installed on the host system. The feature is s390-specific and is ++ represented as a parameter of the -cpu option on the QEMU command line: ++ ++ qemu-system-s390x -cpu $model,ap=on|off ++ ++ Where: ++ ++ $model is the CPU model defined for the guest (defaults to the model of ++ the host system if not specified). ++ ++ ap=on|off indicates whether AP facilities are installed (on) or not ++ (off). The default for CPU models zEC12 or newer ++ is ap=on. AP facilities must be installed on the guest if a ++ vfio-ap device (-device vfio-ap,sysfsdev=$path) is configured ++ for the guest, or the guest will fail to start. ++ ++2. Query Configuration Information (QCI) facility ++ ++ The QCI facility is used by the AP bus running on the guest to query the ++ configuration of the AP facilities. This facility will be available ++ only if the QCI facility is installed on the host system. The feature is ++ s390-specific and is represented as a parameter of the -cpu option on the ++ QEMU command line: ++ ++ qemu-system-s390x -cpu $model,apqci=on|off ++ ++ Where: ++ ++ $model is the CPU model defined for the guest ++ ++ apqci=on|off indicates whether the QCI facility is installed (on) or ++ not (off). The default for CPU models zEC12 or newer ++ is apqci=on; for older models, QCI will not be installed. ++ ++ If QCI is installed (apqci=on) but AP facilities are not ++ (ap=off), an error message will be logged, but the guest ++ will be allowed to start. It makes no sense to have QCI ++ installed if the AP facilities are not; this is considered ++ an invalid configuration. ++ ++ If the QCI facility is not installed, APQNs with an APQI ++ greater than 15 will not be detected by the AP bus ++ running on the guest. ++ ++3. Adjunct Process Facility Test (APFT) facility ++ ++ The APFT facility is used by the AP bus running on the guest to test the ++ AP facilities available for a given AP queue. This facility will be available ++ only if the APFT facility is installed on the host system. The feature is ++ s390-specific and is represented as a parameter of the -cpu option on the ++ QEMU command line: ++ ++ qemu-system-s390x -cpu $model,apft=on|off ++ ++ Where: ++ ++ $model is the CPU model defined for the guest (defaults to the model of ++ the host system if not specified). ++ ++ apft=on|off indicates whether the APFT facility is installed (on) or ++ not (off). The default for CPU models zEC12 and ++ newer is apft=on for older models, APFT will not be ++ installed. ++ ++ If APFT is installed (apft=on) but AP facilities are not ++ (ap=off), an error message will be logged, but the guest ++ will be allowed to start. It makes no sense to have APFT ++ installed if the AP facilities are not; this is considered ++ an invalid configuration. ++ ++ It also makes no sense to turn APFT off because the AP bus ++ running on the guest will not detect CEX4 and newer devices ++ without it. Since only CEX4 and newer devices are supported ++ for guest usage, no AP devices can be made accessible to a ++ guest started without APFT installed. ++ ++Example: Configure AP Matrixes for Three Linux Guests: ++===================================================== ++Let's now provide an example to illustrate how KVM guests may be given ++access to AP facilities. For this example, we will show how to configure ++three guests such that executing the lszcrypt command on the guests would ++look like this: ++ ++Guest1 ++------ ++CARD.DOMAIN TYPE MODE ++------------------------------ ++05 CEX5C CCA-Coproc ++05.0004 CEX5C CCA-Coproc ++05.00ab CEX5C CCA-Coproc ++06 CEX5A Accelerator ++06.0004 CEX5A Accelerator ++06.00ab CEX5C CCA-Coproc ++ ++Guest2 ++------ ++CARD.DOMAIN TYPE MODE ++------------------------------ ++05 CEX5A Accelerator ++05.0047 CEX5A Accelerator ++05.00ff CEX5A Accelerator (5,4), (5,171), (6,4), (6,171), ++ ++Guest3 ++------ ++CARD.DOMAIN TYPE MODE ++------------------------------ ++06 CEX5A Accelerator ++06.0047 CEX5A Accelerator ++06.00ff CEX5A Accelerator ++ ++These are the steps: ++ ++1. Install the vfio_ap module on the linux host. The dependency chain for the ++ vfio_ap module is: ++ * iommu ++ * s390 ++ * zcrypt ++ * vfio ++ * vfio_mdev ++ * vfio_mdev_device ++ * KVM ++ ++ To build the vfio_ap module, the kernel build must be configured with the ++ following Kconfig elements selected: ++ * IOMMU_SUPPORT ++ * S390 ++ * ZCRYPT ++ * S390_AP_IOMMU ++ * VFIO ++ * VFIO_MDEV ++ * VFIO_MDEV_DEVICE ++ * KVM ++ ++ If using make menuconfig select the following to build the vfio_ap module: ++ -> Device Drivers ++ -> IOMMU Hardware Support ++ select S390 AP IOMMU Support ++ -> VFIO Non-Privileged userspace driver framework ++ -> Mediated device driver frramework ++ -> VFIO driver for Mediated devices ++ -> I/O subsystem ++ -> VFIO support for AP devices ++ ++2. Secure the AP queues to be used by the three guests so that the host can not ++ access them. To secure the AP queues 05.0004, 05.0047, 05.00ab, 05.00ff, ++ 06.0004, 06.0047, 06.00ab, and 06.00ff for use by the vfio_ap device driver, ++ the corresponding APQNs must be removed from the default queue drivers pool ++ as follows: ++ ++ echo -5,-6 > /sys/bus/ap/apmask ++ ++ echo -4,-0x47,-0xab,-0xff > /sys/bus/ap/aqmask ++ ++ This will result in AP queues 05.0004, 05.0047, 05.00ab, 05.00ff, 06.0004, ++ 06.0047, 06.00ab, and 06.00ff getting bound to the vfio_ap device driver. The ++ sysfs directory for the vfio_ap device driver will now contain symbolic links ++ to the AP queue devices bound to it: ++ ++ /sys/bus/ap ++ ... [drivers] ++ ...... [vfio_ap] ++ ......... [05.0004] ++ ......... [05.0047] ++ ......... [05.00ab] ++ ......... [05.00ff] ++ ......... [06.0004] ++ ......... [06.0047] ++ ......... [06.00ab] ++ ......... [06.00ff] ++ ++ Keep in mind that only type 10 and newer adapters (i.e., CEX4 and later) ++ can be bound to the vfio_ap device driver. The reason for this is to ++ simplify the implementation by not needlessly complicating the design by ++ supporting older devices that will go out of service in the relatively near ++ future, and for which there are few older systems on which to test. ++ ++ The administrator, therefore, must take care to secure only AP queues that ++ can be bound to the vfio_ap device driver. The device type for a given AP ++ queue device can be read from the parent card's sysfs directory. For example, ++ to see the hardware type of the queue 05.0004: ++ ++ cat /sys/bus/ap/devices/card05/hwtype ++ ++ The hwtype must be 10 or higher (CEX4 or newer) in order to be bound to the ++ vfio_ap device driver. ++ ++3. Create the mediated devices needed to configure the AP matrixes for the ++ three guests and to provide an interface to the vfio_ap driver for ++ use by the guests: ++ ++ /sys/devices/vfio_ap/matrix/ ++ --- [mdev_supported_types] ++ ------ [vfio_ap-passthrough] (passthrough mediated matrix device type) ++ --------- create ++ --------- [devices] ++ ++ To create the mediated devices for the three guests: ++ ++ uuidgen > create ++ uuidgen > create ++ uuidgen > create ++ ++ or ++ ++ echo $uuid1 > create ++ echo $uuid2 > create ++ echo $uuid3 > create ++ ++ This will create three mediated devices in the [devices] subdirectory named ++ after the UUID used to create the mediated device. We'll call them $uuid1, ++ $uuid2 and $uuid3 and this is the sysfs directory structure after creation: ++ ++ /sys/devices/vfio_ap/matrix/ ++ --- [mdev_supported_types] ++ ------ [vfio_ap-passthrough] ++ --------- [devices] ++ ------------ [$uuid1] ++ --------------- assign_adapter ++ --------------- assign_control_domain ++ --------------- assign_domain ++ --------------- matrix ++ --------------- unassign_adapter ++ --------------- unassign_control_domain ++ --------------- unassign_domain ++ ++ ------------ [$uuid2] ++ --------------- assign_adapter ++ --------------- assign_control_domain ++ --------------- assign_domain ++ --------------- matrix ++ --------------- unassign_adapter ++ ----------------unassign_control_domain ++ ----------------unassign_domain ++ ++ ------------ [$uuid3] ++ --------------- assign_adapter ++ --------------- assign_control_domain ++ --------------- assign_domain ++ --------------- matrix ++ --------------- unassign_adapter ++ ----------------unassign_control_domain ++ ----------------unassign_domain ++ ++4. The administrator now needs to configure the matrixes for the mediated ++ devices $uuid1 (for Guest1), $uuid2 (for Guest2) and $uuid3 (for Guest3). ++ ++ This is how the matrix is configured for Guest1: ++ ++ echo 5 > assign_adapter ++ echo 6 > assign_adapter ++ echo 4 > assign_domain ++ echo 0xab > assign_domain ++ ++ Control domains can similarly be assigned using the assign_control_domain ++ sysfs file. ++ ++ If a mistake is made configuring an adapter, domain or control domain, ++ you can use the unassign_xxx interfaces to unassign the adapter, domain or ++ control domain. ++ ++ To display the matrix configuration for Guest1: ++ ++ cat matrix ++ ++ The output will display the APQNs in the format xx.yyyy, where xx is ++ the adapter number and yyyy is the domain number. The output for Guest1 ++ will look like this: ++ ++ 05.0004 ++ 05.00ab ++ 06.0004 ++ 06.00ab ++ ++ This is how the matrix is configured for Guest2: ++ ++ echo 5 > assign_adapter ++ echo 0x47 > assign_domain ++ echo 0xff > assign_domain ++ ++ This is how the matrix is configured for Guest3: ++ ++ echo 6 > assign_adapter ++ echo 0x47 > assign_domain ++ echo 0xff > assign_domain ++ ++5. Start Guest1: ++ ++ /usr/bin/qemu-system-s390x ... -cpu host,ap=on,apqci=on,apft=on \ ++ -device vfio-ap,sysfsdev=/sys/devices/vfio_ap/matrix/$uuid1 ... ++ ++7. Start Guest2: ++ ++ /usr/bin/qemu-system-s390x ... -cpu host,ap=on,apqci=on,apft=on \ ++ -device vfio-ap,sysfsdev=/sys/devices/vfio_ap/matrix/$uuid2 ... ++ ++7. Start Guest3: ++ ++ /usr/bin/qemu-system-s390x ... -cpu host,ap=on,apqci=on,apft=on \ ++ -device vfio-ap,sysfsdev=/sys/devices/vfio_ap/matrix/$uuid3 ... ++ ++When the guest is shut down, the mediated matrix devices may be removed. ++ ++Using our example again, to remove the mediated matrix device $uuid1: ++ ++ /sys/devices/vfio_ap/matrix/ ++ --- [mdev_supported_types] ++ ------ [vfio_ap-passthrough] ++ --------- [devices] ++ ------------ [$uuid1] ++ --------------- remove ++ ++ ++ echo 1 > remove ++ ++ This will remove all of the mdev matrix device's sysfs structures including ++ the mdev device itself. To recreate and reconfigure the mdev matrix device, ++ all of the steps starting with step 3 will have to be performed again. Note ++ that the remove will fail if a guest using the mdev is still running. ++ ++ It is not necessary to remove an mdev matrix device, but one may want to ++ remove it if no guest will use it during the remaining lifetime of the linux ++ host. If the mdev matrix device is removed, one may want to also reconfigure ++ the pool of adapters and queues reserved for use by the default drivers. ++ ++Limitations ++=========== ++* The KVM/kernel interfaces do not provide a way to prevent restoring an APQN ++ to the default drivers pool of a queue that is still assigned to a mediated ++ device in use by a guest. It is incumbent upon the administrator to ++ ensure there is no mediated device in use by a guest to which the APQN is ++ assigned lest the host be given access to the private data of the AP queue ++ device, such as a private key configured specifically for the guest. ++ ++* Dynamically modifying the AP matrix for a running guest (which would amount to ++ hot(un)plug of AP devices for the guest) is currently not supported ++ ++* Live guest migration is not supported for guests using AP devices. +-- +1.8.3.1 + diff --git a/0075-vnc-call-sasl_server_init-only-when-required.patch b/0075-vnc-call-sasl_server_init-only-when-required.patch new file mode 100644 index 0000000..292688c --- /dev/null +++ b/0075-vnc-call-sasl_server_init-only-when-required.patch @@ -0,0 +1,89 @@ +From dbf0257cf3587d5580765cbd2040f370820fb5e3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Tue, 2 Oct 2018 12:34:03 +0100 +Subject: vnc: call sasl_server_init() only when required +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Marc-André Lureau +Message-id: <20181002123403.20747-2-marcandre.lureau@redhat.com> +Patchwork-id: 82356 +O-Subject: [RHEL8/rhel qemu-kvm PATCH 1/1] vnc: call sasl_server_init() only when required +Bugzilla: 1609327 +RH-Acked-by: Daniel P. Berrange +RH-Acked-by: Thomas Huth +RH-Acked-by: Danilo de Paula + +VNC server is calling sasl_server_init() during startup of QEMU, even +if SASL auth has not been enabled. + +This may create undesirable warnings like "Could not find keytab file: +/etc/qemu/krb5.tab" when the user didn't configure SASL on host and +started VNC server. + +Instead, only initialize SASL when needed. Note that HMP/QMP "change +vnc" calls vnc_display_open() again, which will initialize SASL if +needed. + +Fix assignment in if condition, while touching this code. + +Related to: +https://bugzilla.redhat.com/show_bug.cgi?id=1609327 + +Signed-off-by: Marc-André Lureau +Reviewed-by: Daniel P. Berrangé +Message-id: 20180907063634.359-1-marcandre.lureau@redhat.com +Signed-off-by: Gerd Hoffmann + +(cherry picked from commit b5dc0d7d565048fcf2767060261d8385805aced1) + +BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1609327 +Brew: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=18601393 +Signed-off-by: Danilo C. L. de Paula + +Conflicts: + ui/vnc.c + Due to "qemu"->"qemu-kvm" rename. + +Signed-off-by: Marc-André Lureau +--- + ui/vnc.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/ui/vnc.c b/ui/vnc.c +index 050c421..b3fe7d7 100644 +--- a/ui/vnc.c ++++ b/ui/vnc.c +@@ -3878,9 +3878,6 @@ void vnc_display_open(const char *id, Error **errp) + bool reverse = false; + const char *credid; + bool sasl = false; +-#ifdef CONFIG_VNC_SASL +- int saslErr; +-#endif + int acl = 0; + int lock_key_sync = 1; + int key_delay_ms; +@@ -4054,10 +4051,14 @@ void vnc_display_open(const char *id, Error **errp) + trace_vnc_auth_init(vd, 1, vd->ws_auth, vd->ws_subauth); + + #ifdef CONFIG_VNC_SASL +- if ((saslErr = sasl_server_init(NULL, "qemu-kvm")) != SASL_OK) { +- error_setg(errp, "Failed to initialize SASL auth: %s", +- sasl_errstring(saslErr, NULL, NULL)); +- goto fail; ++ if (sasl) { ++ int saslErr = sasl_server_init(NULL, "qemu-kvm"); ++ ++ if (saslErr != SASL_OK) { ++ error_setg(errp, "Failed to initialize SASL auth: %s", ++ sasl_errstring(saslErr, NULL, NULL)); ++ goto fail; ++ } + } + #endif + vd->lock_key_sync = lock_key_sync; +-- +1.8.3.1 + diff --git a/0076-nbd-server-fix-NBD_CMD_CACHE.patch b/0076-nbd-server-fix-NBD_CMD_CACHE.patch new file mode 100644 index 0000000..05c36f6 --- /dev/null +++ b/0076-nbd-server-fix-NBD_CMD_CACHE.patch @@ -0,0 +1,52 @@ +From c10de200e291af4a6a5cb41ac10e1ae7a2b9c5b2 Mon Sep 17 00:00:00 2001 +From: John Snow +Date: Wed, 10 Oct 2018 18:19:23 +0100 +Subject: nbd/server: fix NBD_CMD_CACHE + +RH-Author: John Snow +Message-id: <20181010181924.30470-2-jsnow@redhat.com> +Patchwork-id: 82576 +O-Subject: [RHEL8/rhel qemu-kvm PATCH 1/2] nbd/server: fix NBD_CMD_CACHE +Bugzilla: 1636142 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Danilo de Paula +RH-Acked-by: Thomas Huth + +From: Vladimir Sementsov-Ogievskiy + +We should not go to structured-read branch on CACHE command, fix that. + +Bug introduced in bc37b06a5cde24 "nbd/server: introduce NBD_CMD_CACHE" +with the whole feature and affects 3.0.0 release. + +Signed-off-by: Vladimir Sementsov-Ogievskiy +CC: qemu-stable@nongnu.org +Message-Id: <20181003144738.70670-1-vsementsov@virtuozzo.com> +Reviewed-by: Eric Blake +[eblake: commit message typo fix] +Signed-off-by: Eric Blake +(cherry picked from commit 2f454defc23e1be78f2a96bad2877ce7829f61b4) +Signed-off-by: John Snow + +Signed-off-by: Danilo C. L. de Paula +--- + nbd/server.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/nbd/server.c b/nbd/server.c +index ea5fe0e..1ce3f44 100644 +--- a/nbd/server.c ++++ b/nbd/server.c +@@ -2135,7 +2135,8 @@ static coroutine_fn int nbd_do_cmd_read(NBDClient *client, NBDRequest *request, + } + + if (client->structured_reply && !(request->flags & NBD_CMD_FLAG_DF) && +- request->len) { ++ request->len && request->type != NBD_CMD_CACHE) ++ { + return nbd_co_send_sparse_read(client, request->handle, request->from, + data, request->len, errp); + } +-- +1.8.3.1 + diff --git a/0077-nbd-fix-NBD_FLAG_SEND_CACHE-value.patch b/0077-nbd-fix-NBD_FLAG_SEND_CACHE-value.patch new file mode 100644 index 0000000..c876e37 --- /dev/null +++ b/0077-nbd-fix-NBD_FLAG_SEND_CACHE-value.patch @@ -0,0 +1,96 @@ +From 24022cbbfd2230d4781a079d1856e0315895c8ce Mon Sep 17 00:00:00 2001 +From: John Snow +Date: Wed, 10 Oct 2018 18:19:24 +0100 +Subject: nbd: fix NBD_FLAG_SEND_CACHE value + +RH-Author: John Snow +Message-id: <20181010181924.30470-3-jsnow@redhat.com> +Patchwork-id: 82578 +O-Subject: [RHEL8/rhel qemu-kvm PATCH 2/2] nbd: fix NBD_FLAG_SEND_CACHE value +Bugzilla: 1636142 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Danilo de Paula +RH-Acked-by: Thomas Huth + +From: "Denis V. Lunev" + +Commit bc37b06a5 added NBD_CMD_CACHE support, but used the wrong value +for NBD_FLAG_SEND_CACHE flag for negotiation. That commit picked bit 8, +which had already been assigned by the NBD specification to mean +NBD_FLAG_CAN_MULTI_CONN, and which was already implemented in the +Linux kernel as a part of stable userspace-kernel API since 4.10: + +"bit 8, NBD_FLAG_CAN_MULTI_CONN: Indicates that the server operates +entirely without cache, or that the cache it uses is shared among all +connections to the given device. In particular, if this flag is +present, then the effects of NBD_CMD_FLUSH and NBD_CMD_FLAG_FUA +MUST be visible across all connections when the server sends its reply +to that command to the client. In the absense of this flag, clients +SHOULD NOT multiplex their commands over more than one connection to +the export. +... +bit 10, NBD_FLAG_SEND_CACHE: documents that the server understands +NBD_CMD_CACHE; however, note that server implementations exist +which support the command without advertising this bit, and +conversely that this bit does not guarantee that the command will +succeed or have an impact." + +Consequences: +- a client trying to use NBD_CMD_CACHE per the NBD spec will not +see the feature as available from a qemu 3.0 server (not fatal, +clients already have to be prepared for caching to not exist) +- a client accidentally coded to the qemu 3.0 bit value instead +of following the spec may interpret NBD_CMD_CACHE as being available +when it is not (probably not fatal, the spec says the server should +gracefully fail unknown commands, and that clients of NBD_CMD_CACHE +should be prepared for failure even when the feature is advertised); +such clients are unlikely (perhaps only in unreleased Virtuozzo code), +and will disappear over time +- a client prepared to use multiple connections based on +NBD_FLAG_CAN_MULTI_CONN may cause data corruption when it assumes +that caching is consistent when in reality qemu 3.0 did not have +a consistent cache. Partially mitigated by using read-only +connections (where nothing needs to be flushed, so caching is +indeed consistent) or when using qemu-nbd with the default -e 1 +(at most one client at a time); visible only when using -e 2 or +more for a writable export. + +Thus the commit fixes negotiation flag in QEMU according to the +specification. + +Signed-off-by: Denis V. Lunev +CC: Vladimir Sementsov-Ogievskiy +CC: Valery Vdovin +CC: Eric Blake +CC: Paolo Bonzini +CC: qemu-stable@nongnu.org +Message-Id: <20181004100313.4253-1-den@openvz.org> +Reviewed-by: Eric Blake +[eblake: enhance commit message, add defines for unimplemented flags] +Signed-off-by: Eric Blake +(cherry picked from commit df91328adab8490367776d2b21b35d790a606120) +Signed-off-by: John Snow + +Signed-off-by: Danilo C. L. de Paula +--- + include/block/nbd.h | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/include/block/nbd.h b/include/block/nbd.h +index 4638c83..a53b0cf 100644 +--- a/include/block/nbd.h ++++ b/include/block/nbd.h +@@ -135,7 +135,9 @@ typedef struct NBDExtent { + #define NBD_FLAG_SEND_TRIM (1 << 5) /* Send TRIM (discard) */ + #define NBD_FLAG_SEND_WRITE_ZEROES (1 << 6) /* Send WRITE_ZEROES */ + #define NBD_FLAG_SEND_DF (1 << 7) /* Send DF (Do not Fragment) */ +-#define NBD_FLAG_SEND_CACHE (1 << 8) /* Send CACHE (prefetch) */ ++#define NBD_FLAG_CAN_MULTI_CONN (1 << 8) /* Multi-client cache consistent */ ++#define NBD_FLAG_SEND_RESIZE (1 << 9) /* Send resize */ ++#define NBD_FLAG_SEND_CACHE (1 << 10) /* Send CACHE (prefetch) */ + + /* New-style handshake (global) flags, sent from server to client, and + control what will happen during handshake phase. */ +-- +1.8.3.1 + diff --git a/0078-block-linux-aio-acquire-AioContext-before-qemu_laio_.patch b/0078-block-linux-aio-acquire-AioContext-before-qemu_laio_.patch new file mode 100644 index 0000000..0e324f3 --- /dev/null +++ b/0078-block-linux-aio-acquire-AioContext-before-qemu_laio_.patch @@ -0,0 +1,134 @@ +From ca570895f9825c8ed6691bb520341ac9e07bac5a Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Wed, 10 Oct 2018 20:21:52 +0100 +Subject: block/linux-aio: acquire AioContext before + qemu_laio_process_completions + +RH-Author: Kevin Wolf +Message-id: <20181010202213.7372-14-kwolf@redhat.com> +Patchwork-id: 82603 +O-Subject: [RHEL-8 qemu-kvm PATCH 23/44] block/linux-aio: acquire AioContext before qemu_laio_process_completions +Bugzilla: 1637976 +RH-Acked-by: Max Reitz +RH-Acked-by: John Snow +RH-Acked-by: Thomas Huth + +From: Sergio Lopez + +In qemu_laio_process_completions_and_submit, the AioContext is acquired +before the ioq_submit iteration and after qemu_laio_process_completions, +but the latter is not thread safe either. + +This change avoids a number of random crashes when the Main Thread and +an IO Thread collide processing completions for the same AioContext. +This is an example of such crash: + + - The IO Thread is trying to acquire the AioContext at aio_co_enter, + which evidences that it didn't lock it before: + +Thread 3 (Thread 0x7fdfd8bd8700 (LWP 36743)): + #0 0x00007fdfe0dd542d in __lll_lock_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135 + #1 0x00007fdfe0dd0de6 in _L_lock_870 () at /lib64/libpthread.so.0 + #2 0x00007fdfe0dd0cdf in __GI___pthread_mutex_lock (mutex=mutex@entry=0x5631fde0e6c0) + at ../nptl/pthread_mutex_lock.c:114 + #3 0x00005631fc0603a7 in qemu_mutex_lock_impl (mutex=0x5631fde0e6c0, file=0x5631fc23520f "util/async.c", line=511) at util/qemu-thread-posix.c:66 + #4 0x00005631fc05b558 in aio_co_enter (ctx=0x5631fde0e660, co=0x7fdfcc0c2b40) at util/async.c:493 + #5 0x00005631fc05b5ac in aio_co_wake (co=) at util/async.c:478 + #6 0x00005631fbfc51ad in qemu_laio_process_completion (laiocb=) at block/linux-aio.c:104 + #7 0x00005631fbfc523c in qemu_laio_process_completions (s=s@entry=0x7fdfc0297670) + at block/linux-aio.c:222 + #8 0x00005631fbfc5499 in qemu_laio_process_completions_and_submit (s=0x7fdfc0297670) + at block/linux-aio.c:237 + #9 0x00005631fc05d978 in aio_dispatch_handlers (ctx=ctx@entry=0x5631fde0e660) at util/aio-posix.c:406 + #10 0x00005631fc05e3ea in aio_poll (ctx=0x5631fde0e660, blocking=blocking@entry=true) + at util/aio-posix.c:693 + #11 0x00005631fbd7ad96 in iothread_run (opaque=0x5631fde0e1c0) at iothread.c:64 + #12 0x00007fdfe0dcee25 in start_thread (arg=0x7fdfd8bd8700) at pthread_create.c:308 + #13 0x00007fdfe0afc34d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:113 + + - The Main Thread is also processing completions from the same + AioContext, and crashes due to failed assertion at util/iov.c:78: + +Thread 1 (Thread 0x7fdfeb5eac80 (LWP 36740)): + #0 0x00007fdfe0a391f7 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56 + #1 0x00007fdfe0a3a8e8 in __GI_abort () at abort.c:90 + #2 0x00007fdfe0a32266 in __assert_fail_base (fmt=0x7fdfe0b84e68 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=assertion@entry=0x5631fc238ccb "offset == 0", file=file@entry=0x5631fc23698e "util/iov.c", line=line@entry=78, function=function@entry=0x5631fc236adc <__PRETTY_FUNCTION__.15220> "iov_memset") + at assert.c:92 + #3 0x00007fdfe0a32312 in __GI___assert_fail (assertion=assertion@entry=0x5631fc238ccb "offset == 0", file=file@entry=0x5631fc23698e "util/iov.c", line=line@entry=78, function=function@entry=0x5631fc236adc <__PRETTY_FUNCTION__.15220> "iov_memset") at assert.c:101 + #4 0x00005631fc065287 in iov_memset (iov=, iov_cnt=, offset=, offset@entry=65536, fillc=fillc@entry=0, bytes=15515191315812405248) at util/iov.c:78 + #5 0x00005631fc065a63 in qemu_iovec_memset (qiov=, offset=offset@entry=65536, fillc=fillc@entry=0, bytes=) at util/iov.c:410 + #6 0x00005631fbfc5178 in qemu_laio_process_completion (laiocb=0x7fdd920df630) at block/linux-aio.c:88 + #7 0x00005631fbfc523c in qemu_laio_process_completions (s=s@entry=0x7fdfc0297670) + at block/linux-aio.c:222 + #8 0x00005631fbfc5499 in qemu_laio_process_completions_and_submit (s=0x7fdfc0297670) + at block/linux-aio.c:237 + #9 0x00005631fbfc54ed in qemu_laio_poll_cb (opaque=) at block/linux-aio.c:272 + #10 0x00005631fc05d85e in run_poll_handlers_once (ctx=ctx@entry=0x5631fde0e660) at util/aio-posix.c:497 + #11 0x00005631fc05e2ca in aio_poll (blocking=false, ctx=0x5631fde0e660) at util/aio-posix.c:574 + #12 0x00005631fc05e2ca in aio_poll (ctx=0x5631fde0e660, blocking=blocking@entry=false) + at util/aio-posix.c:604 + #13 0x00005631fbfcb8a3 in bdrv_do_drained_begin (ignore_parent=, recursive=, bs=) at block/io.c:273 + #14 0x00005631fbfcb8a3 in bdrv_do_drained_begin (bs=0x5631fe8b6200, recursive=, parent=0x0, ignore_bds_parents=, poll=) at block/io.c:390 + #15 0x00005631fbfbcd2e in blk_drain (blk=0x5631fe83ac80) at block/block-backend.c:1590 + #16 0x00005631fbfbe138 in blk_remove_bs (blk=blk@entry=0x5631fe83ac80) at block/block-backend.c:774 + #17 0x00005631fbfbe3d6 in blk_unref (blk=0x5631fe83ac80) at block/block-backend.c:401 + #18 0x00005631fbfbe3d6 in blk_unref (blk=0x5631fe83ac80) at block/block-backend.c:449 + #19 0x00005631fbfc9a69 in commit_complete (job=0x5631fe8b94b0, opaque=0x7fdfcc1bb080) + at block/commit.c:92 + #20 0x00005631fbf7d662 in job_defer_to_main_loop_bh (opaque=0x7fdfcc1b4560) at job.c:973 + #21 0x00005631fc05ad41 in aio_bh_poll (bh=0x7fdfcc01ad90) at util/async.c:90 + #22 0x00005631fc05ad41 in aio_bh_poll (ctx=ctx@entry=0x5631fddffdb0) at util/async.c:118 + #23 0x00005631fc05e210 in aio_dispatch (ctx=0x5631fddffdb0) at util/aio-posix.c:436 + #24 0x00005631fc05ac1e in aio_ctx_dispatch (source=, callback=, user_data=) at util/async.c:261 + #25 0x00007fdfeaae44c9 in g_main_context_dispatch (context=0x5631fde00140) at gmain.c:3201 + #26 0x00007fdfeaae44c9 in g_main_context_dispatch (context=context@entry=0x5631fde00140) at gmain.c:3854 + #27 0x00005631fc05d503 in main_loop_wait () at util/main-loop.c:215 + #28 0x00005631fc05d503 in main_loop_wait (timeout=) at util/main-loop.c:238 + #29 0x00005631fc05d503 in main_loop_wait (nonblocking=nonblocking@entry=0) at util/main-loop.c:497 + #30 0x00005631fbd81412 in main_loop () at vl.c:1866 + #31 0x00005631fbc18ff3 in main (argc=, argv=, envp=) + at vl.c:4647 + + - A closer examination shows that s->io_q.in_flight appears to have + gone backwards: + +(gdb) frame 7 + #7 0x00005631fbfc523c in qemu_laio_process_completions (s=s@entry=0x7fdfc0297670) + at block/linux-aio.c:222 +222 qemu_laio_process_completion(laiocb); +(gdb) p s +$2 = (LinuxAioState *) 0x7fdfc0297670 +(gdb) p *s +$3 = {aio_context = 0x5631fde0e660, ctx = 0x7fdfeb43b000, e = {rfd = 33, wfd = 33}, io_q = {plugged = 0, + in_queue = 0, in_flight = 4294967280, blocked = false, pending = {sqh_first = 0x0, + sqh_last = 0x7fdfc0297698}}, completion_bh = 0x7fdfc0280ef0, event_idx = 21, event_max = 241} +(gdb) p/x s->io_q.in_flight +$4 = 0xfffffff0 + +Signed-off-by: Sergio Lopez +Signed-off-by: Kevin Wolf +(cherry picked from commit e091f0e905a4481f347913420f327d427f18d9d4) +Signed-off-by: Kevin Wolf +Signed-off-by: Danilo C. L. de Paula +--- + block/linux-aio.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/block/linux-aio.c b/block/linux-aio.c +index 19eb922..217ce60 100644 +--- a/block/linux-aio.c ++++ b/block/linux-aio.c +@@ -234,9 +234,9 @@ static void qemu_laio_process_completions(LinuxAioState *s) + + static void qemu_laio_process_completions_and_submit(LinuxAioState *s) + { ++ aio_context_acquire(s->aio_context); + qemu_laio_process_completions(s); + +- aio_context_acquire(s->aio_context); + if (!s->io_q.plugged && !QSIMPLEQ_EMPTY(&s->io_q.pending)) { + ioq_submit(s); + } +-- +1.8.3.1 + diff --git a/0079-util-async-use-qemu_aio_coroutine_enter-in-co_schedu.patch b/0079-util-async-use-qemu_aio_coroutine_enter-in-co_schedu.patch new file mode 100644 index 0000000..7288227 --- /dev/null +++ b/0079-util-async-use-qemu_aio_coroutine_enter-in-co_schedu.patch @@ -0,0 +1,78 @@ +From faa3d5106cb296858227cc240e045ca16cb28c81 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Wed, 10 Oct 2018 20:21:53 +0100 +Subject: util/async: use qemu_aio_coroutine_enter in co_schedule_bh_cb + +RH-Author: Kevin Wolf +Message-id: <20181010202213.7372-15-kwolf@redhat.com> +Patchwork-id: 82604 +O-Subject: [RHEL-8 qemu-kvm PATCH 24/44] util/async: use qemu_aio_coroutine_enter in co_schedule_bh_cb +Bugzilla: 1637976 +RH-Acked-by: Max Reitz +RH-Acked-by: John Snow +RH-Acked-by: Thomas Huth + +From: Sergio Lopez + +AIO Coroutines shouldn't by managed by an AioContext different than the +one assigned when they are created. aio_co_enter avoids entering a +coroutine from a different AioContext, calling aio_co_schedule instead. + +Scheduled coroutines are then entered by co_schedule_bh_cb using +qemu_coroutine_enter, which just calls qemu_aio_coroutine_enter with the +current AioContext obtained with qemu_get_current_aio_context. +Eventually, co->ctx will be set to the AioContext passed as an argument +to qemu_aio_coroutine_enter. + +This means that, if an IO Thread's AioConext is being processed by the +Main Thread (due to aio_poll being called with a BDS AioContext, as it +happens in AIO_WAIT_WHILE among other places), the AioContext from some +coroutines may be wrongly replaced with the one from the Main Thread. + +This is the root cause behind some crashes, mainly triggered by the +drain code at block/io.c. The most common are these abort and failed +assertion: + +util/async.c:aio_co_schedule +456 if (scheduled) { +457 fprintf(stderr, +458 "%s: Co-routine was already scheduled in '%s'\n", +459 __func__, scheduled); +460 abort(); +461 } + +util/qemu-coroutine-lock.c: +286 assert(mutex->holder == self); + +But it's also known to cause random errors at different locations, and +even SIGSEGV with broken coroutine backtraces. + +By using qemu_aio_coroutine_enter directly in co_schedule_bh_cb, we can +pass the correct AioContext as an argument, making sure co->ctx is not +wrongly altered. + +Signed-off-by: Sergio Lopez +Signed-off-by: Kevin Wolf +(cherry picked from commit 6808ae0417131f8dbe7b051256dff7a16634dc1d) +Signed-off-by: Kevin Wolf +Signed-off-by: Danilo C. L. de Paula +--- + util/async.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/util/async.c b/util/async.c +index 05979f8..c10642a 100644 +--- a/util/async.c ++++ b/util/async.c +@@ -400,7 +400,7 @@ static void co_schedule_bh_cb(void *opaque) + + /* Protected by write barrier in qemu_aio_coroutine_enter */ + atomic_set(&co->scheduled, NULL); +- qemu_coroutine_enter(co); ++ qemu_aio_coroutine_enter(ctx, co); + aio_context_release(ctx); + } + } +-- +1.8.3.1 + diff --git a/0080-job-Fix-nested-aio_poll-hanging-in-job_txn_apply.patch b/0080-job-Fix-nested-aio_poll-hanging-in-job_txn_apply.patch new file mode 100644 index 0000000..568e097 --- /dev/null +++ b/0080-job-Fix-nested-aio_poll-hanging-in-job_txn_apply.patch @@ -0,0 +1,105 @@ +From f78998e365809f77ed146ee2afdcf132b12c838c Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Wed, 10 Oct 2018 20:21:54 +0100 +Subject: job: Fix nested aio_poll() hanging in job_txn_apply + +RH-Author: Kevin Wolf +Message-id: <20181010202213.7372-16-kwolf@redhat.com> +Patchwork-id: 82605 +O-Subject: [RHEL-8 qemu-kvm PATCH 25/44] job: Fix nested aio_poll() hanging in job_txn_apply +Bugzilla: 1637976 +RH-Acked-by: Max Reitz +RH-Acked-by: John Snow +RH-Acked-by: Thomas Huth + +From: Fam Zheng + +All callers have acquired ctx already. Doing that again results in +aio_poll() hang. This fixes the problem that a BDRV_POLL_WHILE() in the +callback cannot make progress because ctx is recursively locked, for +example, when drive-backup finishes. + +There are two callers of job_finalize(): + + fam@lemon:~/work/qemu [master]$ git grep -w -A1 '^\s*job_finalize' + blockdev.c: job_finalize(&job->job, errp); + blockdev.c- aio_context_release(aio_context); + -- + job-qmp.c: job_finalize(job, errp); + job-qmp.c- aio_context_release(aio_context); + -- + tests/test-blockjob.c: job_finalize(&job->job, &error_abort); + tests/test-blockjob.c- assert(job->job.status == JOB_STATUS_CONCLUDED); + +Ignoring the test, it's easy to see both callers to job_finalize (and +job_do_finalize) have acquired the context. + +Cc: qemu-stable@nongnu.org +Reported-by: Gu Nini +Reviewed-by: Eric Blake +Signed-off-by: Fam Zheng +Signed-off-by: Kevin Wolf +(cherry picked from commit 49880165a44f26dc84651858750facdee31f2513) +Signed-off-by: Kevin Wolf +Signed-off-by: Danilo C. L. de Paula +--- + job.c | 18 +++++------------- + 1 file changed, 5 insertions(+), 13 deletions(-) + +diff --git a/job.c b/job.c +index bb322de..82b4692 100644 +--- a/job.c ++++ b/job.c +@@ -136,21 +136,13 @@ static void job_txn_del_job(Job *job) + } + } + +-static int job_txn_apply(JobTxn *txn, int fn(Job *), bool lock) ++static int job_txn_apply(JobTxn *txn, int fn(Job *)) + { +- AioContext *ctx; + Job *job, *next; + int rc = 0; + + QLIST_FOREACH_SAFE(job, &txn->jobs, txn_list, next) { +- if (lock) { +- ctx = job->aio_context; +- aio_context_acquire(ctx); +- } + rc = fn(job); +- if (lock) { +- aio_context_release(ctx); +- } + if (rc) { + break; + } +@@ -780,11 +772,11 @@ static void job_do_finalize(Job *job) + assert(job && job->txn); + + /* prepare the transaction to complete */ +- rc = job_txn_apply(job->txn, job_prepare, true); ++ rc = job_txn_apply(job->txn, job_prepare); + if (rc) { + job_completed_txn_abort(job); + } else { +- job_txn_apply(job->txn, job_finalize_single, true); ++ job_txn_apply(job->txn, job_finalize_single); + } + } + +@@ -830,10 +822,10 @@ static void job_completed_txn_success(Job *job) + assert(other_job->ret == 0); + } + +- job_txn_apply(txn, job_transition_to_pending, false); ++ job_txn_apply(txn, job_transition_to_pending); + + /* If no jobs need manual finalization, automatically do so */ +- if (job_txn_apply(txn, job_needs_finalize, false) == 0) { ++ if (job_txn_apply(txn, job_needs_finalize) == 0) { + job_do_finalize(job); + } + } +-- +1.8.3.1 + diff --git a/0081-job-Fix-missing-locking-due-to-mismerge.patch b/0081-job-Fix-missing-locking-due-to-mismerge.patch new file mode 100644 index 0000000..76074d2 --- /dev/null +++ b/0081-job-Fix-missing-locking-due-to-mismerge.patch @@ -0,0 +1,55 @@ +From bb58f00a6c09bd1fe9af6dabe9ea173adc406d7b Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Wed, 10 Oct 2018 20:21:55 +0100 +Subject: job: Fix missing locking due to mismerge + +RH-Author: Kevin Wolf +Message-id: <20181010202213.7372-17-kwolf@redhat.com> +Patchwork-id: 82607 +O-Subject: [RHEL-8 qemu-kvm PATCH 26/44] job: Fix missing locking due to mismerge +Bugzilla: 1637976 +RH-Acked-by: Max Reitz +RH-Acked-by: John Snow +RH-Acked-by: Thomas Huth + +job_completed() had a problem with double locking that was recently +fixed independently by two different commits: + +"job: Fix nested aio_poll() hanging in job_txn_apply" +"jobs: add exit shim" + +One fix removed the first aio_context_acquire(), the other fix removed +the other one. Now we have a bug again and the code is run without any +locking. + +Add it back in one of the places. + +Signed-off-by: Kevin Wolf +Reviewed-by: Max Reitz +Reviewed-by: John Snow +(cherry picked from commit d1756c780b7879fb64e41135feac781d84a1f995) +Signed-off-by: Kevin Wolf +Signed-off-by: Danilo C. L. de Paula +--- + job.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/job.c b/job.c +index 82b4692..5c4e84f 100644 +--- a/job.c ++++ b/job.c +@@ -847,7 +847,11 @@ static void job_completed(Job *job) + static void job_exit(void *opaque) + { + Job *job = (Job *)opaque; ++ AioContext *ctx = job->aio_context; ++ ++ aio_context_acquire(ctx); + job_completed(job); ++ aio_context_release(ctx); + } + + /** +-- +1.8.3.1 + diff --git a/0082-blockjob-Wake-up-BDS-when-job-becomes-idle.patch b/0082-blockjob-Wake-up-BDS-when-job-becomes-idle.patch new file mode 100644 index 0000000..f51df38 --- /dev/null +++ b/0082-blockjob-Wake-up-BDS-when-job-becomes-idle.patch @@ -0,0 +1,161 @@ +From ac751d8909fa4b734fab48e27c0213df48ffd76b Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Wed, 10 Oct 2018 20:21:56 +0100 +Subject: blockjob: Wake up BDS when job becomes idle + +RH-Author: Kevin Wolf +Message-id: <20181010202213.7372-18-kwolf@redhat.com> +Patchwork-id: 82610 +O-Subject: [RHEL-8 qemu-kvm PATCH 27/44] blockjob: Wake up BDS when job becomes idle +Bugzilla: 1637976 +RH-Acked-by: Max Reitz +RH-Acked-by: John Snow +RH-Acked-by: Thomas Huth + +In the context of draining a BDS, the .drained_poll callback of block +jobs is called. If this returns true (i.e. there is still some activity +pending), the drain operation may call aio_poll() with blocking=true to +wait for completion. + +As soon as the pending activity is completed and the job finally arrives +in a quiescent state (i.e. its coroutine either yields with busy=false +or terminates), the block job must notify the aio_poll() loop to wake +up, otherwise we get a deadlock if both are running in different +threads. + +Signed-off-by: Kevin Wolf +Reviewed-by: Fam Zheng +Reviewed-by: Max Reitz +(cherry picked from commit 34dc97b9a0e592bc466bdb0bbfe45d77304a72b6) +Signed-off-by: Kevin Wolf +Signed-off-by: Danilo C. L. de Paula +--- + blockjob.c | 18 ++++++++++++++++++ + include/block/blockjob.h | 13 +++++++++++++ + include/qemu/job.h | 3 +++ + job.c | 7 +++++++ + 4 files changed, 41 insertions(+) + +diff --git a/blockjob.c b/blockjob.c +index be5903a..8d27e8e 100644 +--- a/blockjob.c ++++ b/blockjob.c +@@ -221,6 +221,22 @@ int block_job_add_bdrv(BlockJob *job, const char *name, BlockDriverState *bs, + return 0; + } + ++void block_job_wakeup_all_bdrv(BlockJob *job) ++{ ++ GSList *l; ++ ++ for (l = job->nodes; l; l = l->next) { ++ BdrvChild *c = l->data; ++ bdrv_wakeup(c->bs); ++ } ++} ++ ++static void block_job_on_idle(Notifier *n, void *opaque) ++{ ++ BlockJob *job = opaque; ++ block_job_wakeup_all_bdrv(job); ++} ++ + bool block_job_is_internal(BlockJob *job) + { + return (job->job.id == NULL); +@@ -419,6 +435,7 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver, + job->finalize_completed_notifier.notify = block_job_event_completed; + job->pending_notifier.notify = block_job_event_pending; + job->ready_notifier.notify = block_job_event_ready; ++ job->idle_notifier.notify = block_job_on_idle; + + notifier_list_add(&job->job.on_finalize_cancelled, + &job->finalize_cancelled_notifier); +@@ -426,6 +443,7 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver, + &job->finalize_completed_notifier); + notifier_list_add(&job->job.on_pending, &job->pending_notifier); + notifier_list_add(&job->job.on_ready, &job->ready_notifier); ++ notifier_list_add(&job->job.on_idle, &job->idle_notifier); + + error_setg(&job->blocker, "block device is in use by block job: %s", + job_type_str(&job->job)); +diff --git a/include/block/blockjob.h b/include/block/blockjob.h +index 32c00b7..2290bbb 100644 +--- a/include/block/blockjob.h ++++ b/include/block/blockjob.h +@@ -70,6 +70,9 @@ typedef struct BlockJob { + /** Called when the job transitions to READY */ + Notifier ready_notifier; + ++ /** Called when the job coroutine yields or terminates */ ++ Notifier idle_notifier; ++ + /** BlockDriverStates that are involved in this block job */ + GSList *nodes; + } BlockJob; +@@ -119,6 +122,16 @@ int block_job_add_bdrv(BlockJob *job, const char *name, BlockDriverState *bs, + void block_job_remove_all_bdrv(BlockJob *job); + + /** ++ * block_job_wakeup_all_bdrv: ++ * @job: The block job ++ * ++ * Calls bdrv_wakeup() for all BlockDriverStates that have been added to the ++ * job. This function is to be called whenever child_job_drained_poll() would ++ * go from true to false to notify waiting drain requests. ++ */ ++void block_job_wakeup_all_bdrv(BlockJob *job); ++ ++/** + * block_job_set_speed: + * @job: The job to set the speed for. + * @speed: The new value +diff --git a/include/qemu/job.h b/include/qemu/job.h +index 5cb0681..b4a784d 100644 +--- a/include/qemu/job.h ++++ b/include/qemu/job.h +@@ -156,6 +156,9 @@ typedef struct Job { + /** Notifiers called when the job transitions to READY */ + NotifierList on_ready; + ++ /** Notifiers called when the job coroutine yields or terminates */ ++ NotifierList on_idle; ++ + /** Element of the list of jobs */ + QLIST_ENTRY(Job) job_list; + +diff --git a/job.c b/job.c +index 5c4e84f..48a767c 100644 +--- a/job.c ++++ b/job.c +@@ -402,6 +402,11 @@ static void job_event_ready(Job *job) + notifier_list_notify(&job->on_ready, job); + } + ++static void job_event_idle(Job *job) ++{ ++ notifier_list_notify(&job->on_idle, job); ++} ++ + void job_enter_cond(Job *job, bool(*fn)(Job *job)) + { + if (!job_started(job)) { +@@ -447,6 +452,7 @@ static void coroutine_fn job_do_yield(Job *job, uint64_t ns) + timer_mod(&job->sleep_timer, ns); + } + job->busy = false; ++ job_event_idle(job); + job_unlock(); + qemu_coroutine_yield(); + +@@ -865,6 +871,7 @@ static void coroutine_fn job_co_entry(void *opaque) + assert(job && job->driver && job->driver->run); + job_pause_point(job); + job->ret = job->driver->run(job, &job->err); ++ job_event_idle(job); + job->deferred_to_main_loop = true; + aio_bh_schedule_oneshot(qemu_get_aio_context(), job_exit, job); + } +-- +1.8.3.1 + diff --git a/0083-aio-wait-Increase-num_waiters-even-in-home-thread.patch b/0083-aio-wait-Increase-num_waiters-even-in-home-thread.patch new file mode 100644 index 0000000..14b67eb --- /dev/null +++ b/0083-aio-wait-Increase-num_waiters-even-in-home-thread.patch @@ -0,0 +1,64 @@ +From 0e651f939d3fd65071a8edc8090a777bdb45b921 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Wed, 10 Oct 2018 20:21:57 +0100 +Subject: aio-wait: Increase num_waiters even in home thread + +RH-Author: Kevin Wolf +Message-id: <20181010202213.7372-19-kwolf@redhat.com> +Patchwork-id: 82609 +O-Subject: [RHEL-8 qemu-kvm PATCH 28/44] aio-wait: Increase num_waiters even in home thread +Bugzilla: 1637976 +RH-Acked-by: Max Reitz +RH-Acked-by: John Snow +RH-Acked-by: Thomas Huth + +Even if AIO_WAIT_WHILE() is called in the home context of the +AioContext, we still want to allow the condition to change depending on +other threads as long as they kick the AioWait. Specfically block jobs +can be running in an I/O thread and should then be able to kick a drain +in the main loop context. + +Signed-off-by: Kevin Wolf +Reviewed-by: Fam Zheng +(cherry picked from commit 486574483aba988c83b20e7d3f1ccd50c4c333d8) +Signed-off-by: Kevin Wolf +Signed-off-by: Danilo C. L. de Paula +--- + include/block/aio-wait.h | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/include/block/aio-wait.h b/include/block/aio-wait.h +index c85a62f..600fad1 100644 +--- a/include/block/aio-wait.h ++++ b/include/block/aio-wait.h +@@ -76,6 +76,8 @@ typedef struct { + bool waited_ = false; \ + AioWait *wait_ = (wait); \ + AioContext *ctx_ = (ctx); \ ++ /* Increment wait_->num_waiters before evaluating cond. */ \ ++ atomic_inc(&wait_->num_waiters); \ + if (ctx_ && in_aio_context_home_thread(ctx_)) { \ + while ((cond)) { \ + aio_poll(ctx_, true); \ +@@ -84,8 +86,6 @@ typedef struct { + } else { \ + assert(qemu_get_current_aio_context() == \ + qemu_get_aio_context()); \ +- /* Increment wait_->num_waiters before evaluating cond. */ \ +- atomic_inc(&wait_->num_waiters); \ + while ((cond)) { \ + if (ctx_) { \ + aio_context_release(ctx_); \ +@@ -96,8 +96,8 @@ typedef struct { + } \ + waited_ = true; \ + } \ +- atomic_dec(&wait_->num_waiters); \ + } \ ++ atomic_dec(&wait_->num_waiters); \ + waited_; }) + + /** +-- +1.8.3.1 + diff --git a/0084-test-bdrv-drain-Drain-with-block-jobs-in-an-I-O-thre.patch b/0084-test-bdrv-drain-Drain-with-block-jobs-in-an-I-O-thre.patch new file mode 100644 index 0000000..38d58ff --- /dev/null +++ b/0084-test-bdrv-drain-Drain-with-block-jobs-in-an-I-O-thre.patch @@ -0,0 +1,208 @@ +From 6d374393478f0d57ec8cd338342687d043565662 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Wed, 10 Oct 2018 20:21:58 +0100 +Subject: test-bdrv-drain: Drain with block jobs in an I/O thread + +RH-Author: Kevin Wolf +Message-id: <20181010202213.7372-20-kwolf@redhat.com> +Patchwork-id: 82608 +O-Subject: [RHEL-8 qemu-kvm PATCH 29/44] test-bdrv-drain: Drain with block jobs in an I/O thread +Bugzilla: 1637976 +RH-Acked-by: Max Reitz +RH-Acked-by: John Snow +RH-Acked-by: Thomas Huth + +This extends the existing drain test with a block job to include +variants where the block job runs in a different AioContext. + +Signed-off-by: Kevin Wolf +Reviewed-by: Fam Zheng +(cherry picked from commit f62c172959cd2b6de4dd8ba782e855d64d94764b) +Signed-off-by: Kevin Wolf +Signed-off-by: Danilo C. L. de Paula +--- + tests/test-bdrv-drain.c | 92 +++++++++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 86 insertions(+), 6 deletions(-) + +diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c +index 9bcb3c7..3cf3ba3 100644 +--- a/tests/test-bdrv-drain.c ++++ b/tests/test-bdrv-drain.c +@@ -174,6 +174,28 @@ static void do_drain_end(enum drain_type drain_type, BlockDriverState *bs) + } + } + ++static void do_drain_begin_unlocked(enum drain_type drain_type, BlockDriverState *bs) ++{ ++ if (drain_type != BDRV_DRAIN_ALL) { ++ aio_context_acquire(bdrv_get_aio_context(bs)); ++ } ++ do_drain_begin(drain_type, bs); ++ if (drain_type != BDRV_DRAIN_ALL) { ++ aio_context_release(bdrv_get_aio_context(bs)); ++ } ++} ++ ++static void do_drain_end_unlocked(enum drain_type drain_type, BlockDriverState *bs) ++{ ++ if (drain_type != BDRV_DRAIN_ALL) { ++ aio_context_acquire(bdrv_get_aio_context(bs)); ++ } ++ do_drain_end(drain_type, bs); ++ if (drain_type != BDRV_DRAIN_ALL) { ++ aio_context_release(bdrv_get_aio_context(bs)); ++ } ++} ++ + static void test_drv_cb_common(enum drain_type drain_type, bool recursive) + { + BlockBackend *blk; +@@ -785,11 +807,13 @@ BlockJobDriver test_job_driver = { + }, + }; + +-static void test_blockjob_common(enum drain_type drain_type) ++static void test_blockjob_common(enum drain_type drain_type, bool use_iothread) + { + BlockBackend *blk_src, *blk_target; + BlockDriverState *src, *target; + BlockJob *job; ++ IOThread *iothread = NULL; ++ AioContext *ctx; + int ret; + + src = bdrv_new_open_driver(&bdrv_test, "source", BDRV_O_RDWR, +@@ -797,21 +821,31 @@ static void test_blockjob_common(enum drain_type drain_type) + blk_src = blk_new(BLK_PERM_ALL, BLK_PERM_ALL); + blk_insert_bs(blk_src, src, &error_abort); + ++ if (use_iothread) { ++ iothread = iothread_new(); ++ ctx = iothread_get_aio_context(iothread); ++ blk_set_aio_context(blk_src, ctx); ++ } else { ++ ctx = qemu_get_aio_context(); ++ } ++ + target = bdrv_new_open_driver(&bdrv_test, "target", BDRV_O_RDWR, + &error_abort); + blk_target = blk_new(BLK_PERM_ALL, BLK_PERM_ALL); + blk_insert_bs(blk_target, target, &error_abort); + ++ aio_context_acquire(ctx); + job = block_job_create("job0", &test_job_driver, NULL, src, 0, BLK_PERM_ALL, + 0, 0, NULL, NULL, &error_abort); + block_job_add_bdrv(job, "target", target, 0, BLK_PERM_ALL, &error_abort); + job_start(&job->job); ++ aio_context_release(ctx); + + g_assert_cmpint(job->job.pause_count, ==, 0); + g_assert_false(job->job.paused); + g_assert_true(job->job.busy); /* We're in job_sleep_ns() */ + +- do_drain_begin(drain_type, src); ++ do_drain_begin_unlocked(drain_type, src); + + if (drain_type == BDRV_DRAIN_ALL) { + /* bdrv_drain_all() drains both src and target */ +@@ -822,7 +856,14 @@ static void test_blockjob_common(enum drain_type drain_type) + g_assert_true(job->job.paused); + g_assert_false(job->job.busy); /* The job is paused */ + +- do_drain_end(drain_type, src); ++ do_drain_end_unlocked(drain_type, src); ++ ++ if (use_iothread) { ++ /* paused is reset in the I/O thread, wait for it */ ++ while (job->job.paused) { ++ aio_poll(qemu_get_aio_context(), false); ++ } ++ } + + g_assert_cmpint(job->job.pause_count, ==, 0); + g_assert_false(job->job.paused); +@@ -841,32 +882,64 @@ static void test_blockjob_common(enum drain_type drain_type) + + do_drain_end(drain_type, target); + ++ if (use_iothread) { ++ /* paused is reset in the I/O thread, wait for it */ ++ while (job->job.paused) { ++ aio_poll(qemu_get_aio_context(), false); ++ } ++ } ++ + g_assert_cmpint(job->job.pause_count, ==, 0); + g_assert_false(job->job.paused); + g_assert_true(job->job.busy); /* We're in job_sleep_ns() */ + ++ aio_context_acquire(ctx); + ret = job_complete_sync(&job->job, &error_abort); + g_assert_cmpint(ret, ==, 0); + ++ if (use_iothread) { ++ blk_set_aio_context(blk_src, qemu_get_aio_context()); ++ } ++ aio_context_release(ctx); ++ + blk_unref(blk_src); + blk_unref(blk_target); + bdrv_unref(src); + bdrv_unref(target); ++ ++ if (iothread) { ++ iothread_join(iothread); ++ } + } + + static void test_blockjob_drain_all(void) + { +- test_blockjob_common(BDRV_DRAIN_ALL); ++ test_blockjob_common(BDRV_DRAIN_ALL, false); + } + + static void test_blockjob_drain(void) + { +- test_blockjob_common(BDRV_DRAIN); ++ test_blockjob_common(BDRV_DRAIN, false); + } + + static void test_blockjob_drain_subtree(void) + { +- test_blockjob_common(BDRV_SUBTREE_DRAIN); ++ test_blockjob_common(BDRV_SUBTREE_DRAIN, false); ++} ++ ++static void test_blockjob_iothread_drain_all(void) ++{ ++ test_blockjob_common(BDRV_DRAIN_ALL, true); ++} ++ ++static void test_blockjob_iothread_drain(void) ++{ ++ test_blockjob_common(BDRV_DRAIN, true); ++} ++ ++static void test_blockjob_iothread_drain_subtree(void) ++{ ++ test_blockjob_common(BDRV_SUBTREE_DRAIN, true); + } + + +@@ -1337,6 +1410,13 @@ int main(int argc, char **argv) + g_test_add_func("/bdrv-drain/blockjob/drain_subtree", + test_blockjob_drain_subtree); + ++ g_test_add_func("/bdrv-drain/blockjob/iothread/drain_all", ++ test_blockjob_iothread_drain_all); ++ g_test_add_func("/bdrv-drain/blockjob/iothread/drain", ++ test_blockjob_iothread_drain); ++ g_test_add_func("/bdrv-drain/blockjob/iothread/drain_subtree", ++ test_blockjob_iothread_drain_subtree); ++ + g_test_add_func("/bdrv-drain/deletion/drain", test_delete_by_drain); + g_test_add_func("/bdrv-drain/detach/drain_all", test_detach_by_drain_all); + g_test_add_func("/bdrv-drain/detach/drain", test_detach_by_drain); +-- +1.8.3.1 + diff --git a/0085-test-blockjob-Acquire-AioContext-around-job_cancel_s.patch b/0085-test-blockjob-Acquire-AioContext-around-job_cancel_s.patch new file mode 100644 index 0000000..976ce6a --- /dev/null +++ b/0085-test-blockjob-Acquire-AioContext-around-job_cancel_s.patch @@ -0,0 +1,86 @@ +From 99172abebcedfb48ca06d4c1bd0cd16372449600 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Wed, 10 Oct 2018 20:21:59 +0100 +Subject: test-blockjob: Acquire AioContext around job_cancel_sync() + +RH-Author: Kevin Wolf +Message-id: <20181010202213.7372-21-kwolf@redhat.com> +Patchwork-id: 82606 +O-Subject: [RHEL-8 qemu-kvm PATCH 30/44] test-blockjob: Acquire AioContext around job_cancel_sync() +Bugzilla: 1637976 +RH-Acked-by: Max Reitz +RH-Acked-by: John Snow +RH-Acked-by: Thomas Huth + +All callers in QEMU proper hold the AioContext lock when calling +job_finish_sync(). test-blockjob should do the same when it calls the +function indirectly through job_cancel_sync(). + +Signed-off-by: Kevin Wolf +Reviewed-by: Fam Zheng +(cherry picked from commit 30c070a547322a5e41ce129d540bca3653b1a9c8) +Signed-off-by: Kevin Wolf +Signed-off-by: Danilo C. L. de Paula +--- + include/qemu/job.h | 6 ++++++ + tests/test-blockjob.c | 6 ++++++ + 2 files changed, 12 insertions(+) + +diff --git a/include/qemu/job.h b/include/qemu/job.h +index b4a784d..63c60ef 100644 +--- a/include/qemu/job.h ++++ b/include/qemu/job.h +@@ -524,6 +524,8 @@ void job_user_cancel(Job *job, bool force, Error **errp); + * + * Returns the return value from the job if the job actually completed + * during the call, or -ECANCELED if it was canceled. ++ * ++ * Callers must hold the AioContext lock of job->aio_context. + */ + int job_cancel_sync(Job *job); + +@@ -541,6 +543,8 @@ void job_cancel_sync_all(void); + * function). + * + * Returns the return value from the job. ++ * ++ * Callers must hold the AioContext lock of job->aio_context. + */ + int job_complete_sync(Job *job, Error **errp); + +@@ -566,6 +570,8 @@ void job_dismiss(Job **job, Error **errp); + * + * Returns 0 if the job is successfully completed, -ECANCELED if the job was + * cancelled before completing, and -errno in other error cases. ++ * ++ * Callers must hold the AioContext lock of job->aio_context. + */ + int job_finish_sync(Job *job, void (*finish)(Job *, Error **errp), Error **errp); + +diff --git a/tests/test-blockjob.c b/tests/test-blockjob.c +index de4c1c2..652d1e8 100644 +--- a/tests/test-blockjob.c ++++ b/tests/test-blockjob.c +@@ -223,6 +223,10 @@ static void cancel_common(CancelJob *s) + BlockJob *job = &s->common; + BlockBackend *blk = s->blk; + JobStatus sts = job->job.status; ++ AioContext *ctx; ++ ++ ctx = job->job.aio_context; ++ aio_context_acquire(ctx); + + job_cancel_sync(&job->job); + if (sts != JOB_STATUS_CREATED && sts != JOB_STATUS_CONCLUDED) { +@@ -232,6 +236,8 @@ static void cancel_common(CancelJob *s) + assert(job->job.status == JOB_STATUS_NULL); + job_unref(&job->job); + destroy_blk(blk); ++ ++ aio_context_release(ctx); + } + + static void test_cancel_created(void) +-- +1.8.3.1 + diff --git a/0086-job-Use-AIO_WAIT_WHILE-in-job_finish_sync.patch b/0086-job-Use-AIO_WAIT_WHILE-in-job_finish_sync.patch new file mode 100644 index 0000000..b16aa60 --- /dev/null +++ b/0086-job-Use-AIO_WAIT_WHILE-in-job_finish_sync.patch @@ -0,0 +1,77 @@ +From 3f3282c8ffa29e3dbcf58618beefb36afe8ba79b Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Wed, 10 Oct 2018 20:22:00 +0100 +Subject: job: Use AIO_WAIT_WHILE() in job_finish_sync() + +RH-Author: Kevin Wolf +Message-id: <20181010202213.7372-22-kwolf@redhat.com> +Patchwork-id: 82612 +O-Subject: [RHEL-8 qemu-kvm PATCH 31/44] job: Use AIO_WAIT_WHILE() in job_finish_sync() +Bugzilla: 1637976 +RH-Acked-by: Max Reitz +RH-Acked-by: John Snow +RH-Acked-by: Thomas Huth + +job_finish_sync() needs to release the AioContext lock of the job before +calling aio_poll(). Otherwise, callbacks called by aio_poll() would +possibly take the lock a second time and run into a deadlock with a +nested AIO_WAIT_WHILE() call. + +Also, job_drain() without aio_poll() isn't necessarily enough to make +progress on a job, it could depend on bottom halves to be executed. + +Combine both open-coded while loops into a single AIO_WAIT_WHILE() call +that solves both of these problems. + +Signed-off-by: Kevin Wolf +Reviewed-by: Fam Zheng +Reviewed-by: Max Reitz +(cherry picked from commit de0fbe64806321fc3e6399bfab360553db87a41d) +Signed-off-by: Kevin Wolf +Signed-off-by: Danilo C. L. de Paula +--- + job.c | 14 ++++++-------- + 1 file changed, 6 insertions(+), 8 deletions(-) + +diff --git a/job.c b/job.c +index 48a767c..fa74558 100644 +--- a/job.c ++++ b/job.c +@@ -29,6 +29,7 @@ + #include "qemu/job.h" + #include "qemu/id.h" + #include "qemu/main-loop.h" ++#include "block/aio-wait.h" + #include "trace-root.h" + #include "qapi/qapi-events-job.h" + +@@ -962,6 +963,7 @@ void job_complete(Job *job, Error **errp) + int job_finish_sync(Job *job, void (*finish)(Job *, Error **errp), Error **errp) + { + Error *local_err = NULL; ++ AioWait dummy_wait = {}; + int ret; + + job_ref(job); +@@ -974,14 +976,10 @@ int job_finish_sync(Job *job, void (*finish)(Job *, Error **errp), Error **errp) + job_unref(job); + return -EBUSY; + } +- /* job_drain calls job_enter, and it should be enough to induce progress +- * until the job completes or moves to the main thread. */ +- while (!job->deferred_to_main_loop && !job_is_completed(job)) { +- job_drain(job); +- } +- while (!job_is_completed(job)) { +- aio_poll(qemu_get_aio_context(), true); +- } ++ ++ AIO_WAIT_WHILE(&dummy_wait, job->aio_context, ++ (job_drain(job), !job_is_completed(job))); ++ + ret = (job_is_cancelled(job) && job->ret == 0) ? -ECANCELED : job->ret; + job_unref(job); + return ret; +-- +1.8.3.1 + diff --git a/0087-test-bdrv-drain-Test-AIO_WAIT_WHILE-in-completion-ca.patch b/0087-test-bdrv-drain-Test-AIO_WAIT_WHILE-in-completion-ca.patch new file mode 100644 index 0000000..978a41d --- /dev/null +++ b/0087-test-bdrv-drain-Test-AIO_WAIT_WHILE-in-completion-ca.patch @@ -0,0 +1,59 @@ +From b9c555343b6567159effe1b3eb736fd1e02257bd Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Wed, 10 Oct 2018 20:22:01 +0100 +Subject: test-bdrv-drain: Test AIO_WAIT_WHILE() in completion callback + +RH-Author: Kevin Wolf +Message-id: <20181010202213.7372-23-kwolf@redhat.com> +Patchwork-id: 82611 +O-Subject: [RHEL-8 qemu-kvm PATCH 32/44] test-bdrv-drain: Test AIO_WAIT_WHILE() in completion callback +Bugzilla: 1637976 +RH-Acked-by: Max Reitz +RH-Acked-by: John Snow +RH-Acked-by: Thomas Huth + +This is a regression test for a deadlock that occurred in block job +completion callbacks (via job_defer_to_main_loop) because the AioContext +lock was taken twice: once in job_finish_sync() and then again in +job_defer_to_main_loop_bh(). This would cause AIO_WAIT_WHILE() to hang. + +Signed-off-by: Kevin Wolf +Reviewed-by: Fam Zheng +(cherry picked from commit ae23dde9dd486e57e152a0ebc9802caddedc45fc) +Signed-off-by: Kevin Wolf +Signed-off-by: Danilo C. L. de Paula +--- + tests/test-bdrv-drain.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c +index 3cf3ba3..05f3b55 100644 +--- a/tests/test-bdrv-drain.c ++++ b/tests/test-bdrv-drain.c +@@ -774,6 +774,15 @@ typedef struct TestBlockJob { + bool should_complete; + } TestBlockJob; + ++static int test_job_prepare(Job *job) ++{ ++ TestBlockJob *s = container_of(job, TestBlockJob, common.job); ++ ++ /* Provoke an AIO_WAIT_WHILE() call to verify there is no deadlock */ ++ blk_flush(s->common.blk); ++ return 0; ++} ++ + static int coroutine_fn test_job_run(Job *job, Error **errp) + { + TestBlockJob *s = container_of(job, TestBlockJob, common.job); +@@ -804,6 +813,7 @@ BlockJobDriver test_job_driver = { + .drain = block_job_drain, + .run = test_job_run, + .complete = test_job_complete, ++ .prepare = test_job_prepare, + }, + }; + +-- +1.8.3.1 + diff --git a/0088-block-Add-missing-locking-in-bdrv_co_drain_bh_cb.patch b/0088-block-Add-missing-locking-in-bdrv_co_drain_bh_cb.patch new file mode 100644 index 0000000..1d2abee --- /dev/null +++ b/0088-block-Add-missing-locking-in-bdrv_co_drain_bh_cb.patch @@ -0,0 +1,96 @@ +From 51c1069568d78941554c70f9084531c279899c83 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Wed, 10 Oct 2018 20:22:02 +0100 +Subject: block: Add missing locking in bdrv_co_drain_bh_cb() + +RH-Author: Kevin Wolf +Message-id: <20181010202213.7372-24-kwolf@redhat.com> +Patchwork-id: 82613 +O-Subject: [RHEL-8 qemu-kvm PATCH 33/44] block: Add missing locking in bdrv_co_drain_bh_cb() +Bugzilla: 1637976 +RH-Acked-by: Max Reitz +RH-Acked-by: John Snow +RH-Acked-by: Thomas Huth + +bdrv_do_drained_begin/end() assume that they are called with the +AioContext lock of bs held. If we call drain functions from a coroutine +with the AioContext lock held, we yield and schedule a BH to move out of +coroutine context. This means that the lock for the home context of the +coroutine is released and must be re-acquired in the bottom half. + +Signed-off-by: Kevin Wolf +Reviewed-by: Max Reitz +(cherry picked from commit aa1361d54aac43094b98024b8b6c804eb6e41661) +Signed-off-by: Kevin Wolf +Signed-off-by: Danilo C. L. de Paula +--- + block/io.c | 15 +++++++++++++++ + include/qemu/coroutine.h | 5 +++++ + util/qemu-coroutine.c | 5 +++++ + 3 files changed, 25 insertions(+) + +diff --git a/block/io.c b/block/io.c +index 7100344..914ba78 100644 +--- a/block/io.c ++++ b/block/io.c +@@ -288,6 +288,18 @@ static void bdrv_co_drain_bh_cb(void *opaque) + BlockDriverState *bs = data->bs; + + if (bs) { ++ AioContext *ctx = bdrv_get_aio_context(bs); ++ AioContext *co_ctx = qemu_coroutine_get_aio_context(co); ++ ++ /* ++ * When the coroutine yielded, the lock for its home context was ++ * released, so we need to re-acquire it here. If it explicitly ++ * acquired a different context, the lock is still held and we don't ++ * want to lock it a second time (or AIO_WAIT_WHILE() would hang). ++ */ ++ if (ctx == co_ctx) { ++ aio_context_acquire(ctx); ++ } + bdrv_dec_in_flight(bs); + if (data->begin) { + bdrv_do_drained_begin(bs, data->recursive, data->parent, +@@ -296,6 +308,9 @@ static void bdrv_co_drain_bh_cb(void *opaque) + bdrv_do_drained_end(bs, data->recursive, data->parent, + data->ignore_bds_parents); + } ++ if (ctx == co_ctx) { ++ aio_context_release(ctx); ++ } + } else { + assert(data->begin); + bdrv_drain_all_begin(); +diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h +index 6f8a487..9801e7f 100644 +--- a/include/qemu/coroutine.h ++++ b/include/qemu/coroutine.h +@@ -90,6 +90,11 @@ void qemu_aio_coroutine_enter(AioContext *ctx, Coroutine *co); + void coroutine_fn qemu_coroutine_yield(void); + + /** ++ * Get the AioContext of the given coroutine ++ */ ++AioContext *coroutine_fn qemu_coroutine_get_aio_context(Coroutine *co); ++ ++/** + * Get the currently executing coroutine + */ + Coroutine *coroutine_fn qemu_coroutine_self(void); +diff --git a/util/qemu-coroutine.c b/util/qemu-coroutine.c +index 1ba4191..2295928 100644 +--- a/util/qemu-coroutine.c ++++ b/util/qemu-coroutine.c +@@ -198,3 +198,8 @@ bool qemu_coroutine_entered(Coroutine *co) + { + return co->caller; + } ++ ++AioContext *coroutine_fn qemu_coroutine_get_aio_context(Coroutine *co) ++{ ++ return co->ctx; ++} +-- +1.8.3.1 + diff --git a/0089-block-backend-Add-.drained_poll-callback.patch b/0089-block-backend-Add-.drained_poll-callback.patch new file mode 100644 index 0000000..64eae39 --- /dev/null +++ b/0089-block-backend-Add-.drained_poll-callback.patch @@ -0,0 +1,66 @@ +From ea3026a59a3772f84697af9b62b6272cfb41f40c Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Wed, 10 Oct 2018 20:22:03 +0100 +Subject: block-backend: Add .drained_poll callback + +RH-Author: Kevin Wolf +Message-id: <20181010202213.7372-25-kwolf@redhat.com> +Patchwork-id: 82614 +O-Subject: [RHEL-8 qemu-kvm PATCH 34/44] block-backend: Add .drained_poll callback +Bugzilla: 1637976 +RH-Acked-by: Max Reitz +RH-Acked-by: John Snow +RH-Acked-by: Thomas Huth + +A bdrv_drain operation must ensure that all parents are quiesced, this +includes BlockBackends. Otherwise, callbacks called by requests that are +completed on the BDS layer, but not quite yet on the BlockBackend layer +could still create new requests. + +Signed-off-by: Kevin Wolf +Reviewed-by: Fam Zheng +Reviewed-by: Max Reitz +(cherry picked from commit fe5258a503a87e69be37c9ac48799e293809386e) +Signed-off-by: Kevin Wolf +Signed-off-by: Danilo C. L. de Paula +--- + block/block-backend.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/block/block-backend.c b/block/block-backend.c +index f2f75a9..2b837d1 100644 +--- a/block/block-backend.c ++++ b/block/block-backend.c +@@ -121,6 +121,7 @@ static void blk_root_inherit_options(int *child_flags, QDict *child_options, + abort(); + } + static void blk_root_drained_begin(BdrvChild *child); ++static bool blk_root_drained_poll(BdrvChild *child); + static void blk_root_drained_end(BdrvChild *child); + + static void blk_root_change_media(BdrvChild *child, bool load); +@@ -294,6 +295,7 @@ static const BdrvChildRole child_root = { + .get_parent_desc = blk_root_get_parent_desc, + + .drained_begin = blk_root_drained_begin, ++ .drained_poll = blk_root_drained_poll, + .drained_end = blk_root_drained_end, + + .activate = blk_root_activate, +@@ -2192,6 +2194,13 @@ static void blk_root_drained_begin(BdrvChild *child) + } + } + ++static bool blk_root_drained_poll(BdrvChild *child) ++{ ++ BlockBackend *blk = child->opaque; ++ assert(blk->quiesce_counter); ++ return !!blk->in_flight; ++} ++ + static void blk_root_drained_end(BdrvChild *child) + { + BlockBackend *blk = child->opaque; +-- +1.8.3.1 + diff --git a/0090-block-backend-Fix-potential-double-blk_delete.patch b/0090-block-backend-Fix-potential-double-blk_delete.patch new file mode 100644 index 0000000..56799a1 --- /dev/null +++ b/0090-block-backend-Fix-potential-double-blk_delete.patch @@ -0,0 +1,67 @@ +From 21a2ef76c6aa33f0058d149b1bfdde1d27ba1df4 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Wed, 10 Oct 2018 20:22:04 +0100 +Subject: block-backend: Fix potential double blk_delete() + +RH-Author: Kevin Wolf +Message-id: <20181010202213.7372-26-kwolf@redhat.com> +Patchwork-id: 82615 +O-Subject: [RHEL-8 qemu-kvm PATCH 35/44] block-backend: Fix potential double blk_delete() +Bugzilla: 1637976 +RH-Acked-by: Max Reitz +RH-Acked-by: John Snow +RH-Acked-by: Thomas Huth + +blk_unref() first decreases the refcount of the BlockBackend and calls +blk_delete() if the refcount reaches zero. Requests can still be in +flight at this point, they are only drained during blk_delete(): + +At this point, arbitrary callbacks can run. If any callback takes a +temporary BlockBackend reference, it will first increase the refcount to +1 and then decrease it to 0 again, triggering another blk_delete(). This +will cause a use-after-free crash in the outer blk_delete(). + +Fix it by draining the BlockBackend before decreasing to refcount to 0. +Assert in blk_ref() that it never takes the first refcount (which would +mean that the BlockBackend is already being deleted). + +Signed-off-by: Kevin Wolf +Reviewed-by: Fam Zheng +Reviewed-by: Max Reitz +(cherry picked from commit 5ca9d21bd1c8eeb578d0964e31bd03d47c25773d) +Signed-off-by: Kevin Wolf +Signed-off-by: Danilo C. L. de Paula +--- + block/block-backend.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/block/block-backend.c b/block/block-backend.c +index 2b837d1..94046f0 100644 +--- a/block/block-backend.c ++++ b/block/block-backend.c +@@ -436,6 +436,7 @@ int blk_get_refcnt(BlockBackend *blk) + */ + void blk_ref(BlockBackend *blk) + { ++ assert(blk->refcnt > 0); + blk->refcnt++; + } + +@@ -448,7 +449,13 @@ void blk_unref(BlockBackend *blk) + { + if (blk) { + assert(blk->refcnt > 0); +- if (!--blk->refcnt) { ++ if (blk->refcnt > 1) { ++ blk->refcnt--; ++ } else { ++ blk_drain(blk); ++ /* blk_drain() cannot resurrect blk, nobody held a reference */ ++ assert(blk->refcnt == 1); ++ blk->refcnt = 0; + blk_delete(blk); + } + } +-- +1.8.3.1 + diff --git a/0091-block-backend-Decrease-in_flight-only-after-callback.patch b/0091-block-backend-Decrease-in_flight-only-after-callback.patch new file mode 100644 index 0000000..69805e9 --- /dev/null +++ b/0091-block-backend-Decrease-in_flight-only-after-callback.patch @@ -0,0 +1,74 @@ +From 91ae719381f75ed3554b0c5e1d8bf58583a9208f Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Wed, 10 Oct 2018 20:22:05 +0100 +Subject: block-backend: Decrease in_flight only after callback + +RH-Author: Kevin Wolf +Message-id: <20181010202213.7372-27-kwolf@redhat.com> +Patchwork-id: 82617 +O-Subject: [RHEL-8 qemu-kvm PATCH 36/44] block-backend: Decrease in_flight only after callback +Bugzilla: 1637976 +RH-Acked-by: Max Reitz +RH-Acked-by: John Snow +RH-Acked-by: Thomas Huth + +Request callbacks can do pretty much anything, including operations that +will yield from the coroutine (such as draining the backend). In that +case, a decreased in_flight would be visible to other code and could +lead to a drain completing while the callback hasn't actually completed +yet. + +Note that reordering these operations forbids calling drain directly +inside an AIO callback. As Paolo explains, indirectly calling it is +okay: + +- Calling it through a coroutine is okay, because then + bdrv_drained_begin() goes through bdrv_co_yield_to_drain() and you + have in_flight=2 when bdrv_co_yield_to_drain() yields, then soon + in_flight=1 when the aio_co_wake() in the AIO callback completes, then + in_flight=0 after the bottom half starts. + +- Calling it through a bottom half would be okay too, as long as the AIO + callback remembers to do inc_in_flight/dec_in_flight just like + bdrv_co_yield_to_drain() and bdrv_co_drain_bh_cb() do + +A few more important cases that come to mind: + +- A coroutine that yields because of I/O is okay, with a sequence + similar to bdrv_co_yield_to_drain(). + +- A coroutine that yields with no I/O pending will correctly decrease + in_flight to zero before yielding. + +- Calling more AIO from the callback won't overflow the counter just + because of mutual recursion, because AIO functions always yield at + least once before invoking the callback. + +Signed-off-by: Kevin Wolf +Reviewed-by: Fam Zheng +Reviewed-by: Max Reitz +Reviewed-by: Paolo Bonzini +(cherry picked from commit 46aaf2a566e364a62315219255099cbf1c9b990d) +Signed-off-by: Kevin Wolf +Signed-off-by: Danilo C. L. de Paula +--- + block/block-backend.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/block/block-backend.c b/block/block-backend.c +index 94046f0..9a3e060 100644 +--- a/block/block-backend.c ++++ b/block/block-backend.c +@@ -1341,8 +1341,8 @@ static const AIOCBInfo blk_aio_em_aiocb_info = { + static void blk_aio_complete(BlkAioEmAIOCB *acb) + { + if (acb->has_returned) { +- blk_dec_in_flight(acb->rwco.blk); + acb->common.cb(acb->common.opaque, acb->rwco.ret); ++ blk_dec_in_flight(acb->rwco.blk); + qemu_aio_unref(acb); + } + } +-- +1.8.3.1 + diff --git a/0092-blockjob-Lie-better-in-child_job_drained_poll.patch b/0092-blockjob-Lie-better-in-child_job_drained_poll.patch new file mode 100644 index 0000000..64f5aaa --- /dev/null +++ b/0092-blockjob-Lie-better-in-child_job_drained_poll.patch @@ -0,0 +1,104 @@ +From bc17446b1e7c9578a3e3079173891c93998dfa00 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Wed, 10 Oct 2018 20:22:06 +0100 +Subject: blockjob: Lie better in child_job_drained_poll() + +RH-Author: Kevin Wolf +Message-id: <20181010202213.7372-28-kwolf@redhat.com> +Patchwork-id: 82616 +O-Subject: [RHEL-8 qemu-kvm PATCH 37/44] blockjob: Lie better in child_job_drained_poll() +Bugzilla: 1637976 +RH-Acked-by: Max Reitz +RH-Acked-by: John Snow +RH-Acked-by: Thomas Huth + +Block jobs claim in .drained_poll() that they are in a quiescent state +as soon as job->deferred_to_main_loop is true. This is obviously wrong, +they still have a completion BH to run. We only get away with this +because commit 91af091f923 added an unconditional aio_poll(false) to the +drain functions, but this is bypassing the regular drain mechanisms. + +However, just removing this and telling that the job is still active +doesn't work either: The completion callbacks themselves call drain +functions (directly, or indirectly with bdrv_reopen), so they would +deadlock then. + +As a better lie, tell that the job is active as long as the BH is +pending, but falsely call it quiescent from the point in the BH when the +completion callback is called. At this point, nested drain calls won't +deadlock because they ignore the job, and outer drains will wait for the +job to really reach a quiescent state because the callback is already +running. + +Signed-off-by: Kevin Wolf +Reviewed-by: Max Reitz +(cherry picked from commit b5a7a0573530698ee448b063ac01d485e30446bd) +Signed-off-by: Kevin Wolf +Signed-off-by: Danilo C. L. de Paula +--- + blockjob.c | 2 +- + include/qemu/job.h | 3 +++ + job.c | 11 ++++++++++- + 3 files changed, 14 insertions(+), 2 deletions(-) + +diff --git a/blockjob.c b/blockjob.c +index 8d27e8e..617d86f 100644 +--- a/blockjob.c ++++ b/blockjob.c +@@ -164,7 +164,7 @@ static bool child_job_drained_poll(BdrvChild *c) + /* An inactive or completed job doesn't have any pending requests. Jobs + * with !job->busy are either already paused or have a pause point after + * being reentered, so no job driver code will run before they pause. */ +- if (!job->busy || job_is_completed(job) || job->deferred_to_main_loop) { ++ if (!job->busy || job_is_completed(job)) { + return false; + } + +diff --git a/include/qemu/job.h b/include/qemu/job.h +index 63c60ef..9e7cd1e 100644 +--- a/include/qemu/job.h ++++ b/include/qemu/job.h +@@ -76,6 +76,9 @@ typedef struct Job { + * Set to false by the job while the coroutine has yielded and may be + * re-entered by job_enter(). There may still be I/O or event loop activity + * pending. Accessed under block_job_mutex (in blockjob.c). ++ * ++ * When the job is deferred to the main loop, busy is true as long as the ++ * bottom half is still pending. + */ + bool busy; + +diff --git a/job.c b/job.c +index fa74558..00a1cd1 100644 +--- a/job.c ++++ b/job.c +@@ -857,7 +857,16 @@ static void job_exit(void *opaque) + AioContext *ctx = job->aio_context; + + aio_context_acquire(ctx); ++ ++ /* This is a lie, we're not quiescent, but still doing the completion ++ * callbacks. However, completion callbacks tend to involve operations that ++ * drain block nodes, and if .drained_poll still returned true, we would ++ * deadlock. */ ++ job->busy = false; ++ job_event_idle(job); ++ + job_completed(job); ++ + aio_context_release(ctx); + } + +@@ -872,8 +881,8 @@ static void coroutine_fn job_co_entry(void *opaque) + assert(job && job->driver && job->driver->run); + job_pause_point(job); + job->ret = job->driver->run(job, &job->err); +- job_event_idle(job); + job->deferred_to_main_loop = true; ++ job->busy = true; + aio_bh_schedule_oneshot(qemu_get_aio_context(), job_exit, job); + } + +-- +1.8.3.1 + diff --git a/0093-block-Remove-aio_poll-in-bdrv_drain_poll-variants.patch b/0093-block-Remove-aio_poll-in-bdrv_drain_poll-variants.patch new file mode 100644 index 0000000..60cdc36 --- /dev/null +++ b/0093-block-Remove-aio_poll-in-bdrv_drain_poll-variants.patch @@ -0,0 +1,64 @@ +From ce7a9c21d6a43b736d5aa2041acbd5d1edca0070 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Wed, 10 Oct 2018 20:22:07 +0100 +Subject: block: Remove aio_poll() in bdrv_drain_poll variants + +RH-Author: Kevin Wolf +Message-id: <20181010202213.7372-29-kwolf@redhat.com> +Patchwork-id: 82619 +O-Subject: [RHEL-8 qemu-kvm PATCH 38/44] block: Remove aio_poll() in bdrv_drain_poll variants +Bugzilla: 1637976 +RH-Acked-by: Max Reitz +RH-Acked-by: John Snow +RH-Acked-by: Thomas Huth + +bdrv_drain_poll_top_level() was buggy because it didn't release the +AioContext lock of the node to be drained before calling aio_poll(). +This way, callbacks called by aio_poll() would possibly take the lock a +second time and run into a deadlock with a nested AIO_WAIT_WHILE() call. + +However, it turns out that the aio_poll() call isn't actually needed any +more. It was introduced in commit 91af091f923, which is effectively +reverted by this patch. The cases it was supposed to fix are now covered +by bdrv_drain_poll(), which waits for block jobs to reach a quiescent +state. + +Signed-off-by: Kevin Wolf +Reviewed-by: Fam Zheng +Reviewed-by: Max Reitz +(cherry picked from commit 4cf077b59fc73eec29f8b7d082919dbb278bdc86) +Signed-off-by: Kevin Wolf +Signed-off-by: Danilo C. L. de Paula +--- + block/io.c | 8 -------- + 1 file changed, 8 deletions(-) + +diff --git a/block/io.c b/block/io.c +index 914ba78..8b81ff3 100644 +--- a/block/io.c ++++ b/block/io.c +@@ -268,10 +268,6 @@ bool bdrv_drain_poll(BlockDriverState *bs, bool recursive, + static bool bdrv_drain_poll_top_level(BlockDriverState *bs, bool recursive, + BdrvChild *ignore_parent) + { +- /* Execute pending BHs first and check everything else only after the BHs +- * have executed. */ +- while (aio_poll(bs->aio_context, false)); +- + return bdrv_drain_poll(bs, recursive, ignore_parent, false); + } + +@@ -511,10 +507,6 @@ static bool bdrv_drain_all_poll(void) + BlockDriverState *bs = NULL; + bool result = false; + +- /* Execute pending BHs first (may modify the graph) and check everything +- * else only after the BHs have executed. */ +- while (aio_poll(qemu_get_aio_context(), false)); +- + /* bdrv_drain_poll() can't make changes to the graph and we are holding the + * main AioContext lock, so iterating bdrv_next_all_states() is safe. */ + while ((bs = bdrv_next_all_states(bs))) { +-- +1.8.3.1 + diff --git a/0094-test-bdrv-drain-Test-nested-poll-in-bdrv_drain_poll_.patch b/0094-test-bdrv-drain-Test-nested-poll-in-bdrv_drain_poll_.patch new file mode 100644 index 0000000..8de1ae2 --- /dev/null +++ b/0094-test-bdrv-drain-Test-nested-poll-in-bdrv_drain_poll_.patch @@ -0,0 +1,63 @@ +From 6c315602205e494dd084a4692a06c16b0e233875 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Wed, 10 Oct 2018 20:22:08 +0100 +Subject: test-bdrv-drain: Test nested poll in bdrv_drain_poll_top_level() + +RH-Author: Kevin Wolf +Message-id: <20181010202213.7372-30-kwolf@redhat.com> +Patchwork-id: 82618 +O-Subject: [RHEL-8 qemu-kvm PATCH 39/44] test-bdrv-drain: Test nested poll in bdrv_drain_poll_top_level() +Bugzilla: 1637976 +RH-Acked-by: Max Reitz +RH-Acked-by: John Snow +RH-Acked-by: Thomas Huth + +This is a regression test for a deadlock that could occur in callbacks +called from the aio_poll() in bdrv_drain_poll_top_level(). The +AioContext lock wasn't released and therefore would be taken a second +time in the callback. This would cause a possible AIO_WAIT_WHILE() in +the callback to hang. + +Signed-off-by: Kevin Wolf +Reviewed-by: Fam Zheng +(cherry picked from commit ecc1a5c790cf2c7732cb9755ca388c2fe108d1a1) +Signed-off-by: Kevin Wolf +Signed-off-by: Danilo C. L. de Paula +--- + tests/test-bdrv-drain.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c +index 05f3b55..f4b57f7 100644 +--- a/tests/test-bdrv-drain.c ++++ b/tests/test-bdrv-drain.c +@@ -636,6 +636,17 @@ static void test_iothread_aio_cb(void *opaque, int ret) + qemu_event_set(&done_event); + } + ++static void test_iothread_main_thread_bh(void *opaque) ++{ ++ struct test_iothread_data *data = opaque; ++ ++ /* Test that the AioContext is not yet locked in a random BH that is ++ * executed during drain, otherwise this would deadlock. */ ++ aio_context_acquire(bdrv_get_aio_context(data->bs)); ++ bdrv_flush(data->bs); ++ aio_context_release(bdrv_get_aio_context(data->bs)); ++} ++ + /* + * Starts an AIO request on a BDS that runs in the AioContext of iothread 1. + * The request involves a BH on iothread 2 before it can complete. +@@ -705,6 +716,8 @@ static void test_iothread_common(enum drain_type drain_type, int drain_thread) + aio_context_acquire(ctx_a); + } + ++ aio_bh_schedule_oneshot(ctx_a, test_iothread_main_thread_bh, &data); ++ + /* The request is running on the IOThread a. Draining its block device + * will make sure that it has completed as far as the BDS is concerned, + * but the drain in this thread can continue immediately after +-- +1.8.3.1 + diff --git a/0095-job-Avoid-deadlocks-in-job_completed_txn_abort.patch b/0095-job-Avoid-deadlocks-in-job_completed_txn_abort.patch new file mode 100644 index 0000000..0b8a8fd --- /dev/null +++ b/0095-job-Avoid-deadlocks-in-job_completed_txn_abort.patch @@ -0,0 +1,85 @@ +From 287d4267dcb2d5f262dba7f6e7f35dcd294b622a Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Wed, 10 Oct 2018 20:22:09 +0100 +Subject: job: Avoid deadlocks in job_completed_txn_abort() + +RH-Author: Kevin Wolf +Message-id: <20181010202213.7372-31-kwolf@redhat.com> +Patchwork-id: 82622 +O-Subject: [RHEL-8 qemu-kvm PATCH 40/44] job: Avoid deadlocks in job_completed_txn_abort() +Bugzilla: 1637976 +RH-Acked-by: Max Reitz +RH-Acked-by: John Snow +RH-Acked-by: Thomas Huth + +Amongst others, job_finalize_single() calls the .prepare/.commit/.abort +callbacks of the individual job driver. Recently, their use was adapted +for all block jobs so that they involve code calling AIO_WAIT_WHILE() +now. Such code must be called under the AioContext lock for the +respective job, but without holding any other AioContext lock. + +Signed-off-by: Kevin Wolf +Reviewed-by: Max Reitz +(cherry picked from commit 644f3a29bd4974aefd46d2adb5062d86063c8a50) +Signed-off-by: Kevin Wolf +Signed-off-by: Danilo C. L. de Paula +--- + job.c | 16 +++++++++++----- + 1 file changed, 11 insertions(+), 5 deletions(-) + +diff --git a/job.c b/job.c +index 00a1cd1..0b02186 100644 +--- a/job.c ++++ b/job.c +@@ -718,6 +718,7 @@ static void job_cancel_async(Job *job, bool force) + + static void job_completed_txn_abort(Job *job) + { ++ AioContext *outer_ctx = job->aio_context; + AioContext *ctx; + JobTxn *txn = job->txn; + Job *other_job; +@@ -731,23 +732,26 @@ static void job_completed_txn_abort(Job *job) + txn->aborting = true; + job_txn_ref(txn); + +- /* We are the first failed job. Cancel other jobs. */ +- QLIST_FOREACH(other_job, &txn->jobs, txn_list) { +- ctx = other_job->aio_context; +- aio_context_acquire(ctx); +- } ++ /* We can only hold the single job's AioContext lock while calling ++ * job_finalize_single() because the finalization callbacks can involve ++ * calls of AIO_WAIT_WHILE(), which could deadlock otherwise. */ ++ aio_context_release(outer_ctx); + + /* Other jobs are effectively cancelled by us, set the status for + * them; this job, however, may or may not be cancelled, depending + * on the caller, so leave it. */ + QLIST_FOREACH(other_job, &txn->jobs, txn_list) { + if (other_job != job) { ++ ctx = other_job->aio_context; ++ aio_context_acquire(ctx); + job_cancel_async(other_job, false); ++ aio_context_release(ctx); + } + } + while (!QLIST_EMPTY(&txn->jobs)) { + other_job = QLIST_FIRST(&txn->jobs); + ctx = other_job->aio_context; ++ aio_context_acquire(ctx); + if (!job_is_completed(other_job)) { + assert(job_is_cancelled(other_job)); + job_finish_sync(other_job, NULL, NULL); +@@ -756,6 +760,8 @@ static void job_completed_txn_abort(Job *job) + aio_context_release(ctx); + } + ++ aio_context_acquire(outer_ctx); ++ + job_txn_unref(txn); + } + +-- +1.8.3.1 + diff --git a/0096-test-bdrv-drain-AIO_WAIT_WHILE-in-job-.commit-.abort.patch b/0096-test-bdrv-drain-AIO_WAIT_WHILE-in-job-.commit-.abort.patch new file mode 100644 index 0000000..44cdf9f --- /dev/null +++ b/0096-test-bdrv-drain-AIO_WAIT_WHILE-in-job-.commit-.abort.patch @@ -0,0 +1,241 @@ +From 10fbd3c89739a1879f47f2a2256831ce5e1ae7ad Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Wed, 10 Oct 2018 20:22:10 +0100 +Subject: test-bdrv-drain: AIO_WAIT_WHILE() in job .commit/.abort + +RH-Author: Kevin Wolf +Message-id: <20181010202213.7372-32-kwolf@redhat.com> +Patchwork-id: 82620 +O-Subject: [RHEL-8 qemu-kvm PATCH 41/44] test-bdrv-drain: AIO_WAIT_WHILE() in job .commit/.abort +Bugzilla: 1637976 +RH-Acked-by: Max Reitz +RH-Acked-by: John Snow +RH-Acked-by: Thomas Huth + +This adds tests for calling AIO_WAIT_WHILE() in the .commit and .abort +callbacks. Both reasons why .abort could be called for a single job are +tested: Either .run or .prepare could return an error. + +Signed-off-by: Kevin Wolf +Reviewed-by: Max Reitz +(cherry picked from commit d49725af46a7710cde02cc120b7f1e485154b483) +Signed-off-by: Kevin Wolf +Signed-off-by: Danilo C. L. de Paula +--- + tests/test-bdrv-drain.c | 116 +++++++++++++++++++++++++++++++++++++++++++----- + 1 file changed, 104 insertions(+), 12 deletions(-) + +diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c +index f4b57f7..d6202b2 100644 +--- a/tests/test-bdrv-drain.c ++++ b/tests/test-bdrv-drain.c +@@ -784,6 +784,8 @@ static void test_iothread_drain_subtree(void) + + typedef struct TestBlockJob { + BlockJob common; ++ int run_ret; ++ int prepare_ret; + bool should_complete; + } TestBlockJob; + +@@ -793,7 +795,23 @@ static int test_job_prepare(Job *job) + + /* Provoke an AIO_WAIT_WHILE() call to verify there is no deadlock */ + blk_flush(s->common.blk); +- return 0; ++ return s->prepare_ret; ++} ++ ++static void test_job_commit(Job *job) ++{ ++ TestBlockJob *s = container_of(job, TestBlockJob, common.job); ++ ++ /* Provoke an AIO_WAIT_WHILE() call to verify there is no deadlock */ ++ blk_flush(s->common.blk); ++} ++ ++static void test_job_abort(Job *job) ++{ ++ TestBlockJob *s = container_of(job, TestBlockJob, common.job); ++ ++ /* Provoke an AIO_WAIT_WHILE() call to verify there is no deadlock */ ++ blk_flush(s->common.blk); + } + + static int coroutine_fn test_job_run(Job *job, Error **errp) +@@ -809,7 +827,7 @@ static int coroutine_fn test_job_run(Job *job, Error **errp) + job_pause_point(&s->common.job); + } + +- return 0; ++ return s->run_ret; + } + + static void test_job_complete(Job *job, Error **errp) +@@ -827,14 +845,24 @@ BlockJobDriver test_job_driver = { + .run = test_job_run, + .complete = test_job_complete, + .prepare = test_job_prepare, ++ .commit = test_job_commit, ++ .abort = test_job_abort, + }, + }; + +-static void test_blockjob_common(enum drain_type drain_type, bool use_iothread) ++enum test_job_result { ++ TEST_JOB_SUCCESS, ++ TEST_JOB_FAIL_RUN, ++ TEST_JOB_FAIL_PREPARE, ++}; ++ ++static void test_blockjob_common(enum drain_type drain_type, bool use_iothread, ++ enum test_job_result result) + { + BlockBackend *blk_src, *blk_target; + BlockDriverState *src, *target; + BlockJob *job; ++ TestBlockJob *tjob; + IOThread *iothread = NULL; + AioContext *ctx; + int ret; +@@ -858,9 +886,23 @@ static void test_blockjob_common(enum drain_type drain_type, bool use_iothread) + blk_insert_bs(blk_target, target, &error_abort); + + aio_context_acquire(ctx); +- job = block_job_create("job0", &test_job_driver, NULL, src, 0, BLK_PERM_ALL, +- 0, 0, NULL, NULL, &error_abort); ++ tjob = block_job_create("job0", &test_job_driver, NULL, src, ++ 0, BLK_PERM_ALL, ++ 0, 0, NULL, NULL, &error_abort); ++ job = &tjob->common; + block_job_add_bdrv(job, "target", target, 0, BLK_PERM_ALL, &error_abort); ++ ++ switch (result) { ++ case TEST_JOB_SUCCESS: ++ break; ++ case TEST_JOB_FAIL_RUN: ++ tjob->run_ret = -EIO; ++ break; ++ case TEST_JOB_FAIL_PREPARE: ++ tjob->prepare_ret = -EIO; ++ break; ++ } ++ + job_start(&job->job); + aio_context_release(ctx); + +@@ -918,7 +960,7 @@ static void test_blockjob_common(enum drain_type drain_type, bool use_iothread) + + aio_context_acquire(ctx); + ret = job_complete_sync(&job->job, &error_abort); +- g_assert_cmpint(ret, ==, 0); ++ g_assert_cmpint(ret, ==, (result == TEST_JOB_SUCCESS ? 0 : -EIO)); + + if (use_iothread) { + blk_set_aio_context(blk_src, qemu_get_aio_context()); +@@ -937,32 +979,68 @@ static void test_blockjob_common(enum drain_type drain_type, bool use_iothread) + + static void test_blockjob_drain_all(void) + { +- test_blockjob_common(BDRV_DRAIN_ALL, false); ++ test_blockjob_common(BDRV_DRAIN_ALL, false, TEST_JOB_SUCCESS); + } + + static void test_blockjob_drain(void) + { +- test_blockjob_common(BDRV_DRAIN, false); ++ test_blockjob_common(BDRV_DRAIN, false, TEST_JOB_SUCCESS); + } + + static void test_blockjob_drain_subtree(void) + { +- test_blockjob_common(BDRV_SUBTREE_DRAIN, false); ++ test_blockjob_common(BDRV_SUBTREE_DRAIN, false, TEST_JOB_SUCCESS); ++} ++ ++static void test_blockjob_error_drain_all(void) ++{ ++ test_blockjob_common(BDRV_DRAIN_ALL, false, TEST_JOB_FAIL_RUN); ++ test_blockjob_common(BDRV_DRAIN_ALL, false, TEST_JOB_FAIL_PREPARE); ++} ++ ++static void test_blockjob_error_drain(void) ++{ ++ test_blockjob_common(BDRV_DRAIN, false, TEST_JOB_FAIL_RUN); ++ test_blockjob_common(BDRV_DRAIN, false, TEST_JOB_FAIL_PREPARE); ++} ++ ++static void test_blockjob_error_drain_subtree(void) ++{ ++ test_blockjob_common(BDRV_SUBTREE_DRAIN, false, TEST_JOB_FAIL_RUN); ++ test_blockjob_common(BDRV_SUBTREE_DRAIN, false, TEST_JOB_FAIL_PREPARE); + } + + static void test_blockjob_iothread_drain_all(void) + { +- test_blockjob_common(BDRV_DRAIN_ALL, true); ++ test_blockjob_common(BDRV_DRAIN_ALL, true, TEST_JOB_SUCCESS); + } + + static void test_blockjob_iothread_drain(void) + { +- test_blockjob_common(BDRV_DRAIN, true); ++ test_blockjob_common(BDRV_DRAIN, true, TEST_JOB_SUCCESS); + } + + static void test_blockjob_iothread_drain_subtree(void) + { +- test_blockjob_common(BDRV_SUBTREE_DRAIN, true); ++ test_blockjob_common(BDRV_SUBTREE_DRAIN, true, TEST_JOB_SUCCESS); ++} ++ ++static void test_blockjob_iothread_error_drain_all(void) ++{ ++ test_blockjob_common(BDRV_DRAIN_ALL, true, TEST_JOB_FAIL_RUN); ++ test_blockjob_common(BDRV_DRAIN_ALL, true, TEST_JOB_FAIL_PREPARE); ++} ++ ++static void test_blockjob_iothread_error_drain(void) ++{ ++ test_blockjob_common(BDRV_DRAIN, true, TEST_JOB_FAIL_RUN); ++ test_blockjob_common(BDRV_DRAIN, true, TEST_JOB_FAIL_PREPARE); ++} ++ ++static void test_blockjob_iothread_error_drain_subtree(void) ++{ ++ test_blockjob_common(BDRV_SUBTREE_DRAIN, true, TEST_JOB_FAIL_RUN); ++ test_blockjob_common(BDRV_SUBTREE_DRAIN, true, TEST_JOB_FAIL_PREPARE); + } + + +@@ -1433,6 +1511,13 @@ int main(int argc, char **argv) + g_test_add_func("/bdrv-drain/blockjob/drain_subtree", + test_blockjob_drain_subtree); + ++ g_test_add_func("/bdrv-drain/blockjob/error/drain_all", ++ test_blockjob_error_drain_all); ++ g_test_add_func("/bdrv-drain/blockjob/error/drain", ++ test_blockjob_error_drain); ++ g_test_add_func("/bdrv-drain/blockjob/error/drain_subtree", ++ test_blockjob_error_drain_subtree); ++ + g_test_add_func("/bdrv-drain/blockjob/iothread/drain_all", + test_blockjob_iothread_drain_all); + g_test_add_func("/bdrv-drain/blockjob/iothread/drain", +@@ -1440,6 +1525,13 @@ int main(int argc, char **argv) + g_test_add_func("/bdrv-drain/blockjob/iothread/drain_subtree", + test_blockjob_iothread_drain_subtree); + ++ g_test_add_func("/bdrv-drain/blockjob/iothread/error/drain_all", ++ test_blockjob_iothread_error_drain_all); ++ g_test_add_func("/bdrv-drain/blockjob/iothread/error/drain", ++ test_blockjob_iothread_error_drain); ++ g_test_add_func("/bdrv-drain/blockjob/iothread/error/drain_subtree", ++ test_blockjob_iothread_error_drain_subtree); ++ + g_test_add_func("/bdrv-drain/deletion/drain", test_delete_by_drain); + g_test_add_func("/bdrv-drain/detach/drain_all", test_detach_by_drain_all); + g_test_add_func("/bdrv-drain/detach/drain", test_detach_by_drain); +-- +1.8.3.1 + diff --git a/0097-test-bdrv-drain-Fix-outdated-comments.patch b/0097-test-bdrv-drain-Fix-outdated-comments.patch new file mode 100644 index 0000000..08e50a7 --- /dev/null +++ b/0097-test-bdrv-drain-Fix-outdated-comments.patch @@ -0,0 +1,69 @@ +From 1eaa60bc24cb3fecba8da61f21c44e6f4c9ee4c1 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Wed, 10 Oct 2018 20:22:11 +0100 +Subject: test-bdrv-drain: Fix outdated comments + +RH-Author: Kevin Wolf +Message-id: <20181010202213.7372-33-kwolf@redhat.com> +Patchwork-id: 82621 +O-Subject: [RHEL-8 qemu-kvm PATCH 42/44] test-bdrv-drain: Fix outdated comments +Bugzilla: 1637976 +RH-Acked-by: Max Reitz +RH-Acked-by: John Snow +RH-Acked-by: Thomas Huth + +Commit 89bd030533e changed the test case from using job_sleep_ns() to +using qemu_co_sleep_ns() instead. Also, block_job_sleep_ns() became +job_sleep_ns() in commit 5d43e86e11f. + +In both cases, some comments in the test case were not updated. Do that +now. + +Reported-by: Max Reitz +Signed-off-by: Kevin Wolf +Reviewed-by: Eric Blake +(cherry picked from commit 5599c162c3bec2bc8f0123e4d5802a70d9984b3b) +Signed-off-by: Kevin Wolf +Signed-off-by: Danilo C. L. de Paula +--- + tests/test-bdrv-drain.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c +index d6202b2..7e7ba9b 100644 +--- a/tests/test-bdrv-drain.c ++++ b/tests/test-bdrv-drain.c +@@ -820,9 +820,9 @@ static int coroutine_fn test_job_run(Job *job, Error **errp) + + job_transition_to_ready(&s->common.job); + while (!s->should_complete) { +- /* Avoid block_job_sleep_ns() because it marks the job as !busy. We +- * want to emulate some actual activity (probably some I/O) here so +- * that drain has to wait for this acitivity to stop. */ ++ /* Avoid job_sleep_ns() because it marks the job as !busy. We want to ++ * emulate some actual activity (probably some I/O) here so that drain ++ * has to wait for this activity to stop. */ + qemu_co_sleep_ns(QEMU_CLOCK_REALTIME, 100000); + job_pause_point(&s->common.job); + } +@@ -908,7 +908,7 @@ static void test_blockjob_common(enum drain_type drain_type, bool use_iothread, + + g_assert_cmpint(job->job.pause_count, ==, 0); + g_assert_false(job->job.paused); +- g_assert_true(job->job.busy); /* We're in job_sleep_ns() */ ++ g_assert_true(job->job.busy); /* We're in qemu_co_sleep_ns() */ + + do_drain_begin_unlocked(drain_type, src); + +@@ -956,7 +956,7 @@ static void test_blockjob_common(enum drain_type drain_type, bool use_iothread, + + g_assert_cmpint(job->job.pause_count, ==, 0); + g_assert_false(job->job.paused); +- g_assert_true(job->job.busy); /* We're in job_sleep_ns() */ ++ g_assert_true(job->job.busy); /* We're in qemu_co_sleep_ns() */ + + aio_context_acquire(ctx); + ret = job_complete_sync(&job->job, &error_abort); +-- +1.8.3.1 + diff --git a/0098-block-Use-a-single-global-AioWait.patch b/0098-block-Use-a-single-global-AioWait.patch new file mode 100644 index 0000000..4fc26b8 --- /dev/null +++ b/0098-block-Use-a-single-global-AioWait.patch @@ -0,0 +1,367 @@ +From ea2355d819127ace6195e1d007bc305a49e7d465 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Wed, 10 Oct 2018 20:22:12 +0100 +Subject: block: Use a single global AioWait + +RH-Author: Kevin Wolf +Message-id: <20181010202213.7372-34-kwolf@redhat.com> +Patchwork-id: 82623 +O-Subject: [RHEL-8 qemu-kvm PATCH 43/44] block: Use a single global AioWait +Bugzilla: 1637976 +RH-Acked-by: Max Reitz +RH-Acked-by: John Snow +RH-Acked-by: Thomas Huth + +When draining a block node, we recurse to its parent and for subtree +drains also to its children. A single AIO_WAIT_WHILE() is then used to +wait for bdrv_drain_poll() to become true, which depends on all of the +nodes we recursed to. However, if the respective child or parent becomes +quiescent and calls bdrv_wakeup(), only the AioWait of the child/parent +is checked, while AIO_WAIT_WHILE() depends on the AioWait of the +original node. + +Fix this by using a single AioWait for all callers of AIO_WAIT_WHILE(). + +This may mean that the draining thread gets a few more unnecessary +wakeups because an unrelated operation got completed, but we already +wake it up when something _could_ have changed rather than only if it +has certainly changed. + +Apart from that, drain is a slow path anyway. In theory it would be +possible to use wakeups more selectively and still correctly, but the +gains are likely not worth the additional complexity. In fact, this +patch is a nice simplification for some places in the code. + +Signed-off-by: Kevin Wolf +Reviewed-by: Eric Blake +Reviewed-by: Max Reitz +(cherry picked from commit cfe29d8294e06420e15d4938421ae006c8ac49e7) +Signed-off-by: Kevin Wolf +Signed-off-by: Danilo C. L. de Paula +--- + block.c | 5 ----- + block/block-backend.c | 11 ++++------- + block/io.c | 7 ++----- + blockjob.c | 13 +------------ + include/block/aio-wait.h | 22 +++++++++++----------- + include/block/block.h | 6 +----- + include/block/block_int.h | 3 --- + include/block/blockjob.h | 10 ---------- + job.c | 3 +-- + util/aio-wait.c | 11 ++++++----- + 10 files changed, 26 insertions(+), 65 deletions(-) + +diff --git a/block.c b/block.c +index 39f373e..9b55956 100644 +--- a/block.c ++++ b/block.c +@@ -4865,11 +4865,6 @@ AioContext *bdrv_get_aio_context(BlockDriverState *bs) + return bs ? bs->aio_context : qemu_get_aio_context(); + } + +-AioWait *bdrv_get_aio_wait(BlockDriverState *bs) +-{ +- return bs ? &bs->wait : NULL; +-} +- + void bdrv_coroutine_enter(BlockDriverState *bs, Coroutine *co) + { + aio_co_enter(bdrv_get_aio_context(bs), co); +diff --git a/block/block-backend.c b/block/block-backend.c +index 9a3e060..723ab5a 100644 +--- a/block/block-backend.c ++++ b/block/block-backend.c +@@ -88,7 +88,6 @@ struct BlockBackend { + * Accessed with atomic ops. + */ + unsigned int in_flight; +- AioWait wait; + }; + + typedef struct BlockBackendAIOCB { +@@ -1300,7 +1299,7 @@ static void blk_inc_in_flight(BlockBackend *blk) + static void blk_dec_in_flight(BlockBackend *blk) + { + atomic_dec(&blk->in_flight); +- aio_wait_kick(&blk->wait); ++ aio_wait_kick(); + } + + static void error_callback_bh(void *opaque) +@@ -1601,9 +1600,8 @@ void blk_drain(BlockBackend *blk) + } + + /* We may have -ENOMEDIUM completions in flight */ +- AIO_WAIT_WHILE(&blk->wait, +- blk_get_aio_context(blk), +- atomic_mb_read(&blk->in_flight) > 0); ++ AIO_WAIT_WHILE(blk_get_aio_context(blk), ++ atomic_mb_read(&blk->in_flight) > 0); + + if (bs) { + bdrv_drained_end(bs); +@@ -1622,8 +1620,7 @@ void blk_drain_all(void) + aio_context_acquire(ctx); + + /* We may have -ENOMEDIUM completions in flight */ +- AIO_WAIT_WHILE(&blk->wait, ctx, +- atomic_mb_read(&blk->in_flight) > 0); ++ AIO_WAIT_WHILE(ctx, atomic_mb_read(&blk->in_flight) > 0); + + aio_context_release(ctx); + } +diff --git a/block/io.c b/block/io.c +index 8b81ff3..bd9d688 100644 +--- a/block/io.c ++++ b/block/io.c +@@ -38,8 +38,6 @@ + /* Maximum bounce buffer for copy-on-read and write zeroes, in bytes */ + #define MAX_BOUNCE_BUFFER (32768 << BDRV_SECTOR_BITS) + +-static AioWait drain_all_aio_wait; +- + static void bdrv_parent_cb_resize(BlockDriverState *bs); + static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs, + int64_t offset, int bytes, BdrvRequestFlags flags); +@@ -557,7 +555,7 @@ void bdrv_drain_all_begin(void) + } + + /* Now poll the in-flight requests */ +- AIO_WAIT_WHILE(&drain_all_aio_wait, NULL, bdrv_drain_all_poll()); ++ AIO_WAIT_WHILE(NULL, bdrv_drain_all_poll()); + + while ((bs = bdrv_next_all_states(bs))) { + bdrv_drain_assert_idle(bs); +@@ -713,8 +711,7 @@ void bdrv_inc_in_flight(BlockDriverState *bs) + + void bdrv_wakeup(BlockDriverState *bs) + { +- aio_wait_kick(bdrv_get_aio_wait(bs)); +- aio_wait_kick(&drain_all_aio_wait); ++ aio_wait_kick(); + } + + void bdrv_dec_in_flight(BlockDriverState *bs) +diff --git a/blockjob.c b/blockjob.c +index 617d86f..06f2429 100644 +--- a/blockjob.c ++++ b/blockjob.c +@@ -221,20 +221,9 @@ int block_job_add_bdrv(BlockJob *job, const char *name, BlockDriverState *bs, + return 0; + } + +-void block_job_wakeup_all_bdrv(BlockJob *job) +-{ +- GSList *l; +- +- for (l = job->nodes; l; l = l->next) { +- BdrvChild *c = l->data; +- bdrv_wakeup(c->bs); +- } +-} +- + static void block_job_on_idle(Notifier *n, void *opaque) + { +- BlockJob *job = opaque; +- block_job_wakeup_all_bdrv(job); ++ aio_wait_kick(); + } + + bool block_job_is_internal(BlockJob *job) +diff --git a/include/block/aio-wait.h b/include/block/aio-wait.h +index 600fad1..afd0ff7 100644 +--- a/include/block/aio-wait.h ++++ b/include/block/aio-wait.h +@@ -30,14 +30,15 @@ + /** + * AioWait: + * +- * An object that facilitates synchronous waiting on a condition. The main +- * loop can wait on an operation running in an IOThread as follows: ++ * An object that facilitates synchronous waiting on a condition. A single ++ * global AioWait object (global_aio_wait) is used internally. ++ * ++ * The main loop can wait on an operation running in an IOThread as follows: + * +- * AioWait *wait = ...; + * AioContext *ctx = ...; + * MyWork work = { .done = false }; + * schedule_my_work_in_iothread(ctx, &work); +- * AIO_WAIT_WHILE(wait, ctx, !work.done); ++ * AIO_WAIT_WHILE(ctx, !work.done); + * + * The IOThread must call aio_wait_kick() to notify the main loop when + * work.done changes: +@@ -46,7 +47,7 @@ + * { + * ... + * work.done = true; +- * aio_wait_kick(wait); ++ * aio_wait_kick(); + * } + */ + typedef struct { +@@ -54,9 +55,10 @@ typedef struct { + unsigned num_waiters; + } AioWait; + ++extern AioWait global_aio_wait; ++ + /** + * AIO_WAIT_WHILE: +- * @wait: the aio wait object + * @ctx: the aio context, or NULL if multiple aio contexts (for which the + * caller does not hold a lock) are involved in the polling condition. + * @cond: wait while this conditional expression is true +@@ -72,9 +74,9 @@ typedef struct { + * wait on conditions between two IOThreads since that could lead to deadlock, + * go via the main loop instead. + */ +-#define AIO_WAIT_WHILE(wait, ctx, cond) ({ \ ++#define AIO_WAIT_WHILE(ctx, cond) ({ \ + bool waited_ = false; \ +- AioWait *wait_ = (wait); \ ++ AioWait *wait_ = &global_aio_wait; \ + AioContext *ctx_ = (ctx); \ + /* Increment wait_->num_waiters before evaluating cond. */ \ + atomic_inc(&wait_->num_waiters); \ +@@ -102,14 +104,12 @@ typedef struct { + + /** + * aio_wait_kick: +- * @wait: the aio wait object that should re-evaluate its condition +- * + * Wake up the main thread if it is waiting on AIO_WAIT_WHILE(). During + * synchronous operations performed in an IOThread, the main thread lets the + * IOThread's event loop run, waiting for the operation to complete. A + * aio_wait_kick() call will wake up the main thread. + */ +-void aio_wait_kick(AioWait *wait); ++void aio_wait_kick(void); + + /** + * aio_wait_bh_oneshot: +diff --git a/include/block/block.h b/include/block/block.h +index 4e0871a..4edc1e8 100644 +--- a/include/block/block.h ++++ b/include/block/block.h +@@ -410,13 +410,9 @@ void bdrv_drain_all_begin(void); + void bdrv_drain_all_end(void); + void bdrv_drain_all(void); + +-/* Returns NULL when bs == NULL */ +-AioWait *bdrv_get_aio_wait(BlockDriverState *bs); +- + #define BDRV_POLL_WHILE(bs, cond) ({ \ + BlockDriverState *bs_ = (bs); \ +- AIO_WAIT_WHILE(bdrv_get_aio_wait(bs_), \ +- bdrv_get_aio_context(bs_), \ ++ AIO_WAIT_WHILE(bdrv_get_aio_context(bs_), \ + cond); }) + + int bdrv_pdiscard(BdrvChild *child, int64_t offset, int bytes); +diff --git a/include/block/block_int.h b/include/block/block_int.h +index 4000d2a..92ecbd8 100644 +--- a/include/block/block_int.h ++++ b/include/block/block_int.h +@@ -794,9 +794,6 @@ struct BlockDriverState { + unsigned int in_flight; + unsigned int serialising_in_flight; + +- /* Kicked to signal main loop when a request completes. */ +- AioWait wait; +- + /* counter for nested bdrv_io_plug. + * Accessed with atomic ops. + */ +diff --git a/include/block/blockjob.h b/include/block/blockjob.h +index 2290bbb..ede0bd8 100644 +--- a/include/block/blockjob.h ++++ b/include/block/blockjob.h +@@ -122,16 +122,6 @@ int block_job_add_bdrv(BlockJob *job, const char *name, BlockDriverState *bs, + void block_job_remove_all_bdrv(BlockJob *job); + + /** +- * block_job_wakeup_all_bdrv: +- * @job: The block job +- * +- * Calls bdrv_wakeup() for all BlockDriverStates that have been added to the +- * job. This function is to be called whenever child_job_drained_poll() would +- * go from true to false to notify waiting drain requests. +- */ +-void block_job_wakeup_all_bdrv(BlockJob *job); +- +-/** + * block_job_set_speed: + * @job: The job to set the speed for. + * @speed: The new value +diff --git a/job.c b/job.c +index 0b02186..ed4da6f 100644 +--- a/job.c ++++ b/job.c +@@ -978,7 +978,6 @@ void job_complete(Job *job, Error **errp) + int job_finish_sync(Job *job, void (*finish)(Job *, Error **errp), Error **errp) + { + Error *local_err = NULL; +- AioWait dummy_wait = {}; + int ret; + + job_ref(job); +@@ -992,7 +991,7 @@ int job_finish_sync(Job *job, void (*finish)(Job *, Error **errp), Error **errp) + return -EBUSY; + } + +- AIO_WAIT_WHILE(&dummy_wait, job->aio_context, ++ AIO_WAIT_WHILE(job->aio_context, + (job_drain(job), !job_is_completed(job))); + + ret = (job_is_cancelled(job) && job->ret == 0) ? -ECANCELED : job->ret; +diff --git a/util/aio-wait.c b/util/aio-wait.c +index b8a8f86..b487749 100644 +--- a/util/aio-wait.c ++++ b/util/aio-wait.c +@@ -26,21 +26,22 @@ + #include "qemu/main-loop.h" + #include "block/aio-wait.h" + ++AioWait global_aio_wait; ++ + static void dummy_bh_cb(void *opaque) + { + /* The point is to make AIO_WAIT_WHILE()'s aio_poll() return */ + } + +-void aio_wait_kick(AioWait *wait) ++void aio_wait_kick(void) + { + /* The barrier (or an atomic op) is in the caller. */ +- if (atomic_read(&wait->num_waiters)) { ++ if (atomic_read(&global_aio_wait.num_waiters)) { + aio_bh_schedule_oneshot(qemu_get_aio_context(), dummy_bh_cb, NULL); + } + } + + typedef struct { +- AioWait wait; + bool done; + QEMUBHFunc *cb; + void *opaque; +@@ -54,7 +55,7 @@ static void aio_wait_bh(void *opaque) + data->cb(data->opaque); + + data->done = true; +- aio_wait_kick(&data->wait); ++ aio_wait_kick(); + } + + void aio_wait_bh_oneshot(AioContext *ctx, QEMUBHFunc *cb, void *opaque) +@@ -67,5 +68,5 @@ void aio_wait_bh_oneshot(AioContext *ctx, QEMUBHFunc *cb, void *opaque) + assert(qemu_get_current_aio_context() == qemu_get_aio_context()); + + aio_bh_schedule_oneshot(ctx, aio_wait_bh, &data); +- AIO_WAIT_WHILE(&data.wait, ctx, !data.done); ++ AIO_WAIT_WHILE(ctx, !data.done); + } +-- +1.8.3.1 + diff --git a/0099-test-bdrv-drain-Test-draining-job-source-child-and-p.patch b/0099-test-bdrv-drain-Test-draining-job-source-child-and-p.patch new file mode 100644 index 0000000..5533b5f --- /dev/null +++ b/0099-test-bdrv-drain-Test-draining-job-source-child-and-p.patch @@ -0,0 +1,198 @@ +From f31ce5e7d486c860d44cb103b672f81de9bc537c Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Wed, 10 Oct 2018 20:22:13 +0100 +Subject: test-bdrv-drain: Test draining job source child and parent + +RH-Author: Kevin Wolf +Message-id: <20181010202213.7372-35-kwolf@redhat.com> +Patchwork-id: 82624 +O-Subject: [RHEL-8 qemu-kvm PATCH 44/44] test-bdrv-drain: Test draining job source child and parent +Bugzilla: 1637976 +RH-Acked-by: Max Reitz +RH-Acked-by: John Snow +RH-Acked-by: Thomas Huth + +For the block job drain test, don't only test draining the source and +the target node, but create a backing chain for the source +(source_backing <- source <- source_overlay) and test draining each of +the nodes in it. + +When using iothreads, the source node (and therefore the job) is in a +different AioContext than the drain, which happens from the main +thread. This way, the main thread waits in AIO_WAIT_WHILE() for the +iothread to make process and aio_wait_kick() is required to notify it. +The test validates that calling bdrv_wakeup() for a child or a parent +node will actually notify AIO_WAIT_WHILE() instead of letting it hang. + +Increase the sleep time a bit (to 1 ms) because the test case is racy +and with the shorter sleep, it didn't reproduce the bug it is supposed +to test for me under 'rr record -n'. + +This was because bdrv_drain_invoke_entry() (in the main thread) was only +called after the job had already reached the pause point, so we got a +bdrv_dec_in_flight() from the main thread and the additional +aio_wait_kick() when the job becomes idle (that we really wanted to test +here) wasn't even necessary any more to make progress. + +Signed-off-by: Kevin Wolf +Reviewed-by: Eric Blake +Reviewed-by: Max Reitz +(cherry picked from commit d8b3afd597d54e496809b05ac39ac29a5799664f) +Signed-off-by: Kevin Wolf +Signed-off-by: Danilo C. L. de Paula +--- + tests/test-bdrv-drain.c | 77 ++++++++++++++++++++++++++++++++++++++++++++----- + 1 file changed, 69 insertions(+), 8 deletions(-) + +diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c +index 7e7ba9b..8641b54 100644 +--- a/tests/test-bdrv-drain.c ++++ b/tests/test-bdrv-drain.c +@@ -786,6 +786,7 @@ typedef struct TestBlockJob { + BlockJob common; + int run_ret; + int prepare_ret; ++ bool running; + bool should_complete; + } TestBlockJob; + +@@ -818,12 +819,17 @@ static int coroutine_fn test_job_run(Job *job, Error **errp) + { + TestBlockJob *s = container_of(job, TestBlockJob, common.job); + ++ /* We are running the actual job code past the pause point in ++ * job_co_entry(). */ ++ s->running = true; ++ + job_transition_to_ready(&s->common.job); + while (!s->should_complete) { + /* Avoid job_sleep_ns() because it marks the job as !busy. We want to + * emulate some actual activity (probably some I/O) here so that drain + * has to wait for this activity to stop. */ +- qemu_co_sleep_ns(QEMU_CLOCK_REALTIME, 100000); ++ qemu_co_sleep_ns(QEMU_CLOCK_REALTIME, 1000000); ++ + job_pause_point(&s->common.job); + } + +@@ -856,11 +862,19 @@ enum test_job_result { + TEST_JOB_FAIL_PREPARE, + }; + +-static void test_blockjob_common(enum drain_type drain_type, bool use_iothread, +- enum test_job_result result) ++enum test_job_drain_node { ++ TEST_JOB_DRAIN_SRC, ++ TEST_JOB_DRAIN_SRC_CHILD, ++ TEST_JOB_DRAIN_SRC_PARENT, ++}; ++ ++static void test_blockjob_common_drain_node(enum drain_type drain_type, ++ bool use_iothread, ++ enum test_job_result result, ++ enum test_job_drain_node drain_node) + { + BlockBackend *blk_src, *blk_target; +- BlockDriverState *src, *target; ++ BlockDriverState *src, *src_backing, *src_overlay, *target, *drain_bs; + BlockJob *job; + TestBlockJob *tjob; + IOThread *iothread = NULL; +@@ -869,8 +883,32 @@ static void test_blockjob_common(enum drain_type drain_type, bool use_iothread, + + src = bdrv_new_open_driver(&bdrv_test, "source", BDRV_O_RDWR, + &error_abort); ++ src_backing = bdrv_new_open_driver(&bdrv_test, "source-backing", ++ BDRV_O_RDWR, &error_abort); ++ src_overlay = bdrv_new_open_driver(&bdrv_test, "source-overlay", ++ BDRV_O_RDWR, &error_abort); ++ ++ bdrv_set_backing_hd(src_overlay, src, &error_abort); ++ bdrv_unref(src); ++ bdrv_set_backing_hd(src, src_backing, &error_abort); ++ bdrv_unref(src_backing); ++ + blk_src = blk_new(BLK_PERM_ALL, BLK_PERM_ALL); +- blk_insert_bs(blk_src, src, &error_abort); ++ blk_insert_bs(blk_src, src_overlay, &error_abort); ++ ++ switch (drain_node) { ++ case TEST_JOB_DRAIN_SRC: ++ drain_bs = src; ++ break; ++ case TEST_JOB_DRAIN_SRC_CHILD: ++ drain_bs = src_backing; ++ break; ++ case TEST_JOB_DRAIN_SRC_PARENT: ++ drain_bs = src_overlay; ++ break; ++ default: ++ g_assert_not_reached(); ++ } + + if (use_iothread) { + iothread = iothread_new(); +@@ -906,11 +944,21 @@ static void test_blockjob_common(enum drain_type drain_type, bool use_iothread, + job_start(&job->job); + aio_context_release(ctx); + ++ if (use_iothread) { ++ /* job_co_entry() is run in the I/O thread, wait for the actual job ++ * code to start (we don't want to catch the job in the pause point in ++ * job_co_entry(). */ ++ while (!tjob->running) { ++ aio_poll(qemu_get_aio_context(), false); ++ } ++ } ++ + g_assert_cmpint(job->job.pause_count, ==, 0); + g_assert_false(job->job.paused); ++ g_assert_true(tjob->running); + g_assert_true(job->job.busy); /* We're in qemu_co_sleep_ns() */ + +- do_drain_begin_unlocked(drain_type, src); ++ do_drain_begin_unlocked(drain_type, drain_bs); + + if (drain_type == BDRV_DRAIN_ALL) { + /* bdrv_drain_all() drains both src and target */ +@@ -921,7 +969,7 @@ static void test_blockjob_common(enum drain_type drain_type, bool use_iothread, + g_assert_true(job->job.paused); + g_assert_false(job->job.busy); /* The job is paused */ + +- do_drain_end_unlocked(drain_type, src); ++ do_drain_end_unlocked(drain_type, drain_bs); + + if (use_iothread) { + /* paused is reset in the I/O thread, wait for it */ +@@ -969,7 +1017,7 @@ static void test_blockjob_common(enum drain_type drain_type, bool use_iothread, + + blk_unref(blk_src); + blk_unref(blk_target); +- bdrv_unref(src); ++ bdrv_unref(src_overlay); + bdrv_unref(target); + + if (iothread) { +@@ -977,6 +1025,19 @@ static void test_blockjob_common(enum drain_type drain_type, bool use_iothread, + } + } + ++static void test_blockjob_common(enum drain_type drain_type, bool use_iothread, ++ enum test_job_result result) ++{ ++ test_blockjob_common_drain_node(drain_type, use_iothread, result, ++ TEST_JOB_DRAIN_SRC); ++ test_blockjob_common_drain_node(drain_type, use_iothread, result, ++ TEST_JOB_DRAIN_SRC_CHILD); ++ if (drain_type == BDRV_SUBTREE_DRAIN) { ++ test_blockjob_common_drain_node(drain_type, use_iothread, result, ++ TEST_JOB_DRAIN_SRC_PARENT); ++ } ++} ++ + static void test_blockjob_drain_all(void) + { + test_blockjob_common(BDRV_DRAIN_ALL, false, TEST_JOB_SUCCESS); +-- +1.8.3.1 + diff --git a/0100-block-rbd-pull-out-qemu_rbd_convert_options.patch b/0100-block-rbd-pull-out-qemu_rbd_convert_options.patch new file mode 100644 index 0000000..a88abfb --- /dev/null +++ b/0100-block-rbd-pull-out-qemu_rbd_convert_options.patch @@ -0,0 +1,95 @@ +From 5fcd80dc34d84739e75e6d1ec5e21ad73af14ff9 Mon Sep 17 00:00:00 2001 +From: John Snow +Date: Wed, 10 Oct 2018 20:30:12 +0100 +Subject: block/rbd: pull out qemu_rbd_convert_options + +RH-Author: John Snow +Message-id: <20181010203015.11719-2-jsnow@redhat.com> +Patchwork-id: 82627 +O-Subject: [RHEL8/rhel qemu-kvm PATCH 1/4] block/rbd: pull out qemu_rbd_convert_options +Bugzilla: 1635585 +RH-Acked-by: Markus Armbruster +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +From: Jeff Cody + +Code movement to pull the conversion from Qdict to BlockdevOptionsRbd +into a helper function. + +Reviewed-by: Eric Blake +Reviewed-by: John Snow +Signed-off-by: Jeff Cody +Message-id: 5b49a980f2cde6610ab1df41bb0277d00b5db893.1536704901.git.jcody@redhat.com +Signed-off-by: Jeff Cody +(cherry picked from commit f24b03b56cdb28d753b4ff9ae210d555f14cb0d8) +Signed-off-by: John Snow +Signed-off-by: Danilo C. L. de Paula +--- + block/rbd.c | 36 ++++++++++++++++++++++++------------ + 1 file changed, 24 insertions(+), 12 deletions(-) + +diff --git a/block/rbd.c b/block/rbd.c +index ca8e5bb..b199450 100644 +--- a/block/rbd.c ++++ b/block/rbd.c +@@ -655,12 +655,34 @@ failed_opts: + return r; + } + ++static int qemu_rbd_convert_options(QDict *options, BlockdevOptionsRbd **opts, ++ Error **errp) ++{ ++ Visitor *v; ++ Error *local_err = NULL; ++ ++ /* Convert the remaining options into a QAPI object */ ++ v = qobject_input_visitor_new_flat_confused(options, errp); ++ if (!v) { ++ return -EINVAL; ++ } ++ ++ visit_type_BlockdevOptionsRbd(v, NULL, opts, &local_err); ++ visit_free(v); ++ ++ if (local_err) { ++ error_propagate(errp, local_err); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ + static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags, + Error **errp) + { + BDRVRBDState *s = bs->opaque; + BlockdevOptionsRbd *opts = NULL; +- Visitor *v; + const QDictEntry *e; + Error *local_err = NULL; + char *keypairs, *secretid; +@@ -676,19 +698,9 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags, + qdict_del(options, "password-secret"); + } + +- /* Convert the remaining options into a QAPI object */ +- v = qobject_input_visitor_new_flat_confused(options, errp); +- if (!v) { +- r = -EINVAL; +- goto out; +- } +- +- visit_type_BlockdevOptionsRbd(v, NULL, &opts, &local_err); +- visit_free(v); +- ++ r = qemu_rbd_convert_options(options, &opts, &local_err); + if (local_err) { + error_propagate(errp, local_err); +- r = -EINVAL; + goto out; + } + +-- +1.8.3.1 + diff --git a/0101-block-rbd-Attempt-to-parse-legacy-filenames.patch b/0101-block-rbd-Attempt-to-parse-legacy-filenames.patch new file mode 100644 index 0000000..24add45 --- /dev/null +++ b/0101-block-rbd-Attempt-to-parse-legacy-filenames.patch @@ -0,0 +1,120 @@ +From 6198ce651b242298fa6f5cc7ba79eb168789899c Mon Sep 17 00:00:00 2001 +From: John Snow +Date: Wed, 10 Oct 2018 20:30:13 +0100 +Subject: block/rbd: Attempt to parse legacy filenames + +RH-Author: John Snow +Message-id: <20181010203015.11719-3-jsnow@redhat.com> +Patchwork-id: 82629 +O-Subject: [RHEL8/rhel qemu-kvm PATCH 2/4] block/rbd: Attempt to parse legacy filenames +Bugzilla: 1635585 +RH-Acked-by: Markus Armbruster +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +From: Jeff Cody + +When we converted rbd to get rid of the older key/value-centric +encoding format, we broke compatibility with image files with backing +file strings encoded in the old format. + +This leaves a bit of an ugly conundrum, and a hacky solution. + +If the initial attempt to parse the "proper" options fails, it assumes +that we may have an older key/value encoded filename. Fall back to +attempting to parse the filename, and extract the required options from +it. If that fails, pass along the original error message. + +We do not support mixed modern usage alongside legacy keyvalue pair +usage. + +A deprecation warning has been added, although care should be taken +when actually deprecating since the impact is not limited to +commandline or qapi usage, but also opening existing images. + +Reviewed-by: Eric Blake +Signed-off-by: Jeff Cody +Message-id: 15b332e5432ad069441f7275a46080f465d789a0.1536704901.git.jcody@redhat.com +Signed-off-by: Jeff Cody +(cherry picked from commit 084d1d13bdb753d558b991996e7686c077bd6d80) +Signed-off-by: John Snow +Signed-off-by: Danilo C. L. de Paula +--- + block/rbd.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 52 insertions(+), 2 deletions(-) + +diff --git a/block/rbd.c b/block/rbd.c +index b199450..014c68d 100644 +--- a/block/rbd.c ++++ b/block/rbd.c +@@ -678,6 +678,33 @@ static int qemu_rbd_convert_options(QDict *options, BlockdevOptionsRbd **opts, + return 0; + } + ++static int qemu_rbd_attempt_legacy_options(QDict *options, ++ BlockdevOptionsRbd **opts, ++ char **keypairs) ++{ ++ char *filename; ++ int r; ++ ++ filename = g_strdup(qdict_get_try_str(options, "filename")); ++ if (!filename) { ++ return -EINVAL; ++ } ++ qdict_del(options, "filename"); ++ ++ qemu_rbd_parse_filename(filename, options, NULL); ++ ++ /* keypairs freed by caller */ ++ *keypairs = g_strdup(qdict_get_try_str(options, "=keyvalue-pairs")); ++ if (*keypairs) { ++ qdict_del(options, "=keyvalue-pairs"); ++ } ++ ++ r = qemu_rbd_convert_options(options, opts, NULL); ++ ++ g_free(filename); ++ return r; ++} ++ + static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags, + Error **errp) + { +@@ -700,8 +727,31 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags, + + r = qemu_rbd_convert_options(options, &opts, &local_err); + if (local_err) { +- error_propagate(errp, local_err); +- goto out; ++ /* If keypairs are present, that means some options are present in ++ * the modern option format. Don't attempt to parse legacy option ++ * formats, as we won't support mixed usage. */ ++ if (keypairs) { ++ error_propagate(errp, local_err); ++ goto out; ++ } ++ ++ /* If the initial attempt to convert and process the options failed, ++ * we may be attempting to open an image file that has the rbd options ++ * specified in the older format consisting of all key/value pairs ++ * encoded in the filename. Go ahead and attempt to parse the ++ * filename, and see if we can pull out the required options. */ ++ r = qemu_rbd_attempt_legacy_options(options, &opts, &keypairs); ++ if (r < 0) { ++ /* Propagate the original error, not the legacy parsing fallback ++ * error, as the latter was just a best-effort attempt. */ ++ error_propagate(errp, local_err); ++ goto out; ++ } ++ /* Take care whenever deciding to actually deprecate; once this ability ++ * is removed, we will not be able to open any images with legacy-styled ++ * backing image strings. */ ++ error_report("RBD options encoded in the filename as keyvalue pairs " ++ "is deprecated"); + } + + /* Remove the processed options from the QDict (the visitor processes +-- +1.8.3.1 + diff --git a/0102-block-rbd-add-deprecation-documentation-for-filename.patch b/0102-block-rbd-add-deprecation-documentation-for-filename.patch new file mode 100644 index 0000000..fdd94ea --- /dev/null +++ b/0102-block-rbd-add-deprecation-documentation-for-filename.patch @@ -0,0 +1,59 @@ +From aed464e31c9f6d92aa67960dc1a0891461393305 Mon Sep 17 00:00:00 2001 +From: John Snow +Date: Tue, 11 Sep 2018 18:32:33 -0400 +Subject: block/rbd: add deprecation documentation for filename keyvalue pairs + +RH-Author: John Snow +Message-id: <20181010203015.11719-5-jsnow@redhat.com> +Patchwork-id: 82625 +O-Subject: [RHEL8/rhel qemu-kvm PATCH 4/4] block/rbd: add deprecation docume +Bugzilla: 1635585 +RH-Acked-by: Markus Armbruster +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +From: Jeff Cody + +Signed-off-by: Jeff Cody +Message-id: 647f5b5ab7efd8bf567a504c832b1d2d6f719b23.1536704901.git.jcody@re +Signed-off-by: Jeff Cody +(cherry picked from commit 3bebd37e04f972775b1ece1bdda95451bc9fb14c) +Signed-off-by: John Snow +Signed-off-by: Danilo C. L. de Paula +Signed-off-by: John Snow + +Rebase notes (3.0.0): +- Used upstream version +--- + qemu-deprecated.texi | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/qemu-deprecated.texi b/qemu-deprecated.texi +index 9920a85..cff0e8b 100644 +--- a/qemu-deprecated.texi ++++ b/qemu-deprecated.texi +@@ -227,6 +227,21 @@ from old QEMU versions anymore. A newer machine type should be used instead. + In order to prevent QEMU from automatically opening an image's backing + chain, use ``"backing": null'' instead. + ++@subsubsection rbd keyvalue pair encoded filenames: "" (since 3.1.0) ++ ++Options for ``rbd'' should be specified according to its runtime options, ++like other block drivers. Legacy parsing of keyvalue pair encoded ++filenames is useful to open images with the old format for backing files; ++These image files should be updated to use the current format. ++ ++Example of legacy encoding: ++ ++@code{json:@{"file.driver":"rbd", "file.filename":"rbd:rbd/name"@}} ++ ++The above, converted to the current supported format: ++ ++@code{json:@{"file.driver":"rbd", "file.pool":"rbd", "file.image":"name"@}} ++ + @subsection vio-spapr-device device options + + @subsubsection "irq": "" (since 3.0.0) +-- +1.8.3.1 + diff --git a/0103-block-rbd-add-iotest-for-rbd-legacy-keyvalue-filenam.patch b/0103-block-rbd-add-iotest-for-rbd-legacy-keyvalue-filenam.patch new file mode 100644 index 0000000..397826f --- /dev/null +++ b/0103-block-rbd-add-iotest-for-rbd-legacy-keyvalue-filenam.patch @@ -0,0 +1,141 @@ +From 76eb6df2dfd755e7cbda2eb07df464d25f9d73c5 Mon Sep 17 00:00:00 2001 +From: John Snow +Date: Wed, 10 Oct 2018 20:30:14 +0100 +Subject: block/rbd: add iotest for rbd legacy keyvalue filename parsing + +RH-Author: John Snow +Message-id: <20181010203015.11719-4-jsnow@redhat.com> +Patchwork-id: 82628 +O-Subject: [RHEL8/rhel qemu-kvm PATCH 3/4] block/rbd: add iotest for rbd legacy keyvalue filename parsing +Bugzilla: 1635585 +RH-Acked-by: Markus Armbruster +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +From: Jeff Cody + +This is a small test that will check for the ability to parse +both legacy and modern options for rbd. + +The way the test is set up is for failure to occur, but without +having to wait to timeout on a non-existent rbd server. The error +messages in the success path show that the arguments were parsed. + +The failure behavior prior to the patch series that has this test, is +qemu-img complaining about mandatory options (e.g. 'pool') not being +provided. + +Reviewed-by: Eric Blake +Signed-off-by: Jeff Cody +Message-id: f830580e339b974a83ed4870d11adcdc17f49a47.1536704901.git.jcody@redhat.com +Signed-off-by: Jeff Cody +(cherry picked from commit 66e6a735e97450ac50fcaf40f78600c688534cae) +Signed-off-by: John Snow +Signed-off-by: Danilo C. L. de Paula + +Conflicts: + tests/qemu-iotests/group: context (missing prior tests) +Signed-off-by: John Snow +--- + tests/qemu-iotests/231 | 62 ++++++++++++++++++++++++++++++++++++++++++++++ + tests/qemu-iotests/231.out | 9 +++++++ + tests/qemu-iotests/group | 1 + + 3 files changed, 72 insertions(+) + create mode 100755 tests/qemu-iotests/231 + create mode 100644 tests/qemu-iotests/231.out + +diff --git a/tests/qemu-iotests/231 b/tests/qemu-iotests/231 +new file mode 100755 +index 0000000..3e28370 +--- /dev/null ++++ b/tests/qemu-iotests/231 +@@ -0,0 +1,62 @@ ++#!/bin/bash ++# ++# Test legacy and modern option parsing for rbd/ceph. This will not ++# actually connect to a ceph server, but rather looks for the appropriate ++# error message that indicates we parsed the options correctly. ++# ++# Copyright (C) 2018 Red Hat, Inc. ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++# ++ ++# creator ++owner=jcody@redhat.com ++ ++seq=`basename $0` ++echo "QA output created by $seq" ++ ++here=`pwd` ++status=1 # failure is the default! ++ ++_cleanup() ++{ ++ rm "${BOGUS_CONF}" ++} ++trap "_cleanup; exit \$status" 0 1 2 3 15 ++ ++# get standard environment, filters and checks ++. ./common.rc ++. ./common.filter ++ ++_supported_fmt generic ++_supported_proto rbd ++_supported_os Linux ++ ++BOGUS_CONF=${TEST_DIR}/ceph-$$.conf ++touch "${BOGUS_CONF}" ++ ++_filter_conf() ++{ ++ sed -e "s#$BOGUS_CONF#BOGUS_CONF#g" ++} ++ ++# We expect this to fail, with no monitor ip provided and a null conf file. Just want it ++# to fail in the right way. ++$QEMU_IMG info "json:{'file.driver':'rbd','file.filename':'rbd:rbd/bogus:conf=${BOGUS_CONF}'}" 2>&1 | _filter_conf ++$QEMU_IMG info "json:{'file.driver':'rbd','file.pool':'rbd','file.image':'bogus','file.conf':'${BOGUS_CONF}'}" 2>&1 | _filter_conf ++ ++# success, all done ++echo "*** done" ++rm -f $seq.full ++status=0 +diff --git a/tests/qemu-iotests/231.out b/tests/qemu-iotests/231.out +new file mode 100644 +index 0000000..579ba11 +--- /dev/null ++++ b/tests/qemu-iotests/231.out +@@ -0,0 +1,9 @@ ++QA output created by 231 ++qemu-img: RBD options encoded in the filename as keyvalue pairs is deprecated. Future versions may cease to parse these options in the future. ++unable to get monitor info from DNS SRV with service name: ceph-mon ++no monitors specified to connect to. ++qemu-img: Could not open 'json:{'file.driver':'rbd','file.filename':'rbd:rbd/bogus:conf=BOGUS_CONF'}': error connecting: No such file or directory ++unable to get monitor info from DNS SRV with service name: ceph-mon ++no monitors specified to connect to. ++qemu-img: Could not open 'json:{'file.driver':'rbd','file.pool':'rbd','file.image':'bogus','file.conf':'BOGUS_CONF'}': error connecting: No such file or directory ++*** done +diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group +index 23ab4d3..cc1ca7e 100644 +--- a/tests/qemu-iotests/group ++++ b/tests/qemu-iotests/group +@@ -226,3 +226,4 @@ + 226 auto quick + 227 auto quick + 229 auto quick ++231 auto quick +-- +1.8.3.1 + diff --git a/0104-luks-Allow-share-rw-on.patch b/0104-luks-Allow-share-rw-on.patch new file mode 100644 index 0000000..bdb3f47 --- /dev/null +++ b/0104-luks-Allow-share-rw-on.patch @@ -0,0 +1,52 @@ +From 8a08519b748ec41c6f542f4ef9406647269db18c Mon Sep 17 00:00:00 2001 +From: Fam Zheng +Date: Fri, 28 Sep 2018 06:09:52 +0100 +Subject: luks: Allow share-rw=on +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Fam Zheng +Message-id: <20180928060952.8616-2-famz@redhat.com> +Patchwork-id: 82311 +O-Subject: [RHEL8/rhel qemu-kvm PATCH 1/1] luks: Allow share-rw=on +Bugzilla: 1629701 +RH-Acked-by: Laszlo Ersek +RH-Acked-by: John Snow +RH-Acked-by: Thomas Huth + +Format drivers such as qcow2 don't allow sharing the same image between +two QEMU instances in order to prevent image corruptions, because of +metadata cache. LUKS driver don't modify metadata except for when +creating image, so it is safe to relax the permission. This makes +share-rw=on property work on virtual devices. + +Suggested-by: Daniel P. Berrangé +Signed-off-by: Fam Zheng +Reviewed-by: Daniel P. Berrangé +Signed-off-by: Kevin Wolf +(cherry picked from commit 497da8236ab2663a8108858ba7ea59aac21c5fe6) +Signed-off-by: Fam Zheng +Signed-off-by: Danilo C. L. de Paula +--- + block/crypto.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/block/crypto.c b/block/crypto.c +index 146d81c..33ee01b 100644 +--- a/block/crypto.c ++++ b/block/crypto.c +@@ -627,7 +627,9 @@ BlockDriver bdrv_crypto_luks = { + .bdrv_probe = block_crypto_probe_luks, + .bdrv_open = block_crypto_open_luks, + .bdrv_close = block_crypto_close, +- .bdrv_child_perm = bdrv_format_default_perms, ++ /* This driver doesn't modify LUKS metadata except when creating image. ++ * Allow share-rw=on as a special case. */ ++ .bdrv_child_perm = bdrv_filter_default_perms, + .bdrv_co_create = block_crypto_co_create_luks, + .bdrv_co_create_opts = block_crypto_co_create_opts_luks, + .bdrv_co_truncate = block_crypto_co_truncate, +-- +1.8.3.1 + diff --git a/81-kvm-rhel.rules b/81-kvm-rhel.rules new file mode 100644 index 0000000..787cad6 --- /dev/null +++ b/81-kvm-rhel.rules @@ -0,0 +1 @@ +DEVPATH=="*/kvm", ACTION=="change", RUN+="/lib/udev/udev-kvm-check $env{COUNT} $env{EVENT}" diff --git a/qemu-kvm.spec b/qemu-kvm.spec index 60b6e11..75804fb 100644 --- a/qemu-kvm.spec +++ b/qemu-kvm.spec @@ -5,7 +5,7 @@ %global have_spice 1 %global have_opengl 1 %global have_fdt 0 -%global have_gluster 0 +%global have_gluster 1 %global have_kvm_setup 0 %global have_seccomp 1 %global have_memlock_limits 0 @@ -56,6 +56,9 @@ %global requires_all_modules \ Requires: %{name}-block-curl = %{epoch}:%{version}-%{release} \ +%if %{have_gluster} \ +Requires: %{name}-block-gluster = %{epoch}:%{version}-%{release} \ +%endif \ Requires: %{name}-block-iscsi = %{epoch}:%{version}-%{release} \ Requires: %{name}-block-rbd = %{epoch}:%{version}-%{release} \ Requires: %{name}-block-ssh = %{epoch}:%{version}-%{release} @@ -69,7 +72,7 @@ Provides: %1-rhel = %{epoch}:%{version}-%{release} Summary: QEMU is a machine emulator and virtualizer Name: qemu-kvm Version: 3.0.0 -Release: 1%{?dist} +Release: 2%{?dist} # Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped Epoch: 15 License: GPLv2 and GPLv2+ and CC-BY @@ -106,54 +109,112 @@ Source30: kvm-s390x.conf Source31: kvm-x86.conf Source32: qemu-pr-helper.service Source33: qemu-pr-helper.socket +Source34: 81-kvm-rhel.rules +Source35: udev-kvm-check.c -Patch0001: 0001-Initial-redhat-build.patch -Patch0002: 0002-Enable-disable-devices-for-RHEL-7.patch -Patch0003: 0003-Add-RHEL-machine-types.patch -Patch0004: 0004-Use-kvm-by-default.patch -Patch0005: 0005-vfio-cap-number-of-devices-that-can-be-assigned.patch -Patch0006: 0006-Add-support-statement-to-help-output.patch -Patch0007: 0007-globally-limit-the-maximum-number-of-CPUs.patch -Patch0008: 0008-Add-support-for-simpletrace.patch -Patch0009: 0009-Use-qemu-kvm-in-documentation-instead-of-qemu-system.patch -Patch0010: 0010-usb-xhci-Fix-PCI-capability-order.patch -Patch0011: 0011-virtio-scsi-Reject-scsi-cd-if-data-plane-enabled-RHE.patch -Patch0012: 0012-linux-headers-asm-s390-kvm.h-header-sync.patch -Patch0013: 0013-s390x-Enable-KVM-huge-page-backing-support.patch -Patch0014: 0014-s390x-kvm-add-etoken-facility.patch -Patch0015: 0015-s390x-cpumodel-default-enable-bpb-and-ppa15-for-z196.patch -Patch0016: 0016-i386-Fix-arch_query_cpu_model_expansion-leak.patch -Patch0017: 0017-i386-Disable-TOPOEXT-by-default-on-cpu-host.patch -Patch0018: 0018-curl-Make-sslverify-off-disable-host-as-well-as-peer.patch -Patch0019: 0019-migration-postcopy-Clear-have_listen_thread.patch -Patch0020: 0020-migration-cleanup-in-error-paths-in-loadvm.patch -Patch0021: 0021-jobs-change-start-callback-to-run-callback.patch -Patch0022: 0022-jobs-canonize-Error-object.patch -Patch0023: 0023-jobs-add-exit-shim.patch -Patch0024: 0024-block-commit-utilize-job_exit-shim.patch -Patch0025: 0025-block-mirror-utilize-job_exit-shim.patch -Patch0026: 0026-jobs-utilize-job_exit-shim.patch -Patch0027: 0027-block-backup-make-function-variables-consistently-na.patch -Patch0028: 0028-jobs-remove-ret-argument-to-job_completed-privatize-.patch -Patch0029: 0029-jobs-remove-job_defer_to_main_loop.patch -Patch0030: 0030-block-commit-add-block-job-creation-flags.patch -Patch0031: 0031-block-mirror-add-block-job-creation-flags.patch -Patch0032: 0032-block-stream-add-block-job-creation-flags.patch -Patch0033: 0033-block-commit-refactor-commit-to-use-job-callbacks.patch -Patch0034: 0034-block-mirror-don-t-install-backing-chain-on-abort.patch -Patch0035: 0035-block-mirror-conservative-mirror_exit-refactor.patch -Patch0036: 0036-block-stream-refactor-stream-to-use-job-callbacks.patch -Patch0037: 0037-tests-blockjob-replace-Blockjob-with-Job.patch -Patch0038: 0038-tests-test-blockjob-remove-exit-callback.patch -Patch0039: 0039-tests-test-blockjob-txn-move-.exit-to-.clean.patch -Patch0040: 0040-jobs-remove-.exit-callback.patch -Patch0041: 0041-qapi-block-commit-expose-new-job-properties.patch -Patch0042: 0042-qapi-block-mirror-expose-new-job-properties.patch -Patch0043: 0043-qapi-block-stream-expose-new-job-properties.patch -Patch0044: 0044-block-backup-qapi-documentation-fixup.patch -Patch0045: 0045-blockdev-document-transactional-shortcomings.patch +Patch0004: 0004-Initial-redhat-build.patch +Patch0005: 0005-Enable-disable-devices-for-RHEL-7.patch +Patch0006: 0006-Machine-type-related-general-changes.patch +Patch0007: 0007-Add-aarch64-machine-types.patch +Patch0008: 0008-Add-ppc64-machine-types.patch +Patch0009: 0009-Add-s390x-machine-types.patch +Patch0010: 0010-Add-x86_64-machine-types.patch +Patch0011: 0011-Enable-make-check.patch +Patch0012: 0012-Use-kvm-by-default.patch +Patch0013: 0013-vfio-cap-number-of-devices-that-can-be-assigned.patch +Patch0014: 0014-Add-support-statement-to-help-output.patch +Patch0015: 0015-globally-limit-the-maximum-number-of-CPUs.patch +Patch0016: 0016-Add-support-for-simpletrace.patch +Patch0017: 0017-Use-qemu-kvm-in-documentation-instead-of-qemu-system.patch +Patch0018: 0018-usb-xhci-Fix-PCI-capability-order.patch +Patch0019: 0019-virtio-scsi-Reject-scsi-cd-if-data-plane-enabled-RHE.patch +Patch0020: 0020-linux-headers-asm-s390-kvm.h-header-sync.patch +Patch0021: 0021-s390x-Enable-KVM-huge-page-backing-support.patch +Patch0022: 0022-s390x-kvm-add-etoken-facility.patch +Patch0023: 0023-s390x-cpumodel-default-enable-bpb-and-ppa15-for-z196.patch +Patch0024: 0024-i386-Fix-arch_query_cpu_model_expansion-leak.patch +Patch0025: 0025-i386-Disable-TOPOEXT-by-default-on-cpu-host.patch +Patch0026: 0026-curl-Make-sslverify-off-disable-host-as-well-as-peer.patch +Patch0027: 0027-migration-postcopy-Clear-have_listen_thread.patch +Patch0028: 0028-migration-cleanup-in-error-paths-in-loadvm.patch +Patch0029: 0029-jobs-change-start-callback-to-run-callback.patch +Patch0030: 0030-jobs-canonize-Error-object.patch +Patch0031: 0031-jobs-add-exit-shim.patch +Patch0032: 0032-block-commit-utilize-job_exit-shim.patch +Patch0033: 0033-block-mirror-utilize-job_exit-shim.patch +Patch0034: 0034-jobs-utilize-job_exit-shim.patch +Patch0035: 0035-block-backup-make-function-variables-consistently-na.patch +Patch0036: 0036-jobs-remove-ret-argument-to-job_completed-privatize-.patch +Patch0037: 0037-jobs-remove-job_defer_to_main_loop.patch +Patch0038: 0038-block-commit-add-block-job-creation-flags.patch +Patch0039: 0039-block-mirror-add-block-job-creation-flags.patch +Patch0040: 0040-block-stream-add-block-job-creation-flags.patch +Patch0041: 0041-block-commit-refactor-commit-to-use-job-callbacks.patch +Patch0042: 0042-block-mirror-don-t-install-backing-chain-on-abort.patch +Patch0043: 0043-block-mirror-conservative-mirror_exit-refactor.patch +Patch0044: 0044-block-stream-refactor-stream-to-use-job-callbacks.patch +Patch0045: 0045-tests-blockjob-replace-Blockjob-with-Job.patch +Patch0046: 0046-tests-test-blockjob-remove-exit-callback.patch +Patch0047: 0047-tests-test-blockjob-txn-move-.exit-to-.clean.patch +Patch0048: 0048-jobs-remove-.exit-callback.patch +Patch0049: 0049-qapi-block-commit-expose-new-job-properties.patch +Patch0050: 0050-qapi-block-mirror-expose-new-job-properties.patch +Patch0051: 0051-qapi-block-stream-expose-new-job-properties.patch +Patch0052: 0052-block-backup-qapi-documentation-fixup.patch +Patch0053: 0053-blockdev-document-transactional-shortcomings.patch +Patch0054: 0054-seccomp-use-SIGSYS-signal-instead-of-killing-the-thr.patch +Patch0055: 0055-seccomp-prefer-SCMP_ACT_KILL_PROCESS-if-available.patch +Patch0056: 0056-seccomp-set-the-seccomp-filter-to-all-threads.patch +Patch0057: 0057-memory-cleanup-side-effects-of-memory_region_init_fo.patch +Patch0058: 0058-mirror-Fail-gracefully-for-source-target.patch +Patch0059: 0059-commit-Add-top-node-base-node-options.patch +Patch0060: 0060-qemu-iotests-Test-commit-with-top-node-base-node.patch +Patch0061: 0061-block-for-jobs-do-not-clear-user_paused-until-after-.patch +Patch0062: 0062-block-iotest-to-catch-abort-on-forced-blockjob-cance.patch +Patch0063: 0063-Revert-hw-acpi-build-build-SRAT-memory-affinity-stru.patch +Patch0064: 0064-aio-posix-Don-t-count-ctx-notifier-as-progress-when-.patch +Patch0065: 0065-aio-Do-aio_notify_accept-only-during-blocking-aio_po.patch +Patch0066: 0066-aio-posix-fix-concurrent-access-to-poll_disable_cnt.patch +Patch0067: 0067-aio-posix-compute-timeout-before-polling.patch +Patch0068: 0068-aio-posix-do-skip-system-call-if-ctx-notifier-pollin.patch +Patch0069: 0069-linux-headers-update.patch +Patch0070: 0070-s390x-cpumodel-Set-up-CPU-model-for-AP-device-suppor.patch +Patch0071: 0071-s390x-kvm-enable-AP-instruction-interpretation-for-g.patch +Patch0072: 0072-s390x-ap-base-Adjunct-Processor-AP-object-model.patch +Patch0073: 0073-s390x-vfio-ap-Introduce-VFIO-AP-device.patch +Patch0074: 0074-s390-doc-detailed-specifications-for-AP-virtualizati.patch +Patch0075: 0075-vnc-call-sasl_server_init-only-when-required.patch +Patch0076: 0076-nbd-server-fix-NBD_CMD_CACHE.patch +Patch0077: 0077-nbd-fix-NBD_FLAG_SEND_CACHE-value.patch +Patch0078: 0078-block-linux-aio-acquire-AioContext-before-qemu_laio_.patch +Patch0079: 0079-util-async-use-qemu_aio_coroutine_enter-in-co_schedu.patch +Patch0080: 0080-job-Fix-nested-aio_poll-hanging-in-job_txn_apply.patch +Patch0081: 0081-job-Fix-missing-locking-due-to-mismerge.patch +Patch0082: 0082-blockjob-Wake-up-BDS-when-job-becomes-idle.patch +Patch0083: 0083-aio-wait-Increase-num_waiters-even-in-home-thread.patch +Patch0084: 0084-test-bdrv-drain-Drain-with-block-jobs-in-an-I-O-thre.patch +Patch0085: 0085-test-blockjob-Acquire-AioContext-around-job_cancel_s.patch +Patch0086: 0086-job-Use-AIO_WAIT_WHILE-in-job_finish_sync.patch +Patch0087: 0087-test-bdrv-drain-Test-AIO_WAIT_WHILE-in-completion-ca.patch +Patch0088: 0088-block-Add-missing-locking-in-bdrv_co_drain_bh_cb.patch +Patch0089: 0089-block-backend-Add-.drained_poll-callback.patch +Patch0090: 0090-block-backend-Fix-potential-double-blk_delete.patch +Patch0091: 0091-block-backend-Decrease-in_flight-only-after-callback.patch +Patch0092: 0092-blockjob-Lie-better-in-child_job_drained_poll.patch +Patch0093: 0093-block-Remove-aio_poll-in-bdrv_drain_poll-variants.patch +Patch0094: 0094-test-bdrv-drain-Test-nested-poll-in-bdrv_drain_poll_.patch +Patch0095: 0095-job-Avoid-deadlocks-in-job_completed_txn_abort.patch +Patch0096: 0096-test-bdrv-drain-AIO_WAIT_WHILE-in-job-.commit-.abort.patch +Patch0097: 0097-test-bdrv-drain-Fix-outdated-comments.patch +Patch0098: 0098-block-Use-a-single-global-AioWait.patch +Patch0099: 0099-test-bdrv-drain-Test-draining-job-source-child-and-p.patch +Patch0100: 0100-block-rbd-pull-out-qemu_rbd_convert_options.patch +Patch0101: 0101-block-rbd-Attempt-to-parse-legacy-filenames.patch +Patch0102: 0102-block-rbd-add-deprecation-documentation-for-filename.patch +Patch0103: 0103-block-rbd-add-iotest-for-rbd-legacy-keyvalue-filenam.patch +Patch0104: 0104-luks-Allow-share-rw-on.patch BuildRequires: zlib-devel BuildRequires: glib2-devel @@ -168,7 +229,7 @@ BuildRequires: pciutils-devel BuildRequires: libiscsi-devel BuildRequires: ncurses-devel BuildRequires: libattr-devel -BuildRequires: libusbx-devel >= 1.0.19 +BuildRequires: libusbx-devel >= 1.0.22 %if %{have_usbredir} BuildRequires: usbredir-devel >= 0.7.1 %endif @@ -376,6 +437,17 @@ Install this package if you want to access remote disks over http, https, ftp and other transports provided by the CURL library. +%if %{have_gluster} +%package block-gluster +Summary: QEMU Gluster block driver +Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} +%description block-gluster +This package provides the additional Gluster block driver for QEMU. + +Install this package if you want to access remote Gluster storage. +%endif + + %package block-iscsi Summary: QEMU iSCSI block driver Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} @@ -411,9 +483,6 @@ the Secure Shell (SSH) protocol. %prep %setup -q -n qemu-%{version} -%patch0001 -p1 -%patch0002 -p1 -%patch0003 -p1 %patch0004 -p1 %patch0005 -p1 %patch0006 -p1 @@ -456,6 +525,65 @@ the Secure Shell (SSH) protocol. %patch0043 -p1 %patch0044 -p1 %patch0045 -p1 +%patch0046 -p1 +%patch0047 -p1 +%patch0048 -p1 +%patch0049 -p1 +%patch0050 -p1 +%patch0051 -p1 +%patch0052 -p1 +%patch0053 -p1 +%patch0054 -p1 +%patch0055 -p1 +%patch0056 -p1 +%patch0057 -p1 +%patch0058 -p1 +%patch0059 -p1 +%patch0060 -p1 +%patch0061 -p1 +%patch0062 -p1 +%patch0063 -p1 +%patch0064 -p1 +%patch0065 -p1 +%patch0066 -p1 +%patch0067 -p1 +%patch0068 -p1 +%patch0069 -p1 +%patch0070 -p1 +%patch0071 -p1 +%patch0072 -p1 +%patch0073 -p1 +%patch0074 -p1 +%patch0075 -p1 +%patch0076 -p1 +%patch0077 -p1 +%patch0078 -p1 +%patch0079 -p1 +%patch0080 -p1 +%patch0081 -p1 +%patch0082 -p1 +%patch0083 -p1 +%patch0084 -p1 +%patch0085 -p1 +%patch0086 -p1 +%patch0087 -p1 +%patch0088 -p1 +%patch0089 -p1 +%patch0090 -p1 +%patch0091 -p1 +%patch0092 -p1 +%patch0093 -p1 +%patch0094 -p1 +%patch0095 -p1 +%patch0096 -p1 +%patch0097 -p1 +%patch0098 -p1 +%patch0099 -p1 +%patch0100 -p1 +%patch0101 -p1 +%patch0102 -p1 +%patch0103 -p1 +%patch0104 -p1 %build %global buildarch %{kvm_target}-softmmu @@ -646,9 +774,11 @@ make V=1 %{?_smp_mflags} $buildldflags cp -a %{kvm_target}-softmmu/qemu-system-%{kvm_target} qemu-kvm gcc %{SOURCE6} $RPM_OPT_FLAGS $RPM_LD_FLAGS -o ksmctl +gcc %{SOURCE35} $RPM_OPT_FLAGS $RPM_LD_FLAGS -o udev-kvm-check %install -%define _udevdir %(pkg-config --variable=udevdir udev)/rules.d +%define _udevdir %(pkg-config --variable=udevdir udev) +%define _udevrulesdir %{_udevdir}/rules.d install -D -p -m 0644 %{SOURCE4} $RPM_BUILD_ROOT%{_unitdir}/ksm.service install -D -p -m 0644 %{SOURCE5} $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/ksm @@ -669,9 +799,12 @@ install -D -p -m 0644 %{SOURCE26} $RPM_BUILD_ROOT%{_sysconfdir}/modprobe.d/vhost %endif mkdir -p $RPM_BUILD_ROOT%{_bindir}/ -mkdir -p $RPM_BUILD_ROOT%{_udevdir} - +mkdir -p $RPM_BUILD_ROOT%{_udevrulesdir}/ mkdir -p $RPM_BUILD_ROOT%{_datadir}/%{name} + +install -p -m 0755 udev-kvm-check $RPM_BUILD_ROOT%{_udevdir} +install -p -m 0644 %{SOURCE34} $RPM_BUILD_ROOT%{_udevrulesdir} + install -m 0644 scripts/dump-guest-memory.py \ $RPM_BUILD_ROOT%{_datadir}/%{name} @@ -685,7 +818,7 @@ mkdir -p $RPM_BUILD_ROOT%{_datadir}/systemtap/tapset # Install qemu-guest-agent service and udev rules install -m 0644 %{_sourcedir}/qemu-guest-agent.service %{buildroot}%{_unitdir} install -m 0644 %{_sourcedir}/qemu-ga.sysconfig %{buildroot}%{_sysconfdir}/sysconfig/qemu-ga -install -m 0644 %{_sourcedir}/99-qemu-guest-agent.rules %{buildroot}%{_udevdir} +install -m 0644 %{_sourcedir}/99-qemu-guest-agent.rules %{buildroot}%{_udevrulesdir} # - the fsfreeze hook script: install -D --preserve-timestamps \ @@ -940,6 +1073,9 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ %config(noreplace) %{_sysconfdir}/sysconfig/ksm %{_unitdir}/ksmtuned.service %{_sbindir}/ksmtuned +%{_udevdir}/udev-kvm-check +%{_udevrulesdir}/81-kvm-rhel.rules +%ghost %{_sysconfdir}/kvm %config(noreplace) %{_sysconfdir}/ksmtuned.conf %dir %{_sysconfdir}/%{name} %config(noreplace) %{_sysconfdir}/%{name}/bridge.conf @@ -1009,7 +1145,7 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ %{_bindir}/qemu-ga %{_mandir}/man8/qemu-ga.8* %{_unitdir}/qemu-guest-agent.service -%{_udevdir}/99-qemu-guest-agent.rules +%{_udevrulesdir}/99-qemu-guest-agent.rules %config(noreplace) %{_sysconfdir}/sysconfig/qemu-ga %{_sysconfdir}/qemu-ga %{_datadir}/%{name}/qemu-ga @@ -1018,6 +1154,11 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ %files block-curl %{_libdir}/qemu-kvm/block-curl.so +%if %{have_gluster} +%files block-gluster +%{_libdir}/qemu-kvm/block-gluster.so +%endif + %files block-iscsi %{_libdir}/qemu-kvm/block-iscsi.so @@ -1029,6 +1170,156 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ %changelog +* Thu Nov 08 2018 Danilo Cesar Lemes de Paula - 3.0.0-2.el8 +- Mass import 2.12.0 fixes into 3.0 + +- kvm-luks-Allow-share-rw-on.patch [bz#1629701] +- kvm-redhat-reenable-gluster-support.patch [bz#1599340] +- kvm-redhat-bump-libusb-requirement.patch [bz#1627970] +- Resolves: bz#1599340 + (Reenable glusterfs in qemu-kvm once BZ#1567292 gets fixed) +- Resolves: bz#1627970 + (symbol lookup error: /usr/libexec/qemu-kvm: undefined symbol: libusb_set_option) +- Resolves: bz#1629701 + ("share-rw=on" does not work for luks format image - Fast Train) + +- kvm-block-rbd-pull-out-qemu_rbd_convert_options.patch [bz#1635585] +- kvm-block-rbd-Attempt-to-parse-legacy-filenames.patch [bz#1635585] +- kvm-block-rbd-add-deprecation-documentation-for-filename.patch [bz#1635585] +- kvm-block-rbd-add-iotest-for-rbd-legacy-keyvalue-filenam.patch [bz#1635585] +- Resolves: bz#1635585 + (rbd json format of 7.6 is incompatible with 7.5) + +- kvm-vnc-call-sasl_server_init-only-when-required.patch [bz#1609327] +- kvm-nbd-server-fix-NBD_CMD_CACHE.patch [bz#1636142] +- kvm-nbd-fix-NBD_FLAG_SEND_CACHE-value.patch [bz#1636142] +- kvm-test-bdrv-drain-bdrv_drain-works-with-cross-AioConte.patch [bz#1637976] +- kvm-block-Use-bdrv_do_drain_begin-end-in-bdrv_drain_all.patch [bz#1637976] +- kvm-block-Remove-recursive-parameter-from-bdrv_drain_inv.patch [bz#1637976] +- kvm-block-Don-t-manually-poll-in-bdrv_drain_all.patch [bz#1637976] +- kvm-tests-test-bdrv-drain-bdrv_drain_all-works-in-corout.patch [bz#1637976] +- kvm-block-Avoid-unnecessary-aio_poll-in-AIO_WAIT_WHILE.patch [bz#1637976] +- kvm-block-Really-pause-block-jobs-on-drain.patch [bz#1637976] +- kvm-block-Remove-bdrv_drain_recurse.patch [bz#1637976] +- kvm-test-bdrv-drain-Add-test-for-node-deletion.patch [bz#1637976] +- kvm-block-Drain-recursively-with-a-single-BDRV_POLL_WHIL.patch [bz#1637976] +- kvm-test-bdrv-drain-Test-node-deletion-in-subtree-recurs.patch [bz#1637976] +- kvm-block-Don-t-poll-in-parent-drain-callbacks.patch [bz#1637976] +- kvm-test-bdrv-drain-Graph-change-through-parent-callback.patch [bz#1637976] +- kvm-block-Defer-.bdrv_drain_begin-callback-to-polling-ph.patch [bz#1637976] +- kvm-test-bdrv-drain-Test-that-bdrv_drain_invoke-doesn-t-.patch [bz#1637976] +- kvm-block-Allow-AIO_WAIT_WHILE-with-NULL-ctx.patch [bz#1637976] +- kvm-block-Move-bdrv_drain_all_begin-out-of-coroutine-con.patch [bz#1637976] +- kvm-block-ignore_bds_parents-parameter-for-drain-functio.patch [bz#1637976] +- kvm-block-Allow-graph-changes-in-bdrv_drain_all_begin-en.patch [bz#1637976] +- kvm-test-bdrv-drain-Test-graph-changes-in-drain_all-sect.patch [bz#1637976] +- kvm-block-Poll-after-drain-on-attaching-a-node.patch [bz#1637976] +- kvm-test-bdrv-drain-Test-bdrv_append-to-drained-node.patch [bz#1637976] +- kvm-block-linux-aio-acquire-AioContext-before-qemu_laio_.patch [bz#1637976] +- kvm-util-async-use-qemu_aio_coroutine_enter-in-co_schedu.patch [bz#1637976] +- kvm-job-Fix-nested-aio_poll-hanging-in-job_txn_apply.patch [bz#1637976] +- kvm-job-Fix-missing-locking-due-to-mismerge.patch [bz#1637976] +- kvm-blockjob-Wake-up-BDS-when-job-becomes-idle.patch [bz#1637976] +- kvm-aio-wait-Increase-num_waiters-even-in-home-thread.patch [bz#1637976] +- kvm-test-bdrv-drain-Drain-with-block-jobs-in-an-I-O-thre.patch [bz#1637976] +- kvm-test-blockjob-Acquire-AioContext-around-job_cancel_s.patch [bz#1637976] +- kvm-job-Use-AIO_WAIT_WHILE-in-job_finish_sync.patch [bz#1637976] +- kvm-test-bdrv-drain-Test-AIO_WAIT_WHILE-in-completion-ca.patch [bz#1637976] +- kvm-block-Add-missing-locking-in-bdrv_co_drain_bh_cb.patch [bz#1637976] +- kvm-block-backend-Add-.drained_poll-callback.patch [bz#1637976] +- kvm-block-backend-Fix-potential-double-blk_delete.patch [bz#1637976] +- kvm-block-backend-Decrease-in_flight-only-after-callback.patch [bz#1637976] +- kvm-blockjob-Lie-better-in-child_job_drained_poll.patch [bz#1637976] +- kvm-block-Remove-aio_poll-in-bdrv_drain_poll-variants.patch [bz#1637976] +- kvm-test-bdrv-drain-Test-nested-poll-in-bdrv_drain_poll_.patch [bz#1637976] +- kvm-job-Avoid-deadlocks-in-job_completed_txn_abort.patch [bz#1637976] +- kvm-test-bdrv-drain-AIO_WAIT_WHILE-in-job-.commit-.abort.patch [bz#1637976] +- kvm-test-bdrv-drain-Fix-outdated-comments.patch [bz#1637976] +- kvm-block-Use-a-single-global-AioWait.patch [bz#1637976] +- kvm-test-bdrv-drain-Test-draining-job-source-child-and-p.patch [bz#1637976] +- kvm-qemu-img-Fix-assert-when-mapping-unaligned-raw-file.patch [bz#1639374] +- kvm-iotests-Add-test-221-to-catch-qemu-img-map-regressio.patch [bz#1639374] +- Resolves: bz#1609327 + (qemu-kvm[37046]: Could not find keytab file: /etc/qemu/krb5.tab: Unknown error 49408) +- Resolves: bz#1636142 + (qemu NBD_CMD_CACHE flaws impacting non-qemu NBD clients) +- Resolves: bz#1637976 + (Crashes and hangs with iothreads vs. block jobs) +- Resolves: bz#1639374 + (qemu-img map 'Aborted (core dumped)' when specifying a plain file) + +- kvm-linux-headers-update.patch [bz#1508142] +- kvm-s390x-cpumodel-Set-up-CPU-model-for-AP-device-suppor.patch [bz#1508142] +- kvm-s390x-kvm-enable-AP-instruction-interpretation-for-g.patch [bz#1508142] +- kvm-s390x-ap-base-Adjunct-Processor-AP-object-model.patch [bz#1508142] +- kvm-s390x-vfio-ap-Introduce-VFIO-AP-device.patch [bz#1508142] +- kvm-s390-doc-detailed-specifications-for-AP-virtualizati.patch [bz#1508142] +- Resolves: bz#1508142 + ([IBM 8.0 FEAT] KVM: Guest-dedicated Crypto Adapters - qemu part) + +- kvm-Revert-hw-acpi-build-build-SRAT-memory-affinity-stru.patch [bz#1609235] +- kvm-add-udev-kvm-check.patch [bz#1552663] +- kvm-aio-posix-Don-t-count-ctx-notifier-as-progress-when-.patch [bz#1623085] +- kvm-aio-Do-aio_notify_accept-only-during-blocking-aio_po.patch [bz#1623085] +- kvm-aio-posix-fix-concurrent-access-to-poll_disable_cnt.patch [bz#1632622] +- kvm-aio-posix-compute-timeout-before-polling.patch [bz#1632622] +- kvm-aio-posix-do-skip-system-call-if-ctx-notifier-pollin.patch [bz#1632622] +- kvm-intel-iommu-send-PSI-always-even-if-across-PDEs.patch [bz#1450712] +- kvm-intel-iommu-remove-IntelIOMMUNotifierNode.patch [bz#1450712] +- kvm-intel-iommu-add-iommu-lock.patch [bz#1450712] +- kvm-intel-iommu-only-do-page-walk-for-MAP-notifiers.patch [bz#1450712] +- kvm-intel-iommu-introduce-vtd_page_walk_info.patch [bz#1450712] +- kvm-intel-iommu-pass-in-address-space-when-page-walk.patch [bz#1450712] +- kvm-intel-iommu-trace-domain-id-during-page-walk.patch [bz#1450712] +- kvm-util-implement-simple-iova-tree.patch [bz#1450712] +- kvm-intel-iommu-rework-the-page-walk-logic.patch [bz#1450712] +- kvm-i386-define-the-ssbd-CPUID-feature-bit-CVE-2018-3639.patch [bz#1633928] +- Resolves: bz#1450712 + (Booting nested guest with vIOMMU, the assigned network devices can not receive packets (qemu)) +- Resolves: bz#1552663 + (81-kvm-rhel.rules is no longer part of initscripts) +- Resolves: bz#1609235 + (Win2016 guest can't recognize pc-dimm hotplugged to node 0) +- Resolves: bz#1623085 + (VM doesn't boot from HD) +- Resolves: bz#1632622 + (~40% virtio_blk disk performance drop for win2012r2 guest when comparing qemu-kvm-rhev-2.12.0-9 with qemu-kvm-rhev-2.12.0-12) +- Resolves: bz#1633928 + (CVE-2018-3639 qemu-kvm: hw: cpu: speculative store bypass [rhel-8.0]) + +- kvm-block-for-jobs-do-not-clear-user_paused-until-after-.patch [bz#1635583] +- kvm-iotests-Add-failure-matching-to-common.qemu.patch [bz#1635583] +- kvm-block-iotest-to-catch-abort-on-forced-blockjob-cance.patch [bz#1635583] +- Resolves: bz#1635583 + (Quitting VM causes qemu core dump once the block mirror job paused for no enough target space) + +- kvm-check-Only-test-ivshm-when-it-is-compiled-in.patch [bz#1621817] +- kvm-Disable-ivshmem.patch [bz#1621817] +- kvm-mirror-Fail-gracefully-for-source-target.patch [bz#1637963] +- kvm-commit-Add-top-node-base-node-options.patch [bz#1637970] +- kvm-qemu-iotests-Test-commit-with-top-node-base-node.patch [bz#1637970] +- Resolves: bz#1621817 + (Disable IVSHMEM in RHEL 8) +- Resolves: bz#1637963 + (Segfault on 'blockdev-mirror' with same node as source and target) +- Resolves: bz#1637970 + (allow using node-names with block-commit) + +- kvm-redhat-make-the-plugins-executable.patch [bz#1638304] +- Resolves: bz#1638304 + (the driver packages lack all the library Requires) + +- kvm-seccomp-allow-sched_setscheduler-with-SCHED_IDLE-pol.patch [bz#1618356] +- kvm-seccomp-use-SIGSYS-signal-instead-of-killing-the-thr.patch [bz#1618356] +- kvm-seccomp-prefer-SCMP_ACT_KILL_PROCESS-if-available.patch [bz#1618356] +- kvm-configure-require-libseccomp-2.2.0.patch [bz#1618356] +- kvm-seccomp-set-the-seccomp-filter-to-all-threads.patch [bz#1618356] +- kvm-memory-cleanup-side-effects-of-memory_region_init_fo.patch [bz#1600365] +- Resolves: bz#1600365 + (QEMU core dumped when hotplug memory exceeding host hugepages and with discard-data=yes) +- Resolves: bz#1618356 + (qemu-kvm: Qemu: seccomp: blacklist is not applied to all threads [rhel-8]) + * Fri Oct 12 2018 Danilo Cesar Lemes de Paula - 3.0.0-1.el8 - Rebase on qemu-kvm 3.0.0 diff --git a/udev-kvm-check.c b/udev-kvm-check.c new file mode 100644 index 0000000..cb0ecba --- /dev/null +++ b/udev-kvm-check.c @@ -0,0 +1,172 @@ +/* + * udev-kvm-check.c + * + * Copyright 2018 Red Hat, Inc. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include +#include +#include +#include +#include + +#define DEFAULT 0 +#define FACILITY "kvm" +#define SYSCONFIG_KVM "/etc/sysconfig/kvm" + +#define COUNT_MSG \ + "%d %s now active" + +#define SUBSCRIPTION_MSG \ + "%d %s now active; your Red Hat Enterprise Linux subscription" \ + " limit is %d guests. Please review your Red Hat Enterprise Linux" \ + " subscription agreement or contact your Red Hat" \ + " support representative for more information. You" \ + " may review the Red Hat Enterprise subscription" \ + " limits at http://www.redhat.com/rhel-virt-limits" + +int get_threshold_from_file(FILE *fp) +{ + static const char key[] = "THRESHOLD="; + int pos = 0; + int thres; + int ch; + +start: + /* State START - at beginning of line, search for beginning of "THRESHOLD=" + * string. + */ + ch = getc(fp); + if (ch == EOF) { + return DEFAULT; + } + if (isspace(ch)) { + goto start; + } + if (ch == 'T') { + pos = 1; + goto key; + } + goto eol; + +eol: + /* State EOL - loop until end of line */ + ch = getc(fp); + if (ch == EOF) { + return DEFAULT; + } + if (ch == '\n') { + goto start; + } + goto eol; + +key: + /* State KEY - match "THRESHOLD=" string, go to THRESHOLD if found */ + ch = getc(fp); + if (ch == EOF) { + return DEFAULT; + } + if (ch == key[pos]) { + pos++; + if (key[pos] == 0) { + goto threshold; + } else { + goto key; + } + } + goto eol; + +threshold: + /* State THRESHOLD - parse number using fscanf, expect comment or space + * or EOL. + */ + ch = getc(fp); + if (ch == EOF) { + return DEFAULT; + } + if (!isdigit(ch)) { + goto eol; + } + ungetc(ch, fp); + if (fscanf(fp, "%d", &thres) != 1) { + return DEFAULT; + } + ch = getc(fp); + if (ch == '#' || ch == EOF || ch == '\n' || isspace(ch)) { + return thres; + } + goto eol; +} + +int get_threshold() +{ + FILE *fp = fopen(SYSCONFIG_KVM, "r"); + int val; + + if (!fp) { + return DEFAULT; + } + + val = get_threshold_from_file(fp); + fclose (fp); + return val; +} + +const char *guest(int count) +{ + return (count == 1 ? "guest" : "guests"); +} + +void emit_count_message(int count) +{ + openlog(FACILITY, LOG_CONS, LOG_USER); + syslog(LOG_INFO, COUNT_MSG, count, guest(count)); + closelog(); +} + +void emit_subscription_message(int count, int threshold) +{ + openlog(FACILITY, LOG_CONS, LOG_USER); + syslog(LOG_WARNING, SUBSCRIPTION_MSG, count, guest(count), threshold); + closelog(); +} + +int main(int argc, char **argv) +{ + int count, threshold; + + if (argc < 3) + exit(1); + + count = atoi(argv[1]); + threshold = get_threshold(); + + if (!strcmp(argv[2], "create")) { + if (threshold == 0) { + emit_count_message(count); + } else if (count > threshold) { + emit_subscription_message(count, threshold); + } + } else { + if (count >= threshold) { + emit_count_message(count); + } + } + + return 0; +}