linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/7] KVM: selftests: Add tests for pmu event filter
@ 2023-04-14 11:00 Jinrong Liang
  2023-04-14 11:00 ` [PATCH 1/7] KVM: selftests: Replace int with uint32_t for nevents Jinrong Liang
                   ` (6 more replies)
  0 siblings, 7 replies; 11+ messages in thread
From: Jinrong Liang @ 2023-04-14 11:00 UTC (permalink / raw)
  To: Sean Christopherson
  Cc: Like Xu, Paolo Bonzini, Jonathan Corbet, Shuah Khan, Aaron Lewis,
	David Matlack, Vishal Annapurve, Wanpeng Li, Jinrong Liang,
	linux-kselftest, linux-doc, kvm, linux-kernel

From: Jinrong Liang <cloudliang@tencent.com>

Hi,

This patch set adds some tests to ensure consistent PMU performance event
filter behavior. Specifically, the patches aim to improve KVM's PMU event
filter by strengthening the test coverage, adding documentation, and making
other small changes. 

The first patch replaces int with uint32_t for nevents to ensure consistency
and readability in the code. The second patch adds fixed_counter_bitmap to
create_pmu_event_filter() to support the use of the same creator to control
the use of guest fixed counters. The third patch adds test cases for
unsupported input values in PMU filter, including unsupported "action"
values, unsupported "flags" values, and unsupported "nevents" values. Also,
it tests setting non-existent fixed counters in the fixed bitmap doesn't
fail.

The fourth patch updates the documentation for KVM_SET_PMU_EVENT_FILTER ioctl
to include a detailed description of how fixed performance events are handled
in the pmu filter. The fifth patch adds tests to cover that pmu_event_filter
works as expected when applied to fixed performance counters, even if there
is no fixed counter exists. The sixth patch adds a test to ensure that setting
both generic and fixed performance event filters does not affect the consistency
of the fixed performance filter behavior in KVM. The seventh patch adds a test
to verify the behavior of the pmu event filter when an incomplete
kvm_pmu_event_filter structure is used.

These changes help to ensure that KVM's PMU event filter functions as expected
in all supported use cases. These patches have been tested and verified to
function properly.

Thanks for your review and feedback.

Sincerely,

Jinrong Liang

Jinrong Liang (7):
  KVM: selftests: Replace int with uint32_t for nevents
  KVM: selftests: Apply create_pmu_event_filter() to fixed ctrs
  KVM: selftests: Test unavailable event filters are rejected
  KVM: x86/pmu: Add documentation for fixed ctr on PMU filter
  KVM: selftests: Check if pmu_event_filter meets expectations on fixed
    ctrs
  KVM: selftests: Check gp event filters without affecting fixed event
    filters
  KVM: selftests: Test pmu event filter with incompatible
    kvm_pmu_event_filter

 Documentation/virt/kvm/api.rst                |  21 ++
 .../kvm/x86_64/pmu_event_filter_test.c        | 239 ++++++++++++++++--
 2 files changed, 243 insertions(+), 17 deletions(-)


base-commit: a25497a280bbd7bbcc08c87ddb2b3909affc8402
-- 
2.31.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/7] KVM: selftests: Replace int with uint32_t for nevents
  2023-04-14 11:00 [PATCH 0/7] KVM: selftests: Add tests for pmu event filter Jinrong Liang
@ 2023-04-14 11:00 ` Jinrong Liang
  2023-04-14 11:00 ` [PATCH 2/7] KVM: selftests: Apply create_pmu_event_filter() to fixed ctrs Jinrong Liang
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Jinrong Liang @ 2023-04-14 11:00 UTC (permalink / raw)
  To: Sean Christopherson
  Cc: Like Xu, Paolo Bonzini, Jonathan Corbet, Shuah Khan, Aaron Lewis,
	David Matlack, Vishal Annapurve, Wanpeng Li, Jinrong Liang,
	linux-kselftest, linux-doc, kvm, linux-kernel

From: Jinrong Liang <cloudliang@tencent.com>

Defined as type __u32, the nevents field in kvm_pmu_event_filter
can only accept positive values within a specific range. Therefore,
replacing int with uint32_t for nevents ensures consistency and
readability in the code. This change has been tested and verified
to work correctly with all relevant code.

Signed-off-by: Jinrong Liang <cloudliang@tencent.com>
---
 .../selftests/kvm/x86_64/pmu_event_filter_test.c     | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c b/tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c
index 1f60dfae69e0..c0521fc9e8f6 100644
--- a/tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c
+++ b/tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c
@@ -194,7 +194,7 @@ static struct kvm_pmu_event_filter *alloc_pmu_event_filter(uint32_t nevents)
 
 
 static struct kvm_pmu_event_filter *
-create_pmu_event_filter(const uint64_t event_list[], int nevents,
+create_pmu_event_filter(const uint64_t event_list[], uint32_t nevents,
 			uint32_t action, uint32_t flags)
 {
 	struct kvm_pmu_event_filter *f;
@@ -648,7 +648,7 @@ const struct masked_events_test test_cases[] = {
 };
 
 static int append_test_events(const struct masked_events_test *test,
-			      uint64_t *events, int nevents)
+			      uint64_t *events, uint32_t nevents)
 {
 	const uint64_t *evts;
 	int i;
@@ -670,7 +670,7 @@ static bool bool_eq(bool a, bool b)
 }
 
 static void run_masked_events_tests(struct kvm_vcpu *vcpu, uint64_t *events,
-				    int nevents)
+				    uint32_t nevents)
 {
 	int ntests = ARRAY_SIZE(test_cases);
 	struct perf_counter c;
@@ -695,7 +695,7 @@ static void run_masked_events_tests(struct kvm_vcpu *vcpu, uint64_t *events,
 	}
 }
 
-static void add_dummy_events(uint64_t *events, int nevents)
+static void add_dummy_events(uint64_t *events, uint32_t nevents)
 {
 	int i;
 
@@ -714,7 +714,7 @@ static void add_dummy_events(uint64_t *events, int nevents)
 
 static void test_masked_events(struct kvm_vcpu *vcpu)
 {
-	int nevents = MAX_FILTER_EVENTS - MAX_TEST_EVENTS;
+	uint32_t nevents = MAX_FILTER_EVENTS - MAX_TEST_EVENTS;
 	uint64_t events[MAX_FILTER_EVENTS];
 
 	/* Run the test cases against a sparse PMU event filter. */
@@ -726,7 +726,7 @@ static void test_masked_events(struct kvm_vcpu *vcpu)
 }
 
 static int run_filter_test(struct kvm_vcpu *vcpu, const uint64_t *events,
-			   int nevents, uint32_t flags)
+			   uint32_t nevents, uint32_t flags)
 {
 	struct kvm_pmu_event_filter *f;
 	int r;
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 2/7] KVM: selftests: Apply create_pmu_event_filter() to fixed ctrs
  2023-04-14 11:00 [PATCH 0/7] KVM: selftests: Add tests for pmu event filter Jinrong Liang
  2023-04-14 11:00 ` [PATCH 1/7] KVM: selftests: Replace int with uint32_t for nevents Jinrong Liang
@ 2023-04-14 11:00 ` Jinrong Liang
  2023-04-14 11:00 ` [PATCH 3/7] KVM: selftests: Test unavailable event filters are rejected Jinrong Liang
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Jinrong Liang @ 2023-04-14 11:00 UTC (permalink / raw)
  To: Sean Christopherson
  Cc: Like Xu, Paolo Bonzini, Jonathan Corbet, Shuah Khan, Aaron Lewis,
	David Matlack, Vishal Annapurve, Wanpeng Li, Jinrong Liang,
	linux-kselftest, linux-doc, kvm, linux-kernel

From: Jinrong Liang <cloudliang@tencent.com>

Add fixed_counter_bitmap to the create_pmu_event_filter() to
support the use of the same creator to control the use of guest
fixed counters.

No functional change intended.

Signed-off-by: Jinrong Liang <cloudliang@tencent.com>
---
 .../kvm/x86_64/pmu_event_filter_test.c        | 31 ++++++++++++-------
 1 file changed, 19 insertions(+), 12 deletions(-)

diff --git a/tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c b/tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c
index c0521fc9e8f6..4e87eea6986b 100644
--- a/tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c
+++ b/tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c
@@ -192,19 +192,22 @@ static struct kvm_pmu_event_filter *alloc_pmu_event_filter(uint32_t nevents)
 	return f;
 }
 
-
 static struct kvm_pmu_event_filter *
 create_pmu_event_filter(const uint64_t event_list[], uint32_t nevents,
-			uint32_t action, uint32_t flags)
+			uint32_t action, uint32_t flags,
+			uint32_t fixed_counter_bitmap)
 {
 	struct kvm_pmu_event_filter *f;
 	int i;
 
 	f = alloc_pmu_event_filter(nevents);
 	f->action = action;
+	f->fixed_counter_bitmap = fixed_counter_bitmap;
 	f->flags = flags;
-	for (i = 0; i < nevents; i++)
-		f->events[i] = event_list[i];
+	if (f->nevents) {
+		for (i = 0; i < f->nevents; i++)
+			f->events[i] = event_list[i];
+	}
 
 	return f;
 }
@@ -213,7 +216,7 @@ static struct kvm_pmu_event_filter *event_filter(uint32_t action)
 {
 	return create_pmu_event_filter(event_list,
 				       ARRAY_SIZE(event_list),
-				       action, 0);
+				       action, 0, 0);
 }
 
 /*
@@ -260,7 +263,7 @@ static void test_amd_deny_list(struct kvm_vcpu *vcpu)
 	struct kvm_pmu_event_filter *f;
 	uint64_t count;
 
-	f = create_pmu_event_filter(&event, 1, KVM_PMU_EVENT_DENY, 0);
+	f = create_pmu_event_filter(&event, 1, KVM_PMU_EVENT_DENY, 0, 0);
 	count = test_with_filter(vcpu, f);
 
 	free(f);
@@ -544,7 +547,7 @@ static struct perf_counter run_masked_events_test(struct kvm_vcpu *vcpu,
 
 	f = create_pmu_event_filter(masked_events, nmasked_events,
 				    KVM_PMU_EVENT_ALLOW,
-				    KVM_PMU_EVENT_FLAG_MASKED_EVENTS);
+				    KVM_PMU_EVENT_FLAG_MASKED_EVENTS, 0);
 	r.raw = test_with_filter(vcpu, f);
 	free(f);
 
@@ -726,12 +729,14 @@ static void test_masked_events(struct kvm_vcpu *vcpu)
 }
 
 static int run_filter_test(struct kvm_vcpu *vcpu, const uint64_t *events,
-			   uint32_t nevents, uint32_t flags)
+			   uint32_t nevents, uint32_t flags, uint32_t action,
+			   uint32_t fixed_counter_bitmap)
 {
 	struct kvm_pmu_event_filter *f;
 	int r;
 
-	f = create_pmu_event_filter(events, nevents, KVM_PMU_EVENT_ALLOW, flags);
+	f = create_pmu_event_filter(events, nevents, action, flags,
+				    fixed_counter_bitmap);
 	r = __vm_ioctl(vcpu->vm, KVM_SET_PMU_EVENT_FILTER, f);
 	free(f);
 
@@ -747,14 +752,16 @@ static void test_filter_ioctl(struct kvm_vcpu *vcpu)
 	 * Unfortunately having invalid bits set in event data is expected to
 	 * pass when flags == 0 (bits other than eventsel+umask).
 	 */
-	r = run_filter_test(vcpu, &e, 1, 0);
+	r = run_filter_test(vcpu, &e, 1, 0, KVM_PMU_EVENT_ALLOW, 0);
 	TEST_ASSERT(r == 0, "Valid PMU Event Filter is failing");
 
-	r = run_filter_test(vcpu, &e, 1, KVM_PMU_EVENT_FLAG_MASKED_EVENTS);
+	r = run_filter_test(vcpu, &e, 1, KVM_PMU_EVENT_FLAG_MASKED_EVENTS,
+			    KVM_PMU_EVENT_ALLOW, 0);
 	TEST_ASSERT(r != 0, "Invalid PMU Event Filter is expected to fail");
 
 	e = KVM_PMU_ENCODE_MASKED_ENTRY(0xff, 0xff, 0xff, 0xf);
-	r = run_filter_test(vcpu, &e, 1, KVM_PMU_EVENT_FLAG_MASKED_EVENTS);
+	r = run_filter_test(vcpu, &e, 1, KVM_PMU_EVENT_FLAG_MASKED_EVENTS,
+			    KVM_PMU_EVENT_ALLOW, 0);
 	TEST_ASSERT(r == 0, "Valid PMU Event Filter is failing");
 }
 
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 3/7] KVM: selftests: Test unavailable event filters are rejected
  2023-04-14 11:00 [PATCH 0/7] KVM: selftests: Add tests for pmu event filter Jinrong Liang
  2023-04-14 11:00 ` [PATCH 1/7] KVM: selftests: Replace int with uint32_t for nevents Jinrong Liang
  2023-04-14 11:00 ` [PATCH 2/7] KVM: selftests: Apply create_pmu_event_filter() to fixed ctrs Jinrong Liang
@ 2023-04-14 11:00 ` Jinrong Liang
  2023-04-14 11:00 ` [PATCH 4/7] KVM: x86/pmu: Add documentation for fixed ctr on PMU filter Jinrong Liang
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Jinrong Liang @ 2023-04-14 11:00 UTC (permalink / raw)
  To: Sean Christopherson
  Cc: Like Xu, Paolo Bonzini, Jonathan Corbet, Shuah Khan, Aaron Lewis,
	David Matlack, Vishal Annapurve, Wanpeng Li, Jinrong Liang,
	linux-kselftest, linux-doc, kvm, linux-kernel

From: Jinrong Liang <cloudliang@tencent.com>

Adds unsupported input test cases for PMU filter. Specifically,
it tests the input of unsupported "action" values, unsupported
"flags" values, and unsupported "nevents" values, which should
all return an error, as they are currently unsupported by the
filter. Additionally, the patch tests setting non-exist fixed
counters in the fixed bitmap doesn't fail.

This change aims to improve the testing of the PMU filter and
ensure that it functions correctly in all supported use cases.
The patch has been tested and verified to function correctly.

Signed-off-by: Jinrong Liang <cloudliang@tencent.com>
---
 .../kvm/x86_64/pmu_event_filter_test.c        | 52 +++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c b/tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c
index 4e87eea6986b..a3d5c30ce914 100644
--- a/tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c
+++ b/tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c
@@ -27,6 +27,10 @@
 #define ARCH_PERFMON_BRANCHES_RETIRED		5
 
 #define NUM_BRANCHES 42
+#define FIXED_CTR_NUM_MASK				GENMASK_ULL(4, 0)
+#define PMU_EVENT_FILTER_INVALID_ACTION		(KVM_PMU_EVENT_DENY + 1)
+#define PMU_EVENT_FILTER_INVALID_FLAGS			(KVM_PMU_EVENT_FLAG_MASKED_EVENTS + 1)
+#define PMU_EVENT_FILTER_INVALID_NEVENTS		(MAX_FILTER_EVENTS + 1)
 
 /*
  * This is how the event selector and unit mask are stored in an AMD
@@ -743,10 +747,22 @@ static int run_filter_test(struct kvm_vcpu *vcpu, const uint64_t *events,
 	return r;
 }
 
+static uint8_t get_kvm_supported_fixed_num(void)
+{
+	const struct kvm_cpuid_entry2 *kvm_entry;
+
+	if (host_cpu_is_amd)
+		return 0;
+
+	kvm_entry = get_cpuid_entry(kvm_get_supported_cpuid(), 0xa, 0);
+	return kvm_entry->edx & FIXED_CTR_NUM_MASK;
+}
+
 static void test_filter_ioctl(struct kvm_vcpu *vcpu)
 {
 	uint64_t e = ~0ul;
 	int r;
+	uint8_t max_fixed_num = get_kvm_supported_fixed_num();
 
 	/*
 	 * Unfortunately having invalid bits set in event data is expected to
@@ -763,6 +779,42 @@ static void test_filter_ioctl(struct kvm_vcpu *vcpu)
 	r = run_filter_test(vcpu, &e, 1, KVM_PMU_EVENT_FLAG_MASKED_EVENTS,
 			    KVM_PMU_EVENT_ALLOW, 0);
 	TEST_ASSERT(r == 0, "Valid PMU Event Filter is failing");
+
+	/*
+	 * Test input of unsupported "action" values should return an error.
+	 * The only values currently supported are 0 or 1.
+	 */
+	r = run_filter_test(vcpu, 0, 0, 0, PMU_EVENT_FILTER_INVALID_ACTION, 0);
+	TEST_ASSERT(r != 0, "Set invalid action is expected to fail.");
+
+	/*
+	 * Test input of unsupported "flags" values should return an error.
+	 * The only values currently supported are 0 or 1.
+	 */
+	r = run_filter_test(vcpu, 0, 0, PMU_EVENT_FILTER_INVALID_FLAGS,
+			    KVM_PMU_EVENT_ALLOW, 0);
+	TEST_ASSERT(r != 0, "Set invalid flags is expected to fail.");
+
+	/*
+	 * Test input of unsupported "nevents" values should return an error.
+	 * The only values currently supported are those less than or equal to
+	 * MAX_FILTER_EVENTS.
+	 */
+	r = run_filter_test(vcpu, event_list, PMU_EVENT_FILTER_INVALID_NEVENTS,
+			    0, KVM_PMU_EVENT_ALLOW, 0);
+	TEST_ASSERT(r != 0,
+		    "Setting PMU event filters that exceeds the maximum supported value should fail");
+
+	/*
+	 * In this case, set non-exist fixed counters in the fixed bitmap
+	 * doesn't fail.
+	 */
+	if (max_fixed_num) {
+		r = run_filter_test(vcpu, 0, 0, 0, KVM_PMU_EVENT_ALLOW,
+				    ~GENMASK_ULL(max_fixed_num, 0));
+		TEST_ASSERT(r == 0,
+			    "Set invalid or non-exist fixed cunters in the fixed bitmap fail.");
+	}
 }
 
 int main(int argc, char *argv[])
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 4/7] KVM: x86/pmu: Add documentation for fixed ctr on PMU filter
  2023-04-14 11:00 [PATCH 0/7] KVM: selftests: Add tests for pmu event filter Jinrong Liang
                   ` (2 preceding siblings ...)
  2023-04-14 11:00 ` [PATCH 3/7] KVM: selftests: Test unavailable event filters are rejected Jinrong Liang
@ 2023-04-14 11:00 ` Jinrong Liang
  2023-04-15  0:53   ` kernel test robot
  2023-04-15  3:24   ` Bagas Sanjaya
  2023-04-14 11:00 ` [PATCH 5/7] KVM: selftests: Check if pmu_event_filter meets expectations on fixed ctrs Jinrong Liang
                   ` (2 subsequent siblings)
  6 siblings, 2 replies; 11+ messages in thread
From: Jinrong Liang @ 2023-04-14 11:00 UTC (permalink / raw)
  To: Sean Christopherson
  Cc: Like Xu, Paolo Bonzini, Jonathan Corbet, Shuah Khan, Aaron Lewis,
	David Matlack, Vishal Annapurve, Wanpeng Li, Jinrong Liang,
	linux-kselftest, linux-doc, kvm, linux-kernel

From: Jinrong Liang <cloudliang@tencent.com>

Update the documentation for the KVM_SET_PMU_EVENT_FILTER ioctl
to include a detailed description of how fixed performance events
are handled in the pmu filter. The action and fixed_counter_bitmap
members of the pmu filter to determine whether fixed performance
events can be programmed by the guest. This information is helpful
for correctly configuring the fixed_counter_bitmap and action fields
to filter fixed performance events.

Suggested-by: Like Xu <likexu@tencent.com>
Signed-off-by: Jinrong Liang <cloudliang@tencent.com>
---
 Documentation/virt/kvm/api.rst | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
index a69e91088d76..036f5b1a39af 100644
--- a/Documentation/virt/kvm/api.rst
+++ b/Documentation/virt/kvm/api.rst
@@ -5122,6 +5122,27 @@ Valid values for 'action'::
   #define KVM_PMU_EVENT_ALLOW 0
   #define KVM_PMU_EVENT_DENY 1
 
+Via this API, KVM userspace can also control the behavior of the VM's fixed
+counters (if any) by configuring the "action" and "fixed_counter_bitmap" fields.
+
+Specifically, KVM follows the following pseudo-code when determining whether to
+allow the guest FixCtr[i] to count its pre-defined fixed event:
+
+  FixCtr[i]_is_allowed = (action == ALLOW) && (bitmap & BIT(i)) ||
+    (action == DENY) && !(bitmap & BIT(i));
+  FixCtr[i]_is_denied = !FixCtr[i]_is_allowed;
+
+Note once this API interface is called, the default zero value of the field
+"fixed_counter_bitmap" will implicitly affect all fixed counters, even if it's
+expected to be used only to control the events on generic counters.
+
+In addition, pre-defined performance events on the fixed counters already have
+event_select and unit_mask values defined, which means userspace can also
+control fixed counters by configuring "action"+ "events" fields.
+
+When there is a contradiction between these two polices, the fixed performance
+counter will only follow the rule of the pseudo-code above.
+
 4.121 KVM_PPC_SVM_OFF
 ---------------------
 
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 5/7] KVM: selftests: Check if pmu_event_filter meets expectations on fixed ctrs
  2023-04-14 11:00 [PATCH 0/7] KVM: selftests: Add tests for pmu event filter Jinrong Liang
                   ` (3 preceding siblings ...)
  2023-04-14 11:00 ` [PATCH 4/7] KVM: x86/pmu: Add documentation for fixed ctr on PMU filter Jinrong Liang
@ 2023-04-14 11:00 ` Jinrong Liang
  2023-04-14 11:00 ` [PATCH 6/7] KVM: selftests: Check gp event filters without affecting fixed event filters Jinrong Liang
  2023-04-14 11:00 ` [PATCH 7/7] KVM: selftests: Test pmu event filter with incompatible kvm_pmu_event_filter Jinrong Liang
  6 siblings, 0 replies; 11+ messages in thread
From: Jinrong Liang @ 2023-04-14 11:00 UTC (permalink / raw)
  To: Sean Christopherson
  Cc: Like Xu, Paolo Bonzini, Jonathan Corbet, Shuah Khan, Aaron Lewis,
	David Matlack, Vishal Annapurve, Wanpeng Li, Jinrong Liang,
	linux-kselftest, linux-doc, kvm, linux-kernel

From: Jinrong Liang <cloudliang@tencent.com>

Add tests to cover that pmu_event_filter works as expected when
it's applied to fixed performance counters, even if there is none
fixed counter exists (e.g. Intel guest pmu version=1 or AMD guest).

Signed-off-by: Jinrong Liang <cloudliang@tencent.com>
---
 .../kvm/x86_64/pmu_event_filter_test.c        | 109 ++++++++++++++++++
 1 file changed, 109 insertions(+)

diff --git a/tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c b/tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c
index a3d5c30ce914..0f54c53d7fff 100644
--- a/tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c
+++ b/tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c
@@ -31,6 +31,7 @@
 #define PMU_EVENT_FILTER_INVALID_ACTION		(KVM_PMU_EVENT_DENY + 1)
 #define PMU_EVENT_FILTER_INVALID_FLAGS			(KVM_PMU_EVENT_FLAG_MASKED_EVENTS + 1)
 #define PMU_EVENT_FILTER_INVALID_NEVENTS		(MAX_FILTER_EVENTS + 1)
+#define INTEL_PMC_IDX_FIXED 32
 
 /*
  * This is how the event selector and unit mask are stored in an AMD
@@ -817,6 +818,113 @@ static void test_filter_ioctl(struct kvm_vcpu *vcpu)
 	}
 }
 
+static void intel_guest_run_fixed_counters(uint8_t fixed_ctr_idx)
+{
+	for (;;) {
+		wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, 0);
+		wrmsr(MSR_CORE_PERF_FIXED_CTR0 + fixed_ctr_idx, 0);
+
+		/* Only OS_EN bit is enabled for fixed counter[idx]. */
+		wrmsr(MSR_CORE_PERF_FIXED_CTR_CTRL, BIT_ULL(4 * fixed_ctr_idx));
+		wrmsr(MSR_CORE_PERF_GLOBAL_CTRL,
+		      BIT_ULL(INTEL_PMC_IDX_FIXED + fixed_ctr_idx));
+		__asm__ __volatile__("loop ." : "+c"((int){NUM_BRANCHES}));
+		wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, 0);
+
+		GUEST_SYNC(rdmsr(MSR_CORE_PERF_FIXED_CTR0 + fixed_ctr_idx));
+	}
+}
+
+static struct kvm_vcpu *new_vcpu(void *guest_code)
+{
+	struct kvm_vm *vm;
+	struct kvm_vcpu *vcpu;
+
+	vm = vm_create_with_one_vcpu(&vcpu, guest_code);
+	vm_init_descriptor_tables(vm);
+	vcpu_init_descriptor_tables(vcpu);
+
+	return vcpu;
+}
+
+static void free_vcpu(struct kvm_vcpu *vcpu)
+{
+	kvm_vm_free(vcpu->vm);
+}
+
+static uint64_t test_fixed_ctr_without_filter(struct kvm_vcpu *vcpu)
+{
+	return run_vcpu_to_sync(vcpu);
+}
+
+static const uint32_t actions[] = {
+	KVM_PMU_EVENT_ALLOW,
+	KVM_PMU_EVENT_DENY,
+};
+
+static uint64_t test_fixed_ctr_with_filter(struct kvm_vcpu *vcpu,
+					   uint32_t action,
+					   uint32_t bitmap)
+{
+	struct kvm_pmu_event_filter *f;
+	uint64_t r;
+
+	f = create_pmu_event_filter(0, 0, action, 0, bitmap);
+	r = test_with_filter(vcpu, f);
+	free(f);
+	return r;
+}
+
+static bool fixed_ctr_is_allowed(uint8_t idx, uint32_t action, uint32_t bitmap)
+{
+	return (action == KVM_PMU_EVENT_ALLOW && (bitmap & BIT_ULL(idx))) ||
+		(action == KVM_PMU_EVENT_DENY && !(bitmap & BIT_ULL(idx)));
+}
+
+static void test_fixed_ctr_action_and_bitmap(struct kvm_vcpu *vcpu,
+					     uint8_t fixed_ctr_idx,
+					     uint8_t max_fixed_num)
+{
+	uint8_t i;
+	uint32_t bitmap;
+	uint64_t count;
+	bool expected;
+
+	/*
+	 * Check the fixed performance counter can count normally works when
+	 * KVM userspace doesn't set any pmu filter.
+	 */
+	TEST_ASSERT(max_fixed_num && test_fixed_ctr_without_filter(vcpu),
+		    "Fixed counter does not exist or does not work as expected.");
+
+	for (i = 0; i < ARRAY_SIZE(actions); i++) {
+		for (bitmap = 0; bitmap < BIT_ULL(max_fixed_num); bitmap++) {
+			expected = fixed_ctr_is_allowed(fixed_ctr_idx, actions[i], bitmap);
+			count = test_fixed_ctr_with_filter(vcpu, actions[i], bitmap);
+
+			TEST_ASSERT(expected == !!count,
+				    "Fixed event filter does not work as expected.");
+		}
+	}
+}
+
+static void test_fixed_counter_bitmap(void)
+{
+	struct kvm_vcpu *vcpu;
+	uint8_t idx, max_fixed_num = get_kvm_supported_fixed_num();
+
+	/*
+	 * Check that pmu_event_filter works as expected when it's applied to
+	 * fixed performance counters.
+	 */
+	for (idx = 0; idx < max_fixed_num; idx++) {
+		vcpu = new_vcpu(intel_guest_run_fixed_counters);
+		vcpu_args_set(vcpu, 1, idx);
+		test_fixed_ctr_action_and_bitmap(vcpu, idx, max_fixed_num);
+		free_vcpu(vcpu);
+	}
+}
+
 int main(int argc, char *argv[])
 {
 	void (*guest_code)(void);
@@ -860,6 +968,7 @@ int main(int argc, char *argv[])
 	kvm_vm_free(vm);
 
 	test_pmu_config_disable(guest_code);
+	test_fixed_counter_bitmap();
 
 	return 0;
 }
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 6/7] KVM: selftests: Check gp event filters without affecting fixed event filters
  2023-04-14 11:00 [PATCH 0/7] KVM: selftests: Add tests for pmu event filter Jinrong Liang
                   ` (4 preceding siblings ...)
  2023-04-14 11:00 ` [PATCH 5/7] KVM: selftests: Check if pmu_event_filter meets expectations on fixed ctrs Jinrong Liang
@ 2023-04-14 11:00 ` Jinrong Liang
  2023-04-14 11:00 ` [PATCH 7/7] KVM: selftests: Test pmu event filter with incompatible kvm_pmu_event_filter Jinrong Liang
  6 siblings, 0 replies; 11+ messages in thread
From: Jinrong Liang @ 2023-04-14 11:00 UTC (permalink / raw)
  To: Sean Christopherson
  Cc: Like Xu, Paolo Bonzini, Jonathan Corbet, Shuah Khan, Aaron Lewis,
	David Matlack, Vishal Annapurve, Wanpeng Li, Jinrong Liang,
	linux-kselftest, linux-doc, kvm, linux-kernel

From: Jinrong Liang <cloudliang@tencent.com>

Add a test to ensure that setting both generic and fixed performance
event filters does not affect the consistency of the fixed performance
filter behavior in KVM. This test helps to ensure that the fixed
performance filter works as expected even when generic performance
event filters are also set.

Signed-off-by: Jinrong Liang <cloudliang@tencent.com>
---
 .../selftests/kvm/x86_64/pmu_event_filter_test.c   | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c b/tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c
index 0f54c53d7fff..9be4c6f8fb7e 100644
--- a/tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c
+++ b/tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c
@@ -889,6 +889,7 @@ static void test_fixed_ctr_action_and_bitmap(struct kvm_vcpu *vcpu,
 	uint32_t bitmap;
 	uint64_t count;
 	bool expected;
+	struct kvm_pmu_event_filter *f;
 
 	/*
 	 * Check the fixed performance counter can count normally works when
@@ -902,6 +903,19 @@ static void test_fixed_ctr_action_and_bitmap(struct kvm_vcpu *vcpu,
 			expected = fixed_ctr_is_allowed(fixed_ctr_idx, actions[i], bitmap);
 			count = test_fixed_ctr_with_filter(vcpu, actions[i], bitmap);
 
+			TEST_ASSERT(expected == !!count,
+				    "Fixed event filter does not work as expected.");
+
+			/*
+			 * Check that setting both events[] and fixed_counter_bitmap
+			 * does not affect the consistency of the fixed ctrs' behaviour.
+			 *
+			 * Note, the fixed_counter_bitmap rule has high priority.
+			 */
+			f = event_filter(actions[i]);
+			f->fixed_counter_bitmap = bitmap;
+			count = test_with_filter(vcpu, f);
+
 			TEST_ASSERT(expected == !!count,
 				    "Fixed event filter does not work as expected.");
 		}
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 7/7] KVM: selftests: Test pmu event filter with incompatible kvm_pmu_event_filter
  2023-04-14 11:00 [PATCH 0/7] KVM: selftests: Add tests for pmu event filter Jinrong Liang
                   ` (5 preceding siblings ...)
  2023-04-14 11:00 ` [PATCH 6/7] KVM: selftests: Check gp event filters without affecting fixed event filters Jinrong Liang
@ 2023-04-14 11:00 ` Jinrong Liang
  6 siblings, 0 replies; 11+ messages in thread
From: Jinrong Liang @ 2023-04-14 11:00 UTC (permalink / raw)
  To: Sean Christopherson
  Cc: Like Xu, Paolo Bonzini, Jonathan Corbet, Shuah Khan, Aaron Lewis,
	David Matlack, Vishal Annapurve, Wanpeng Li, Jinrong Liang,
	linux-kselftest, linux-doc, kvm, linux-kernel

From: Jinrong Liang <cloudliang@tencent.com>

Add test to verify the behavior of the pmu event filter when an
incomplete kvm_pmu_event_filter structure is used. By running the
test, we can ensure that the pmu event filter correctly handles
incomplete structures and does not allow events to be counted when
they should not be.

Signed-off-by: Jinrong Liang <cloudliang@tencent.com>
---
 .../kvm/x86_64/pmu_event_filter_test.c        | 23 +++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c b/tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c
index 9be4c6f8fb7e..a6b6e0d086ae 100644
--- a/tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c
+++ b/tools/testing/selftests/kvm/x86_64/pmu_event_filter_test.c
@@ -881,6 +881,24 @@ static bool fixed_ctr_is_allowed(uint8_t idx, uint32_t action, uint32_t bitmap)
 		(action == KVM_PMU_EVENT_DENY && !(bitmap & BIT_ULL(idx)));
 }
 
+struct incompatible_pmu_event_filter {
+	__u32 action;
+	__u32 nevents;
+	__u32 fixed_counter_bitmap;
+};
+
+static uint64_t test_incompatible_filter(struct kvm_vcpu *vcpu, uint32_t action,
+					 uint32_t bitmap)
+{
+	struct incompatible_pmu_event_filter err_f;
+
+	err_f.action = action;
+	err_f.fixed_counter_bitmap = bitmap;
+	ioctl((vcpu->vm)->fd, KVM_SET_PMU_EVENT_FILTER, &err_f.action);
+
+	return run_vcpu_to_sync(vcpu);
+}
+
 static void test_fixed_ctr_action_and_bitmap(struct kvm_vcpu *vcpu,
 					     uint8_t fixed_ctr_idx,
 					     uint8_t max_fixed_num)
@@ -918,6 +936,11 @@ static void test_fixed_ctr_action_and_bitmap(struct kvm_vcpu *vcpu,
 
 			TEST_ASSERT(expected == !!count,
 				    "Fixed event filter does not work as expected.");
+
+			/* Test incompatible event filter works as expected. */
+			count = test_incompatible_filter(vcpu, actions[i], bitmap);
+			TEST_ASSERT(expected == !!count,
+				    "Incompatible filter does not work as expected.");
 		}
 	}
 }
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH 4/7] KVM: x86/pmu: Add documentation for fixed ctr on PMU filter
  2023-04-14 11:00 ` [PATCH 4/7] KVM: x86/pmu: Add documentation for fixed ctr on PMU filter Jinrong Liang
@ 2023-04-15  0:53   ` kernel test robot
  2023-04-15  3:24   ` Bagas Sanjaya
  1 sibling, 0 replies; 11+ messages in thread
From: kernel test robot @ 2023-04-15  0:53 UTC (permalink / raw)
  To: Jinrong Liang, Sean Christopherson
  Cc: oe-kbuild-all, Like Xu, Paolo Bonzini, Jonathan Corbet,
	Shuah Khan, Aaron Lewis, David Matlack, Vishal Annapurve,
	Wanpeng Li, Jinrong Liang, linux-kselftest, linux-doc, kvm,
	linux-kernel

Hi Jinrong,

kernel test robot noticed the following build warnings:

[auto build test WARNING on a25497a280bbd7bbcc08c87ddb2b3909affc8402]

url:    https://github.com/intel-lab-lkp/linux/commits/Jinrong-Liang/KVM-selftests-Replace-int-with-uint32_t-for-nevents/20230414-190401
base:   a25497a280bbd7bbcc08c87ddb2b3909affc8402
patch link:    https://lore.kernel.org/r/20230414110056.19665-5-cloudliang%40tencent.com
patch subject: [PATCH 4/7] KVM: x86/pmu: Add documentation for fixed ctr on PMU filter
reproduce:
        # https://github.com/intel-lab-lkp/linux/commit/b0effe04478df3b33a26331f48540851c4d33173
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Jinrong-Liang/KVM-selftests-Replace-int-with-uint32_t-for-nevents/20230414-190401
        git checkout b0effe04478df3b33a26331f48540851c4d33173
        make menuconfig
        # enable CONFIG_COMPILE_TEST, CONFIG_WARN_MISSING_DOCUMENTS, CONFIG_WARN_ABI_ERRORS
        make htmldocs

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
| Link: https://lore.kernel.org/oe-kbuild-all/202304150850.rx4UDDsB-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> Documentation/virt/kvm/api.rst:5133: WARNING: Definition list ends without a blank line; unexpected unindent.

vim +5133 Documentation/virt/kvm/api.rst

  5130	
  5131	  FixCtr[i]_is_allowed = (action == ALLOW) && (bitmap & BIT(i)) ||
  5132	    (action == DENY) && !(bitmap & BIT(i));
> 5133	  FixCtr[i]_is_denied = !FixCtr[i]_is_allowed;
  5134	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 4/7] KVM: x86/pmu: Add documentation for fixed ctr on PMU filter
  2023-04-14 11:00 ` [PATCH 4/7] KVM: x86/pmu: Add documentation for fixed ctr on PMU filter Jinrong Liang
  2023-04-15  0:53   ` kernel test robot
@ 2023-04-15  3:24   ` Bagas Sanjaya
  2023-04-16  0:25     ` Jinrong Liang
  1 sibling, 1 reply; 11+ messages in thread
From: Bagas Sanjaya @ 2023-04-15  3:24 UTC (permalink / raw)
  To: Jinrong Liang, Sean Christopherson
  Cc: Like Xu, Paolo Bonzini, Jonathan Corbet, Shuah Khan, Aaron Lewis,
	David Matlack, Vishal Annapurve, Wanpeng Li, Jinrong Liang,
	linux-kselftest, linux-doc, kvm, linux-kernel

On Fri, Apr 14, 2023 at 07:00:53PM +0800, Jinrong Liang wrote:
> +Specifically, KVM follows the following pseudo-code when determining whether to
> +allow the guest FixCtr[i] to count its pre-defined fixed event:
> +
> +  FixCtr[i]_is_allowed = (action == ALLOW) && (bitmap & BIT(i)) ||
> +    (action == DENY) && !(bitmap & BIT(i));
> +  FixCtr[i]_is_denied = !FixCtr[i]_is_allowed;
> +

As kernel test robot has reported [1], you need to wrap the code above
in a code block:

---- >8 ----
diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
index 036f5b1a39aff8..b5836767e0e76d 100644
--- a/Documentation/virt/kvm/api.rst
+++ b/Documentation/virt/kvm/api.rst
@@ -5126,7 +5126,7 @@ Via this API, KVM userspace can also control the behavior of the VM's fixed
 counters (if any) by configuring the "action" and "fixed_counter_bitmap" fields.
 
 Specifically, KVM follows the following pseudo-code when determining whether to
-allow the guest FixCtr[i] to count its pre-defined fixed event:
+allow the guest FixCtr[i] to count its pre-defined fixed event::
 
   FixCtr[i]_is_allowed = (action == ALLOW) && (bitmap & BIT(i)) ||
     (action == DENY) && !(bitmap & BIT(i));

Thanks.

[1]: https://lore.kernel.org/linux-doc/202304150850.rx4UDDsB-lkp@intel.com/

-- 
An old man doll... just what I always wanted! - Clara

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH 4/7] KVM: x86/pmu: Add documentation for fixed ctr on PMU filter
  2023-04-15  3:24   ` Bagas Sanjaya
@ 2023-04-16  0:25     ` Jinrong Liang
  0 siblings, 0 replies; 11+ messages in thread
From: Jinrong Liang @ 2023-04-16  0:25 UTC (permalink / raw)
  To: Bagas Sanjaya
  Cc: Sean Christopherson, Like Xu, Paolo Bonzini, Jonathan Corbet,
	Shuah Khan, Aaron Lewis, David Matlack, Vishal Annapurve,
	Wanpeng Li, Jinrong Liang, linux-kselftest, linux-doc, kvm,
	linux-kernel

Bagas Sanjaya <bagasdotme@gmail.com> 于2023年4月15日周六 11:24写道:
>
> On Fri, Apr 14, 2023 at 07:00:53PM +0800, Jinrong Liang wrote:
> > +Specifically, KVM follows the following pseudo-code when determining whether to
> > +allow the guest FixCtr[i] to count its pre-defined fixed event:
> > +
> > +  FixCtr[i]_is_allowed = (action == ALLOW) && (bitmap & BIT(i)) ||
> > +    (action == DENY) && !(bitmap & BIT(i));
> > +  FixCtr[i]_is_denied = !FixCtr[i]_is_allowed;
> > +
>
> As kernel test robot has reported [1], you need to wrap the code above
> in a code block:

I will make the changes as you suggested, i.e. wrap the code above in
a code block.

Thanks.

>
> ---- >8 ----
> diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
> index 036f5b1a39aff8..b5836767e0e76d 100644
> --- a/Documentation/virt/kvm/api.rst
> +++ b/Documentation/virt/kvm/api.rst
> @@ -5126,7 +5126,7 @@ Via this API, KVM userspace can also control the behavior of the VM's fixed
>  counters (if any) by configuring the "action" and "fixed_counter_bitmap" fields.
>
>  Specifically, KVM follows the following pseudo-code when determining whether to
> -allow the guest FixCtr[i] to count its pre-defined fixed event:
> +allow the guest FixCtr[i] to count its pre-defined fixed event::
>
>    FixCtr[i]_is_allowed = (action == ALLOW) && (bitmap & BIT(i)) ||
>      (action == DENY) && !(bitmap & BIT(i));
>
> Thanks.
>
> [1]: https://lore.kernel.org/linux-doc/202304150850.rx4UDDsB-lkp@intel.com/
>
> --
> An old man doll... just what I always wanted! - Clara

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2023-04-16  0:25 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-14 11:00 [PATCH 0/7] KVM: selftests: Add tests for pmu event filter Jinrong Liang
2023-04-14 11:00 ` [PATCH 1/7] KVM: selftests: Replace int with uint32_t for nevents Jinrong Liang
2023-04-14 11:00 ` [PATCH 2/7] KVM: selftests: Apply create_pmu_event_filter() to fixed ctrs Jinrong Liang
2023-04-14 11:00 ` [PATCH 3/7] KVM: selftests: Test unavailable event filters are rejected Jinrong Liang
2023-04-14 11:00 ` [PATCH 4/7] KVM: x86/pmu: Add documentation for fixed ctr on PMU filter Jinrong Liang
2023-04-15  0:53   ` kernel test robot
2023-04-15  3:24   ` Bagas Sanjaya
2023-04-16  0:25     ` Jinrong Liang
2023-04-14 11:00 ` [PATCH 5/7] KVM: selftests: Check if pmu_event_filter meets expectations on fixed ctrs Jinrong Liang
2023-04-14 11:00 ` [PATCH 6/7] KVM: selftests: Check gp event filters without affecting fixed event filters Jinrong Liang
2023-04-14 11:00 ` [PATCH 7/7] KVM: selftests: Test pmu event filter with incompatible kvm_pmu_event_filter Jinrong Liang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).