From 63ee776f8cd876b7d1a618bf4ca1cba1b62c35bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1n=20Tomko?= Date: Mon, 12 Aug 2013 13:48:34 +0200 Subject: [PATCH] Build QEMU command line for pcihole64 QEMU commit 3984890 introduced the "pci-hole64-size" property, to i440FX-pcihost and q35-pcihost with a default setting of 2 GB. Translate x to: -global q35-pcihost.pci-hole64-size=x for q35 machines and -global i440FX-pcihost.pci-hole64-size=x for i440FX-based machines. Error out on other machine types or if the size was specified but the pcihost device lacks 'pci-hole64-size' property. https://bugzilla.redhat.com/show_bug.cgi?id=990418 --- src/qemu/qemu_capabilities.c | 14 +++++ src/qemu/qemu_capabilities.h | 2 + src/qemu/qemu_command.c | 58 +++++++++++++++++++ .../qemuxml2argv-pcihole64-none.args | 4 ++ .../qemuxml2argv-pcihole64-q35.args | 9 +++ .../qemuxml2argv-pcihole64.args | 5 ++ tests/qemuxml2argvtest.c | 10 ++++ 7 files changed, 102 insertions(+) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-pcihole64-none.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-pcihole64-q35.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-pcihole64.args diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index ffbede770a..7888e2dd62 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -235,6 +235,8 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST, "vnc-share-policy", /* 150 */ "device-del-event", "dmi-to-pci-bridge", + "i440fx-pci-hole64-size", + "q35-pci-hole64-size", ); struct _virQEMUCaps { @@ -1436,6 +1438,14 @@ static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsScsiGeneric[] = { { "bootindex", QEMU_CAPS_DEVICE_SCSI_GENERIC_BOOTINDEX }, }; +static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsI440FXPciHost[] = { + { "pci-hole64-size", QEMU_CAPS_I440FX_PCI_HOLE64_SIZE }, +}; + +static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsQ35PciHost[] = { + { "pci-hole64-size", QEMU_CAPS_Q35_PCI_HOLE64_SIZE }, +}; + struct virQEMUCapsObjectTypeProps { const char *type; struct virQEMUCapsStringFlags *props; @@ -1473,6 +1483,10 @@ static struct virQEMUCapsObjectTypeProps virQEMUCapsObjectProps[] = { ARRAY_CARDINALITY(virQEMUCapsObjectPropsUsbHost) }, { "scsi-generic", virQEMUCapsObjectPropsScsiGeneric, ARRAY_CARDINALITY(virQEMUCapsObjectPropsScsiGeneric) }, + { "i440FX-pcihost", virQEMUCapsObjectPropsI440FXPciHost, + ARRAY_CARDINALITY(virQEMUCapsObjectPropsI440FXPciHost) }, + { "q35-pcihost", virQEMUCapsObjectPropsQ35PciHost, + ARRAY_CARDINALITY(virQEMUCapsObjectPropsQ35PciHost) }, }; diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 074e55d869..69f3395afd 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -191,6 +191,8 @@ enum virQEMUCapsFlags { QEMU_CAPS_VNC_SHARE_POLICY = 150, /* set display sharing policy */ QEMU_CAPS_DEVICE_DEL_EVENT = 151, /* DEVICE_DELETED event */ QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE = 152, /* -device i82801b11-bridge */ + QEMU_CAPS_I440FX_PCI_HOLE64_SIZE = 153, /* i440FX-pcihost.pci-hole64-size */ + QEMU_CAPS_Q35_PCI_HOLE64_SIZE = 154, /* q35-pcihost.pci-hole64-size */ QEMU_CAPS_LAST, /* this must always be the last item */ }; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index d8e5b471d4..45a334734a 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -2399,6 +2399,17 @@ qemuDomainMachineIsQ35(virDomainDefPtr def) } +static bool +qemuDomainMachineIsI440FX(virDomainDefPtr def) +{ + return (STREQ(def->os.machine, "pc") || + STRPREFIX(def->os.machine, "pc-0.") || + STRPREFIX(def->os.machine, "pc-1.") || + STRPREFIX(def->os.machine, "pc-i440") || + STRPREFIX(def->os.machine, "rhel")); +} + + static int qemuDomainValidateDevicePCISlotsQ35(virDomainDefPtr def, virQEMUCapsPtr qemuCaps, @@ -7952,6 +7963,53 @@ qemuBuildCommandLine(virConnectPtr conn, virCommandAddArgList(cmd, "-bootloader", def->os.bootloader, NULL); } + for (i = 0; i < def->ncontrollers; i++) { + virDomainControllerDefPtr cont = def->controllers[i]; + if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI && + cont->opts.pciopts.pcihole64) { + const char *hoststr = NULL; + bool cap = false; + bool machine = false; + + switch (cont->model) { + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT: + hoststr = "i440FX-pcihost"; + cap = virQEMUCapsGet(qemuCaps, QEMU_CAPS_I440FX_PCI_HOLE64_SIZE); + machine = qemuDomainMachineIsI440FX(def); + break; + + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT: + hoststr = "q35-pcihost"; + cap = virQEMUCapsGet(qemuCaps, QEMU_CAPS_Q35_PCI_HOLE64_SIZE); + machine = qemuDomainMachineIsQ35(def); + break; + + default: + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("64-bit PCI hole setting is only for root" + " PCI controllers")); + goto error; + } + + if (!machine) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Setting the 64-bit PCI hole size is not " + "supported for machine '%s'"), def->os.machine); + goto error; + } + if (!cap) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("64-bit PCI hole size setting is not supported " + "with this QEMU binary")); + goto error; + } + + virCommandAddArg(cmd, "-global"); + virCommandAddArgFormat(cmd, "%s.pci-hole64-size=%luK", hoststr, + cont->opts.pciopts.pcihole64size); + } + } + for (i = 0; i < def->ndisks; i++) { virDomainDiskDefPtr disk = def->disks[i]; diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pcihole64-none.args b/tests/qemuxml2argvdata/qemuxml2argv-pcihole64-none.args new file mode 100644 index 0000000000..e878d2ff02 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-pcihole64-none.args @@ -0,0 +1,4 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test \ +/usr/libexec/qemu-kvm -S -M pc-1.2 -m 2048 -smp 2 -nographic -nodefaults \ +-monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c \ +-usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pcihole64-q35.args b/tests/qemuxml2argvdata/qemuxml2argv-pcihole64-q35.args new file mode 100644 index 0000000000..6d33b65630 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-pcihole64-q35.args @@ -0,0 +1,9 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test \ +/usr/libexec/qemu-kvm -S -M q35 -m 2048 -smp 2 -nographic -nodefaults \ +-monitor unix:/tmp/test-monitor,server,nowait -no-acpi \ +-boot c -global q35-pcihost.pci-hole64-size=1048576K \ +-device i82801b11-bridge,id=pci.1,bus=pcie.0,addr=0x2 \ +-device pci-bridge,chassis_nr=2,id=pci.2,bus=pci.1,addr=0x1 \ +-drive file=/dev/HostVG/QEMUGuest1,if=none,id=drive-sata0-0-0 \ +-device ide-drive,unit=0,drive=drive-sata0-0-0,id=sata0-0-0 \ +-vga qxl -global qxl.ram_size=67108864 -global qxl.vram_size=18874368 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pcihole64.args b/tests/qemuxml2argvdata/qemuxml2argv-pcihole64.args new file mode 100644 index 0000000000..3165139b74 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-pcihole64.args @@ -0,0 +1,5 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test \ +/usr/libexec/qemu-kvm -S -M pc-1.2 -m 2048 -smp 2 -nographic -nodefaults \ +-monitor unix:/tmp/test-monitor,server,nowait -no-acpi \ +-boot c -global i440FX-pcihost.pci-hole64-size=1048576K -usb \ +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index fda5a0a678..4e3508b5bb 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1047,6 +1047,16 @@ mymain(void) QEMU_CAPS_KVM, QEMU_CAPS_DEVICE, QEMU_CAPS_DRIVE, QEMU_CAPS_VIRTIO_SCSI); + DO_TEST("pcihole64", QEMU_CAPS_DEVICE, QEMU_CAPS_I440FX_PCI_HOLE64_SIZE); + DO_TEST_FAILURE("pcihole64-none", QEMU_CAPS_DEVICE); + DO_TEST("pcihole64-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_VGA, QEMU_CAPS_DEVICE_VIDEO_PRIMARY, + QEMU_CAPS_VGA_QXL, QEMU_CAPS_DEVICE_QXL, + QEMU_CAPS_Q35_PCI_HOLE64_SIZE); + virObjectUnref(driver.config); virObjectUnref(driver.caps); virObjectUnref(driver.xmlopt);