Add a regression test that runs one vCPU and then tries to change the
VM-scoped PMU counter count through an idle sibling. Verify that
SET_NR_COUNTERS fails with EBUSY once any vCPU has run.

Assisted-by: Codex:gpt-5.6-sol
Signed-off-by: Akihiko Odaki <[email protected]>
---
 .../selftests/kvm/arm64/vpmu_counter_access.c      | 38 ++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/tools/testing/selftests/kvm/arm64/vpmu_counter_access.c 
b/tools/testing/selftests/kvm/arm64/vpmu_counter_access.c
index 22223395969e..3b5bb421f401 100644
--- a/tools/testing/selftests/kvm/arm64/vpmu_counter_access.c
+++ b/tools/testing/selftests/kvm/arm64/vpmu_counter_access.c
@@ -461,6 +461,11 @@ static void run_vcpu(struct kvm_vcpu *vcpu, u64 pmcr_n)
        }
 }
 
+static void guest_code_done(void)
+{
+       GUEST_DONE();
+}
+
 static void test_create_vpmu_vm_with_nr_counters(unsigned int nr_counters, 
bool expect_fail)
 {
        struct kvm_vcpu *vcpu;
@@ -622,6 +627,37 @@ static bool kvm_supports_nr_counters_attr(void)
        return supported;
 }
 
+static void test_set_nr_counters_after_vcpu_run(void)
+{
+       struct kvm_vcpu *running_vcpu, *stopped_vcpu;
+       unsigned int nr_counters = 0;
+       struct kvm_vcpu_init init;
+       struct kvm_vm *vm;
+       int ret;
+       u64 irq = 23;
+
+       vm = vm_create(2);
+       vm_ioctl(vm, KVM_ARM_PREFERRED_TARGET, &init);
+       init.features[0] |= BIT(KVM_ARM_VCPU_PMU_V3);
+       running_vcpu = aarch64_vcpu_add(vm, 0, &init, guest_code_done);
+       stopped_vcpu = aarch64_vcpu_add(vm, 1, &init, guest_code_done);
+       kvm_arch_vm_finalize_vcpus(vm);
+
+       vcpu_device_attr_set(running_vcpu, KVM_ARM_VCPU_PMU_V3_CTRL,
+                            KVM_ARM_VCPU_PMU_V3_IRQ, &irq);
+       vcpu_device_attr_set(running_vcpu, KVM_ARM_VCPU_PMU_V3_CTRL,
+                            KVM_ARM_VCPU_PMU_V3_INIT, NULL);
+       vcpu_run(running_vcpu);
+
+       ret = __vcpu_device_attr_set(stopped_vcpu, KVM_ARM_VCPU_PMU_V3_CTRL,
+                                    KVM_ARM_VCPU_PMU_V3_SET_NR_COUNTERS,
+                                    &nr_counters);
+       TEST_ASSERT(ret == -1 && errno == EBUSY,
+                   KVM_IOCTL_ERROR(KVM_SET_DEVICE_ATTR, ret));
+
+       kvm_vm_free(vm);
+}
+
 int main(void)
 {
        u64 i, pmcr_n;
@@ -630,6 +666,8 @@ int main(void)
        TEST_REQUIRE(kvm_supports_vgic_v3());
        TEST_REQUIRE(kvm_supports_nr_counters_attr());
 
+       test_set_nr_counters_after_vcpu_run();
+
        pmcr_n = get_pmcr_n_limit();
        for (i = 0; i <= pmcr_n; i++) {
                run_access_test(i);

-- 
2.55.0


Reply via email to