@@ -54,12 +54,15 @@ static struct kvm_vm *sev_vm_create(bool es)
54
54
return vm ;
55
55
}
56
56
57
- static struct kvm_vm * __vm_create ( void )
57
+ static struct kvm_vm * aux_vm_create ( bool with_vcpus )
58
58
{
59
59
struct kvm_vm * vm ;
60
60
int i ;
61
61
62
62
vm = vm_create (VM_MODE_DEFAULT , 0 , O_RDWR );
63
+ if (!with_vcpus )
64
+ return vm ;
65
+
63
66
for (i = 0 ; i < NR_MIGRATE_TEST_VCPUS ; ++ i )
64
67
vm_vcpu_add (vm , i );
65
68
@@ -93,7 +96,7 @@ static void test_sev_migrate_from(bool es)
93
96
94
97
src_vm = sev_vm_create (es );
95
98
for (i = 0 ; i < NR_MIGRATE_TEST_VMS ; ++ i )
96
- dst_vms [i ] = __vm_create ( );
99
+ dst_vms [i ] = aux_vm_create (true );
97
100
98
101
/* Initial migration from the src to the first dst. */
99
102
sev_migrate_from (dst_vms [0 ]-> fd , src_vm -> fd );
@@ -162,7 +165,7 @@ static void test_sev_migrate_parameters(void)
162
165
sev_vm = sev_vm_create (/* es= */ false);
163
166
sev_es_vm = sev_vm_create (/* es= */ true);
164
167
vm_no_vcpu = vm_create (VM_MODE_DEFAULT , 0 , O_RDWR );
165
- vm_no_sev = __vm_create ( );
168
+ vm_no_sev = aux_vm_create (true );
166
169
sev_es_vm_no_vmsa = vm_create (VM_MODE_DEFAULT , 0 , O_RDWR );
167
170
sev_ioctl (sev_es_vm_no_vmsa -> fd , KVM_SEV_ES_INIT , NULL );
168
171
vm_vcpu_add (sev_es_vm_no_vmsa , 1 );
@@ -203,11 +206,106 @@ static void test_sev_migrate_parameters(void)
203
206
kvm_vm_free (vm_no_sev );
204
207
}
205
208
209
+ static int __sev_mirror_create (int dst_fd , int src_fd )
210
+ {
211
+ struct kvm_enable_cap cap = {
212
+ .cap = KVM_CAP_VM_COPY_ENC_CONTEXT_FROM ,
213
+ .args = { src_fd }
214
+ };
215
+
216
+ return ioctl (dst_fd , KVM_ENABLE_CAP , & cap );
217
+ }
218
+
219
+
220
+ static void sev_mirror_create (int dst_fd , int src_fd )
221
+ {
222
+ int ret ;
223
+
224
+ ret = __sev_mirror_create (dst_fd , src_fd );
225
+ TEST_ASSERT (!ret , "Copying context failed, ret: %d, errno: %d\n" , ret , errno );
226
+ }
227
+
228
+ static void test_sev_mirror (bool es )
229
+ {
230
+ struct kvm_vm * src_vm , * dst_vm ;
231
+ struct kvm_sev_launch_start start = {
232
+ .policy = es ? SEV_POLICY_ES : 0
233
+ };
234
+ int i ;
235
+
236
+ src_vm = sev_vm_create (es );
237
+ dst_vm = aux_vm_create (false);
238
+
239
+ sev_mirror_create (dst_vm -> fd , src_vm -> fd );
240
+
241
+ /* Check that we can complete creation of the mirror VM. */
242
+ for (i = 0 ; i < NR_MIGRATE_TEST_VCPUS ; ++ i )
243
+ vm_vcpu_add (dst_vm , i );
244
+ sev_ioctl (dst_vm -> fd , KVM_SEV_LAUNCH_START , & start );
245
+ if (es )
246
+ sev_ioctl (dst_vm -> fd , KVM_SEV_LAUNCH_UPDATE_VMSA , NULL );
247
+
248
+ kvm_vm_free (src_vm );
249
+ kvm_vm_free (dst_vm );
250
+ }
251
+
252
+ static void test_sev_mirror_parameters (void )
253
+ {
254
+ struct kvm_vm * sev_vm , * sev_es_vm , * vm_no_vcpu , * vm_with_vcpu ;
255
+ int ret ;
256
+
257
+ sev_vm = sev_vm_create (/* es= */ false);
258
+ sev_es_vm = sev_vm_create (/* es= */ true);
259
+ vm_with_vcpu = aux_vm_create (true);
260
+ vm_no_vcpu = aux_vm_create (false);
261
+
262
+ ret = __sev_mirror_create (sev_vm -> fd , sev_vm -> fd );
263
+ TEST_ASSERT (
264
+ ret == -1 && errno == EINVAL ,
265
+ "Should not be able copy context to self. ret: %d, errno: %d\n" ,
266
+ ret , errno );
267
+
268
+ ret = __sev_mirror_create (sev_vm -> fd , sev_es_vm -> fd );
269
+ TEST_ASSERT (
270
+ ret == -1 && errno == EINVAL ,
271
+ "Should not be able copy context to SEV enabled VM. ret: %d, errno: %d\n" ,
272
+ ret , errno );
273
+
274
+ ret = __sev_mirror_create (sev_es_vm -> fd , sev_vm -> fd );
275
+ TEST_ASSERT (
276
+ ret == -1 && errno == EINVAL ,
277
+ "Should not be able copy context to SEV-ES enabled VM. ret: %d, errno: %d\n" ,
278
+ ret , errno );
279
+
280
+ ret = __sev_mirror_create (vm_no_vcpu -> fd , vm_with_vcpu -> fd );
281
+ TEST_ASSERT (ret == -1 && errno == EINVAL ,
282
+ "Copy context requires SEV enabled. ret %d, errno: %d\n" , ret ,
283
+ errno );
284
+
285
+ ret = __sev_mirror_create (vm_with_vcpu -> fd , sev_vm -> fd );
286
+ TEST_ASSERT (
287
+ ret == -1 && errno == EINVAL ,
288
+ "SEV copy context requires no vCPUS on the destination. ret: %d, errno: %d\n" ,
289
+ ret , errno );
290
+
291
+ kvm_vm_free (sev_vm );
292
+ kvm_vm_free (sev_es_vm );
293
+ kvm_vm_free (vm_with_vcpu );
294
+ kvm_vm_free (vm_no_vcpu );
295
+ }
296
+
206
297
int main (int argc , char * argv [])
207
298
{
208
- test_sev_migrate_from (/* es= */ false);
209
- test_sev_migrate_from (/* es= */ true);
210
- test_sev_migrate_locking ();
211
- test_sev_migrate_parameters ();
299
+ if (kvm_check_cap (KVM_CAP_VM_MOVE_ENC_CONTEXT_FROM )) {
300
+ test_sev_migrate_from (/* es= */ false);
301
+ test_sev_migrate_from (/* es= */ true);
302
+ test_sev_migrate_locking ();
303
+ test_sev_migrate_parameters ();
304
+ }
305
+ if (kvm_check_cap (KVM_CAP_VM_COPY_ENC_CONTEXT_FROM )) {
306
+ test_sev_mirror (/* es= */ false);
307
+ test_sev_mirror (/* es= */ true);
308
+ test_sev_mirror_parameters ();
309
+ }
212
310
return 0 ;
213
311
}
0 commit comments