diff --git a/nova/tests/unit/virt/libvirt/test_config.py b/nova/tests/unit/virt/libvirt/test_config.py index 396edfd02482..1fe3b52e2ed6 100644 --- a/nova/tests/unit/virt/libvirt/test_config.py +++ b/nova/tests/unit/virt/libvirt/test_config.py @@ -2318,6 +2318,15 @@ class LibvirtConfigGuestFeatureTest(LibvirtConfigBaseTest): obj.vapic = True obj.spinlocks = True obj.vendorid_spoof = True + obj.vpindex = True + obj.runtime = True + obj.synic = True + obj.reset = True + obj.frequencies = True + obj.reenlightenment = True + obj.tlbflush = True + obj.ipi = True + obj.evmcs = True xml = obj.to_xml() self.assertXmlEqual(xml, """ @@ -2326,6 +2335,15 @@ class LibvirtConfigGuestFeatureTest(LibvirtConfigBaseTest): + + + + + + + + + """) def test_feature_pmu(self): diff --git a/nova/tests/unit/virt/libvirt/test_driver.py b/nova/tests/unit/virt/libvirt/test_driver.py index 7233c00a72cc..cac5a5bcbec8 100644 --- a/nova/tests/unit/virt/libvirt/test_driver.py +++ b/nova/tests/unit/virt/libvirt/test_driver.py @@ -27172,6 +27172,35 @@ class LibvirtDriverTestCase(test.NoDBTestCase, TraitsComparisonMixin): mock_get_guest.return_value.assert_not_called() self.assertIsNone(mock_find.call_args.args[3]) + def test_set_features_windows(self): + self.flags(virt_type='kvm', group='libvirt') + guest = vconfig.LibvirtConfigGuest() + self.drvr._set_features( + guest, 'windows', + objects.ImageMeta( + properties=objects.ImageMetaProps() + ), + objects.Flavor(extra_specs={}) + ) + features = guest.features + hv = None + for feature in features: + if feature.root_name == 'hyperv': + hv = feature + self.assertTrue(hv.relaxed) + self.assertTrue(hv.vapic) + self.assertTrue(hv.spinlocks) + self.assertEqual(8191, hv.spinlock_retries) + self.assertTrue(hv.vpindex) + self.assertTrue(hv.runtime) + self.assertTrue(hv.synic) + self.assertTrue(hv.reset) + self.assertTrue(hv.frequencies) + self.assertTrue(hv.reenlightenment) + self.assertTrue(hv.tlbflush) + self.assertTrue(hv.ipi) + self.assertTrue(hv.evmcs) + class LibvirtVolumeUsageTestCase(test.NoDBTestCase): """Test for LibvirtDriver.get_all_volume_usage.""" diff --git a/nova/virt/libvirt/config.py b/nova/virt/libvirt/config.py index 1a81be3ade56..4444d7cd2896 100644 --- a/nova/virt/libvirt/config.py +++ b/nova/virt/libvirt/config.py @@ -2732,6 +2732,15 @@ class LibvirtConfigGuestFeatureHyperV(LibvirtConfigGuestFeature): self.vapic = False self.spinlocks = False self.spinlock_retries = self.MIN_SPINLOCK_RETRIES + self.vpindex = False + self.runtime = False + self.synic = False + self.reset = False + self.frequencies = False + self.reenlightenment = False + self.tlbflush = False + self.ipi = False + self.evmcs = False self.vendorid_spoof = False self.vendorid = self.SPOOFED_VENDOR_ID @@ -2748,6 +2757,24 @@ class LibvirtConfigGuestFeatureHyperV(LibvirtConfigGuestFeature): if self.vendorid_spoof: root.append(etree.Element("vendor_id", state="on", value=self.vendorid)) + if self.vpindex: + root.append(etree.Element('vpindex', state='on')) + if self.runtime: + root.append(etree.Element('runtime', state='on')) + if self.synic: + root.append(etree.Element('synic', state='on')) + if self.reset: + root.append(etree.Element('reset', state='on')) + if self.frequencies: + root.append(etree.Element('frequencies', state='on')) + if self.reenlightenment: + root.append(etree.Element('reenlightenment', state='on')) + if self.tlbflush: + root.append(etree.Element('tlbflush', state='on')) + if self.ipi: + root.append(etree.Element('ipi', state='on')) + if self.evmcs: + root.append(etree.Element('evmcs', state='on')) return root diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index b35f17fe3ae4..096433c2ae61 100644 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -6080,6 +6080,15 @@ class LibvirtDriver(driver.ComputeDriver): # with Microsoft hv.spinlock_retries = 8191 hv.vapic = True + hv.vpindex = True + hv.runtime = True + hv.synic = True + hv.reset = True + hv.frequencies = True + hv.reenlightenment = True + hv.tlbflush = True + hv.ipi = True + hv.evmcs = True # NOTE(kosamara): Spoofing the vendor_id aims to allow the nvidia # driver to work on windows VMs. At the moment, the nvidia driver diff --git a/releasenotes/notes/update-libvirt-enlightenments-for-windows-23abea98cc1db667.yaml b/releasenotes/notes/update-libvirt-enlightenments-for-windows-23abea98cc1db667.yaml new file mode 100644 index 000000000000..c262be152749 --- /dev/null +++ b/releasenotes/notes/update-libvirt-enlightenments-for-windows-23abea98cc1db667.yaml @@ -0,0 +1,21 @@ +--- +features: + - | + The following enlightenments are now added by default to the libvirt XML for Windows guests: + + * vpindex + * runtime + * synic + * reset + * frequencies + * reenlightenment + * tlbflush + * ipi + * evmc + + This adds to the list of already existing enlightenments, namely: + + * relaxed + * vapic + * spinlocks retries + * vendor_id spoofing