[PATCH virt-manager v2] Add support for enabling Secure Encrypted Virtualization in the GUI

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From 9646a5dd083a5acdf6cf519863354efaf4bdd07c Mon Sep 17 00:00:00 2001
From: Charles Arnold <carnold@xxxxxxxx>
Date: Thu, 7 Apr 2022 13:00:10 -0600
Subject: [PATCH v2 1/1] Add support for enabling Secure Encrypted Virtualization
 in the GUI

Add an "Enable launch security" checkbox on the Details memory tab.
Do the minimal configuration required for libvirt to enable this feature
on compatible hardware.

Allow libvirt to determine the firmware file. This just requires
enabling of efi and setting an appropriate policy. Check the libvirt
domain capabilities to determine whether SEV or SEV-ES is supported.

Signed-off-by: Charles Arnold <carnold@xxxxxxxx>
---
 ui/details.ui                      | 15 ++++++++++++++-
 virtManager/details/details.py     | 15 ++++++++++++++-
 virtManager/object/domain.py       | 14 +++++++++++++-
 virtinst/domain/launch_security.py | 23 +++++++++++++++--------
 virtinst/domain/memorybacking.py   |  3 +++
 virtinst/domcapabilities.py        |  8 +++++++-
 6 files changed, 66 insertions(+), 12 deletions(-)

diff --git a/ui/details.ui b/ui/details.ui
index 10b30824..b86db275 100644
--- a/ui/details.ui
+++ b/ui/details.ui
@@ -1925,7 +1925,20 @@
                                   </packing>
                                 </child>
                                 <child>
-                                  <placeholder/>
+                                  <object class="GtkCheckButton" id="launch-security"> +                                    <property name="label" translatable="yes">Enable launch security</property> +                                    <property name="visible">True</property> +                                    <property name="can-focus">True</property> +                                    <property name="receives-default">False</property> +                                    <property name="halign">start</property> +                                    <property name="use-underline">True</property> +                                    <property name="draw-indicator">True</property> +                                    <signal name="toggled" handler="on_mem_launch_security_toggled" swapped="no"/>
+                                  </object>
+                                  <packing>
+                                    <property name="left-attach">1</property> +                                    <property name="top-attach">4</property>
+                                  </packing>
                                 </child>
                               </object>
                               <packing>
diff --git a/virtManager/details/details.py b/virtManager/details/details.py
index 24810f0f..c22a10fb 100644
--- a/virtManager/details/details.py
+++ b/virtManager/details/details.py
@@ -47,6 +47,7 @@ from ..delete import vmmDeleteStorage

  EDIT_MEM,
  EDIT_MEM_SHARED,
+ EDIT_MEM_SEV,

  EDIT_AUTOSTART,
  EDIT_BOOTORDER,
@@ -84,7 +85,7 @@ from ..delete import vmmDeleteStorage

  EDIT_FS,

- EDIT_HOSTDEV_ROMBAR) = range(1, 38)
+ EDIT_HOSTDEV_ROMBAR) = range(1, 39)


 # Columns in hw list model
@@ -437,6 +438,7 @@ class vmmDetails(vmmGObjectUI):
             "on_mem_maxmem_changed": _e(EDIT_MEM),
             "on_mem_memory_changed": self._curmem_changed_cb,
             "on_mem_shared_access_toggled": _e(EDIT_MEM_SHARED),
+            "on_mem_launch_security_toggled": _e(EDIT_MEM_SEV),

             "on_boot_list_changed": self._boot_list_changed_cb,
             "on_boot_moveup_clicked": self._boot_moveup_clicked_cb,
@@ -1467,6 +1469,9 @@ class vmmDetails(vmmGObjectUI):
         if self._edited(EDIT_MEM_SHARED):
             kwargs["mem_shared"] = self.widget("shared-memory").get_active()

+        if self._edited(EDIT_MEM_SEV):
+            kwargs["sevmem"] = self.widget("launch-security").get_active()
+
         return self._change_config(
                 self.vm.define_memory, kwargs,
                 hotplug_args=hotplug_args)
@@ -1972,6 +1977,14 @@ class vmmDetails(vmmGObjectUI):
         curmem.set_value(int(round(vm_cur_mem)))
         maxmem.set_value(int(round(vm_max_mem)))

+        domcaps = self.vm.get_domain_capabilities()
+        show_sev = domcaps.supports_sev_launch_security()
+        self.widget("launch-security").set_sensitive(show_sev)
+        if self.vm.get_launch_security_type():
+            self.widget("launch-security").set_active(True)
+        else:
+            self.widget("launch-security").set_active(False)
+
         shared_mem, shared_mem_err = self.vm.has_shared_mem()
         self.widget("shared-memory").set_active(shared_mem)
         self.widget("shared-memory").set_sensitive(not bool(shared_mem_err))
diff --git a/virtManager/object/domain.py b/virtManager/object/domain.py
index 70e4e49f..feb43bd2 100644
--- a/virtManager/object/domain.py
+++ b/virtManager/object/domain.py
@@ -688,7 +688,7 @@ class vmmDomain(vmmLibvirtObject):
             guest.memoryBacking.access_mode = access_mode

     def define_memory(self, memory=_SENTINEL, maxmem=_SENTINEL,
-            mem_shared=_SENTINEL):
+            mem_shared=_SENTINEL, sevmem=_SENTINEL):
         guest = self._make_xmlobj_to_define()

         if memory != _SENTINEL:
@@ -697,6 +697,15 @@ class vmmDomain(vmmLibvirtObject):
             guest.memory = int(maxmem)
         if mem_shared != _SENTINEL:
             self._edit_shared_mem(guest, mem_shared)
+        if sevmem != _SENTINEL:
+            if sevmem is True:
+                guest.launchSecurity.type = "sev"
+                guest.launchSecurity.set_defaults(guest)
+                guest.memoryBacking.set_locked(True)
+            else:
+                guest.launchSecurity.type = None
+                guest.launchSecurity.policy = None
+                guest.memoryBacking.set_locked(False)

         self._redefine_xmlobj(guest)

@@ -1310,6 +1319,9 @@ class vmmDomain(vmmLibvirtObject):
     def get_description(self):
         return self.get_xmlobj().description

+    def get_launch_security_type(self):
+        return self.get_xmlobj().launchSecurity.type
+
     def get_boot_order(self):
         legacy = not self.can_use_device_boot_order()
         return self.xmlobj.get_boot_order(legacy=legacy)
diff --git a/virtinst/domain/launch_security.py b/virtinst/domain/launch_security.py
index 7af71811..f4a4a4b8 100644
--- a/virtinst/domain/launch_security.py
+++ b/virtinst/domain/launch_security.py
@@ -19,16 +19,23 @@ class DomainLaunchSecurity(XMLBuilder):
     kernelHashes = XMLProperty("./@kernelHashes", is_yesno=True)

     def _set_defaults_sev(self, guest):
-        if not guest.os.is_q35() or not guest.is_uefi():
-            raise RuntimeError(_("SEV launch security requires a Q35 UEFI machine"))
+        if not guest.os.is_q35():
+            raise RuntimeError(_("SEV launch security requires a Q35 machine")) +        # Libvirt will select the appropriate firmware file based on the policy
+        # defined below and if efi is enabled.
+        if not guest.is_uefi():
+            guest.os.firmware = 'efi'

-        # 'policy' is a mandatory 4-byte argument for the SEV firmware,
-        # if missing, let's use 0x03 which, according to the table at
-        # https://libvirt.org/formatdomain.html#launchSecurity:
-        # (bit 0) - disables the debugging mode
-        # (bit 1) - disables encryption key sharing across multiple guests
+        # The 'policy' is a mandatory 4-byte argument for the SEV firmware.
+        # If missing, we use 0x03 for the original SEV implementation and
+        # 0x07 for SEV-ES.
+        # Reference: https://libvirt.org/formatdomain.html#launchSecurity
         if self.policy is None:
-            self.policy = "0x03"
+            domcaps = guest.lookup_domcaps()
+            if domcaps.supports_sev_launch_security(check_es=True):
+                self.policy = "0x07"
+            else:
+                self.policy = "0x03"

     def set_defaults(self, guest):
         if self.type == "sev":
diff --git a/virtinst/domain/memorybacking.py b/virtinst/domain/memorybacking.py
index c883c57d..4ddd3865 100644
--- a/virtinst/domain/memorybacking.py
+++ b/virtinst/domain/memorybacking.py
@@ -27,6 +27,9 @@ class DomainMemoryBacking(XMLBuilder):
     XML_NAME = "memoryBacking"
     _XML_PROP_ORDER = ["hugepages", "nosharepages", "locked", "pages"]

+    def set_locked(self, value):
+        self.locked = value
+
     hugepages = XMLProperty("./hugepages", is_bool=True)
     nosharepages = XMLProperty("./nosharepages", is_bool=True)
     locked = XMLProperty("./locked", is_bool=True)
diff --git a/virtinst/domcapabilities.py b/virtinst/domcapabilities.py
index 3ebc409d..4d79c6d1 100644
--- a/virtinst/domcapabilities.py
+++ b/virtinst/domcapabilities.py
@@ -93,6 +93,10 @@ def _make_capsblock(xml_root_name):
 class _SEV(XMLBuilder):
     XML_NAME = "sev"
     supported = XMLProperty("./@supported", is_yesno=True)
+    cbitpos = XMLProperty("./cbitpos")
+    reducedPhysBits = XMLProperty("./reducedPhysBits")
+    maxGuests = XMLProperty("./maxGuests")
+    maxESGuests = XMLProperty("./maxESGuests")


 #############################
@@ -390,12 +394,14 @@ class DomainCapabilities(XMLBuilder):
     # Misc support methods #
     ########################

-    def supports_sev_launch_security(self):
+    def supports_sev_launch_security(self, check_es=False):
         """
         Returns False if either libvirt doesn't advertise support for SEV at          all (< libvirt-4.5.0) or if it explicitly advertises it as unsupported
         on the platform
         """
+        if check_es:
+            return bool(self.features.sev.supported and self.features.sev.maxESGuests)
         return bool(self.features.sev.supported)

     def supports_video_bochs(self):
--
2.31.1






[Index of Archives]     [Linux Virtualization]     [KVM Development]     [CentOS Virtualization]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite Forum]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]     [Video 4 Linux]

  Powered by Linux