Switch to uses_virtio to enable iommu driver for AMD SEV

In order to use AMD SEV, devices that use virtio should also use
iommu driver. The problem is to understand that a device uses virtio,
because there are many attributes and values that can indicate it.
For example, it can be `model='virtio'` for rng and
`<target bus='virtio'/>` for disk.

Add new property for devices `uses_virtio`, that will indicate that a
device in its current configuration is a virtio device, and implement it
for known devices.

The patch does not change how resulting libvirt XMLs look and does not
fix user-visible bugs. This refactoring is required for further work on
AMD SEV related patches.

The changes to memballoon-related tests were required because the tests
were using fake values that does are not possible in real life and that
were preventing tests of the new method. The tests now use the value
that nova currently uses to generate libvirt xml.

Change-Id: I0f85918996128d573b5dbd6ac49a9c2356cd40a9
Partial-Bug: #1845986
(cherry picked from commit 2b0024c040)
This commit is contained in:
Boris Bobrov 2019-09-25 20:07:50 +02:00 committed by Stephen Finucane
parent 3c62efc5f0
commit f38e151b0d
3 changed files with 36 additions and 16 deletions

View File

@ -1836,6 +1836,7 @@ class LibvirtConfigGuestInterfaceTest(LibvirtConfigBaseTest):
obj.mac_addr = "DE:AD:BE:EF:CA:FE"
obj.model = "virtio"
obj.target_dev = "vnet0"
self.assertTrue(obj.uses_virtio)
return obj
def test_config_driver_options(self):
@ -2855,6 +2856,8 @@ class LibvirtConfigGuestSnapshotTest(LibvirtConfigBaseTest):
obj.target_bus = "virtio"
obj.serial = "7a97c4a3-6f59-41d4-bf47-191d7f97f8e9"
self.assertTrue(obj.uses_virtio)
xml = obj.to_xml()
self.assertXmlEqual("""
<disk type="file" device="disk">
@ -3261,6 +3264,8 @@ class LibvirtConfigGuestVideoTest(LibvirtConfigBaseTest):
obj = config.LibvirtConfigGuestVideo()
obj.type = 'qxl'
self.assertFalse(obj.uses_virtio)
xml = obj.to_xml()
self.assertXmlEqual(xml, """
<video>
@ -3329,6 +3334,8 @@ class LibvirtConfigGuestRngTest(LibvirtConfigBaseTest):
obj = config.LibvirtConfigGuestRng()
obj.driver_iommu = True
self.assertTrue(obj.uses_virtio)
xml = obj.to_xml()
self.assertXmlEqual(xml, """
<rng model='virtio'>
@ -3663,12 +3670,12 @@ class LibvirtConfigMemoryBalloonTest(LibvirtConfigBaseTest):
def test_config_memory_balloon_period(self):
balloon = config.LibvirtConfigMemoryBalloon()
balloon.model = 'fake_virtio'
balloon.model = 'virtio'
balloon.period = 11
xml = balloon.to_xml()
expected_xml = """
<memballoon model='fake_virtio'>
<memballoon model='virtio'>
<stats period='11'/>
</memballoon>"""
@ -3676,22 +3683,24 @@ class LibvirtConfigMemoryBalloonTest(LibvirtConfigBaseTest):
def test_config_memory_balloon_no_period(self):
balloon = config.LibvirtConfigMemoryBalloon()
balloon.model = 'fake_virtio'
balloon.model = 'virtio'
xml = balloon.to_xml()
expected_xml = """
<memballoon model='fake_virtio' />"""
<memballoon model='virtio' />"""
self.assertXmlEqual(expected_xml, xml)
def test_config_memory_balloon_driver_iommu(self):
balloon = config.LibvirtConfigMemoryBalloon()
balloon.model = 'fake_virtio'
balloon.model = 'virtio'
balloon.driver_iommu = True
self.assertTrue(balloon.uses_virtio)
xml = balloon.to_xml()
expected_xml = """
<memballoon model='fake_virtio'>
<memballoon model='virtio'>
<driver iommu="on" />
</memballoon>"""

View File

@ -875,6 +875,10 @@ class LibvirtConfigGuestDevice(LibvirtConfigObject):
def __init__(self, **kwargs):
super(LibvirtConfigGuestDevice, self).__init__(**kwargs)
@property
def uses_virtio(self):
return False
class LibvirtConfigGuestDisk(LibvirtConfigGuestDevice):
@ -984,6 +988,10 @@ class LibvirtConfigGuestDisk(LibvirtConfigGuestDevice):
if len(iotune) > 0:
dev.append(iotune)
@property
def uses_virtio(self):
return 'virtio' == self.target_bus
def format_dom(self):
dev = super(LibvirtConfigGuestDisk, self).format_dom()
@ -1573,6 +1581,10 @@ class LibvirtConfigGuestInterface(LibvirtConfigGuestDevice):
self.device_addr = None
self.mtu = None
@property
def uses_virtio(self):
return 'virtio' == self.model
def format_dom(self):
dev = super(LibvirtConfigGuestInterface, self).format_dom()
@ -1890,6 +1902,10 @@ class LibvirtConfigMemoryBalloon(LibvirtConfigGuestDevice):
self.period = None
self.driver_iommu = False
@property
def uses_virtio(self):
return 'virtio' == self.model
def format_dom(self):
dev = super(LibvirtConfigMemoryBalloon, self).format_dom()
dev.set('model', str(self.model))
@ -3009,6 +3025,10 @@ class LibvirtConfigGuestRng(LibvirtConfigGuestDevice):
self.rate_bytes = None
self.driver_iommu = False
@property
def uses_virtio(self):
return 'virtio' == self.device_model
def format_dom(self):
dev = super(LibvirtConfigGuestRng, self).format_dom()
dev.set('model', self.device_model)

View File

@ -21,7 +21,6 @@ classes based on common operational needs / policies
from nova.pci import utils as pci_utils
from nova.virt.libvirt import config
MIN_LIBVIRT_ETHERNET_SCRIPT_PATH_NONE = (1, 3, 3)
@ -200,14 +199,6 @@ def set_vcpu_realtime_scheduler(conf, vcpus_rt, priority):
def set_driver_iommu_for_sev(conf):
virtio_attrs = {
config.LibvirtConfigGuestDisk: 'target_bus',
config.LibvirtConfigGuestInterface: 'model',
config.LibvirtConfigGuestRng: 'device_model',
config.LibvirtConfigMemoryBalloon: 'model',
}
for dev in conf.devices:
virtio_attr = virtio_attrs.get(dev.__class__)
if virtio_attr and getattr(dev, virtio_attr) == 'virtio':
if dev.uses_virtio:
dev.driver_iommu = True