[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v3 38/49] i386/sev: Add handling to encrypt/finalize guest launch
From: |
Michael Roth |
Subject: |
[PATCH v3 38/49] i386/sev: Add handling to encrypt/finalize guest launch data |
Date: |
Wed, 20 Mar 2024 03:39:34 -0500 |
From: Brijesh Singh <brijesh.singh@amd.com>
Process any queued up launch data and encrypt/measure it into the SNP
guest instance prior to initial guest launch.
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Co-authored-by: Michael Roth <michael.roth@amd.com>
Signed-off-by: Michael Roth <michael.roth@amd.com>
---
target/i386/sev.c | 101 ++++++++++++++++++++++++++++++++++++++-
target/i386/trace-events | 2 +
2 files changed, 102 insertions(+), 1 deletion(-)
diff --git a/target/i386/sev.c b/target/i386/sev.c
index 9f63a41f08..4155342e72 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -749,6 +749,61 @@ out:
return ret;
}
+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;
+ 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;
+ }
+
+ update.uaddr = (__u64)(unsigned long)data->hva;
+ update.gfn_start = data->gpa >> TARGET_PAGE_BITS;
+ update.len = data->len;
+ update.type = data->type;
+
+ trace_kvm_sev_snp_launch_update(data->hva, data->gpa, data->len,
+ snp_page_type_to_str(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;
+ }
+
+ ret = sev_ioctl(SEV_COMMON(sev_snp_guest)->sev_fd,
+ KVM_SEV_SNP_LAUNCH_UPDATE,
+ &update, &fw_error);
+ if (ret) {
+ error_report("SNP_LAUNCH_UPDATE ret=%d fw_error=%d '%s'",
+ ret, fw_error, fw_error_to_str(fw_error));
+ }
+
+out:
+ return ret;
+}
+
static int
sev_launch_update_data(SevGuestState *sev_guest, uint8_t *addr, uint64_t len)
{
@@ -894,6 +949,46 @@ sev_launch_finish(SevGuestState *sev_guest)
migrate_add_blocker(&sev_mig_blocker, &error_fatal);
}
+static void
+sev_snp_launch_finish(SevSnpGuestState *sev_snp)
+{
+ int ret, error;
+ Error *local_err = NULL;
+ OvmfSevMetadata *metadata;
+ SevLaunchUpdateData *data;
+ struct kvm_sev_snp_launch_finish *finish = &sev_snp->kvm_finish_conf;
+
+ 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_snp)->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);
+ }
+
+ sev_set_guest_state(SEV_COMMON(sev_snp), 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);
+ }
+}
+
+
static void
sev_vm_state_change(void *opaque, bool running, RunState state)
{
@@ -901,7 +996,11 @@ sev_vm_state_change(void *opaque, bool running, RunState
state)
if (running) {
if (!sev_check_state(sev_common, SEV_STATE_RUNNING)) {
- sev_launch_finish(SEV_GUEST(sev_common));
+ if (sev_snp_enabled()) {
+ sev_snp_launch_finish(SEV_SNP_GUEST(sev_common));
+ } else {
+ sev_launch_finish(SEV_GUEST(sev_common));
+ }
}
}
}
diff --git a/target/i386/trace-events b/target/i386/trace-events
index cb26d8a925..873a7e424e 100644
--- a/target/i386/trace-events
+++ b/target/i386/trace-events
@@ -12,3 +12,5 @@ kvm_sev_launch_finish(void) ""
kvm_sev_launch_secret(uint64_t hpa, uint64_t hva, uint64_t secret, int len)
"hpa 0x%" PRIx64 " hva 0x%" PRIx64 " data 0x%" PRIx64 " len %d"
kvm_sev_attestation_report(const char *mnonce, const char *data) "mnonce %s
data %s"
kvm_sev_snp_launch_start(uint64_t policy, char *gosvw) "policy 0x%" PRIx64 "
gosvw %s"
+kvm_sev_snp_launch_update(void *addr, uint32_t gpa, uint64_t len, const char
*type) "addr %p gpa 0x%x len 0x%" PRIx64 " (%s page)"
+kvm_sev_snp_launch_finish(char *id_block, char *id_auth, char *host_data)
"id_block %s id_auth %s host_data %s"
--
2.25.1
- Re: [PATCH v3 32/49] i386/sev: Don't return launch measurements for SEV-SNP guests, (continued)
- [PATCH v3 33/49] kvm: Make kvm_convert_memory() non-static, Michael Roth, 2024/03/20
- [PATCH v3 34/49] i386/sev: Add KVM_EXIT_VMGEXIT handling for Page State Changes, Michael Roth, 2024/03/20
- [PATCH v3 35/49] i386/sev: Add KVM_EXIT_VMGEXIT handling for Page State Changes (MSR-based), Michael Roth, 2024/03/20
- [PATCH v3 36/49] i386/sev: Add KVM_EXIT_VMGEXIT handling for Extended Guest Requests, Michael Roth, 2024/03/20
- [PATCH v3 37/49] i386/sev: Add the SNP launch start context, Michael Roth, 2024/03/20
- [PATCH v3 38/49] i386/sev: Add handling to encrypt/finalize guest launch data,
Michael Roth <=
- [PATCH v3 39/49] i386/sev: Set CPU state to protected once SNP guest payload is finalized, Michael Roth, 2024/03/20
- [PATCH v3 40/49] hw/i386/sev: Add function to get SEV metadata from OVMF header, Michael Roth, 2024/03/20
- [PATCH v3 03/49] scripts/update-linux-headers: Add bits.h to file imports, Michael Roth, 2024/03/20
- [PATCH v3 41/49] i386/sev: Add support for populating OVMF metadata pages, Michael Roth, 2024/03/20
- [PATCH v3 42/49] i386/sev: Add support for SNP CPUID validation, Michael Roth, 2024/03/20
- [PATCH v3 43/49] qapi, i386: Move kernel-hashes to SevCommonProperties, Michael Roth, 2024/03/20