1*67730e6cSSean Christopherson // SPDX-License-Identifier: GPL-2.0-only 2*67730e6cSSean Christopherson /* 3*67730e6cSSean Christopherson * vcpu_width_config - Test KVM_ARM_VCPU_INIT() with KVM_ARM_VCPU_EL1_32BIT. 4*67730e6cSSean Christopherson * 5*67730e6cSSean Christopherson * Copyright (c) 2022 Google LLC. 6*67730e6cSSean Christopherson * 7*67730e6cSSean Christopherson * This is a test that ensures that non-mixed-width vCPUs (all 64bit vCPUs 8*67730e6cSSean Christopherson * or all 32bit vcPUs) can be configured and mixed-width vCPUs cannot be 9*67730e6cSSean Christopherson * configured. 10*67730e6cSSean Christopherson */ 11*67730e6cSSean Christopherson 12*67730e6cSSean Christopherson #include "kvm_util.h" 13*67730e6cSSean Christopherson #include "processor.h" 14*67730e6cSSean Christopherson #include "test_util.h" 15*67730e6cSSean Christopherson 16*67730e6cSSean Christopherson 17*67730e6cSSean Christopherson /* 18*67730e6cSSean Christopherson * Add a vCPU, run KVM_ARM_VCPU_INIT with @init0, and then 19*67730e6cSSean Christopherson * add another vCPU, and run KVM_ARM_VCPU_INIT with @init1. 20*67730e6cSSean Christopherson */ 21*67730e6cSSean Christopherson static int add_init_2vcpus(struct kvm_vcpu_init *init0, 22*67730e6cSSean Christopherson struct kvm_vcpu_init *init1) 23*67730e6cSSean Christopherson { 24*67730e6cSSean Christopherson struct kvm_vcpu *vcpu0, *vcpu1; 25*67730e6cSSean Christopherson struct kvm_vm *vm; 26*67730e6cSSean Christopherson int ret; 27*67730e6cSSean Christopherson 28*67730e6cSSean Christopherson vm = vm_create_barebones(); 29*67730e6cSSean Christopherson 30*67730e6cSSean Christopherson vcpu0 = __vm_vcpu_add(vm, 0); 31*67730e6cSSean Christopherson ret = __vcpu_ioctl(vcpu0, KVM_ARM_VCPU_INIT, init0); 32*67730e6cSSean Christopherson if (ret) 33*67730e6cSSean Christopherson goto free_exit; 34*67730e6cSSean Christopherson 35*67730e6cSSean Christopherson vcpu1 = __vm_vcpu_add(vm, 1); 36*67730e6cSSean Christopherson ret = __vcpu_ioctl(vcpu1, KVM_ARM_VCPU_INIT, init1); 37*67730e6cSSean Christopherson 38*67730e6cSSean Christopherson free_exit: 39*67730e6cSSean Christopherson kvm_vm_free(vm); 40*67730e6cSSean Christopherson return ret; 41*67730e6cSSean Christopherson } 42*67730e6cSSean Christopherson 43*67730e6cSSean Christopherson /* 44*67730e6cSSean Christopherson * Add two vCPUs, then run KVM_ARM_VCPU_INIT for one vCPU with @init0, 45*67730e6cSSean Christopherson * and run KVM_ARM_VCPU_INIT for another vCPU with @init1. 46*67730e6cSSean Christopherson */ 47*67730e6cSSean Christopherson static int add_2vcpus_init_2vcpus(struct kvm_vcpu_init *init0, 48*67730e6cSSean Christopherson struct kvm_vcpu_init *init1) 49*67730e6cSSean Christopherson { 50*67730e6cSSean Christopherson struct kvm_vcpu *vcpu0, *vcpu1; 51*67730e6cSSean Christopherson struct kvm_vm *vm; 52*67730e6cSSean Christopherson int ret; 53*67730e6cSSean Christopherson 54*67730e6cSSean Christopherson vm = vm_create_barebones(); 55*67730e6cSSean Christopherson 56*67730e6cSSean Christopherson vcpu0 = __vm_vcpu_add(vm, 0); 57*67730e6cSSean Christopherson vcpu1 = __vm_vcpu_add(vm, 1); 58*67730e6cSSean Christopherson 59*67730e6cSSean Christopherson ret = __vcpu_ioctl(vcpu0, KVM_ARM_VCPU_INIT, init0); 60*67730e6cSSean Christopherson if (ret) 61*67730e6cSSean Christopherson goto free_exit; 62*67730e6cSSean Christopherson 63*67730e6cSSean Christopherson ret = __vcpu_ioctl(vcpu1, KVM_ARM_VCPU_INIT, init1); 64*67730e6cSSean Christopherson 65*67730e6cSSean Christopherson free_exit: 66*67730e6cSSean Christopherson kvm_vm_free(vm); 67*67730e6cSSean Christopherson return ret; 68*67730e6cSSean Christopherson } 69*67730e6cSSean Christopherson 70*67730e6cSSean Christopherson /* 71*67730e6cSSean Christopherson * Tests that two 64bit vCPUs can be configured, two 32bit vCPUs can be 72*67730e6cSSean Christopherson * configured, and two mixed-width vCPUs cannot be configured. 73*67730e6cSSean Christopherson * Each of those three cases, configure vCPUs in two different orders. 74*67730e6cSSean Christopherson * The one is running KVM_CREATE_VCPU for 2 vCPUs, and then running 75*67730e6cSSean Christopherson * KVM_ARM_VCPU_INIT for them. 76*67730e6cSSean Christopherson * The other is running KVM_CREATE_VCPU and KVM_ARM_VCPU_INIT for a vCPU, 77*67730e6cSSean Christopherson * and then run those commands for another vCPU. 78*67730e6cSSean Christopherson */ 79*67730e6cSSean Christopherson int main(void) 80*67730e6cSSean Christopherson { 81*67730e6cSSean Christopherson struct kvm_vcpu_init init0, init1; 82*67730e6cSSean Christopherson struct kvm_vm *vm; 83*67730e6cSSean Christopherson int ret; 84*67730e6cSSean Christopherson 85*67730e6cSSean Christopherson TEST_REQUIRE(kvm_has_cap(KVM_CAP_ARM_EL1_32BIT)); 86*67730e6cSSean Christopherson 87*67730e6cSSean Christopherson /* Get the preferred target type and copy that to init1 for later use */ 88*67730e6cSSean Christopherson vm = vm_create_barebones(); 89*67730e6cSSean Christopherson vm_ioctl(vm, KVM_ARM_PREFERRED_TARGET, &init0); 90*67730e6cSSean Christopherson kvm_vm_free(vm); 91*67730e6cSSean Christopherson init1 = init0; 92*67730e6cSSean Christopherson 93*67730e6cSSean Christopherson /* Test with 64bit vCPUs */ 94*67730e6cSSean Christopherson ret = add_init_2vcpus(&init0, &init0); 95*67730e6cSSean Christopherson TEST_ASSERT(ret == 0, 96*67730e6cSSean Christopherson "Configuring 64bit EL1 vCPUs failed unexpectedly"); 97*67730e6cSSean Christopherson ret = add_2vcpus_init_2vcpus(&init0, &init0); 98*67730e6cSSean Christopherson TEST_ASSERT(ret == 0, 99*67730e6cSSean Christopherson "Configuring 64bit EL1 vCPUs failed unexpectedly"); 100*67730e6cSSean Christopherson 101*67730e6cSSean Christopherson /* Test with 32bit vCPUs */ 102*67730e6cSSean Christopherson init0.features[0] = (1 << KVM_ARM_VCPU_EL1_32BIT); 103*67730e6cSSean Christopherson ret = add_init_2vcpus(&init0, &init0); 104*67730e6cSSean Christopherson TEST_ASSERT(ret == 0, 105*67730e6cSSean Christopherson "Configuring 32bit EL1 vCPUs failed unexpectedly"); 106*67730e6cSSean Christopherson ret = add_2vcpus_init_2vcpus(&init0, &init0); 107*67730e6cSSean Christopherson TEST_ASSERT(ret == 0, 108*67730e6cSSean Christopherson "Configuring 32bit EL1 vCPUs failed unexpectedly"); 109*67730e6cSSean Christopherson 110*67730e6cSSean Christopherson /* Test with mixed-width vCPUs */ 111*67730e6cSSean Christopherson init0.features[0] = 0; 112*67730e6cSSean Christopherson init1.features[0] = (1 << KVM_ARM_VCPU_EL1_32BIT); 113*67730e6cSSean Christopherson ret = add_init_2vcpus(&init0, &init1); 114*67730e6cSSean Christopherson TEST_ASSERT(ret != 0, 115*67730e6cSSean Christopherson "Configuring mixed-width vCPUs worked unexpectedly"); 116*67730e6cSSean Christopherson ret = add_2vcpus_init_2vcpus(&init0, &init1); 117*67730e6cSSean Christopherson TEST_ASSERT(ret != 0, 118*67730e6cSSean Christopherson "Configuring mixed-width vCPUs worked unexpectedly"); 119*67730e6cSSean Christopherson 120*67730e6cSSean Christopherson return 0; 121*67730e6cSSean Christopherson } 122