@@ -84,9 +84,10 @@ struct enc_region {
84
84
};
85
85
86
86
/* 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 )
88
88
{
89
- int ret , asid , error = 0 ;
89
+ int ret , error = 0 ;
90
+ unsigned int asid ;
90
91
91
92
/* Check if there are any ASIDs to reclaim before performing a flush */
92
93
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)
116
117
}
117
118
118
119
/* 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 )
120
121
{
121
122
if (sev_flush_asids (min_asid , max_asid ))
122
123
return false;
@@ -143,8 +144,20 @@ static void sev_misc_cg_uncharge(struct kvm_sev_info *sev)
143
144
144
145
static int sev_asid_new (struct kvm_sev_info * sev )
145
146
{
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 ;
147
156
bool retry = true;
157
+ int ret ;
158
+
159
+ if (min_asid > max_asid )
160
+ return - ENOTTY ;
148
161
149
162
WARN_ON (sev -> misc_cg );
150
163
sev -> misc_cg = get_current_misc_cg ();
@@ -157,12 +170,6 @@ static int sev_asid_new(struct kvm_sev_info *sev)
157
170
158
171
mutex_lock (& sev_bitmap_lock );
159
172
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 ;
166
173
again :
167
174
asid = find_next_zero_bit (sev_asid_bitmap , max_asid + 1 , min_asid );
168
175
if (asid > max_asid ) {
@@ -179,15 +186,16 @@ static int sev_asid_new(struct kvm_sev_info *sev)
179
186
180
187
mutex_unlock (& sev_bitmap_lock );
181
188
182
- return asid ;
189
+ sev -> asid = asid ;
190
+ return 0 ;
183
191
e_uncharge :
184
192
sev_misc_cg_uncharge (sev );
185
193
put_misc_cg (sev -> misc_cg );
186
194
sev -> misc_cg = NULL ;
187
195
return ret ;
188
196
}
189
197
190
- static int sev_get_asid (struct kvm * kvm )
198
+ static unsigned int sev_get_asid (struct kvm * kvm )
191
199
{
192
200
struct kvm_sev_info * sev = & to_kvm_svm (kvm )-> sev_info ;
193
201
@@ -247,21 +255,19 @@ static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp)
247
255
{
248
256
struct kvm_sev_info * sev = & to_kvm_svm (kvm )-> sev_info ;
249
257
struct sev_platform_init_args init_args = {0 };
250
- int asid , ret ;
258
+ int ret ;
251
259
252
260
if (kvm -> created_vcpus )
253
261
return - EINVAL ;
254
262
255
- ret = - EBUSY ;
256
263
if (unlikely (sev -> active ))
257
- return ret ;
264
+ return - EINVAL ;
258
265
259
266
sev -> active = true;
260
267
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 )
263
270
goto e_no_asid ;
264
- sev -> asid = asid ;
265
271
266
272
init_args .probe = false;
267
273
ret = sev_platform_init (& init_args );
@@ -287,8 +293,8 @@ static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp)
287
293
288
294
static int sev_bind_asid (struct kvm * kvm , unsigned int handle , int * error )
289
295
{
296
+ unsigned int asid = sev_get_asid (kvm );
290
297
struct sev_data_activate activate ;
291
- int asid = sev_get_asid (kvm );
292
298
int ret ;
293
299
294
300
/* activate ASID on the given handle */
@@ -2240,8 +2246,10 @@ void __init sev_hardware_setup(void)
2240
2246
goto out ;
2241
2247
}
2242
2248
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
+ }
2245
2253
sev_supported = true;
2246
2254
2247
2255
/* SEV-ES support requested? */
@@ -2272,7 +2280,9 @@ void __init sev_hardware_setup(void)
2272
2280
out :
2273
2281
if (boot_cpu_has (X86_FEATURE_SEV ))
2274
2282
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" ,
2276
2286
min_sev_asid , max_sev_asid );
2277
2287
if (boot_cpu_has (X86_FEATURE_SEV_ES ))
2278
2288
pr_info ("SEV-ES %s (ASIDs %u - %u)\n" ,
@@ -2320,7 +2330,7 @@ int sev_cpu_init(struct svm_cpu_data *sd)
2320
2330
*/
2321
2331
static void sev_flush_encrypted_page (struct kvm_vcpu * vcpu , void * va )
2322
2332
{
2323
- int asid = to_kvm_svm (vcpu -> kvm )-> sev_info . asid ;
2333
+ unsigned int asid = sev_get_asid (vcpu -> kvm );
2324
2334
2325
2335
/*
2326
2336
* 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)
2638
2648
void pre_sev_run (struct vcpu_svm * svm , int cpu )
2639
2649
{
2640
2650
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 );
2642
2652
2643
2653
/* Assign the asid allocated with this SEV guest */
2644
2654
svm -> asid = asid ;
0 commit comments