Real Q35 hardware has an ICH9 chip that includes several integrated
devices at particular addresses (see the file docs/q35-chipset.cfg in
the qemu source). libvirt already attempts to put the first two sets
of ich9 USB2 controllers it finds at 00:1D.* and 00:1A.* to match the
real hardware. This patch does the same for the ich9 "HD audio"
device.
The reason I made this patch is that currently the *only* device in a
reasonable "workstation" type virtual machine config that requires a
legacy PCI slot is the audio device, Without this patch, the standard
Q35 machine created by virt-manager will have a dmi-to-pci-bridge and
a pci-bridge just for the sound device; with the patch (and if you
change the sound device model from the default "ich6" to "ich9"), the
machine definition constructed by virt-manager has absolutely no
legacy PCI controllers - any legacy PCI devices (e.g. video and sound)
are on pcie-root as integrated devices.
As cool as it is to have virt-manager making a legacy-PCI-free config
so easily, I'm undecided whether or not this is a worthwhile patch. On
one hand, it's following an existing convention of trying to place
devices that are known to be integrated chipset devices on Q35
hardware at the same address they appear in real life (but doesn't
insist on this address, and doesn't add any new device if one isn't
already present in the config). On the other hand it creates yet
another exception to "follow the same formula for everything", while
it's probably better for us to be trying to *get away* from that.
Two alternate solutions:
1) convince virt-manager to use "ich9" as the default sound for Q35,
and explicitly place it at 00:1B.0 in the definition it sends to
libvirt.
2) convince qemu to add a PCI Express sound device (I'm not sure which
one would be most appropriate).
---
src/qemu/qemu_domain_address.c | 25 +++++
.../qemuxml2argv-q35-virt-manager-basic.args | 56 ++++++++++
.../qemuxml2argv-q35-virt-manager-basic.xml | 76 ++++++++++++++
tests/qemuxml2argvtest.c | 31 ++++++
.../qemuxml2xmlout-q35-virt-manager-basic.xml | 116 +++++++++++++++++++++
tests/qemuxml2xmltest.c | 23 ++++
6 files changed, 327 insertions(+)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-q35-virt-manager-basic.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-q35-virt-manager-basic.xml
create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virt-manager-basic.xml
diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c
index a9c4c32..6cfd710 100644
--- a/src/qemu/qemu_domain_address.c
+++ b/src/qemu/qemu_domain_address.c
@@ -1218,6 +1218,31 @@ qemuDomainValidateDevicePCISlotsQ35(virDomainDefPtr def,
goto cleanup;
}
}
+
+ memset(&tmp_addr, 0, sizeof(tmp_addr));
+ tmp_addr.slot = 0x1B;
+ if (!virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) {
+ /* Since real Q35 hardware has an ICH9 chip that has an
+ * integrated HD audio device at 0000:00:1B.0 put any
+ * unaddressed ICH9 audio device at that address if it's not
+ * already taken. If there's something already there, let the
+ * normal device addressing assign something later.
+ */
+ for (i = 0; i < def->nsounds; i++) {
+ virDomainSoundDefPtr sound = def->sounds[i];
+
+ if (sound->model != VIR_DOMAIN_SOUND_MODEL_ICH9)
+ continue;
+ if (!virDeviceInfoPCIAddressWanted(&sound->info))
+ break;
+ if (virDomainPCIAddressReserveSlot(addrs, &tmp_addr, flags) < 0)
+ goto cleanup;
+ sound->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
+ sound->info.addr.pci = tmp_addr;
+ break;
+ }
+ }
+
ret = 0;
cleanup:
VIR_FREE(addrStr);
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-virt-manager-basic.args
b/tests/qemuxml2argvdata/qemuxml2argv-q35-virt-manager-basic.args
new file mode 100644
index 0000000..163e7f1
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-virt-manager-basic.args
@@ -0,0 +1,56 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=spice \
+/usr/bin/qemu-system_x86_64 \
+-name virt-manager-basic \
+-S \
+-M pc-q35-2.7 \
+-m 4096 \
+-smp 2,sockets=2,cores=1,threads=1 \
+-uuid 1b826c23-8767-47ad-a6b5-c83a88277f71 \
+-nodefaults \
+-monitor unix:/tmp/lib/domain--1-virt-manager-basic/monitor.sock,server,nowait \
+-rtc base=utc,driftfix=slew \
+-no-kvm-pit-reinjection \
+-global ICH9-LPC.disable_s3=1 \
+-global ICH9-LPC.disable_s4=1 \
+-boot c \
+-device ioh3420,port=0x10,chassis=1,id=pci.1,bus=pcie.0,addr=0x2 \
+-device ioh3420,port=0x18,chassis=2,id=pci.2,bus=pcie.0,addr=0x3 \
+-device ioh3420,port=0x20,chassis=3,id=pci.3,bus=pcie.0,addr=0x4 \
+-device ioh3420,port=0x28,chassis=4,id=pci.4,bus=pcie.0,addr=0x5 \
+-device ioh3420,port=0x30,chassis=5,id=pci.5,bus=pcie.0,addr=0x6 \
+-device nec-usb-xhci,id=usb,bus=pci.2,addr=0x0 \
+-device virtio-serial-pci,id=virtio-serial0,bus=pci.3,addr=0x0 \
+-drive file=/var/lib/libvirt/images/basic.qcow2,format=qcow2,if=none,\
+id=drive-virtio-disk0 \
+-device virtio-blk-pci,bus=pci.4,addr=0x0,drive=drive-virtio-disk0,\
+id=virtio-disk0 \
+-netdev user,id=hostnet0 \
+-device virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:9a:e6:c6,bus=pci.1,\
+addr=0x0 \
+-serial pty \
+-chardev socket,id=charchannel0,\
+path=/tmp/channel/domain--1-virt-manager-basic/org.qemu.guest_agent.0,server,\
+nowait \
+-device virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,\
+id=channel0,name=org.qemu.guest_agent.0 \
+-chardev spicevmc,id=charchannel1,name=vdagent \
+-device virtserialport,bus=virtio-serial0.0,nr=2,chardev=charchannel1,\
+id=channel1,name=com.redhat.spice.0 \
+-device usb-tablet,id=input0,bus=usb.0,port=1 \
+-spice port=5901,tls-port=5902,addr=127.0.0.1,x509-dir=/etc/pki/libvirt-spice,\
+image-compression=off \
+-vga qxl \
+-global qxl-vga.ram_size=67108864 \
+-global qxl-vga.vram_size=67108864 \
+-device ich9-intel-hda,id=sound0,bus=pcie.0,addr=0x1b \
+-device hda-duplex,id=sound0-codec0,bus=sound0.0,cad=0 \
+-chardev spicevmc,id=charredir0,name=usbredir \
+-device usb-redir,chardev=charredir0,id=redir0,bus=usb.0,port=2 \
+-chardev spicevmc,id=charredir1,name=usbredir \
+-device usb-redir,chardev=charredir1,id=redir1,bus=usb.0,port=3 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.5,addr=0x0
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35-virt-manager-basic.xml
b/tests/qemuxml2argvdata/qemuxml2argv-q35-virt-manager-basic.xml
new file mode 100644
index 0000000..6d212a4
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-virt-manager-basic.xml
@@ -0,0 +1,76 @@
+<domain type='kvm'>
+ <name>virt-manager-basic</name>
+ <uuid>1b826c23-8767-47ad-a6b5-c83a88277f71</uuid>
+ <memory unit='KiB'>4194304</memory>
+ <currentMemory unit='KiB'>4194304</currentMemory>
+ <vcpu placement='static'>2</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc-q35-2.7'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <features>
+ <acpi/>
+ <apic/>
+ <vmport state='off'/>
+ </features>
+ <clock offset='utc'>
+ <timer name='rtc' tickpolicy='catchup'/>
+ <timer name='pit' tickpolicy='delay'/>
+ <timer name='hpet' present='no'/>
+ </clock>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>restart</on_crash>
+ <pm>
+ <suspend-to-mem enabled='no'/>
+ <suspend-to-disk enabled='no'/>
+ </pm>
+ <devices>
+ <emulator>/usr/bin/qemu-system_x86_64</emulator>
+ <disk type='file' device='disk'>
+ <driver name='qemu' type='qcow2'/>
+ <source file='/var/lib/libvirt/images/basic.qcow2'/>
+ <target dev='vda' bus='virtio'/>
+ </disk>
+ <controller type='usb' model='nec-xhci'/>
+ <controller type='sata'/>
+ <controller type='virtio-serial' index='0'/>
+ <interface type='user'>
+ <mac address='52:54:00:9a:e6:c6'/>
+ <model type='virtio'/>
+ </interface>
+ <serial type='pty'>
+ <target port='0'/>
+ </serial>
+ <console type='pty'>
+ <target type='serial' port='0'/>
+ </console>
+ <channel type='unix'>
+ <target type='virtio' name='org.qemu.guest_agent.0'/>
+ <address type='virtio-serial' controller='0' bus='0'
port='1'/>
+ </channel>
+ <channel type='spicevmc'>
+ <target type='virtio' name='com.redhat.spice.0'/>
+ <address type='virtio-serial' controller='0' bus='0'
port='2'/>
+ </channel>
+ <input type='tablet' bus='usb'>
+ <address type='usb' bus='0' port='1'/>
+ </input>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <graphics type='spice' autoport='yes'>
+ <listen type='address'/>
+ <image compression='off'/>
+ </graphics>
+ <sound model='ich9'/>
+ <video>
+ <model type='qxl' ram='65536' vram='65536'
vgamem='16384' heads='1' primary='yes'/>
+ </video>
+ <redirdev bus='usb' type='spicevmc'>
+ <address type='usb' bus='0' port='2'/>
+ </redirdev>
+ <redirdev bus='usb' type='spicevmc'>
+ <address type='usb' bus='0' port='3'/>
+ </redirdev>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index db63b21..6c3c367 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -1784,6 +1784,37 @@ mymain(void)
QEMU_CAPS_PCI_MULTIFUNCTION, QEMU_CAPS_ICH9_USB_EHCI1,
QEMU_CAPS_NEC_USB_XHCI,
QEMU_CAPS_DEVICE_VIDEO_PRIMARY);
+ DO_TEST("q35-virt-manager-basic",
+ QEMU_CAPS_KVM,
+ QEMU_CAPS_RTC,
+ QEMU_CAPS_NO_KVM_PIT,
+ QEMU_CAPS_ICH9_DISABLE_S3,
+ QEMU_CAPS_ICH9_DISABLE_S4,
+ QEMU_CAPS_VIRTIO_PCI_DISABLE_LEGACY,
+ QEMU_CAPS_DEVICE_VIRTIO_RNG,
+ QEMU_CAPS_OBJECT_RNG_RANDOM,
+ QEMU_CAPS_NETDEV,
+ QEMU_CAPS_DEVICE_VIRTIO_NET,
+ QEMU_CAPS_DEVICE_VIRTIO_GPU,
+ QEMU_CAPS_DEVICE_VIRTIO_GPU_VIRGL,
+ QEMU_CAPS_VIRTIO_KEYBOARD,
+ QEMU_CAPS_VIRTIO_MOUSE,
+ QEMU_CAPS_VIRTIO_TABLET,
+ QEMU_CAPS_VIRTIO_INPUT_HOST,
+ QEMU_CAPS_VIRTIO_SCSI,
+ QEMU_CAPS_FSDEV,
+ QEMU_CAPS_FSDEV_WRITEOUT,
+ QEMU_CAPS_DEVICE_PCI_BRIDGE,
+ QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
+ QEMU_CAPS_DEVICE_IOH3420,
+ QEMU_CAPS_ICH9_AHCI,
+ QEMU_CAPS_PCI_MULTIFUNCTION, QEMU_CAPS_ICH9_USB_EHCI1,
+ QEMU_CAPS_NEC_USB_XHCI,
+ QEMU_CAPS_DEVICE_ICH9_INTEL_HDA,
+ QEMU_CAPS_DEVICE_VIDEO_PRIMARY,
+ QEMU_CAPS_SPICE, QEMU_CAPS_CHARDEV_SPICEVMC,
+ QEMU_CAPS_VGA_QXL, QEMU_CAPS_DEVICE_QXL,
+ QEMU_CAPS_HDA_DUPLEX, QEMU_CAPS_USB_REDIR);
DO_TEST("pcie-root-port",
QEMU_CAPS_DEVICE_PCI_BRIDGE,
QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virt-manager-basic.xml
b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virt-manager-basic.xml
new file mode 100644
index 0000000..fe9ea4e
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35-virt-manager-basic.xml
@@ -0,0 +1,116 @@
+<domain type='kvm'>
+ <name>virt-manager-basic</name>
+ <uuid>1b826c23-8767-47ad-a6b5-c83a88277f71</uuid>
+ <memory unit='KiB'>4194304</memory>
+ <currentMemory unit='KiB'>4194304</currentMemory>
+ <vcpu placement='static'>2</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc-q35-2.7'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <features>
+ <acpi/>
+ <apic/>
+ <vmport state='off'/>
+ </features>
+ <clock offset='utc'>
+ <timer name='rtc' tickpolicy='catchup'/>
+ <timer name='pit' tickpolicy='delay'/>
+ <timer name='hpet' present='no'/>
+ </clock>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>restart</on_crash>
+ <pm>
+ <suspend-to-mem enabled='no'/>
+ <suspend-to-disk enabled='no'/>
+ </pm>
+ <devices>
+ <emulator>/usr/bin/qemu-system_x86_64</emulator>
+ <disk type='file' device='disk'>
+ <driver name='qemu' type='qcow2'/>
+ <source file='/var/lib/libvirt/images/basic.qcow2'/>
+ <target dev='vda' bus='virtio'/>
+ <address type='pci' domain='0x0000' bus='0x04'
slot='0x00' function='0x0'/>
+ </disk>
+ <controller type='usb' index='0' model='nec-xhci'>
+ <address type='pci' domain='0x0000' bus='0x02'
slot='0x00' function='0x0'/>
+ </controller>
+ <controller type='sata' index='0'>
+ <address type='pci' domain='0x0000' bus='0x00'
slot='0x1f' function='0x2'/>
+ </controller>
+ <controller type='virtio-serial' index='0'>
+ <address type='pci' domain='0x0000' bus='0x03'
slot='0x00' function='0x0'/>
+ </controller>
+ <controller type='pci' index='0' model='pcie-root'/>
+ <controller type='pci' index='1'
model='pcie-root-port'>
+ <model name='ioh3420'/>
+ <target chassis='1' port='0x10'/>
+ <address type='pci' domain='0x0000' bus='0x00'
slot='0x02' function='0x0'/>
+ </controller>
+ <controller type='pci' index='2'
model='pcie-root-port'>
+ <model name='ioh3420'/>
+ <target chassis='2' port='0x18'/>
+ <address type='pci' domain='0x0000' bus='0x00'
slot='0x03' function='0x0'/>
+ </controller>
+ <controller type='pci' index='3'
model='pcie-root-port'>
+ <model name='ioh3420'/>
+ <target chassis='3' port='0x20'/>
+ <address type='pci' domain='0x0000' bus='0x00'
slot='0x04' function='0x0'/>
+ </controller>
+ <controller type='pci' index='4'
model='pcie-root-port'>
+ <model name='ioh3420'/>
+ <target chassis='4' port='0x28'/>
+ <address type='pci' domain='0x0000' bus='0x00'
slot='0x05' function='0x0'/>
+ </controller>
+ <controller type='pci' index='5'
model='pcie-root-port'>
+ <model name='ioh3420'/>
+ <target chassis='5' port='0x30'/>
+ <address type='pci' domain='0x0000' bus='0x00'
slot='0x06' function='0x0'/>
+ </controller>
+ <interface type='user'>
+ <mac address='52:54:00:9a:e6:c6'/>
+ <model type='virtio'/>
+ <address type='pci' domain='0x0000' bus='0x01'
slot='0x00' function='0x0'/>
+ </interface>
+ <serial type='pty'>
+ <target port='0'/>
+ </serial>
+ <console type='pty'>
+ <target type='serial' port='0'/>
+ </console>
+ <channel type='unix'>
+ <target type='virtio' name='org.qemu.guest_agent.0'/>
+ <address type='virtio-serial' controller='0' bus='0'
port='1'/>
+ </channel>
+ <channel type='spicevmc'>
+ <target type='virtio' name='com.redhat.spice.0'/>
+ <address type='virtio-serial' controller='0' bus='0'
port='2'/>
+ </channel>
+ <input type='tablet' bus='usb'>
+ <address type='usb' bus='0' port='1'/>
+ </input>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <graphics type='spice' autoport='yes'>
+ <listen type='address'/>
+ <image compression='off'/>
+ </graphics>
+ <sound model='ich9'>
+ <address type='pci' domain='0x0000' bus='0x00'
slot='0x1b' function='0x0'/>
+ </sound>
+ <video>
+ <model type='qxl' ram='65536' vram='65536'
vgamem='16384' heads='1' primary='yes'/>
+ <address type='pci' domain='0x0000' bus='0x00'
slot='0x01' function='0x0'/>
+ </video>
+ <redirdev bus='usb' type='spicevmc'>
+ <address type='usb' bus='0' port='2'/>
+ </redirdev>
+ <redirdev bus='usb' type='spicevmc'>
+ <address type='usb' bus='0' port='3'/>
+ </redirdev>
+ <memballoon model='virtio'>
+ <address type='pci' domain='0x0000' bus='0x05'
slot='0x00' function='0x0'/>
+ </memballoon>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 6c3b6ea..331763b 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -778,6 +778,29 @@ mymain(void)
QEMU_CAPS_PCI_MULTIFUNCTION, QEMU_CAPS_ICH9_USB_EHCI1,
QEMU_CAPS_NEC_USB_XHCI,
QEMU_CAPS_DEVICE_VIDEO_PRIMARY);
+ DO_TEST("q35-virt-manager-basic",
+ QEMU_CAPS_VIRTIO_PCI_DISABLE_LEGACY,
+ QEMU_CAPS_DEVICE_VIRTIO_RNG,
+ QEMU_CAPS_OBJECT_RNG_RANDOM,
+ QEMU_CAPS_NETDEV,
+ QEMU_CAPS_DEVICE_VIRTIO_NET,
+ QEMU_CAPS_DEVICE_VIRTIO_GPU,
+ QEMU_CAPS_DEVICE_VIRTIO_GPU_VIRGL,
+ QEMU_CAPS_VIRTIO_KEYBOARD,
+ QEMU_CAPS_VIRTIO_MOUSE,
+ QEMU_CAPS_VIRTIO_TABLET,
+ QEMU_CAPS_VIRTIO_INPUT_HOST,
+ QEMU_CAPS_VIRTIO_SCSI,
+ QEMU_CAPS_FSDEV,
+ QEMU_CAPS_FSDEV_WRITEOUT,
+ QEMU_CAPS_DEVICE_PCI_BRIDGE,
+ QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
+ QEMU_CAPS_DEVICE_IOH3420,
+ QEMU_CAPS_ICH9_AHCI,
+ QEMU_CAPS_PCI_MULTIFUNCTION, QEMU_CAPS_ICH9_USB_EHCI1,
+ QEMU_CAPS_NEC_USB_XHCI,
+ QEMU_CAPS_DEVICE_ICH9_INTEL_HDA,
+ QEMU_CAPS_DEVICE_VIDEO_PRIMARY);
DO_TEST("pcie-root",
QEMU_CAPS_DEVICE_PCI_BRIDGE, QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
--
2.7.4