From nobody Wed Dec 31 05:05:48 2025 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6CD0BC4332F for ; Wed, 8 Nov 2023 00:32:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232584AbjKHAcN (ORCPT ); Tue, 7 Nov 2023 19:32:13 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47318 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235566AbjKHAb4 (ORCPT ); Tue, 7 Nov 2023 19:31:56 -0500 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B50C7170F for ; Tue, 7 Nov 2023 16:31:53 -0800 (PST) Received: by mail-yb1-xb49.google.com with SMTP id 3f1490d57ef6-d9a5a3f2d4fso7256004276.3 for ; Tue, 07 Nov 2023 16:31:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1699403513; x=1700008313; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=M4yIuLWtUhd20HNDbIbdJZg/15m7GuOnQW/l0bWB/Yg=; b=TQNj32ibUGvqOlULKYklb2l45iGtZbUtdmt9uwG3qyh5cTxOQauZFKnbZRM8H3ar2H wbqfaArK/cWVYjPBX4QG7qtmtNBm+/XXpMZlo27i6L7OyyM/HgLnHX6fXR7z/jJ5tsOU dgueE06HAIivwAbnhePCuHW/M9TbS8JDjoWf2kyW6BFf/BZwdiL3+0NHc2I0hYSvyF0e IOmjY8NfBtCuSjJd/HtitMHlqEXZSItjaAma4Nr3cwXizkfT957c/lg2u+EmOaiWctRk eP+3RkhAe5D68QFXUpNjAER7RpIKHwoXx2cFasZxWznDy+3jswZVbc3XBxwvJWiUR8Az v3HA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1699403513; x=1700008313; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=M4yIuLWtUhd20HNDbIbdJZg/15m7GuOnQW/l0bWB/Yg=; b=cU+qZSijG/ho1hAdzEJJzqtknRIJr2FcqaKoVbmI2gfYAPWb54elvqHw3PpzuOOP75 Ra8Fnp2uxu9sfgtPMig9onHprJ0UYM2hg3dxrN66JlDNYYMUtiaj0oxARaJ3JhCGisck EVb9xSYTsxEiIiZiC0bwe7eNOtr7Bvil662j0w50z6r2nu8JdFyGgLqGC8ke5u3TBXJk VMgrGhncDmbTuLi83ChdbEIgk20rg947bI69XJ2FY7VvkuubgMx1Ue4iHYPbBcwespMQ LkWoXoxZuD3uMT48tXwV+TFRI0cDPqiMO43cv0a25aprCmbPukd9a2jj/wTbd3/2GPC6 yq7Q== X-Gm-Message-State: AOJu0YyBQXqah5FVVH7Hz1JGLtJGWQzkKG7WKu7IVT+CigmCdQqvG7vf Uizry3q9vPhZLYxjJt6TJwupvbkF8HU= X-Google-Smtp-Source: AGHT+IHsCY6ukPLMgBIpgrZV4IP7VOUx73LJtwvx6GOvx1AOW9j3qL7P05yYFoSxtVF8CAuUJn46hapPNlQ= X-Received: from zagreus.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:5c37]) (user=seanjc job=sendgmr) by 2002:a25:e64a:0:b0:da0:29ba:668c with SMTP id d71-20020a25e64a000000b00da029ba668cmr5699ybh.10.1699403512902; Tue, 07 Nov 2023 16:31:52 -0800 (PST) Reply-To: Sean Christopherson Date: Tue, 7 Nov 2023 16:31:23 -0800 In-Reply-To: <20231108003135.546002-1-seanjc@google.com> Mime-Version: 1.0 References: <20231108003135.546002-1-seanjc@google.com> X-Mailer: git-send-email 2.42.0.869.gea05f2083d-goog Message-ID: <20231108003135.546002-8-seanjc@google.com> Subject: [PATCH v7 07/19] KVM: selftests: Extend {kvm,this}_pmu_has() to support fixed counters From: Sean Christopherson To: Sean Christopherson , Paolo Bonzini Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Kan Liang , Dapeng Mi , Jim Mattson , Jinrong Liang , Aaron Lewis , Like Xu Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Extend the kvm_x86_pmu_feature framework to allow querying for fixed counters via {kvm,this}_pmu_has(). Like architectural events, checking for a fixed counter annoyingly requires checking multiple CPUID fields, as a fixed counter exists if: FxCtr[i]_is_supported :=3D ECX[i] || (EDX[4:0] > i); Note, KVM currently doesn't actually support exposing fixed counters via the bitmask, but that will hopefully change sooner than later, and Intel's SDM explicitly "recommends" checking both the number of counters and the mask. Rename the intermedate "anti_feature" field to simply 'f' since the fixed counter bitmask (thankfully) doesn't have reversed polarity like the architectural events bitmask. Note, ideally the helpers would use BUILD_BUG_ON() to assert on the incoming register, but the expected usage in PMU tests can't guarantee the inputs are compile-time constants. Opportunistically define macros for all of the known architectural events and fixed counters. Signed-off-by: Sean Christopherson --- .../selftests/kvm/include/x86_64/processor.h | 65 ++++++++++++++----- 1 file changed, 47 insertions(+), 18 deletions(-) diff --git a/tools/testing/selftests/kvm/include/x86_64/processor.h b/tools= /testing/selftests/kvm/include/x86_64/processor.h index 2d9771151dd9..64aecb3dcf60 100644 --- a/tools/testing/selftests/kvm/include/x86_64/processor.h +++ b/tools/testing/selftests/kvm/include/x86_64/processor.h @@ -281,24 +281,41 @@ struct kvm_x86_cpu_property { * that indicates the feature is _not_ supported, and a property that stat= es * the length of the bit mask of unsupported features. A feature is suppo= rted * if the size of the bit mask is larger than the "unavailable" bit, and s= aid - * bit is not set. + * bit is not set. Fixed counters also bizarre enumeration, but inverted = from + * arch events for general purpose counters. Fixed counters are supported= if a + * feature flag is set **OR** the total number of fixed counters is greater + * than index of the counter. * - * Wrap the "unavailable" feature to simplify checking whether or not a gi= ven - * architectural event is supported. + * Wrap the events for general purpose and fixed counters to simplify chec= king + * whether or not a given architectural event is supported. */ struct kvm_x86_pmu_feature { - struct kvm_x86_cpu_feature anti_feature; + struct kvm_x86_cpu_feature f; }; -#define KVM_X86_PMU_FEATURE(__bit) \ -({ \ - struct kvm_x86_pmu_feature feature =3D { \ - .anti_feature =3D KVM_X86_CPU_FEATURE(0xa, 0, EBX, __bit), \ - }; \ - \ - feature; \ +#define KVM_X86_PMU_FEATURE(__reg, __bit) \ +({ \ + struct kvm_x86_pmu_feature feature =3D { \ + .f =3D KVM_X86_CPU_FEATURE(0xa, 0, __reg, __bit), \ + }; \ + \ + kvm_static_assert(KVM_CPUID_##__reg =3D=3D KVM_CPUID_EBX || \ + KVM_CPUID_##__reg =3D=3D KVM_CPUID_ECX); \ + feature; \ }) =20 -#define X86_PMU_FEATURE_BRANCH_INSNS_RETIRED KVM_X86_PMU_FEATURE(5) +#define X86_PMU_FEATURE_CPU_CYCLES KVM_X86_PMU_FEATURE(EBX, 0) +#define X86_PMU_FEATURE_INSNS_RETIRED KVM_X86_PMU_FEATURE(EBX, 1) +#define X86_PMU_FEATURE_REFERENCE_CYCLES KVM_X86_PMU_FEATURE(EBX, 2) +#define X86_PMU_FEATURE_LLC_REFERENCES KVM_X86_PMU_FEATURE(EBX, 3) +#define X86_PMU_FEATURE_LLC_MISSES KVM_X86_PMU_FEATURE(EBX, 4) +#define X86_PMU_FEATURE_BRANCH_INSNS_RETIRED KVM_X86_PMU_FEATURE(EBX, 5) +#define X86_PMU_FEATURE_BRANCHES_MISPREDICTED KVM_X86_PMU_FEATURE(EBX, 6) +#define X86_PMU_FEATURE_TOPDOWN_SLOTS KVM_X86_PMU_FEATURE(EBX, 7) + +#define X86_PMU_FEATURE_INSNS_RETIRED_FIXED KVM_X86_PMU_FEATURE(ECX, 0) +#define X86_PMU_FEATURE_CPU_CYCLES_FIXED KVM_X86_PMU_FEATURE(ECX, 1) +#define X86_PMU_FEATURE_REFERENCE_TSC_CYCLES_FIXED KVM_X86_PMU_FEATURE(ECX= , 2) +#define X86_PMU_FEATURE_TOPDOWN_SLOTS_FIXED KVM_X86_PMU_FEATURE(ECX, 3) =20 static inline unsigned int x86_family(unsigned int eax) { @@ -697,10 +714,16 @@ static __always_inline bool this_cpu_has_p(struct kvm= _x86_cpu_property property) =20 static inline bool this_pmu_has(struct kvm_x86_pmu_feature feature) { - uint32_t nr_bits =3D this_cpu_property(X86_PROPERTY_PMU_EBX_BIT_VECTOR_LE= NGTH); + uint32_t nr_bits; =20 - return nr_bits > feature.anti_feature.bit && - !this_cpu_has(feature.anti_feature); + if (feature.f.reg =3D=3D KVM_CPUID_EBX) { + nr_bits =3D this_cpu_property(X86_PROPERTY_PMU_EBX_BIT_VECTOR_LENGTH); + return nr_bits > feature.f.bit && !this_cpu_has(feature.f); + } + + GUEST_ASSERT(feature.f.reg =3D=3D KVM_CPUID_ECX); + nr_bits =3D this_cpu_property(X86_PROPERTY_PMU_NR_FIXED_COUNTERS); + return nr_bits > feature.f.bit || this_cpu_has(feature.f); } =20 static __always_inline uint64_t this_cpu_supported_xcr0(void) @@ -916,10 +939,16 @@ static __always_inline bool kvm_cpu_has_p(struct kvm_= x86_cpu_property property) =20 static inline bool kvm_pmu_has(struct kvm_x86_pmu_feature feature) { - uint32_t nr_bits =3D kvm_cpu_property(X86_PROPERTY_PMU_EBX_BIT_VECTOR_LEN= GTH); + uint32_t nr_bits; =20 - return nr_bits > feature.anti_feature.bit && - !kvm_cpu_has(feature.anti_feature); + if (feature.f.reg =3D=3D KVM_CPUID_EBX) { + nr_bits =3D kvm_cpu_property(X86_PROPERTY_PMU_EBX_BIT_VECTOR_LENGTH); + return nr_bits > feature.f.bit && !kvm_cpu_has(feature.f); + } + + TEST_ASSERT_EQ(feature.f.reg, KVM_CPUID_ECX); + nr_bits =3D kvm_cpu_property(X86_PROPERTY_PMU_NR_FIXED_COUNTERS); + return nr_bits > feature.f.bit || kvm_cpu_has(feature.f); } =20 static __always_inline uint64_t kvm_cpu_supported_xcr0(void) --=20 2.42.0.869.gea05f2083d-goog