From: Markus Armbruster <armbru@redhat.com>
To: Michael Roth <michael.roth@amd.com>
Cc: <qemu-devel@nongnu.org>, <pbonzini@redhat.com>,
<berrange@redhat.com>, <eduardo@habkost.net>,
<thomas.lendacky@amd.com>, <huibo.wang@amd.com>
Subject: Re: [PATCH v3 3/3] i386/sev: Add KVM_EXIT_SNP_REQ_CERTS support for certificate-fetching
Date: Tue, 27 Oct 2026 13:38:41 +0100 [thread overview]
Message-ID: <87pkwv71ym.fsf@pond.sub.org> (raw)
In-Reply-To: <20261026172300.2061829-4-michael.roth@amd.com> (Michael Roth's message of "Mon, 26 Oct 2026 12:21:49 -0500")
Michael Roth <michael.roth@amd.com> writes:
> 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 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 in QEMU.
>
> 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 prior commit. Once the callback
> is issued (after the next KVM_RUN), the attestation report will have
> been fetched, so the report and certificate data fetched by QEMU should
> be consistent with one another, and the certificate lock can then be
> released. The included documentation updates have more details on how
> this is handled.
>
> [1] "Guest Hypervisor Communication Block (GHCB) Standardization",
> https://www.amd.com/en/developer/sev.html
>
> Co-developed-by: Melody Wang <huibo.wang@amd.com>
> Signed-off-by: Melody Wang <huibo.wang@amd.com>
> Signed-off-by: Michael Roth <michael.roth@amd.com>
> ---
> docs/system/i386/amd-memory-encryption.rst | 77 +++++
> qapi/qom.json | 23 +-
> target/i386/kvm/kvm.c | 10 +
> target/i386/sev-system-stub.c | 5 +
> target/i386/sev.c | 338 +++++++++++++++++++++
> target/i386/sev.h | 3 +-
> 6 files changed, 454 insertions(+), 2 deletions(-)
>
> diff --git a/docs/system/i386/amd-memory-encryption.rst b/docs/system/i386/amd-memory-encryption.rst
> index 6c23f3535f..da6f1a3693 100644
> --- a/docs/system/i386/amd-memory-encryption.rst
> +++ b/docs/system/i386/amd-memory-encryption.rst
> @@ -228,6 +228,83 @@ schema for the 'sev-snp-guest' object)::
> -machine ...,confidential-guest-support=sev0 \
> -object sev-snp-guest,id=sev0,cbitpos=51,reduced-phys-bits=1
>
> +Certificate-fetching (SEV-SNP)
> +------------------------------
> +
> +When an SEV-SNP guest requests an attestation report from the host, it may
> +optionally request that the host also deliver the certificates (and
> +potentially other accompanying data) as part of the response.
> +
> +QEMU can be configured to provide this certificate data in the following
> +manner::
> +
> + # ${QEMU} \
> + -machine ...,confidential-guest-support=sev0 \
> + -object sev-snp-guest,id=sev0,cbitpos=51,reduced-phys-bits=1,certs-filename=<certs>
> +
> +where the format of the file is defined in the SEV-ES Guest-Hypervisor
> +Communication Block Standardization (GHCB) v2.04, section 4.1.8.1, as::
> +
> + Returned certificates are identified in a table starting at offset 0x0 of
> + [the file]. Each entry consists of a 16-byte GUID, a 4-byte offset from
> + [the file] to where the certificate data starts and a 4-byte length
> + representing the length of the certificate data. The table is terminated
> + with an entry containing all zeroes for the GUID, offset and length.
> +
> + struct cert_table {
> + struct {
> + unsigned char guid[16];
> + uint32 offset;
> + uint32 length;
> + } cert_table_entry[];
> + };
> +
> +Because QEMU supplies the certificate to the hypervisor prior to the
> +hypervisor actually issuing an attestation request, there is potential for
> +the certificate data to becoming stale due to a firmware upgrade or other
> +host management activities. The ioctl which enables certificate-fetching
> +support via the KVM hypervisor, KVM_SEV_SNP_ENABLE_REQ_CERTS, documents
> +the following suggested scheme as part of its linux documentation (v7.3
> +at the time of this writing), and it is highly recommended that all software
> +interacting with these certificates, or performing operations that may
> +affect their validity, adopt this same scheme for interoperability::
> +
> + The recommended scheme to do this is to use file locking (e.g. via
> + fcntl()'s F_OFD_SETLK) in the following manner:
> +
> + - Prior to obtaining/providing certificate data as part of servicing an
> + exit type of ``KVM_EXIT_SNP_REQ_CERTS``, the VMM should obtain a
> + shared/read or exclusive/write lock on the certificate blob file before
> + reading it and returning it to KVM, and continue to hold the lock until
> + the attestation request is actually sent to firmware. To facilitate
> + this, the VMM can set the ``immediate_exit`` flag of kvm_run just after
> + supplying the certificate data, and just before resuming the vCPU.
> + This will ensure the vCPU will exit again to userspace with ``-EINTR``
> + after it finishes fetching the attestation request from firmware, at
> + which point the VMM can safely drop the file lock.
> +
> + - Tools/libraries that perform updates to SNP firmware TCB values or
> + endorsement keys (e.g. via /dev/sev interfaces such as ``SNP_COMMIT``,
> + ``SNP_SET_CONFIG``, or ``SNP_VLEK_LOAD``, see
> + Documentation/virt/coco/sev-guest.rst for more details) in such a way
> + that the certificate blob needs to be updated, should similarly take an
> + exclusive lock on the certificate blob for the duration of any updates
> + to endorsement keys or the certificate blob contents to ensure that
> + VMMs using the above scheme will not return certificate blob data that
> + is out of sync with the endorsement key used by firmware at the time
> + the attestation request is actually issued.
> +
> + This scheme is recommended so that tools can use a fairly generic/natural
> + approach to synchronizing firmware/certificate updates via file-locking,
> + which should make it easier to maintain interoperability across
> + tools/VMMs/vendors.
> +
> +As such, QEMU implements this same scheme by waiting for a read-lock on the
> +file containing the certificate data before supplying any data it contains.
> +In order to ensure that the lock is not released until after the hypervisor
> +is finished fetching the attestation report for the guest, the lock is held
> +until a subsequent exit from the hypervisor that indicates the attestation
> +report has already been fetched, as which point QEMU will drop the lock.
>
> Debugging
> ---------
> diff --git a/qapi/qom.json b/qapi/qom.json
> index 4810d53e58..8884a1eb66 100644
> --- a/qapi/qom.json
> +++ b/qapi/qom.json
> @@ -1104,6 +1104,25 @@
> # @tsc-frequency: set secure TSC frequency. Only valid if Secure TSC
> # is enabled (default: zero) (since 11.1)
> #
> +# @certs-filename: Certificate data that can be passed to guests as
> +# part of an attestion request. See the
> +# :doc:`/system/i386/amd-memory-encryption` documentation for more
> +# details on the usage and file format.
> +# (default: none) (since: 11.2)
> +#
> +# @certs-timeout: Maximum time in milliseconds to wait to obtain a
> +# read lock on the certificate file specified by @certs-filename.
> +# This is not a cumulative value and only affects how long QEMU
> +# waits before returning execution to the vCPU and informing the
> +# guest of the timeout, so the guest can still continue retrying
> +# for as long as it likes, which for linux guests at the time of
> +# this writing will be about 60 seconds before the guest gives
> +# up and disables further requests. If this guest-side timeout is
> +# insufficient, set this higher to allow more time to fetch the
> +# certificate. If the guest-side timeout is sufficient,
> +# set this lower to reduce the likelihood of soft lockups in the
> +# guest. (default: 100) (since: 11.2)
> +#
> # Since: 9.1
> ##
> { 'struct': 'SevSnpGuestProperties',
> @@ -1117,7 +1136,9 @@
> '*host-data': 'str',
> '*vcek-disabled': 'bool',
> '*secure-tsc': 'bool',
> - '*tsc-frequency': 'uint32' } }
> + '*tsc-frequency': 'uint32',
> + '*certs-filename': 'str',
> + '*certs-timeout': 'uint32' } }
Why uint32 for time? We commonly use 'int'.
Hmm, see [*] below.
>
> ##
> # @TdxGuestProperties:
> diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
> index da922f72d7..9f7bdf9618 100644
> --- a/target/i386/kvm/kvm.c
> +++ b/target/i386/kvm/kvm.c
> @@ -6651,6 +6651,16 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
> break;
> }
> ret = 0;
> + break;
> + case KVM_EXIT_SNP_REQ_CERTS:
> + if (!sev_snp_enabled()) {
> + error_report("KVM: Encountered a certificate request exit for a "
> + "non-SEV-SNP guest.");
> + ret = -1;
> + } else {
> + ret = kvm_handle_snp_req_certs(cs, run);
> + }
> +
> break;
> default:
> fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason);
> diff --git a/target/i386/sev-system-stub.c b/target/i386/sev-system-stub.c
> index d97536cca1..e53f1bbefc 100644
> --- a/target/i386/sev-system-stub.c
> +++ b/target/i386/sev-system-stub.c
> @@ -34,3 +34,8 @@ int sev_es_save_reset_vector(void *flash_ptr, uint64_t flash_size)
> void pc_system_parse_sev_metadata(uint8_t *flash_ptr, size_t flash_size)
> {
> }
> +
> +int kvm_handle_snp_req_certs(CPUState *cpu, struct kvm_run *run)
> +{
> + g_assert_not_reached();
> +}
> diff --git a/target/i386/sev.c b/target/i386/sev.c
> index 11072b00dc..3cb2e9cd0c 100644
> --- a/target/i386/sev.c
> +++ b/target/i386/sev.c
> @@ -186,6 +186,8 @@ struct SevSnpGuestState {
> uint8_t *id_auth;
> char *host_data;
> uint32_t tsc_khz;
> + char *certs_filename;
> + uint32_t certs_timeout;
>
> struct kvm_sev_snp_launch_start kvm_start_conf;
> struct kvm_sev_snp_launch_finish kvm_finish_conf;
> @@ -1701,6 +1703,278 @@ sev_snp_launch_finish(SevCommonState *sev_common)
> sev_set_guest_state(sev_common, SEV_STATE_RUNNING);
> }
>
> +/*
> + * Cases where -EAGAIN is returned on an error path are expected to terminate
> + * after the next call (e.g. via a qemu_open() error) if they are not transient
> + * issues. These potentially-transient issues are still logged however, since
> + * they are not expected on a well-behaved system.
> + */
> +static int open_certs_locked(SevSnpGuestState *sev_snp_guest)
> +{
> + struct stat locked_file, current_file;
> + int fd, ret;
> +
> + fd = qemu_open(sev_snp_guest->certs_filename, O_RDONLY, NULL);
> + if (fd == -1) {
> + error_report_once("Unable to open certificate file: %s",
> + strerror(errno));
> + return -errno;
> + }
> +
> + if (fstat(fd, &locked_file) == -1) {
> + error_report_once("Unable to check status of certificate file: %s",
> + strerror(errno));
> + ret = -errno;
> + goto out_close;
> + }
> +
> + ret = qemu_lock_fd(fd, 0, 0, false);
> + if (ret == -EACCES) {
> + /*
> + * F_SETLK is documented to potentially return either EACCES or EAGAIN
> + * for contended file locks.
> + */
> + ret = -EAGAIN;
> + } else if (ret == -EDEADLK) {
> + error_report_once("Potential deadlock encountered while trying "
> + "to lock the certificate file");
> + ret = -EAGAIN;
> + }
> +
> + if (ret) {
> + if (ret != -EAGAIN) {
> + error_report_once("Error while trying to lock certificate file: %s",
> + strerror(-ret));
> + }
> + goto out_close;
> + }
> +
> + if (stat(sev_snp_guest->certs_filename, ¤t_file) == -1) {
> + error_report_once("Certificate file no longer present: %s",
> + strerror(errno));
> + ret = -EAGAIN;
> + goto out_close;
> + }
> +
> + /*
> + * Locked files should not be changing; this violates the locking
> + * protocol assumed by this implementation. Indicate the need to
> + * retry to the caller, but make sure to log it first.
> + */
> + if (locked_file.st_ino != current_file.st_ino ||
> + locked_file.st_dev != current_file.st_dev) {
> + error_report_once("Locked certificate file was recreated");
> + ret = -EAGAIN;
> + goto out_close;
> + }
> +
> + /*
> + * The locked file is intact and as-expected, and it has not been replaced
> + * since then, so the fd should be okay to use.
> + */
> + return fd;
> +
> +out_close:
> + close(fd);
> + return ret;
> +}
> +
> +static void close_certs(int fd)
> +{
> + qemu_unlock_fd(fd, 0, 0);
> + close(fd);
> +}
> +
> +static ssize_t get_certs_size(int fd)
> +{
> + ssize_t size;
> +
> + size = lseek(fd, 0, SEEK_END);
> + if (size == -1) {
> + error_report_once("Error while determining the size of the certificate file: %s",
> + strerror(errno));
> + return -errno;
> + }
> +
> + return size;
> +}
> +
> +static int read_certs(int fd, void *buf, size_t buf_len)
> +{
> + ssize_t n;
> +
> + n = lseek(fd, 0, SEEK_SET);
> + if (n == -1) {
> + error_report_once("Error while setting certificate file position: %s",
> + strerror(errno));
> + return -errno;
> + }
> +
> + while ((n = read(fd, buf, buf_len)) != 0) {
> + if (n == -1) {
> + if (errno == EINTR) {
> + continue;
> + }
> +
> + error_report_once("Error reading the certificate file: %s",
> + strerror(errno));
> + return -errno;
> + }
> + buf += n;
> + buf_len -= n;
> + }
> +
> + return 0;
> +}
> +
> +static void snp_release_certs_lock(CPUState *cpu, run_on_cpu_data data)
> +{
> + close_certs(data.host_int);
> +}
> +
> +/*
> + * NOTE: It is not expected that the guest will call this in a tight loop
> + * where error reporting would flood logs. A failed certificate fetch results
> + * in a failed attestation request, which results in a disabled attestation
> + * driver in the guest usually.
> + *
> + * However, one instance of such an error is usually enough of a clue to
> + * to identify the component of the system that should be investigated.
> + *
> + * So, to guard against a malicious guest trying to flood host logs, while
> + * still providing reasonable debug/error information to the user, use
> + * error_report_once() throughout this function and its supporting helpers.
> + */
> +int kvm_handle_snp_req_certs(CPUState *cpu, struct kvm_run *run)
> +{
> + struct kvm_exit_snp_req_certs *req_certs = &run->snp_req_certs;
> + SevSnpGuestState *sev_snp_guest;
> + ssize_t certs_size;
> + uint32_t npages;
> + void *guest_buf;
> + int64_t t0_ms;
> + hwaddr buf_sz;
> + int ret, fd;
> + hwaddr gpa;
> +
> + gpa = req_certs->gpa;
> + npages = req_certs->npages;
> +
> + sev_snp_guest = SEV_SNP_GUEST(MACHINE(qdev_get_machine())->cgs);
> + if (!sev_snp_guest->certs_filename) {
> + req_certs->ret = 0;
> + return 0;
> + }
> +
> + /*
> + * By default, any errors encountered below will be forwarded to the guest
> + * as an EIO. This will likely result in the guest disabling its driver, but
> + * it's better than crashing QEMU.
> + *
> + * Leave the special cases, SUCCESS/ENOSPC/EAGAIN, to re-set the guest
> + * return code as-needed.
> + *
> + * Errors that are useful for debugging QEMU will still be logged, with care
> + * to avoid busy/EAGAIN paths/etc.
> + */
> + req_certs->ret = EIO;
> +
> + /*
> + * -EAGAIN from open_certs_locked() indicates that a lock could not be
> + * obtained on the certificate file. It would be possible to set
> + * req_certs->ret = EAGAIN to immediately inform the requesting vCPU of
> + * this condition so that it can retry again later, however, linux guests
> + * are currently hard-limited to a 60 second timeout, at which point they
> + * will assume misbehavior and refuse to continue issuing attestation
> + * requests from that point forward.
> + *
> + * Avoid risking triggering this by instead busy-waiting on the QEMU side,
> + * which allows more time for QEMU to wait on potentially long-running
> + * tasks like SNP firmware updates/etc. which may be holding an exclusive
> + * lock on the certificate file.
> + *
> + * The down-side to doing things this way is that too long of a busy-wait
> + * will result in soft-lockups in the guest, but the guest will otherwise
> + * continue normally afterward.
> + *
> + * If the QEMU-side timeout is reached, then just go ahead and indicate
> + * EAGAIN to the guest, at which point the above-mentioned guest-side
> + * timeout will trigger if QEMU's timeout exceeds that of the guest. But
> + * that's better than killing the vCPU, which is the only viable
> + * alternative at that point.
> + */
> + t0_ms = g_get_monotonic_time() / 1000;
> +
> + do {
> + fd = open_certs_locked(sev_snp_guest);
> +
> + if (fd == -EAGAIN) {
> + int64_t t1_ms = g_get_monotonic_time() / 1000;
> +
> + if (t1_ms - t0_ms > sev_snp_guest->certs_timeout) {
[*] Left operand is int64_t, and the right operand is uint32_t. The
right operand is converted to int64_t, which is safe, but to see that,
you need to know the "usual arithmetic conversions (C99 § 6.3.1.8)
intimately. Suggest to make the right operand int64_t to avoid such
brain burn.
> + req_certs->ret = EAGAIN;
> + return 0;
> + }
> +
> + /*
> + * If some other process (QEMU only ever takes a read lock) has an
> + * exclusive lock on the certificate file, then it is likely because
> + * a firmware update or other long-running operation is taking place;
> + * it's a waste to re-try at a high rate.
> + */
> + g_usleep(1000);
> + } else if (fd < 0) {
> + return 0;
> + }
> + } while (fd == -EAGAIN);
> +
> + certs_size = get_certs_size(fd);
> + if (certs_size < 0) {
> + goto err_close;
> + }
> +
> + buf_sz = (hwaddr)npages * TARGET_PAGE_SIZE;
> + if (buf_sz < certs_size) {
> + /* Communicate to guest that more pages are needed. */
> + req_certs->ret = ENOSPC;
> + req_certs->npages = DIV_ROUND_UP(certs_size, TARGET_PAGE_SIZE);
> + goto err_close;
> + }
> +
> + guest_buf = address_space_map(&address_space_memory, gpa, &buf_sz, true,
> + MEMTXATTRS_UNSPECIFIED);
> + if (!guest_buf) {
> + error_report_once("Unable to map guest buffer to provide "
> + "certificate data.");
> + goto err_close;
> + }
> +
> + if (buf_sz < (hwaddr)npages * TARGET_PAGE_SIZE) {
> + error_report_once("Unable to map the full guest buffer to provide "
> + "certificate data.");
> + address_space_unmap(&address_space_memory, guest_buf, buf_sz, true, 0);
> + goto err_close;
> + }
> +
> + ret = read_certs(fd, guest_buf, buf_sz);
> + address_space_unmap(&address_space_memory, guest_buf, buf_sz, true, buf_sz);
> +
> + if (!ret) {
> + /*
> + * Looks good, return the certificate to the guest and prepare to
> + * release the file lock once KVM signals completion.
> + */
> + kvm_add_immediate_exit_callback(cpu, snp_release_certs_lock,
> + RUN_ON_CPU_HOST_INT(fd));
> +
> + req_certs->ret = 0;
> + return 0;
> + }
> +
> +err_close:
> + close_certs(fd);
> + return 0;
> +}
>
> static void
> sev_vm_state_change(void *opaque, bool running, RunState state)
> @@ -2051,6 +2325,41 @@ static int sev_snp_kvm_init(ConfidentialGuestSupport *cgs, Error **errp)
> g_free(sev_snp_guest->kernel_hashes_data);
> sev_snp_guest->kernel_hashes_data = NULL;
>
> + if (sev_snp_guest->certs_filename) {
> + unsigned long certs_attr;
> + struct kvm_device_attr attr = {
> + .group = KVM_X86_GRP_SEV,
> + .attr = KVM_X86_SEV_SNP_REQ_CERTS,
> + .addr = (unsigned long) &certs_attr
> + };
> + int ret;
> +
> + if (!kvm_check_extension(kvm_state, KVM_CAP_SYS_ATTRIBUTES) ||
> + !kvm_check_extension(kvm_state, KVM_CAP_IMMEDIATE_EXIT)) {
> + return -EINVAL;
> + }
> +
> + ret = kvm_ioctl(kvm_state, KVM_GET_DEVICE_ATTR, &attr);
> + if (ret < 0) {
> + error_setg(errp, "Certificate-fetching attribute not present.");
> + return ret;
> + }
> +
> + if (!certs_attr) {
> + error_setg(errp, "Certificate-fetching attribute not set.");
> + return -EINVAL;
> + }
> +
> + ret = sev_ioctl(SEV_COMMON(sev_snp_guest)->sev_fd,
> + KVM_SEV_SNP_ENABLE_REQ_CERTS,
> + NULL, NULL);
> + if (ret) {
> + error_setg(errp, "Failed to enable support for SEV-SNP "
> + "certificate-fetching requests.");
> + return ret;
> + }
> + }
> +
> return 0;
> }
>
> @@ -3320,6 +3629,26 @@ sev_snp_guest_set_tsc_frequency(Object *obj, Visitor *v, const char *name,
> SEV_SNP_GUEST(obj)->tsc_khz = value / 1000;
> }
>
> +static char *
> +sev_snp_guest_get_certs_filename(Object *obj, Error **errp)
> +{
> + SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
> +
> + return g_strdup(sev_snp_guest->certs_filename);
> +}
> +
> +static void
> +sev_snp_guest_set_certs_filename(Object *obj, const char *value, Error **errp)
> +{
> + SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
> +
> + if (sev_snp_guest->certs_filename) {
> + g_free(sev_snp_guest->certs_filename);
> + }
> +
> + sev_snp_guest->certs_filename = value ? g_strdup(value) : NULL;
> +}
> +
> static void
> sev_snp_guest_class_init(ObjectClass *oc, const void *data)
> {
> @@ -3361,6 +3690,12 @@ sev_snp_guest_class_init(ObjectClass *oc, const void *data)
> object_class_property_add(oc, "tsc-frequency", "uint32",
> sev_snp_guest_get_tsc_frequency,
> sev_snp_guest_set_tsc_frequency, NULL, NULL);
> + object_class_property_add_str(oc, "certs-filename",
> + sev_snp_guest_get_certs_filename,
> + sev_snp_guest_set_certs_filename);
> + object_class_property_add_uint32_ptr(oc, "certs-timeout",
> + offsetof(SevSnpGuestState, certs_timeout),
> + OBJ_PROP_FLAG_READWRITE);
> }
>
> static void
> @@ -3374,6 +3709,8 @@ sev_snp_guest_instance_init(Object *obj)
> /* default init/start/finish params for kvm */
> sev_snp_guest->kvm_start_conf.policy = DEFAULT_SEV_SNP_POLICY;
> sev_set_feature(SEV_COMMON(sev_snp_guest), SVM_SEV_FEAT_SNP_ACTIVE, true);
> +
> + sev_snp_guest->certs_timeout = 100;
> }
>
> static void
> @@ -3387,6 +3724,7 @@ sev_snp_guest_finalize(Object *obj)
> g_free(sev_snp_guest->id_auth_base64);
> g_free(sev_snp_guest->id_auth);
> g_free(sev_snp_guest->host_data);
> + g_free(sev_snp_guest->certs_filename);
> }
>
> /* guest info specific to sev-snp */
> diff --git a/target/i386/sev.h b/target/i386/sev.h
> index 7725f92e19..4d9e9b44b4 100644
> --- a/target/i386/sev.h
> +++ b/target/i386/sev.h
> @@ -15,6 +15,7 @@
> #define I386_SEV_H
>
> #include "target/i386/svm.h"
> +#include "system/kvm.h"
>
> #ifndef CONFIG_USER_ONLY
> #include CONFIG_DEVICES /* CONFIG_SEV */
> @@ -198,5 +199,5 @@ void pc_system_parse_sev_metadata(uint8_t *flash_ptr, size_t flash_size);
>
> uint32_t sev_get_cbit_position(void);
> uint32_t sev_get_reduced_phys_bits(void);
> -
> +int kvm_handle_snp_req_certs(CPUState *cpu, struct kvm_run *run);
> #endif
prev parent reply other threads:[~2026-10-27 12:39 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-26 17:21 [PATCH v3 0/3] SEV-SNP: Add support for SNP certificate fetching Michael Roth
2026-10-26 17:21 ` [PATCH v3 1/3] hw/cpu: Add async_run_on_cpu_after_accel() Michael Roth
2026-10-26 17:21 ` [PATCH v3 2/3] accel/kvm: Add kvm_immediate_exit callback infrastructure Michael Roth
2026-10-26 17:21 ` [PATCH v3 3/3] i386/sev: Add KVM_EXIT_SNP_REQ_CERTS support for certificate-fetching Michael Roth
2026-10-27 12:38 ` Markus Armbruster [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87pkwv71ym.fsf@pond.sub.org \
--to=armbru@redhat.com \
--cc=berrange@redhat.com \
--cc=eduardo@habkost.net \
--cc=huibo.wang@amd.com \
--cc=michael.roth@amd.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=thomas.lendacky@amd.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.