Create a controller for qga when SEV is used

When a guest agent is requested, it requires a virtio-serial controller.
If the controller is not created explicitly, it will be created by
libvirt. But if AMD SEV is also requested, the controller is expected
to use the iommu driver.

In order to achive that, the controller is created explicitly with the
required driver.

Change-Id: I47c248649b9d77e8bd7c5350fc84d89342be4623
Closes-Bug: 1845986
(cherry picked from commit c2fd8294fd)
This commit is contained in:
Boris Bobrov 2019-11-05 20:06:29 +01:00 committed by Stephen Finucane
parent 0662697bbf
commit 7bdd8e97fb
5 changed files with 64 additions and 7 deletions

View File

@ -228,12 +228,19 @@ class DesignerTestCase(test.NoDBTestCase):
def test_set_driver_iommu_for_sev(self):
conf = fake_libvirt_data.fake_kvm_guest()
# obj.devices[11]
controller = config.LibvirtConfigGuestController()
controller.type = 'virtio-serial'
controller.index = 0
conf.add_device(controller)
designer.set_driver_iommu_for_sev(conf)
# All disks/interfaces/memballoon are expected to be virtio,
# thus driver_iommu should be on
self.assertEqual(10, len(conf.devices))
for i in (0, 2, 3, 6, 8, 9):
self.assertEqual(11, len(conf.devices))
for i in (0, 2, 3, 6, 8, 9, 10):
dev = conf.devices[i]
self.assertTrue(
dev.driver_iommu,

View File

@ -3060,7 +3060,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
@mock.patch.object(libvirt_driver.LibvirtDriver,
"_has_uefi_support", new=mock.Mock(return_value=True))
def _setup_sev_guest(self):
def _setup_sev_guest(self, extra_image_properties=None):
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
drvr._host._supports_amd_sev = True
@ -3082,13 +3082,16 @@ class LibvirtConnTestCase(test.NoDBTestCase,
instance_ref = objects.Instance(**self.test_instance)
instance_ref.flavor = flavor
image_meta_properties = {
'hw_firmware_type': 'uefi',
'hw_machine_type': 'q35'}
if extra_image_properties:
image_meta_properties.update(extra_image_properties)
image_meta = objects.ImageMeta.from_dict({
'id': 'd9c6aeee-8258-4bdb-bca4-39940461b182',
'name': 'fakeimage',
'disk_format': 'raw',
'properties': {'hw_firmware_type': 'uefi',
'hw_machine_type': 'q35'}
})
'properties': image_meta_properties})
disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
instance_ref,
@ -5981,6 +5984,24 @@ class LibvirtConnTestCase(test.NoDBTestCase,
self.assertEqual(cfg.devices[6].type, "unix")
self.assertEqual(cfg.devices[6].target_name, "org.qemu.guest_agent.0")
@mock.patch.object(host.Host, 'get_domain_capabilities')
@mock.patch.object(designer, 'set_driver_iommu_for_sev')
def test_get_guest_config_with_qga_through_image_meta_with_sev(
self, mock_designer, fake_domain_caps):
self._setup_fake_domain_caps(fake_domain_caps)
extra_properties = {"hw_qemu_guest_agent": "yes"}
cfg = self._setup_sev_guest(extra_properties)
self.assertIsInstance(cfg.devices[8],
vconfig.LibvirtConfigGuestController)
self.assertIsInstance(cfg.devices[9],
vconfig.LibvirtConfigGuestChannel)
self.assertEqual(cfg.devices[8].type, "virtio-serial")
self.assertTrue(cfg.devices[8].uses_virtio)
self.assertEqual(cfg.devices[9].type, "unix")
self.assertEqual(cfg.devices[9].target_name, "org.qemu.guest_agent.0")
def test_get_guest_config_with_video_driver_vram(self):
self.flags(enabled=False, group='vnc')
self.flags(virt_type='kvm', group='libvirt')

View File

@ -1933,7 +1933,9 @@ class LibvirtConfigGuestController(LibvirtConfigGuestDevice):
@property
def uses_virtio(self):
return 'virtio-scsi' == self.model
model_is_virtio = 'virtio-scsi' == self.model
type_is_virtio = 'virtio-serial' == self.type
return model_is_virtio or type_is_virtio
def format_dom(self):
controller = super(LibvirtConfigGuestController, self).format_dom()

View File

@ -5148,9 +5148,22 @@ class LibvirtDriver(driver.ComputeDriver):
rng_device.backend = rng_path
guest.add_device(rng_device)
def _add_virtio_serial_controller(self, guest, instance):
virtio_controller = vconfig.LibvirtConfigGuestController()
virtio_controller.type = 'virtio-serial'
guest.add_device(virtio_controller)
def _set_qemu_guest_agent(self, guest, flavor, instance, image_meta):
# Enable qga only if the 'hw_qemu_guest_agent' is equal to yes
if image_meta.properties.get('hw_qemu_guest_agent', False):
# a virtio-serial controller is required for qga. If it is not
# created explicitly, libvirt will do it by itself. But in case
# of AMD SEV, any virtio device should use iommu driver, and
# libvirt does not know about it. That is why the controller
# should be created manually.
if self._sev_enabled(flavor, image_meta):
self._add_virtio_serial_controller(guest, instance)
LOG.debug("Qemu guest agent is enabled through image "
"metadata", instance=instance)
self._add_qga_device(guest, instance)

View File

@ -0,0 +1,14 @@
---
fixes:
- |
`Bug 1845986`_ has been fixed by adding iommu driver when the following
metadata options are used with AMD SEV:
- ``hw_scsi_model=virtio-scsi`` and either ``hw_disk_bus=scsi`` or
``hw_cdrom_bus=scsi``
- ``hw_video_model=virtio``
Also a virtio-serial controller is created when ``hw_qemu_guest_agent=yes``
option is used, together with iommu driver for it.
.. _Bug 1845986: https://launchpad.net/bugs/1845986