diff options
| author | Mark Brown <broonie@kernel.org> | 2026-05-29 22:46:54 +0100 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2026-05-29 22:46:54 +0100 |
| commit | f624c17e475e17a1dbeef56ef624378f4e5a80b7 (patch) | |
| tree | aeae91c403e0713b4a67f8610040905e8c0786fd /drivers | |
| parent | 29fa9b4922922bd33cac81162dbf669bfb55a52d (diff) | |
| parent | d1568b1332b6b3b36b222c2868fc102727c12a34 (diff) | |
| download | linux-next-history-f624c17e475e17a1dbeef56ef624378f4e5a80b7.tar.gz | |
Merge branch 'next' of https://github.com/kvm-x86/linux.git
# Conflicts:
# arch/x86/include/asm/tdx.h
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/crypto/ccp/sev-dev.c | 101 |
1 files changed, 93 insertions, 8 deletions
diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c index a8eb51ec0ee2d..ca473ca198b81 100644 --- a/drivers/crypto/ccp/sev-dev.c +++ b/drivers/crypto/ccp/sev-dev.c @@ -2369,7 +2369,8 @@ e_free_pdh: return ret; } -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 *status, + int *error) { struct sev_device *sev = psp_master->sev_data; struct sev_data_snp_addr buf; @@ -2377,9 +2378,6 @@ static int sev_ioctl_do_snp_platform_status(struct sev_issue_cmd *argp) void *data; int ret; - if (!argp->data) - return -EINVAL; - status_page = alloc_page(GFP_KERNEL_ACCOUNT); if (!status_page) return -ENOMEM; @@ -2402,7 +2400,7 @@ static int sev_ioctl_do_snp_platform_status(struct sev_issue_cmd *argp) } buf.address = __psp_pa(data); - ret = __sev_do_cmd_locked(SEV_CMD_SNP_PLATFORM_STATUS, &buf, &argp->error); + ret = __sev_do_cmd_locked(SEV_CMD_SNP_PLATFORM_STATUS, &buf, error); if (sev->snp_initialized) { /* @@ -2417,15 +2415,32 @@ static int sev_ioctl_do_snp_platform_status(struct sev_issue_cmd *argp) if (ret) goto cleanup; - if (copy_to_user((void __user *)argp->data, data, - sizeof(struct sev_user_data_snp_status))) - ret = -EFAULT; + memcpy(status, data, sizeof(*status)); cleanup: __free_pages(status_page, 0); return ret; } +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 = __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 = -EFAULT; + + return ret; +} + static int sev_ioctl_do_snp_commit(struct sev_issue_cmd *argp) { struct sev_data_snp_commit buf; @@ -2897,3 +2912,73 @@ void sev_pci_exit(void) sev_firmware_shutdown(sev); } + +static int get_v1_svn(struct sev_device *sev) +{ + struct sev_snp_tcb_version_genoa_milan *tcb; + struct sev_user_data_snp_status status; + int ret, error = 0; + + mutex_lock(&sev_cmd_mutex); + ret = __sev_do_snp_platform_status(&status, &error); + mutex_unlock(&sev_cmd_mutex); + if (ret < 0) + return ret; + + tcb = (struct sev_snp_tcb_version_genoa_milan *)&status + .current_tcb_version; + return tcb->snp; +} + +static int get_v2_svn(struct sev_device *sev) +{ + struct sev_user_data_snp_status status; + struct sev_snp_tcb_version_turin *tcb; + int ret, error = 0; + + mutex_lock(&sev_cmd_mutex); + ret = __sev_do_snp_platform_status(&status, &error); + mutex_unlock(&sev_cmd_mutex); + if (ret < 0) + return ret; + + tcb = (struct sev_snp_tcb_version_turin *)&status + .current_tcb_version; + return tcb->snp; +} + +static bool sev_firmware_allows_es(struct sev_device *sev) +{ + /* Documented in AMD-SB-3023 */ + if (boot_cpu_has(X86_FEATURE_ZEN4) || boot_cpu_has(X86_FEATURE_ZEN3)) + return get_v1_svn(sev) < 0x1b; + else if (boot_cpu_has(X86_FEATURE_ZEN5)) + return get_v2_svn(sev) < 0x4; + else + return true; +} + +int sev_firmware_supported_vm_types(void) +{ + int supported_vm_types = 0; + struct sev_device *sev; + + if (!psp_master || !psp_master->sev_data) + return supported_vm_types; + sev = psp_master->sev_data; + + supported_vm_types |= BIT(KVM_X86_SEV_VM); + supported_vm_types |= BIT(KVM_X86_SEV_ES_VM); + + if (!sev->snp_initialized) + return supported_vm_types; + + supported_vm_types |= BIT(KVM_X86_SNP_VM); + + if (!sev_firmware_allows_es(sev)) + supported_vm_types &= ~BIT(KVM_X86_SEV_ES_VM); + + return supported_vm_types; + +} +EXPORT_SYMBOL_FOR_MODULES(sev_firmware_supported_vm_types, "kvm-amd"); |
