Skip to content

Commit 90455cd

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "libvirt: Set driver_iommu when attaching virtio devices to SEV instance" into stable/wallaby
2 parents 97c3517 + 5d65680 commit 90455cd

File tree

6 files changed

+215
-74
lines changed

6 files changed

+215
-74
lines changed

nova/tests/unit/virt/libvirt/test_designer.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ def test_set_vif_mtu_config(self):
244244
designer.set_vif_mtu_config(conf, 9000)
245245
self.assertEqual(9000, conf.mtu)
246246

247-
def test_set_driver_iommu_for_sev(self):
247+
def test_set_driver_iommu(self):
248248
conf = fake_libvirt_data.fake_kvm_guest()
249249

250250
# obj.devices[11]
@@ -253,7 +253,7 @@ def test_set_driver_iommu_for_sev(self):
253253
controller.index = 0
254254
conf.add_device(controller)
255255

256-
designer.set_driver_iommu_for_sev(conf)
256+
designer.set_driver_iommu_for_all_devices(conf)
257257

258258
# All disks/interfaces/memballoon are expected to be virtio,
259259
# thus driver_iommu should be on

nova/tests/unit/virt/libvirt/test_driver.py

Lines changed: 145 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -3299,7 +3299,7 @@ def test_get_guest_config_sev_no_feature(self):
32993299
self._setup_sev_guest)
33003300

33013301
@mock.patch.object(host.Host, 'get_domain_capabilities')
3302-
@mock.patch.object(designer, 'set_driver_iommu_for_sev')
3302+
@mock.patch.object(designer, 'set_driver_iommu_for_all_devices')
33033303
def test_get_guest_config_sev(self, mock_designer, fake_domain_caps):
33043304
self._setup_fake_domain_caps(fake_domain_caps)
33053305
cfg = self._setup_sev_guest()
@@ -6459,7 +6459,7 @@ def test_get_guest_config_with_qga_through_image_meta(self):
64596459
self.assertEqual(cfg.devices[6].target_name, "org.qemu.guest_agent.0")
64606460

64616461
@mock.patch.object(host.Host, 'get_domain_capabilities')
6462-
@mock.patch.object(designer, 'set_driver_iommu_for_sev')
6462+
@mock.patch.object(designer, 'set_driver_iommu_for_all_devices')
64636463
def test_get_guest_config_with_qga_through_image_meta_with_sev(
64646464
self, mock_designer, fake_domain_caps,
64656465
):
@@ -8817,22 +8817,60 @@ def _fake_libvirt_config_guest_disk(self):
88178817

88188818
return fake_config
88198819

8820+
@mock.patch.object(libvirt_driver.LibvirtDriver, '_sev_enabled',
8821+
new=mock.Mock(return_value=False))
88208822
@mock.patch.object(volume_drivers.LibvirtFakeVolumeDriver, 'get_config')
88218823
@mock.patch.object(libvirt_driver.LibvirtDriver, '_set_cache_mode')
8822-
def test_get_volume_config(self, _set_cache_mode, get_config):
8824+
def test_get_volume_config(self, mock_set_cache_mode, mock_get_config):
88238825
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
8824-
connection_info = {'driver_volume_type': 'fake',
8825-
'data': {'device_path': '/fake',
8826-
'access_mode': 'rw'}}
8827-
disk_info = {'bus': 'fake-bus', 'type': 'fake-type',
8828-
'dev': 'vdb'}
8829-
config_guest_disk = self._fake_libvirt_config_guest_disk()
8826+
instance = objects.Instance(**self.test_instance)
8827+
connection_info = {
8828+
'driver_volume_type': 'fake',
8829+
'data': {
8830+
'device_path': '/fake',
8831+
'access_mode': 'rw'
8832+
}
8833+
}
8834+
generated_config = self._fake_libvirt_config_guest_disk()
8835+
mock_get_config.return_value = copy.deepcopy(generated_config)
8836+
8837+
returned_config = drvr._get_volume_config(
8838+
instance,
8839+
connection_info,
8840+
mock.sentinel.disk_info)
8841+
8842+
mock_get_config.assert_called_once_with(
8843+
connection_info,
8844+
mock.sentinel.disk_info)
8845+
mock_set_cache_mode.assert_called_once_with(returned_config)
8846+
self.assertEqual(generated_config.to_xml(), returned_config.to_xml())
8847+
8848+
@mock.patch.object(libvirt_driver.LibvirtDriver, '_sev_enabled',
8849+
new=mock.Mock(return_value=True))
8850+
@mock.patch.object(libvirt_driver.LibvirtDriver, '_set_cache_mode',
8851+
new=mock.Mock())
8852+
@mock.patch.object(volume_drivers.LibvirtFakeVolumeDriver, 'get_config')
8853+
def test_get_volume_config_sev(self, mock_get_config):
8854+
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
8855+
instance = objects.Instance(**self.test_instance)
8856+
connection_info = {
8857+
'driver_volume_type': 'fake',
8858+
'data': {
8859+
'device_path': '/fake',
8860+
'access_mode': 'rw'
8861+
}
8862+
}
8863+
generated_config = self._fake_libvirt_config_guest_disk()
8864+
generated_config.target_bus = 'virtio'
8865+
mock_get_config.return_value = copy.deepcopy(generated_config)
8866+
8867+
returned_config = drvr._get_volume_config(
8868+
instance,
8869+
connection_info,
8870+
mock.sentinel.disk_info)
88308871

8831-
get_config.return_value = copy.deepcopy(config_guest_disk)
8832-
config = drvr._get_volume_config(connection_info, disk_info)
8833-
get_config.assert_called_once_with(connection_info, disk_info)
8834-
_set_cache_mode.assert_called_once_with(config)
8835-
self.assertEqual(config_guest_disk.to_xml(), config.to_xml())
8872+
# Assert that driver_iommu is enabled for this virtio volume
8873+
self.assertTrue(returned_config.driver_iommu)
88368874

88378875
@mock.patch.object(libvirt_driver.LibvirtDriver, '_get_volume_driver')
88388876
@mock.patch.object(libvirt_driver.LibvirtDriver, '_attach_encryptor')
@@ -9292,7 +9330,7 @@ def test_attach_volume_with_vir_domain_affect_live_flag(self,
92929330
mock_connect_volume.assert_called_with(
92939331
self.context, connection_info, instance, encryption=None)
92949332
mock_get_volume_config.assert_called_with(
9295-
connection_info, disk_info)
9333+
instance, connection_info, disk_info)
92969334
mock_dom.attachDeviceFlags.assert_called_with(
92979335
mock_conf.to_xml(), flags=flags)
92989336
mock_check_discard.assert_called_with(mock_conf, instance)
@@ -11492,8 +11530,13 @@ def test_live_migration_update_volume_xml(self, mock_xml,
1149211530
drvr._live_migration_uri(target_connection),
1149311531
params=params, flags=0)
1149411532
mock_updated_guest_xml.assert_called_once_with(
11495-
guest, migrate_data, mock.ANY, get_vif_config=None,
11496-
new_resources=None)
11533+
instance_ref,
11534+
guest,
11535+
migrate_data,
11536+
mock.ANY,
11537+
get_vif_config=None,
11538+
new_resources=None
11539+
)
1149711540

1149811541
def test_live_migration_update_vifs_xml(self):
1149911542
"""Tests that when migrate_data.vifs is populated, the destination
@@ -11519,9 +11562,14 @@ def test_live_migration_update_vifs_xml(self):
1151911562
guest = libvirt_guest.Guest(mock.MagicMock())
1152011563
fake_xml = '<domain type="qemu"/>'
1152111564

11522-
def fake_get_updated_guest_xml(guest, migrate_data, get_volume_config,
11523-
get_vif_config=None,
11524-
new_resources=None):
11565+
def fake_get_updated_guest_xml(
11566+
instance,
11567+
guest,
11568+
migrate_data,
11569+
get_volume_config,
11570+
get_vif_config=None,
11571+
new_resources=None
11572+
):
1152511573
self.assertIsNotNone(get_vif_config)
1152611574
return fake_xml
1152711575

@@ -11688,18 +11736,30 @@ def test_update_volume_xml(self):
1168811736
conf.source_type = "block"
1168911737
conf.source_path = bdmi.connection_info['data'].get('device_path')
1169011738

11739+
instance = objects.Instance(**self.test_instance)
1169111740
guest = libvirt_guest.Guest(mock.MagicMock())
11741+
1169211742
with test.nested(
11693-
mock.patch.object(drvr, '_get_volume_config',
11694-
return_value=conf),
11695-
mock.patch.object(guest, 'get_xml_desc',
11696-
return_value=initial_xml)):
11697-
config = libvirt_migrate.get_updated_guest_xml(guest,
11698-
objects.LibvirtLiveMigrateData(
11699-
bdms=[bdmi],
11700-
serial_listen_addr='127.0.0.1',
11701-
serial_listen_ports=[1234]),
11702-
drvr._get_volume_config)
11743+
mock.patch.object(
11744+
drvr, '_get_volume_config', return_value=conf
11745+
),
11746+
mock.patch.object(
11747+
guest, 'get_xml_desc', return_value=initial_xml
11748+
),
11749+
mock.patch.object(
11750+
drvr, '_sev_enabled', new=mock.Mock(return_value=False)
11751+
)
11752+
):
11753+
config = libvirt_migrate.get_updated_guest_xml(
11754+
instance,
11755+
guest,
11756+
objects.LibvirtLiveMigrateData(
11757+
bdms=[bdmi],
11758+
serial_listen_addr='127.0.0.1',
11759+
serial_listen_ports=[1234]
11760+
),
11761+
drvr._get_volume_config
11762+
)
1170311763
parser = etree.XMLParser(remove_blank_text=True)
1170411764
config = etree.fromstring(config, parser)
1170511765
target_xml = etree.fromstring(target_xml, parser)
@@ -11884,18 +11944,30 @@ def test_update_volume_xml_no_serial(self):
1188411944
conf.source_type = "block"
1188511945
conf.source_path = bdmi.connection_info['data'].get('device_path')
1188611946

11947+
instance = objects.Instance(**self.test_instance)
1188711948
guest = libvirt_guest.Guest(mock.MagicMock())
11949+
1188811950
with test.nested(
11889-
mock.patch.object(drvr, '_get_volume_config',
11890-
return_value=conf),
11891-
mock.patch.object(guest, 'get_xml_desc',
11892-
return_value=initial_xml)):
11893-
config = libvirt_migrate.get_updated_guest_xml(guest,
11951+
mock.patch.object(
11952+
drvr, '_get_volume_config', return_value=conf
11953+
),
11954+
mock.patch.object(
11955+
guest, 'get_xml_desc', return_value=initial_xml
11956+
),
11957+
mock.patch.object(
11958+
drvr, '_sev_enabled', new=mock.Mock(return_value=False)
11959+
)
11960+
):
11961+
config = libvirt_migrate.get_updated_guest_xml(
11962+
instance,
11963+
guest,
1189411964
objects.LibvirtLiveMigrateData(
1189511965
bdms=[bdmi],
1189611966
serial_listen_addr = '127.0.0.1',
11897-
serial_listen_ports = [1234]),
11898-
drvr._get_volume_config)
11967+
serial_listen_ports = [1234]
11968+
),
11969+
drvr._get_volume_config
11970+
)
1189911971
self.assertEqual(target_xml, config)
1190011972

1190111973
def test_update_volume_xml_no_connection_info(self):
@@ -11918,19 +11990,30 @@ def test_update_volume_xml_no_connection_info(self):
1191811990
format='qcow')
1191911991
bdmi.connection_info = {}
1192011992
conf = vconfig.LibvirtConfigGuestDisk()
11993+
instance = objects.Instance(**self.test_instance)
1192111994
guest = libvirt_guest.Guest(mock.MagicMock())
11995+
1192211996
with test.nested(
11923-
mock.patch.object(drvr, '_get_volume_config',
11924-
return_value=conf),
11925-
mock.patch.object(guest, 'get_xml_desc',
11926-
return_value=initial_xml)):
11997+
mock.patch.object(
11998+
drvr, '_get_volume_config', return_value=conf
11999+
),
12000+
mock.patch.object(
12001+
guest, 'get_xml_desc', return_value=initial_xml
12002+
),
12003+
mock.patch.object(
12004+
drvr, '_sev_enabled', new=mock.Mock(return_value=False)
12005+
)
12006+
):
1192712007
config = libvirt_migrate.get_updated_guest_xml(
12008+
instance,
1192812009
guest,
1192912010
objects.LibvirtLiveMigrateData(
1193012011
bdms=[bdmi],
1193112012
serial_listen_addr='127.0.0.1',
11932-
serial_listen_ports=[1234]),
11933-
drvr._get_volume_config)
12013+
serial_listen_ports=[1234]
12014+
),
12015+
drvr._get_volume_config
12016+
)
1193412017
self.assertEqual(target_xml, config)
1193512018

1193612019
@mock.patch.object(host.Host, 'has_min_version', return_value=True)
@@ -19077,7 +19160,9 @@ def test_get_guest_storage_config(self):
1907719160
self.assertIsNone(instance.default_swap_device)
1907819161
connect_volume.assert_called_with(self.context,
1907919162
bdm['connection_info'], instance)
19080-
get_volume_config.assert_called_with(bdm['connection_info'],
19163+
get_volume_config.assert_called_with(
19164+
instance,
19165+
bdm['connection_info'],
1908119166
{'bus': 'virtio', 'type': 'disk', 'dev': 'vdc'})
1908219167
volume_save.assert_called_once_with()
1908319168

@@ -22855,16 +22940,19 @@ def test_attach_interface_guest_set_metadata(self):
2285522940
mock_save.assert_called_once_with()
2285622941
mock_set_metadata.assert_called_once_with(config_meta)
2285722942

22943+
@mock.patch('nova.virt.libvirt.designer.set_driver_iommu_for_device')
22944+
@mock.patch.object(libvirt_driver.LibvirtDriver, '_sev_enabled')
2285822945
@mock.patch.object(objects.Instance, 'get_network_info')
2285922946
@mock.patch.object(objects.Instance, 'save')
2286022947
@mock.patch.object(libvirt_driver.LibvirtDriver, '_build_device_metadata')
2286122948
@mock.patch.object(FakeVirtDomain, 'info')
2286222949
@mock.patch.object(FakeVirtDomain, 'attachDeviceFlags')
2286322950
@mock.patch.object(host.Host, '_get_domain')
2286422951
def _test_attach_interface(self, power_state, expected_flags,
22865-
mock_get_domain, mock_attach,
22866-
mock_info, mock_build, mock_save,
22867-
mock_get_network_info):
22952+
mock_get_domain, mock_attach, mock_info,
22953+
mock_build, mock_save, mock_get_network_info,
22954+
mock_sev_enabled, mock_designer_set_iommu,
22955+
sev_enabled=False):
2286822956
instance = self._create_instance()
2286922957
network_info = _fake_network_info(self)
2287022958
domain = FakeVirtDomain(fake_xml="""
@@ -22882,6 +22970,7 @@ def _test_attach_interface(self, power_state, expected_flags,
2288222970
</domain>""")
2288322971
mock_get_domain.return_value = domain
2288422972
mock_info.return_value = [power_state, 1, 2, 3, 4]
22973+
mock_sev_enabled.return_value = sev_enabled
2288522974

2288622975
fake_image_meta = objects.ImageMeta.from_dict(
2288722976
{'id': instance.image_ref})
@@ -22907,13 +22996,22 @@ def _test_attach_interface(self, power_state, expected_flags,
2290722996
mock_get_network_info.assert_called_once_with()
2290822997
mock_attach.assert_called_once_with(expected.to_xml(),
2290922998
flags=expected_flags)
22999+
if sev_enabled:
23000+
mock_designer_set_iommu.assert_called_once_with(expected)
2291023001

2291123002
def test_attach_interface_with_running_instance(self):
2291223003
self._test_attach_interface(
2291323004
power_state.RUNNING,
2291423005
(fakelibvirt.VIR_DOMAIN_AFFECT_CONFIG |
2291523006
fakelibvirt.VIR_DOMAIN_AFFECT_LIVE))
2291623007

23008+
def test_attach_interface_with_sev(self):
23009+
self._test_attach_interface(
23010+
power_state.RUNNING,
23011+
(fakelibvirt.VIR_DOMAIN_AFFECT_CONFIG |
23012+
fakelibvirt.VIR_DOMAIN_AFFECT_LIVE),
23013+
sev_enabled=True)
23014+
2291723015
def test_attach_interface_with_pause_instance(self):
2291823016
self._test_attach_interface(
2291923017
power_state.PAUSED,

0 commit comments

Comments
 (0)