@@ -84,9 +84,10 @@ struct enc_region {
8484};
8585
8686/* Called with the sev_bitmap_lock held, or on shutdown */
87- static int sev_flush_asids (int min_asid , int max_asid )
87+ static int sev_flush_asids (unsigned int min_asid , unsigned int max_asid )
8888{
89- int ret , asid , error = 0 ;
89+ int ret , error = 0 ;
90+ unsigned int asid ;
9091
9192 /* Check if there are any ASIDs to reclaim before performing a flush */
9293 asid = find_next_bit (sev_reclaim_asid_bitmap , nr_asids , min_asid );
@@ -116,7 +117,7 @@ static inline bool is_mirroring_enc_context(struct kvm *kvm)
116117}
117118
118119/* Must be called with the sev_bitmap_lock held */
119- static bool __sev_recycle_asids (int min_asid , int max_asid )
120+ static bool __sev_recycle_asids (unsigned int min_asid , unsigned int max_asid )
120121{
121122 if (sev_flush_asids (min_asid , max_asid ))
122123 return false;
@@ -143,8 +144,20 @@ static void sev_misc_cg_uncharge(struct kvm_sev_info *sev)
143144
144145static int sev_asid_new (struct kvm_sev_info * sev )
145146{
146- int asid , min_asid , max_asid , ret ;
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 ;
147156 bool retry = true;
157+ int ret ;
158+
159+ if (min_asid > max_asid )
160+ return - ENOTTY ;
148161
149162 WARN_ON (sev -> misc_cg );
150163 sev -> misc_cg = get_current_misc_cg ();
@@ -157,12 +170,6 @@ static int sev_asid_new(struct kvm_sev_info *sev)
157170
158171 mutex_lock (& sev_bitmap_lock );
159172
160- /*
161- * SEV-enabled guests must use asid from min_sev_asid to max_sev_asid.
162- * SEV-ES-enabled guest can use from 1 to min_sev_asid - 1.
163- */
164- min_asid = sev -> es_active ? 1 : min_sev_asid ;
165- max_asid = sev -> es_active ? min_sev_asid - 1 : max_sev_asid ;
166173again :
167174 asid = find_next_zero_bit (sev_asid_bitmap , max_asid + 1 , min_asid );
168175 if (asid > max_asid ) {
@@ -179,15 +186,16 @@ static int sev_asid_new(struct kvm_sev_info *sev)
179186
180187 mutex_unlock (& sev_bitmap_lock );
181188
182- return asid ;
189+ sev -> asid = asid ;
190+ return 0 ;
183191e_uncharge :
184192 sev_misc_cg_uncharge (sev );
185193 put_misc_cg (sev -> misc_cg );
186194 sev -> misc_cg = NULL ;
187195 return ret ;
188196}
189197
190- static int sev_get_asid (struct kvm * kvm )
198+ static unsigned int sev_get_asid (struct kvm * kvm )
191199{
192200 struct kvm_sev_info * sev = & to_kvm_svm (kvm )-> sev_info ;
193201
@@ -247,21 +255,19 @@ static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp)
247255{
248256 struct kvm_sev_info * sev = & to_kvm_svm (kvm )-> sev_info ;
249257 struct sev_platform_init_args init_args = {0 };
250- int asid , ret ;
258+ int ret ;
251259
252260 if (kvm -> created_vcpus )
253261 return - EINVAL ;
254262
255- ret = - EBUSY ;
256263 if (unlikely (sev -> active ))
257- return ret ;
264+ return - EINVAL ;
258265
259266 sev -> active = true;
260267 sev -> es_active = argp -> id == KVM_SEV_ES_INIT ;
261- asid = sev_asid_new (sev );
262- if (asid < 0 )
268+ ret = sev_asid_new (sev );
269+ if (ret )
263270 goto e_no_asid ;
264- sev -> asid = asid ;
265271
266272 init_args .probe = false;
267273 ret = sev_platform_init (& init_args );
@@ -287,8 +293,8 @@ static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp)
287293
288294static int sev_bind_asid (struct kvm * kvm , unsigned int handle , int * error )
289295{
296+ unsigned int asid = sev_get_asid (kvm );
290297 struct sev_data_activate activate ;
291- int asid = sev_get_asid (kvm );
292298 int ret ;
293299
294300 /* activate ASID on the given handle */
@@ -2240,8 +2246,10 @@ void __init sev_hardware_setup(void)
22402246 goto out ;
22412247 }
22422248
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 ));
2249+ if (min_sev_asid <= max_sev_asid ) {
2250+ sev_asid_count = max_sev_asid - min_sev_asid + 1 ;
2251+ WARN_ON_ONCE (misc_cg_set_capacity (MISC_CG_RES_SEV , sev_asid_count ));
2252+ }
22452253 sev_supported = true;
22462254
22472255 /* SEV-ES support requested? */
@@ -2272,7 +2280,9 @@ void __init sev_hardware_setup(void)
22722280out :
22732281 if (boot_cpu_has (X86_FEATURE_SEV ))
22742282 pr_info ("SEV %s (ASIDs %u - %u)\n" ,
2275- sev_supported ? "enabled" : "disabled" ,
2283+ sev_supported ? min_sev_asid <= max_sev_asid ? "enabled" :
2284+ "unusable" :
2285+ "disabled" ,
22762286 min_sev_asid , max_sev_asid );
22772287 if (boot_cpu_has (X86_FEATURE_SEV_ES ))
22782288 pr_info ("SEV-ES %s (ASIDs %u - %u)\n" ,
@@ -2320,7 +2330,7 @@ int sev_cpu_init(struct svm_cpu_data *sd)
23202330 */
23212331static void sev_flush_encrypted_page (struct kvm_vcpu * vcpu , void * va )
23222332{
2323- int asid = to_kvm_svm (vcpu -> kvm )-> sev_info . asid ;
2333+ unsigned int asid = sev_get_asid (vcpu -> kvm );
23242334
23252335 /*
23262336 * Note! The address must be a kernel address, as regular page walk
@@ -2638,7 +2648,7 @@ void sev_es_unmap_ghcb(struct vcpu_svm *svm)
26382648void pre_sev_run (struct vcpu_svm * svm , int cpu )
26392649{
26402650 struct svm_cpu_data * sd = per_cpu_ptr (& svm_data , cpu );
2641- int asid = sev_get_asid (svm -> vcpu .kvm );
2651+ unsigned int asid = sev_get_asid (svm -> vcpu .kvm );
26422652
26432653 /* Assign the asid allocated with this SEV guest */
26442654 svm -> asid = asid ;
0 commit comments