Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * vcpu_width_config - Test KVM_ARM_VCPU_INIT() with KVM_ARM_VCPU_EL1_32BIT.
0004  *
0005  * Copyright (c) 2022 Google LLC.
0006  *
0007  * This is a test that ensures that non-mixed-width vCPUs (all 64bit vCPUs
0008  * or all 32bit vcPUs) can be configured and mixed-width vCPUs cannot be
0009  * configured.
0010  */
0011 
0012 #include "kvm_util.h"
0013 #include "processor.h"
0014 #include "test_util.h"
0015 
0016 
0017 /*
0018  * Add a vCPU, run KVM_ARM_VCPU_INIT with @init0, and then
0019  * add another vCPU, and run KVM_ARM_VCPU_INIT with @init1.
0020  */
0021 static int add_init_2vcpus(struct kvm_vcpu_init *init0,
0022                struct kvm_vcpu_init *init1)
0023 {
0024     struct kvm_vcpu *vcpu0, *vcpu1;
0025     struct kvm_vm *vm;
0026     int ret;
0027 
0028     vm = vm_create_barebones();
0029 
0030     vcpu0 = __vm_vcpu_add(vm, 0);
0031     ret = __vcpu_ioctl(vcpu0, KVM_ARM_VCPU_INIT, init0);
0032     if (ret)
0033         goto free_exit;
0034 
0035     vcpu1 = __vm_vcpu_add(vm, 1);
0036     ret = __vcpu_ioctl(vcpu1, KVM_ARM_VCPU_INIT, init1);
0037 
0038 free_exit:
0039     kvm_vm_free(vm);
0040     return ret;
0041 }
0042 
0043 /*
0044  * Add two vCPUs, then run KVM_ARM_VCPU_INIT for one vCPU with @init0,
0045  * and run KVM_ARM_VCPU_INIT for another vCPU with @init1.
0046  */
0047 static int add_2vcpus_init_2vcpus(struct kvm_vcpu_init *init0,
0048                   struct kvm_vcpu_init *init1)
0049 {
0050     struct kvm_vcpu *vcpu0, *vcpu1;
0051     struct kvm_vm *vm;
0052     int ret;
0053 
0054     vm = vm_create_barebones();
0055 
0056     vcpu0 = __vm_vcpu_add(vm, 0);
0057     vcpu1 = __vm_vcpu_add(vm, 1);
0058 
0059     ret = __vcpu_ioctl(vcpu0, KVM_ARM_VCPU_INIT, init0);
0060     if (ret)
0061         goto free_exit;
0062 
0063     ret = __vcpu_ioctl(vcpu1, KVM_ARM_VCPU_INIT, init1);
0064 
0065 free_exit:
0066     kvm_vm_free(vm);
0067     return ret;
0068 }
0069 
0070 /*
0071  * Tests that two 64bit vCPUs can be configured, two 32bit vCPUs can be
0072  * configured, and two mixed-width vCPUs cannot be configured.
0073  * Each of those three cases, configure vCPUs in two different orders.
0074  * The one is running KVM_CREATE_VCPU for 2 vCPUs, and then running
0075  * KVM_ARM_VCPU_INIT for them.
0076  * The other is running KVM_CREATE_VCPU and KVM_ARM_VCPU_INIT for a vCPU,
0077  * and then run those commands for another vCPU.
0078  */
0079 int main(void)
0080 {
0081     struct kvm_vcpu_init init0, init1;
0082     struct kvm_vm *vm;
0083     int ret;
0084 
0085     TEST_REQUIRE(kvm_has_cap(KVM_CAP_ARM_EL1_32BIT));
0086 
0087     /* Get the preferred target type and copy that to init1 for later use */
0088     vm = vm_create_barebones();
0089     vm_ioctl(vm, KVM_ARM_PREFERRED_TARGET, &init0);
0090     kvm_vm_free(vm);
0091     init1 = init0;
0092 
0093     /* Test with 64bit vCPUs */
0094     ret = add_init_2vcpus(&init0, &init0);
0095     TEST_ASSERT(ret == 0,
0096             "Configuring 64bit EL1 vCPUs failed unexpectedly");
0097     ret = add_2vcpus_init_2vcpus(&init0, &init0);
0098     TEST_ASSERT(ret == 0,
0099             "Configuring 64bit EL1 vCPUs failed unexpectedly");
0100 
0101     /* Test with 32bit vCPUs */
0102     init0.features[0] = (1 << KVM_ARM_VCPU_EL1_32BIT);
0103     ret = add_init_2vcpus(&init0, &init0);
0104     TEST_ASSERT(ret == 0,
0105             "Configuring 32bit EL1 vCPUs failed unexpectedly");
0106     ret = add_2vcpus_init_2vcpus(&init0, &init0);
0107     TEST_ASSERT(ret == 0,
0108             "Configuring 32bit EL1 vCPUs failed unexpectedly");
0109 
0110     /* Test with mixed-width vCPUs  */
0111     init0.features[0] = 0;
0112     init1.features[0] = (1 << KVM_ARM_VCPU_EL1_32BIT);
0113     ret = add_init_2vcpus(&init0, &init1);
0114     TEST_ASSERT(ret != 0,
0115             "Configuring mixed-width vCPUs worked unexpectedly");
0116     ret = add_2vcpus_init_2vcpus(&init0, &init1);
0117     TEST_ASSERT(ret != 0,
0118             "Configuring mixed-width vCPUs worked unexpectedly");
0119 
0120     return 0;
0121 }