Received: by 2002:a05:7412:e794:b0:fa:551:50a7 with SMTP id o20csp634421rdd; Tue, 9 Jan 2024 15:08:23 -0800 (PST) X-Google-Smtp-Source: AGHT+IGuVCk3mf6EJzRtb/d2uPutTBvfZ6r1Nwwb7fPZ66ra6fKmHoT0NMp+gdQiunG4KTB4oOlg X-Received: by 2002:a05:6a00:4fca:b0:6d9:bb58:fe30 with SMTP id le10-20020a056a004fca00b006d9bb58fe30mr228756pfb.23.1704841703394; Tue, 09 Jan 2024 15:08:23 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1704841703; cv=none; d=google.com; s=arc-20160816; b=ATwIK5QimX+YOVuMQESvZRB/SWxIzHRpAiBKHj61AhQ8BN3qnqrmpUcL0T2JFLkX7i hvhSKVqhtUT3lQ7XJ2Me1nmyA1xcWwCATCYT4J8tpzlw6zJU5whUstq0TyanZZWtUTDu P9CRESamEbiNN1dMVS9uVrrSEqHLQ30LStVBuU+6Q2lkmD7dgsqvijwr+ep3IwYqoU7g PbIT9J1hxGPzioPTph1qgApMuURomNr5EKS0AfNH75LHK5QZuMe6omrNIy0xIv+Y2LY8 ZFaPsFpoaBvrAxgyX/yJO6Frl0ZlkWXflbWvNJSPhfNL8bg/oXz77gYH51GV4ZGNG3Jz LFrA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=cc:to:from:subject:message-id:references:mime-version :list-unsubscribe:list-subscribe:list-id:precedence:in-reply-to:date :reply-to:dkim-signature; bh=bzI7ZO6tNGlUzmltnB+PRcMw8O3L9lh6nE9+2Vf5zg0=; fh=gm96CM+cG0KJxn7vnhn0c1c98ILNP1HHUrKfrGecw3M=; b=W037kO3dsh/ln3oyxts9E/FajEngd1Wv3ENIW2CHjWSptNXpVKHMjUhjOfAM6kD77j CtNnZHEu3oSWrt9XzfETE9SL2JyjEb/Ivbx65gEQ10dc2TrxdmfTkYdAOYRbf0MMN2aJ tguC2wOqi8sQV5XdPHToCRgdgAmF91BUIa7GUn7XjzYg+cUAVZK1yJFAgYRVTxjOXeCE Y1eb+jF2SlHeKP2BIXdPs8elREmKr+Ib7fHPjXBsbCF2QwIQoVpIW1PSB1N9hHULY/UY aKemDBErBi0VUbXpijJe9LQfx2lc8VDc+Gb0GViYnjC+P1vYuK+8UiGdbKqlXkh/v1qB 6+hw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=cyRVBMEg; spf=pass (google.com: domain of linux-kernel+bounces-21503-linux.lists.archive=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-21503-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [139.178.88.99]) by mx.google.com with ESMTPS id eb4-20020a056a004c8400b006d9a9d65993si2309650pfb.127.2024.01.09.15.08.23 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Jan 2024 15:08:23 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-21503-linux.lists.archive=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) client-ip=139.178.88.99; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=cyRVBMEg; spf=pass (google.com: domain of linux-kernel+bounces-21503-linux.lists.archive=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-21503-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sv.mirrors.kernel.org (Postfix) with ESMTPS id 0FA41286CAE for ; Tue, 9 Jan 2024 23:08:23 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 47564481BE; Tue, 9 Jan 2024 23:03:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="cyRVBMEg" Received: from mail-pg1-f201.google.com (mail-pg1-f201.google.com [209.85.215.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0480B47F66 for ; Tue, 9 Jan 2024 23:03:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com Received: by mail-pg1-f201.google.com with SMTP id 41be03b00d2f7-5ca4ee5b97aso1220829a12.1 for ; Tue, 09 Jan 2024 15:03:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1704841400; x=1705446200; 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=bzI7ZO6tNGlUzmltnB+PRcMw8O3L9lh6nE9+2Vf5zg0=; b=cyRVBMEgmrai+tiaoH/GOFzx5hSoKzJI/IF/7XUN1fZctnqZJO+0gkcKRGg+12ngCJ NuV9paau9ij+aG2b7kB1n4ws/x17PL/ZL0254kFsoqJJVqdU5I9Zva9apTg/3X9/xfrd ESxv9ZFtT3idWjejYR4dsM1EqZRq/QCYZk+JiszxcT5KVSoRH7Dj4fJThtyUDVgC0Or6 hldH4BVorDsV9B1gnHFGhWvhk6/cynN0m+W2PqE2DchBFMkAPAlQ2w3AeutTZ2hdAD7Y I6IIjaHwj0eB3Qrvt80w38JEXZyYQMj8E1vfHhpd3P2R8Oro1jPexyhQEzVbB6Uk/7iW RXQQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1704841400; x=1705446200; 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=bzI7ZO6tNGlUzmltnB+PRcMw8O3L9lh6nE9+2Vf5zg0=; b=WKnLRDBL3KKZdJday61MIy9TRkd4DFVRrnPFLYA6JFuy8BI8QgxX5YWuc/BNFPu8GM xnAB6xlj5ATb8q1mW0CzfU/l0QK+wRcEcXrt67705Xz5az57KJeoqnWDdj44nCj+er++ Rikl9aQg2rIvp5pZDTAdfvCtm3I8qc5Et7MgU2rjC4BKoxTIxF/7JUWzCOoUIS9BsJHk qtRHm8mEPNTEJ6y8NN1ptGkyEWC8kn97ccZsCGquK81uwuIugETPL8SFg4gv/KCFlRdj +fHrOWdyZiJs2vBmGAh6BRcLnN5CX/xyvJSYVMJ7qC2p+sfVxWkPqSjzn60xUSfV70MF nCjg== X-Gm-Message-State: AOJu0Yy2F8SYoi2zN+6HiCqJViRJJwHpgaVSwfasaDGKJhpIqJFCZvEM 78pajGtExDqzrr8x5HGnGcpZbgiV6F+OR1j6Uw== X-Received: from zagreus.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:5c37]) (user=seanjc job=sendgmr) by 2002:a65:6390:0:b0:5ce:d4a8:3820 with SMTP id h16-20020a656390000000b005ced4a83820mr143pgv.10.1704841400468; Tue, 09 Jan 2024 15:03:20 -0800 (PST) Reply-To: Sean Christopherson Date: Tue, 9 Jan 2024 15:02:34 -0800 In-Reply-To: <20240109230250.424295-1-seanjc@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240109230250.424295-1-seanjc@google.com> X-Mailer: git-send-email 2.43.0.472.g3155946c3a-goog Message-ID: <20240109230250.424295-15-seanjc@google.com> Subject: [PATCH v10 14/29] 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 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 := 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 4f737d3b893c..92d4f8ecc730 100644 --- a/tools/testing/selftests/kvm/include/x86_64/processor.h +++ b/tools/testing/selftests/kvm/include/x86_64/processor.h @@ -282,24 +282,41 @@ struct kvm_x86_cpu_property { * that indicates the feature is _not_ supported, and a property that states * the length of the bit mask of unsupported features. A feature is supported * if the size of the bit mask is larger than the "unavailable" bit, and said - * 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 given - * architectural event is supported. + * Wrap the events for general purpose and fixed counters to simplify checking + * 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 = { \ - .anti_feature = KVM_X86_CPU_FEATURE(0xa, 0, EBX, __bit), \ - }; \ - \ - feature; \ +#define KVM_X86_PMU_FEATURE(__reg, __bit) \ +({ \ + struct kvm_x86_pmu_feature feature = { \ + .f = KVM_X86_CPU_FEATURE(0xa, 0, __reg, __bit), \ + }; \ + \ + kvm_static_assert(KVM_CPUID_##__reg == KVM_CPUID_EBX || \ + KVM_CPUID_##__reg == KVM_CPUID_ECX); \ + feature; \ }) -#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) static inline unsigned int x86_family(unsigned int eax) { @@ -698,10 +715,16 @@ static __always_inline bool this_cpu_has_p(struct kvm_x86_cpu_property property) static inline bool this_pmu_has(struct kvm_x86_pmu_feature feature) { - uint32_t nr_bits = this_cpu_property(X86_PROPERTY_PMU_EBX_BIT_VECTOR_LENGTH); + uint32_t nr_bits; - return nr_bits > feature.anti_feature.bit && - !this_cpu_has(feature.anti_feature); + if (feature.f.reg == KVM_CPUID_EBX) { + nr_bits = 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 == KVM_CPUID_ECX); + nr_bits = this_cpu_property(X86_PROPERTY_PMU_NR_FIXED_COUNTERS); + return nr_bits > feature.f.bit || this_cpu_has(feature.f); } static __always_inline uint64_t this_cpu_supported_xcr0(void) @@ -917,10 +940,16 @@ static __always_inline bool kvm_cpu_has_p(struct kvm_x86_cpu_property property) static inline bool kvm_pmu_has(struct kvm_x86_pmu_feature feature) { - uint32_t nr_bits = kvm_cpu_property(X86_PROPERTY_PMU_EBX_BIT_VECTOR_LENGTH); + uint32_t nr_bits; - return nr_bits > feature.anti_feature.bit && - !kvm_cpu_has(feature.anti_feature); + if (feature.f.reg == KVM_CPUID_EBX) { + nr_bits = 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 = kvm_cpu_property(X86_PROPERTY_PMU_NR_FIXED_COUNTERS); + return nr_bits > feature.f.bit || kvm_cpu_has(feature.f); } static __always_inline uint64_t kvm_cpu_supported_xcr0(void) -- 2.43.0.472.g3155946c3a-goog