diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 8ecbe655b8..b91cf8aa1e 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -8816,9 +8816,9 @@ qemuBuildCommandLine(virConnectPtr conn, * List of controller types that we add commandline args for, * *in the order we want to add them*. * - * We don't add an explicit FD controller because the - * provided PIIX4 device already includes one. It isn't possible to - * remove the PIIX4. + * The floppy controller is implicit on PIIX4 and older Q35 + * machines. For newer Q35 machines it is added out of the + * controllers loop, after the floppy drives. * * We don't add PCI/PCIe root controller either, because it's * implicit, but we do add PCI bridges and other PCI @@ -8839,6 +8839,8 @@ qemuBuildCommandLine(virConnectPtr conn, virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); virBuffer boot_buf = VIR_BUFFER_INITIALIZER; char *boot_order_str = NULL, *boot_opts_str = NULL; + virBuffer fdc_opts = VIR_BUFFER_INITIALIZER; + char *fdc_opts_str = NULL; VIR_DEBUG("conn=%p driver=%p def=%p mon=%p json=%d " "qemuCaps=%p migrateFrom=%s migrateFD=%d " @@ -9789,8 +9791,12 @@ qemuBuildCommandLine(virConnectPtr conn, disk->info.alias) < 0) goto error; - virCommandAddArg(cmd, "-global"); - virCommandAddArgFormat(cmd, "isa-fdc.%s", optstr); + if (!qemuDomainMachineNeedsFDC(def)) { + virCommandAddArg(cmd, "-global"); + virCommandAddArgFormat(cmd, "isa-fdc.%s", optstr); + } else { + virBufferAsprintf(&fdc_opts, "%s,", optstr); + } VIR_FREE(optstr); if (bootindex) { @@ -9800,8 +9806,12 @@ qemuBuildCommandLine(virConnectPtr conn, bootindex) < 0) goto error; - virCommandAddArg(cmd, "-global"); - virCommandAddArgFormat(cmd, "isa-fdc.%s", optstr); + if (!qemuDomainMachineNeedsFDC(def)) { + virCommandAddArg(cmd, "-global"); + virCommandAddArgFormat(cmd, "isa-fdc.%s", optstr); + } else { + virBufferAsprintf(&fdc_opts, "%s,", optstr); + } VIR_FREE(optstr); } } else { @@ -9815,6 +9825,13 @@ qemuBuildCommandLine(virConnectPtr conn, } } } + /* Newer Q35 machine types require an explicit FDC controller */ + virBufferTrim(&fdc_opts, ",", -1); + if ((fdc_opts_str = virBufferContentAndReset(&fdc_opts))) { + virCommandAddArg(cmd, "-device"); + virCommandAddArgFormat(cmd, "isa-fdc,%s", fdc_opts_str); + VIR_FREE(fdc_opts_str); + } } else { for (i = 0; i < def->ndisks; i++) { char dev[NAME_MAX]; diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 78df7d1bf5..8b050a0439 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -3245,6 +3245,25 @@ qemuDomainMachineIsI440FX(const virDomainDef *def) } +bool +qemuDomainMachineNeedsFDC(const virDomainDef *def) +{ + char *p = STRSKIP(def->os.machine, "pc-q35-"); + + if (p) { + if (STRPREFIX(p, "1.") || + STRPREFIX(p, "2.0") || + STRPREFIX(p, "2.1") || + STRPREFIX(p, "2.2") || + STRPREFIX(p, "2.3")) + return false; + return true; + } + return false; +} + + + /** * qemuDomainUpdateCurrentMemorySize: * diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 54e1e7bb40..66dbcf5973 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -465,6 +465,7 @@ virDomainChrSourceDefPtr qemuFindAgentConfig(virDomainDefPtr def); bool qemuDomainMachineIsQ35(const virDomainDef *def); bool qemuDomainMachineIsI440FX(const virDomainDef *def); +bool qemuDomainMachineNeedsFDC(const virDomainDef *def); int qemuDomainUpdateCurrentMemorySize(virQEMUDriverPtr driver, virDomainObjPtr vm); diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-floppy-q35.args b/tests/qemuxml2argvdata/qemuxml2argv-boot-floppy-q35.args new file mode 100644 index 0000000000..464bfa97ab --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-floppy-q35.args @@ -0,0 +1,12 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \ +/usr/bin/qemu -S \ +-M pc-q35-2.4 \ +-m 214 -smp 1 \ +-nographic -nodefaults \ +-monitor unix:/tmp/test-monitor,server,nowait \ +-no-acpi -boot a \ +-device i82801b11-bridge,id=pci.1,bus=pcie.0,addr=0x1e \ +-device pci-bridge,chassis_nr=2,id=pci.2,bus=pci.1,addr=0x1 \ +-drive file=/tmp/firmware.img,if=none,id=drive-fdc0-0-0 \ +-device isa-fdc,driveA=drive-fdc0-0-0 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.2,addr=0x3 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-floppy-q35.xml b/tests/qemuxml2argvdata/qemuxml2argv-boot-floppy-q35.xml new file mode 100644 index 0000000000..70d3262d32 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-floppy-q35.xml @@ -0,0 +1,40 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219100 + 219100 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu + + + + +
+ + +
+ + + +
+ + +
+ + + + + +
+ + + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-bootindex-floppy-q35.args b/tests/qemuxml2argvdata/qemuxml2argv-bootindex-floppy-q35.args new file mode 100644 index 0000000000..2f0627ba58 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-bootindex-floppy-q35.args @@ -0,0 +1,11 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \ +/usr/bin/qemu -S -M pc-q35-2.4 \ +-m 214 -smp 1 \ +-nographic -nodefaults \ +-monitor unix:/tmp/test-monitor,server,nowait \ +-no-acpi \ +-device i82801b11-bridge,id=pci.1,bus=pcie.0,addr=0x1e \ +-device pci-bridge,chassis_nr=2,id=pci.2,bus=pci.1,addr=0x1 \ +-drive file=/tmp/firmware.img,if=none,id=drive-fdc0-0-0 \ +-device isa-fdc,driveA=drive-fdc0-0-0,bootindexA=1 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.2,addr=0x3 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-bootindex-floppy-q35.xml b/tests/qemuxml2argvdata/qemuxml2argv-bootindex-floppy-q35.xml new file mode 100644 index 0000000000..70d3262d32 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-bootindex-floppy-q35.xml @@ -0,0 +1,40 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219100 + 219100 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu + + + + +
+ + +
+ + + +
+ + +
+ + + + + +
+ + + diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 574777b998..bee6637276 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -607,6 +607,15 @@ mymain(void) DO_TEST("boot-cdrom", NONE); DO_TEST("boot-network", NONE); DO_TEST("boot-floppy", NONE); + DO_TEST("boot-floppy-q35", + QEMU_CAPS_DEVICE, QEMU_CAPS_DEVICE_PCI_BRIDGE, + QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE, + QEMU_CAPS_DRIVE, QEMU_CAPS_ICH9_AHCI); + DO_TEST("bootindex-floppy-q35", + QEMU_CAPS_DEVICE, QEMU_CAPS_DEVICE_PCI_BRIDGE, + QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE, + QEMU_CAPS_DRIVE, QEMU_CAPS_ICH9_AHCI, QEMU_CAPS_BOOT_MENU, + QEMU_CAPS_BOOTINDEX); DO_TEST("boot-multi", QEMU_CAPS_BOOT_MENU); DO_TEST("boot-menu-enable", QEMU_CAPS_BOOT_MENU, QEMU_CAPS_DEVICE, QEMU_CAPS_DRIVE);