Path: blob/master/tools/testing/selftests/kvm/arm64/vcpu_width_config.c
38237 views
// SPDX-License-Identifier: GPL-2.0-only1/*2* vcpu_width_config - Test KVM_ARM_VCPU_INIT() with KVM_ARM_VCPU_EL1_32BIT.3*4* Copyright (c) 2022 Google LLC.5*6* This is a test that ensures that non-mixed-width vCPUs (all 64bit vCPUs7* or all 32bit vcPUs) can be configured and mixed-width vCPUs cannot be8* configured.9*/1011#include "kvm_util.h"12#include "processor.h"13#include "test_util.h"141516/*17* Add a vCPU, run KVM_ARM_VCPU_INIT with @init0, and then18* add another vCPU, and run KVM_ARM_VCPU_INIT with @init1.19*/20static int add_init_2vcpus(struct kvm_vcpu_init *init0,21struct kvm_vcpu_init *init1)22{23struct kvm_vcpu *vcpu0, *vcpu1;24struct kvm_vm *vm;25int ret;2627vm = vm_create_barebones();2829vcpu0 = __vm_vcpu_add(vm, 0);30ret = __vcpu_ioctl(vcpu0, KVM_ARM_VCPU_INIT, init0);31if (ret)32goto free_exit;3334vcpu1 = __vm_vcpu_add(vm, 1);35ret = __vcpu_ioctl(vcpu1, KVM_ARM_VCPU_INIT, init1);3637free_exit:38kvm_vm_free(vm);39return ret;40}4142/*43* Add two vCPUs, then run KVM_ARM_VCPU_INIT for one vCPU with @init0,44* and run KVM_ARM_VCPU_INIT for another vCPU with @init1.45*/46static int add_2vcpus_init_2vcpus(struct kvm_vcpu_init *init0,47struct kvm_vcpu_init *init1)48{49struct kvm_vcpu *vcpu0, *vcpu1;50struct kvm_vm *vm;51int ret;5253vm = vm_create_barebones();5455vcpu0 = __vm_vcpu_add(vm, 0);56vcpu1 = __vm_vcpu_add(vm, 1);5758ret = __vcpu_ioctl(vcpu0, KVM_ARM_VCPU_INIT, init0);59if (ret)60goto free_exit;6162ret = __vcpu_ioctl(vcpu1, KVM_ARM_VCPU_INIT, init1);6364free_exit:65kvm_vm_free(vm);66return ret;67}6869/*70* Tests that two 64bit vCPUs can be configured, two 32bit vCPUs can be71* configured, and two mixed-width vCPUs cannot be configured.72* Each of those three cases, configure vCPUs in two different orders.73* The one is running KVM_CREATE_VCPU for 2 vCPUs, and then running74* KVM_ARM_VCPU_INIT for them.75* The other is running KVM_CREATE_VCPU and KVM_ARM_VCPU_INIT for a vCPU,76* and then run those commands for another vCPU.77*/78int main(void)79{80struct kvm_vcpu_init init0, init1;81struct kvm_vm *vm;82int ret;8384TEST_REQUIRE(kvm_has_cap(KVM_CAP_ARM_EL1_32BIT));8586/* Get the preferred target type and copy that to init1 for later use */87vm = vm_create_barebones();88vm_ioctl(vm, KVM_ARM_PREFERRED_TARGET, &init0);89kvm_vm_free(vm);90init1 = init0;9192/* Test with 64bit vCPUs */93ret = add_init_2vcpus(&init0, &init0);94TEST_ASSERT(ret == 0,95"Configuring 64bit EL1 vCPUs failed unexpectedly");96ret = add_2vcpus_init_2vcpus(&init0, &init0);97TEST_ASSERT(ret == 0,98"Configuring 64bit EL1 vCPUs failed unexpectedly");99100/* Test with 32bit vCPUs */101init0.features[0] = (1 << KVM_ARM_VCPU_EL1_32BIT);102ret = add_init_2vcpus(&init0, &init0);103TEST_ASSERT(ret == 0,104"Configuring 32bit EL1 vCPUs failed unexpectedly");105ret = add_2vcpus_init_2vcpus(&init0, &init0);106TEST_ASSERT(ret == 0,107"Configuring 32bit EL1 vCPUs failed unexpectedly");108109/* Test with mixed-width vCPUs */110init0.features[0] = 0;111init1.features[0] = (1 << KVM_ARM_VCPU_EL1_32BIT);112ret = add_init_2vcpus(&init0, &init1);113TEST_ASSERT(ret != 0,114"Configuring mixed-width vCPUs worked unexpectedly");115ret = add_2vcpus_init_2vcpus(&init0, &init1);116TEST_ASSERT(ret != 0,117"Configuring mixed-width vCPUs worked unexpectedly");118119return 0;120}121122123