From nobody Mon Dec 1 22:37:33 2025 Received: from mail136-9.atl41.mandrillapp.com (mail136-9.atl41.mandrillapp.com [198.2.136.9]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C9BD720DD72 for ; Wed, 26 Nov 2025 19:11:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.2.136.9 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764184290; cv=none; b=IlP55Nd209+eKEJiroNeWXUU2cUVM0A0pPzjlZSZxocvVP0bKxAPKEXdNnOQ0UlaOdII2Kw5d+phpYhgCta/y4JMGw3HB9m2yWRWaMaulhGHwPc6edq6hJpF6Lb8nQQAY6/XFnCc06jdCNzLLh8+qnlGjIN4BDHaQ0YTZeY/spg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764184290; c=relaxed/simple; bh=nKeewWW3P5B4SMtRZCew3v4YB5Dt7pUrcKq0obyJyJ8=; h=From:Subject:To:Cc:Message-Id:Date:MIME-Version:Content-Type; b=X/wTZyiupp3Q9VajC+MbeKFPZ3xtLpiB1J0kEz0cCjl5Y246Lf1648rMf2ggNMlxwLLrzkqGqHEYNBqBAlhonr+2Prd9X9OLVHEChCylQUnQ+f/gbNApKiByhMcFYv/j306xaDpZ14P8KeKAdtuIrgvm3N5YTPUii+cFcY0vjhQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=vates.tech; spf=pass smtp.mailfrom=bounce.vates.tech; dkim=pass (2048-bit key) header.d=mandrillapp.com header.i=@mandrillapp.com header.b=R9wKxLRk; dkim=pass (2048-bit key) header.d=vates.tech header.i=thomas.courrege@vates.tech header.b=x21aKLER; arc=none smtp.client-ip=198.2.136.9 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=vates.tech Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bounce.vates.tech Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=mandrillapp.com header.i=@mandrillapp.com header.b="R9wKxLRk"; dkim=pass (2048-bit key) header.d=vates.tech header.i=thomas.courrege@vates.tech header.b="x21aKLER" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandrillapp.com; s=mte1; t=1764184287; x=1764454287; bh=/MREF0EwtVtv19KMTRgY9BsLCx0psIVUg7lgQIree34=; h=From:Subject:To:Cc:Message-Id:Feedback-ID:Date:MIME-Version: Content-Type:Content-Transfer-Encoding:CC:Date:Subject:From; b=R9wKxLRk0ZwBnSCqt4v+BVhNW6iOmQBuqXQ/ew6h00TrHGdoofOiinEEjo5q2jBUL tDCtZcgbzu14fcs/YlAYcarq0jq4N6Fbq5wvZGU64FtceiNBpI8Auhc7fIXKoY9mvi Uo72RvXc6KYVPka2i/br5jm9YeL+t7zXvY7o806HNOJMWrMQfDrES3igRh5SdBp0V2 1vFrO3MEfBz0mjgaICrMnTZE4byHT38hJ8WrutmMsWWyilKg6sfsSoa9b00yQEA2y0 K3wOEbfxuLH9BqdjWoCXmUFUn4UOou0KT6JoVhgLyoJk5c2ivTQFs27UGznsGP1+1c QKw7gkUT+jJFQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; s=mte1; t=1764184287; x=1764444787; i=thomas.courrege@vates.tech; bh=/MREF0EwtVtv19KMTRgY9BsLCx0psIVUg7lgQIree34=; h=From:Subject:To:Cc:Message-Id:Feedback-ID:Date:MIME-Version: Content-Type:Content-Transfer-Encoding:CC:Date:Subject:From; b=x21aKLER+ctQra8xh7FBM/Z8duAPg4ge7dBVrrp5mIZ8hBQOxPOBlovmL3ixHcYf2 1m/oeCZNXJhvmNhT7wVXEs1eMFGKJIgpX08t1ppjwiNzUPDxaO2B/sAkuTaajosUvQ zof9jvXPfVL7VktkPc4DLs4NjYujsWO79kULbEVkFVV2hXDjWIC2Vma4vbPTICB3pC 705ZSWdB348SFAcqdz1E+xLDyei9EyKiAX/3MUGtfaqLKXKHKZwjJ6HIYv0cWFZW78 cYqXZCVmgHVrVuMx9u0y+EAG3yj+t+vSOBi1LIEpwhlmyKQdW7bIOJuN0jOrLrTkTL Hbk71w0t0/lZw== Received: from pmta11.mandrill.prod.atl01.rsglab.com (localhost [127.0.0.1]) by mail136-9.atl41.mandrillapp.com (Mailchimp) with ESMTP id 4dGq0v4DBWzHXZ2LJ for ; Wed, 26 Nov 2025 19:11:27 +0000 (GMT) From: "Thomas Courrege" Subject: =?utf-8?Q?[PATCH]=20KVM:=20SEV:=20Add=20hypervisor=20report=20request=20for=20SNP=20guests?= Received: from [37.26.189.201] by mandrillapp.com id 283a3624e4e34e71ac6e918793db4c94; Wed, 26 Nov 2025 19:11:27 +0000 X-Mailer: git-send-email 2.52.0 X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2 X-Bm-Transport-Timestamp: 1764184286986 To: 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 Message-Id: <20251126191114.874779-1-thomas.courrege@vates.tech> X-Native-Encoded: 1 X-Report-Abuse: =?UTF-8?Q?Please=20forward=20a=20copy=20of=20this=20message,=20including=20all=20headers,=20to=20abuse@mandrill.com.=20You=20can=20also=20report=20abuse=20here:=20https://mandrillapp.com/contact/abuse=3Fid=3D30504962.283a3624e4e34e71ac6e918793db4c94?= X-Mandrill-User: md_30504962 Feedback-ID: 30504962:30504962.20251126:md Date: Wed, 26 Nov 2025 19:11:27 +0000 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 --- .../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/Documen= tation/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 furth= er details on the input parameters in ``struct kvm_sev_snp_launch_finish``. =20 +21. 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; + }; + Device attribute API =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kv= m.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 =3D 100, KVM_SEV_SNP_LAUNCH_UPDATE, KVM_SEV_SNP_LAUNCH_FINISH, + KVM_SEV_SNP_HV_REPORT_REQ, =20 KVM_SEV_NR_MAX, }; @@ -870,6 +871,12 @@ struct kvm_sev_receive_update_data { __u32 pad2; }; =20 +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; } =20 +static int sev_snp_report_request(struct kvm *kvm, struct kvm_sev_cmd *arg= p) +{ + struct kvm_sev_info *sev =3D 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 =3D u64_to_user_ptr(argp->data); + struct sev_data_snp_msg_report_rsp *report_rsp =3D NULL; + int ret; + + 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) + return -ENOSPC; + + memset(&data, 0, sizeof(data)); + + u_report =3D u64_to_user_ptr(params.report_uaddr); + if (!u_report) + return -EINVAL; + + report_rsp =3D snp_alloc_firmware_page(GFP_KERNEL_ACCOUNT | __GFP_ZERO); + if (!report_rsp) + return -ENOMEM; + + data.len =3D sizeof(data); + data.hv_report_paddr =3D __psp_pa(report_rsp); + data.key_sel =3D params.key_sel; + + data.gctx_addr =3D __psp_pa(sev->snp_context); + ret =3D sev_issue_cmd(kvm, SEV_CMD_SNP_HV_REPORT_REQ, &data, + &argp->error); + + if (ret) + goto e_free_rsp; + + params.report_len =3D report_rsp->report_size; + if (copy_to_user(u_params, ¶ms, sizeof(params))) + ret =3D -EFAULT; + + if (params.report_len < report_rsp->report_size) { + ret =3D -ENOSPC; + /* report is located right after rsp */ + } else if (copy_to_user(u_report, report_rsp + 1, report_rsp->report_size= )) { + ret =3D -EFAULT; + } + +e_free_rsp: + 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 *a= rgp) case KVM_SEV_SNP_LAUNCH_FINISH: r =3D snp_launch_finish(kvm, &sev_cmd); break; + case KVM_SEV_SNP_HV_REPORT_REQ: + r =3D sev_snp_report_request(kvm, &sev_cmd); + break; default: r =3D -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_rep= ort_req); default: return 0; } =20 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 =3D 0x093, SEV_CMD_SNP_GUEST_REQUEST =3D 0x094, SEV_CMD_SNP_ACTIVATE_EX =3D 0x095, + SEV_CMD_SNP_HV_REPORT_REQ =3D 0x096, SEV_CMD_SNP_LAUNCH_START =3D 0x0A0, SEV_CMD_SNP_LAUNCH_UPDATE =3D 0x0A1, SEV_CMD_SNP_LAUNCH_FINISH =3D 0x0A2, @@ -554,6 +555,33 @@ struct sev_data_attestation_report { u32 len; /* In/Out */ } __packed; =20 +/** + * 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 p= arams * --=20 2.52.0