From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 4ECC3CD342F for ; Mon, 4 May 2026 21:19:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Type:Cc:To:From: Subject:Message-ID:References:Mime-Version:In-Reply-To:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=A1LC20y4taYV29x8hD4zY85wXN5CKP6Npg+wcjsGL1w=; b=TdPV9d81NrxS8PfcVUI4ANpEs2 +aMmC4wh7Jrmdh2bK1RvF4TaBwd5qk8xqjgdsEDG7ki344H8puu0w61bHmzHxah/A7/eymDrM14Jn dF+efwErlek2fSbODAVlGUBaPL2r10Oq5ColfDIQrJAlSaxlElGZTUoCjXLy4rFTBzYm6ARbhfqOo tuMZQpL+MJuvOG0hjyZhtLiscVZYxa5SqKB6MF5BNc2L2IGLhtNeXLhumuB5eLngmO2cvs3LxSz8U 5xnM7kB2pVRCSoer0oV+leQQJ2jRtUFL5kcltI9M2rczVndPSlM1QJ8HLzwOryHFw8TxFafGM7aaD kuwpZHzw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) id 1wK0h0-0000000EM6D-40wc; Mon, 04 May 2026 21:19:07 +0000 Received: from desiato.infradead.org ([2001:8b0:10b:1:d65d:64ff:fe57:4e05]) by bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux)) id 1wK0gu-0000000ELve-3i8b for linux-arm-kernel@bombadil.infradead.org; Mon, 04 May 2026 21:19:01 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Content-Type:Cc:To:From:Subject: Message-ID:References:Mime-Version:In-Reply-To:Date:Sender:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description; bh=A1LC20y4taYV29x8hD4zY85wXN5CKP6Npg+wcjsGL1w=; b=MRruimlOw7GQxBqIbINftq51Bi p40ezOPi0EHxVbmtVIQtuOV6W53lSyAq2gO8V4Ag/SVEDScBpIr0cb7h7sQ6px4RqmX5qjIgmt1xZ IEH7zFHzJbdcjhZpF0jgIQ3+lJkSZq1rk9jTZ2KCYwP35VkdOW3CPHPQzdApHNeaE28szEiSaAVei spTwer9/p4LNxq6u85EMz/L7H2P4KJJ/O3TA7mB8/WQI7Ze/vmVT/PEyhNc6FTLMOTGqwwfQkIeAl Bze1oAJ3rv0WkhLlxZkfKs10PNBCYFJOkd+1Abomgom82FlZPYX5nTZjtLrqRGFoxDJGusuKkgKni RRswtm6g==; Received: from mail-oo1-xc4a.google.com ([2607:f8b0:4864:20::c4a]) by desiato.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux)) id 1wK0gq-0000000CG3p-0x77 for linux-arm-kernel@lists.infradead.org; Mon, 04 May 2026 21:18:59 +0000 Received: by mail-oo1-xc4a.google.com with SMTP id 006d021491bc7-696ae5fc653so1637798eaf.1 for ; Mon, 04 May 2026 14:18:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1777929533; x=1778534333; darn=lists.infradead.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=A1LC20y4taYV29x8hD4zY85wXN5CKP6Npg+wcjsGL1w=; b=EKzV7FAxiM8GzJ1MC4El+1CMFH+QHsWQNzhcRgykLRJmrSt5RWC4+Snck4ZzSuAkDS gUXWD2I9h9i5ERBC2bs9KK+yppMThxILgRob7qp577J6aZSjAxrf1xZLMT4XnFxBw51U 3VcNXm2UQ2bZAXRH5JT9zuSQ3voOvdYNSCKaMSxDdROTW+HAvvoWTlLAdmvIis33cGUU YN3VFGYaPCBybNerd+T0n+2+mxZe6iX1Hpx5IWhPB3H1eYUpSFkp3WjzbfHr8V7sFfbL 6OeBklxeoqAzl5BkveCLo3wWTwveF568wuFBk/SDxNS9PyilmHzx4Z9b2qJfASrcHHX5 2j6A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777929533; x=1778534333; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=A1LC20y4taYV29x8hD4zY85wXN5CKP6Npg+wcjsGL1w=; b=Vix/O89Oo4MzDIVr4qHDiH8vmJkPohPj2tYmxal62ZxV4B5SnI4j1dpK1mmynD3h6t Rk2IoAcXAG8NuDMeuGHENdYDg8B7V2Z5IYPBKsV2Tf/lGKWDr0npu7WfJq246y2VuMan Civ1ITCqjP7RpRkYbkaABFdSi5sDKmEuTVTKmYRndLsHM16ot2SiVVo2g/I+Lda6ssJK e+jDwW688elFYuPNWaVav5OhbCt0c/XmEZgl+1uAZ3UHWrZZ6diaHsl02O8QLoq2H6gY jWzeeWTR6G/8GOKCk98zZXAvGnM1uHex7eYGMOD8Mj9BXhneDLelghCrZ4O0oVr689j1 24AA== X-Forwarded-Encrypted: i=1; AFNElJ81NgexbDyNKZ/DcYWowxq7m2qDMdaXUuzFfKrD9Ghnc4J0mBIsVYLj8A7OSIl68haRa0r8DcYktK+BuNt6OKPX@lists.infradead.org X-Gm-Message-State: AOJu0YyaldrzMlgjuhUniZ4l67bb+4ohs84DRyD1gHSKgic2F0gIjM9X UyexCdQt1HVd3nAWBxzk711wdRBuJ43ccucIIX0G3Uk07SJMwvteLJGkcujBuCjGQeQe4Mkg7Km Tvq0m/8gJ6osyPk2S/FpFpWOmaA== X-Received: from ilql7.prod.google.com ([2002:a92:d947:0:b0:4fe:69b2:404b]) (user=coltonlewis job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6820:2014:b0:694:6e61:8de0 with SMTP id 006d021491bc7-6998d24837amr140937eaf.30.1777929533288; Mon, 04 May 2026 14:18:53 -0700 (PDT) Date: Mon, 4 May 2026 21:18:12 +0000 In-Reply-To: <20260504211813.1804997-1-coltonlewis@google.com> Mime-Version: 1.0 References: <20260504211813.1804997-1-coltonlewis@google.com> X-Mailer: git-send-email 2.54.0.545.g6539524ca2-goog Message-ID: <20260504211813.1804997-20-coltonlewis@google.com> Subject: [PATCH v7 19/20] KVM: arm64: selftests: Add test case for Partitioned PMU From: Colton Lewis To: kvm@vger.kernel.org Cc: Alexandru Elisei , Paolo Bonzini , Jonathan Corbet , Russell King , Catalin Marinas , Will Deacon , Marc Zyngier , Oliver Upton , Mingwei Zhang , Joey Gouly , Suzuki K Poulose , Zenghui Yu , Mark Rutland , Shuah Khan , Ganapatrao Kulkarni , James Clark , linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linux-perf-users@vger.kernel.org, linux-kselftest@vger.kernel.org, Colton Lewis Content-Type: text/plain; charset="UTF-8" X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20260504_221856_526461_34283ECB X-CRM114-Status: GOOD ( 21.83 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Rerun all tests for a Partitioned PMU in vpmu_counter_access. Create an enum specifying whether we are testing the emulated or Partitioned PMU and all the test functions are modified to take the implementation as an argument and make the difference in setup appropriately. Signed-off-by: Colton Lewis --- .../selftests/kvm/arm64/vpmu_counter_access.c | 94 ++++++++++++++----- 1 file changed, 73 insertions(+), 21 deletions(-) diff --git a/tools/testing/selftests/kvm/arm64/vpmu_counter_access.c b/tools/testing/selftests/kvm/arm64/vpmu_counter_access.c index ae36325c022fb..9702f1d43b832 100644 --- a/tools/testing/selftests/kvm/arm64/vpmu_counter_access.c +++ b/tools/testing/selftests/kvm/arm64/vpmu_counter_access.c @@ -25,9 +25,20 @@ /* The cycle counter bit position that's common among the PMU registers */ #define ARMV8_PMU_CYCLE_IDX 31 +enum pmu_impl { + EMULATED, + PARTITIONED +}; + +const char *pmu_impl_str[] = { + "Emulated", + "Partitioned" +}; + struct vpmu_vm { struct kvm_vm *vm; struct kvm_vcpu *vcpu; + bool pmu_partitioned; }; static struct vpmu_vm vpmu_vm; @@ -399,7 +410,7 @@ static void guest_code(uint64_t expected_pmcr_n) } /* Create a VM that has one vCPU with PMUv3 configured. */ -static void create_vpmu_vm(void *guest_code) +static void create_vpmu_vm(void *guest_code, enum pmu_impl impl) { struct kvm_vcpu_init init; uint8_t pmuver, ec; @@ -409,6 +420,13 @@ static void create_vpmu_vm(void *guest_code) .attr = KVM_ARM_VCPU_PMU_V3_IRQ, .addr = (uint64_t)&irq, }; + bool partition = (impl == PARTITIONED); + struct kvm_device_attr part_attr = { + .group = KVM_ARM_VCPU_PMU_V3_CTRL, + .attr = KVM_ARM_VCPU_PMU_V3_ENABLE_PARTITION, + .addr = (uint64_t)&partition + }; + int ret; /* The test creates the vpmu_vm multiple times. Ensure a clean state */ memset(&vpmu_vm, 0, sizeof(vpmu_vm)); @@ -436,6 +454,15 @@ static void create_vpmu_vm(void *guest_code) "Unexpected PMUVER (0x%x) on the vCPU with PMUv3", pmuver); vcpu_ioctl(vpmu_vm.vcpu, KVM_SET_DEVICE_ATTR, &irq_attr); + + ret = __vcpu_has_device_attr( + vpmu_vm.vcpu, KVM_ARM_VCPU_PMU_V3_CTRL, KVM_ARM_VCPU_PMU_V3_ENABLE_PARTITION); + if (!ret) { + vcpu_ioctl(vpmu_vm.vcpu, KVM_SET_DEVICE_ATTR, &part_attr); + vpmu_vm.pmu_partitioned = partition; + pr_debug("Set PMU partitioning: %d\n", partition); + } + } static void destroy_vpmu_vm(void) @@ -461,13 +488,14 @@ static void run_vcpu(struct kvm_vcpu *vcpu, uint64_t pmcr_n) } } -static void test_create_vpmu_vm_with_nr_counters(unsigned int nr_counters, bool expect_fail) +static void test_create_vpmu_vm_with_nr_counters( + unsigned int nr_counters, enum pmu_impl impl, bool expect_fail) { struct kvm_vcpu *vcpu; unsigned int prev; int ret; - create_vpmu_vm(guest_code); + create_vpmu_vm(guest_code, impl); vcpu = vpmu_vm.vcpu; prev = get_pmcr_n(vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_PMCR_EL0))); @@ -489,7 +517,7 @@ static void test_create_vpmu_vm_with_nr_counters(unsigned int nr_counters, bool * Create a guest with one vCPU, set the PMCR_EL0.N for the vCPU to @pmcr_n, * and run the test. */ -static void run_access_test(uint64_t pmcr_n) +static void run_access_test(uint64_t pmcr_n, enum pmu_impl impl) { uint64_t sp; struct kvm_vcpu *vcpu; @@ -497,7 +525,7 @@ static void run_access_test(uint64_t pmcr_n) pr_debug("Test with pmcr_n %lu\n", pmcr_n); - test_create_vpmu_vm_with_nr_counters(pmcr_n, false); + test_create_vpmu_vm_with_nr_counters(pmcr_n, impl, false); vcpu = vpmu_vm.vcpu; /* Save the initial sp to restore them later to run the guest again */ @@ -531,14 +559,14 @@ static struct pmreg_sets validity_check_reg_sets[] = { * Create a VM, and check if KVM handles the userspace accesses of * the PMU register sets in @validity_check_reg_sets[] correctly. */ -static void run_pmregs_validity_test(uint64_t pmcr_n) +static void run_pmregs_validity_test(uint64_t pmcr_n, enum pmu_impl impl) { int i; struct kvm_vcpu *vcpu; uint64_t set_reg_id, clr_reg_id, reg_val; uint64_t valid_counters_mask, max_counters_mask; - test_create_vpmu_vm_with_nr_counters(pmcr_n, false); + test_create_vpmu_vm_with_nr_counters(pmcr_n, impl, false); vcpu = vpmu_vm.vcpu; valid_counters_mask = get_counters_mask(pmcr_n); @@ -588,11 +616,11 @@ static void run_pmregs_validity_test(uint64_t pmcr_n) * the vCPU to @pmcr_n, which is larger than the host value. * The attempt should fail as @pmcr_n is too big to set for the vCPU. */ -static void run_error_test(uint64_t pmcr_n) +static void run_error_test(uint64_t pmcr_n, enum pmu_impl impl) { - pr_debug("Error test with pmcr_n %lu (larger than the host)\n", pmcr_n); + pr_debug("Error test with pmcr_n %lu (larger than the host allows)\n", pmcr_n); - test_create_vpmu_vm_with_nr_counters(pmcr_n, true); + test_create_vpmu_vm_with_nr_counters(pmcr_n, impl, true); destroy_vpmu_vm(); } @@ -600,11 +628,11 @@ static void run_error_test(uint64_t pmcr_n) * Return the default number of implemented PMU event counters excluding * the cycle counter (i.e. PMCR_EL0.N value) for the guest. */ -static uint64_t get_pmcr_n_limit(void) +static uint64_t get_pmcr_n_limit(enum pmu_impl impl) { uint64_t pmcr; - create_vpmu_vm(guest_code); + create_vpmu_vm(guest_code, impl); pmcr = vcpu_get_reg(vpmu_vm.vcpu, KVM_ARM64_SYS_REG(SYS_PMCR_EL0)); destroy_vpmu_vm(); return get_pmcr_n(pmcr); @@ -614,7 +642,7 @@ static bool kvm_supports_nr_counters_attr(void) { bool supported; - create_vpmu_vm(NULL); + create_vpmu_vm(NULL, EMULATED); supported = !__vcpu_has_device_attr(vpmu_vm.vcpu, KVM_ARM_VCPU_PMU_V3_CTRL, KVM_ARM_VCPU_PMU_V3_SET_NR_COUNTERS); destroy_vpmu_vm(); @@ -622,22 +650,46 @@ static bool kvm_supports_nr_counters_attr(void) return supported; } -int main(void) +static bool kvm_supports_partition_attr(void) +{ + bool supported; + + create_vpmu_vm(NULL, EMULATED); + supported = !__vcpu_has_device_attr(vpmu_vm.vcpu, KVM_ARM_VCPU_PMU_V3_CTRL, + KVM_ARM_VCPU_PMU_V3_ENABLE_PARTITION); + destroy_vpmu_vm(); + + return supported; +} + +void test_pmu(enum pmu_impl impl) { uint64_t i, pmcr_n; - TEST_REQUIRE(kvm_has_cap(KVM_CAP_ARM_PMU_V3)); - TEST_REQUIRE(kvm_supports_vgic_v3()); - TEST_REQUIRE(kvm_supports_nr_counters_attr()); + pr_info("Testing PMU: Implementation = %s\n", pmu_impl_str[impl]); + + pmcr_n = get_pmcr_n_limit(impl); + pr_debug("PMCR_EL0.N: Limit = %lu\n", pmcr_n); - pmcr_n = get_pmcr_n_limit(); for (i = 0; i <= pmcr_n; i++) { - run_access_test(i); - run_pmregs_validity_test(i); + run_access_test(i, impl); + run_pmregs_validity_test(i, impl); } for (i = pmcr_n + 1; i < ARMV8_PMU_MAX_COUNTERS; i++) - run_error_test(i); + run_error_test(i, impl); +} + +int main(void) +{ + TEST_REQUIRE(kvm_has_cap(KVM_CAP_ARM_PMU_V3)); + TEST_REQUIRE(kvm_supports_vgic_v3()); + TEST_REQUIRE(kvm_supports_nr_counters_attr()); + + test_pmu(EMULATED); + + if (kvm_supports_partition_attr()) + test_pmu(PARTITIONED); return 0; } -- 2.54.0.545.g6539524ca2-goog