Skip to content

Commit 179a842

Browse files
ashkalrabonzini
authored andcommitted
KVM: SEV: Disable SEV-SNP support on initialization failure
During platform init, SNP initialization may fail for several reasons, such as firmware command failures and incompatible versions. However, the KVM capability may continue to advertise support for it. The platform may have SNP enabled but if SNP_INIT fails then SNP is not supported by KVM. During KVM module initialization query the SNP platform status to obtain the SNP initialization state and use it as an additional condition to determine support for SEV-SNP. Co-developed-by: Sean Christopherson <[email protected]> Signed-off-by: Sean Christopherson <[email protected]> Co-developed-by: Pratik R. Sampat <[email protected]> Signed-off-by: Pratik R. Sampat <[email protected]> Reviewed-by: Tom Lendacky <[email protected]> Signed-off-by: Ashish Kalra <[email protected]> Reviewed-by: Pankaj Gupta <[email protected]> Reviewed-by: Pavan Kumar Paluri <[email protected]> Message-ID: <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent ce360c2 commit 179a842

File tree

1 file changed

+35
-9
lines changed

1 file changed

+35
-9
lines changed

arch/x86/kvm/svm/sev.c

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2871,6 +2871,33 @@ void __init sev_set_cpu_caps(void)
28712871
}
28722872
}
28732873

2874+
static bool is_sev_snp_initialized(void)
2875+
{
2876+
struct sev_user_data_snp_status *status;
2877+
struct sev_data_snp_addr buf;
2878+
bool initialized = false;
2879+
int ret, error = 0;
2880+
2881+
status = snp_alloc_firmware_page(GFP_KERNEL | __GFP_ZERO);
2882+
if (!status)
2883+
return false;
2884+
2885+
buf.address = __psp_pa(status);
2886+
ret = sev_do_cmd(SEV_CMD_SNP_PLATFORM_STATUS, &buf, &error);
2887+
if (ret) {
2888+
pr_err("SEV: SNP_PLATFORM_STATUS failed ret=%d, fw_error=%d (%#x)\n",
2889+
ret, error, error);
2890+
goto out;
2891+
}
2892+
2893+
initialized = !!status->state;
2894+
2895+
out:
2896+
snp_free_firmware_page(status);
2897+
2898+
return initialized;
2899+
}
2900+
28742901
void __init sev_hardware_setup(void)
28752902
{
28762903
unsigned int eax, ebx, ecx, edx, sev_asid_count, sev_es_asid_count;
@@ -2975,6 +3002,14 @@ void __init sev_hardware_setup(void)
29753002
sev_snp_supported = sev_snp_enabled && cc_platform_has(CC_ATTR_HOST_SEV_SNP);
29763003

29773004
out:
3005+
if (sev_enabled) {
3006+
init_args.probe = true;
3007+
if (sev_platform_init(&init_args))
3008+
sev_supported = sev_es_supported = sev_snp_supported = false;
3009+
else if (sev_snp_supported)
3010+
sev_snp_supported = is_sev_snp_initialized();
3011+
}
3012+
29783013
if (boot_cpu_has(X86_FEATURE_SEV))
29793014
pr_info("SEV %s (ASIDs %u - %u)\n",
29803015
sev_supported ? min_sev_asid <= max_sev_asid ? "enabled" :
@@ -3001,15 +3036,6 @@ void __init sev_hardware_setup(void)
30013036
sev_supported_vmsa_features = 0;
30023037
if (sev_es_debug_swap_enabled)
30033038
sev_supported_vmsa_features |= SVM_SEV_FEAT_DEBUG_SWAP;
3004-
3005-
if (!sev_enabled)
3006-
return;
3007-
3008-
/*
3009-
* Do both SNP and SEV initialization at KVM module load.
3010-
*/
3011-
init_args.probe = true;
3012-
sev_platform_init(&init_args);
30133039
}
30143040

30153041
void sev_hardware_unsetup(void)

0 commit comments

Comments
 (0)