Commit fad133c7 authored by Tom Lendacky's avatar Tom Lendacky Committed by Borislav Petkov (AMD)

crypto: ccp: Add the SNP_COMMIT command

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.

  [ mdr: Note the reported TCB update in the documentation/commit. ]
Signed-off-by: default avatarTom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: default avatarMichael Roth <michael.roth@amd.com>
Signed-off-by: default avatarBorislav Petkov (AMD) <bp@alien8.de>
Link: https://lore.kernel.org/r/20240126041126.1927228-25-michael.roth@amd.com
parent f5db8841
......@@ -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
============================
......
......@@ -222,6 +222,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;
}
......@@ -1990,6 +1991,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.len = 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;
......@@ -2044,6 +2058,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;
......
......@@ -801,6 +801,15 @@ struct sev_platform_init_args {
bool probe;
};
/**
* struct sev_data_snp_commit - SNP_COMMIT structure
*
* @len: length of the command buffer read by the PSP
*/
struct sev_data_snp_commit {
u32 len;
} __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,
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment