[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250428195113.392303-1-michael.roth@amd.com>
Date: Mon, 28 Apr 2025 14:51:11 -0500
From: Michael Roth <michael.roth@....com>
To: <kvm@...r.kernel.org>
CC: <linux-coco@...ts.linux.dev>, <linux-kernel@...r.kernel.org>,
<pbonzini@...hat.com>, <seanjc@...gle.com>, <jroedel@...e.de>,
<thomas.lendacky@....com>, <liam.merwick@...cle.com>,
<dionnaglaze@...gle.com>, <huibo.wang@....com>
Subject: [PATCH v6 0/2] SEV-SNP: Add KVM support for SNP certificate fetching
This patchset is also available at:
https://github.com/amdese/linux/commits/snp-certs-v6
and is based on top of kvm/next (45eb29140e68)
Overview
--------
The GHCB 2.0 specification defines 2 GHCB request types to allow SNP guests
to send encrypted messages/requests to firmware: SNP Guest Requests and SNP
Extended Guest Requests. These encrypted messages are used for things like
servicing attestation requests issued by the guest. Implementing support for
these is required to be fully GHCB-compliant.
For the most part, KVM only needs to handle forwarding these requests to
firmware (to be issued via the SNP_GUEST_REQUEST firmware command defined
in the SEV-SNP Firmware ABI), and then forwarding the encrypted response to
the guest.
However, in the case of SNP Extended Guest Requests, the host is also
able to provide the certificate data corresponding to the endorsement key
used by firmware to sign attestation report requests. This certificate data
is provided by userspace because:
1) It allows for different keys/key types to be used for each particular
guest with requiring any sort of KVM API to configure the certificate
table in advance on a per-guest basis.
2) It provides additional flexibility with how attestation requests might
be handled during live migration where the certificate data for
source/dest might be different.
3) It allows all synchronization between certificates and firmware/signing
key updates to be handled purely by userspace rather than requiring
some in-kernel mechanism to facilitate it. [1]
To support fetching certificate data from userspace, a new KVM
KVM_EXIT_SNP_REQ_CERTS exit type is used to fetch the data similarly to
KVM_EXIT_MMIO/etc, with an associate KVM capability to detect/enable the
exits depending on whether userspace has been configured to provide
certificate data.
[1] https://lore.kernel.org/kvm/ZS614OSoritrE1d2@google.com/
Testing
-------
For testing this via QEMU, use the following tree:
https://github.com/amdese/qemu/commits/snp-certs-rfc3-wip0
A basic command-line invocation for SNP with certificate data supplied
would be:
qemu-system-x86_64 -smp 32,maxcpus=255 -cpu EPYC-Milan-v2
-machine q35,confidential-guest-support=sev0,memory-backend=ram1
-object memory-backend-memfd,id=ram1,size=4G,share=true,reserve=false
-object sev-snp-guest,id=sev0,cbitpos=51,reduced-phys-bits=1,id-auth=,certs-filename=/home/mroth/cert.blob
-bios OVMF.fd
Something like the following simple example can be used to simulate an
exclusive lock being held on the certificate by management tools performing an
update:
#include <stdlib.h>
#include <stdio.h>
#define __USE_GNU
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <stdbool.h>
#include <sys/types.h>
#include <sys/stat.h>
int main(int argc, void **argv)
{
int ret, fd, i = 0;
char *path = argv[1];
struct flock fl = {
.l_whence = SEEK_SET,
.l_start = 0,
.l_len = 0,
.l_type = F_WRLCK
};
fd = open(path, O_RDWR);
ret = fcntl(fd, F_OFD_SETLK, &fl);
if (ret) {
printf("error locking file, ret %d errno %d\n", ret, errno);
return ret;
}
while (true) {
i++;
printf("now holding lock (%d seconds elapsed)...\n", i);
usleep(1000 * 1000);
}
return 0;
}
The format of the certificate blob is defined in the GHCB 2.0 specification,
but if it's not being parsed on the guest-side then random data will suffice
for testing the KVM bits.
Any feedback/review is appreciated.
Thanks!
-Mike
Changes since v5:
* Drop KVM capability in favor of a KVM device attribute to advertise
support to userspace, and introduce a new KVM_SEV_SNP_ENABLE_REQ_CERTS
command to switch it on (Sean)
* Only allow certificate-fetching to be enabled prior to starting any
vCPUs to avoid races/unexpected behavior (Sean)
* Drop unecessary cast in SNP_GUEST_VMM_ERR_GENERIC definition (Sean)
* Add checks to enforce that userspace only uses EIO to indicate generic
errors when fetching certificates to ensure that other error codes remain
usable for other/future error conditions (Joerg, Sean)
* Clean up setting of GHCB error codes via a small helper routine (Sean)
* Use READ_ONCE() when checking userspace's return value in struct kvm_run
(Sean)
* Use u64 instead of u32 for npages/ret fields in the kvm_run struct (Sean)
* Use a switch statement to handle individual error codes reported by
userspace (Sean)
* Move 'snp_certs_enabled' flag from struct kvm_arch to kvm_sev_info (Sean)
* Documentation fix-ups (Sean)
* Rebase to latest kvm/next
Changes since v4:
* Minor documentation updates to make the implementation notes less
specific to QEMU.
* Collected Reviewed-by/Tested-by from v3 since there have been no
functional changes since then and only minor documentation updates.
* Rebased/re-tested on top of latest kvm/next (d3d0b8dfe060)
Changes since v3:
* This version updates the documentation scheme about how file locking is
expected to happen.
Changes since v2:
* As per discussion during PUCK, drop all the KVM_EXIT_COCO infrastructure
since there are enough differences with TDX's quote generation to make
unifying the 2 exits over-complicated for userspace, and the code-sharing
we stand to gain from placing everything under the KVM_EXIT_COCO_*
umbrella are of questionable benefit.
* Update/simplify documentation as per the above.
* Rebase/re-test on top of latest kvm-coco-queue
Changes since v1:
* Drop subtype-specific error codes. Instead use standard error codes like
ENOSPC/etc. and let KVM determine whether a particular error requires
special handling for a particular KVM_EXIT_COCO subtype. (Sean)
* Introduce special handling for EAGAIN for KVM_EXIT_COCO_REQ_CERTS such
that the guest can be instructed to retry if userspace is temporarily unable
to immediately lock/provide the certificate data. (Sean)
* Move the 'ret' field of struct kvm_exit_coco to the top-level so all
sub-types can propagate error codes the same way.
* Add more clarifying details in KVM documentation about the suggested
file-locking scheme to avoid races between certificate requests and updates
to SNP firmware that might modify the endorsement key corresponding to the
certificate data.
Changes since splitting this off from v15 SNP KVM patchset:
* Address clang-reported warnings regarding uninitialized variables
* Address a memory leak of the request/response buffer pages, and refactor
the code based on Sean's suggestions:
https://lore.kernel.org/kvm/ZktbBRLXeOp9X6aH@google.com/
* Fix SNP Extended Guest Request handling to only attempt to fetch
certificates if handling MSG_REQ_REPORT (attestation) message types
* Drop KVM_EXIT_VMGEXIT and introduce KVM_EXIT_COCO events instead
* Refactor patch layout for easier handling/review
----------------------------------------------------------------
Michael Roth (2):
KVM: Introduce KVM_EXIT_SNP_REQ_CERTS for SNP certificate-fetching
KVM: SEV: Add KVM_SEV_SNP_ENABLE_REQ_CERTS command
Documentation/virt/kvm/api.rst | 80 ++++++++++++++++++++++
.../virt/kvm/x86/amd-memory-encryption.rst | 17 ++++-
arch/x86/include/uapi/asm/kvm.h | 2 +
arch/x86/kvm/svm/sev.c | 67 ++++++++++++++++--
arch/x86/kvm/svm/svm.h | 1 +
include/uapi/linux/kvm.h | 9 +++
include/uapi/linux/sev-guest.h | 8 +++
7 files changed, 176 insertions(+), 8 deletions(-)
Powered by blists - more mailing lists