libvirt: Disable VMCoreInfo device for SEV-encrypted instances
When VMCoreInfo device is enabled, the QEMU fw_cfg device in guest OS requires DMA between host OS and guest OS through the device. However DMA is prohibited when guest memory is encrypted using SEV, and the attempt results in kernel crash. Do not add VMCoreInfo when memory encryption is enabled. Closes-Bug: #2117170 Change-Id: I05c7b1ae46ccd8d9aa42456b493ac6ee7ddd8bae Signed-off-by: Takashi Kajinami <kajinamit@oss.nttdata.com>
This commit is contained in:
@@ -3787,6 +3787,53 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
||||
None, None, flavor, image_meta,
|
||||
)
|
||||
|
||||
@mock.patch.object(
|
||||
fakelibvirt.virConnect, '_domain_capability_features', new=
|
||||
fakelibvirt.virConnect._domain_capability_features_with_SEV
|
||||
)
|
||||
@mock.patch.object(host.Host, "_check_machine_type", new=mock.Mock())
|
||||
def test_get_guest_config_memory_encryption(self):
|
||||
"""Generate a guest with memory encryption.
|
||||
|
||||
This configures an memory encryption.
|
||||
"""
|
||||
self.flags(virt_type="kvm", group='libvirt')
|
||||
|
||||
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||
drvr._host._supports_amd_sev = True
|
||||
drvr._host._supports_amd_sev_es = False
|
||||
instance_ref = objects.Instance(**self.test_instance)
|
||||
image_meta = objects.ImageMeta.from_dict({
|
||||
"hw_architecture": fields.Architecture.X86_64,
|
||||
"disk_format": "raw",
|
||||
"properties": {
|
||||
"hw_machine_type": "q35",
|
||||
"hw_firmware_type": "uefi",
|
||||
"hw_mem_encryption": True,
|
||||
}
|
||||
})
|
||||
|
||||
disk_info = blockinfo.get_disk_info(
|
||||
CONF.libvirt.virt_type,
|
||||
instance_ref,
|
||||
image_meta,
|
||||
)
|
||||
|
||||
cfg = drvr._get_guest_config(
|
||||
instance_ref,
|
||||
_fake_network_info(self),
|
||||
image_meta,
|
||||
disk_info,
|
||||
)
|
||||
|
||||
# NOTE(tkajinm): vmcoreinfo should be disabled in this case
|
||||
self.assertEqual(2, len(cfg.features))
|
||||
for idx, device_type in enumerate([
|
||||
vconfig.LibvirtConfigGuestFeatureACPI,
|
||||
vconfig.LibvirtConfigGuestFeatureAPIC,
|
||||
]):
|
||||
self.assertIsInstance(cfg.features[idx], device_type)
|
||||
|
||||
def _test_get_mem_encryption_config(
|
||||
self, expected=None, host_sev_enabled=False, enc_extra_spec=None,
|
||||
enc_image_prop=None, hw_machine_type=None, hw_firmware_type=None):
|
||||
|
@@ -6689,8 +6689,11 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||
fields.Architecture.I686, fields.Architecture.X86_64,
|
||||
fields.Architecture.AARCH64,
|
||||
):
|
||||
guest.add_feature(
|
||||
vconfig.LibvirtConfigGuestFeatureVMCoreInfo())
|
||||
# VMCoreInfo device requires DMA between guest OS and host
|
||||
# OS, which is prohibited when guest memory is encrypted.
|
||||
if not self._get_mem_encryption_config(flavor, image_meta):
|
||||
guest.add_feature(
|
||||
vconfig.LibvirtConfigGuestFeatureVMCoreInfo())
|
||||
|
||||
if hide_hypervisor_id:
|
||||
guest.add_feature(
|
||||
|
@@ -0,0 +1,7 @@
|
||||
---
|
||||
fixes:
|
||||
- |
|
||||
[`bug 2117170 <https://bugs.launchpad.net/nova/+bug/2117170>`_] Libvirt
|
||||
driver no longer enables VMCoreInfo device when an instance has memory
|
||||
encryption is enabled, to avoid kernel crash caused by fw_cfg device in
|
||||
guest requiring DMA.
|
Reference in New Issue
Block a user