[v1,25/26] crypto: ccp: Add the SNP_COMMIT command
Commit Message
From: Tom Lendacky <thomas.lendacky@amd.com>
The SNP_COMMIT command is used to commit the currently installed version
of the SEV firmware. Once committed, the firmware cannot be replaced
with a previous firmware version (cannot be rolled back). This command
will also update the reported TCB to match that of the currently
installed firmware.
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
[mdr: note the reported TCB update in the documentation/commit]
Signed-off-by: Michael Roth <michael.roth@amd.com>
---
Documentation/virt/coco/sev-guest.rst | 11 +++++++++++
drivers/crypto/ccp/sev-dev.c | 17 +++++++++++++++++
include/linux/psp-sev.h | 9 +++++++++
include/uapi/linux/psp-sev.h | 1 +
4 files changed, 38 insertions(+)
Comments
On Sat, Dec 30, 2023 at 10:19:53AM -0600, Michael Roth wrote:
> +/**
> + * struct sev_data_snp_commit - SNP_COMMIT structure
> + *
> + * @length: len of the command buffer read by the PSP
> + */
> +struct sev_data_snp_commit {
> + u32 length;
> +} __packed;
> +
diff --git a/include/linux/psp-sev.h b/include/linux/psp-sev.h
index 11af3dd9126d..31b9266b26ce 100644
--- a/include/linux/psp-sev.h
+++ b/include/linux/psp-sev.h
@@ -790,7 +790,7 @@ struct sev_data_snp_shutdown_ex {
/**
* struct sev_data_snp_commit - SNP_COMMIT structure
*
- * @length: len of the command buffer read by the PSP
+ * @length: length of the command buffer read by the PSP
*/
struct sev_data_snp_commit {
u32 length;
@@ -151,6 +151,17 @@ The SNP_PLATFORM_STATUS command is used to query the SNP platform status. The
status includes API major, minor version and more. See the SEV-SNP
specification for further details.
+2.5 SNP_COMMIT
+--------------
+:Technology: sev-snp
+:Type: hypervisor ioctl cmd
+:Returns (out): 0 on success, -negative on error
+
+SNP_COMMIT is used to commit the currently installed firmware using the
+SEV-SNP firmware SNP_COMMIT command. This prevents roll-back to a previously
+committed firmware version. This will also update the reported TCB to match
+that of the currently installed firmware.
+
3. SEV-SNP CPUID Enforcement
============================
@@ -224,6 +224,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_COMMIT: return sizeof(struct sev_data_snp_commit);
default: return 0;
}
@@ -2004,6 +2005,19 @@ static int sev_ioctl_do_snp_platform_status(struct sev_issue_cmd *argp)
return ret;
}
+static int sev_ioctl_do_snp_commit(struct sev_issue_cmd *argp)
+{
+ struct sev_device *sev = psp_master->sev_data;
+ struct sev_data_snp_commit buf;
+
+ if (!sev->snp_initialized)
+ return -EINVAL;
+
+ buf.length = sizeof(buf);
+
+ return __sev_do_cmd_locked(SEV_CMD_SNP_COMMIT, &buf, &argp->error);
+}
+
static long sev_ioctl(struct file *file, unsigned int ioctl, unsigned long arg)
{
void __user *argp = (void __user *)arg;
@@ -2058,6 +2072,9 @@ static long sev_ioctl(struct file *file, unsigned int ioctl, unsigned long arg)
case SNP_PLATFORM_STATUS:
ret = sev_ioctl_do_snp_platform_status(&input);
break;
+ case SNP_COMMIT:
+ ret = sev_ioctl_do_snp_commit(&input);
+ break;
default:
ret = -EINVAL;
goto out;
@@ -787,6 +787,15 @@ struct sev_data_snp_shutdown_ex {
u32 rsvd1:31;
} __packed;
+/**
+ * struct sev_data_snp_commit - SNP_COMMIT structure
+ *
+ * @length: len of the command buffer read by the PSP
+ */
+struct sev_data_snp_commit {
+ u32 length;
+} __packed;
+
#ifdef CONFIG_CRYPTO_DEV_SP_PSP
/**
@@ -29,6 +29,7 @@ enum {
SEV_GET_ID, /* This command is deprecated, use SEV_GET_ID2 */
SEV_GET_ID2,
SNP_PLATFORM_STATUS,
+ SNP_COMMIT,
SEV_MAX,
};