@@ -54,12 +54,15 @@ static struct kvm_vm *sev_vm_create(bool es)
5454 return vm ;
5555}
5656
57- static struct kvm_vm * __vm_create ( void )
57+ static struct kvm_vm * aux_vm_create ( bool with_vcpus )
5858{
5959 struct kvm_vm * vm ;
6060 int i ;
6161
6262 vm = vm_create (VM_MODE_DEFAULT , 0 , O_RDWR );
63+ if (!with_vcpus )
64+ return vm ;
65+
6366 for (i = 0 ; i < NR_MIGRATE_TEST_VCPUS ; ++ i )
6467 vm_vcpu_add (vm , i );
6568
@@ -93,7 +96,7 @@ static void test_sev_migrate_from(bool es)
9396
9497 src_vm = sev_vm_create (es );
9598 for (i = 0 ; i < NR_MIGRATE_TEST_VMS ; ++ i )
96- dst_vms [i ] = __vm_create ( );
99+ dst_vms [i ] = aux_vm_create (true );
97100
98101 /* Initial migration from the src to the first dst. */
99102 sev_migrate_from (dst_vms [0 ]-> fd , src_vm -> fd );
@@ -162,7 +165,7 @@ static void test_sev_migrate_parameters(void)
162165 sev_vm = sev_vm_create (/* es= */ false);
163166 sev_es_vm = sev_vm_create (/* es= */ true);
164167 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 );
166169 sev_es_vm_no_vmsa = vm_create (VM_MODE_DEFAULT , 0 , O_RDWR );
167170 sev_ioctl (sev_es_vm_no_vmsa -> fd , KVM_SEV_ES_INIT , NULL );
168171 vm_vcpu_add (sev_es_vm_no_vmsa , 1 );
@@ -203,11 +206,106 @@ static void test_sev_migrate_parameters(void)
203206 kvm_vm_free (vm_no_sev );
204207}
205208
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+
206297int main (int argc , char * argv [])
207298{
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+ }
212310 return 0 ;
213311}
0 commit comments