From: Nikunj A Dadhania <nikunj@amd.com>
To: Thomas Courrege <thomas.courrege@vates.tech>,
<pbonzini@redhat.com>, <seanjc@google.com>, <corbet@lwn.net>,
<ashish.kalra@amd.com>, <thomas.lendacky@amd.com>,
<john.allen@amd.com>, <herbert@gondor.apana.org.au>
Cc: <thomas.courrege@vates.tech>, <x86@kernel.org>,
<kvm@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
<linux-crypto@vger.kernel.org>
Subject: Re: [PATCH] KVM: SEV: Add hypervisor report request for SNP guests
Date: Mon, 1 Dec 2025 11:46:51 +0000 [thread overview]
Message-ID: <85h5uabf10.fsf@amd.com> (raw)
In-Reply-To: <20251126191114.874779-1-thomas.courrege@vates.tech>
"Thomas Courrege" <thomas.courrege@vates.tech> writes:
> Add support for retrieving the SEV-SNP attestation report via the
> SNP_HV_REPORT_REQ firmware command and expose it through a new KVM
> ioctl for SNP guests.
>
> Signed-off-by: Thomas Courrege <thomas.courrege@vates.tech>
> ---
> .../virt/kvm/x86/amd-memory-encryption.rst | 18 ++++++
> arch/x86/include/uapi/asm/kvm.h | 7 +++
> arch/x86/kvm/svm/sev.c | 60 +++++++++++++++++++
> drivers/crypto/ccp/sev-dev.c | 1 +
> include/linux/psp-sev.h | 28 +++++++++
> 5 files changed, 114 insertions(+)
>
> diff --git a/Documentation/virt/kvm/x86/amd-memory-encryption.rst b/Documentation/virt/kvm/x86/amd-memory-encryption.rst
> index 1ddb6a86ce7f..f473e9304634 100644
> --- a/Documentation/virt/kvm/x86/amd-memory-encryption.rst
> +++ b/Documentation/virt/kvm/x86/amd-memory-encryption.rst
> @@ -572,6 +572,24 @@ Returns: 0 on success, -negative on error
> See SNP_LAUNCH_FINISH in the SEV-SNP specification [snp-fw-abi]_ for further
> details on the input parameters in ``struct kvm_sev_snp_launch_finish``.
>
> +21. KVM_SEV_SNP_GET_HV_REPORT
> +-----------------------------
The ioctl name is KVM_SEV_SNP_HV_REPORT_REQ in code but documented as
KVM_SEV_SNP_GET_HV_REPORT
> +
> +The KVM_SEV_SNP_GET_HV_REPORT command requests the hypervisor-generated
> +SNP attestation report. This report is produced by the PSP using the
> +HV-SIGNED key selected by the caller.
> +
> +Parameters (in): struct kvm_sev_snp_hv_report_req
> +
> +Returns: 0 on success, -negative on error
> +
> +::
> + struct kvm_sev_snp_hv_report_req {
> + __u8 key_sel;
> + __u64 report_uaddr;
> + __u64 report_len;
> + };
> +
Should we document the valid values of key_sel here?
> Device attribute API
> ====================
>
> diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kvm.h
> index d420c9c066d4..ff034668cac4 100644
> --- a/arch/x86/include/uapi/asm/kvm.h
> +++ b/arch/x86/include/uapi/asm/kvm.h
> @@ -742,6 +742,7 @@ enum sev_cmd_id {
> KVM_SEV_SNP_LAUNCH_START = 100,
> KVM_SEV_SNP_LAUNCH_UPDATE,
> KVM_SEV_SNP_LAUNCH_FINISH,
> + KVM_SEV_SNP_HV_REPORT_REQ,
>
> KVM_SEV_NR_MAX,
> };
> @@ -870,6 +871,12 @@ struct kvm_sev_receive_update_data {
> __u32 pad2;
> };
>
> +struct kvm_sev_snp_hv_report_req {
> + __u8 key_sel;
> + __u64 report_uaddr;
> + __u64 report_len;
> +};
> +
> struct kvm_sev_snp_launch_start {
> __u64 policy;
> __u8 gosvw[16];
> diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
> index 0835c664fbfd..4ab572d970a4 100644
> --- a/arch/x86/kvm/svm/sev.c
> +++ b/arch/x86/kvm/svm/sev.c
> @@ -2253,6 +2253,63 @@ static int snp_launch_start(struct kvm *kvm, struct kvm_sev_cmd *argp)
> return rc;
> }
>
> +static int sev_snp_report_request(struct kvm *kvm, struct kvm_sev_cmd
> *argp)
s/sev_snp_report_request/sev_snp_hv_report_request/
> +{
> + struct kvm_sev_info *sev = to_kvm_sev_info(kvm);
> + struct sev_data_snp_hv_report_req data;
> + struct kvm_sev_snp_hv_report_req params;
> + void __user *u_report;
> + void __user *u_params = u64_to_user_ptr(argp->data);
> + struct sev_data_snp_msg_report_rsp *report_rsp = NULL;
> + int ret;
Variable declarations: Not in reverse Christmas tree order (preferred
but not mandatory per KVM x86 guidelines)
> +
> + if (!sev_snp_guest(kvm))
> + return -ENOTTY;
> +
> + if (copy_from_user(¶ms, u_params, sizeof(params)))
> + return -EFAULT;
> +
> + /* A report uses 1184 bytes */
> + if (params.report_len < 1184)
Can we use a define (ATTESTATION_REPORT_SIZE) for the magic number?
> + return -ENOSPC;
> +
> + memset(&data, 0, sizeof(data));
> +
> + u_report = u64_to_user_ptr(params.report_uaddr);
> + if (!u_report)
> + return -EINVAL;
> +
> + report_rsp = snp_alloc_firmware_page(GFP_KERNEL_ACCOUNT | __GFP_ZERO);
> + if (!report_rsp)
> + return -ENOMEM;
> +
> + data.len = sizeof(data);
> + data.hv_report_paddr = __psp_pa(report_rsp);
> + data.key_sel = params.key_sel;
> +
> + data.gctx_addr = __psp_pa(sev->snp_context);
> + ret = sev_issue_cmd(kvm, SEV_CMD_SNP_HV_REPORT_REQ, &data,
> + &argp->error);
> +
> + if (ret)
> + goto e_free_rsp;
> +
> + params.report_len = report_rsp->report_size;
> + if (copy_to_user(u_params, ¶ms, sizeof(params)))
> + ret = -EFAULT;
> +
> + if (params.report_len < report_rsp->report_size) {
> + ret = -ENOSPC;
> + /* report is located right after rsp */
I think the above comment is for "report_rsp + 1", but is embedded in
the if { }, that is confusing.
> + } else if (copy_to_user(u_report, report_rsp + 1, report_rsp->report_size)) {
> + ret = -EFAULT;
> + }
> +
> +e_free_rsp:
Should we zero the report_rsp before freeing (contains sensitive
attestation data) ?
memzero_explicit(report_rsp, PAGE_SIZE);
Regards
Nikunj
> + snp_free_firmware_page(report_rsp);
> + return ret;
> +}
> +
> struct sev_gmem_populate_args {
> __u8 type;
> int sev_fd;
> @@ -2664,6 +2721,9 @@ int sev_mem_enc_ioctl(struct kvm *kvm, void __user *argp)
> case KVM_SEV_SNP_LAUNCH_FINISH:
> r = snp_launch_finish(kvm, &sev_cmd);
> break;
> + case KVM_SEV_SNP_HV_REPORT_REQ:
> + r = sev_snp_report_request(kvm, &sev_cmd);
> + break;
> default:
> r = -EINVAL;
> goto out;
> diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c
> index 0d13d47c164b..5236d5ee19ac 100644
> --- a/drivers/crypto/ccp/sev-dev.c
> +++ b/drivers/crypto/ccp/sev-dev.c
> @@ -251,6 +251,7 @@ static int sev_cmd_buffer_len(int cmd)
> case SEV_CMD_SNP_COMMIT: return sizeof(struct sev_data_snp_commit);
> case SEV_CMD_SNP_FEATURE_INFO: return sizeof(struct sev_data_snp_feature_info);
> case SEV_CMD_SNP_VLEK_LOAD: return sizeof(struct sev_user_data_snp_vlek_load);
> + case SEV_CMD_SNP_HV_REPORT_REQ: return sizeof(struct sev_data_snp_hv_report_req);
> default: return 0;
> }
>
> diff --git a/include/linux/psp-sev.h b/include/linux/psp-sev.h
> index e0dbcb4b4fd9..c382edc8713a 100644
> --- a/include/linux/psp-sev.h
> +++ b/include/linux/psp-sev.h
> @@ -91,6 +91,7 @@ enum sev_cmd {
> SEV_CMD_SNP_GCTX_CREATE = 0x093,
> SEV_CMD_SNP_GUEST_REQUEST = 0x094,
> SEV_CMD_SNP_ACTIVATE_EX = 0x095,
> + SEV_CMD_SNP_HV_REPORT_REQ = 0x096,
> SEV_CMD_SNP_LAUNCH_START = 0x0A0,
> SEV_CMD_SNP_LAUNCH_UPDATE = 0x0A1,
> SEV_CMD_SNP_LAUNCH_FINISH = 0x0A2,
> @@ -554,6 +555,33 @@ struct sev_data_attestation_report {
> u32 len; /* In/Out */
> } __packed;
>
> +/**
> + * struct sev_data_snp_hv_report_req - SNP_HV_REPORT_REQ command params
> + *
> + * @len: length of the command buffer in bytes
> + * @key_sel: Selects which key to use for generating the signature.
> + * @gctx_addr: System physical address of guest context page
> + * @hv_report_paddr: System physical address where MSG_EXPORT_RSP will be written
> + */
> +struct sev_data_snp_hv_report_req {
> + u32 len; /* In */
> + u32 key_sel:2; /* In */
> + u32 rsvd:30;
> + u64 gctx_addr; /* In */
> + u64 hv_report_paddr; /* In */
> +} __packed;
> +/**
> + * struct sev_data_snp_msg_export_rsp
> + *
> + * @status: Status : 0h: Success. 16h: Invalid parameters.
> + * @report_size: Size in bytes of the attestation report
> + */
> +struct sev_data_snp_msg_report_rsp {
> + u32 status; /* Out */
> + u32 report_size; /* Out */
> + u8 rsvd[24];
> +} __packed;
> +
> /**
> * struct sev_data_snp_download_firmware - SNP_DOWNLOAD_FIRMWARE command params
> *
> --
> 2.52.0
prev parent reply other threads:[~2025-12-01 11:47 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-26 19:11 [PATCH] KVM: SEV: Add hypervisor report request for SNP guests Thomas Courrege
2025-11-26 19:11 ` Thomas Courrege
2025-11-26 19:11 ` Thomas Courrege
2025-12-01 11:46 ` Nikunj A Dadhania [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=85h5uabf10.fsf@amd.com \
--to=nikunj@amd.com \
--cc=ashish.kalra@amd.com \
--cc=corbet@lwn.net \
--cc=herbert@gondor.apana.org.au \
--cc=john.allen@amd.com \
--cc=kvm@vger.kernel.org \
--cc=linux-crypto@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=pbonzini@redhat.com \
--cc=seanjc@google.com \
--cc=thomas.courrege@vates.tech \
--cc=thomas.lendacky@amd.com \
--cc=x86@kernel.org \
/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.