From nobody Sat Jun 20 14:11:42 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 03E7B46AF0F; Thu, 30 Apr 2026 16:08:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777565282; cv=none; b=ZlUrt/mPBFm/KllIG3ni5a/oRlf5tKywbHhwxy6ftMCJ/7P0PayoWKl7/0kjm8P5iS0R+R/jLvtDStpklblwHgaJq/rodK4Cjcs7XwFXJy5eNouSoFMFeYcQexCKpUInHwUedGo7msv01QLHmf4jnEG4N3QTWl/tGVoZW04eOlI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777565282; c=relaxed/simple; bh=C1WWXsx7zxzzTYAeVl8gjACb9XsYo205RN3A//xC6lU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=bGT9a1nwsIDfrNSJtjyJkLM7XZSbzFpiNV0XMMTHkffQneG7iOuaR7LL8Rn4y8ghr55t4KJwVi0QvG28RnzgtSZCGIhAzfg6c0TTWPdqjCiCi83q8t562bRr15R2Lgt3ODcC546AtJQkyw9G+tnbLdTi4RhTnF98c37lJtABlsQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=r9xLpc7T; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="r9xLpc7T" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5FCB7C2BCB8; Thu, 30 Apr 2026 16:08:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777565281; bh=C1WWXsx7zxzzTYAeVl8gjACb9XsYo205RN3A//xC6lU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=r9xLpc7T2ZNdfl+T2mHWYSBVgG4JOYXPrFkU7lIh2jyP5srd/R/TD0xKgwSSb5M/l c4raRkiEMZGrCsUbPbLKGWkpQ4uc0Yny+y8oZQwfmTeegPFGIkcc8Rp6He03dNhtCz Khl4BpUKhVQfv+tbzQj4LBVl1Swesh7CJKFQoT1MIY4ZkBHfo09648OigdkWBGrQtH ja0Vpzv9crsVPRXPCEsV2kdFaVMbuuAHY+5ekBdfmSHn72b6zlb6ZUGek70inMVf/+ Vuf6/PIy1WvALsdS7sYHbXJok+9MPQaUHK3irUu6Y6mEaYSRnclYSySasY3xAktC6c gxy76oUYqtduw== From: Tycho Andersen To: Ashish Kalra , Tom Lendacky , John Allen , Herbert Xu , "David S. Miller" Cc: linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, Sean Christopherson , Kim Phillips , Alexey Kardashevskiy , "Tycho Andersen (AMD)" , Nikunj A Dadhania , "Pratik R. Sampat" , Michael Roth Subject: [RFC v1 1/6] crypto/ccp: Hoist kernel part of SNP_PLATFORM_STATUS Date: Thu, 30 Apr 2026 10:07:11 -0600 Message-ID: <20260430160716.1120553-2-tycho@kernel.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260430160716.1120553-1-tycho@kernel.org> References: <20260430160716.1120553-1-tycho@kernel.org> 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" From: "Tycho Andersen (AMD)" ...to its own function. This way it can be used when the kernel needs access to the platform status regardless of the INIT state of the firmware. No functional change intended. Signed-off-by: Tycho Andersen (AMD) --- drivers/crypto/ccp/sev-dev.c | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c index d1e9e0ac63b6..22bc4ef27a63 100644 --- a/drivers/crypto/ccp/sev-dev.c +++ b/drivers/crypto/ccp/sev-dev.c @@ -2381,7 +2381,8 @@ static int sev_ioctl_do_pdh_export(struct sev_issue_c= md *argp, bool writable) return ret; } =20 -static int sev_ioctl_do_snp_platform_status(struct sev_issue_cmd *argp) +static int __sev_do_snp_platform_status(struct sev_user_data_snp_status *s= tatus, + int *error) { struct sev_device *sev =3D psp_master->sev_data; struct sev_data_snp_addr buf; @@ -2389,9 +2390,6 @@ static int sev_ioctl_do_snp_platform_status(struct se= v_issue_cmd *argp) void *data; int ret; =20 - if (!argp->data) - return -EINVAL; - status_page =3D alloc_page(GFP_KERNEL_ACCOUNT); if (!status_page) return -ENOMEM; @@ -2414,7 +2412,7 @@ static int sev_ioctl_do_snp_platform_status(struct se= v_issue_cmd *argp) } =20 buf.address =3D __psp_pa(data); - ret =3D __sev_do_cmd_locked(SEV_CMD_SNP_PLATFORM_STATUS, &buf, &argp->err= or); + ret =3D __sev_do_cmd_locked(SEV_CMD_SNP_PLATFORM_STATUS, &buf, error); =20 if (sev->snp_initialized) { /* @@ -2429,15 +2427,32 @@ static int sev_ioctl_do_snp_platform_status(struct = sev_issue_cmd *argp) if (ret) goto cleanup; =20 - if (copy_to_user((void __user *)argp->data, data, - sizeof(struct sev_user_data_snp_status))) - ret =3D -EFAULT; + memcpy(status, data, sizeof(*status)); =20 cleanup: __free_pages(status_page, 0); return ret; } =20 +static int sev_ioctl_do_snp_platform_status(struct sev_issue_cmd *argp) +{ + struct sev_user_data_snp_status status; + int ret; + + if (!argp->data) + return -EINVAL; + + ret =3D __sev_do_snp_platform_status(&status, &argp->error); + if (ret < 0) + return ret; + + if (copy_to_user((void __user *)argp->data, &status, + sizeof(struct sev_user_data_snp_status))) + ret =3D -EFAULT; + + return ret; +} + static int sev_ioctl_do_snp_commit(struct sev_issue_cmd *argp) { struct sev_device *sev =3D psp_master->sev_data; --=20 2.54.0 From nobody Sat Jun 20 14:11:42 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 CE38946AF3F; Thu, 30 Apr 2026 16:08:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777565283; cv=none; b=YeY1r+30jMuwKKtu3p1R7XsMlCap/l/lfUi+TV+vFqGHOC1rEwe3eJ4PtIAbMt3ddRoBzZvhvemmQ3ErO3PRz39j7eXoUcr4juPSzpd7+AdvfbWCNL1LFUNDiQX5CiqYD/5hQ57ud+wkl1cN2JREVTBFgXDcipdNTEVGNIlZQ9E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777565283; c=relaxed/simple; bh=RD/xehk71EurLmD3n8bVFda9UNe1vsIrDTcsFaZpYRM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=uIPmXKEHma4VfxYviHl4804yaL+K4U5kLMMP2RSCHeKj6Lrt0u0Gqzfv36pFUhi7mb0T0A1lfvvvtH+JMkUL5L+6a4y4JA50g+GRCqbQUTnriNWUkngryHQ0jRTHa6IIAdlcPrNT5H/GC19hRAfZBu/ofqX3vLhjegL8cWzJGjM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=e9EVyH+O; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="e9EVyH+O" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3002FC2BCB8; Thu, 30 Apr 2026 16:08:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777565283; bh=RD/xehk71EurLmD3n8bVFda9UNe1vsIrDTcsFaZpYRM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=e9EVyH+O2dXMsY05UCTePIqHsu2aROutq8u9lq4Hmk/BemBWxBTIOulKXSfsXVT9W LjrawUwXZaOMbBqM22lrL2ZRZxCWRDPf+Cr6yyZ54o1r41YTl/nMC4ke5jeq1TCPnD rwDTPogbx3Tuk6XiCK7Mh981TwximVHQ6QsjEU6JbhllMWLnewddsNvKf9gNoSO2l2 DdbHog3u1q+XU9EpCu+h7878MaafSbbVK5vKeNt7+5KU/00FU4d0Kmeu4E2v5h55nU y7U44AfjrNyRV5tvxxzWSKoFaJolT0lhNAlUkHon13fFM9QrAxbpzdjlWnvQ9IBlur LEPYH0ScQHlKg== From: Tycho Andersen To: Ashish Kalra , Tom Lendacky , John Allen , Herbert Xu , "David S. Miller" Cc: linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, Sean Christopherson , Kim Phillips , Alexey Kardashevskiy , "Tycho Andersen (AMD)" , Nikunj A Dadhania , "Pratik R. Sampat" , Michael Roth Subject: [RFC v1 2/6] crypto/ccp: Allow snp_get_platform_data() after SNP init Date: Thu, 30 Apr 2026 10:07:12 -0600 Message-ID: <20260430160716.1120553-3-tycho@kernel.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260430160716.1120553-1-tycho@kernel.org> References: <20260430160716.1120553-1-tycho@kernel.org> 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" From: "Tycho Andersen (AMD)" In preparation for refreshing the cached SNP platform status and feature information after a successful firmware live update, allow snp_get_platform_data() to be called when the SNP firmware is in the INIT state. When SNP is initialized the firmware additionally requires status pages to be in the firmware-owned RMP state. __sev_do_snp_platform_status() already handles this for SNP_PLATFORM_STATUS, so switch to that helper for that command. Add the same mark/reclaim dance around the SNP_FEATURE_INFO page. Signed-off-by: Tycho Andersen (AMD) --- drivers/crypto/ccp/sev-dev.c | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c index 22bc4ef27a63..7ca29ccda0e7 100644 --- a/drivers/crypto/ccp/sev-dev.c +++ b/drivers/crypto/ccp/sev-dev.c @@ -132,6 +132,9 @@ static void __sev_firmware_shutdown(struct sev_device *= sev, bool panic); static int snp_shutdown_on_panic(struct notifier_block *nb, unsigned long reason, void *arg); =20 +static int __sev_do_snp_platform_status(struct sev_user_data_snp_status *s= tatus, + int *error); + static struct notifier_block snp_panic_notifier =3D { .notifier_call =3D snp_shutdown_on_panic, }; @@ -1264,19 +1267,12 @@ static int snp_get_platform_data(struct sev_device = *sev, int *error) { struct sev_data_snp_feature_info snp_feat_info; struct snp_feature_info *feat_info; - struct sev_data_snp_addr buf; struct page *page; int rc; =20 - /* - * This function is expected to be called before SNP is - * initialized. - */ - if (sev->snp_initialized) - return -EINVAL; - - buf.address =3D __psp_pa(&sev->snp_plat_status); - rc =3D sev_do_cmd(SEV_CMD_SNP_PLATFORM_STATUS, &buf, error); + mutex_lock(&sev_cmd_mutex); + rc =3D __sev_do_snp_platform_status(&sev->snp_plat_status, error); + mutex_unlock(&sev_cmd_mutex); if (rc) { dev_err(sev->dev, "SNP PLATFORM_STATUS command failed, ret =3D %d, error= =3D %#x\n", rc, *error); @@ -1305,17 +1301,32 @@ static int snp_get_platform_data(struct sev_device = *sev, int *error) return -ENOMEM; =20 feat_info =3D page_address(page); + + if (sev->snp_initialized) { + if (rmp_mark_pages_firmware(__pa(feat_info), 1, false)) { + rc =3D -EFAULT; + goto free_page; + } + } + snp_feat_info.length =3D sizeof(snp_feat_info); snp_feat_info.ecx_in =3D 0; snp_feat_info.feature_info_paddr =3D __psp_pa(feat_info); =20 rc =3D sev_do_cmd(SEV_CMD_SNP_FEATURE_INFO, &snp_feat_info, error); + + if (sev->snp_initialized) { + if (snp_reclaim_pages(__pa(feat_info), 1, false)) + return -EFAULT; + } + if (!rc) sev->snp_feat_info_0 =3D *feat_info; else dev_err(sev->dev, "SNP FEATURE_INFO command failed, ret =3D %d, error = =3D %#x\n", rc, *error); =20 +free_page: __free_page(page); =20 return rc; --=20 2.54.0 From nobody Sat Jun 20 14:11:42 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 EAF1347278D; Thu, 30 Apr 2026 16:08:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777565286; cv=none; b=iCzvkLHGGnT7CZgR/ASl4C1yZMWttPTncuepUj52ZLayYrj/lvmz0GcIhkNvppm0q1Xw39ShbnRqhBr1fpBuhZi8IWjCnow3YWPXeHxVtlOEXeQoqS5nt3IfVO1GAAU9jD+VNdq5Y1/cBFDZTa+CN21HUM+xR9lSolU+somHaY4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777565286; c=relaxed/simple; bh=YzGD1DNsaiZ2gMNu0AtMCMF96uvzxD5DY9G8hcz0NQQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mx4F1CSavMO3HyPx4wbAsJDVplOJqvME409nV9RsuFDC1SQj6CPFTK9E/CW/kx2SjlXaU4rwuGlUJJzqMkko0YatbESa1iyJyCawbrLVwykum3rOuuXRyuPx3T8PKK9fx3PRfpe1rKfvcVNOnx0uLWJ2+HrG/uR4XEcDOkDtjC0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=SBR3CLVE; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="SBR3CLVE" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 00FACC2BCB3; Thu, 30 Apr 2026 16:08:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777565285; bh=YzGD1DNsaiZ2gMNu0AtMCMF96uvzxD5DY9G8hcz0NQQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=SBR3CLVEu/rbXXSc2FGNc3taISQaC2KoYuGCJvaXWGSfM3qTBq0RK9p0F+qBJuEqk IkzZ6TiqM0LsMTeKWgYgYvgOVdzB80Bt/QvuUj81Aj1brK5juZW86TePBY/ac0OJjg aG+4SHjFxXUUDMNnUm6gkgQUc22uuJweMiQw9IC1HXXGoHkvLDmSMaXRypXJwLcF+V LYn68nx/ghJPdSkbzVKehwkMHoJ14XN1Wh2FyNJoHOeZDGuvMe68TKw8UU5puuWAPh SrMtQBSB31yLK42nnVJUVWjnGsDyGVfkkIKNZewDngepPxcE9+5h2jJf4IJ0wzYxyv rY3pvsx3XpXCA== From: Tycho Andersen To: Ashish Kalra , Tom Lendacky , John Allen , Herbert Xu , "David S. Miller" Cc: linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, Sean Christopherson , Kim Phillips , Alexey Kardashevskiy , "Tycho Andersen (AMD)" , Nikunj A Dadhania , "Pratik R. Sampat" , Michael Roth Subject: [RFC v1 3/6] crypto/ccp: Add DOWNLOAD_FIRMWARE_EX message struct Date: Thu, 30 Apr 2026 10:07:13 -0600 Message-ID: <20260430160716.1120553-4-tycho@kernel.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260430160716.1120553-1-tycho@kernel.org> References: <20260430160716.1120553-1-tycho@kernel.org> 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" From: "Tycho Andersen (AMD)" ...and appropriate sizeof() in sev_cmd_buffer_len() for use in do_sev_cmd(). The message is documented in SEV-SNP firmware document id 56860. Signed-off-by: Tycho Andersen (AMD) --- drivers/crypto/ccp/sev-dev.c | 1 + include/linux/psp-sev.h | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c index 7ca29ccda0e7..defdc1bc226e 100644 --- a/drivers/crypto/ccp/sev-dev.c +++ b/drivers/crypto/ccp/sev-dev.c @@ -252,6 +252,7 @@ static int sev_cmd_buffer_len(int cmd) case SEV_CMD_SNP_PLATFORM_STATUS: return sizeof(struct sev_data_snp_addr); case SEV_CMD_SNP_GUEST_REQUEST: return sizeof(struct sev_data_snp_guest_= request); case SEV_CMD_SNP_CONFIG: return sizeof(struct sev_user_data_snp_config); + case SEV_CMD_SNP_DOWNLOAD_FIRMWARE_EX: return sizeof(struct sev_data_down= load_firmware_ex); 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); diff --git a/include/linux/psp-sev.h b/include/linux/psp-sev.h index d5099a2baca5..5227e901bff2 100644 --- a/include/linux/psp-sev.h +++ b/include/linux/psp-sev.h @@ -855,6 +855,26 @@ struct sev_platform_init_args { unsigned int max_snp_asid; }; =20 +/** + * struct sev_data_download_firmware_ex + * + * @len: length of the command buffer read by the PSP + * @rsvd0: reserved + * @fw_paddr: physical address of the start of the firmware blob + * @fw_len: length of the firmware blob + * @commit: whether to immediately commit the firmware update. If set, this + * operation behaves like DOWNLOAD_FIRMWARE. + * @rsvd1: reserved + */ +struct sev_data_download_firmware_ex { + u32 len; /* In */ + u32 rsvd0; + u64 fw_paddr; /* In */ + u32 fw_len; /* In */ + u32 commit:1; /* In */ + u32 rsvd1:31; +} __packed; + /** * struct sev_data_snp_commit - SNP_COMMIT structure * --=20 2.54.0 From nobody Sat Jun 20 14:11:42 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 AACC5477983; Thu, 30 Apr 2026 16:08:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777565287; cv=none; b=Zwz82/9qFNmqwGj13uOnJwwXzkE6QYdnsdZUnAVdn5WfCm7NnAoa7Hyipr6fTsUf2rxzXSvDBk1zn0nuSg+LpkELOW7eHXDoh4DO1XWxKlIo+SiMMEQeVyQY+WfsoWDlfOYAzto0n8kjXCKoeleuZ/dQUtKphRbPYUYFnyji03E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777565287; c=relaxed/simple; bh=ppqUBdHv5atY4swQeEtCHJ6NLY5UYUIHNSSBVG5oToY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=hg0HD1wOdZdxFZYrFNdALerjSUD6A8PLk3UxSYYgJuXLBQ05WHUXvqn77132fZ5czfZstYpXfGnrU/IDMrThhrSYQktO0fLHG/4iejCVjwSvBLrGcyw+q3R9275WIu/OECobPbSZvB7Hbszyl4z4zOkTRzjwgaRFD+pKdg+HjT4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=oigEgUG3; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="oigEgUG3" Received: by smtp.kernel.org (Postfix) with ESMTPSA id CC925C2BCB8; Thu, 30 Apr 2026 16:08:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777565287; bh=ppqUBdHv5atY4swQeEtCHJ6NLY5UYUIHNSSBVG5oToY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oigEgUG3dWXwDwUJzUJgvzyzHnD0kM+7ALFEWEFlQGcWyH/ZV5+9KSlxB/llYkKxe LTX25P9KzqQ9NAR0SXMDTe2rSWmKtId79ViSnScmMWA3p6XE19lxDx6pHRejQLE/na 1ykL2j7d8RXRKzQb73+gx7NPsqKAiLq5TdG5uzvnu3PCRT+tPtD7HofU0GpR8sZIac aQ8TNrP+l+jtnDi6S8FAA0miC6/zALd+G2GxWy0yUB/NGdzhPGeDYR6gQE+VbHL45P lZJHerGExYwdXLrBrwNh4KJjI7oAiyHajva00sqO92Ym9mBWzlaxF5tNawEwOLrplA 3ZPu07rBpmaRA== From: Tycho Andersen To: Ashish Kalra , Tom Lendacky , John Allen , Herbert Xu , "David S. Miller" Cc: linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, Sean Christopherson , Kim Phillips , Alexey Kardashevskiy , "Tycho Andersen (AMD)" , Nikunj A Dadhania , "Pratik R. Sampat" , Michael Roth Subject: [RFC v1 4/6] crypto/ccp: Reclaim command buffer when the PSP dies Date: Thu, 30 Apr 2026 10:07:14 -0600 Message-ID: <20260430160716.1120553-5-tycho@kernel.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260430160716.1120553-1-tycho@kernel.org> References: <20260430160716.1120553-1-tycho@kernel.org> 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" From: "Tycho Andersen (AMD)" When the PSP dies due to timeout the psp_dead flag is set, but the buffer-in-use flag was not unset, and the pages were not reclaimed for legacy commands. In preparation for a firmware quirk where updates time out but the situation is recoverable, move the reclamation before the error checking and handling. Be sure to only copy the output buffer when the command has not timed out, i.e. when there is sensible output in the buffer. Signed-off-by: Tycho Andersen (AMD) --- drivers/crypto/ccp/sev-dev.c | 60 +++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c index defdc1bc226e..2df621b9f6e2 100644 --- a/drivers/crypto/ccp/sev-dev.c +++ b/drivers/crypto/ccp/sev-dev.c @@ -948,6 +948,38 @@ int __sev_do_cmd_locked(int cmd, void *data, int *psp_= ret) =20 /* wait for command completion */ ret =3D sev_wait_cmd_ioc(sev, ®, psp_timeout); + + /* + * Copy potential output from the PSP back to data. Do this even on + * failure in case the caller wants to glean something from the error, + * unless the operation timed out, in which case there is nothing to + * copy back. + */ + if (data) { + int ret_reclaim; + /* + * Restore the page state after the command completes. + */ + ret_reclaim =3D snp_reclaim_cmd_buf(cmd, cmd_buf); + if (ret_reclaim) { + dev_err(sev->dev, + "SEV: failed to reclaim buffer for legacy command %#x. Error: %d\n", + cmd, ret_reclaim); + return ret_reclaim; + } + + if (ret !=3D -ETIMEDOUT) + memcpy(data, cmd_buf, buf_len); + + if (sev->cmd_buf_backup_active) + sev->cmd_buf_backup_active =3D false; + else + sev->cmd_buf_active =3D false; + + if (snp_unmap_cmd_buf_desc_list(desc_list)) + return -EFAULT; + } + if (ret) { if (psp_ret) *psp_ret =3D 0; @@ -984,34 +1016,6 @@ int __sev_do_cmd_locked(int cmd, void *data, int *psp= _ret) ret =3D sev_write_init_ex_file_if_required(cmd); } =20 - /* - * Copy potential output from the PSP back to data. Do this even on - * failure in case the caller wants to glean something from the error. - */ - if (data) { - int ret_reclaim; - /* - * Restore the page state after the command completes. - */ - ret_reclaim =3D snp_reclaim_cmd_buf(cmd, cmd_buf); - if (ret_reclaim) { - dev_err(sev->dev, - "SEV: failed to reclaim buffer for legacy command %#x. Error: %d\n", - cmd, ret_reclaim); - return ret_reclaim; - } - - memcpy(data, cmd_buf, buf_len); - - if (sev->cmd_buf_backup_active) - sev->cmd_buf_backup_active =3D false; - else - sev->cmd_buf_active =3D false; - - if (snp_unmap_cmd_buf_desc_list(desc_list)) - return -EFAULT; - } - print_hex_dump_debug("(out): ", DUMP_PREFIX_OFFSET, 16, 2, data, buf_len, false); =20 --=20 2.54.0 From nobody Sat Jun 20 14:11:42 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 845124779B0; Thu, 30 Apr 2026 16:08:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777565289; cv=none; b=js4/Zu95bi1cjtMo5ppwmHSmd5wkV1Hc9PS0NLpW50lFHXQtJmCnoLZsVpkRFg3Lh7kX5TScCI8K0xEJbpRCd4tJo9hplkmPvRRmHGg3uWEz3PLBoUAmGgmvZFy+XbL96li/2P8WBlh8mQsEko2wPFP0FRgJgnJMcXiilxAxxhE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777565289; c=relaxed/simple; bh=pejxj9fzZ+77vwlzN5M73gcB3B9Ho8n9BQSAk7R+bfU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=IX4ZolJ70+idrotXoLsmZXH2xegKEfv1tbMkY9BZPnl/5wieB5rSGkN1oq4mgp3IT9SrJ6iWzQza8nY5FUChu9pngAcIH6uMnw/IcJrVHBjHlotnWvnC8VHY9FeNE4SNuFLj45u97u3dGfodDlwo6e86cwAiPznGGBOyntjHwM4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ZGAb/QPn; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ZGAb/QPn" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9F985C2BCB9; Thu, 30 Apr 2026 16:08:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777565289; bh=pejxj9fzZ+77vwlzN5M73gcB3B9Ho8n9BQSAk7R+bfU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZGAb/QPnE3OmdOSIQSFLbmRe34WshOtfGRuV0ii0cHcyyNKrW6+akIf72dOXubo+B zdk/29PCNca8CqnDLaBDlyjiDblmOaJtBZBaPcfPyVXDaElI9HpxidPCziL/4YjHxY I74j38sVuwCJZpoBx96YBmQfoV1j/GzOKe/i4isbJNng3K7c8zJdu8XNWHr9exBdAG luEUPDzjnrpSCoxmfDw9CcvRWLa8V052EIDYYed/4Po0SPiLFMrV6Z+FE3x+PmQ7j9 yMe9PBWsYOt1NzQkods7WOA3H3MlW31WjlmDF/MFK/uVFZx63E1+JhLVsNtzX84gzR OyCkyhyNsYhjw== From: Tycho Andersen To: Ashish Kalra , Tom Lendacky , John Allen , Herbert Xu , "David S. Miller" Cc: linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, Sean Christopherson , Kim Phillips , Alexey Kardashevskiy , "Tycho Andersen (AMD)" , Nikunj A Dadhania , "Pratik R. Sampat" , Michael Roth Subject: [RFC v1 5/6] crypto/ccp: Register with fw_uploader and always fail Date: Thu, 30 Apr 2026 10:07:15 -0600 Message-ID: <20260430160716.1120553-6-tycho@kernel.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260430160716.1120553-1-tycho@kernel.org> References: <20260430160716.1120553-1-tycho@kernel.org> 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" From: "Tycho Andersen (AMD)" In preparation for SNP live firmware downloading support, add an 'sev' firmware loader that always fails with EBUSY. Signed-off-by: Tycho Andersen (AMD) --- drivers/crypto/ccp/sev-dev.c | 51 ++++++++++++++++++++++++++++++++++++ drivers/crypto/ccp/sev-dev.h | 3 +++ 2 files changed, 54 insertions(+) diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c index 2df621b9f6e2..b4711bf823e8 100644 --- a/drivers/crypto/ccp/sev-dev.c +++ b/drivers/crypto/ccp/sev-dev.c @@ -2040,6 +2040,53 @@ static int sev_update_firmware(struct device *dev) return ret; } =20 +static enum fw_upload_err sev_fw_upload_prepare(struct fw_upload *fw_uploa= d, + const u8 *data, u32 size) +{ + return FW_UPLOAD_ERR_NONE; +} + +static enum fw_upload_err sev_fw_upload_write(struct fw_upload *fw_upload, + const u8 *data, u32 offset, + u32 size, u32 *written) +{ + return FW_UPLOAD_ERR_BUSY; +} + +static enum fw_upload_err sev_fw_upload_poll_complete(struct fw_upload *fw= _upload) +{ + return FW_UPLOAD_ERR_NONE; +} + +static void sev_fw_upload_cancel(struct fw_upload *fw_upload) +{ + /* intentional no-op */ +} + +static const struct fw_upload_ops sev_fw_upload_ops =3D { + .prepare =3D sev_fw_upload_prepare, + .write =3D sev_fw_upload_write, + .poll_complete =3D sev_fw_upload_poll_complete, + .cancel =3D sev_fw_upload_cancel, +}; + +static void register_sev_fw_uploader(struct sev_device *sev) +{ + struct fw_upload *fwl; + + if (!IS_ENABLED(CONFIG_FW_UPLOAD)) + return; + + fwl =3D firmware_upload_register(THIS_MODULE, sev->dev, "sev", + &sev_fw_upload_ops, sev); + if (IS_ERR(fwl)) { + dev_err(sev->dev, "SEV firmware upload registration failure: %ld\n", PTR= _ERR(fwl)); + return; + } + + sev->fwl =3D fwl; +} + static int __sev_snp_shutdown_locked(int *error, bool panic) { struct psp_device *psp =3D psp_master; @@ -2953,6 +3000,7 @@ void sev_pci_init(void) api_major, api_minor, build, sev->api_major, sev->api_minor, sev->build); =20 + register_sev_fw_uploader(sev); return; =20 err: @@ -2969,4 +3017,7 @@ void sev_pci_exit(void) return; =20 sev_firmware_shutdown(sev); + + if (sev->fwl) + firmware_upload_unregister(sev->fwl); } diff --git a/drivers/crypto/ccp/sev-dev.h b/drivers/crypto/ccp/sev-dev.h index b1cd556bbbf6..2f5781cb7bb1 100644 --- a/drivers/crypto/ccp/sev-dev.h +++ b/drivers/crypto/ccp/sev-dev.h @@ -24,6 +24,7 @@ #include #include #include +#include =20 #define SEV_CMDRESP_CMD GENMASK(26, 16) #define SEV_CMD_COMPLETE BIT(1) @@ -66,6 +67,8 @@ struct sev_device { =20 struct tsm_dev *tsmdev; struct sev_tio_status *tio_status; + + struct fw_upload *fwl; }; =20 int sev_dev_init(struct psp_device *psp); --=20 2.54.0 From nobody Sat Jun 20 14:11:42 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 192FA477E34; Thu, 30 Apr 2026 16:08:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777565291; cv=none; b=GQXAqMkH/RRU8ok+CNHL70/fFqgR3k7pyERWkb8Ms077m2vaRK4V9skLplbVy598EsSdireCdj0Sw4k1qtJhTez8aBE9ak2Mbky9wTfyCSylW2H+jVrHOgYrcyUq30YgjjN5WiIhBI8tOBMWSRnNAsYtqDN4Q9Sx+UK+I0MlcDc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777565291; c=relaxed/simple; bh=A218sexPB4Eoz81IHOSyS19fv9sHjGhguWb/ZRqThiA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=nQzoYrCi4e/yZCHWDvm29oz7cqY4WXwzb7iVd2JqSSAYJPWgKyWcW3faDpgV7+FGTbCSWawwjaa+n+gz2yMERMnzW/W+nVhWkesSpniPUk5O6aKjvMh/ejR6lTCLiwqwFT517mWk0rjmhuJXM7/YnnEmN+gTojdzOZoKLJKvH1M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=nWPSJQ+4; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="nWPSJQ+4" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 747ABC2BCB8; Thu, 30 Apr 2026 16:08:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777565291; bh=A218sexPB4Eoz81IHOSyS19fv9sHjGhguWb/ZRqThiA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nWPSJQ+4hZNmF8Lb9iJd3RLMr0MOg9OLD3PLc7eDxya/ctA2YgbOb0vrgNog2m/EB 0tW6frMkmaJKH8SNYUX3bpHA2qUzgYc2JUm4YZBniwSC4h52dyl1u8jvdqS0WwxE7z UdZucScD+bVuYBq0smM5mhIliP7RJCyYgFlAGviK6PSrjjRFLhoEW0Tls0H5V0p9pF /7PZC3PgqPS3W5ZtZnwvEapepu5tnt9AjkcRS/xAqG9w6Ne+3jIF5+6LSBY72HRpHO mpAMPor9ljJClfZ/dce9oz1hR2+2T82B2dsKRo6lhzxQA5hcUaykFjVIdEuSt4mrt+ Ctpz7aZcgIb8w== From: Tycho Andersen To: Ashish Kalra , Tom Lendacky , John Allen , Herbert Xu , "David S. Miller" Cc: linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, Sean Christopherson , Kim Phillips , Alexey Kardashevskiy , "Tycho Andersen (AMD)" , Nikunj A Dadhania , "Pratik R. Sampat" , Michael Roth Subject: [RFC v1 6/6] crypto/ccp: Implement SNP firmware live update Date: Thu, 30 Apr 2026 10:07:16 -0600 Message-ID: <20260430160716.1120553-7-tycho@kernel.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260430160716.1120553-1-tycho@kernel.org> References: <20260430160716.1120553-1-tycho@kernel.org> 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" From: "Tycho Andersen (AMD)" Put all the previous primitives together to implement SNP firmware live update via DOWNLOAD_FIRMWARE_EX. DOWNLOAD_FIRMWARE_EX can only be run while the legacy SEV firmware is the UNINIT state. If the legacy firmware is in the WORKING state running legacy guests, refuse to update. If the legacy firmware is in the INIT state, de-initialize it so that the update can be run. When the firmware is installed, it is only provisionally loaded. It relies on userspace to issue ioctl(/dev/sev, SNP_COMMIT, ...) when it is happy with the provisional firmware. To roll back, userspace should not do an SNP_COMMIT, and invoke the firmware loader in the same way but with the old firmware image. The firmware spec notes: If a guest context page is updated to a provisional firmware version, then updating the context page back to the committed version after a rollback will always succeed. There are essentially four classes of errors during an update: 1. kernel bugs that WARN_ON_ONCE() 2. invalid firmware (bad image, bad signature, downgrade too far, etc.) 3. UPDATE_FAILED, things can continue as normally 4. HARDWARE_UNSAFE, declare the PSP dead, since the behavior of the SEV firmware is undefined 5. RESTORE_REQUIRED, the firmware can only successfully execute DOWNLOAD_FIRMWARE_EX commands. The admin needs to load the old firmware image. There is a firmware bug where upgrades across 1.58.03 time out, even though the upgrade actually succeeds. There is no documented way to determine what the input firmware version is, so there is no way to detect this case before trying a firmware update. Instead look for the timeout and try an SNP_PLATFORM_STATUS to see if the PSP is still alive. Finally, this differs from the previous implementation [1] in a couple of ways: 1. guest context pages are no longer required to be updated as of 1.58 of the SEV-SNP Firmware spec doc 56860. 2. no WBINVD+DF_FLUSH is required after a firmware update, so it drops that code [1]: https://lore.kernel.org/lkml/20241112232253.3379178-7-dionnaglaze@goog= le.com/ Signed-off-by: Tycho Andersen (AMD) --- drivers/crypto/ccp/sev-dev.c | 244 ++++++++++++++++++++++++++++++++++- 1 file changed, 243 insertions(+), 1 deletion(-) diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c index b4711bf823e8..e7fe6dbf69c2 100644 --- a/drivers/crypto/ccp/sev-dev.c +++ b/drivers/crypto/ccp/sev-dev.c @@ -90,6 +90,8 @@ MODULE_FIRMWARE("amd/amd_sev_fam19h_model1xh.sbin"); /* 4= th gen EPYC */ =20 static bool psp_dead; static int psp_timeout; +static bool dlfwex_wants_rollback; +static bool sev_firmware_needs_reinit; =20 enum snp_hv_fixed_pages_state { ALLOCATED, @@ -2046,11 +2048,251 @@ static enum fw_upload_err sev_fw_upload_prepare(st= ruct fw_upload *fw_upload, return FW_UPLOAD_ERR_NONE; } =20 +static int sev_download_firmware_ex(struct sev_device *sev, const u8 *data, + u32 size) +{ + struct sev_data_download_firmware_ex sev_data =3D {0}; + int ret, error =3D 0, order; + struct page *p; + void *fw_blob; + + order =3D get_order(size); + p =3D alloc_pages(GFP_KERNEL, order); + if (!p) + return -ENOMEM; + + fw_blob =3D page_address(p); + memcpy(fw_blob, data, size); + + sev_data.len =3D sizeof(sev_data); + sev_data.fw_paddr =3D __psp_pa(fw_blob); + sev_data.fw_len =3D size; + sev_data.commit =3D 0; + + ret =3D __sev_do_cmd_locked(SEV_CMD_SNP_DOWNLOAD_FIRMWARE_EX, &sev_data, = &error); + + /* + * Quirk: firmware upgrades across 1.58.03 give ETIMEDOUT for + * DLFWEX, even though the command actually succeeds. If we're + * in this case, test that we can do SNP_PLATFORM_STATUS, and + * if so, continue as normal. + */ + if (ret =3D=3D -ETIMEDOUT) { + struct sev_user_data_snp_status status; + + dev_info(sev->dev, "Firmware update timed out, checking status for quirk= ...\n"); + psp_dead =3D false; + + ret =3D __sev_do_snp_platform_status(&status, &error); + if (ret) { + dev_err(sev->dev, "SNP STATUS failed after firmware upgrade, ret =3D %d= , error =3D %#x\n", + ret, error); + psp_dead =3D true; + goto out; + } + } + + if (ret < 0 && error !=3D 0) + ret =3D error; + +out: + __free_pages(p, order); + return ret; +} + +static int sev_firmware_shutdown_if_sev_initialized(struct sev_device *sev) +{ + int rc, error, sev_plat_state; + + lockdep_assert_held(&sev_cmd_mutex); + + error =3D 0; + rc =3D sev_get_platform_state(&sev_plat_state, &error); + if (rc < 0) { + if (error) + rc =3D error; + dev_dbg(sev->dev, "SEV get platform state failed %d\n", rc); + return rc; + } + + switch (sev_plat_state) { + case SEV_STATE_UNINIT: + return 0; + case SEV_STATE_INIT: + error =3D 0; + rc =3D __sev_platform_shutdown_locked(&error); + if (rc) { + if (error) + rc =3D error; + dev_err(sev->dev, "SEV platform shutdown failed %d\n", rc); + return rc; + } + sev_firmware_needs_reinit =3D true; + return 0; + case SEV_STATE_WORKING: + return -EBUSY; + default: + dev_err(sev->dev, "Unknown SEV firmware state: %d\n", sev_plat_state); + return -EINVAL; + } +} + +static void sev_firmware_reinit_if_shutdown(struct sev_device *sev) +{ + int rc, error; + + guard(mutex)(&sev_cmd_mutex); + + if (!sev_firmware_needs_reinit) + return; + + sev_firmware_needs_reinit =3D false; + error =3D 0; + rc =3D __sev_platform_init_locked(&error); + if (rc) { + if (error) + rc =3D error; + dev_err(sev->dev, "SEV platform re-init failed %d\n", rc); + } +} + static enum fw_upload_err sev_fw_upload_write(struct fw_upload *fw_upload, const u8 *data, u32 offset, u32 size, u32 *written) { - return FW_UPLOAD_ERR_BUSY; + struct sev_device *sev =3D fw_upload->dd_handle; + u8 old_major, old_minor, old_build; + int rc, error =3D 0; + enum fw_upload_err ret; + + if (offset !=3D 0) + return FW_UPLOAD_ERR_INVALID_SIZE; + + old_major =3D sev->api_major; + old_minor =3D sev->api_minor; + old_build =3D sev->build; + + mutex_lock(&sev_cmd_mutex); + + /* + * If the last firmware update returned RESTORE_REQUIRED, allow only + * this DLFWEX command so the admin can restore the previous FW + * version. If we are in this state the legacy firmware has previously + * been shut down, so no need to do it again. + */ + if (dlfwex_wants_rollback && psp_dead) { + dlfwex_wants_rollback =3D false; + psp_dead =3D false; + } else { + rc =3D sev_firmware_shutdown_if_sev_initialized(sev); + if (rc) { + ret =3D FW_UPLOAD_ERR_BUSY; + goto unlock; + } + } + + rc =3D sev_download_firmware_ex(sev, data, size); + if (rc) { + ret =3D FW_UPLOAD_ERR_FW_INVALID; + switch (rc) { + case SEV_RET_INVALID_PLATFORM_STATE: + fallthrough; + case SEV_RET_INVALID_ADDRESS: + /* these are probably kernel bugs */ + WARN_ON_ONCE(true); + ret =3D FW_UPLOAD_ERR_BUSY; + goto unlock; + case SEV_RET_INVALID_LEN: + ret =3D FW_UPLOAD_ERR_INVALID_SIZE; + goto unlock; + case SEV_RET_INVALID_PARAM: + dev_err(sev->dev, "SEV firmware image is not well formed\n"); + goto unlock; + case SEV_RET_SHUTDOWN_REQUIRED: + dev_err(sev->dev, "SEV firmware too far, shutdown required\n"); + goto unlock; + case SEV_RET_INVALID_CONFIG: + dev_err(sev->dev, "SEV firmware upgrade would rollback SVN\n"); + goto unlock; + case SEV_RET_BAD_SIGNATURE: + dev_err(sev->dev, "SEV firmware upgrade bad signature\n"); + goto unlock; + case SEV_RET_BAD_VERSION: + dev_err(sev->dev, "SEV firmware upgrade less than CommittedVersion\n"); + goto unlock; + case SEV_RET_UNSUPPORTED: + dev_err(sev->dev, "SEV firmware required feature not supported\n"); + goto unlock; + case SEV_RET_UPDATE_FAILED: + /* + * Update failed but fw rolled back on its own, + * operation can continue normally. + */ + dev_err(sev->dev, "SEV firmware update failed\n"); + ret =3D FW_UPLOAD_ERR_HW_ERROR; + goto unlock; + case SEV_RET_HWSEV_RET_UNSAFE: + /* + * "Following a return of HARDWARE_UNSAFE, operation of + * the SEV firmware is indeterminate + * and the recommendation is to reboot the platform." + */ + dev_err(sev->dev, "SEV firmware no longer safe to operate\n"); + psp_dead =3D true; + ret =3D FW_UPLOAD_ERR_HW_ERROR; + goto unlock; + case SEV_RET_RESTORE_REQUIRED: + /* + * FW asked us to roll back; we don't hold onto the + * last FW image, so we can't. We can set a flag to + * allow the admin to rollback if they happen to have + * the old firmware image handy. + */ + dev_err(sev->dev, "SEV firmware update failed, please roll back\n"); + psp_dead =3D true; + dlfwex_wants_rollback =3D true; + ret =3D FW_UPLOAD_ERR_HW_ERROR; + goto unlock; + default: + dev_err(sev->dev, "Unknown SEV firmware err %d\n", rc); + ret =3D FW_UPLOAD_ERR_HW_ERROR; + goto unlock; + } + } + + *written =3D size; + ret =3D FW_UPLOAD_ERR_NONE; + +unlock: + mutex_unlock(&sev_cmd_mutex); + + /* + * sev_get_api_version() updates the SEV and SNP statuses, SNP feature + * info if available, build numbers, etc. cached in struct sev_device. + * Update these if they may have changed for new firmware. + */ + if (ret =3D=3D FW_UPLOAD_ERR_NONE) { + error =3D 0; + + rc =3D sev_get_api_version(); + if (rc) { + dev_warn(sev->dev, + "SNP platform data refresh after firmware update failed %d\n", + rc); + } else if (sev->api_major !=3D old_major || + sev->api_minor !=3D old_minor || + sev->build !=3D old_build) { + dev_info(sev->dev, "SEV firmware updated to %d.%d build %d\n", + sev->api_major, sev->api_minor, sev->build); + } else { + dev_info(sev->dev, "SEV firmware not updated\n"); + } + } + + if (!dlfwex_wants_rollback) + sev_firmware_reinit_if_shutdown(sev); + + return ret; } =20 static enum fw_upload_err sev_fw_upload_poll_complete(struct fw_upload *fw= _upload) --=20 2.54.0