diff --git a/nova/tests/functional/test_servers_provider_tree.py b/nova/tests/functional/test_servers_provider_tree.py index da562c4f19f5..625ca97c5399 100644 --- a/nova/tests/functional/test_servers_provider_tree.py +++ b/nova/tests/functional/test_servers_provider_tree.py @@ -45,6 +45,8 @@ class ProviderTreeTests(integrated_helpers.ProviderUsageBaseTestCase): os_traits.COMPUTE_VOLUME_EXTEND, os_traits.COMPUTE_VOLUME_MULTI_ATTACH, os_traits.COMPUTE_TRUSTED_CERTS, + os_traits.COMPUTE_ADDRESS_SPACE_EMULATED, + os_traits.COMPUTE_ADDRESS_SPACE_PASSTHROUGH, ] ]) diff --git a/nova/tests/unit/virt/libvirt/test_driver.py b/nova/tests/unit/virt/libvirt/test_driver.py index 1cad45875bf4..57f216712ff3 100644 --- a/nova/tests/unit/virt/libvirt/test_driver.py +++ b/nova/tests/unit/virt/libvirt/test_driver.py @@ -21367,6 +21367,40 @@ class LibvirtConnTestCase(test.NoDBTestCase, cpu_model = drvr._get_cpu_model_mapping(expect_model[0]) self.assertEqual(cpu_model, expect_model[0]) + @mock.patch.object(fakelibvirt.Connection, 'getLibVersion', + return_value=versionutils.convert_version_to_int( + libvirt_driver.MIN_LIBVIRT_MAXPHYSADDR)) + @mock.patch.object(fakelibvirt.Connection, 'getVersion', + return_value=versionutils.convert_version_to_int( + libvirt_driver.MIN_QEMU_MAXPHYSADDR)) + @mock.patch.object(fakelibvirt.Connection, 'getType', + return_value=host.HV_DRIVER_QEMU) + def test_update_host_specific_capabilities_with_maxphysaddr( + self, mock_get_lib_version, mock_get_version, mock_type): + driver = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI()) + driver._update_host_specific_capabilities() + self.assertTrue( + driver.capabilities.get('supports_address_space_passthrough')) + self.assertTrue( + driver.capabilities.get('supports_address_space_emulated')) + + @mock.patch.object(fakelibvirt.Connection, 'getLibVersion', + return_value=versionutils.convert_version_to_int( + libvirt_driver.MIN_LIBVIRT_MAXPHYSADDR)) + @mock.patch.object(fakelibvirt.Connection, 'getVersion', + return_value=versionutils.convert_version_to_int( + libvirt_driver.MIN_QEMU_MAXPHYSADDR) - 1) + @mock.patch.object(fakelibvirt.Connection, 'getType', + return_value=host.HV_DRIVER_QEMU) + def test_update_host_specific_capabilities_without_maxphysaddr( + self, mock_get_lib_version, mock_get_version, mock_type): + driver = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI()) + driver._update_host_specific_capabilities() + self.assertFalse( + driver.capabilities.get('supports_address_space_passthrough')) + self.assertFalse( + driver.capabilities.get('supports_address_space_emulated')) + @mock.patch.object(fakelibvirt.Connection, 'getLibVersion', return_value=versionutils.convert_version_to_int( libvirt_driver.MIN_LIBVIRT_TB_CACHE_SIZE) - 1) diff --git a/nova/virt/driver.py b/nova/virt/driver.py index 5d42a392d85d..8cd56bdd2121 100644 --- a/nova/virt/driver.py +++ b/nova/virt/driver.py @@ -157,6 +157,10 @@ CAPABILITY_TRAITS_MAP = { os_traits.COMPUTE_EPHEMERAL_ENCRYPTION_LUKS, "supports_ephemeral_encryption_plain": os_traits.COMPUTE_EPHEMERAL_ENCRYPTION_PLAIN, + "supports_address_space_passthrough": + os_traits.COMPUTE_ADDRESS_SPACE_PASSTHROUGH, + "supports_address_space_emulated": + os_traits.COMPUTE_ADDRESS_SPACE_EMULATED, } @@ -226,6 +230,8 @@ class ComputeDriver(object): "supports_secure_boot": False, "supports_socket_pci_numa_affinity": False, "supports_remote_managed_ports": False, + "supports_address_space_passthrough": False, + "supports_address_space_emulated": False, # Ephemeral encryption support flags "supports_ephemeral_encryption": False, diff --git a/nova/virt/fake.py b/nova/virt/fake.py index bf7dc8fc7235..25c21a0473fc 100644 --- a/nova/virt/fake.py +++ b/nova/virt/fake.py @@ -119,6 +119,8 @@ class FakeDriver(driver.ComputeDriver): "supports_pcpus": False, "supports_accelerators": True, "supports_remote_managed_ports": True, + "supports_address_space_passthrough": True, + "supports_address_space_emulated": True, # Supported image types "supports_image_type_raw": True, diff --git a/nova/virt/hyperv/driver.py b/nova/virt/hyperv/driver.py index ba18c85cf7da..d0f95dd549cc 100644 --- a/nova/virt/hyperv/driver.py +++ b/nova/virt/hyperv/driver.py @@ -104,6 +104,8 @@ class HyperVDriver(driver.ComputeDriver): "supports_accelerators": False, "supports_secure_boot": True, "supports_remote_managed_ports": False, + "supports_address_space_passthrough": False, + "supports_address_space_emulated": False, # Supported image types "supports_image_type_vhd": True, diff --git a/nova/virt/ironic/driver.py b/nova/virt/ironic/driver.py index 77fefb81ea48..960acf06a849 100644 --- a/nova/virt/ironic/driver.py +++ b/nova/virt/ironic/driver.py @@ -165,6 +165,8 @@ class IronicDriver(virt_driver.ComputeDriver): "supports_pcpus": False, "supports_accelerators": False, "supports_remote_managed_ports": False, + "supports_address_space_passthrough": False, + "supports_address_space_emulated": False, # Image type support flags "supports_image_type_aki": False, diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index ddb52138ef1e..b51b57fbec36 100644 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -252,6 +252,10 @@ LIBVIRT_PERF_EVENT_PREFIX = 'VIR_PERF_PARAM_' MIN_LIBVIRT_VDPA = (6, 9, 0) MIN_QEMU_VDPA = (5, 1, 0) +# Maxphysaddr minimal support version. +MIN_LIBVIRT_MAXPHYSADDR = (8, 7, 0) +MIN_QEMU_MAXPHYSADDR = (2, 7, 0) + REGISTER_IMAGE_PROPERTY_DEFAULTS = [ 'hw_machine_type', 'hw_cdrom_bus', @@ -857,6 +861,19 @@ class LibvirtDriver(driver.ComputeDriver): self._host.supports_remote_managed_ports }) + supports_maxphysaddr = self._host.has_min_version( + lv_ver=MIN_LIBVIRT_MAXPHYSADDR, + hv_ver=MIN_QEMU_MAXPHYSADDR, + hv_type=host.HV_DRIVER_QEMU, + ) + + # NOTE(nmiki): Currently libvirt does not provide a distinction + # between passthrough mode and emulated mode support status. + self.capabilities.update({ + 'supports_address_space_passthrough': supports_maxphysaddr, + 'supports_address_space_emulated': supports_maxphysaddr, + }) + def _register_all_undefined_instance_details(self) -> None: """Register the default image properties of instances on this host diff --git a/nova/virt/vmwareapi/driver.py b/nova/virt/vmwareapi/driver.py index bcdab23bce80..456e9648154a 100644 --- a/nova/virt/vmwareapi/driver.py +++ b/nova/virt/vmwareapi/driver.py @@ -72,6 +72,8 @@ class VMwareVCDriver(driver.ComputeDriver): "supports_pcpus": False, "supports_accelerators": False, "supports_remote_managed_ports": False, + "supports_address_space_passthrough": False, + "supports_address_space_emulated": False, # Image type support flags "supports_image_type_aki": False, diff --git a/nova/virt/zvm/driver.py b/nova/virt/zvm/driver.py index a1fa721515c3..d996527f38bd 100644 --- a/nova/virt/zvm/driver.py +++ b/nova/virt/zvm/driver.py @@ -47,6 +47,8 @@ class ZVMDriver(driver.ComputeDriver): capabilities = { "supports_pcpus": False, "supports_remote_managed_ports": False, + "supports_address_space_passthrough": False, + "supports_address_space_emulated": False, # Image type support flags "supports_image_type_aki": False, diff --git a/requirements.txt b/requirements.txt index e885a4a66f1a..9be319ab7630 100644 --- a/requirements.txt +++ b/requirements.txt @@ -52,7 +52,7 @@ psutil>=3.2.2 # BSD oslo.versionedobjects>=1.35.0 # Apache-2.0 os-brick>=5.2 # Apache-2.0 os-resource-classes>=1.1.0 # Apache-2.0 -os-traits>=2.9.0 # Apache-2.0 +os-traits>=2.10.0 # Apache-2.0 os-vif>=3.1.0 # Apache-2.0 castellan>=0.16.0 # Apache-2.0 microversion-parse>=0.2.1 # Apache-2.0