(2.10) Fix conflict between virtio + spice or soundhw
authorDimitris Aragiorgis <dimara@grnet.gr>
Mon, 17 Mar 2014 12:00:19 +0000 (14:00 +0200)
committerDimitris Aragiorgis <dimara@grnet.gr>
Thu, 27 Mar 2014 08:01:22 +0000 (10:01 +0200)
With regard to PCI slot occupied by a KVM instance we have
observed the following:

1) Slot 0 will always be Host bridge.
2) Slot 1 will always be ISA bridge.
3) Slot 2 will always be VGA controller (even with -display none).
4) If soundhw=hda|ac97|es1370 an extra PCI slot is occupied.
   This slot *MUST* be the No. 3.

5) Option '-balloon virtio' gets an extra PCI slot.
   Still it can take id, bus, and addr args and be placed anywhere

6) If spice is used instead of vnc we have:
   * No extra PCI slot gets occupied without vdagent
   * Otherwise we have the following extra optionsa [1]
     a) -device virtio-serial-pci
        (this can take id, bus, and addr args too)
     b) -device virtserialport,chardev=spicechannel0,...
     c) -chardev spicevmc,id=spicechannel0

This patch does the following:

1) Change _DEFAULT_PCI_RESERVATIONS to "1110...."
2) Move soundhw option early in the command line and if hda etc.
   reserve slot 3.
3) Add id, bus, and addr in balloon option and reserve next slot.
4) Add id, bus, and addr in -device virtio-serial-pci option and if
   passed reserve next slot.

[1] http://www.linux-kvm.org/page/SPICE

Fixes issue 757.

Signed-off-by: Dimitris Aragiorgis <dimara@grnet.gr>
Reviewed-by: Jose A. Lopes <jabolopes@google.com>

lib/hypervisor/hv_kvm.py

index 1b15e17..a38943a 100644 (file)
@@ -778,7 +778,9 @@ class KVMHypervisor(hv_base.BaseHypervisor):
     re.compile(r'^QEMU (\d+)\.(\d+)(\.(\d+))?.*monitor.*', re.M)
   _INFO_VERSION_CMD = "info version"
 
-  _DEFAULT_PCI_RESERVATIONS = "11110000000000000000000000000000"
+  # Slot 0 for Host bridge, Slot 1 for ISA bridge, Slot 2 for VGA controller
+  _DEFAULT_PCI_RESERVATIONS = "11100000000000000000000000000000"
+  _SOUNDHW_WITH_PCI_SLOT = ["ac97", "es1370", "hda"]
 
   ANCILLARY_FILES = [
     _KVM_NETWORK_SCRIPT,
@@ -1444,7 +1446,23 @@ class KVMHypervisor(hv_base.BaseHypervisor):
     kvm_cmd.extend(["-smp", ",".join(smp_list)])
 
     kvm_cmd.extend(["-pidfile", pidfile])
-    kvm_cmd.extend(["-balloon", "virtio"])
+
+    pci_reservations = bitarray(self._DEFAULT_PCI_RESERVATIONS)
+
+    # As requested by music lovers
+    if hvp[constants.HV_SOUNDHW]:
+      soundhw = hvp[constants.HV_SOUNDHW]
+      # For some reason only few sound devices require a PCI slot
+      # while the Audio controller *must* be in slot 3.
+      # That's why we bridge this option early in command line
+      if soundhw in self._SOUNDHW_WITH_PCI_SLOT:
+        _ = _GetFreeSlot(pci_reservations, reserve=True)
+      kvm_cmd.extend(["-soundhw", soundhw])
+
+    # Add id to ballon and place to the first available slot (3 or 4)
+    addr = _GetFreeSlot(pci_reservations, reserve=True)
+    pci_info = ",bus=pci.0,addr=%s" % hex(addr)
+    kvm_cmd.extend(["-balloon", "virtio,id=balloon%s" % pci_info])
     kvm_cmd.extend(["-daemonize"])
     if not instance.hvparams[constants.HV_ACPI]:
       kvm_cmd.extend(["-no-acpi"])
@@ -1697,7 +1715,9 @@ class KVMHypervisor(hv_base.BaseHypervisor):
       else:
         # Enable the spice agent communication channel between the host and the
         # agent.
-        kvm_cmd.extend(["-device", "virtio-serial-pci"])
+        addr = _GetFreeSlot(pci_reservations, reserve=True)
+        pci_info = ",bus=pci.0,addr=%s" % hex(addr)
+        kvm_cmd.extend(["-device", "virtio-serial-pci,id=spice%s" % pci_info])
         kvm_cmd.extend([
           "-device",
           "virtserialport,chardev=spicechannel0,name=com.redhat.spice.0",
@@ -1725,10 +1745,6 @@ class KVMHypervisor(hv_base.BaseHypervisor):
     if hvp[constants.HV_CPU_TYPE]:
       kvm_cmd.extend(["-cpu", hvp[constants.HV_CPU_TYPE]])
 
-    # As requested by music lovers
-    if hvp[constants.HV_SOUNDHW]:
-      kvm_cmd.extend(["-soundhw", hvp[constants.HV_SOUNDHW]])
-
     # Pass a -vga option if requested, or if spice is used, for backwards
     # compatibility.
     if hvp[constants.HV_VGA]:
@@ -1744,7 +1760,6 @@ class KVMHypervisor(hv_base.BaseHypervisor):
     if hvp[constants.HV_KVM_EXTRA]:
       kvm_cmd.extend(hvp[constants.HV_KVM_EXTRA].split(" "))
 
-    pci_reservations = bitarray(self._DEFAULT_PCI_RESERVATIONS)
     kvm_disks = []
     for disk, link_name in block_devices:
       disk.pci = _GetFreeSlot(pci_reservations, disk.pci, True)