2018-03-08 15:48:41 +03:00
|
|
|
/*
|
|
|
|
* QEMU SEV support
|
|
|
|
*
|
|
|
|
* Copyright Advanced Micro Devices 2016-2018
|
|
|
|
*
|
|
|
|
* Author:
|
|
|
|
* Brijesh Singh <brijesh.singh@amd.com>
|
|
|
|
*
|
|
|
|
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
|
|
|
* See the COPYING file in the top-level directory.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2018-12-04 20:25:35 +03:00
|
|
|
#include "qemu/osdep.h"
|
|
|
|
|
2018-03-08 15:48:44 +03:00
|
|
|
#include <linux/kvm.h>
|
2024-05-30 14:16:43 +03:00
|
|
|
#include <linux/kvm_para.h>
|
2018-03-08 15:48:44 +03:00
|
|
|
#include <linux/psp-sev.h>
|
|
|
|
|
|
|
|
#include <sys/ioctl.h>
|
|
|
|
|
2018-03-08 15:48:41 +03:00
|
|
|
#include "qapi/error.h"
|
|
|
|
#include "qom/object_interfaces.h"
|
|
|
|
#include "qemu/base64.h"
|
2019-05-23 17:35:07 +03:00
|
|
|
#include "qemu/module.h"
|
2021-02-08 17:04:52 +03:00
|
|
|
#include "qemu/uuid.h"
|
2023-03-15 20:43:13 +03:00
|
|
|
#include "qemu/error-report.h"
|
2021-09-30 08:49:14 +03:00
|
|
|
#include "crypto/hash.h"
|
2018-03-08 15:48:41 +03:00
|
|
|
#include "sysemu/kvm.h"
|
2024-03-19 17:30:25 +03:00
|
|
|
#include "kvm/kvm_i386.h"
|
2021-10-07 19:17:07 +03:00
|
|
|
#include "sev.h"
|
2018-03-08 15:48:41 +03:00
|
|
|
#include "sysemu/sysemu.h"
|
2019-08-12 08:23:59 +03:00
|
|
|
#include "sysemu/runstate.h"
|
2018-03-08 15:48:44 +03:00
|
|
|
#include "trace.h"
|
2018-03-08 15:48:57 +03:00
|
|
|
#include "migration/blocker.h"
|
2020-09-03 23:43:22 +03:00
|
|
|
#include "qom/object.h"
|
2020-10-27 20:03:03 +03:00
|
|
|
#include "monitor/monitor.h"
|
2021-10-07 19:17:15 +03:00
|
|
|
#include "monitor/hmp-target.h"
|
2021-10-07 19:17:10 +03:00
|
|
|
#include "qapi/qapi-commands-misc-target.h"
|
2024-03-18 18:07:43 +03:00
|
|
|
#include "confidential-guest.h"
|
2021-02-08 17:04:52 +03:00
|
|
|
#include "hw/i386/pc.h"
|
2021-11-11 13:00:48 +03:00
|
|
|
#include "exec/address-spaces.h"
|
2024-05-30 14:16:27 +03:00
|
|
|
#include "qemu/queue.h"
|
2018-03-08 15:48:41 +03:00
|
|
|
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
OBJECT_DECLARE_TYPE(SevCommonState, SevCommonStateClass, SEV_COMMON)
|
|
|
|
OBJECT_DECLARE_TYPE(SevGuestState, SevCommonStateClass, SEV_GUEST)
|
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 <brijesh.singh@amd.com>
Co-developed-by: Michael Roth <michael.roth@amd.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (for QAPI schema)
Signed-off-by: Michael Roth <michael.roth@amd.com>
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-8-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:19 +03:00
|
|
|
OBJECT_DECLARE_TYPE(SevSnpGuestState, SevCommonStateClass, SEV_SNP_GUEST)
|
2020-06-04 09:42:12 +03:00
|
|
|
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
struct SevCommonState {
|
2024-03-18 18:07:43 +03:00
|
|
|
X86ConfidentialGuest parent_obj;
|
2020-06-04 09:42:12 +03:00
|
|
|
|
2024-03-19 17:30:25 +03:00
|
|
|
int kvm_type;
|
|
|
|
|
2020-06-04 09:42:14 +03:00
|
|
|
/* configuration parameters */
|
2020-06-04 09:42:12 +03:00
|
|
|
char *sev_device;
|
|
|
|
uint32_t cbitpos;
|
|
|
|
uint32_t reduced_phys_bits;
|
2021-11-11 13:00:43 +03:00
|
|
|
bool kernel_hashes;
|
2020-06-04 09:42:12 +03:00
|
|
|
|
2020-06-04 09:42:14 +03:00
|
|
|
/* runtime state */
|
2020-06-04 09:42:19 +03:00
|
|
|
uint8_t api_major;
|
|
|
|
uint8_t api_minor;
|
|
|
|
uint8_t build_id;
|
|
|
|
int sev_fd;
|
|
|
|
SevState state;
|
2021-02-08 17:04:52 +03:00
|
|
|
|
|
|
|
uint32_t reset_cs;
|
|
|
|
uint32_t reset_ip;
|
|
|
|
bool reset_data_valid;
|
2020-06-04 09:42:12 +03:00
|
|
|
};
|
|
|
|
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
struct SevCommonStateClass {
|
|
|
|
X86ConfidentialGuestClass parent_class;
|
|
|
|
|
2024-05-30 14:16:17 +03:00
|
|
|
/* public */
|
|
|
|
int (*launch_start)(SevCommonState *sev_common);
|
2024-05-30 14:16:18 +03:00
|
|
|
void (*launch_finish)(SevCommonState *sev_common);
|
2024-05-31 13:51:44 +03:00
|
|
|
int (*launch_update_data)(SevCommonState *sev_common, hwaddr gpa, uint8_t *ptr, uint64_t len);
|
2024-05-30 14:16:21 +03:00
|
|
|
int (*kvm_init)(ConfidentialGuestSupport *cgs, Error **errp);
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* SevGuestState:
|
|
|
|
*
|
|
|
|
* The SevGuestState object is used for creating and managing a SEV
|
|
|
|
* guest.
|
|
|
|
*
|
|
|
|
* # $QEMU \
|
|
|
|
* -object sev-guest,id=sev0 \
|
|
|
|
* -machine ...,memory-encryption=sev0
|
|
|
|
*/
|
|
|
|
struct SevGuestState {
|
|
|
|
SevCommonState parent_obj;
|
|
|
|
gchar *measurement;
|
|
|
|
|
|
|
|
/* configuration parameters */
|
|
|
|
uint32_t handle;
|
|
|
|
uint32_t policy;
|
|
|
|
char *dh_cert_file;
|
|
|
|
char *session_file;
|
|
|
|
bool legacy_vm_type;
|
|
|
|
};
|
|
|
|
|
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 <brijesh.singh@amd.com>
Co-developed-by: Michael Roth <michael.roth@amd.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (for QAPI schema)
Signed-off-by: Michael Roth <michael.roth@amd.com>
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-8-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:19 +03:00
|
|
|
struct SevSnpGuestState {
|
|
|
|
SevCommonState parent_obj;
|
|
|
|
|
|
|
|
/* configuration parameters */
|
|
|
|
char *guest_visible_workarounds;
|
|
|
|
char *id_block;
|
|
|
|
char *id_auth;
|
|
|
|
char *host_data;
|
|
|
|
|
|
|
|
struct kvm_sev_snp_launch_start kvm_start_conf;
|
|
|
|
struct kvm_sev_snp_launch_finish kvm_finish_conf;
|
|
|
|
};
|
|
|
|
|
2018-03-08 15:48:41 +03:00
|
|
|
#define DEFAULT_GUEST_POLICY 0x1 /* disable debug */
|
|
|
|
#define DEFAULT_SEV_DEVICE "/dev/sev"
|
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 <brijesh.singh@amd.com>
Co-developed-by: Michael Roth <michael.roth@amd.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (for QAPI schema)
Signed-off-by: Michael Roth <michael.roth@amd.com>
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-8-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:19 +03:00
|
|
|
#define DEFAULT_SEV_SNP_POLICY 0x30000
|
2018-03-08 15:48:41 +03:00
|
|
|
|
2024-05-30 14:16:27 +03:00
|
|
|
typedef struct SevLaunchUpdateData {
|
|
|
|
QTAILQ_ENTRY(SevLaunchUpdateData) next;
|
|
|
|
hwaddr gpa;
|
|
|
|
void *hva;
|
|
|
|
uint64_t len;
|
|
|
|
int type;
|
|
|
|
} SevLaunchUpdateData;
|
|
|
|
|
|
|
|
static QTAILQ_HEAD(, SevLaunchUpdateData) launch_update;
|
|
|
|
|
2021-02-08 17:04:52 +03:00
|
|
|
#define SEV_INFO_BLOCK_GUID "00f771de-1a7e-4fcb-890e-68c77e2fb44e"
|
|
|
|
typedef struct __attribute__((__packed__)) SevInfoBlock {
|
|
|
|
/* SEV-ES Reset Vector Address */
|
|
|
|
uint32_t reset_addr;
|
|
|
|
} SevInfoBlock;
|
|
|
|
|
2021-09-30 08:49:14 +03:00
|
|
|
#define SEV_HASH_TABLE_RV_GUID "7255371f-3a3b-4b04-927b-1da6efa8d454"
|
|
|
|
typedef struct QEMU_PACKED SevHashTableDescriptor {
|
|
|
|
/* SEV hash table area guest address */
|
|
|
|
uint32_t base;
|
|
|
|
/* SEV hash table area size (in bytes) */
|
|
|
|
uint32_t size;
|
|
|
|
} SevHashTableDescriptor;
|
|
|
|
|
|
|
|
/* hard code sha256 digest size */
|
|
|
|
#define HASH_SIZE 32
|
|
|
|
|
|
|
|
typedef struct QEMU_PACKED SevHashTableEntry {
|
|
|
|
QemuUUID guid;
|
|
|
|
uint16_t len;
|
|
|
|
uint8_t hash[HASH_SIZE];
|
|
|
|
} SevHashTableEntry;
|
|
|
|
|
|
|
|
typedef struct QEMU_PACKED SevHashTable {
|
|
|
|
QemuUUID guid;
|
|
|
|
uint16_t len;
|
|
|
|
SevHashTableEntry cmdline;
|
|
|
|
SevHashTableEntry initrd;
|
|
|
|
SevHashTableEntry kernel;
|
|
|
|
} SevHashTable;
|
|
|
|
|
2021-11-11 13:00:47 +03:00
|
|
|
/*
|
|
|
|
* Data encrypted by sev_encrypt_flash() must be padded to a multiple of
|
|
|
|
* 16 bytes.
|
|
|
|
*/
|
|
|
|
typedef struct QEMU_PACKED PaddedSevHashTable {
|
|
|
|
SevHashTable ht;
|
|
|
|
uint8_t padding[ROUND_UP(sizeof(SevHashTable), 16) - sizeof(SevHashTable)];
|
|
|
|
} PaddedSevHashTable;
|
|
|
|
|
|
|
|
QEMU_BUILD_BUG_ON(sizeof(PaddedSevHashTable) % 16 != 0);
|
|
|
|
|
2018-03-08 15:48:57 +03:00
|
|
|
static Error *sev_mig_blocker;
|
2018-03-08 15:48:44 +03:00
|
|
|
|
|
|
|
static const char *const sev_fw_errlist[] = {
|
2021-04-30 16:48:29 +03:00
|
|
|
[SEV_RET_SUCCESS] = "",
|
|
|
|
[SEV_RET_INVALID_PLATFORM_STATE] = "Platform state is invalid",
|
|
|
|
[SEV_RET_INVALID_GUEST_STATE] = "Guest state is invalid",
|
|
|
|
[SEV_RET_INAVLID_CONFIG] = "Platform configuration is invalid",
|
|
|
|
[SEV_RET_INVALID_LEN] = "Buffer too small",
|
|
|
|
[SEV_RET_ALREADY_OWNED] = "Platform is already owned",
|
|
|
|
[SEV_RET_INVALID_CERTIFICATE] = "Certificate is invalid",
|
|
|
|
[SEV_RET_POLICY_FAILURE] = "Policy is not allowed",
|
|
|
|
[SEV_RET_INACTIVE] = "Guest is not active",
|
|
|
|
[SEV_RET_INVALID_ADDRESS] = "Invalid address",
|
|
|
|
[SEV_RET_BAD_SIGNATURE] = "Bad signature",
|
|
|
|
[SEV_RET_BAD_MEASUREMENT] = "Bad measurement",
|
|
|
|
[SEV_RET_ASID_OWNED] = "ASID is already owned",
|
|
|
|
[SEV_RET_INVALID_ASID] = "Invalid ASID",
|
|
|
|
[SEV_RET_WBINVD_REQUIRED] = "WBINVD is required",
|
|
|
|
[SEV_RET_DFFLUSH_REQUIRED] = "DF_FLUSH is required",
|
|
|
|
[SEV_RET_INVALID_GUEST] = "Guest handle is invalid",
|
|
|
|
[SEV_RET_INVALID_COMMAND] = "Invalid command",
|
|
|
|
[SEV_RET_ACTIVE] = "Guest is active",
|
|
|
|
[SEV_RET_HWSEV_RET_PLATFORM] = "Hardware error",
|
|
|
|
[SEV_RET_HWSEV_RET_UNSAFE] = "Hardware unsafe",
|
|
|
|
[SEV_RET_UNSUPPORTED] = "Feature not supported",
|
|
|
|
[SEV_RET_INVALID_PARAM] = "Invalid parameter",
|
2021-04-30 16:48:30 +03:00
|
|
|
[SEV_RET_RESOURCE_LIMIT] = "Required firmware resource depleted",
|
|
|
|
[SEV_RET_SECURE_DATA_INVALID] = "Part-specific integrity check failure",
|
2018-03-08 15:48:44 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
#define SEV_FW_MAX_ERROR ARRAY_SIZE(sev_fw_errlist)
|
|
|
|
|
2024-05-30 14:16:32 +03:00
|
|
|
/* <linux/kvm.h> doesn't expose this, so re-use the max from kvm.c */
|
|
|
|
#define KVM_MAX_CPUID_ENTRIES 100
|
|
|
|
|
|
|
|
typedef struct KvmCpuidInfo {
|
|
|
|
struct kvm_cpuid2 cpuid;
|
|
|
|
struct kvm_cpuid_entry2 entries[KVM_MAX_CPUID_ENTRIES];
|
|
|
|
} KvmCpuidInfo;
|
|
|
|
|
|
|
|
#define SNP_CPUID_FUNCTION_MAXCOUNT 64
|
|
|
|
#define SNP_CPUID_FUNCTION_UNKNOWN 0xFFFFFFFF
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
uint32_t eax_in;
|
|
|
|
uint32_t ecx_in;
|
|
|
|
uint64_t xcr0_in;
|
|
|
|
uint64_t xss_in;
|
|
|
|
uint32_t eax;
|
|
|
|
uint32_t ebx;
|
|
|
|
uint32_t ecx;
|
|
|
|
uint32_t edx;
|
|
|
|
uint64_t reserved;
|
|
|
|
} __attribute__((packed)) SnpCpuidFunc;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
uint32_t count;
|
|
|
|
uint32_t reserved1;
|
|
|
|
uint64_t reserved2;
|
|
|
|
SnpCpuidFunc entries[SNP_CPUID_FUNCTION_MAXCOUNT];
|
|
|
|
} __attribute__((packed)) SnpCpuidInfo;
|
|
|
|
|
2018-03-08 15:48:44 +03:00
|
|
|
static int
|
|
|
|
sev_ioctl(int fd, int cmd, void *data, int *error)
|
|
|
|
{
|
|
|
|
int r;
|
|
|
|
struct kvm_sev_cmd input;
|
|
|
|
|
|
|
|
memset(&input, 0x0, sizeof(input));
|
|
|
|
|
|
|
|
input.id = cmd;
|
|
|
|
input.sev_fd = fd;
|
2023-12-13 21:32:45 +03:00
|
|
|
input.data = (uintptr_t)data;
|
2018-03-08 15:48:44 +03:00
|
|
|
|
|
|
|
r = kvm_vm_ioctl(kvm_state, KVM_MEMORY_ENCRYPT_OP, &input);
|
|
|
|
|
|
|
|
if (error) {
|
|
|
|
*error = input.error;
|
|
|
|
}
|
|
|
|
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
sev_platform_ioctl(int fd, int cmd, void *data, int *error)
|
|
|
|
{
|
|
|
|
int r;
|
|
|
|
struct sev_issue_cmd arg;
|
|
|
|
|
|
|
|
arg.cmd = cmd;
|
|
|
|
arg.data = (unsigned long)data;
|
|
|
|
r = ioctl(fd, SEV_ISSUE_CMD, &arg);
|
|
|
|
if (error) {
|
|
|
|
*error = arg.error;
|
|
|
|
}
|
|
|
|
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char *
|
|
|
|
fw_error_to_str(int code)
|
|
|
|
{
|
|
|
|
if (code < 0 || code >= SEV_FW_MAX_ERROR) {
|
|
|
|
return "unknown error";
|
|
|
|
}
|
|
|
|
|
|
|
|
return sev_fw_errlist[code];
|
|
|
|
}
|
|
|
|
|
2018-03-08 15:48:49 +03:00
|
|
|
static bool
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
sev_check_state(const SevCommonState *sev_common, SevState state)
|
2018-03-08 15:48:49 +03:00
|
|
|
{
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
assert(sev_common);
|
|
|
|
return sev_common->state == state ? true : false;
|
2018-03-08 15:48:49 +03:00
|
|
|
}
|
|
|
|
|
2018-03-08 15:48:48 +03:00
|
|
|
static void
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
sev_set_guest_state(SevCommonState *sev_common, SevState new_state)
|
2018-03-08 15:48:48 +03:00
|
|
|
{
|
|
|
|
assert(new_state < SEV_STATE__MAX);
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
assert(sev_common);
|
2018-03-08 15:48:48 +03:00
|
|
|
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
trace_kvm_sev_change_state(SevState_str(sev_common->state),
|
2018-03-08 15:48:48 +03:00
|
|
|
SevState_str(new_state));
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
sev_common->state = new_state;
|
2018-03-08 15:48:48 +03:00
|
|
|
}
|
|
|
|
|
2018-03-08 15:48:45 +03:00
|
|
|
static void
|
2021-04-29 14:27:00 +03:00
|
|
|
sev_ram_block_added(RAMBlockNotifier *n, void *host, size_t size,
|
|
|
|
size_t max_size)
|
2018-03-08 15:48:45 +03:00
|
|
|
{
|
|
|
|
int r;
|
|
|
|
struct kvm_enc_region range;
|
2019-02-05 01:23:40 +03:00
|
|
|
ram_addr_t offset;
|
|
|
|
MemoryRegion *mr;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The RAM device presents a memory region that should be treated
|
|
|
|
* as IO region and should not be pinned.
|
|
|
|
*/
|
|
|
|
mr = memory_region_from_host(host, &offset);
|
|
|
|
if (mr && memory_region_is_ram_device(mr)) {
|
|
|
|
return;
|
|
|
|
}
|
2018-03-08 15:48:45 +03:00
|
|
|
|
2023-12-13 21:32:45 +03:00
|
|
|
range.addr = (uintptr_t)host;
|
2021-04-29 14:27:00 +03:00
|
|
|
range.size = max_size;
|
2018-03-08 15:48:45 +03:00
|
|
|
|
2021-04-29 14:27:00 +03:00
|
|
|
trace_kvm_memcrypt_register_region(host, max_size);
|
2018-03-08 15:48:45 +03:00
|
|
|
r = kvm_vm_ioctl(kvm_state, KVM_MEMORY_ENCRYPT_REG_REGION, &range);
|
|
|
|
if (r) {
|
|
|
|
error_report("%s: failed to register region (%p+%#zx) error '%s'",
|
2021-04-29 14:27:00 +03:00
|
|
|
__func__, host, max_size, strerror(errno));
|
2018-03-08 15:48:45 +03:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2021-04-29 14:27:00 +03:00
|
|
|
sev_ram_block_removed(RAMBlockNotifier *n, void *host, size_t size,
|
|
|
|
size_t max_size)
|
2018-03-08 15:48:45 +03:00
|
|
|
{
|
|
|
|
int r;
|
|
|
|
struct kvm_enc_region range;
|
2019-07-15 17:28:39 +03:00
|
|
|
ram_addr_t offset;
|
|
|
|
MemoryRegion *mr;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The RAM device presents a memory region that should be treated
|
|
|
|
* as IO region and should not have been pinned.
|
|
|
|
*/
|
|
|
|
mr = memory_region_from_host(host, &offset);
|
|
|
|
if (mr && memory_region_is_ram_device(mr)) {
|
|
|
|
return;
|
|
|
|
}
|
2018-03-08 15:48:45 +03:00
|
|
|
|
2023-12-13 21:32:45 +03:00
|
|
|
range.addr = (uintptr_t)host;
|
2021-04-29 14:27:00 +03:00
|
|
|
range.size = max_size;
|
2018-03-08 15:48:45 +03:00
|
|
|
|
2021-04-29 14:27:00 +03:00
|
|
|
trace_kvm_memcrypt_unregister_region(host, max_size);
|
2018-03-08 15:48:45 +03:00
|
|
|
r = kvm_vm_ioctl(kvm_state, KVM_MEMORY_ENCRYPT_UNREG_REGION, &range);
|
|
|
|
if (r) {
|
|
|
|
error_report("%s: failed to unregister region (%p+%#zx)",
|
2021-04-29 14:27:00 +03:00
|
|
|
__func__, host, max_size);
|
2018-03-08 15:48:45 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct RAMBlockNotifier sev_ram_notifier = {
|
|
|
|
.ram_block_added = sev_ram_block_added,
|
|
|
|
.ram_block_removed = sev_ram_block_removed,
|
|
|
|
};
|
|
|
|
|
2018-03-08 15:48:44 +03:00
|
|
|
bool
|
|
|
|
sev_enabled(void)
|
|
|
|
{
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
ConfidentialGuestSupport *cgs = MACHINE(qdev_get_machine())->cgs;
|
|
|
|
|
|
|
|
return !!object_dynamic_cast(OBJECT(cgs), TYPE_SEV_COMMON);
|
2018-03-08 15:48:44 +03:00
|
|
|
}
|
|
|
|
|
2024-05-30 14:16:20 +03:00
|
|
|
bool
|
|
|
|
sev_snp_enabled(void)
|
|
|
|
{
|
|
|
|
ConfidentialGuestSupport *cgs = MACHINE(qdev_get_machine())->cgs;
|
|
|
|
|
|
|
|
return !!object_dynamic_cast(OBJECT(cgs), TYPE_SEV_SNP_GUEST);
|
|
|
|
}
|
|
|
|
|
2021-01-26 20:36:44 +03:00
|
|
|
bool
|
|
|
|
sev_es_enabled(void)
|
|
|
|
{
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
ConfidentialGuestSupport *cgs = MACHINE(qdev_get_machine())->cgs;
|
|
|
|
|
2024-05-30 14:16:20 +03:00
|
|
|
return sev_snp_enabled() ||
|
|
|
|
(sev_enabled() && SEV_GUEST(cgs)->policy & SEV_POLICY_ES);
|
2021-01-26 20:36:44 +03:00
|
|
|
}
|
|
|
|
|
2018-03-08 15:48:44 +03:00
|
|
|
uint32_t
|
|
|
|
sev_get_cbit_position(void)
|
|
|
|
{
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs);
|
|
|
|
|
|
|
|
return sev_common ? sev_common->cbitpos : 0;
|
2018-03-08 15:48:44 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t
|
|
|
|
sev_get_reduced_phys_bits(void)
|
|
|
|
{
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs);
|
|
|
|
|
|
|
|
return sev_common ? sev_common->reduced_phys_bits : 0;
|
2018-03-08 15:48:44 +03:00
|
|
|
}
|
|
|
|
|
2021-10-07 19:17:14 +03:00
|
|
|
static SevInfo *sev_get_info(void)
|
2018-03-08 15:48:44 +03:00
|
|
|
{
|
|
|
|
SevInfo *info;
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs);
|
2018-03-08 15:48:44 +03:00
|
|
|
|
|
|
|
info = g_new0(SevInfo, 1);
|
2020-06-04 09:42:15 +03:00
|
|
|
info->enabled = sev_enabled();
|
2018-03-08 15:48:44 +03:00
|
|
|
|
|
|
|
if (info->enabled) {
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
info->api_major = sev_common->api_major;
|
|
|
|
info->api_minor = sev_common->api_minor;
|
|
|
|
info->build_id = sev_common->build_id;
|
|
|
|
info->state = sev_common->state;
|
2024-05-30 14:16:26 +03:00
|
|
|
|
|
|
|
if (sev_snp_enabled()) {
|
|
|
|
info->sev_type = SEV_GUEST_TYPE_SEV_SNP;
|
|
|
|
info->u.sev_snp.snp_policy =
|
|
|
|
object_property_get_uint(OBJECT(sev_common), "policy", NULL);
|
|
|
|
} else {
|
|
|
|
info->sev_type = SEV_GUEST_TYPE_SEV;
|
|
|
|
info->u.sev.handle = SEV_GUEST(sev_common)->handle;
|
|
|
|
info->u.sev.policy =
|
|
|
|
(uint32_t)object_property_get_uint(OBJECT(sev_common),
|
|
|
|
"policy", NULL);
|
|
|
|
}
|
2018-03-08 15:48:44 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return info;
|
|
|
|
}
|
|
|
|
|
2021-10-07 19:17:14 +03:00
|
|
|
SevInfo *qmp_query_sev(Error **errp)
|
|
|
|
{
|
|
|
|
SevInfo *info;
|
|
|
|
|
|
|
|
info = sev_get_info();
|
|
|
|
if (!info) {
|
|
|
|
error_setg(errp, "SEV feature is not available");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return info;
|
|
|
|
}
|
|
|
|
|
|
|
|
void hmp_info_sev(Monitor *mon, const QDict *qdict)
|
|
|
|
{
|
|
|
|
SevInfo *info = sev_get_info();
|
|
|
|
|
2024-05-30 14:16:26 +03:00
|
|
|
if (!info || !info->enabled) {
|
|
|
|
monitor_printf(mon, "SEV is not enabled\n");
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
monitor_printf(mon, "SEV type: %s\n", SevGuestType_str(info->sev_type));
|
|
|
|
monitor_printf(mon, "state: %s\n", SevState_str(info->state));
|
|
|
|
monitor_printf(mon, "build: %d\n", info->build_id);
|
|
|
|
monitor_printf(mon, "api version: %d.%d\n", info->api_major,
|
|
|
|
info->api_minor);
|
|
|
|
|
|
|
|
if (sev_snp_enabled()) {
|
2021-10-07 19:17:14 +03:00
|
|
|
monitor_printf(mon, "debug: %s\n",
|
2024-05-30 14:16:26 +03:00
|
|
|
info->u.sev_snp.snp_policy & SEV_SNP_POLICY_DBG ? "on"
|
|
|
|
: "off");
|
|
|
|
monitor_printf(mon, "SMT allowed: %s\n",
|
|
|
|
info->u.sev_snp.snp_policy & SEV_SNP_POLICY_SMT ? "on"
|
|
|
|
: "off");
|
2021-10-07 19:17:14 +03:00
|
|
|
} else {
|
2024-05-30 14:16:26 +03:00
|
|
|
monitor_printf(mon, "handle: %d\n", info->u.sev.handle);
|
|
|
|
monitor_printf(mon, "debug: %s\n",
|
|
|
|
info->u.sev.policy & SEV_POLICY_NODBG ? "off" : "on");
|
|
|
|
monitor_printf(mon, "key-sharing: %s\n",
|
|
|
|
info->u.sev.policy & SEV_POLICY_NOKS ? "off" : "on");
|
2021-10-07 19:17:14 +03:00
|
|
|
}
|
|
|
|
|
2024-05-30 14:16:26 +03:00
|
|
|
out:
|
2021-10-07 19:17:14 +03:00
|
|
|
qapi_free_SevInfo(info);
|
|
|
|
}
|
|
|
|
|
2018-03-08 15:49:00 +03:00
|
|
|
static int
|
|
|
|
sev_get_pdh_info(int fd, guchar **pdh, size_t *pdh_len, guchar **cert_chain,
|
2020-06-30 18:35:46 +03:00
|
|
|
size_t *cert_chain_len, Error **errp)
|
2018-03-08 15:49:00 +03:00
|
|
|
{
|
2018-04-27 16:11:26 +03:00
|
|
|
guchar *pdh_data = NULL;
|
|
|
|
guchar *cert_chain_data = NULL;
|
2018-03-08 15:49:00 +03:00
|
|
|
struct sev_user_data_pdh_cert_export export = {};
|
|
|
|
int err, r;
|
|
|
|
|
|
|
|
/* query the certificate length */
|
|
|
|
r = sev_platform_ioctl(fd, SEV_PDH_CERT_EXPORT, &export, &err);
|
|
|
|
if (r < 0) {
|
|
|
|
if (err != SEV_RET_INVALID_LEN) {
|
2021-10-07 19:16:58 +03:00
|
|
|
error_setg(errp, "SEV: Failed to export PDH cert"
|
|
|
|
" ret=%d fw_err=%d (%s)",
|
2020-06-30 18:35:46 +03:00
|
|
|
r, err, fw_error_to_str(err));
|
2018-03-08 15:49:00 +03:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pdh_data = g_new(guchar, export.pdh_cert_len);
|
|
|
|
cert_chain_data = g_new(guchar, export.cert_chain_len);
|
|
|
|
export.pdh_cert_address = (unsigned long)pdh_data;
|
|
|
|
export.cert_chain_address = (unsigned long)cert_chain_data;
|
|
|
|
|
|
|
|
r = sev_platform_ioctl(fd, SEV_PDH_CERT_EXPORT, &export, &err);
|
|
|
|
if (r < 0) {
|
2021-10-07 19:16:58 +03:00
|
|
|
error_setg(errp, "SEV: Failed to export PDH cert ret=%d fw_err=%d (%s)",
|
2020-06-30 18:35:46 +03:00
|
|
|
r, err, fw_error_to_str(err));
|
2018-03-08 15:49:00 +03:00
|
|
|
goto e_free;
|
|
|
|
}
|
|
|
|
|
|
|
|
*pdh = pdh_data;
|
|
|
|
*pdh_len = export.pdh_cert_len;
|
|
|
|
*cert_chain = cert_chain_data;
|
|
|
|
*cert_chain_len = export.cert_chain_len;
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
e_free:
|
|
|
|
g_free(pdh_data);
|
|
|
|
g_free(cert_chain_data);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2022-02-28 12:30:14 +03:00
|
|
|
static int sev_get_cpu0_id(int fd, guchar **id, size_t *id_len, Error **errp)
|
|
|
|
{
|
|
|
|
guchar *id_data;
|
|
|
|
struct sev_user_data_get_id2 get_id2 = {};
|
|
|
|
int err, r;
|
|
|
|
|
|
|
|
/* query the ID length */
|
|
|
|
r = sev_platform_ioctl(fd, SEV_GET_ID2, &get_id2, &err);
|
|
|
|
if (r < 0 && err != SEV_RET_INVALID_LEN) {
|
|
|
|
error_setg(errp, "SEV: Failed to get ID ret=%d fw_err=%d (%s)",
|
|
|
|
r, err, fw_error_to_str(err));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
id_data = g_new(guchar, get_id2.length);
|
|
|
|
get_id2.address = (unsigned long)id_data;
|
|
|
|
|
|
|
|
r = sev_platform_ioctl(fd, SEV_GET_ID2, &get_id2, &err);
|
|
|
|
if (r < 0) {
|
|
|
|
error_setg(errp, "SEV: Failed to get ID ret=%d fw_err=%d (%s)",
|
|
|
|
r, err, fw_error_to_str(err));
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
*id = id_data;
|
|
|
|
*id_len = get_id2.length;
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
err:
|
|
|
|
g_free(id_data);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2021-10-07 19:17:12 +03:00
|
|
|
static SevCapability *sev_get_capabilities(Error **errp)
|
2018-03-08 15:49:00 +03:00
|
|
|
{
|
2018-04-27 16:11:26 +03:00
|
|
|
SevCapability *cap = NULL;
|
|
|
|
guchar *pdh_data = NULL;
|
|
|
|
guchar *cert_chain_data = NULL;
|
2022-02-28 12:30:14 +03:00
|
|
|
guchar *cpu0_id_data = NULL;
|
|
|
|
size_t pdh_len = 0, cert_chain_len = 0, cpu0_id_len = 0;
|
2018-03-08 15:49:00 +03:00
|
|
|
uint32_t ebx;
|
|
|
|
int fd;
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
SevCommonState *sev_common;
|
|
|
|
char *sev_device;
|
2018-03-08 15:49:00 +03:00
|
|
|
|
2020-06-30 18:38:18 +03:00
|
|
|
if (!kvm_enabled()) {
|
|
|
|
error_setg(errp, "KVM not enabled");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
if (kvm_vm_ioctl(kvm_state, KVM_MEMORY_ENCRYPT_OP, NULL) < 0) {
|
|
|
|
error_setg(errp, "SEV is not enabled in KVM");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs);
|
|
|
|
if (!sev_common) {
|
|
|
|
error_setg(errp, "SEV is not configured");
|
|
|
|
}
|
|
|
|
|
|
|
|
sev_device = object_property_get_str(OBJECT(sev_common), "sev-device",
|
|
|
|
&error_abort);
|
|
|
|
fd = open(sev_device, O_RDWR);
|
2018-03-08 15:49:00 +03:00
|
|
|
if (fd < 0) {
|
2021-10-07 19:16:58 +03:00
|
|
|
error_setg_errno(errp, errno, "SEV: Failed to open %s",
|
2020-06-30 18:35:46 +03:00
|
|
|
DEFAULT_SEV_DEVICE);
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
g_free(sev_device);
|
2018-03-08 15:49:00 +03:00
|
|
|
return NULL;
|
|
|
|
}
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
g_free(sev_device);
|
2018-03-08 15:49:00 +03:00
|
|
|
|
|
|
|
if (sev_get_pdh_info(fd, &pdh_data, &pdh_len,
|
2020-06-30 18:35:46 +03:00
|
|
|
&cert_chain_data, &cert_chain_len, errp)) {
|
2018-04-27 16:11:26 +03:00
|
|
|
goto out;
|
2018-03-08 15:49:00 +03:00
|
|
|
}
|
|
|
|
|
2022-02-28 12:30:14 +03:00
|
|
|
if (sev_get_cpu0_id(fd, &cpu0_id_data, &cpu0_id_len, errp)) {
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2018-03-08 15:49:00 +03:00
|
|
|
cap = g_new0(SevCapability, 1);
|
|
|
|
cap->pdh = g_base64_encode(pdh_data, pdh_len);
|
|
|
|
cap->cert_chain = g_base64_encode(cert_chain_data, cert_chain_len);
|
2022-02-28 12:30:14 +03:00
|
|
|
cap->cpu0_id = g_base64_encode(cpu0_id_data, cpu0_id_len);
|
2018-03-08 15:49:00 +03:00
|
|
|
|
|
|
|
host_cpuid(0x8000001F, 0, NULL, &ebx, NULL, NULL);
|
|
|
|
cap->cbitpos = ebx & 0x3f;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* When SEV feature is enabled, we loose one bit in guest physical
|
|
|
|
* addressing.
|
|
|
|
*/
|
|
|
|
cap->reduced_phys_bits = 1;
|
|
|
|
|
2018-04-27 16:11:26 +03:00
|
|
|
out:
|
2022-02-28 12:30:14 +03:00
|
|
|
g_free(cpu0_id_data);
|
2018-03-08 15:49:00 +03:00
|
|
|
g_free(pdh_data);
|
|
|
|
g_free(cert_chain_data);
|
|
|
|
close(fd);
|
|
|
|
return cap;
|
|
|
|
}
|
|
|
|
|
2021-10-07 19:17:12 +03:00
|
|
|
SevCapability *qmp_query_sev_capabilities(Error **errp)
|
|
|
|
{
|
|
|
|
return sev_get_capabilities(errp);
|
|
|
|
}
|
|
|
|
|
2024-05-30 14:16:30 +03:00
|
|
|
static OvmfSevMetadata *ovmf_sev_metadata_table;
|
|
|
|
|
|
|
|
#define OVMF_SEV_META_DATA_GUID "dc886566-984a-4798-A75e-5585a7bf67cc"
|
|
|
|
typedef struct __attribute__((__packed__)) OvmfSevMetadataOffset {
|
|
|
|
uint32_t offset;
|
|
|
|
} OvmfSevMetadataOffset;
|
|
|
|
|
|
|
|
OvmfSevMetadata *pc_system_get_ovmf_sev_metadata_ptr(void)
|
|
|
|
{
|
|
|
|
return ovmf_sev_metadata_table;
|
|
|
|
}
|
|
|
|
|
|
|
|
void pc_system_parse_sev_metadata(uint8_t *flash_ptr, size_t flash_size)
|
|
|
|
{
|
|
|
|
OvmfSevMetadata *metadata;
|
|
|
|
OvmfSevMetadataOffset *data;
|
|
|
|
|
|
|
|
if (!pc_system_ovmf_table_find(OVMF_SEV_META_DATA_GUID, (uint8_t **)&data,
|
|
|
|
NULL)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
metadata = (OvmfSevMetadata *)(flash_ptr + flash_size - data->offset);
|
|
|
|
if (memcmp(metadata->signature, "ASEV", 4) != 0 ||
|
|
|
|
metadata->len < sizeof(OvmfSevMetadata) ||
|
|
|
|
metadata->len > flash_size - data->offset) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ovmf_sev_metadata_table = g_memdup2(metadata, metadata->len);
|
|
|
|
}
|
|
|
|
|
2021-10-07 19:17:10 +03:00
|
|
|
static SevAttestationReport *sev_get_attestation_report(const char *mnonce,
|
|
|
|
Error **errp)
|
2021-04-29 20:07:28 +03:00
|
|
|
{
|
|
|
|
struct kvm_sev_attestation_report input = {};
|
|
|
|
SevAttestationReport *report = NULL;
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
SevCommonState *sev_common;
|
2021-10-07 19:17:04 +03:00
|
|
|
g_autofree guchar *data = NULL;
|
|
|
|
g_autofree guchar *buf = NULL;
|
2021-04-29 20:07:28 +03:00
|
|
|
gsize len;
|
|
|
|
int err = 0, ret;
|
|
|
|
|
|
|
|
if (!sev_enabled()) {
|
|
|
|
error_setg(errp, "SEV is not enabled");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* lets decode the mnonce string */
|
|
|
|
buf = g_base64_decode(mnonce, &len);
|
|
|
|
if (!buf) {
|
|
|
|
error_setg(errp, "SEV: failed to decode mnonce input");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* verify the input mnonce length */
|
|
|
|
if (len != sizeof(input.mnonce)) {
|
|
|
|
error_setg(errp, "SEV: mnonce must be %zu bytes (got %" G_GSIZE_FORMAT ")",
|
|
|
|
sizeof(input.mnonce), len);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs);
|
|
|
|
|
2021-04-29 20:07:28 +03:00
|
|
|
/* Query the report length */
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
ret = sev_ioctl(sev_common->sev_fd, KVM_SEV_GET_ATTESTATION_REPORT,
|
2021-04-29 20:07:28 +03:00
|
|
|
&input, &err);
|
|
|
|
if (ret < 0) {
|
|
|
|
if (err != SEV_RET_INVALID_LEN) {
|
2021-10-07 19:16:58 +03:00
|
|
|
error_setg(errp, "SEV: Failed to query the attestation report"
|
|
|
|
" length ret=%d fw_err=%d (%s)",
|
|
|
|
ret, err, fw_error_to_str(err));
|
2021-04-29 20:07:28 +03:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
data = g_malloc(input.len);
|
|
|
|
input.uaddr = (unsigned long)data;
|
|
|
|
memcpy(input.mnonce, buf, sizeof(input.mnonce));
|
|
|
|
|
|
|
|
/* Query the report */
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
ret = sev_ioctl(sev_common->sev_fd, KVM_SEV_GET_ATTESTATION_REPORT,
|
2021-04-29 20:07:28 +03:00
|
|
|
&input, &err);
|
|
|
|
if (ret) {
|
2021-10-07 19:16:58 +03:00
|
|
|
error_setg_errno(errp, errno, "SEV: Failed to get attestation report"
|
2021-04-29 20:07:28 +03:00
|
|
|
" ret=%d fw_err=%d (%s)", ret, err, fw_error_to_str(err));
|
2021-10-07 19:17:04 +03:00
|
|
|
return NULL;
|
2021-04-29 20:07:28 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
report = g_new0(SevAttestationReport, 1);
|
|
|
|
report->data = g_base64_encode(data, input.len);
|
|
|
|
|
|
|
|
trace_kvm_sev_attestation_report(mnonce, report->data);
|
|
|
|
|
|
|
|
return report;
|
|
|
|
}
|
|
|
|
|
2021-10-07 19:17:10 +03:00
|
|
|
SevAttestationReport *qmp_query_sev_attestation_report(const char *mnonce,
|
|
|
|
Error **errp)
|
|
|
|
{
|
|
|
|
return sev_get_attestation_report(mnonce, errp);
|
|
|
|
}
|
|
|
|
|
2018-03-08 15:48:48 +03:00
|
|
|
static int
|
|
|
|
sev_read_file_base64(const char *filename, guchar **data, gsize *len)
|
|
|
|
{
|
|
|
|
gsize sz;
|
2021-08-20 19:56:50 +03:00
|
|
|
g_autofree gchar *base64 = NULL;
|
2018-03-08 15:48:48 +03:00
|
|
|
GError *error = NULL;
|
|
|
|
|
|
|
|
if (!g_file_get_contents(filename, &base64, &sz, &error)) {
|
2021-10-07 19:16:58 +03:00
|
|
|
error_report("SEV: Failed to read '%s' (%s)", filename, error->message);
|
2020-08-31 16:43:09 +03:00
|
|
|
g_error_free(error);
|
2018-03-08 15:48:48 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
*data = g_base64_decode(base64, len);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2024-05-30 14:16:27 +03:00
|
|
|
static int
|
|
|
|
sev_snp_launch_start(SevCommonState *sev_common)
|
|
|
|
{
|
|
|
|
int fw_error, rc;
|
|
|
|
SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(sev_common);
|
|
|
|
struct kvm_sev_snp_launch_start *start = &sev_snp_guest->kvm_start_conf;
|
|
|
|
|
|
|
|
trace_kvm_sev_snp_launch_start(start->policy,
|
|
|
|
sev_snp_guest->guest_visible_workarounds);
|
|
|
|
|
2024-05-30 14:16:43 +03:00
|
|
|
if (!kvm_enable_hypercall(BIT_ULL(KVM_HC_MAP_GPA_RANGE))) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2024-05-30 14:16:27 +03:00
|
|
|
rc = sev_ioctl(sev_common->sev_fd, KVM_SEV_SNP_LAUNCH_START,
|
|
|
|
start, &fw_error);
|
|
|
|
if (rc < 0) {
|
|
|
|
error_report("%s: SNP_LAUNCH_START ret=%d fw_error=%d '%s'",
|
|
|
|
__func__, rc, fw_error, fw_error_to_str(fw_error));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
QTAILQ_INIT(&launch_update);
|
|
|
|
|
|
|
|
sev_set_guest_state(sev_common, SEV_STATE_LAUNCH_UPDATE);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-03-08 15:48:48 +03:00
|
|
|
static int
|
2024-05-30 14:16:17 +03:00
|
|
|
sev_launch_start(SevCommonState *sev_common)
|
2018-03-08 15:48:48 +03:00
|
|
|
{
|
|
|
|
gsize sz;
|
|
|
|
int ret = 1;
|
2018-04-27 16:11:26 +03:00
|
|
|
int fw_error, rc;
|
2024-05-30 14:16:17 +03:00
|
|
|
SevGuestState *sev_guest = SEV_GUEST(sev_common);
|
2021-10-11 20:30:25 +03:00
|
|
|
struct kvm_sev_launch_start start = {
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
.handle = sev_guest->handle, .policy = sev_guest->policy
|
2021-10-11 20:30:25 +03:00
|
|
|
};
|
2018-03-08 15:48:48 +03:00
|
|
|
guchar *session = NULL, *dh_cert = NULL;
|
|
|
|
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
if (sev_guest->session_file) {
|
|
|
|
if (sev_read_file_base64(sev_guest->session_file, &session, &sz) < 0) {
|
2018-04-27 16:11:26 +03:00
|
|
|
goto out;
|
2018-03-08 15:48:48 +03:00
|
|
|
}
|
2021-10-11 20:30:25 +03:00
|
|
|
start.session_uaddr = (unsigned long)session;
|
|
|
|
start.session_len = sz;
|
2018-03-08 15:48:48 +03:00
|
|
|
}
|
|
|
|
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
if (sev_guest->dh_cert_file) {
|
|
|
|
if (sev_read_file_base64(sev_guest->dh_cert_file, &dh_cert, &sz) < 0) {
|
2018-04-27 16:11:26 +03:00
|
|
|
goto out;
|
2018-03-08 15:48:48 +03:00
|
|
|
}
|
2021-10-11 20:30:25 +03:00
|
|
|
start.dh_uaddr = (unsigned long)dh_cert;
|
|
|
|
start.dh_len = sz;
|
2018-03-08 15:48:48 +03:00
|
|
|
}
|
|
|
|
|
2021-10-11 20:30:25 +03:00
|
|
|
trace_kvm_sev_launch_start(start.policy, session, dh_cert);
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
rc = sev_ioctl(sev_common->sev_fd, KVM_SEV_LAUNCH_START, &start, &fw_error);
|
2018-04-27 16:11:26 +03:00
|
|
|
if (rc < 0) {
|
2018-03-08 15:48:48 +03:00
|
|
|
error_report("%s: LAUNCH_START ret=%d fw_error=%d '%s'",
|
|
|
|
__func__, ret, fw_error, fw_error_to_str(fw_error));
|
2018-04-27 16:11:26 +03:00
|
|
|
goto out;
|
2018-03-08 15:48:48 +03:00
|
|
|
}
|
|
|
|
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
sev_set_guest_state(sev_common, SEV_STATE_LAUNCH_UPDATE);
|
|
|
|
sev_guest->handle = start.handle;
|
2018-04-27 16:11:26 +03:00
|
|
|
ret = 0;
|
2018-03-08 15:48:48 +03:00
|
|
|
|
2018-04-27 16:11:26 +03:00
|
|
|
out:
|
2018-03-08 15:48:48 +03:00
|
|
|
g_free(session);
|
|
|
|
g_free(dh_cert);
|
2018-04-27 16:11:26 +03:00
|
|
|
return ret;
|
2018-03-08 15:48:48 +03:00
|
|
|
}
|
|
|
|
|
2024-05-30 14:16:32 +03:00
|
|
|
static void
|
|
|
|
sev_snp_cpuid_report_mismatches(SnpCpuidInfo *old,
|
|
|
|
SnpCpuidInfo *new)
|
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
if (old->count != new->count) {
|
|
|
|
error_report("SEV-SNP: CPUID validation failed due to count mismatch,"
|
|
|
|
"provided: %d, expected: %d", old->count, new->count);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < old->count; i++) {
|
|
|
|
SnpCpuidFunc *old_func, *new_func;
|
|
|
|
|
|
|
|
old_func = &old->entries[i];
|
|
|
|
new_func = &new->entries[i];
|
|
|
|
|
|
|
|
if (memcmp(old_func, new_func, sizeof(SnpCpuidFunc))) {
|
|
|
|
error_report("SEV-SNP: CPUID validation failed for function 0x%x, index: 0x%x"
|
|
|
|
"provided: eax:0x%08x, ebx: 0x%08x, ecx: 0x%08x, edx: 0x%08x"
|
|
|
|
"expected: eax:0x%08x, ebx: 0x%08x, ecx: 0x%08x, edx: 0x%08x",
|
|
|
|
old_func->eax_in, old_func->ecx_in,
|
|
|
|
old_func->eax, old_func->ebx, old_func->ecx, old_func->edx,
|
|
|
|
new_func->eax, new_func->ebx, new_func->ecx, new_func->edx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-05-30 14:16:28 +03:00
|
|
|
static const char *
|
|
|
|
snp_page_type_to_str(int type)
|
|
|
|
{
|
|
|
|
switch (type) {
|
|
|
|
case KVM_SEV_SNP_PAGE_TYPE_NORMAL: return "Normal";
|
|
|
|
case KVM_SEV_SNP_PAGE_TYPE_ZERO: return "Zero";
|
|
|
|
case KVM_SEV_SNP_PAGE_TYPE_UNMEASURED: return "Unmeasured";
|
|
|
|
case KVM_SEV_SNP_PAGE_TYPE_SECRETS: return "Secrets";
|
|
|
|
case KVM_SEV_SNP_PAGE_TYPE_CPUID: return "Cpuid";
|
|
|
|
default: return "unknown";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
sev_snp_launch_update(SevSnpGuestState *sev_snp_guest,
|
|
|
|
SevLaunchUpdateData *data)
|
|
|
|
{
|
|
|
|
int ret, fw_error;
|
2024-05-30 14:16:32 +03:00
|
|
|
SnpCpuidInfo snp_cpuid_info;
|
2024-05-30 14:16:28 +03:00
|
|
|
struct kvm_sev_snp_launch_update update = {0};
|
|
|
|
|
|
|
|
if (!data->hva || !data->len) {
|
|
|
|
error_report("SNP_LAUNCH_UPDATE called with invalid address"
|
|
|
|
"/ length: %p / %lx",
|
|
|
|
data->hva, data->len);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2024-05-30 14:16:32 +03:00
|
|
|
if (data->type == KVM_SEV_SNP_PAGE_TYPE_CPUID) {
|
|
|
|
/* Save a copy for comparison in case the LAUNCH_UPDATE fails */
|
|
|
|
memcpy(&snp_cpuid_info, data->hva, sizeof(snp_cpuid_info));
|
|
|
|
}
|
|
|
|
|
2024-05-30 14:16:28 +03:00
|
|
|
update.uaddr = (__u64)(unsigned long)data->hva;
|
|
|
|
update.gfn_start = data->gpa >> TARGET_PAGE_BITS;
|
|
|
|
update.len = data->len;
|
|
|
|
update.type = data->type;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* KVM_SEV_SNP_LAUNCH_UPDATE requires that GPA ranges have the private
|
|
|
|
* memory attribute set in advance.
|
|
|
|
*/
|
|
|
|
ret = kvm_set_memory_attributes_private(data->gpa, data->len);
|
|
|
|
if (ret) {
|
|
|
|
error_report("SEV-SNP: failed to configure initial"
|
|
|
|
"private guest memory");
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (update.len || ret == -EAGAIN) {
|
|
|
|
trace_kvm_sev_snp_launch_update(update.uaddr, update.gfn_start <<
|
|
|
|
TARGET_PAGE_BITS, update.len,
|
|
|
|
snp_page_type_to_str(update.type));
|
|
|
|
|
|
|
|
ret = sev_ioctl(SEV_COMMON(sev_snp_guest)->sev_fd,
|
|
|
|
KVM_SEV_SNP_LAUNCH_UPDATE,
|
|
|
|
&update, &fw_error);
|
|
|
|
if (ret && ret != -EAGAIN) {
|
|
|
|
error_report("SNP_LAUNCH_UPDATE ret=%d fw_error=%d '%s'",
|
|
|
|
ret, fw_error, fw_error_to_str(fw_error));
|
2024-05-30 14:16:32 +03:00
|
|
|
|
|
|
|
if (data->type == KVM_SEV_SNP_PAGE_TYPE_CPUID) {
|
|
|
|
sev_snp_cpuid_report_mismatches(&snp_cpuid_info, data->hva);
|
|
|
|
error_report("SEV-SNP: failed update CPUID page");
|
|
|
|
}
|
2024-05-30 14:16:28 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
out:
|
|
|
|
if (!ret && update.gfn_start << TARGET_PAGE_BITS != data->gpa + data->len) {
|
|
|
|
error_report("SEV-SNP: expected update of GPA range %lx-%lx,"
|
|
|
|
"got GPA range %lx-%llx",
|
|
|
|
data->gpa, data->gpa + data->len, data->gpa,
|
|
|
|
update.gfn_start << TARGET_PAGE_BITS);
|
|
|
|
ret = -EIO;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2018-03-08 15:48:49 +03:00
|
|
|
static int
|
2024-05-31 13:51:44 +03:00
|
|
|
sev_launch_update_data(SevCommonState *sev_common, hwaddr gpa, uint8_t *addr, uint64_t len)
|
2018-03-08 15:48:49 +03:00
|
|
|
{
|
|
|
|
int ret, fw_error;
|
|
|
|
struct kvm_sev_launch_update_data update;
|
|
|
|
|
|
|
|
if (!addr || !len) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2023-12-13 21:32:45 +03:00
|
|
|
update.uaddr = (uintptr_t)addr;
|
2018-03-08 15:48:49 +03:00
|
|
|
update.len = len;
|
|
|
|
trace_kvm_sev_launch_update_data(addr, len);
|
2024-05-31 13:51:44 +03:00
|
|
|
ret = sev_ioctl(sev_common->sev_fd, KVM_SEV_LAUNCH_UPDATE_DATA,
|
2018-03-08 15:48:49 +03:00
|
|
|
&update, &fw_error);
|
|
|
|
if (ret) {
|
|
|
|
error_report("%s: LAUNCH_UPDATE ret=%d fw_error=%d '%s'",
|
|
|
|
__func__, ret, fw_error, fw_error_to_str(fw_error));
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2021-01-26 20:36:44 +03:00
|
|
|
static int
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
sev_launch_update_vmsa(SevGuestState *sev_guest)
|
2021-01-26 20:36:44 +03:00
|
|
|
{
|
|
|
|
int ret, fw_error;
|
|
|
|
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
ret = sev_ioctl(SEV_COMMON(sev_guest)->sev_fd, KVM_SEV_LAUNCH_UPDATE_VMSA,
|
|
|
|
NULL, &fw_error);
|
2021-01-26 20:36:44 +03:00
|
|
|
if (ret) {
|
|
|
|
error_report("%s: LAUNCH_UPDATE_VMSA ret=%d fw_error=%d '%s'",
|
|
|
|
__func__, ret, fw_error, fw_error_to_str(fw_error));
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2018-03-08 15:48:51 +03:00
|
|
|
static void
|
|
|
|
sev_launch_get_measure(Notifier *notifier, void *unused)
|
|
|
|
{
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs);
|
|
|
|
SevGuestState *sev_guest = SEV_GUEST(sev_common);
|
2018-03-08 15:48:51 +03:00
|
|
|
int ret, error;
|
2021-10-07 19:17:05 +03:00
|
|
|
g_autofree guchar *data = NULL;
|
2021-10-11 20:30:26 +03:00
|
|
|
struct kvm_sev_launch_measure measurement = {};
|
2018-03-08 15:48:51 +03:00
|
|
|
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
if (!sev_check_state(sev_common, SEV_STATE_LAUNCH_UPDATE)) {
|
2018-03-08 15:48:51 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-01-26 20:36:44 +03:00
|
|
|
if (sev_es_enabled()) {
|
|
|
|
/* measure all the VM save areas before getting launch_measure */
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
ret = sev_launch_update_vmsa(sev_guest);
|
2021-01-26 20:36:44 +03:00
|
|
|
if (ret) {
|
|
|
|
exit(1);
|
|
|
|
}
|
2024-03-18 21:41:10 +03:00
|
|
|
kvm_mark_guest_state_protected();
|
2021-01-26 20:36:44 +03:00
|
|
|
}
|
|
|
|
|
2018-03-08 15:48:51 +03:00
|
|
|
/* query the measurement blob length */
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
ret = sev_ioctl(sev_common->sev_fd, KVM_SEV_LAUNCH_MEASURE,
|
2021-10-11 20:30:26 +03:00
|
|
|
&measurement, &error);
|
|
|
|
if (!measurement.len) {
|
2018-03-08 15:48:51 +03:00
|
|
|
error_report("%s: LAUNCH_MEASURE ret=%d fw_error=%d '%s'",
|
|
|
|
__func__, ret, error, fw_error_to_str(errno));
|
2021-10-07 19:17:05 +03:00
|
|
|
return;
|
2018-03-08 15:48:51 +03:00
|
|
|
}
|
|
|
|
|
2021-10-11 20:30:26 +03:00
|
|
|
data = g_new0(guchar, measurement.len);
|
|
|
|
measurement.uaddr = (unsigned long)data;
|
2018-03-08 15:48:51 +03:00
|
|
|
|
|
|
|
/* get the measurement blob */
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
ret = sev_ioctl(sev_common->sev_fd, KVM_SEV_LAUNCH_MEASURE,
|
2021-10-11 20:30:26 +03:00
|
|
|
&measurement, &error);
|
2018-03-08 15:48:51 +03:00
|
|
|
if (ret) {
|
|
|
|
error_report("%s: LAUNCH_MEASURE ret=%d fw_error=%d '%s'",
|
|
|
|
__func__, ret, error, fw_error_to_str(errno));
|
2021-10-07 19:17:05 +03:00
|
|
|
return;
|
2018-03-08 15:48:51 +03:00
|
|
|
}
|
|
|
|
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
sev_set_guest_state(sev_common, SEV_STATE_LAUNCH_SECRET);
|
2018-03-08 15:48:51 +03:00
|
|
|
|
|
|
|
/* encode the measurement value and emit the event */
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
sev_guest->measurement = g_base64_encode(data, measurement.len);
|
|
|
|
trace_kvm_sev_launch_measurement(sev_guest->measurement);
|
2018-03-08 15:48:51 +03:00
|
|
|
}
|
|
|
|
|
2021-10-07 19:17:13 +03:00
|
|
|
static char *sev_get_launch_measurement(void)
|
2018-03-08 15:48:51 +03:00
|
|
|
{
|
2024-05-30 14:16:24 +03:00
|
|
|
ConfidentialGuestSupport *cgs = MACHINE(qdev_get_machine())->cgs;
|
|
|
|
SevGuestState *sev_guest =
|
|
|
|
(SevGuestState *)object_dynamic_cast(OBJECT(cgs), TYPE_SEV_GUEST);
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
|
2020-06-04 09:42:15 +03:00
|
|
|
if (sev_guest &&
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
SEV_COMMON(sev_guest)->state >= SEV_STATE_LAUNCH_SECRET) {
|
2020-06-04 09:42:19 +03:00
|
|
|
return g_strdup(sev_guest->measurement);
|
2018-03-08 15:48:51 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2021-10-07 19:17:13 +03:00
|
|
|
SevLaunchMeasureInfo *qmp_query_sev_launch_measure(Error **errp)
|
|
|
|
{
|
|
|
|
char *data;
|
|
|
|
SevLaunchMeasureInfo *info;
|
|
|
|
|
|
|
|
data = sev_get_launch_measurement();
|
|
|
|
if (!data) {
|
|
|
|
error_setg(errp, "SEV launch measurement is not available");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
info = g_malloc0(sizeof(*info));
|
|
|
|
info->data = data;
|
|
|
|
|
|
|
|
return info;
|
|
|
|
}
|
|
|
|
|
2018-03-08 15:48:51 +03:00
|
|
|
static Notifier sev_machine_done_notify = {
|
|
|
|
.notify = sev_launch_get_measure,
|
|
|
|
};
|
|
|
|
|
2018-03-08 15:48:52 +03:00
|
|
|
static void
|
2024-05-30 14:16:18 +03:00
|
|
|
sev_launch_finish(SevCommonState *sev_common)
|
2018-03-08 15:48:52 +03:00
|
|
|
{
|
|
|
|
int ret, error;
|
|
|
|
|
|
|
|
trace_kvm_sev_launch_finish();
|
2024-05-30 14:16:18 +03:00
|
|
|
ret = sev_ioctl(sev_common->sev_fd, KVM_SEV_LAUNCH_FINISH, 0,
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
&error);
|
2018-03-08 15:48:52 +03:00
|
|
|
if (ret) {
|
|
|
|
error_report("%s: LAUNCH_FINISH ret=%d fw_error=%d '%s'",
|
|
|
|
__func__, ret, error, fw_error_to_str(error));
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2024-05-30 14:16:18 +03:00
|
|
|
sev_set_guest_state(sev_common, SEV_STATE_RUNNING);
|
2018-03-08 15:48:57 +03:00
|
|
|
|
|
|
|
/* add migration blocker */
|
|
|
|
error_setg(&sev_mig_blocker,
|
|
|
|
"SEV: Migration is not implemented");
|
2023-10-18 16:03:36 +03:00
|
|
|
migrate_add_blocker(&sev_mig_blocker, &error_fatal);
|
2018-03-08 15:48:52 +03:00
|
|
|
}
|
|
|
|
|
2024-05-30 14:16:31 +03:00
|
|
|
static int
|
2024-05-30 14:16:32 +03:00
|
|
|
snp_launch_update_data(uint64_t gpa, void *hva,
|
|
|
|
uint32_t len, int type)
|
2024-05-30 14:16:31 +03:00
|
|
|
{
|
|
|
|
SevLaunchUpdateData *data;
|
|
|
|
|
|
|
|
data = g_new0(SevLaunchUpdateData, 1);
|
|
|
|
data->gpa = gpa;
|
|
|
|
data->hva = hva;
|
|
|
|
data->len = len;
|
|
|
|
data->type = type;
|
|
|
|
|
|
|
|
QTAILQ_INSERT_TAIL(&launch_update, data, next);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2024-05-30 14:16:38 +03:00
|
|
|
static int
|
|
|
|
sev_snp_launch_update_data(SevCommonState *sev_common, hwaddr gpa,
|
|
|
|
uint8_t *ptr, uint64_t len)
|
|
|
|
{
|
|
|
|
int ret = snp_launch_update_data(gpa, ptr, len,
|
|
|
|
KVM_SEV_SNP_PAGE_TYPE_NORMAL);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2024-05-30 14:16:32 +03:00
|
|
|
static int
|
|
|
|
sev_snp_cpuid_info_fill(SnpCpuidInfo *snp_cpuid_info,
|
|
|
|
const KvmCpuidInfo *kvm_cpuid_info)
|
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
if (kvm_cpuid_info->cpuid.nent > SNP_CPUID_FUNCTION_MAXCOUNT) {
|
|
|
|
error_report("SEV-SNP: CPUID entry count (%d) exceeds max (%d)",
|
|
|
|
kvm_cpuid_info->cpuid.nent, SNP_CPUID_FUNCTION_MAXCOUNT);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
memset(snp_cpuid_info, 0, sizeof(*snp_cpuid_info));
|
|
|
|
|
|
|
|
for (i = 0; i < kvm_cpuid_info->cpuid.nent; i++) {
|
|
|
|
const struct kvm_cpuid_entry2 *kvm_cpuid_entry;
|
|
|
|
SnpCpuidFunc *snp_cpuid_entry;
|
|
|
|
|
|
|
|
kvm_cpuid_entry = &kvm_cpuid_info->entries[i];
|
|
|
|
snp_cpuid_entry = &snp_cpuid_info->entries[i];
|
|
|
|
|
|
|
|
snp_cpuid_entry->eax_in = kvm_cpuid_entry->function;
|
|
|
|
if (kvm_cpuid_entry->flags == KVM_CPUID_FLAG_SIGNIFCANT_INDEX) {
|
|
|
|
snp_cpuid_entry->ecx_in = kvm_cpuid_entry->index;
|
|
|
|
}
|
|
|
|
snp_cpuid_entry->eax = kvm_cpuid_entry->eax;
|
|
|
|
snp_cpuid_entry->ebx = kvm_cpuid_entry->ebx;
|
|
|
|
snp_cpuid_entry->ecx = kvm_cpuid_entry->ecx;
|
|
|
|
snp_cpuid_entry->edx = kvm_cpuid_entry->edx;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Guest kernels will calculate EBX themselves using the 0xD
|
|
|
|
* subfunctions corresponding to the individual XSAVE areas, so only
|
|
|
|
* encode the base XSAVE size in the initial leaves, corresponding
|
|
|
|
* to the initial XCR0=1 state.
|
|
|
|
*/
|
|
|
|
if (snp_cpuid_entry->eax_in == 0xD &&
|
|
|
|
(snp_cpuid_entry->ecx_in == 0x0 || snp_cpuid_entry->ecx_in == 0x1)) {
|
|
|
|
snp_cpuid_entry->ebx = 0x240;
|
|
|
|
snp_cpuid_entry->xcr0_in = 1;
|
|
|
|
snp_cpuid_entry->xss_in = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
snp_cpuid_info->count = i;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
snp_launch_update_cpuid(uint32_t cpuid_addr, void *hva, uint32_t cpuid_len)
|
|
|
|
{
|
|
|
|
KvmCpuidInfo kvm_cpuid_info = {0};
|
|
|
|
SnpCpuidInfo snp_cpuid_info;
|
|
|
|
CPUState *cs = first_cpu;
|
|
|
|
int ret;
|
|
|
|
uint32_t i = 0;
|
|
|
|
|
|
|
|
assert(sizeof(snp_cpuid_info) <= cpuid_len);
|
|
|
|
|
|
|
|
/* get the cpuid list from KVM */
|
|
|
|
do {
|
|
|
|
kvm_cpuid_info.cpuid.nent = ++i;
|
|
|
|
ret = kvm_vcpu_ioctl(cs, KVM_GET_CPUID2, &kvm_cpuid_info);
|
|
|
|
} while (ret == -E2BIG);
|
|
|
|
|
|
|
|
if (ret) {
|
|
|
|
error_report("SEV-SNP: unable to query CPUID values for CPU: '%s'",
|
|
|
|
strerror(-ret));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = sev_snp_cpuid_info_fill(&snp_cpuid_info, &kvm_cpuid_info);
|
|
|
|
if (ret) {
|
|
|
|
error_report("SEV-SNP: failed to generate CPUID table information");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
memcpy(hva, &snp_cpuid_info, sizeof(snp_cpuid_info));
|
|
|
|
|
|
|
|
return snp_launch_update_data(cpuid_addr, hva, cpuid_len,
|
|
|
|
KVM_SEV_SNP_PAGE_TYPE_CPUID);
|
|
|
|
}
|
|
|
|
|
2024-05-30 14:16:31 +03:00
|
|
|
static int
|
|
|
|
snp_metadata_desc_to_page_type(int desc_type)
|
|
|
|
{
|
|
|
|
switch (desc_type) {
|
|
|
|
/* Add the umeasured prevalidated pages as a zero page */
|
|
|
|
case SEV_DESC_TYPE_SNP_SEC_MEM: return KVM_SEV_SNP_PAGE_TYPE_ZERO;
|
|
|
|
case SEV_DESC_TYPE_SNP_SECRETS: return KVM_SEV_SNP_PAGE_TYPE_SECRETS;
|
|
|
|
case SEV_DESC_TYPE_CPUID: return KVM_SEV_SNP_PAGE_TYPE_CPUID;
|
|
|
|
default:
|
|
|
|
return KVM_SEV_SNP_PAGE_TYPE_ZERO;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
snp_populate_metadata_pages(SevSnpGuestState *sev_snp,
|
|
|
|
OvmfSevMetadata *metadata)
|
|
|
|
{
|
|
|
|
OvmfSevMetadataDesc *desc;
|
|
|
|
int type, ret, i;
|
|
|
|
void *hva;
|
|
|
|
MemoryRegion *mr = NULL;
|
|
|
|
|
|
|
|
for (i = 0; i < metadata->num_desc; i++) {
|
|
|
|
desc = &metadata->descs[i];
|
|
|
|
|
|
|
|
type = snp_metadata_desc_to_page_type(desc->type);
|
|
|
|
|
|
|
|
hva = gpa2hva(&mr, desc->base, desc->len, NULL);
|
|
|
|
if (!hva) {
|
|
|
|
error_report("%s: Failed to get HVA for GPA 0x%x sz 0x%x",
|
|
|
|
__func__, desc->base, desc->len);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2024-05-30 14:16:32 +03:00
|
|
|
if (type == KVM_SEV_SNP_PAGE_TYPE_CPUID) {
|
|
|
|
ret = snp_launch_update_cpuid(desc->base, hva, desc->len);
|
|
|
|
} else {
|
|
|
|
ret = snp_launch_update_data(desc->base, hva, desc->len, type);
|
|
|
|
}
|
|
|
|
|
2024-05-30 14:16:31 +03:00
|
|
|
if (ret) {
|
|
|
|
error_report("%s: Failed to add metadata page gpa 0x%x+%x type %d",
|
|
|
|
__func__, desc->base, desc->len, desc->type);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-05-30 14:16:28 +03:00
|
|
|
static void
|
|
|
|
sev_snp_launch_finish(SevCommonState *sev_common)
|
|
|
|
{
|
|
|
|
int ret, error;
|
|
|
|
Error *local_err = NULL;
|
2024-05-30 14:16:31 +03:00
|
|
|
OvmfSevMetadata *metadata;
|
2024-05-30 14:16:28 +03:00
|
|
|
SevLaunchUpdateData *data;
|
|
|
|
SevSnpGuestState *sev_snp = SEV_SNP_GUEST(sev_common);
|
|
|
|
struct kvm_sev_snp_launch_finish *finish = &sev_snp->kvm_finish_conf;
|
|
|
|
|
2024-05-30 14:16:31 +03:00
|
|
|
/*
|
|
|
|
* To boot the SNP guest, the hypervisor is required to populate the CPUID
|
|
|
|
* and Secrets page before finalizing the launch flow. The location of
|
|
|
|
* the secrets and CPUID page is available through the OVMF metadata GUID.
|
|
|
|
*/
|
|
|
|
metadata = pc_system_get_ovmf_sev_metadata_ptr();
|
|
|
|
if (metadata == NULL) {
|
|
|
|
error_report("%s: Failed to locate SEV metadata header", __func__);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Populate all the metadata pages */
|
|
|
|
snp_populate_metadata_pages(sev_snp, metadata);
|
|
|
|
|
2024-05-30 14:16:28 +03:00
|
|
|
QTAILQ_FOREACH(data, &launch_update, next) {
|
|
|
|
ret = sev_snp_launch_update(sev_snp, data);
|
|
|
|
if (ret) {
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
trace_kvm_sev_snp_launch_finish(sev_snp->id_block, sev_snp->id_auth,
|
|
|
|
sev_snp->host_data);
|
|
|
|
ret = sev_ioctl(sev_common->sev_fd, KVM_SEV_SNP_LAUNCH_FINISH,
|
|
|
|
finish, &error);
|
|
|
|
if (ret) {
|
|
|
|
error_report("SNP_LAUNCH_FINISH ret=%d fw_error=%d '%s'",
|
|
|
|
ret, error, fw_error_to_str(error));
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2024-05-30 14:16:29 +03:00
|
|
|
kvm_mark_guest_state_protected();
|
2024-05-30 14:16:28 +03:00
|
|
|
sev_set_guest_state(sev_common, SEV_STATE_RUNNING);
|
|
|
|
|
|
|
|
/* add migration blocker */
|
|
|
|
error_setg(&sev_mig_blocker,
|
|
|
|
"SEV-SNP: Migration is not implemented");
|
|
|
|
ret = migrate_add_blocker(&sev_mig_blocker, &local_err);
|
|
|
|
if (local_err) {
|
|
|
|
error_report_err(local_err);
|
|
|
|
error_free(sev_mig_blocker);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-03-08 15:48:52 +03:00
|
|
|
static void
|
2021-01-11 18:20:20 +03:00
|
|
|
sev_vm_state_change(void *opaque, bool running, RunState state)
|
2018-03-08 15:48:52 +03:00
|
|
|
{
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
SevCommonState *sev_common = opaque;
|
2024-05-30 14:16:18 +03:00
|
|
|
SevCommonStateClass *klass = SEV_COMMON_GET_CLASS(opaque);
|
2018-03-08 15:48:52 +03:00
|
|
|
|
|
|
|
if (running) {
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
if (!sev_check_state(sev_common, SEV_STATE_RUNNING)) {
|
2024-05-30 14:16:18 +03:00
|
|
|
klass->launch_finish(sev_common);
|
2018-03-08 15:48:52 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-19 17:30:25 +03:00
|
|
|
static int sev_kvm_type(X86ConfidentialGuest *cg)
|
|
|
|
{
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
SevCommonState *sev_common = SEV_COMMON(cg);
|
|
|
|
SevGuestState *sev_guest = SEV_GUEST(sev_common);
|
2024-03-19 17:30:25 +03:00
|
|
|
int kvm_type;
|
|
|
|
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
if (sev_common->kvm_type != -1) {
|
2024-03-19 17:30:25 +03:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
kvm_type = (sev_guest->policy & SEV_POLICY_ES) ?
|
|
|
|
KVM_X86_SEV_ES_VM : KVM_X86_SEV_VM;
|
|
|
|
if (kvm_is_vm_type_supported(kvm_type) && !sev_guest->legacy_vm_type) {
|
|
|
|
sev_common->kvm_type = kvm_type;
|
2024-03-19 17:30:25 +03:00
|
|
|
} else {
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
sev_common->kvm_type = KVM_X86_DEFAULT_VM;
|
2024-03-19 17:30:25 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
out:
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
return sev_common->kvm_type;
|
2024-03-19 17:30:25 +03:00
|
|
|
}
|
|
|
|
|
2024-05-31 13:44:44 +03:00
|
|
|
static int sev_snp_kvm_type(X86ConfidentialGuest *cg)
|
|
|
|
{
|
|
|
|
return KVM_X86_SNP_VM;
|
|
|
|
}
|
|
|
|
|
2024-05-30 14:16:21 +03:00
|
|
|
static int sev_common_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
|
2018-03-08 15:48:44 +03:00
|
|
|
{
|
|
|
|
char *devname;
|
2021-01-26 20:36:44 +03:00
|
|
|
int ret, fw_error, cmd;
|
2018-03-08 15:48:44 +03:00
|
|
|
uint32_t ebx;
|
|
|
|
uint32_t host_cbitpos;
|
|
|
|
struct sev_user_data_status status = {};
|
2024-05-30 14:16:22 +03:00
|
|
|
SevCommonState *sev_common = SEV_COMMON(cgs);
|
2024-05-30 14:16:17 +03:00
|
|
|
SevCommonStateClass *klass = SEV_COMMON_GET_CLASS(cgs);
|
2024-05-31 13:44:44 +03:00
|
|
|
X86ConfidentialGuestClass *x86_klass =
|
|
|
|
X86_CONFIDENTIAL_GUEST_GET_CLASS(cgs);
|
2018-03-08 15:48:44 +03:00
|
|
|
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
sev_common->state = SEV_STATE_UNINIT;
|
2018-03-08 15:48:44 +03:00
|
|
|
|
|
|
|
host_cpuid(0x8000001F, 0, NULL, &ebx, NULL, NULL);
|
|
|
|
host_cbitpos = ebx & 0x3f;
|
|
|
|
|
2022-09-30 18:14:29 +03:00
|
|
|
/*
|
|
|
|
* The cbitpos value will be placed in bit positions 5:0 of the EBX
|
|
|
|
* register of CPUID 0x8000001F. No need to verify the range as the
|
|
|
|
* comparison against the host value accomplishes that.
|
|
|
|
*/
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
if (host_cbitpos != sev_common->cbitpos) {
|
2020-06-04 07:18:52 +03:00
|
|
|
error_setg(errp, "%s: cbitpos check failed, host '%d' requested '%d'",
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
__func__, host_cbitpos, sev_common->cbitpos);
|
2024-05-30 14:16:21 +03:00
|
|
|
return -1;
|
2018-03-08 15:48:44 +03:00
|
|
|
}
|
|
|
|
|
2022-09-30 18:14:29 +03:00
|
|
|
/*
|
|
|
|
* The reduced-phys-bits value will be placed in bit positions 11:6 of
|
|
|
|
* the EBX register of CPUID 0x8000001F, so verify the supplied value
|
|
|
|
* is in the range of 1 to 63.
|
|
|
|
*/
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
if (sev_common->reduced_phys_bits < 1 ||
|
|
|
|
sev_common->reduced_phys_bits > 63) {
|
2022-09-30 18:14:29 +03:00
|
|
|
error_setg(errp, "%s: reduced_phys_bits check failed,"
|
|
|
|
" it should be in the range of 1 to 63, requested '%d'",
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
__func__, sev_common->reduced_phys_bits);
|
2024-05-30 14:16:21 +03:00
|
|
|
return -1;
|
2018-03-08 15:48:44 +03:00
|
|
|
}
|
|
|
|
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
devname = object_property_get_str(OBJECT(sev_common), "sev-device", NULL);
|
|
|
|
sev_common->sev_fd = open(devname, O_RDWR);
|
|
|
|
if (sev_common->sev_fd < 0) {
|
2020-06-04 07:18:52 +03:00
|
|
|
error_setg(errp, "%s: Failed to open %s '%s'", __func__,
|
|
|
|
devname, strerror(errno));
|
|
|
|
g_free(devname);
|
2024-05-30 14:16:21 +03:00
|
|
|
return -1;
|
2018-03-29 12:10:21 +03:00
|
|
|
}
|
2020-06-04 07:18:52 +03:00
|
|
|
g_free(devname);
|
2018-03-08 15:48:44 +03:00
|
|
|
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
ret = sev_platform_ioctl(sev_common->sev_fd, SEV_PLATFORM_STATUS, &status,
|
2018-03-08 15:48:44 +03:00
|
|
|
&fw_error);
|
|
|
|
if (ret) {
|
2020-06-04 07:18:52 +03:00
|
|
|
error_setg(errp, "%s: failed to get platform status ret=%d "
|
|
|
|
"fw_error='%d: %s'", __func__, ret, fw_error,
|
|
|
|
fw_error_to_str(fw_error));
|
2024-05-30 14:16:21 +03:00
|
|
|
return -1;
|
2018-03-08 15:48:44 +03:00
|
|
|
}
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
sev_common->build_id = status.build;
|
|
|
|
sev_common->api_major = status.api_major;
|
|
|
|
sev_common->api_minor = status.api_minor;
|
2018-03-08 15:48:44 +03:00
|
|
|
|
2021-01-26 20:36:44 +03:00
|
|
|
if (sev_es_enabled()) {
|
2021-01-26 20:36:45 +03:00
|
|
|
if (!kvm_kernel_irqchip_allowed()) {
|
2024-05-30 14:16:13 +03:00
|
|
|
error_setg(errp, "%s: SEV-ES guests require in-kernel irqchip"
|
|
|
|
"support", __func__);
|
2024-05-30 14:16:21 +03:00
|
|
|
return -1;
|
2021-01-26 20:36:45 +03:00
|
|
|
}
|
2024-05-30 14:16:20 +03:00
|
|
|
}
|
2021-01-26 20:36:45 +03:00
|
|
|
|
2024-05-30 14:16:20 +03:00
|
|
|
if (sev_es_enabled() && !sev_snp_enabled()) {
|
2021-01-26 20:36:44 +03:00
|
|
|
if (!(status.flags & SEV_STATUS_FLAGS_CONFIG_ES)) {
|
2024-05-30 14:16:13 +03:00
|
|
|
error_setg(errp, "%s: guest policy requires SEV-ES, but "
|
2021-01-26 20:36:44 +03:00
|
|
|
"host SEV-ES support unavailable",
|
|
|
|
__func__);
|
2024-05-30 14:16:21 +03:00
|
|
|
return -1;
|
2021-01-26 20:36:44 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-08 15:48:44 +03:00
|
|
|
trace_kvm_sev_init();
|
2024-05-31 13:44:44 +03:00
|
|
|
if (x86_klass->kvm_type(X86_CONFIDENTIAL_GUEST(sev_common)) == KVM_X86_DEFAULT_VM) {
|
2024-03-19 17:30:25 +03:00
|
|
|
cmd = sev_es_enabled() ? KVM_SEV_ES_INIT : KVM_SEV_INIT;
|
|
|
|
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
ret = sev_ioctl(sev_common->sev_fd, cmd, NULL, &fw_error);
|
2024-03-19 17:30:25 +03:00
|
|
|
} else {
|
|
|
|
struct kvm_sev_init args = { 0 };
|
|
|
|
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
ret = sev_ioctl(sev_common->sev_fd, KVM_SEV_INIT2, &args, &fw_error);
|
2024-03-19 17:30:25 +03:00
|
|
|
}
|
|
|
|
|
2018-03-08 15:48:44 +03:00
|
|
|
if (ret) {
|
2020-06-04 07:18:52 +03:00
|
|
|
error_setg(errp, "%s: failed to initialize ret=%d fw_error=%d '%s'",
|
|
|
|
__func__, ret, fw_error, fw_error_to_str(fw_error));
|
2024-05-30 14:16:21 +03:00
|
|
|
return -1;
|
2018-03-08 15:48:44 +03:00
|
|
|
}
|
|
|
|
|
2024-05-30 14:16:17 +03:00
|
|
|
ret = klass->launch_start(sev_common);
|
2024-05-30 14:16:27 +03:00
|
|
|
|
2018-03-08 15:48:48 +03:00
|
|
|
if (ret) {
|
2020-06-04 07:18:52 +03:00
|
|
|
error_setg(errp, "%s: failed to create encryption context", __func__);
|
2024-05-30 14:16:21 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (klass->kvm_init && klass->kvm_init(cgs, errp)) {
|
|
|
|
return -1;
|
2018-03-08 15:48:48 +03:00
|
|
|
}
|
|
|
|
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
qemu_add_vm_change_state_handler(sev_vm_state_change, sev_common);
|
2018-03-08 15:48:45 +03:00
|
|
|
|
2020-10-20 09:01:19 +03:00
|
|
|
cgs->ready = true;
|
|
|
|
|
sev: Remove false abstraction of flash encryption
When AMD's SEV memory encryption is in use, flash memory banks (which are
initialed by pc_system_flash_map()) need to be encrypted with the guest's
key, so that the guest can read them.
That's abstracted via the kvm_memcrypt_encrypt_data() callback in the KVM
state.. except, that it doesn't really abstract much at all.
For starters, the only call site is in code specific to the 'pc'
family of machine types, so it's obviously specific to those and to
x86 to begin with. But it makes a bunch of further assumptions that
need not be true about an arbitrary confidential guest system based on
memory encryption, let alone one based on other mechanisms:
* it assumes that the flash memory is defined to be encrypted with the
guest key, rather than being shared with hypervisor
* it assumes that that hypervisor has some mechanism to encrypt data into
the guest, even though it can't decrypt it out, since that's the whole
point
* the interface assumes that this encrypt can be done in place, which
implies that the hypervisor can write into a confidential guests's
memory, even if what it writes isn't meaningful
So really, this "abstraction" is actually pretty specific to the way SEV
works. So, this patch removes it and instead has the PC flash
initialization code call into a SEV specific callback.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
2021-01-12 03:58:04 +03:00
|
|
|
return 0;
|
2024-05-30 14:16:21 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static int sev_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* SEV/SEV-ES rely on pinned memory to back guest RAM so discarding
|
|
|
|
* isn't actually possible. With SNP, only guest_memfd pages are used
|
|
|
|
* for private guest memory, so discarding of shared memory is still
|
|
|
|
* possible..
|
|
|
|
*/
|
|
|
|
ret = ram_block_discard_disable(true);
|
|
|
|
if (ret) {
|
|
|
|
error_setg(errp, "%s: cannot disable RAM discard", __func__);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* SEV uses these notifiers to register/pin pages prior to guest use,
|
|
|
|
* but SNP relies on guest_memfd for private pages, which has its
|
|
|
|
* own internal mechanisms for registering/pinning private memory.
|
|
|
|
*/
|
|
|
|
ram_block_notifier_add(&sev_ram_notifier);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The machine done notify event is used for SEV guests to get the
|
|
|
|
* measurement of the encrypted images. When SEV-SNP is enabled, the
|
|
|
|
* measurement is part of the guest attestation process where it can
|
|
|
|
* be collected without any reliance on the VMM. So skip registering
|
|
|
|
* the notifier for SNP in favor of using guest attestation instead.
|
|
|
|
*/
|
|
|
|
qemu_add_machine_init_done_notifier(&sev_machine_done_notify);
|
|
|
|
|
|
|
|
return 0;
|
2018-03-08 15:48:44 +03:00
|
|
|
}
|
|
|
|
|
2024-05-30 14:16:22 +03:00
|
|
|
static int sev_snp_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
|
|
|
|
{
|
|
|
|
MachineState *ms = MACHINE(qdev_get_machine());
|
|
|
|
X86MachineState *x86ms = X86_MACHINE(ms);
|
|
|
|
|
|
|
|
if (x86ms->smm == ON_OFF_AUTO_AUTO) {
|
|
|
|
x86ms->smm = ON_OFF_AUTO_OFF;
|
|
|
|
} else if (x86ms->smm == ON_OFF_AUTO_ON) {
|
|
|
|
error_setg(errp, "SEV-SNP does not support SMM.");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-03-08 15:48:49 +03:00
|
|
|
int
|
2024-05-30 14:16:36 +03:00
|
|
|
sev_encrypt_flash(hwaddr gpa, uint8_t *ptr, uint64_t len, Error **errp)
|
2018-03-08 15:48:49 +03:00
|
|
|
{
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs);
|
2024-05-31 13:51:44 +03:00
|
|
|
SevCommonStateClass *klass = SEV_COMMON_GET_CLASS(sev_common);
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
|
|
|
|
if (!sev_common) {
|
sev: Remove false abstraction of flash encryption
When AMD's SEV memory encryption is in use, flash memory banks (which are
initialed by pc_system_flash_map()) need to be encrypted with the guest's
key, so that the guest can read them.
That's abstracted via the kvm_memcrypt_encrypt_data() callback in the KVM
state.. except, that it doesn't really abstract much at all.
For starters, the only call site is in code specific to the 'pc'
family of machine types, so it's obviously specific to those and to
x86 to begin with. But it makes a bunch of further assumptions that
need not be true about an arbitrary confidential guest system based on
memory encryption, let alone one based on other mechanisms:
* it assumes that the flash memory is defined to be encrypted with the
guest key, rather than being shared with hypervisor
* it assumes that that hypervisor has some mechanism to encrypt data into
the guest, even though it can't decrypt it out, since that's the whole
point
* the interface assumes that this encrypt can be done in place, which
implies that the hypervisor can write into a confidential guests's
memory, even if what it writes isn't meaningful
So really, this "abstraction" is actually pretty specific to the way SEV
works. So, this patch removes it and instead has the PC flash
initialization code call into a SEV specific callback.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
2021-01-12 03:58:04 +03:00
|
|
|
return 0;
|
|
|
|
}
|
2018-03-08 15:48:49 +03:00
|
|
|
|
|
|
|
/* if SEV is in update state then encrypt the data else do nothing */
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
if (sev_check_state(sev_common, SEV_STATE_LAUNCH_UPDATE)) {
|
2024-05-31 13:51:44 +03:00
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = klass->launch_update_data(sev_common, gpa, ptr, len);
|
sev: Remove false abstraction of flash encryption
When AMD's SEV memory encryption is in use, flash memory banks (which are
initialed by pc_system_flash_map()) need to be encrypted with the guest's
key, so that the guest can read them.
That's abstracted via the kvm_memcrypt_encrypt_data() callback in the KVM
state.. except, that it doesn't really abstract much at all.
For starters, the only call site is in code specific to the 'pc'
family of machine types, so it's obviously specific to those and to
x86 to begin with. But it makes a bunch of further assumptions that
need not be true about an arbitrary confidential guest system based on
memory encryption, let alone one based on other mechanisms:
* it assumes that the flash memory is defined to be encrypted with the
guest key, rather than being shared with hypervisor
* it assumes that that hypervisor has some mechanism to encrypt data into
the guest, even though it can't decrypt it out, since that's the whole
point
* the interface assumes that this encrypt can be done in place, which
implies that the hypervisor can write into a confidential guests's
memory, even if what it writes isn't meaningful
So really, this "abstraction" is actually pretty specific to the way SEV
works. So, this patch removes it and instead has the PC flash
initialization code call into a SEV specific callback.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
2021-01-12 03:58:04 +03:00
|
|
|
if (ret < 0) {
|
2021-10-07 19:16:58 +03:00
|
|
|
error_setg(errp, "SEV: Failed to encrypt pflash rom");
|
sev: Remove false abstraction of flash encryption
When AMD's SEV memory encryption is in use, flash memory banks (which are
initialed by pc_system_flash_map()) need to be encrypted with the guest's
key, so that the guest can read them.
That's abstracted via the kvm_memcrypt_encrypt_data() callback in the KVM
state.. except, that it doesn't really abstract much at all.
For starters, the only call site is in code specific to the 'pc'
family of machine types, so it's obviously specific to those and to
x86 to begin with. But it makes a bunch of further assumptions that
need not be true about an arbitrary confidential guest system based on
memory encryption, let alone one based on other mechanisms:
* it assumes that the flash memory is defined to be encrypted with the
guest key, rather than being shared with hypervisor
* it assumes that that hypervisor has some mechanism to encrypt data into
the guest, even though it can't decrypt it out, since that's the whole
point
* the interface assumes that this encrypt can be done in place, which
implies that the hypervisor can write into a confidential guests's
memory, even if what it writes isn't meaningful
So really, this "abstraction" is actually pretty specific to the way SEV
works. So, this patch removes it and instead has the PC flash
initialization code call into a SEV specific callback.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
2021-01-12 03:58:04 +03:00
|
|
|
return ret;
|
|
|
|
}
|
2018-03-08 15:48:49 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-10-27 20:03:03 +03:00
|
|
|
int sev_inject_launch_secret(const char *packet_hdr, const char *secret,
|
|
|
|
uint64_t gpa, Error **errp)
|
|
|
|
{
|
target/i386/sev: Fix missing ERRP_GUARD() for error_prepend()
As the comment in qapi/error, passing @errp to error_prepend() requires
ERRP_GUARD():
* = Why, when and how to use ERRP_GUARD() =
*
* Without ERRP_GUARD(), use of the @errp parameter is restricted:
...
* - It should not be passed to error_prepend(), error_vprepend() or
* error_append_hint(), because that doesn't work with &error_fatal.
* ERRP_GUARD() lifts these restrictions.
*
* To use ERRP_GUARD(), add it right at the beginning of the function.
* @errp can then be used without worrying about the argument being
* NULL or &error_fatal.
ERRP_GUARD() could avoid the case when @errp is the pointer of
error_fatal, the user can't see this additional information, because
exit() happens in error_setg earlier than information is added [1].
The sev_inject_launch_secret() passes @errp to error_prepend(), and as
an APIs defined in target/i386/sev.h, it is necessary to protect its
@errp with ERRP_GUARD().
To avoid the issue like [1] said, add missing ERRP_GUARD() at the
beginning of this function.
[1]: Issue description in the commit message of commit ae7c80a7bd73
("error: New macro ERRP_GUARD()").
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-ID: <20240229143914.1977550-17-zhao1.liu@linux.intel.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
2024-02-29 17:39:13 +03:00
|
|
|
ERRP_GUARD();
|
2020-10-27 20:03:03 +03:00
|
|
|
struct kvm_sev_launch_secret input;
|
|
|
|
g_autofree guchar *data = NULL, *hdr = NULL;
|
|
|
|
int error, ret = 1;
|
|
|
|
void *hva;
|
|
|
|
gsize hdr_sz = 0, data_sz = 0;
|
|
|
|
MemoryRegion *mr = NULL;
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs);
|
2020-10-27 20:03:03 +03:00
|
|
|
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
if (!sev_common) {
|
2021-10-07 19:16:58 +03:00
|
|
|
error_setg(errp, "SEV not enabled for guest");
|
2020-10-27 20:03:03 +03:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* secret can be injected only in this state */
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
if (!sev_check_state(sev_common, SEV_STATE_LAUNCH_SECRET)) {
|
2020-10-27 20:03:03 +03:00
|
|
|
error_setg(errp, "SEV: Not in correct state. (LSECRET) %x",
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
sev_common->state);
|
2020-10-27 20:03:03 +03:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
hdr = g_base64_decode(packet_hdr, &hdr_sz);
|
|
|
|
if (!hdr || !hdr_sz) {
|
|
|
|
error_setg(errp, "SEV: Failed to decode sequence header");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
data = g_base64_decode(secret, &data_sz);
|
|
|
|
if (!data || !data_sz) {
|
|
|
|
error_setg(errp, "SEV: Failed to decode data");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
hva = gpa2hva(&mr, gpa, data_sz, errp);
|
|
|
|
if (!hva) {
|
|
|
|
error_prepend(errp, "SEV: Failed to calculate guest address: ");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
input.hdr_uaddr = (uint64_t)(unsigned long)hdr;
|
|
|
|
input.hdr_len = hdr_sz;
|
|
|
|
|
|
|
|
input.trans_uaddr = (uint64_t)(unsigned long)data;
|
|
|
|
input.trans_len = data_sz;
|
|
|
|
|
|
|
|
input.guest_uaddr = (uint64_t)(unsigned long)hva;
|
|
|
|
input.guest_len = data_sz;
|
|
|
|
|
|
|
|
trace_kvm_sev_launch_secret(gpa, input.guest_uaddr,
|
|
|
|
input.trans_uaddr, input.trans_len);
|
|
|
|
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
ret = sev_ioctl(sev_common->sev_fd, KVM_SEV_LAUNCH_SECRET,
|
2020-10-27 20:03:03 +03:00
|
|
|
&input, &error);
|
|
|
|
if (ret) {
|
|
|
|
error_setg(errp, "SEV: failed to inject secret ret=%d fw_error=%d '%s'",
|
|
|
|
ret, error, fw_error_to_str(error));
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
target/i386/sev: Move qmp_sev_inject_launch_secret() to sev.c
Move qmp_sev_inject_launch_secret() from monitor.c to sev.c
and make sev_inject_launch_secret() static. We don't need the
stub anymore, remove it.
Previously with binaries built without SEV, management layer
was getting an empty response:
{ "execute": "sev-inject-launch-secret",
"arguments": { "packet-header": "mypkt", "secret": "mypass", "gpa": 4294959104 }
}
{
"return": {
}
}
Now the response is explicit, mentioning the feature is disabled:
{ "execute": "sev-inject-launch-secret",
"arguments": { "packet-header": "mypkt", "secret": "mypass", "gpa": 4294959104 }
}
{
"error": {
"class": "GenericError",
"desc": "this feature or command is not currently supported"
}
}
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20211007161716.453984-19-philmd@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-10-07 19:17:11 +03:00
|
|
|
#define SEV_SECRET_GUID "4c2eb361-7d9b-4cc3-8081-127c90d3d294"
|
|
|
|
struct sev_secret_area {
|
|
|
|
uint32_t base;
|
|
|
|
uint32_t size;
|
|
|
|
};
|
|
|
|
|
|
|
|
void qmp_sev_inject_launch_secret(const char *packet_hdr,
|
|
|
|
const char *secret,
|
|
|
|
bool has_gpa, uint64_t gpa,
|
|
|
|
Error **errp)
|
|
|
|
{
|
|
|
|
if (!sev_enabled()) {
|
|
|
|
error_setg(errp, "SEV not enabled for guest");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (!has_gpa) {
|
|
|
|
uint8_t *data;
|
|
|
|
struct sev_secret_area *area;
|
|
|
|
|
|
|
|
if (!pc_system_ovmf_table_find(SEV_SECRET_GUID, &data, NULL)) {
|
|
|
|
error_setg(errp, "SEV: no secret area found in OVMF,"
|
|
|
|
" gpa must be specified.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
area = (struct sev_secret_area *)data;
|
|
|
|
gpa = area->base;
|
|
|
|
}
|
|
|
|
|
|
|
|
sev_inject_launch_secret(packet_hdr, secret, gpa, errp);
|
|
|
|
}
|
|
|
|
|
2021-02-08 17:04:52 +03:00
|
|
|
static int
|
|
|
|
sev_es_parse_reset_block(SevInfoBlock *info, uint32_t *addr)
|
|
|
|
{
|
|
|
|
if (!info->reset_addr) {
|
|
|
|
error_report("SEV-ES reset address is zero");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
*addr = info->reset_addr;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
sev_es_find_reset_vector(void *flash_ptr, uint64_t flash_size,
|
|
|
|
uint32_t *addr)
|
|
|
|
{
|
|
|
|
QemuUUID info_guid, *guid;
|
|
|
|
SevInfoBlock *info;
|
|
|
|
uint8_t *data;
|
|
|
|
uint16_t *len;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Initialize the address to zero. An address of zero with a successful
|
|
|
|
* return code indicates that SEV-ES is not active.
|
|
|
|
*/
|
|
|
|
*addr = 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Extract the AP reset vector for SEV-ES guests by locating the SEV GUID.
|
|
|
|
* The SEV GUID is located on its own (original implementation) or within
|
|
|
|
* the Firmware GUID Table (new implementation), either of which are
|
|
|
|
* located 32 bytes from the end of the flash.
|
|
|
|
*
|
|
|
|
* Check the Firmware GUID Table first.
|
|
|
|
*/
|
|
|
|
if (pc_system_ovmf_table_find(SEV_INFO_BLOCK_GUID, &data, NULL)) {
|
|
|
|
return sev_es_parse_reset_block((SevInfoBlock *)data, addr);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* SEV info block not found in the Firmware GUID Table (or there isn't
|
|
|
|
* a Firmware GUID Table), fall back to the original implementation.
|
|
|
|
*/
|
|
|
|
data = flash_ptr + flash_size - 0x20;
|
|
|
|
|
|
|
|
qemu_uuid_parse(SEV_INFO_BLOCK_GUID, &info_guid);
|
|
|
|
info_guid = qemu_uuid_bswap(info_guid); /* GUIDs are LE */
|
|
|
|
|
|
|
|
guid = (QemuUUID *)(data - sizeof(info_guid));
|
|
|
|
if (!qemu_uuid_is_equal(guid, &info_guid)) {
|
|
|
|
error_report("SEV information block/Firmware GUID Table block not found in pflash rom");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
len = (uint16_t *)((uint8_t *)guid - sizeof(*len));
|
|
|
|
info = (SevInfoBlock *)(data - le16_to_cpu(*len));
|
|
|
|
|
|
|
|
return sev_es_parse_reset_block(info, addr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void sev_es_set_reset_vector(CPUState *cpu)
|
|
|
|
{
|
|
|
|
X86CPU *x86;
|
|
|
|
CPUX86State *env;
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs);
|
2021-02-08 17:04:52 +03:00
|
|
|
|
|
|
|
/* Only update if we have valid reset information */
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
if (!sev_common || !sev_common->reset_data_valid) {
|
2021-02-08 17:04:52 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Do not update the BSP reset state */
|
|
|
|
if (cpu->cpu_index == 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
x86 = X86_CPU(cpu);
|
|
|
|
env = &x86->env;
|
|
|
|
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
cpu_x86_load_seg_cache(env, R_CS, 0xf000, sev_common->reset_cs, 0xffff,
|
2021-02-08 17:04:52 +03:00
|
|
|
DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK |
|
|
|
|
DESC_R_MASK | DESC_A_MASK);
|
|
|
|
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
env->eip = sev_common->reset_ip;
|
2021-02-08 17:04:52 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
int sev_es_save_reset_vector(void *flash_ptr, uint64_t flash_size)
|
|
|
|
{
|
|
|
|
CPUState *cpu;
|
|
|
|
uint32_t addr;
|
|
|
|
int ret;
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs);
|
2021-02-08 17:04:52 +03:00
|
|
|
|
|
|
|
if (!sev_es_enabled()) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
addr = 0;
|
|
|
|
ret = sev_es_find_reset_vector(flash_ptr, flash_size,
|
|
|
|
&addr);
|
|
|
|
if (ret) {
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (addr) {
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
sev_common->reset_cs = addr & 0xffff0000;
|
|
|
|
sev_common->reset_ip = addr & 0x0000ffff;
|
|
|
|
sev_common->reset_data_valid = true;
|
2021-02-08 17:04:52 +03:00
|
|
|
|
|
|
|
CPU_FOREACH(cpu) {
|
|
|
|
sev_es_set_reset_vector(cpu);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-09-30 08:49:14 +03:00
|
|
|
static const QemuUUID sev_hash_table_header_guid = {
|
|
|
|
.data = UUID_LE(0x9438d606, 0x4f22, 0x4cc9, 0xb4, 0x79, 0xa7, 0x93,
|
|
|
|
0xd4, 0x11, 0xfd, 0x21)
|
|
|
|
};
|
|
|
|
|
|
|
|
static const QemuUUID sev_kernel_entry_guid = {
|
|
|
|
.data = UUID_LE(0x4de79437, 0xabd2, 0x427f, 0xb8, 0x35, 0xd5, 0xb1,
|
|
|
|
0x72, 0xd2, 0x04, 0x5b)
|
|
|
|
};
|
|
|
|
static const QemuUUID sev_initrd_entry_guid = {
|
|
|
|
.data = UUID_LE(0x44baf731, 0x3a2f, 0x4bd7, 0x9a, 0xf1, 0x41, 0xe2,
|
|
|
|
0x91, 0x69, 0x78, 0x1d)
|
|
|
|
};
|
|
|
|
static const QemuUUID sev_cmdline_entry_guid = {
|
|
|
|
.data = UUID_LE(0x97d02dd8, 0xbd20, 0x4c94, 0xaa, 0x78, 0xe7, 0x71,
|
|
|
|
0x4d, 0x36, 0xab, 0x2a)
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Add the hashes of the linux kernel/initrd/cmdline to an encrypted guest page
|
|
|
|
* which is included in SEV's initial memory measurement.
|
|
|
|
*/
|
|
|
|
bool sev_add_kernel_loader_hashes(SevKernelLoaderContext *ctx, Error **errp)
|
|
|
|
{
|
|
|
|
uint8_t *data;
|
|
|
|
SevHashTableDescriptor *area;
|
|
|
|
SevHashTable *ht;
|
2021-11-11 13:00:47 +03:00
|
|
|
PaddedSevHashTable *padded_ht;
|
2021-09-30 08:49:14 +03:00
|
|
|
uint8_t cmdline_hash[HASH_SIZE];
|
|
|
|
uint8_t initrd_hash[HASH_SIZE];
|
|
|
|
uint8_t kernel_hash[HASH_SIZE];
|
|
|
|
uint8_t *hashp;
|
|
|
|
size_t hash_len = HASH_SIZE;
|
2021-11-11 13:00:48 +03:00
|
|
|
hwaddr mapped_len = sizeof(*padded_ht);
|
|
|
|
MemTxAttrs attrs = { 0 };
|
|
|
|
bool ret = true;
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
SevCommonState *sev_common = SEV_COMMON(MACHINE(qdev_get_machine())->cgs);
|
2021-09-30 08:49:14 +03:00
|
|
|
|
2021-11-11 13:00:44 +03:00
|
|
|
/*
|
|
|
|
* Only add the kernel hashes if the sev-guest configuration explicitly
|
|
|
|
* stated kernel-hashes=on.
|
|
|
|
*/
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
if (!sev_common->kernel_hashes) {
|
2021-11-11 13:00:44 +03:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-09-30 08:49:14 +03:00
|
|
|
if (!pc_system_ovmf_table_find(SEV_HASH_TABLE_RV_GUID, &data, NULL)) {
|
2021-11-11 13:00:45 +03:00
|
|
|
error_setg(errp, "SEV: kernel specified but guest firmware "
|
|
|
|
"has no hashes table GUID");
|
2021-09-30 08:49:14 +03:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
area = (SevHashTableDescriptor *)data;
|
2021-11-11 13:00:47 +03:00
|
|
|
if (!area->base || area->size < sizeof(PaddedSevHashTable)) {
|
2021-11-11 13:00:46 +03:00
|
|
|
error_setg(errp, "SEV: guest firmware hashes table area is invalid "
|
|
|
|
"(base=0x%x size=0x%x)", area->base, area->size);
|
|
|
|
return false;
|
|
|
|
}
|
2021-09-30 08:49:14 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Calculate hash of kernel command-line with the terminating null byte. If
|
|
|
|
* the user doesn't supply a command-line via -append, the 1-byte "\0" will
|
|
|
|
* be used.
|
|
|
|
*/
|
|
|
|
hashp = cmdline_hash;
|
|
|
|
if (qcrypto_hash_bytes(QCRYPTO_HASH_ALG_SHA256, ctx->cmdline_data,
|
|
|
|
ctx->cmdline_size, &hashp, &hash_len, errp) < 0) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
assert(hash_len == HASH_SIZE);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Calculate hash of initrd. If the user doesn't supply an initrd via
|
|
|
|
* -initrd, an empty buffer will be used (ctx->initrd_size == 0).
|
|
|
|
*/
|
|
|
|
hashp = initrd_hash;
|
|
|
|
if (qcrypto_hash_bytes(QCRYPTO_HASH_ALG_SHA256, ctx->initrd_data,
|
|
|
|
ctx->initrd_size, &hashp, &hash_len, errp) < 0) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
assert(hash_len == HASH_SIZE);
|
|
|
|
|
|
|
|
/* Calculate hash of the kernel */
|
|
|
|
hashp = kernel_hash;
|
|
|
|
struct iovec iov[2] = {
|
|
|
|
{ .iov_base = ctx->setup_data, .iov_len = ctx->setup_size },
|
|
|
|
{ .iov_base = ctx->kernel_data, .iov_len = ctx->kernel_size }
|
|
|
|
};
|
|
|
|
if (qcrypto_hash_bytesv(QCRYPTO_HASH_ALG_SHA256, iov, ARRAY_SIZE(iov),
|
|
|
|
&hashp, &hash_len, errp) < 0) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
assert(hash_len == HASH_SIZE);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Populate the hashes table in the guest's memory at the OVMF-designated
|
|
|
|
* area for the SEV hashes table
|
|
|
|
*/
|
2021-11-11 13:00:48 +03:00
|
|
|
padded_ht = address_space_map(&address_space_memory, area->base,
|
|
|
|
&mapped_len, true, attrs);
|
|
|
|
if (!padded_ht || mapped_len != sizeof(*padded_ht)) {
|
|
|
|
error_setg(errp, "SEV: cannot map hashes table guest memory area");
|
|
|
|
return false;
|
|
|
|
}
|
2021-11-11 13:00:47 +03:00
|
|
|
ht = &padded_ht->ht;
|
2021-09-30 08:49:14 +03:00
|
|
|
|
|
|
|
ht->guid = sev_hash_table_header_guid;
|
|
|
|
ht->len = sizeof(*ht);
|
|
|
|
|
|
|
|
ht->cmdline.guid = sev_cmdline_entry_guid;
|
|
|
|
ht->cmdline.len = sizeof(ht->cmdline);
|
|
|
|
memcpy(ht->cmdline.hash, cmdline_hash, sizeof(ht->cmdline.hash));
|
|
|
|
|
|
|
|
ht->initrd.guid = sev_initrd_entry_guid;
|
|
|
|
ht->initrd.len = sizeof(ht->initrd);
|
|
|
|
memcpy(ht->initrd.hash, initrd_hash, sizeof(ht->initrd.hash));
|
|
|
|
|
|
|
|
ht->kernel.guid = sev_kernel_entry_guid;
|
|
|
|
ht->kernel.len = sizeof(ht->kernel);
|
|
|
|
memcpy(ht->kernel.hash, kernel_hash, sizeof(ht->kernel.hash));
|
|
|
|
|
2021-11-11 13:00:47 +03:00
|
|
|
/* zero the excess data so the measurement can be reliably calculated */
|
|
|
|
memset(padded_ht->padding, 0, sizeof(padded_ht->padding));
|
2021-09-30 08:49:14 +03:00
|
|
|
|
2024-05-30 14:16:36 +03:00
|
|
|
if (sev_encrypt_flash(area->base, (uint8_t *)padded_ht,
|
|
|
|
sizeof(*padded_ht), errp) < 0) {
|
2021-11-11 13:00:48 +03:00
|
|
|
ret = false;
|
2021-09-30 08:49:14 +03:00
|
|
|
}
|
|
|
|
|
2021-11-11 13:00:48 +03:00
|
|
|
address_space_unmap(&address_space_memory, padded_ht,
|
|
|
|
mapped_len, true, mapped_len);
|
|
|
|
|
|
|
|
return ret;
|
2021-09-30 08:49:14 +03:00
|
|
|
}
|
|
|
|
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
static char *
|
|
|
|
sev_common_get_sev_device(Object *obj, Error **errp)
|
|
|
|
{
|
|
|
|
return g_strdup(SEV_COMMON(obj)->sev_device);
|
|
|
|
}
|
|
|
|
|
2024-02-29 09:00:36 +03:00
|
|
|
static void
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
sev_common_set_sev_device(Object *obj, const char *value, Error **errp)
|
|
|
|
{
|
|
|
|
SEV_COMMON(obj)->sev_device = g_strdup(value);
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool sev_common_get_kernel_hashes(Object *obj, Error **errp)
|
|
|
|
{
|
|
|
|
return SEV_COMMON(obj)->kernel_hashes;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sev_common_set_kernel_hashes(Object *obj, bool value, Error **errp)
|
|
|
|
{
|
|
|
|
SEV_COMMON(obj)->kernel_hashes = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
sev_common_class_init(ObjectClass *oc, void *data)
|
2024-02-29 09:00:36 +03:00
|
|
|
{
|
|
|
|
ConfidentialGuestSupportClass *klass = CONFIDENTIAL_GUEST_SUPPORT_CLASS(oc);
|
|
|
|
|
2024-05-30 14:16:21 +03:00
|
|
|
klass->kvm_init = sev_common_kvm_init;
|
2024-02-29 09:00:36 +03:00
|
|
|
|
|
|
|
object_class_property_add_str(oc, "sev-device",
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
sev_common_get_sev_device,
|
|
|
|
sev_common_set_sev_device);
|
2024-02-29 09:00:36 +03:00
|
|
|
object_class_property_set_description(oc, "sev-device",
|
|
|
|
"SEV device to use");
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
object_class_property_add_bool(oc, "kernel-hashes",
|
|
|
|
sev_common_get_kernel_hashes,
|
|
|
|
sev_common_set_kernel_hashes);
|
|
|
|
object_class_property_set_description(oc, "kernel-hashes",
|
|
|
|
"add kernel hashes to guest firmware for measured Linux boot");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
sev_common_instance_init(Object *obj)
|
|
|
|
{
|
|
|
|
SevCommonState *sev_common = SEV_COMMON(obj);
|
|
|
|
|
|
|
|
sev_common->kvm_type = -1;
|
|
|
|
|
|
|
|
sev_common->sev_device = g_strdup(DEFAULT_SEV_DEVICE);
|
|
|
|
|
|
|
|
object_property_add_uint32_ptr(obj, "cbitpos", &sev_common->cbitpos,
|
|
|
|
OBJ_PROP_FLAG_READWRITE);
|
|
|
|
object_property_add_uint32_ptr(obj, "reduced-phys-bits",
|
|
|
|
&sev_common->reduced_phys_bits,
|
|
|
|
OBJ_PROP_FLAG_READWRITE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* sev guest info common to sev/sev-es/sev-snp */
|
|
|
|
static const TypeInfo sev_common_info = {
|
|
|
|
.parent = TYPE_X86_CONFIDENTIAL_GUEST,
|
|
|
|
.name = TYPE_SEV_COMMON,
|
|
|
|
.instance_size = sizeof(SevCommonState),
|
|
|
|
.instance_init = sev_common_instance_init,
|
|
|
|
.class_size = sizeof(SevCommonStateClass),
|
|
|
|
.class_init = sev_common_class_init,
|
|
|
|
.abstract = true,
|
|
|
|
.interfaces = (InterfaceInfo[]) {
|
|
|
|
{ TYPE_USER_CREATABLE },
|
|
|
|
{ }
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
static char *
|
|
|
|
sev_guest_get_dh_cert_file(Object *obj, Error **errp)
|
|
|
|
{
|
|
|
|
return g_strdup(SEV_GUEST(obj)->dh_cert_file);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
sev_guest_set_dh_cert_file(Object *obj, const char *value, Error **errp)
|
|
|
|
{
|
|
|
|
SEV_GUEST(obj)->dh_cert_file = g_strdup(value);
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *
|
|
|
|
sev_guest_get_session_file(Object *obj, Error **errp)
|
|
|
|
{
|
|
|
|
SevGuestState *sev_guest = SEV_GUEST(obj);
|
|
|
|
|
|
|
|
return sev_guest->session_file ? g_strdup(sev_guest->session_file) : NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
sev_guest_set_session_file(Object *obj, const char *value, Error **errp)
|
|
|
|
{
|
|
|
|
SEV_GUEST(obj)->session_file = g_strdup(value);
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool sev_guest_get_legacy_vm_type(Object *obj, Error **errp)
|
|
|
|
{
|
|
|
|
return SEV_GUEST(obj)->legacy_vm_type;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sev_guest_set_legacy_vm_type(Object *obj, bool value, Error **errp)
|
|
|
|
{
|
|
|
|
SEV_GUEST(obj)->legacy_vm_type = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
sev_guest_class_init(ObjectClass *oc, void *data)
|
|
|
|
{
|
2024-05-30 14:16:17 +03:00
|
|
|
SevCommonStateClass *klass = SEV_COMMON_CLASS(oc);
|
2024-05-31 13:44:44 +03:00
|
|
|
X86ConfidentialGuestClass *x86_klass = X86_CONFIDENTIAL_GUEST_CLASS(oc);
|
2024-05-30 14:16:17 +03:00
|
|
|
|
|
|
|
klass->launch_start = sev_launch_start;
|
2024-05-30 14:16:18 +03:00
|
|
|
klass->launch_finish = sev_launch_finish;
|
2024-05-31 13:51:44 +03:00
|
|
|
klass->launch_update_data = sev_launch_update_data;
|
2024-05-30 14:16:21 +03:00
|
|
|
klass->kvm_init = sev_kvm_init;
|
2024-05-31 13:44:44 +03:00
|
|
|
x86_klass->kvm_type = sev_kvm_type;
|
2024-05-30 14:16:17 +03:00
|
|
|
|
2024-02-29 09:00:36 +03:00
|
|
|
object_class_property_add_str(oc, "dh-cert-file",
|
|
|
|
sev_guest_get_dh_cert_file,
|
|
|
|
sev_guest_set_dh_cert_file);
|
|
|
|
object_class_property_set_description(oc, "dh-cert-file",
|
|
|
|
"guest owners DH certificate (encoded with base64)");
|
|
|
|
object_class_property_add_str(oc, "session-file",
|
|
|
|
sev_guest_get_session_file,
|
|
|
|
sev_guest_set_session_file);
|
|
|
|
object_class_property_set_description(oc, "session-file",
|
|
|
|
"guest owners session parameters (encoded with base64)");
|
i386/sev: Add 'legacy-vm-type' parameter for SEV guest objects
QEMU will currently automatically make use of the KVM_SEV_INIT2 API for
initializing SEV and SEV-ES guests verses the older
KVM_SEV_INIT/KVM_SEV_ES_INIT interfaces.
However, the older interfaces will silently avoid sync'ing FPU/XSAVE
state to the VMSA prior to encryption, thus relying on behavior and
measurements that assume the related fields to be allow zero.
With KVM_SEV_INIT2, this state is now synced into the VMSA, resulting in
measurements changes and, theoretically, behaviorial changes, though the
latter are unlikely to be seen in practice.
To allow a smooth transition to the newer interface, while still
providing a mechanism to maintain backward compatibility with VMs
created using the older interfaces, provide a new command-line
parameter:
-object sev-guest,legacy-vm-type=true,...
and have it default to false.
Signed-off-by: Michael Roth <michael.roth@amd.com>
Message-ID: <20240409230743.962513-2-michael.roth@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-04-10 02:07:41 +03:00
|
|
|
object_class_property_add_bool(oc, "legacy-vm-type",
|
|
|
|
sev_guest_get_legacy_vm_type,
|
|
|
|
sev_guest_set_legacy_vm_type);
|
|
|
|
object_class_property_set_description(oc, "legacy-vm-type",
|
|
|
|
"use legacy VM type to maintain measurement compatibility with older QEMU or kernel versions.");
|
2024-02-29 09:00:36 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
sev_guest_instance_init(Object *obj)
|
|
|
|
{
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
SevGuestState *sev_guest = SEV_GUEST(obj);
|
2024-03-19 17:30:25 +03:00
|
|
|
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
sev_guest->policy = DEFAULT_GUEST_POLICY;
|
|
|
|
object_property_add_uint32_ptr(obj, "handle", &sev_guest->handle,
|
2024-02-29 09:00:36 +03:00
|
|
|
OBJ_PROP_FLAG_READWRITE);
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
object_property_add_uint32_ptr(obj, "policy", &sev_guest->policy,
|
2024-02-29 09:00:36 +03:00
|
|
|
OBJ_PROP_FLAG_READWRITE);
|
2024-04-10 02:07:43 +03:00
|
|
|
object_apply_compat_props(obj);
|
2024-02-29 09:00:36 +03:00
|
|
|
}
|
|
|
|
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
/* guest info specific sev/sev-es */
|
2024-02-29 09:00:36 +03:00
|
|
|
static const TypeInfo sev_guest_info = {
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
.parent = TYPE_SEV_COMMON,
|
2024-02-29 09:00:36 +03:00
|
|
|
.name = TYPE_SEV_GUEST,
|
|
|
|
.instance_size = sizeof(SevGuestState),
|
|
|
|
.instance_init = sev_guest_instance_init,
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
.class_init = sev_guest_class_init,
|
2024-02-29 09:00:36 +03:00
|
|
|
};
|
|
|
|
|
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 <brijesh.singh@amd.com>
Co-developed-by: Michael Roth <michael.roth@amd.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (for QAPI schema)
Signed-off-by: Michael Roth <michael.roth@amd.com>
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-8-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:19 +03:00
|
|
|
static void
|
|
|
|
sev_snp_guest_get_policy(Object *obj, Visitor *v, const char *name,
|
|
|
|
void *opaque, Error **errp)
|
|
|
|
{
|
|
|
|
visit_type_uint64(v, name,
|
|
|
|
(uint64_t *)&SEV_SNP_GUEST(obj)->kvm_start_conf.policy,
|
|
|
|
errp);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
sev_snp_guest_set_policy(Object *obj, Visitor *v, const char *name,
|
|
|
|
void *opaque, Error **errp)
|
|
|
|
{
|
|
|
|
visit_type_uint64(v, name,
|
|
|
|
(uint64_t *)&SEV_SNP_GUEST(obj)->kvm_start_conf.policy,
|
|
|
|
errp);
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *
|
|
|
|
sev_snp_guest_get_guest_visible_workarounds(Object *obj, Error **errp)
|
|
|
|
{
|
|
|
|
return g_strdup(SEV_SNP_GUEST(obj)->guest_visible_workarounds);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
sev_snp_guest_set_guest_visible_workarounds(Object *obj, const char *value,
|
|
|
|
Error **errp)
|
|
|
|
{
|
|
|
|
SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
|
|
|
|
struct kvm_sev_snp_launch_start *start = &sev_snp_guest->kvm_start_conf;
|
|
|
|
g_autofree guchar *blob;
|
|
|
|
gsize len;
|
|
|
|
|
|
|
|
g_free(sev_snp_guest->guest_visible_workarounds);
|
|
|
|
|
|
|
|
/* store the base64 str so we don't need to re-encode in getter */
|
|
|
|
sev_snp_guest->guest_visible_workarounds = g_strdup(value);
|
|
|
|
|
|
|
|
blob = qbase64_decode(sev_snp_guest->guest_visible_workarounds,
|
|
|
|
-1, &len, errp);
|
|
|
|
if (!blob) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (len != sizeof(start->gosvw)) {
|
|
|
|
error_setg(errp, "parameter length of %lu exceeds max of %lu",
|
|
|
|
len, sizeof(start->gosvw));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
memcpy(start->gosvw, blob, len);
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *
|
|
|
|
sev_snp_guest_get_id_block(Object *obj, Error **errp)
|
|
|
|
{
|
|
|
|
SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
|
|
|
|
|
|
|
|
return g_strdup(sev_snp_guest->id_block);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
sev_snp_guest_set_id_block(Object *obj, const char *value, Error **errp)
|
|
|
|
{
|
|
|
|
SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
|
|
|
|
struct kvm_sev_snp_launch_finish *finish = &sev_snp_guest->kvm_finish_conf;
|
|
|
|
gsize len;
|
|
|
|
|
|
|
|
g_free(sev_snp_guest->id_block);
|
|
|
|
g_free((guchar *)finish->id_block_uaddr);
|
|
|
|
|
|
|
|
/* store the base64 str so we don't need to re-encode in getter */
|
|
|
|
sev_snp_guest->id_block = g_strdup(value);
|
|
|
|
|
|
|
|
finish->id_block_uaddr =
|
|
|
|
(uint64_t)qbase64_decode(sev_snp_guest->id_block, -1, &len, errp);
|
|
|
|
|
|
|
|
if (!finish->id_block_uaddr) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (len != KVM_SEV_SNP_ID_BLOCK_SIZE) {
|
|
|
|
error_setg(errp, "parameter length of %lu not equal to %u",
|
|
|
|
len, KVM_SEV_SNP_ID_BLOCK_SIZE);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
finish->id_block_en = (len) ? 1 : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *
|
|
|
|
sev_snp_guest_get_id_auth(Object *obj, Error **errp)
|
|
|
|
{
|
|
|
|
SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
|
|
|
|
|
|
|
|
return g_strdup(sev_snp_guest->id_auth);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
sev_snp_guest_set_id_auth(Object *obj, const char *value, Error **errp)
|
|
|
|
{
|
|
|
|
SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
|
|
|
|
struct kvm_sev_snp_launch_finish *finish = &sev_snp_guest->kvm_finish_conf;
|
|
|
|
gsize len;
|
|
|
|
|
|
|
|
g_free(sev_snp_guest->id_auth);
|
|
|
|
g_free((guchar *)finish->id_auth_uaddr);
|
|
|
|
|
|
|
|
/* store the base64 str so we don't need to re-encode in getter */
|
|
|
|
sev_snp_guest->id_auth = g_strdup(value);
|
|
|
|
|
|
|
|
finish->id_auth_uaddr =
|
|
|
|
(uint64_t)qbase64_decode(sev_snp_guest->id_auth, -1, &len, errp);
|
|
|
|
|
|
|
|
if (!finish->id_auth_uaddr) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (len > KVM_SEV_SNP_ID_AUTH_SIZE) {
|
|
|
|
error_setg(errp, "parameter length:ID_AUTH %lu exceeds max of %u",
|
|
|
|
len, KVM_SEV_SNP_ID_AUTH_SIZE);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool
|
|
|
|
sev_snp_guest_get_author_key_enabled(Object *obj, Error **errp)
|
|
|
|
{
|
|
|
|
SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
|
|
|
|
|
|
|
|
return !!sev_snp_guest->kvm_finish_conf.auth_key_en;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
sev_snp_guest_set_author_key_enabled(Object *obj, bool value, Error **errp)
|
|
|
|
{
|
|
|
|
SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
|
|
|
|
|
|
|
|
sev_snp_guest->kvm_finish_conf.auth_key_en = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool
|
|
|
|
sev_snp_guest_get_vcek_disabled(Object *obj, Error **errp)
|
|
|
|
{
|
|
|
|
SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
|
|
|
|
|
|
|
|
return !!sev_snp_guest->kvm_finish_conf.vcek_disabled;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
sev_snp_guest_set_vcek_disabled(Object *obj, bool value, Error **errp)
|
|
|
|
{
|
|
|
|
SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
|
|
|
|
|
|
|
|
sev_snp_guest->kvm_finish_conf.vcek_disabled = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *
|
|
|
|
sev_snp_guest_get_host_data(Object *obj, Error **errp)
|
|
|
|
{
|
|
|
|
SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
|
|
|
|
|
|
|
|
return g_strdup(sev_snp_guest->host_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
sev_snp_guest_set_host_data(Object *obj, const char *value, Error **errp)
|
|
|
|
{
|
|
|
|
SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
|
|
|
|
struct kvm_sev_snp_launch_finish *finish = &sev_snp_guest->kvm_finish_conf;
|
|
|
|
g_autofree guchar *blob;
|
|
|
|
gsize len;
|
|
|
|
|
|
|
|
g_free(sev_snp_guest->host_data);
|
|
|
|
|
|
|
|
/* store the base64 str so we don't need to re-encode in getter */
|
|
|
|
sev_snp_guest->host_data = g_strdup(value);
|
|
|
|
|
|
|
|
blob = qbase64_decode(sev_snp_guest->host_data, -1, &len, errp);
|
|
|
|
|
|
|
|
if (!blob) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (len != sizeof(finish->host_data)) {
|
|
|
|
error_setg(errp, "parameter length of %lu not equal to %lu",
|
|
|
|
len, sizeof(finish->host_data));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
memcpy(finish->host_data, blob, len);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
sev_snp_guest_class_init(ObjectClass *oc, void *data)
|
|
|
|
{
|
2024-05-30 14:16:22 +03:00
|
|
|
SevCommonStateClass *klass = SEV_COMMON_CLASS(oc);
|
2024-05-31 13:44:44 +03:00
|
|
|
X86ConfidentialGuestClass *x86_klass = X86_CONFIDENTIAL_GUEST_CLASS(oc);
|
2024-05-30 14:16:22 +03:00
|
|
|
|
2024-05-30 14:16:27 +03:00
|
|
|
klass->launch_start = sev_snp_launch_start;
|
2024-05-30 14:16:28 +03:00
|
|
|
klass->launch_finish = sev_snp_launch_finish;
|
2024-05-30 14:16:38 +03:00
|
|
|
klass->launch_update_data = sev_snp_launch_update_data;
|
2024-05-30 14:16:22 +03:00
|
|
|
klass->kvm_init = sev_snp_kvm_init;
|
2024-05-31 13:44:44 +03:00
|
|
|
x86_klass->kvm_type = sev_snp_kvm_type;
|
2024-05-30 14:16:22 +03:00
|
|
|
|
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 <brijesh.singh@amd.com>
Co-developed-by: Michael Roth <michael.roth@amd.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (for QAPI schema)
Signed-off-by: Michael Roth <michael.roth@amd.com>
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-8-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:19 +03:00
|
|
|
object_class_property_add(oc, "policy", "uint64",
|
|
|
|
sev_snp_guest_get_policy,
|
|
|
|
sev_snp_guest_set_policy, NULL, NULL);
|
|
|
|
object_class_property_add_str(oc, "guest-visible-workarounds",
|
|
|
|
sev_snp_guest_get_guest_visible_workarounds,
|
|
|
|
sev_snp_guest_set_guest_visible_workarounds);
|
|
|
|
object_class_property_add_str(oc, "id-block",
|
|
|
|
sev_snp_guest_get_id_block,
|
|
|
|
sev_snp_guest_set_id_block);
|
|
|
|
object_class_property_add_str(oc, "id-auth",
|
|
|
|
sev_snp_guest_get_id_auth,
|
|
|
|
sev_snp_guest_set_id_auth);
|
|
|
|
object_class_property_add_bool(oc, "author-key-enabled",
|
|
|
|
sev_snp_guest_get_author_key_enabled,
|
|
|
|
sev_snp_guest_set_author_key_enabled);
|
|
|
|
object_class_property_add_bool(oc, "vcek-required",
|
|
|
|
sev_snp_guest_get_vcek_disabled,
|
|
|
|
sev_snp_guest_set_vcek_disabled);
|
|
|
|
object_class_property_add_str(oc, "host-data",
|
|
|
|
sev_snp_guest_get_host_data,
|
|
|
|
sev_snp_guest_set_host_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
sev_snp_guest_instance_init(Object *obj)
|
|
|
|
{
|
2024-05-30 14:16:22 +03:00
|
|
|
ConfidentialGuestSupport *cgs = CONFIDENTIAL_GUEST_SUPPORT(obj);
|
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 <brijesh.singh@amd.com>
Co-developed-by: Michael Roth <michael.roth@amd.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (for QAPI schema)
Signed-off-by: Michael Roth <michael.roth@amd.com>
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-8-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:19 +03:00
|
|
|
SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
|
|
|
|
|
2024-05-30 14:16:22 +03:00
|
|
|
cgs->require_guest_memfd = true;
|
|
|
|
|
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 <brijesh.singh@amd.com>
Co-developed-by: Michael Roth <michael.roth@amd.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (for QAPI schema)
Signed-off-by: Michael Roth <michael.roth@amd.com>
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-8-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:19 +03:00
|
|
|
/* default init/start/finish params for kvm */
|
|
|
|
sev_snp_guest->kvm_start_conf.policy = DEFAULT_SEV_SNP_POLICY;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* guest info specific to sev-snp */
|
|
|
|
static const TypeInfo sev_snp_guest_info = {
|
|
|
|
.parent = TYPE_SEV_COMMON,
|
|
|
|
.name = TYPE_SEV_SNP_GUEST,
|
|
|
|
.instance_size = sizeof(SevSnpGuestState),
|
|
|
|
.class_init = sev_snp_guest_class_init,
|
|
|
|
.instance_init = sev_snp_guest_instance_init,
|
|
|
|
};
|
|
|
|
|
2018-03-08 15:48:41 +03:00
|
|
|
static void
|
|
|
|
sev_register_types(void)
|
|
|
|
{
|
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 <michael.roth@amd.com>
Co-developed-by: Dov Murik <dovmurik@linux.ibm.com>
Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (QAPI schema)
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-5-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:16 +03:00
|
|
|
type_register_static(&sev_common_info);
|
2020-06-04 09:42:13 +03:00
|
|
|
type_register_static(&sev_guest_info);
|
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 <brijesh.singh@amd.com>
Co-developed-by: Michael Roth <michael.roth@amd.com>
Acked-by: Markus Armbruster <armbru@redhat.com> (for QAPI schema)
Signed-off-by: Michael Roth <michael.roth@amd.com>
Co-developed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Signed-off-by: Pankaj Gupta <pankaj.gupta@amd.com>
Message-ID: <20240530111643.1091816-8-pankaj.gupta@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-30 14:16:19 +03:00
|
|
|
type_register_static(&sev_snp_guest_info);
|
2018-03-08 15:48:41 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
type_init(sev_register_types);
|