From 16dcf200dc951c1cde3e5b442457db5f690b8cf0 Mon Sep 17 00:00:00 2001 From: Michael Roth Date: Thu, 30 May 2024 06:16:16 -0500 Subject: i386/sev: Introduce "sev-common" type to encapsulate common SEV state Currently all SEV/SEV-ES functionality is managed through a single 'sev-guest' QOM type. With upcoming support for SEV-SNP, taking this same approach won't work well since some of the properties/state managed by 'sev-guest' is not applicable to SEV-SNP, which will instead rely on a new QOM type with its own set of properties/state. To prepare for this, this patch moves common state into an abstract 'sev-common' parent type to encapsulate properties/state that are common to both SEV/SEV-ES and SEV-SNP, leaving only SEV/SEV-ES-specific properties/state in the current 'sev-guest' type. This should not affect current behavior or command-line options. As part of this patch, some related changes are also made: - a static 'sev_guest' variable is currently used to keep track of the 'sev-guest' instance. SEV-SNP would similarly introduce an 'sev_snp_guest' static variable. But these instances are now available via qdev_get_machine()->cgs, so switch to using that instead and drop the static variable. - 'sev_guest' is currently used as the name for the static variable holding a pointer to the 'sev-guest' instance. Re-purpose the name as a local variable referring the 'sev-guest' instance, and use that consistently throughout the code so it can be easily distinguished from sev-common/sev-snp-guest instances. - 'sev' is generally used as the name for local variables holding a pointer to the 'sev-guest' instance. In cases where that now points to common state, use the name 'sev_common'; in cases where that now points to state specific to 'sev-guest' instance, use the name 'sev_guest' In order to enable kernel-hashes for SNP, pull it from SevGuestProperties to its parent SevCommonProperties so it will be available for both SEV and SNP. Signed-off-by: Michael Roth Co-developed-by: Dov Murik Signed-off-by: Dov Murik Acked-by: Markus Armbruster (QAPI schema) Co-developed-by: Pankaj Gupta Signed-off-by: Pankaj Gupta Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com> Signed-off-by: Paolo Bonzini --- qapi/qom.json | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) (limited to 'qapi') diff --git a/qapi/qom.json b/qapi/qom.json index 38dde6d785..056b38f491 100644 --- a/qapi/qom.json +++ b/qapi/qom.json @@ -875,20 +875,12 @@ 'data': { '*filename': 'str' } } ## -# @SevGuestProperties: +# @SevCommonProperties: # -# Properties for sev-guest objects. +# Properties common to objects that are derivatives of sev-common. # # @sev-device: SEV device to use (default: "/dev/sev") # -# @dh-cert-file: guest owners DH certificate (encoded with base64) -# -# @session-file: guest owners session parameters (encoded with base64) -# -# @policy: SEV policy value (default: 0x1) -# -# @handle: SEV firmware handle (default: 0) -# # @cbitpos: C-bit location in page table entry (default: 0) # # @reduced-phys-bits: number of bits in physical addresses that become @@ -898,6 +890,27 @@ # designated guest firmware page for measured boot with -kernel # (default: false) (since 6.2) # +# Since: 9.1 +## +{ 'struct': 'SevCommonProperties', + 'data': { '*sev-device': 'str', + '*cbitpos': 'uint32', + 'reduced-phys-bits': 'uint32', + '*kernel-hashes': 'bool' } } + +## +# @SevGuestProperties: +# +# Properties for sev-guest objects. +# +# @dh-cert-file: guest owners DH certificate (encoded with base64) +# +# @session-file: guest owners session parameters (encoded with base64) +# +# @policy: SEV policy value (default: 0x1) +# +# @handle: SEV firmware handle (default: 0) +# # @legacy-vm-type: Use legacy KVM_SEV_INIT KVM interface for creating the VM. # The newer KVM_SEV_INIT2 interface syncs additional vCPU # state when initializing the VMSA structures, which will @@ -909,14 +922,11 @@ # Since: 2.12 ## { 'struct': 'SevGuestProperties', - 'data': { '*sev-device': 'str', - '*dh-cert-file': 'str', + 'base': 'SevCommonProperties', + 'data': { '*dh-cert-file': 'str', '*session-file': 'str', '*policy': 'uint32', '*handle': 'uint32', - '*cbitpos': 'uint32', - 'reduced-phys-bits': 'uint32', - '*kernel-hashes': 'bool', '*legacy-vm-type': 'bool' } } ## -- cgit v1.2.3 From 7b34df44260b391e33bc3acf1ced30019d9aadf1 Mon Sep 17 00:00:00 2001 From: Brijesh Singh Date: Thu, 30 May 2024 06:16:19 -0500 Subject: i386/sev: Introduce 'sev-snp-guest' object SEV-SNP support relies on a different set of properties/state than the existing 'sev-guest' object. This patch introduces the 'sev-snp-guest' object, which can be used to configure an SEV-SNP guest. For example, a default-configured SEV-SNP guest with no additional information passed in for use with attestation: -object sev-snp-guest,id=sev0 or a fully-specified SEV-SNP guest where all spec-defined binary blobs are passed in as base64-encoded strings: -object sev-snp-guest,id=sev0, \ policy=0x30000, \ init-flags=0, \ id-block=YWFhYWFhYWFhYWFhYWFhCg==, \ id-auth=CxHK/OKLkXGn/KpAC7Wl1FSiisWDbGTEKz..., \ author-key-enabled=on, \ host-data=LNkCWBRC5CcdGXirbNUV1OrsR28s..., \ guest-visible-workarounds=AA==, \ See the QAPI schema updates included in this patch for more usage details. In some cases these blobs may be up to 4096 characters, but this is generally well below the default limit for linux hosts where command-line sizes are defined by the sysconf-configurable ARG_MAX value, which defaults to 2097152 characters for Ubuntu hosts, for example. Signed-off-by: Brijesh Singh Co-developed-by: Michael Roth Acked-by: Markus Armbruster (for QAPI schema) Signed-off-by: Michael Roth Co-developed-by: Pankaj Gupta Signed-off-by: Pankaj Gupta Message-ID: <20240530111643.1091816-8-pankaj.gupta@amd.com> Signed-off-by: Paolo Bonzini --- qapi/qom.json | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) (limited to 'qapi') diff --git a/qapi/qom.json b/qapi/qom.json index 056b38f491..8bd299265e 100644 --- a/qapi/qom.json +++ b/qapi/qom.json @@ -929,6 +929,62 @@ '*handle': 'uint32', '*legacy-vm-type': 'bool' } } +## +# @SevSnpGuestProperties: +# +# Properties for sev-snp-guest objects. Most of these are direct +# arguments for the KVM_SNP_* interfaces documented in the Linux +# kernel source under +# Documentation/arch/x86/amd-memory-encryption.rst, which are in turn +# closely coupled with the SNP_INIT/SNP_LAUNCH_* firmware commands +# documented in the SEV-SNP Firmware ABI Specification (Rev 0.9). +# +# More usage information is also available in the QEMU source tree +# under docs/amd-memory-encryption. +# +# @policy: the 'POLICY' parameter to the SNP_LAUNCH_START command, as +# defined in the SEV-SNP firmware ABI (default: 0x30000) +# +# @guest-visible-workarounds: 16-byte, base64-encoded blob to report +# hypervisor-defined workarounds, corresponding to the 'GOSVW' +# parameter of the SNP_LAUNCH_START command defined in the SEV-SNP +# firmware ABI (default: all-zero) +# +# @id-block: 96-byte, base64-encoded blob to provide the 'ID Block' +# structure for the SNP_LAUNCH_FINISH command defined in the +# SEV-SNP firmware ABI (default: all-zero) +# +# @id-auth: 4096-byte, base64-encoded blob to provide the 'ID +# Authentication Information Structure' for the SNP_LAUNCH_FINISH +# command defined in the SEV-SNP firmware ABI (default: all-zero) +# +# @author-key-enabled: true if 'id-auth' blob contains the 'AUTHOR_KEY' +# field defined SEV-SNP firmware ABI (default: false) +# +# @host-data: 32-byte, base64-encoded, user-defined blob to provide to +# the guest, as documented for the 'HOST_DATA' parameter of the +# SNP_LAUNCH_FINISH command in the SEV-SNP firmware ABI (default: +# all-zero) +# +# @vcek-disabled: Guests are by default allowed to choose between VLEK +# (Versioned Loaded Endorsement Key) or VCEK (Versioned Chip +# Endorsement Key) when requesting attestation reports from +# firmware. Set this to true to disable the use of VCEK. +# (default: false) (since: 9.1) +# +# Since: 9.1 +## +{ 'struct': 'SevSnpGuestProperties', + 'base': 'SevCommonProperties', + 'data': { + '*policy': 'uint64', + '*guest-visible-workarounds': 'str', + '*id-block': 'str', + '*id-auth': 'str', + '*author-key-enabled': 'bool', + '*host-data': 'str', + '*vcek-disabled': 'bool' } } + ## # @ThreadContextProperties: # @@ -1007,6 +1063,7 @@ { 'name': 'secret_keyring', 'if': 'CONFIG_SECRET_KEYRING' }, 'sev-guest', + 'sev-snp-guest', 'thread-context', 's390-pv-guest', 'throttle-group', @@ -1077,6 +1134,7 @@ 'secret_keyring': { 'type': 'SecretKeyringProperties', 'if': 'CONFIG_SECRET_KEYRING' }, 'sev-guest': 'SevGuestProperties', + 'sev-snp-guest': 'SevSnpGuestProperties', 'thread-context': 'ThreadContextProperties', 'throttle-group': 'ThrottleGroupProperties', 'tls-creds-anon': 'TlsCredsAnonProperties', -- cgit v1.2.3 From 59d3740cb4ac0f010ce35877572904f6297284b4 Mon Sep 17 00:00:00 2001 From: Michael Roth Date: Thu, 30 May 2024 06:16:26 -0500 Subject: i386/sev: Update query-sev QAPI format to handle SEV-SNP Most of the current 'query-sev' command is relevant to both legacy SEV/SEV-ES guests and SEV-SNP guests, with 2 exceptions: - 'policy' is a 64-bit field for SEV-SNP, not 32-bit, and the meaning of the bit positions has changed - 'handle' is not relevant to SEV-SNP To address this, this patch adds a new 'sev-type' field that can be used as a discriminator to select between SEV and SEV-SNP-specific fields/formats without breaking compatibility for existing management tools (so long as management tools that add support for launching SEV-SNP guest update their handling of query-sev appropriately). The corresponding HMP command has also been fixed up similarly. Signed-off-by: Michael Roth Co-developed-by:Pankaj Gupta Signed-off-by: Pankaj Gupta Message-ID: <20240530111643.1091816-15-pankaj.gupta@amd.com> Signed-off-by: Paolo Bonzini --- qapi/misc-target.json | 72 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 58 insertions(+), 14 deletions(-) (limited to 'qapi') diff --git a/qapi/misc-target.json b/qapi/misc-target.json index 4e0a6492a9..2d7d4d89bd 100644 --- a/qapi/misc-target.json +++ b/qapi/misc-target.json @@ -47,6 +47,50 @@ 'send-update', 'receive-update' ], 'if': 'TARGET_I386' } +## +# @SevGuestType: +# +# An enumeration indicating the type of SEV guest being run. +# +# @sev: The guest is a legacy SEV or SEV-ES guest. +# +# @sev-snp: The guest is an SEV-SNP guest. +# +# Since: 6.2 +## +{ 'enum': 'SevGuestType', + 'data': [ 'sev', 'sev-snp' ], + 'if': 'TARGET_I386' } + +## +# @SevGuestInfo: +# +# Information specific to legacy SEV/SEV-ES guests. +# +# @policy: SEV policy value +# +# @handle: SEV firmware handle +# +# Since: 2.12 +## +{ 'struct': 'SevGuestInfo', + 'data': { 'policy': 'uint32', + 'handle': 'uint32' }, + 'if': 'TARGET_I386' } + +## +# @SevSnpGuestInfo: +# +# Information specific to SEV-SNP guests. +# +# @snp-policy: SEV-SNP policy value +# +# Since: 9.1 +## +{ 'struct': 'SevSnpGuestInfo', + 'data': { 'snp-policy': 'uint64' }, + 'if': 'TARGET_I386' } + ## # @SevInfo: # @@ -60,25 +104,25 @@ # # @build-id: SEV FW build id # -# @policy: SEV policy value -# # @state: SEV guest state # -# @handle: SEV firmware handle +# @sev-type: Type of SEV guest being run # # Since: 2.12 ## -{ 'struct': 'SevInfo', - 'data': { 'enabled': 'bool', - 'api-major': 'uint8', - 'api-minor' : 'uint8', - 'build-id' : 'uint8', - 'policy' : 'uint32', - 'state' : 'SevState', - 'handle' : 'uint32' - }, - 'if': 'TARGET_I386' -} +{ 'union': 'SevInfo', + 'base': { 'enabled': 'bool', + 'api-major': 'uint8', + 'api-minor' : 'uint8', + 'build-id' : 'uint8', + 'state' : 'SevState', + 'sev-type' : 'SevGuestType' }, + 'discriminator': 'sev-type', + 'data': { + 'sev': 'SevGuestInfo', + 'sev-snp': 'SevSnpGuestInfo' }, + 'if': 'TARGET_I386' } + ## # @query-sev: -- cgit v1.2.3