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