diff --git a/nova/tests/functional/libvirt/test_report_cpu_traits.py b/nova/tests/functional/libvirt/test_report_cpu_traits.py index 0964029cd7..b470cdf1ac 100644 --- a/nova/tests/functional/libvirt/test_report_cpu_traits.py +++ b/nova/tests/functional/libvirt/test_report_cpu_traits.py @@ -81,7 +81,10 @@ class LibvirtReportTraitsTests(LibvirtReportTraitsTestBase): # trait values are coming from fakelibvirt's baselineCPU result. # COMPUTE_NODE is always set on the compute node provider. traits = self._get_provider_traits(self.host_uuid) - for trait in ('HW_CPU_X86_VMX', 'HW_CPU_X86_AESNI', 'COMPUTE_NODE'): + for trait in ( + 'HW_CPU_X86_VMX', 'HW_CPU_X86_INTEL_VMX', 'HW_CPU_X86_AESNI', + 'COMPUTE_NODE', + ): self.assertIn(trait, traits) self._create_trait('CUSTOM_TRAITS') @@ -96,10 +99,14 @@ class LibvirtReportTraitsTests(LibvirtReportTraitsTestBase): # and it's not in the baseline for the host. traits = set(self._get_provider_traits(self.host_uuid)) expected_traits = self.expected_libvirt_driver_capability_traits.union( - [u'HW_CPU_X86_VMX', u'HW_CPU_X86_AESNI', u'CUSTOM_TRAITS', - # The periodic restored the COMPUTE_NODE trait. - u'COMPUTE_NODE'] - ) + [ + 'HW_CPU_X86_VMX', + 'HW_CPU_X86_INTEL_VMX', + 'HW_CPU_X86_AESNI', + 'CUSTOM_TRAITS', + # The periodic restored the COMPUTE_NODE trait. + 'COMPUTE_NODE', + ]) for trait in expected_traits: self.assertIn(trait, traits) diff --git a/nova/tests/unit/virt/libvirt/test_driver.py b/nova/tests/unit/virt/libvirt/test_driver.py index a2bab72e38..1c28860fb7 100644 --- a/nova/tests/unit/virt/libvirt/test_driver.py +++ b/nova/tests/unit/virt/libvirt/test_driver.py @@ -21101,7 +21101,7 @@ class TestUpdateProviderTree(test.NoDBTestCase): pcpus = 12 memory_mb = 1024 disk_gb = 200 - cpu_traits = {t: False for t in libvirt_utils.CPU_TRAITS_MAPPING.values()} + cpu_traits = libvirt_utils.cpu_features_to_traits({}) def setUp(self): super(TestUpdateProviderTree, self).setUp() @@ -21816,7 +21816,7 @@ class TraitsComparisonMixin(object): def assertTraitsEqual(self, expected, actual): exp = {t: t in expected - for t in libvirt_utils.CPU_TRAITS_MAPPING.values()} + for t in libvirt_utils.cpu_features_to_traits({})} self.assertEqual(exp, actual) @@ -25538,8 +25538,9 @@ class LibvirtDriverTestCase(test.NoDBTestCase, TraitsComparisonMixin): are calculated from fakelibvirt's baseline CPU features. """ self.flags(cpu_mode='host-passthrough', group='libvirt') - self.assertTraitsEqual(['HW_CPU_X86_AESNI', 'HW_CPU_X86_VMX'], - self.drvr._get_cpu_feature_traits()) + self.assertTraitsEqual( + ['HW_CPU_X86_AESNI', 'HW_CPU_X86_VMX', 'HW_CPU_X86_INTEL_VMX'], + self.drvr._get_cpu_feature_traits()) @mock.patch('nova.virt.libvirt.host.libvirt.Connection.baselineCPU') def test_cpu_traits_with_mode_none(self, mock_baseline): @@ -25548,9 +25549,10 @@ class LibvirtDriverTestCase(test.NoDBTestCase, TraitsComparisonMixin): """ self.flags(cpu_mode='none', group='libvirt') mock_baseline.return_value = _fake_qemu64_cpu_feature - self.assertTraitsEqual(['HW_CPU_X86_SSE', 'HW_CPU_X86_SVM', - 'HW_CPU_X86_MMX', 'HW_CPU_X86_SSE2'], - self.drvr._get_cpu_feature_traits()) + self.assertTraitsEqual( + ['HW_CPU_X86_SSE', 'HW_CPU_X86_SVM', 'HW_CPU_X86_AMD_SVM', + 'HW_CPU_X86_MMX', 'HW_CPU_X86_SSE2'], + self.drvr._get_cpu_feature_traits()) mock_baseline.assert_called_with([u''' x86_64 @@ -25638,6 +25640,7 @@ class LibvirtDriverTestCase(test.NoDBTestCase, TraitsComparisonMixin): 'HW_CPU_X86_SSE2', 'HW_CPU_X86_SSE', 'HW_CPU_X86_MMX', + 'HW_CPU_X86_AMD_SVM', 'HW_CPU_X86_SVM' ], self.drvr._get_cpu_feature_traits() ) @@ -25705,6 +25708,7 @@ class LibvirtDriverTestCase(test.NoDBTestCase, TraitsComparisonMixin): 'HW_CPU_X86_SSE2', 'HW_CPU_X86_SSE', 'HW_CPU_X86_MMX', + 'HW_CPU_X86_AMD_SVM', 'HW_CPU_X86_SVM' ], self.drvr._get_cpu_feature_traits() ) diff --git a/nova/virt/libvirt/utils.py b/nova/virt/libvirt/utils.py index 5a60902573..317785d048 100644 --- a/nova/virt/libvirt/utils.py +++ b/nova/virt/libvirt/utils.py @@ -93,9 +93,13 @@ CPU_TRAITS_MAPPING = { 'sse4.2': os_traits.HW_CPU_X86_SSE42, 'sse4a': os_traits.HW_CPU_X86_SSE4A, 'ssse3': os_traits.HW_CPU_X86_SSSE3, - 'svm': os_traits.HW_CPU_X86_SVM, + # We have to continue to support the old (generic) trait for the + # AMD-specific svm feature. + 'svm': (os_traits.HW_CPU_X86_SVM, os_traits.HW_CPU_X86_AMD_SVM), 'tbm': os_traits.HW_CPU_X86_TBM, - 'vmx': os_traits.HW_CPU_X86_VMX, + # We have to continue to support the old (generic) trait for the + # Intel-specific vmx feature. + 'vmx': (os_traits.HW_CPU_X86_VMX, os_traits.HW_CPU_X86_INTEL_VMX), 'xop': os_traits.HW_CPU_X86_XOP } @@ -577,11 +581,15 @@ def cpu_features_to_traits(features: ty.Set[str]) -> ty.Dict[str, bool]: """Returns this driver's CPU traits dict where keys are trait names from CPU_TRAITS_MAPPING, values are boolean indicates whether the trait should be set in the provider tree. + + :param features: A set of feature names (short, lowercase, + CPU_TRAITS_MAPPING's keys). """ - traits = {trait_name: False for trait_name in CPU_TRAITS_MAPPING.values()} - for f in features: - if f in CPU_TRAITS_MAPPING: - traits[CPU_TRAITS_MAPPING[f]] = True + traits = {} + for feature_name, val in CPU_TRAITS_MAPPING.items(): + trait_tuple = val if isinstance(val, tuple) else (val,) + for trait_name in trait_tuple: + traits[trait_name] = feature_name in features return traits