[PATCH v2 0/4] Add usb xhci controller for hotplug on Power

v2: - Added a new test case; Power system requires an USB XHCI controller in order to allow PCI hotplug. This patch adds such controller by default when creating a new VM and inform the users if a VM currently doesn't have the controller. Jose Ricardo Ziviani (4): Add a new error code for pci hotplug Check for usb xhci controller in Power platform Define the USB xhci controller in the template for Power Systems Add a new test case for pci hotplug on Power src/kimchi/i18n.py | 1 + src/kimchi/model/vmhostdevs.py | 28 +++++++++++++++++++++- src/kimchi/vmtemplate.py | 17 +++++++++++++ tests/test_model.py | 54 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 99 insertions(+), 1 deletion(-) -- 1.9.1

Signed-off-by: Jose Ricardo Ziviani <joserz@linux.vnet.ibm.com> --- src/kimchi/i18n.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/kimchi/i18n.py b/src/kimchi/i18n.py index d2ffa34..54750d9 100644 --- a/src/kimchi/i18n.py +++ b/src/kimchi/i18n.py @@ -127,6 +127,7 @@ messages = { "For AMD CPU, add iommu=pt iommu=1."), "KCHVMHDEV0004E": _('"name" should be a device name string'), "KCHVMHDEV0005E": _('The device %(name)s is probably in use by the host. Unable to attach it to the guest.'), + "KCHVMHDEV0006E": _('VM %(vmid)s does not have an USB XHCI controller to accept PCI hotplug.'), "KCHVMIF0001E": _("Interface %(iface)s does not exist in virtual machine %(name)s"), "KCHVMIF0002E": _("Network %(network)s specified for virtual machine %(name)s does not exist"), -- 1.9.1

- Today it is not possible to hotplug a PCI in Power Systems without an USB xhci controller existing in the VM. This commit checks if there is such controller in the VM, displaying an error message if not. Signed-off-by: Jose Ricardo Ziviani <joserz@linux.vnet.ibm.com> --- src/kimchi/model/vmhostdevs.py | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/kimchi/model/vmhostdevs.py b/src/kimchi/model/vmhostdevs.py index ea75fce..186e542 100644 --- a/src/kimchi/model/vmhostdevs.py +++ b/src/kimchi/model/vmhostdevs.py @@ -171,6 +171,26 @@ class VMHostDevsModel(object): if rc != 0: kimchi_log.warning("Unable to turn on sebool virt_use_sysfs") + def _have_xhci_usb_controller(self, xmlstr): + root = objectify.fromstring(xmlstr) + + try: + controllers = root.devices.controller + + except AttributeError: + return False + + for controller in controllers: + + if 'model' not in controller.attrib: + continue + + if controller.attrib['type'] == 'usb' and \ + controller.attrib['model'] == 'nec-xhci': + return True + + return False + def _attach_pci_device(self, vmid, dev_info): self._validate_pci_passthrough_env() @@ -180,11 +200,17 @@ class VMHostDevsModel(object): driver = ('vfio' if DOM_STATE_MAP[dom.info()[0]] == "shutoff" and self.caps.kernel_vfio else 'kvm') - # on powerkvm systems it must be vfio driver. distro, _, _ = platform.linux_distribution() if distro == 'IBM_PowerKVM': + # on powerkvm systems, the driver must be vfio. driver = 'vfio' + # powerkvm requires a xhci usb controller in order to support + # pci hotplug. + if DOM_STATE_MAP[dom.info()[0]] != "shutoff" and \ + not self._have_xhci_usb_controller(dom.XMLDesc(0)): + raise InvalidOperation("KCHVMHDEV0006E", {'vmid': vmid}) + # Attach all PCI devices in the same IOMMU group dev_model = DeviceModel(conn=self.conn) devs_model = DevicesModel(conn=self.conn) -- 1.9.1

- When creating VMs using Kimchi in a Power System, the USB xhci controller is defined by default to have PCI hotplug support. Signed-off-by: Jose Ricardo Ziviani <joserz@linux.vnet.ibm.com> --- src/kimchi/vmtemplate.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/kimchi/vmtemplate.py b/src/kimchi/vmtemplate.py index 79e04ed..3e42971 100644 --- a/src/kimchi/vmtemplate.py +++ b/src/kimchi/vmtemplate.py @@ -22,6 +22,7 @@ import stat import time import urlparse import uuid +import platform from lxml import etree from lxml.builder import E @@ -287,6 +288,19 @@ class VMTemplate(object): self.info.get('memory') << 10, cpu_topo) + def _get_usb_controller(self): + # powerkvm systems must include xhci controller model + distro, _, _ = platform.linux_distribution() + if distro != "IBM_PowerKVM": + return '' + + return """ + <controller type='usb' index='0' model='nec-xhci'> + <address type='pci' domain='0x0000' + bus='0x00' slot='0x0f' function='0x0'/> + </controller> + """ + def to_vm_xml(self, vm_name, vm_uuid, **kwargs): params = dict(self.info) params['name'] = vm_name @@ -323,6 +337,8 @@ class VMTemplate(object): elif params['slots'] == 0: params['slots'] = 1 + params['usb_controller'] = self._get_usb_controller() + xml = """ <domain type='%(domain)s'> %(qemu-stream-cmdline)s @@ -352,6 +368,7 @@ class VMTemplate(object): %(networks)s %(graphics)s %(input_output)s + %(usb_controller)s <memballoon model='virtio' /> </devices> </domain> -- 1.9.1

On 10/07/2015 15:32, Jose Ricardo Ziviani wrote:
- When creating VMs using Kimchi in a Power System, the USB xhci controller is defined by default to have PCI hotplug support.
Signed-off-by: Jose Ricardo Ziviani <joserz@linux.vnet.ibm.com> --- src/kimchi/vmtemplate.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
diff --git a/src/kimchi/vmtemplate.py b/src/kimchi/vmtemplate.py index 79e04ed..3e42971 100644 --- a/src/kimchi/vmtemplate.py +++ b/src/kimchi/vmtemplate.py @@ -22,6 +22,7 @@ import stat import time import urlparse import uuid +import platform
from lxml import etree from lxml.builder import E @@ -287,6 +288,19 @@ class VMTemplate(object): self.info.get('memory') << 10, cpu_topo)
+ def _get_usb_controller(self): + # powerkvm systems must include xhci controller model + distro, _, _ = platform.linux_distribution() + if distro != "IBM_PowerKVM": + return '' + + return """ + <controller type='usb' index='0' model='nec-xhci'> + <address type='pci' domain='0x0000' + bus='0x00' slot='0x0f' function='0x0'/> + </controller> + """ +
We are in a process to remove all the XML strings from Kimchi code and build them using lxml.builder So, please, do it for the controller XML. We have a module named xmlutils which handle all the XML manipulation.
def to_vm_xml(self, vm_name, vm_uuid, **kwargs): params = dict(self.info) params['name'] = vm_name @@ -323,6 +337,8 @@ class VMTemplate(object): elif params['slots'] == 0: params['slots'] = 1
+ params['usb_controller'] = self._get_usb_controller() + xml = """ <domain type='%(domain)s'> %(qemu-stream-cmdline)s @@ -352,6 +368,7 @@ class VMTemplate(object): %(networks)s %(graphics)s %(input_output)s + %(usb_controller)s <memballoon model='virtio' /> </devices> </domain>

- From now on all templates are created with xhci usb controller, so a hotplug must be performed flawlessly. If anything wrong the test case will fail. Signed-off-by: Jose Ricardo Ziviani <joserz@linux.vnet.ibm.com> --- tests/test_model.py | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/tests/test_model.py b/tests/test_model.py index 3828342..e1ad848 100644 --- a/tests/test_model.py +++ b/tests/test_model.py @@ -1205,6 +1205,60 @@ class ModelTests(unittest.TestCase): # remove files creates inst.repository_delete(repo_id) + def _host_is_PKVM(): + import platform + distro, _, _ = platform.linux_distribution() + return distro == 'IBM_PowerKVM' + + @unittest.skipUnless(_host_is_PKVM(), 'Only required for PowerKVM host') + def test_pci_hotplug_requires_xhci_usb_controller(self): + config.set("authentication", "method", "pam") + inst = model.Model(None, objstore_loc=self.tmp_store) + tpl_params = {'name': 'test', 'memory': 1024, 'cdrom': UBUNTU_ISO} + inst.templates_create(tpl_params) + + with RollbackContext() as rollback: + vm_params = {'name': 'kimchi-vm1', 'template': '/templates/test'} + task1 = inst.vms_create(vm_params) + inst.task_wait(task1['id']) + rollback.prependDefer(utils.rollback_wrapper, inst.vm_delete, + 'kimchi-vm1') + # Start vm + inst.vm_start('kimchi-vm1') + rollback.prependDefer(utils.rollback_wrapper, inst.vm_poweroff, + 'kimchi-vm1') + + # get a list with all pci devices supporting live attachment + pci_devices = inst.devices_get_list(_passthrough='true') + self.assertGreater(len(pci_devices), 0) + + # search for an usb device to live attaching to avoid causing + # any problem to host during the tests + for pci_device in pci_devices: + + device = inst.device_lookup(pci_device) + + if 'product' not in device and 'description' not in \ + device['product']: + continue + + description = device['product']['description'] + + if not isinstance(description, str): + continue + + if 'usb' not in description.lower(): + continue + + # attach the first device found + inst.vmhostdevs_create('kimchi-vm1', {'name': pci_device}) + rollback.prependDefer(utils.rollback_wrapper, + inst.vmhostdev_delete, + 'kimchi-vm1', + pci_device) + + break + class BaseModelTests(unittest.TestCase): class FoosModel(object): -- 1.9.1
participants (2)
-
Aline Manera
-
Jose Ricardo Ziviani