Hi Michael,

On 18/12/2024 15:49, Michael Roth wrote:
The GHCB specification[1] defines a VMGEXIT-based Guest Request
hypercall to allow an SNP guest to issue encrypted requests directly to
SNP firmware to do things like query the attestation report for the
guest. These are generally handled purely in the kernel.

In some some cases, it's useful for the host to be able to additionally
supply the certificate chain for the signing key that SNP firmware uses
to sign these attestation reports. To allow for this, the GHCB
specification defines an Extended Guest Request where this certificate
data can be provided in a special format described in the GHCB spec.
This certificate data may be global or guest-specific depending on how
the guest was configured. Rather than providing interfaces to manage
these within the kernel, KVM provides a new KVM_EXIT_SNP_REQ_CERTS exit
to request the certificate contents from userspace. Implement support
for that here.

To synchronize delivery of the certificates to the guest in a way where
they will not be rendered invalid by updates to SNP firmware or
attestation singing/endorsement keys by management tools outside the
purview of QEMU, it is expected by users of KVM_EXIT_SNP_REQ_CERTS to
obtain a shared/read lock on the certificate file prior to delivering
them back to KVM. Only after this will the attestation report be
retrieved from firmware and bundled with the certificate data, so QEMU
must continue to hold the file lock until KVM confirms that the
attestation report has been retrieved/bundled. This confirmation is done
by way of the kvm_immediate_exit callback infrastructure that was
introduced in a previous patch.

[1] "Guest Hypervisor Communication Block (GHCB) Standardization",
     https://www.amd.com/en/developer/sev.html

Signed-off-by: Michael Roth <michael.r...@amd.com>
---
  qapi/qom.json                 |  23 +++-
  target/i386/kvm/kvm.c         |  10 ++
  target/i386/sev-sysemu-stub.c |   5 +
  target/i386/sev.c             | 249 ++++++++++++++++++++++++++++++++++
  target/i386/sev.h             |   2 +
  5 files changed, 288 insertions(+), 1 deletion(-)


...

@@ -2393,6 +2613,26 @@ sev_snp_guest_set_host_data(Object *obj, const char 
*value, Error **errp)
      memcpy(finish->host_data, blob, len);
  }
+static char *
+sev_snp_guest_get_certs_path(Object *obj, Error **errp)
+{
+    SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
+
+    return g_strdup(sev_snp_guest->certs_path);
+}
+
+static void
+sev_snp_guest_set_certs_path(Object *obj, const char *value, Error **errp)
+{
+    SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
+
+    if (sev_snp_guest->certs_path) {
+        g_free(sev_snp_guest->certs_path);
+    }
+

I think there needs to be a check here (sev_snp_guest_set_certs_filename() in snp-certs-rfc2)
or sev_snp_kvm_init() that the cert file path exists as otherwise once
the guest boots and there's a request from the guest to the host to get
the cert, the failure in open_certs_locked() will crash the guest.

Regards,
Liam

+    sev_snp_guest->certs_path = value ? g_strdup(value) : NULL;
+}
+
  static void
  sev_snp_guest_class_init(ObjectClass *oc, void *data)
  {
@@ -2428,6 +2668,9 @@ sev_snp_guest_class_init(ObjectClass *oc, void *data)
      object_class_property_add_str(oc, "host-data",
                                    sev_snp_guest_get_host_data,
                                    sev_snp_guest_set_host_data);
+    object_class_property_add_str(oc, "certs-path",
+                                  sev_snp_guest_get_certs_path,
+                                  sev_snp_guest_set_certs_path);
  }

Reply via email to