@@ -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[])