Skip to content

Commit 0aa6b90

Browse files
ashkalrasean-jc
authored andcommitted
KVM: SVM: Add support for allowing zero SEV ASIDs
Some BIOSes allow the end user to set the minimum SEV ASID value (CPUID 0x8000001F_EDX) to be greater than the maximum number of encrypted guests, or maximum SEV ASID value (CPUID 0x8000001F_ECX) in order to dedicate all the SEV ASIDs to SEV-ES or SEV-SNP. The SEV support, as coded, does not handle the case where the minimum SEV ASID value can be greater than the maximum SEV ASID value. As a result, the following confusing message is issued: [ 30.715724] kvm_amd: SEV enabled (ASIDs 1007 - 1006) Fix the support to properly handle this case. Fixes: 916391a ("KVM: SVM: Add support for SEV-ES capability in KVM") Suggested-by: Sean Christopherson <[email protected]> Signed-off-by: Ashish Kalra <[email protected]> Cc: [email protected] Acked-by: Tom Lendacky <[email protected]> Link: https://lore.kernel.org/r/[email protected] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Sean Christopherson <[email protected]>
1 parent 466eec4 commit 0aa6b90

File tree

1 file changed

+19
-10
lines changed

1 file changed

+19
-10
lines changed

arch/x86/kvm/svm/sev.c

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -144,10 +144,21 @@ static void sev_misc_cg_uncharge(struct kvm_sev_info *sev)
144144

145145
static int sev_asid_new(struct kvm_sev_info *sev)
146146
{
147-
unsigned int asid, min_asid, max_asid;
147+
/*
148+
* SEV-enabled guests must use asid from min_sev_asid to max_sev_asid.
149+
* SEV-ES-enabled guest can use from 1 to min_sev_asid - 1.
150+
* Note: min ASID can end up larger than the max if basic SEV support is
151+
* effectively disabled by disallowing use of ASIDs for SEV guests.
152+
*/
153+
unsigned int min_asid = sev->es_active ? 1 : min_sev_asid;
154+
unsigned int max_asid = sev->es_active ? min_sev_asid - 1 : max_sev_asid;
155+
unsigned int asid;
148156
bool retry = true;
149157
int ret;
150158

159+
if (min_asid > max_asid)
160+
return -ENOTTY;
161+
151162
WARN_ON(sev->misc_cg);
152163
sev->misc_cg = get_current_misc_cg();
153164
ret = sev_misc_cg_try_charge(sev);
@@ -159,12 +170,6 @@ static int sev_asid_new(struct kvm_sev_info *sev)
159170

160171
mutex_lock(&sev_bitmap_lock);
161172

162-
/*
163-
* SEV-enabled guests must use asid from min_sev_asid to max_sev_asid.
164-
* SEV-ES-enabled guest can use from 1 to min_sev_asid - 1.
165-
*/
166-
min_asid = sev->es_active ? 1 : min_sev_asid;
167-
max_asid = sev->es_active ? min_sev_asid - 1 : max_sev_asid;
168173
again:
169174
asid = find_next_zero_bit(sev_asid_bitmap, max_asid + 1, min_asid);
170175
if (asid > max_asid) {
@@ -2234,8 +2239,10 @@ void __init sev_hardware_setup(void)
22342239
goto out;
22352240
}
22362241

2237-
sev_asid_count = max_sev_asid - min_sev_asid + 1;
2238-
WARN_ON_ONCE(misc_cg_set_capacity(MISC_CG_RES_SEV, sev_asid_count));
2242+
if (min_sev_asid <= max_sev_asid) {
2243+
sev_asid_count = max_sev_asid - min_sev_asid + 1;
2244+
WARN_ON_ONCE(misc_cg_set_capacity(MISC_CG_RES_SEV, sev_asid_count));
2245+
}
22392246
sev_supported = true;
22402247

22412248
/* SEV-ES support requested? */
@@ -2266,7 +2273,9 @@ void __init sev_hardware_setup(void)
22662273
out:
22672274
if (boot_cpu_has(X86_FEATURE_SEV))
22682275
pr_info("SEV %s (ASIDs %u - %u)\n",
2269-
sev_supported ? "enabled" : "disabled",
2276+
sev_supported ? min_sev_asid <= max_sev_asid ? "enabled" :
2277+
"unusable" :
2278+
"disabled",
22702279
min_sev_asid, max_sev_asid);
22712280
if (boot_cpu_has(X86_FEATURE_SEV_ES))
22722281
pr_info("SEV-ES %s (ASIDs %u - %u)\n",

0 commit comments

Comments
 (0)