* [PATCH v2 0/2] RISC-V: KVM: Add PMU event filter support
@ 2026-08-07 5:32 Yuhang.chen
2026-08-07 5:32 ` [PATCH v2 1/2] " Yuhang.chen
2026-08-07 5:32 ` [PATCH v2 2/2] RISC-V: KVM: selftests: Add PMU event filter test Yuhang.chen
0 siblings, 2 replies; 3+ messages in thread
From: Yuhang.chen @ 2026-08-07 5:32 UTC (permalink / raw)
To: anup
Cc: atish.patra, palmer, pjw, aou, alex, pbonzini, shuah, kvm,
kvm-riscv, linux-riscv, linux-kernel, linux-kselftest, zhouquan,
Yuhang.chen
This series adds PMU event filter support to RISC-V KVM, allowing a
userspace VMM to restrict which SBI PMU events a guest is permitted to
program.
The KVM_SET_PMU_EVENT_FILTER ioctl and KVM_CAP_PMU_EVENT_FILTER already
exist as generic KVM uAPI (include/uapi/linux/kvm.h); RISC-V KVM does
not yet implement them. Wiring them up lets a VMM limit a guest's PMU
event access, which is useful for sandboxing and for withholding host
PMU events the host does not intend to expose.
Patch 1 implements the kernel side: the uapi struct, the ioctl handler
with an SRCU-protected filter, enforcement in
kvm_riscv_vcpu_pmu_ctr_cfg_match() (a disallowed event fails with
SBI_ERR_NOT_SUPPORTED), and advertisement of KVM_CAP_PMU_EVENT_FILTER.
Like the other arch-specific KVM uAPI structs, struct
kvm_pmu_event_filter is defined per-architecture; its layout reflects
RISC-V PMU events and the ioctl number encodes the struct size.
Patch 2 adds a selftest that covers the ALLOW/DENY semantics with the
event in and out of the list, filter clearing, and ioctl argument
rejection (EINVAL/E2BIG).
Testing: built and run under QEMU TCG with nested KVM (an L1 KVM host
running an L2 guest). The selftest (patch 2) passes and dmesg stays
clean throughout the run.
Based on v7.2-rc2 (a635d6748234).
Changes in v2:
- Mask reserved high bits of the SBI PMU event index before comparing
against the filter, so a guest cannot bypass a DENY filter by setting
bits above bit 19. Noted by sashiko-bot review.
- Reject non-zero pad in the ioctl argument to keep the field usable
for future extensions.
Assisted-by: YuanSheng:deepseek-v4-pro
Co-developed-by: Quan Zhou <zhouquan@iscas.ac.cn>
Signed-off-by: Quan Zhou <zhouquan@iscas.ac.cn>
Signed-off-by: Yuhang.chen <yhchen312@gmail.com>
Yuhang.chen (2):
RISC-V: KVM: Add PMU event filter support
RISC-V: KVM: selftests: Add PMU event filter test
arch/riscv/include/asm/kvm_host.h | 3 +
arch/riscv/include/uapi/asm/kvm.h | 20 ++
arch/riscv/kvm/vcpu_pmu.c | 31 +++
arch/riscv/kvm/vm.c | 69 +++++-
tools/testing/selftests/kvm/Makefile.kvm | 1 +
.../kvm/riscv/pmu_event_filter_test.c | 199 ++++++++++++++++++
6 files changed, 322 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/kvm/riscv/pmu_event_filter_test.c
--
2.34.1
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH v2 1/2] RISC-V: KVM: Add PMU event filter support
2026-08-07 5:32 [PATCH v2 0/2] RISC-V: KVM: Add PMU event filter support Yuhang.chen
@ 2026-08-07 5:32 ` Yuhang.chen
2026-08-07 5:32 ` [PATCH v2 2/2] RISC-V: KVM: selftests: Add PMU event filter test Yuhang.chen
1 sibling, 0 replies; 3+ messages in thread
From: Yuhang.chen @ 2026-08-07 5:32 UTC (permalink / raw)
To: anup
Cc: atish.patra, palmer, pjw, aou, alex, pbonzini, shuah, kvm,
kvm-riscv, linux-riscv, linux-kernel, linux-kselftest, zhouquan,
Yuhang.chen
Allow userspace to restrict which SBI PMU events a guest is permitted
to program via the new VM ioctl KVM_SET_PMU_EVENT_FILTER. It takes a
struct kvm_pmu_event_filter whose events[] array holds SBI PMU event
indices encoded as (type << 16) | code. The action field selects ALLOW
(only listed events may be programmed) or DENY (listed events are
rejected); nevents == 0 clears any active filter.
The filter is enforced in kvm_riscv_vcpu_pmu_ctr_cfg_match(), where a
disallowed event fails configuration with SBI_ERR_NOT_SUPPORTED. It
governs new counter configuration only and is not retroactive. The
filter lives in struct kvm_arch, read via SRCU on the vCPU run path and
replaced under kvm->lock with synchronize_srcu_expedited(). Event
indices are masked to their valid bits before comparison, so reserved
high bits cannot bypass a DENY filter.
Advertise the feature with KVM_CAP_PMU_EVENT_FILTER.
Assisted-by: YuanSheng:deepseek-v4-pro
Co-developed-by: Quan Zhou <zhouquan@iscas.ac.cn>
Signed-off-by: Quan Zhou <zhouquan@iscas.ac.cn>
Signed-off-by: Yuhang.chen <yhchen312@gmail.com>
---
arch/riscv/include/asm/kvm_host.h | 3 ++
arch/riscv/include/uapi/asm/kvm.h | 20 +++++++++
arch/riscv/kvm/vcpu_pmu.c | 31 ++++++++++++++
arch/riscv/kvm/vm.c | 69 ++++++++++++++++++++++++++++++-
4 files changed, 122 insertions(+), 1 deletion(-)
diff --git a/arch/riscv/include/asm/kvm_host.h b/arch/riscv/include/asm/kvm_host.h
index 60017ceec9d2..1cd3d6a11057 100644
--- a/arch/riscv/include/asm/kvm_host.h
+++ b/arch/riscv/include/asm/kvm_host.h
@@ -95,6 +95,9 @@ struct kvm_arch {
/* KVM_CAP_RISCV_MP_STATE_RESET */
bool mp_state_reset;
+
+ /* KVM_SET_PMU_EVENT_FILTER */
+ struct kvm_pmu_event_filter __rcu *pmu_event_filter;
};
struct kvm_cpu_trap {
diff --git a/arch/riscv/include/uapi/asm/kvm.h b/arch/riscv/include/uapi/asm/kvm.h
index 504e73305343..da4f639fa89f 100644
--- a/arch/riscv/include/uapi/asm/kvm.h
+++ b/arch/riscv/include/uapi/asm/kvm.h
@@ -12,6 +12,7 @@
#ifndef __ASSEMBLER__
#include <linux/types.h>
+#include <linux/stddef.h>
#include <asm/bitsperlong.h>
#include <asm/ptrace.h>
@@ -396,6 +397,25 @@ struct kvm_riscv_sbi_fwft {
/* One single KVM irqchip, ie. the AIA */
#define KVM_NR_IRQCHIPS 1
+/* for KVM_CAP_PMU_EVENT_FILTER */
+#define KVM_PMU_EVENT_ALLOW 0
+#define KVM_PMU_EVENT_DENY 1
+
+/*
+ * For KVM_SET_PMU_EVENT_FILTER: restrict which SBI PMU events a guest may
+ * configure. Each @events entry is a SBI PMU event index (type in bits
+ * 19:16, code in bits 15:0). %KVM_PMU_EVENT_ALLOW permits only listed
+ * events; %KVM_PMU_EVENT_DENY rejects them. Enforced at counter
+ * configuration (SBI PMU COUNTER_CFG_MATCH), not retroactively.
+ */
+struct kvm_pmu_event_filter {
+ __u32 action;
+ __u32 nevents;
+ __u32 flags;
+ __u32 pad;
+ __DECLARE_FLEX_ARRAY(__u64, events);
+};
+
#endif
#endif /* __LINUX_KVM_RISCV_H */
diff --git a/arch/riscv/kvm/vcpu_pmu.c b/arch/riscv/kvm/vcpu_pmu.c
index bb46dcbfb24d..756040913468 100644
--- a/arch/riscv/kvm/vcpu_pmu.c
+++ b/arch/riscv/kvm/vcpu_pmu.c
@@ -733,6 +733,32 @@ int kvm_riscv_vcpu_pmu_ctr_stop(struct kvm_vcpu *vcpu, unsigned long ctr_base,
return 0;
}
+static bool kvm_riscv_pmu_event_allowed(struct kvm *kvm, unsigned long eidx)
+{
+ struct kvm_pmu_event_filter *filter;
+ bool in_list = false;
+ unsigned int i;
+
+ /* Reserved high bits must not bypass the filter. */
+ eidx &= SBI_PMU_EVENT_IDX_MASK;
+
+ filter = srcu_dereference(kvm->arch.pmu_event_filter, &kvm->srcu);
+ if (!filter)
+ return true;
+
+ for (i = 0; i < filter->nevents; i++) {
+ if ((unsigned long)filter->events[i] == eidx) {
+ in_list = true;
+ break;
+ }
+ }
+
+ /* ALLOW: permit only listed events; DENY: reject them. */
+ if (filter->action == KVM_PMU_EVENT_ALLOW)
+ return in_list;
+ return !in_list;
+}
+
int kvm_riscv_vcpu_pmu_ctr_cfg_match(struct kvm_vcpu *vcpu, unsigned long ctr_base,
unsigned long ctr_mask, unsigned long flags,
unsigned long eidx, u64 evtdata,
@@ -773,6 +799,11 @@ int kvm_riscv_vcpu_pmu_ctr_cfg_match(struct kvm_vcpu *vcpu, unsigned long ctr_ba
goto out;
}
+ if (!kvm_riscv_pmu_event_allowed(vcpu->kvm, eidx)) {
+ sbiret = SBI_ERR_NOT_SUPPORTED;
+ goto out;
+ }
+
/*
* SKIP_MATCH flag indicates the caller is aware of the assigned counter
* for this event. Just do a sanity check if it already marked used.
diff --git a/arch/riscv/kvm/vm.c b/arch/riscv/kvm/vm.c
index a9f083feeb76..a5a3a2182d1e 100644
--- a/arch/riscv/kvm/vm.c
+++ b/arch/riscv/kvm/vm.c
@@ -53,6 +53,8 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
{
kvm_destroy_vcpus(kvm);
+ kfree(srcu_dereference_check(kvm->arch.pmu_event_filter, &kvm->srcu, 1));
+
kvm_riscv_aia_destroy_vm(kvm);
}
@@ -187,6 +189,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
case KVM_CAP_MP_STATE:
case KVM_CAP_IMMEDIATE_EXIT:
case KVM_CAP_SET_GUEST_DEBUG:
+ case KVM_CAP_PMU_EVENT_FILTER:
r = 1;
break;
case KVM_CAP_NR_VCPUS:
@@ -265,7 +268,71 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap)
}
}
+#define KVM_PMU_EVENT_FILTER_MAX_EVENTS 256
+
+static int kvm_riscv_vm_ioctl_set_pmu_event_filter(struct kvm *kvm,
+ void __user *argp)
+{
+ struct kvm_pmu_event_filter __user *user_filter = argp;
+ struct kvm_pmu_event_filter *filter, tmp;
+ size_t size;
+ int r = 0;
+
+ if (copy_from_user(&tmp, user_filter, sizeof(tmp)))
+ return -EFAULT;
+
+ if (tmp.action != KVM_PMU_EVENT_ALLOW &&
+ tmp.action != KVM_PMU_EVENT_DENY)
+ return -EINVAL;
+
+ if (tmp.flags)
+ return -EINVAL;
+
+ if (tmp.pad)
+ return -EINVAL;
+
+ if (tmp.nevents > KVM_PMU_EVENT_FILTER_MAX_EVENTS)
+ return -E2BIG;
+
+ size = struct_size(filter, events, tmp.nevents);
+ filter = kzalloc(size, GFP_KERNEL_ACCOUNT);
+ if (!filter)
+ return -ENOMEM;
+
+ filter->action = tmp.action;
+ filter->nevents = tmp.nevents;
+ filter->flags = tmp.flags;
+
+ if (copy_from_user(filter->events, user_filter->events,
+ flex_array_size(filter, events, filter->nevents))) {
+ r = -EFAULT;
+ goto cleanup;
+ }
+
+ mutex_lock(&kvm->lock);
+ filter = rcu_replace_pointer(kvm->arch.pmu_event_filter, filter,
+ mutex_is_locked(&kvm->lock));
+ mutex_unlock(&kvm->lock);
+ synchronize_srcu_expedited(&kvm->srcu);
+
+cleanup:
+ kfree(filter);
+ return r;
+}
+
int kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
{
- return -EINVAL;
+ struct kvm *kvm = filp->private_data;
+ void __user *argp = (void __user *)arg;
+ int r;
+
+ switch (ioctl) {
+ case KVM_SET_PMU_EVENT_FILTER:
+ r = kvm_riscv_vm_ioctl_set_pmu_event_filter(kvm, argp);
+ break;
+ default:
+ r = -EINVAL;
+ }
+
+ return r;
}
--
2.34.1
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH v2 2/2] RISC-V: KVM: selftests: Add PMU event filter test
2026-08-07 5:32 [PATCH v2 0/2] RISC-V: KVM: Add PMU event filter support Yuhang.chen
2026-08-07 5:32 ` [PATCH v2 1/2] " Yuhang.chen
@ 2026-08-07 5:32 ` Yuhang.chen
1 sibling, 0 replies; 3+ messages in thread
From: Yuhang.chen @ 2026-08-07 5:32 UTC (permalink / raw)
To: anup
Cc: atish.patra, palmer, pjw, aou, alex, pbonzini, shuah, kvm,
kvm-riscv, linux-riscv, linux-kernel, linux-kselftest, zhouquan,
Yuhang.chen
Add a selftest that exercises KVM_SET_PMU_EVENT_FILTER on RISC-V. The
guest programs the CPU cycles and instructions SBI PMU events through
SBI_EXT_PMU_COUNTER_CFG_MATCH while the host installs filters with the
ALLOW and DENY actions, asserting that disallowed events return
SBI_ERR_NOT_SUPPORTED and allowed events succeed.
The test also validates ioctl argument rejection: an invalid action, a
non-zero flags field, and an over-large nevents value are each expected
to fail with -EINVAL or -E2BIG. A baseline run verifies PMU
availability and the test skips (KSFT_SKIP) when PMU or the filter
capability is absent.
Assisted-by: YuanSheng:deepseek-v4-pro
Co-developed-by: Quan Zhou <zhouquan@iscas.ac.cn>
Signed-off-by: Quan Zhou <zhouquan@iscas.ac.cn>
Signed-off-by: Yuhang.chen <yhchen312@gmail.com>
---
tools/testing/selftests/kvm/Makefile.kvm | 1 +
.../kvm/riscv/pmu_event_filter_test.c | 199 ++++++++++++++++++
2 files changed, 200 insertions(+)
create mode 100644 tools/testing/selftests/kvm/riscv/pmu_event_filter_test.c
diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selftests/kvm/Makefile.kvm
index d28a057fa6c2..5d2dc3b25eac 100644
--- a/tools/testing/selftests/kvm/Makefile.kvm
+++ b/tools/testing/selftests/kvm/Makefile.kvm
@@ -218,6 +218,7 @@ TEST_GEN_PROGS_s390 += pre_fault_memory_test
TEST_GEN_PROGS_riscv = $(TEST_GEN_PROGS_COMMON)
TEST_GEN_PROGS_riscv += riscv/sbi_pmu_test
TEST_GEN_PROGS_riscv += riscv/ebreak_test
+TEST_GEN_PROGS_riscv += riscv/pmu_event_filter_test
TEST_GEN_PROGS_riscv += access_tracking_perf_test
TEST_GEN_PROGS_riscv += arch_timer
TEST_GEN_PROGS_riscv += coalesced_io_test
diff --git a/tools/testing/selftests/kvm/riscv/pmu_event_filter_test.c b/tools/testing/selftests/kvm/riscv/pmu_event_filter_test.c
new file mode 100644
index 000000000000..1a76fce2aca6
--- /dev/null
+++ b/tools/testing/selftests/kvm/riscv/pmu_event_filter_test.c
@@ -0,0 +1,199 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Test for RISC-V KVM_SET_PMU_EVENT_FILTER.
+ *
+ * Verify that a VM-scoped PMU event filter installed via the
+ * KVM_SET_PMU_EVENT_FILTER ioctl is enforced when a guest configures a
+ * counter through the SBI PMU COUNTER_CFG_MATCH call:
+ *
+ * - with no filter, events are programmable (baseline / PMU probe);
+ * - KVM_PMU_EVENT_DENY rejects the listed events;
+ * - KVM_PMU_EVENT_ALLOW admits only the listed events;
+ * - replacing the filter with an empty DENY list re-enables everything.
+ *
+ * The filter is checked before any perf event is created, so the test only
+ * ever programs the cycle event (always supported by the host PMU) and varies
+ * the filter *list* contents to exercise membership without depending on host
+ * support for other events. Counter management and SBI error reporting happen
+ * in the guest; the host installs filters and checks the reported errors.
+ */
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "kvm_util.h"
+#include "test_util.h"
+#include "processor.h"
+#include "ucall_common.h"
+#include "sbi.h"
+
+/* SBI PMU hardware event indexes (type == HW == 0, so eidx == code). */
+#define EV_CYCLES SBI_PMU_HW_CPU_CYCLES /* 1 */
+#define EV_INSTR SBI_PMU_HW_INSTRUCTIONS /* 2 */
+
+/* Must match KVM_PMU_EVENT_FILTER_MAX_EVENTS in arch/riscv/kvm/vm.c. */
+#define MAX_EVENTS 256
+
+static void guest_code(void)
+{
+ struct sbiret ret;
+ unsigned long ctr;
+ long err;
+
+ for (;;) {
+ /*
+ * Request the fixed cycle counter (cbase=0, cmask=1) for the
+ * cycle event. The host installs (or clears) the filter
+ * before each entry, so the result reflects the active policy.
+ */
+ ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_CFG_MATCH,
+ 0, 1, 0, EV_CYCLES, 0, 0);
+ err = ret.error;
+ ctr = ret.value;
+
+ /* Release the counter on success so the next iteration reuses it. */
+ if (!err)
+ sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_STOP,
+ ctr, 1, SBI_PMU_STOP_FLAG_RESET, 0, 0, 0);
+
+ GUEST_SYNC1(err);
+ }
+}
+
+static struct kvm_pmu_event_filter *
+build_filter(__u32 action, __u32 flags, const __u64 *events, __u32 nevents)
+{
+ struct kvm_pmu_event_filter *f;
+ size_t size = sizeof(*f) + (size_t)nevents * sizeof(__u64);
+
+ f = calloc(1, size);
+ TEST_ASSERT(f, "calloc(pmu_event_filter)");
+ f->action = action;
+ f->nevents = nevents;
+ f->flags = flags;
+ if (nevents && events)
+ memcpy(f->events, events, nevents * sizeof(__u64));
+ return f;
+}
+
+/* Install a filter, asserting success. */
+static void set_filter(struct kvm_vm *vm, __u32 action,
+ const __u64 *events, __u32 nevents)
+{
+ struct kvm_pmu_event_filter *f = build_filter(action, 0, events, nevents);
+
+ vm_ioctl(vm, KVM_SET_PMU_EVENT_FILTER, f);
+ free(f);
+}
+
+/* Install a filter and return the raw ioctl result (for negative tests). */
+static int try_set_filter(struct kvm_vm *vm, __u32 action, __u32 flags,
+ const __u64 *events, __u32 nevents)
+{
+ struct kvm_pmu_event_filter *f = build_filter(action, flags, events, nevents);
+ int ret = __vm_ioctl(vm, KVM_SET_PMU_EVENT_FILTER, f);
+
+ free(f);
+ return ret;
+}
+
+/* Run the guest one step and return the cfg_match error code it reports. */
+static long run_one(struct kvm_vcpu *vcpu)
+{
+ struct ucall uc;
+
+ vcpu_run(vcpu);
+ TEST_ASSERT_EQ(get_ucall(vcpu, &uc), UCALL_SYNC);
+ return (long)uc.args[0];
+}
+
+static void test_filter_case(struct kvm_vm *vm, struct kvm_vcpu *vcpu,
+ __u32 action, const __u64 *events, __u32 nevents,
+ long expect, const char *desc)
+{
+ long err;
+
+ set_filter(vm, action, events, nevents);
+ err = run_one(vcpu);
+ TEST_ASSERT_EQ(err, expect);
+ pr_info("%s: err=%ld (expected %ld)\n", desc, err, expect);
+}
+
+static void test_bad_args(struct kvm_vm *vm)
+{
+ __u64 ev = EV_CYCLES;
+ int ret;
+
+ /* Invalid action. */
+ errno = 0;
+ ret = try_set_filter(vm, 2, 0, &ev, 1);
+ TEST_ASSERT(ret < 0 && errno == EINVAL,
+ "invalid action should fail with EINVAL, got ret=%d errno=%d",
+ ret, errno);
+
+ /* Non-zero flags are not supported. */
+ errno = 0;
+ ret = try_set_filter(vm, KVM_PMU_EVENT_ALLOW, 1, &ev, 1);
+ TEST_ASSERT(ret < 0 && errno == EINVAL,
+ "non-zero flags should fail with EINVAL, got ret=%d errno=%d",
+ ret, errno);
+
+ /* Too many events. */
+ errno = 0;
+ ret = try_set_filter(vm, KVM_PMU_EVENT_DENY, 0, NULL, MAX_EVENTS + 1);
+ TEST_ASSERT(ret < 0 && errno == E2BIG,
+ "nevents > max should fail with E2BIG, got ret=%d errno=%d",
+ ret, errno);
+}
+
+int main(void)
+{
+ struct kvm_vm *vm;
+ struct kvm_vcpu *vcpu;
+ long err;
+
+ TEST_REQUIRE(kvm_has_cap(KVM_CAP_PMU_EVENT_FILTER));
+
+ vm = vm_create_with_one_vcpu(&vcpu, guest_code);
+
+ /*
+ * Baseline / PMU probe: with no filter the cycle event must be
+ * programmable. If it isn't, the host PMU is unusable in this
+ * environment (e.g. Sscofpmf unavailable under TCG); skip the rest.
+ */
+ err = run_one(vcpu);
+ if (err) {
+ pr_info("PMU unavailable (baseline cfg_match err=%ld), skipping\n",
+ err);
+ kvm_vm_free(vm);
+ exit(KSFT_SKIP);
+ }
+
+ /* DENY{cycles}: the cycle event is rejected. */
+ test_filter_case(vm, vcpu, KVM_PMU_EVENT_DENY,
+ &(__u64){ EV_CYCLES }, 1,
+ SBI_ERR_NOT_SUPPORTED, "deny cycles");
+
+ /* ALLOW{cycles}: the cycle event is admitted. */
+ test_filter_case(vm, vcpu, KVM_PMU_EVENT_ALLOW,
+ &(__u64){ EV_CYCLES }, 1,
+ 0, "allow cycles");
+
+ /*
+ * ALLOW{instructions}: cycles is not in the allow list, so it is
+ * rejected. Instructions itself is never programmed, so host support
+ * for it is irrelevant.
+ */
+ test_filter_case(vm, vcpu, KVM_PMU_EVENT_ALLOW,
+ &(__u64){ EV_INSTR }, 1,
+ SBI_ERR_NOT_SUPPORTED, "cycles not in allow{instr}");
+
+ /* Empty DENY list: nothing is denied, cycles is programmable again. */
+ test_filter_case(vm, vcpu, KVM_PMU_EVENT_DENY, NULL, 0,
+ 0, "clear (deny empty)");
+
+ test_bad_args(vm);
+
+ kvm_vm_free(vm);
+ return 0;
+}
--
2.34.1
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-08-07 5:33 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-07 5:32 [PATCH v2 0/2] RISC-V: KVM: Add PMU event filter support Yuhang.chen
2026-08-07 5:32 ` [PATCH v2 1/2] " Yuhang.chen
2026-08-07 5:32 ` [PATCH v2 2/2] RISC-V: KVM: selftests: Add PMU event filter test Yuhang.chen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox