diff --git a/virt-manager.changes b/virt-manager.changes
index af3a0bc2..b9e61a8c 100644
--- a/virt-manager.changes
+++ b/virt-manager.changes
@@ -1,3 +1,13 @@
+-------------------------------------------------------------------
+Wed Mar 30 09:06:33 MDT 2022 - carnold@suse.com
+
+- bsc#1196806 - [jsc#SLE-18834][virt-install] ERROR SEV launch
+ security requires a Q35 UEFI machine (epic: jsc#SLE-18732)
+ virtman-add-sev-memory-support.patch
+- Add firmware features to description tooltip when mouse hovers
+ over the selected firmware file.
+ virtman-add-tooltip-to-firmware.patch
+
-------------------------------------------------------------------
Wed Mar 2 21:11:58 MST 2022 - carnold@suse.com
diff --git a/virt-manager.spec b/virt-manager.spec
index 05a9ed64..3fc370c9 100644
--- a/virt-manager.spec
+++ b/virt-manager.spec
@@ -44,6 +44,7 @@ Patch76: virtinst-set-qemu-emulator.patch
Patch103: virtman-load-stored-uris.patch
Patch104: virtman-add-tooltip-to-firmware.patch
Patch105: virtman-modify-gui-defaults.patch
+Patch106: virtman-add-sev-memory-support.patch
Patch120: virtinst-default-xen-to-qcow2-format.patch
Patch121: virtinst-detect-oes-distros.patch
Patch122: virtinst-vol-default-nocow.patch
@@ -86,6 +87,7 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-build
%define verrel %{version}-%{release}
Requires: dbus-1-x11
Requires: dconf
+Requires: gstreamer-plugins-good
Requires: gtk3
Requires: python3-gobject
# For console widget
@@ -168,6 +170,7 @@ machine).
%patch103 -p1
%patch104 -p1
%patch105 -p1
+%patch106 -p1
%patch120 -p1
%patch121 -p1
%patch122 -p1
diff --git a/virtinst-add-pvh-support.patch b/virtinst-add-pvh-support.patch
index 450f0cc5..3bfada4e 100644
--- a/virtinst-add-pvh-support.patch
+++ b/virtinst-add-pvh-support.patch
@@ -45,7 +45,7 @@ Index: virt-manager-4.0.0/virtManager/object/domain.py
===================================================================
--- virt-manager-4.0.0.orig/virtManager/object/domain.py
+++ virt-manager-4.0.0/virtManager/object/domain.py
-@@ -1274,6 +1274,8 @@ class vmmDomain(vmmLibvirtObject):
+@@ -1292,6 +1292,8 @@ class vmmDomain(vmmLibvirtObject):
return self.get_xmlobj().os.is_xenpv()
def is_hvm(self):
return self.get_xmlobj().os.is_hvm()
diff --git a/virtinst-set-default-nic.patch b/virtinst-set-default-nic.patch
index 1b4d501a..1d4f8f03 100644
--- a/virtinst-set-default-nic.patch
+++ b/virtinst-set-default-nic.patch
@@ -1,11 +1,11 @@
References: bsc#1172356, bsc#1177620
Libvirt doesn't accept "Hypervisor default" as a model name
-Index: virt-manager-3.3.0/virtinst/devices/interface.py
+Index: virt-manager-4.0.0/virtinst/devices/interface.py
===================================================================
---- virt-manager-3.3.0.orig/virtinst/devices/interface.py
-+++ virt-manager-3.3.0/virtinst/devices/interface.py
-@@ -302,6 +302,9 @@ class DeviceInterface(Device):
+--- virt-manager-4.0.0.orig/virtinst/devices/interface.py
++++ virt-manager-4.0.0/virtinst/devices/interface.py
+@@ -305,6 +305,9 @@ class DeviceInterface(Device):
return "e1000e"
if not guest.os.is_x86():
return None
diff --git a/virtman-add-sev-memory-support.patch b/virtman-add-sev-memory-support.patch
new file mode 100644
index 00000000..2cd29e61
--- /dev/null
+++ b/virtman-add-sev-memory-support.patch
@@ -0,0 +1,234 @@
+References: bsc#1196806, jsc#SLE-18834
+
+Index: virt-manager-4.0.0/ui/details.ui
+===================================================================
+--- virt-manager-4.0.0.orig/ui/details.ui
++++ virt-manager-4.0.0/ui/details.ui
+@@ -1925,7 +1925,20 @@
+
+
+
+-
++
++
++ 1
++ 4
++
+
+
+
+Index: virt-manager-4.0.0/virtManager/details/details.py
+===================================================================
+--- virt-manager-4.0.0.orig/virtManager/details/details.py
++++ virt-manager-4.0.0/virtManager/details/details.py
+@@ -50,6 +50,7 @@ from ..delete import vmmDeleteStorage
+
+ EDIT_MEM,
+ EDIT_MEM_SHARED,
++ EDIT_MEM_SEV,
+
+ EDIT_AUTOSTART,
+ EDIT_BOOTORDER,
+@@ -87,7 +88,7 @@ from ..delete import vmmDeleteStorage
+
+ EDIT_FS,
+
+- EDIT_HOSTDEV_ROMBAR) = range(1, 38)
++ EDIT_HOSTDEV_ROMBAR) = range(1, 39)
+
+
+ # Columns in hw list model
+@@ -440,6 +441,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,
+@@ -1516,6 +1518,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)
+@@ -2021,6 +2026,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 and self.is_customize_dialog)
++ 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))
+Index: virt-manager-4.0.0/virtManager/object/domain.py
+===================================================================
+--- virt-manager-4.0.0.orig/virtManager/object/domain.py
++++ virt-manager-4.0.0/virtManager/object/domain.py
+@@ -688,15 +688,33 @@ 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()
+
++ def _set_rombar(guest, value):
++ # Ideally turning rombar off would be done automatically
++ # by either libvirt or qemu when SEV is detected.
++ for nic in guest.devices.interface:
++ nic.set_rom_bar(value)
++
+ if memory != _SENTINEL:
+ guest.currentMemory = int(memory)
+ if maxmem != _SENTINEL:
+ guest.memory = int(maxmem)
+ if mem_shared != _SENTINEL:
+ self._edit_shared_mem(guest, mem_shared)
++ if sevmem != _SENTINEL:
++ if sevmem is True:
++ domcaps = self.get_domain_capabilities()
++ guest.launchSecurity.type = "sev"
++ guest.launchSecurity.set_defaults(guest, domcaps.supports_sev_es_launch_security())
++ guest.memoryBacking.set_locked(True)
++ _set_rombar(guest, "off")
++ else:
++ guest.launchSecurity.type = None
++ guest.launchSecurity.policy = None
++ guest.memoryBacking.set_locked(False)
++ _set_rombar(guest, None)
+
+ self._redefine_xmlobj(guest)
+
+@@ -1310,6 +1328,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)
+Index: virt-manager-4.0.0/virtinst/domain/memorybacking.py
+===================================================================
+--- virt-manager-4.0.0.orig/virtinst/domain/memorybacking.py
++++ virt-manager-4.0.0/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)
+Index: virt-manager-4.0.0/virtinst/domcapabilities.py
+===================================================================
+--- virt-manager-4.0.0.orig/virtinst/domcapabilities.py
++++ virt-manager-4.0.0/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")
+
+
+ #############################
+@@ -398,6 +402,9 @@ class DomainCapabilities(XMLBuilder):
+ """
+ return bool(self.features.sev.supported)
+
++ def supports_sev_es_launch_security(self):
++ return bool(self.features.sev.supported and self.features.sev.maxESGuests)
++
+ def supports_video_bochs(self):
+ """
+ Returns False if either libvirt or qemu do not have support to bochs
+Index: virt-manager-4.0.0/virtinst/domain/launch_security.py
+===================================================================
+--- virt-manager-4.0.0.orig/virtinst/domain/launch_security.py
++++ virt-manager-4.0.0/virtinst/domain/launch_security.py
+@@ -18,9 +18,13 @@ class DomainLaunchSecurity(XMLBuilder):
+ dhCert = XMLProperty("./dhCert")
+ 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"))
++ def _set_defaults_sev(self, guest, sev_es):
++ if not guest.os.is_q35():
++ raise RuntimeError(_("SEV launch security requires a Q35 machine"))
++ # Libvirt will select the appropriate firmware file if not specified
++ # as long as we enable efi.
++ 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
+@@ -28,8 +32,11 @@ class DomainLaunchSecurity(XMLBuilder):
+ # (bit 0) - disables the debugging mode
+ # (bit 1) - disables encryption key sharing across multiple guests
+ if self.policy is None:
+- self.policy = "0x03"
++ if sev_es:
++ self.policy = "0x07"
++ else:
++ self.policy = "0x03"
+
+- def set_defaults(self, guest):
++ def set_defaults(self, guest, sev_es=False):
+ if self.type == "sev":
+- return self._set_defaults_sev(guest)
++ return self._set_defaults_sev(guest, sev_es)
+Index: virt-manager-4.0.0/virtinst/devices/interface.py
+===================================================================
+--- virt-manager-4.0.0.orig/virtinst/devices/interface.py
++++ virt-manager-4.0.0/virtinst/devices/interface.py
+@@ -287,6 +287,9 @@ class DeviceInterface(Device):
+ self.type = nettype
+ self.source = source
+
++ def set_rom_bar(self, value):
++ self.rom_bar = value
++
+
+ ##################
+ # Default config #
+Index: virt-manager-4.0.0/virtManager/addhardware.py
+===================================================================
+--- virt-manager-4.0.0.orig/virtManager/addhardware.py
++++ virt-manager-4.0.0/virtManager/addhardware.py
+@@ -1438,6 +1438,9 @@ class vmmAddHardware(vmmGObjectUI):
+ mac = self.widget("create-mac-address").get_text()
+
+ dev = self._netlist.build_device(mac, model)
++ if self.vm.get_launch_security_type() == "sev":
++ dev.set_rom_bar("off")
++
+ return dev
+
+ def _build_input(self):
diff --git a/virtman-add-tooltip-to-firmware.patch b/virtman-add-tooltip-to-firmware.patch
index d77de1e1..a7970fbc 100644
--- a/virtman-add-tooltip-to-firmware.patch
+++ b/virtman-add-tooltip-to-firmware.patch
@@ -2,10 +2,10 @@ References:
When a particular firmware is selected, read the json file for a description.
Add a tooltip of the json description when the mouse move overs the selected firmware.
-Index: virt-manager-3.3.0/virtManager/details/details.py
+Index: virt-manager-4.0.0/virtManager/details/details.py
===================================================================
---- virt-manager-3.3.0.orig/virtManager/details/details.py
-+++ virt-manager-3.3.0/virtManager/details/details.py
+--- virt-manager-4.0.0.orig/virtManager/details/details.py
++++ virt-manager-4.0.0/virtManager/details/details.py
@@ -5,6 +5,9 @@
# See the COPYING file in the top-level directory.
@@ -25,7 +25,7 @@ Index: virt-manager-3.3.0/virtManager/details/details.py
"on_overview_chipset_changed": _e(EDIT_MACHTYPE),
"on_details_inspection_refresh_clicked": self._inspection_refresh_clicked_cb,
-@@ -1117,6 +1120,49 @@ class vmmDetails(vmmGObjectUI):
+@@ -1117,6 +1120,52 @@ class vmmDetails(vmmGObjectUI):
self.storage_browser.set_browse_reason(reason)
self.storage_browser.show(self.topwin)
@@ -54,6 +54,9 @@ Index: virt-manager-3.3.0/virtManager/details/details.py
+ json_exec = str(json_obj['mapping']['executable']['filename'])
+ if json_exec == firmware_file:
+ json_description = str(json_obj['description'])
++ json_features = str(json_obj['features'])
++ if len(json_features) > 0:
++ json_description = json_description + ". Firmware features: " + json_features
+ wrapper = textwrap.TextWrapper(width=60)
+ json_list = wrapper.wrap(text=json_description)
+ json_description = "\n".join(json_list)
diff --git a/virtman-fix-restore-vm-menu-selection.patch b/virtman-fix-restore-vm-menu-selection.patch
index e6977465..d4508f5c 100644
--- a/virtman-fix-restore-vm-menu-selection.patch
+++ b/virtman-fix-restore-vm-menu-selection.patch
@@ -3,11 +3,11 @@ virt-manager no longer tracks the saved state but leaves it up to libvirt.
Libvirt returns libvirt.VIR_DOMAIN_PMSUSPENDED after a vm has been 'saved'.
-Index: virt-manager-3.3.0/virtManager/object/domain.py
+Index: virt-manager-4.0.0/virtManager/object/domain.py
===================================================================
---- virt-manager-3.3.0.orig/virtManager/object/domain.py
-+++ virt-manager-3.3.0/virtManager/object/domain.py
-@@ -1581,7 +1581,8 @@ class vmmDomain(vmmLibvirtObject):
+--- virt-manager-4.0.0.orig/virtManager/object/domain.py
++++ virt-manager-4.0.0/virtManager/object/domain.py
+@@ -1602,7 +1602,8 @@ class vmmDomain(vmmLibvirtObject):
return (self.is_stoppable() or
self.status() in [libvirt.VIR_DOMAIN_CRASHED])
def is_runable(self):