From: David Woodhouse Test the KVM_CAP_ARM_DISABLE_EXITS capability interface: - KVM_CHECK_EXTENSION reports KVM_ARM_DISABLE_EXITS_WFI - KVM_ENABLE_CAP succeeds with valid flags (WFI, zero) - KVM_ENABLE_CAP fails with EINVAL for unknown flags Signed-off-by: David Woodhouse --- tools/testing/selftests/kvm/Makefile.kvm | 1 + .../selftests/kvm/arm64/disable_exits.c | 48 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 tools/testing/selftests/kvm/arm64/disable_exits.c diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selftests/kvm/Makefile.kvm index 878d7cb92555..d8e7ff122445 100644 --- a/tools/testing/selftests/kvm/Makefile.kvm +++ b/tools/testing/selftests/kvm/Makefile.kvm @@ -179,6 +179,7 @@ TEST_GEN_PROGS_arm64 += arm64/vgic_irq TEST_GEN_PROGS_arm64 += arm64/vgic_lpi_stress TEST_GEN_PROGS_arm64 += arm64/vgic_group_iidr TEST_GEN_PROGS_arm64 += arm64/vgic_group_v2 +TEST_GEN_PROGS_arm64 += arm64/disable_exits TEST_GEN_PROGS_arm64 += arm64/vpmu_counter_access TEST_GEN_PROGS_arm64 += arm64/no-vgic-v3 TEST_GEN_PROGS_arm64 += arm64/idreg-idst diff --git a/tools/testing/selftests/kvm/arm64/disable_exits.c b/tools/testing/selftests/kvm/arm64/disable_exits.c new file mode 100644 index 000000000000..27fe6c9297b2 --- /dev/null +++ b/tools/testing/selftests/kvm/arm64/disable_exits.c @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * disable_exits.c - Test KVM_CAP_ARM_DISABLE_EXITS UAPI + * + * Verify that KVM_CHECK_EXTENSION reports the valid exit disable mask + * and that KVM_ENABLE_CAP accepts valid flags and rejects invalid ones. + */ +#include "test_util.h" +#include "kvm_util.h" +#include "processor.h" + +int main(int argc, char *argv[]) +{ + struct kvm_vm *vm; + int r; + + TEST_REQUIRE(kvm_has_cap(KVM_CAP_ARM_DISABLE_EXITS)); + + r = kvm_check_cap(KVM_CAP_ARM_DISABLE_EXITS); + TEST_ASSERT(r & KVM_ARM_DISABLE_EXITS_WFI, + "KVM_CHECK_EXTENSION should report WFI: got 0x%x", r); + TEST_ASSERT(r & KVM_ARM_DISABLE_EXITS_WFE, + "KVM_CHECK_EXTENSION should report WFE: got 0x%x", r); + + vm = vm_create(1); + + /* Valid: disable WFI trapping */ + vm_enable_cap(vm, KVM_CAP_ARM_DISABLE_EXITS, KVM_ARM_DISABLE_EXITS_WFI); + + /* Valid: disable WFE trapping */ + vm_enable_cap(vm, KVM_CAP_ARM_DISABLE_EXITS, KVM_ARM_DISABLE_EXITS_WFE); + + /* Valid: disable both */ + vm_enable_cap(vm, KVM_CAP_ARM_DISABLE_EXITS, + KVM_ARM_DISABLE_EXITS_WFI | KVM_ARM_DISABLE_EXITS_WFE); + + /* Valid: no exits disabled (no-op) */ + vm_enable_cap(vm, KVM_CAP_ARM_DISABLE_EXITS, 0); + + /* Invalid: unknown bit set */ + r = __vm_enable_cap(vm, KVM_CAP_ARM_DISABLE_EXITS, 1ULL << 31); + TEST_ASSERT(r == -1 && errno == EINVAL, + "Unknown flags should fail with EINVAL: got %d errno %d", + r, errno); + + kvm_vm_free(vm); + return 0; +} -- 2.51.0