Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add AMD SEV-SNP vm support #3682

Merged
merged 1 commit into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -3948,31 +3951,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 @@ -3981,13 +3997,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 @@ -4004,13 +4031,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 @@ -1093,19 +1093,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
Loading