[libvirt] [PATCH v3 4/4] Build QEMU command line for pcihole64

Ján Tomko jtomko at redhat.com
Thu Aug 15 11:30:21 UTC 2013


QEMU commit 3984890 introduced the "pci-hole64-size" property,
to i440FX-pcihost and q35-pcihost with a default setting of 2 GB.

Translate <pcihole64>x<pcihole64/> 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 ++++
 tests/qemuxml2argvdata/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 47cc07a..87c9a96 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 074e55d..69f3395 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 8b628d6..5ad73fd 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,
@@ -7919,6 +7930,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 0000000..e878d2f
--- /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 0000000..6d33b65
--- /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 0000000..3165139
--- /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 679124e..f274ced 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -1037,6 +1037,16 @@ mymain(void)
     DO_TEST_PARSE_ERROR("pci-root-address",
                         QEMU_CAPS_DEVICE, QEMU_CAPS_DEVICE_PCI_BRIDGE);
 
+    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);
-- 
1.8.1.5




More information about the libvir-list mailing list