virtinst: cli: Introduce parser support for SEV launch security

Introduce both the launchSecurity XML and parser classes. While at it,
add launchSecurity as a property instance to the Guest class too.

The parser requires the 'type' argument to be mandatory since in the
future it will determine different code paths, therefore
'--launchSecurity foo=bar' is incorrect.

Reviewed-by: Cole Robinson <crobinso@redhat.com>
Signed-off-by: Erik Skultety <eskultet@redhat.com>
This commit is contained in:
Erik Skultety 2019-06-11 17:41:57 +02:00 committed by Cole Robinson
parent 9bfdd92c0e
commit 45f3a47c84
6 changed files with 123 additions and 1 deletions

View File

@ -0,0 +1,63 @@
<domain type="kvm">
<name>foobar</name>
<uuid>00000000-1111-2222-3333-444444444444</uuid>
<memory>65536</memory>
<currentMemory>65536</currentMemory>
<vcpu>1</vcpu>
<os>
<type arch="x86_64" machine="q35">hvm</type>
<loader readonly="yes" type="pflash">/usr/share/edk2/ovmf/OVMF_CODE.fd</loader>
<boot dev="hd"/>
</os>
<features>
<acpi/>
<apic/>
<vmport state="off"/>
</features>
<cpu mode="host-model"/>
<clock offset="utc">
<timer name="rtc" tickpolicy="catchup"/>
<timer name="pit" tickpolicy="delay"/>
<timer name="hpet" present="no"/>
</clock>
<pm>
<suspend-to-mem enabled="no"/>
<suspend-to-disk enabled="no"/>
</pm>
<devices>
<emulator>/usr/bin/qemu-kvm</emulator>
<controller type="usb" index="0" model="ich9-ehci1"/>
<controller type="usb" index="0" model="ich9-uhci1">
<master startport="0"/>
</controller>
<controller type="usb" index="0" model="ich9-uhci2">
<master startport="2"/>
</controller>
<controller type="usb" index="0" model="ich9-uhci3">
<master startport="4"/>
</controller>
<interface type="bridge">
<source bridge="testsuitebr0"/>
<mac address="00:11:22:33:44:55"/>
<model type="e1000e"/>
</interface>
<console type="pty"/>
<input type="tablet" bus="usb"/>
<graphics type="spice" port="-1" tlsPort="-1" autoport="yes">
<image compression="off"/>
</graphics>
<sound model="ich9"/>
<video>
<model type="qxl"/>
</video>
<redirdev bus="usb" type="spicevmc"/>
<redirdev bus="usb" type="spicevmc"/>
</devices>
<launchSecurity type="sev">
<cbitpos>47</cbitpos>
<reducedPhysBits>1</reducedPhysBits>
<policy>0x0001</policy>
<session>BASE64SESSION</session>
<dhCert>BASE64CERT</dhCert>
</launchSecurity>
</domain>

View File

@ -895,6 +895,12 @@ c.add_invalid("--nodisks --boot network --arch mips --virt-type kvm") # Invalid
c.add_invalid("--nodisks --boot network --paravirt --arch mips") # Invalid arch/virt combo c.add_invalid("--nodisks --boot network --paravirt --arch mips") # Invalid arch/virt combo
c.add_invalid("--disk none --location nfs:example.com/fake --nonetworks") # Using --location nfs, no longer supported c.add_invalid("--disk none --location nfs:example.com/fake --nonetworks") # Using --location nfs, no longer supported
c = vinst.add_category("kvm-x86_64-launch-security", "--disk none --noautoconsole")
c.add_compare("--boot uefi --machine q35 --launchSecurity type=sev,reducedPhysBits=1,policy=0x0001,cbitpos=47,dhCert=BASE64CERT,session=BASE64SESSION --connect " + utils.URIs.kvm_amd_sev, "x86_64-launch-security-sev-full") # Full cmdline
c.add_invalid("--launchSecurity policy=0x0001 --connect " + utils.URIs.kvm_amd_sev) # Missing launchSecurity 'type'
c = vinst.add_category("kvm-q35", "--noautoconsole --connect " + utils.URIs.kvm_q35) c = vinst.add_category("kvm-q35", "--noautoconsole --connect " + utils.URIs.kvm_q35)
c.add_compare("--boot uefi --disk none", "boot-uefi") c.add_compare("--boot uefi --disk none", "boot-uefi")

View File

@ -825,6 +825,12 @@ def add_guest_xml_options(geng):
"--qemu-commandline='-display gtk,gl=on'\n" "--qemu-commandline='-display gtk,gl=on'\n"
"--qemu-commandline env=DISPLAY=:0.1")) "--qemu-commandline env=DISPLAY=:0.1"))
ParserLaunchSecurity.register()
geng.add_argument("--launchSecurity", "--launchsecurity", action="append",
help=_("Configure VM launch security (e.g. SEV memory encryption). Ex:\n"
"--launchSecurity type=sev,cbitpos=47,reducedPhysBits=1,policy=0x0001,dhCert=BASE64CERT\n"
"--launchSecurity sev"))
def add_boot_options(insg): def add_boot_options(insg):
ParserBoot.register() ParserBoot.register()
@ -3828,6 +3834,26 @@ class ParserHostdev(VirtCLIParser):
cls.add_arg("rom.bar", "rom_bar", is_onoff=True) cls.add_arg("rom.bar", "rom_bar", is_onoff=True)
#############################
# --launchSecurity parsing #
#############################
class ParserLaunchSecurity(VirtCLIParser):
cli_arg_name = "launchSecurity"
guest_propname = "launchSecurity"
remove_first = "type"
@classmethod
def _init_class(cls, **kwargs):
VirtCLIParser._init_class(**kwargs)
cls.add_arg("type", "type")
cls.add_arg("cbitpos", "cbitpos")
cls.add_arg("reducedPhysBits", "reducedPhysBits")
cls.add_arg("policy", "policy")
cls.add_arg("session", "session")
cls.add_arg("dhCert", "dhCert")
########################### ###########################
# Public virt parser APIs # # Public virt parser APIs #
########################### ###########################

View File

@ -19,5 +19,6 @@ from .seclabel import DomainSeclabel
from .sysinfo import DomainSysinfo from .sysinfo import DomainSysinfo
from .vcpus import DomainVCPUs from .vcpus import DomainVCPUs
from .xmlnsqemu import DomainXMLNSQemu from .xmlnsqemu import DomainXMLNSQemu
from .launch_security import DomainLaunchSecurity
__all__ = [l for l in locals() if l.startswith("Domain")] __all__ = [l for l in locals() if l.startswith("Domain")]

View File

@ -0,0 +1,25 @@
from ..xmlbuilder import XMLBuilder, XMLProperty
class DomainLaunchSecurity(XMLBuilder):
"""
Class for generating <launchSecurity> XML element
"""
XML_NAME = "launchSecurity"
_XML_PROP_ORDER = ["type", "cbitpos", "reducedPhysBits", "policy",
"session", "dhCert"]
type = XMLProperty("./@type")
cbitpos = XMLProperty("./cbitpos", is_int=True)
reducedPhysBits = XMLProperty("./reducedPhysBits", is_int=True)
policy = XMLProperty("./policy")
session = XMLProperty("./session")
dhCert = XMLProperty("./dhCert")
def is_sev(self):
return self.type == "sev"
def validate(self):
if not self.type:
raise RuntimeError(_("Missing mandatory attribute 'type'"))

View File

@ -181,7 +181,7 @@ class Guest(XMLBuilder):
"vcpu_cpuset", "vcpulist", "numatune", "resource", "sysinfo", "vcpu_cpuset", "vcpulist", "numatune", "resource", "sysinfo",
"bootloader", "os", "idmap", "features", "cpu", "clock", "bootloader", "os", "idmap", "features", "cpu", "clock",
"on_poweroff", "on_reboot", "on_crash", "on_poweroff", "on_reboot", "on_crash",
"pm", "emulator", "devices", "seclabels"] "pm", "emulator", "devices", "launchSecurity", "seclabels"]
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
XMLBuilder.__init__(self, *args, **kwargs) XMLBuilder.__init__(self, *args, **kwargs)
@ -272,6 +272,7 @@ class Guest(XMLBuilder):
idmap = XMLChildProperty(DomainIdmap, is_single=True) idmap = XMLChildProperty(DomainIdmap, is_single=True)
resource = XMLChildProperty(DomainResource, is_single=True) resource = XMLChildProperty(DomainResource, is_single=True)
sysinfo = XMLChildProperty(DomainSysinfo, is_single=True) sysinfo = XMLChildProperty(DomainSysinfo, is_single=True)
launchSecurity = XMLChildProperty(DomainLaunchSecurity, is_single=True)
_metadata = XMLChildProperty(DomainMetadata, is_single=True) _metadata = XMLChildProperty(DomainMetadata, is_single=True)
xmlns_qemu = XMLChildProperty(DomainXMLNSQemu, is_single=True) xmlns_qemu = XMLChildProperty(DomainXMLNSQemu, is_single=True)