xref: /openbmc/linux/tools/testing/selftests/kvm/aarch64/vcpu_width_config.c (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
12f5d27e6SReiji Watanabe // SPDX-License-Identifier: GPL-2.0-only
22f5d27e6SReiji Watanabe /*
32f5d27e6SReiji Watanabe  * vcpu_width_config - Test KVM_ARM_VCPU_INIT() with KVM_ARM_VCPU_EL1_32BIT.
42f5d27e6SReiji Watanabe  *
52f5d27e6SReiji Watanabe  * Copyright (c) 2022 Google LLC.
62f5d27e6SReiji Watanabe  *
72f5d27e6SReiji Watanabe  * This is a test that ensures that non-mixed-width vCPUs (all 64bit vCPUs
82f5d27e6SReiji Watanabe  * or all 32bit vcPUs) can be configured and mixed-width vCPUs cannot be
92f5d27e6SReiji Watanabe  * configured.
102f5d27e6SReiji Watanabe  */
112f5d27e6SReiji Watanabe 
122f5d27e6SReiji Watanabe #include "kvm_util.h"
132f5d27e6SReiji Watanabe #include "processor.h"
142f5d27e6SReiji Watanabe #include "test_util.h"
152f5d27e6SReiji Watanabe 
162f5d27e6SReiji Watanabe 
172f5d27e6SReiji Watanabe /*
18376851f8SSean Christopherson  * Add a vCPU, run KVM_ARM_VCPU_INIT with @init0, and then
19376851f8SSean Christopherson  * add another vCPU, and run KVM_ARM_VCPU_INIT with @init1.
202f5d27e6SReiji Watanabe  */
add_init_2vcpus(struct kvm_vcpu_init * init0,struct kvm_vcpu_init * init1)21376851f8SSean Christopherson static int add_init_2vcpus(struct kvm_vcpu_init *init0,
22376851f8SSean Christopherson 			   struct kvm_vcpu_init *init1)
232f5d27e6SReiji Watanabe {
24376851f8SSean Christopherson 	struct kvm_vcpu *vcpu0, *vcpu1;
252f5d27e6SReiji Watanabe 	struct kvm_vm *vm;
262f5d27e6SReiji Watanabe 	int ret;
272f5d27e6SReiji Watanabe 
2895fb0460SSean Christopherson 	vm = vm_create_barebones();
292f5d27e6SReiji Watanabe 
30376851f8SSean Christopherson 	vcpu0 = __vm_vcpu_add(vm, 0);
31768e9a61SSean Christopherson 	ret = __vcpu_ioctl(vcpu0, KVM_ARM_VCPU_INIT, init0);
322f5d27e6SReiji Watanabe 	if (ret)
332f5d27e6SReiji Watanabe 		goto free_exit;
342f5d27e6SReiji Watanabe 
35376851f8SSean Christopherson 	vcpu1 = __vm_vcpu_add(vm, 1);
36768e9a61SSean Christopherson 	ret = __vcpu_ioctl(vcpu1, KVM_ARM_VCPU_INIT, init1);
372f5d27e6SReiji Watanabe 
382f5d27e6SReiji Watanabe free_exit:
392f5d27e6SReiji Watanabe 	kvm_vm_free(vm);
402f5d27e6SReiji Watanabe 	return ret;
412f5d27e6SReiji Watanabe }
422f5d27e6SReiji Watanabe 
432f5d27e6SReiji Watanabe /*
44376851f8SSean Christopherson  * Add two vCPUs, then run KVM_ARM_VCPU_INIT for one vCPU with @init0,
45376851f8SSean Christopherson  * and run KVM_ARM_VCPU_INIT for another vCPU with @init1.
462f5d27e6SReiji Watanabe  */
add_2vcpus_init_2vcpus(struct kvm_vcpu_init * init0,struct kvm_vcpu_init * init1)47376851f8SSean Christopherson static int add_2vcpus_init_2vcpus(struct kvm_vcpu_init *init0,
48376851f8SSean Christopherson 				  struct kvm_vcpu_init *init1)
492f5d27e6SReiji Watanabe {
50376851f8SSean Christopherson 	struct kvm_vcpu *vcpu0, *vcpu1;
512f5d27e6SReiji Watanabe 	struct kvm_vm *vm;
522f5d27e6SReiji Watanabe 	int ret;
532f5d27e6SReiji Watanabe 
5495fb0460SSean Christopherson 	vm = vm_create_barebones();
552f5d27e6SReiji Watanabe 
56376851f8SSean Christopherson 	vcpu0 = __vm_vcpu_add(vm, 0);
57376851f8SSean Christopherson 	vcpu1 = __vm_vcpu_add(vm, 1);
582f5d27e6SReiji Watanabe 
59768e9a61SSean Christopherson 	ret = __vcpu_ioctl(vcpu0, KVM_ARM_VCPU_INIT, init0);
602f5d27e6SReiji Watanabe 	if (ret)
612f5d27e6SReiji Watanabe 		goto free_exit;
622f5d27e6SReiji Watanabe 
63768e9a61SSean Christopherson 	ret = __vcpu_ioctl(vcpu1, KVM_ARM_VCPU_INIT, init1);
642f5d27e6SReiji Watanabe 
652f5d27e6SReiji Watanabe free_exit:
662f5d27e6SReiji Watanabe 	kvm_vm_free(vm);
672f5d27e6SReiji Watanabe 	return ret;
682f5d27e6SReiji Watanabe }
692f5d27e6SReiji Watanabe 
702f5d27e6SReiji Watanabe /*
712f5d27e6SReiji Watanabe  * Tests that two 64bit vCPUs can be configured, two 32bit vCPUs can be
722f5d27e6SReiji Watanabe  * configured, and two mixed-width vCPUs cannot be configured.
732f5d27e6SReiji Watanabe  * Each of those three cases, configure vCPUs in two different orders.
742f5d27e6SReiji Watanabe  * The one is running KVM_CREATE_VCPU for 2 vCPUs, and then running
752f5d27e6SReiji Watanabe  * KVM_ARM_VCPU_INIT for them.
762f5d27e6SReiji Watanabe  * The other is running KVM_CREATE_VCPU and KVM_ARM_VCPU_INIT for a vCPU,
772f5d27e6SReiji Watanabe  * and then run those commands for another vCPU.
782f5d27e6SReiji Watanabe  */
main(void)792f5d27e6SReiji Watanabe int main(void)
802f5d27e6SReiji Watanabe {
81376851f8SSean Christopherson 	struct kvm_vcpu_init init0, init1;
822f5d27e6SReiji Watanabe 	struct kvm_vm *vm;
832f5d27e6SReiji Watanabe 	int ret;
842f5d27e6SReiji Watanabe 
85*7ed397d1SSean Christopherson 	TEST_REQUIRE(kvm_has_cap(KVM_CAP_ARM_EL1_32BIT));
862f5d27e6SReiji Watanabe 
87376851f8SSean Christopherson 	/* Get the preferred target type and copy that to init1 for later use */
8895fb0460SSean Christopherson 	vm = vm_create_barebones();
89376851f8SSean Christopherson 	vm_ioctl(vm, KVM_ARM_PREFERRED_TARGET, &init0);
902f5d27e6SReiji Watanabe 	kvm_vm_free(vm);
91376851f8SSean Christopherson 	init1 = init0;
922f5d27e6SReiji Watanabe 
932f5d27e6SReiji Watanabe 	/* Test with 64bit vCPUs */
94376851f8SSean Christopherson 	ret = add_init_2vcpus(&init0, &init0);
952f5d27e6SReiji Watanabe 	TEST_ASSERT(ret == 0,
962f5d27e6SReiji Watanabe 		    "Configuring 64bit EL1 vCPUs failed unexpectedly");
97376851f8SSean Christopherson 	ret = add_2vcpus_init_2vcpus(&init0, &init0);
982f5d27e6SReiji Watanabe 	TEST_ASSERT(ret == 0,
992f5d27e6SReiji Watanabe 		    "Configuring 64bit EL1 vCPUs failed unexpectedly");
1002f5d27e6SReiji Watanabe 
1012f5d27e6SReiji Watanabe 	/* Test with 32bit vCPUs */
102376851f8SSean Christopherson 	init0.features[0] = (1 << KVM_ARM_VCPU_EL1_32BIT);
103376851f8SSean Christopherson 	ret = add_init_2vcpus(&init0, &init0);
1042f5d27e6SReiji Watanabe 	TEST_ASSERT(ret == 0,
1052f5d27e6SReiji Watanabe 		    "Configuring 32bit EL1 vCPUs failed unexpectedly");
106376851f8SSean Christopherson 	ret = add_2vcpus_init_2vcpus(&init0, &init0);
1072f5d27e6SReiji Watanabe 	TEST_ASSERT(ret == 0,
1082f5d27e6SReiji Watanabe 		    "Configuring 32bit EL1 vCPUs failed unexpectedly");
1092f5d27e6SReiji Watanabe 
1102f5d27e6SReiji Watanabe 	/* Test with mixed-width vCPUs  */
111376851f8SSean Christopherson 	init0.features[0] = 0;
112376851f8SSean Christopherson 	init1.features[0] = (1 << KVM_ARM_VCPU_EL1_32BIT);
113376851f8SSean Christopherson 	ret = add_init_2vcpus(&init0, &init1);
1142f5d27e6SReiji Watanabe 	TEST_ASSERT(ret != 0,
1152f5d27e6SReiji Watanabe 		    "Configuring mixed-width vCPUs worked unexpectedly");
116376851f8SSean Christopherson 	ret = add_2vcpus_init_2vcpus(&init0, &init1);
1172f5d27e6SReiji Watanabe 	TEST_ASSERT(ret != 0,
1182f5d27e6SReiji Watanabe 		    "Configuring mixed-width vCPUs worked unexpectedly");
1192f5d27e6SReiji Watanabe 
1202f5d27e6SReiji Watanabe 	return 0;
1212f5d27e6SReiji Watanabe }
122