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 main inspiration for 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.
---
Change: continue instead of break, as suggested by Andrea.
src/qemu/qemu_domain_address.c | 26 +++++
.../qemuxml2argv-q35-virt-manager-basic.args | 55 ++++++++++
.../qemuxml2argv-q35-virt-manager-basic.xml | 76 ++++++++++++++
tests/qemuxml2argvtest.c | 34 ++++++
.../qemuxml2xmlout-q35-virt-manager-basic.xml | 116 +++++++++++++++++++++
tests/qemuxml2xmltest.c | 24 +++++
6 files changed, 331 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 e81d212..8c4a5de 100644
--- a/src/qemu/qemu_domain_address.c
+++ b/src/qemu/qemu_domain_address.c
@@ -1343,6 +1343,32 @@ 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 ||
+ !virDeviceInfoPCIAddressWanted(&sound->info)) {
+ continue;
+ }
+ 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..d3217d5
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-q35-virt-manager-basic.args
@@ -0,0 +1,55 @@
+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 \
+-device qxl-vga,id=video0,ram_size=67108864,vram_size=67108864,bus=pcie.0,\
+addr=0x1 \
+-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 b78bce0..2dd23cd 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -1837,6 +1837,40 @@ mymain(void)
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_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_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 1e4767e..eb47466 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -786,6 +786,30 @@ mymain(void)
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_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,
QEMU_CAPS_DEVICE_IOH3420, QEMU_CAPS_ICH9_AHCI,
--
2.7.4