Skip to content

Commit

Permalink
Add AMD SEV-SNP secure guest support
Browse files Browse the repository at this point in the history
qemu cmdline sample:
    -object sev-snp-guest,id=sev0, \
    cbitpos=51,reduced-phys-bits=1, \
    policy=0x30000, \
    id-block=YWFhYWFhYWFhYWFhYWFhCg==, \
    id-auth=CxHK/OKLkXGn/KpAC7Wl1FSiisWDbGTEKz..., \
    auth-key-enabled=on, \
    host-data=LNkCWBRC5CcdGXirbNUV1OrsR28s..., \
    guest-visible-workarounds=AA==, \

Signed-off-by: Zhenchao Liu <[email protected]>
  • Loading branch information
zhencliu committed Aug 15, 2024
1 parent eadca31 commit 32af24f
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 25 deletions.
1 change: 1 addition & 0 deletions virttest/qemu_capabilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class Flags(object):
MACHINE_MEMORY_BACKEND = _auto_value()
MIGRATION_PARAMS = _auto_value()
SEV_GUEST = _auto_value()
SNP_GUEST = _auto_value()
TDX_GUEST = _auto_value()
FLOPPY_DEVICE = _auto_value()
BLOCKJOB_BACKING_MASK_PROTOCOL = _auto_value()
Expand Down
75 changes: 53 additions & 22 deletions virttest/qemu_devices/qcontainer.py
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,9 @@ def _probe_capabilities(self):
# -object sev-guest
if self.has_object("sev-guest"):
self.caps.set_flag(Flags.SEV_GUEST)
# -object sev-snp-guest
if self.has_object('sev-snp-guest'):
self.caps.set_flag(Flags.SNP_GUEST)
# -object tdx-guest
if self.has_object("tdx-guest"):
self.caps.set_flag(Flags.TDX_GUEST)
Expand Down Expand Up @@ -1400,8 +1403,8 @@ def machine_q35(machine_params):
qdevices.QCPUBus(params.get("cpu_model"), [[""], [0]], "vcpu"),
)

# FIXME: Use -bios option to set firmware for a tdx vm
if params.get("vm_secure_guest_type") != "tdx":
# FIXME: Use -bios option to set firmware for a tdx/snp vm
if params.get("vm_secure_guest_type") not in ["snp", "tdx"]:
pflash_devices = pflash_handler("ovmf", machine_params)
devices.extend(pflash_devices)

Expand Down Expand Up @@ -3936,31 +3939,44 @@ def secure_guest_object_define_by_params(self, obj_id, params):
:return: the secret QObject device
"""

def _gen_sev_obj_props(obj_id, params):
def _gen_sev_common_props(params):
"""
Generate the sev common properties, refer to SevCommonProperties
Required: cbitpos, reduced-phys-bits
"""
Generate the properties of the sev-guest object.
sev_common_props = {
# FIXME: Set the following two properties from sev capabilities
# if they are not set yet
"cbitpos": int(params["vm_sev_cbitpos"]),
"reduced-phys-bits": int(params["vm_sev_reduced_phys_bits"]),
}

Follow libvirt's way to set the following options:
Required:
policy, cbitpos and reduced-phys-bits
Optional:
session-file, dh-cert-file and kernel-hashes(since 6.2)
if params.get("vm_sev_kernel_hashes"):
sev_common_props["kernel-hashes"] = params.get_boolean(
"vm_sev_kernel_hashes"
)
if params.get("vm_sev_device"):
sev_common_props["sev-device"] = params["vm_sev_device"]

:return: a tuple of (backend, sev-guest QObject properties dict)
return sev_common_props

def _gen_sev_obj_props(obj_id, params):
"""
Generate the sev-guest properties, refer to SevGuestProperties
"""
if Flags.SEV_GUEST not in self.caps:
raise ValueError("Unsupported sev-guest object")

backend, sev_obj_props = "sev-guest", {"id": obj_id}
sev_opts = params.get_dict("vm_secure_guest_object_options")
if sev_opts:
sev_obj_props.update(sev_opts)

sev_obj_props.update(_gen_sev_common_props(params))

# Set policy=3 if vm_sev_policy is not set
sev_obj_props["policy"] = int(params.get("vm_sev_policy", 3))

# FIXME: Set the following two options from sev capabilities
# if they are not set yet
sev_obj_props["cbitpos"] = int(params["vm_sev_cbitpos"])
sev_obj_props["reduced-phys-bits"] = int(params["vm_sev_reduced_phys_bits"])

# FIXME: If these files are host dependent, we have to find
# another way to set them, because different files are needed
# when migrating the vm from one host to another
Expand All @@ -3969,13 +3985,24 @@ def _gen_sev_obj_props(obj_id, params):
if params.get("vm_sev_dh_cert_file"):
sev_obj_props["dh-cert-file"] = params["vm_sev_dh_cert_file"]

if params.get("vm_sev_kernel_hashes"):
sev_obj_props["kernel-hashes"] = params.get_boolean(
"vm_sev_kernel_hashes"
)

return backend, sev_obj_props

def _gen_snp_obj_props(obj_id, params):
"""
Generate the sev-snp-guest properties, refer to SevSnpGuestProperties
"""
if Flags.SNP_GUEST not in self.caps:
raise ValueError('Unsupported sev-snp-guest object')

backend, snp_obj_props = 'sev-snp-guest', {'id': obj_id}
snp_opts = params.get_dict("vm_secure_guest_object_options")
if snp_opts:
snp_obj_props.update(snp_opts)

snp_obj_props.update(_gen_sev_common_props(params))

return backend, snp_obj_props

def _gen_tdx_obj_props(obj_id, params):
"""
Generate the properties of the tdx-guest object.
Expand All @@ -3992,13 +4019,17 @@ def _gen_tdx_obj_props(obj_id, params):

return backend, tdx_obj_props

obj_props_handlers = {"sev": _gen_sev_obj_props, "tdx": _gen_tdx_obj_props}
obj_props_handlers = {
"sev": _gen_sev_obj_props,
"snp": _gen_snp_obj_props,
"tdx": _gen_tdx_obj_props,
}

sectype = params["vm_secure_guest_type"]
if sectype in obj_props_handlers:
backend, properties = obj_props_handlers[sectype](obj_id, params)
else:
raise ValueError("Unsupported secure guest: %s" % sectype)
raise ValueError(f"Unsupported secure guest: {sectype}")

return qdevices.QObject(backend, properties)

Expand Down
7 changes: 6 additions & 1 deletion virttest/qemu_vm.py
Original file line number Diff line number Diff line change
Expand Up @@ -1712,8 +1712,13 @@ def add_secure_guest_descriptor(params):

sectype = params["vm_secure_guest_type"]
sev_mach_props = {}
snp_mach_props = {}
tdx_mach_props = {}
backend_props = {"sev": sev_mach_props, "tdx": tdx_mach_props}
backend_props = {
"sev": sev_mach_props,
"snp": snp_mach_props,
"tdx": tdx_mach_props,
}
for k, v in backend_props.get(sectype, {}).items():
machine_dev.set_param(k, v)

Expand Down
10 changes: 8 additions & 2 deletions virttest/shared/cfg/base.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -1081,19 +1081,25 @@ uuid_dimm = ""
#
# Set the secure guest type, or specify per-vm values (required)
#vm_secure_guest_type[_vm1] = sev
# Note: The following types are supported: sev
# Note: The following types are supported: sev, snp, tdx
# Disable secure guest: vm_secure_guest_type[_vm1] = ""
#
# Set the secure guest object options, use a blank to join more options (optional)
# TODO: Currently this param is used for tdx guest object only
#vm_secure_guest_object_options[_vm1] = "debug=on mrconfigid=xx mrowner=yy"
# Note: In order to keep consistent with the original specific sev params, properties
# defined by this param can be overwriten by the original ones, e.g.
# vm_sev_policy = 3
# vm_secure_guest_object_options = "policy=7"
# Finally the sev policy is 3.
#
# AMD SEV secure guest params
#
# Set the cbitpos, or specify per-vm values (required)
#vm_sev_cbitpos[_vm1] = 51
# Set the reduced-phys-bits, or specify per-vm values (required)
#vm_sev_reduced_phys_bits[_vm1] = 1
# Set the sev device, or specify per-vm values (optional)
#vm_sev_device[_vm1] = /dev/sev
# Set the policy, or specify per-vm values (optional)
#vm_sev_policy[_vm1] = 7
# Note: VT can set a default value 3 if vm_sev_policy is not set,
Expand Down

0 comments on commit 32af24f

Please sign in to comment.