Hi Zhao,
I've added some code and test it on ARM64, it works very well.
And after reviewing the code, it looks good to me.
Reviewed-by: Shaoqin Huang <shahuang@redhat.com>
On 4/9/25 4:26 PM, Zhao Liu wrote:
> Hi all,
>
> Now I've converted the previous RFC (v2) to PATCH.
>
> Compared with RFC v2 [1], this version mianly have the following
> changes:
> * Make PMU related QAPIs accept decimal value instead of string.
> * Introduce a three-level QAPI section to organize KVM PMU stuff.
> * Fix QAPI related style issues.
> * Rename "x86-default" format to "x86-select-umask".
>
> Current pmu-filter QOM design could meet the requirements of both x86
> and ARM sides.
>
>
> Background
> ==========
>
> I picked up Shaoqing's previous work [2] on the KVM PMU filter for arm,
> and now is trying to support this feature for x86 with a JSON-compatible
> API.
>
> While arm and x86 use different KVM ioctls to configure the PMU filter,
> considering they all have similar inputs (PMU event + action), it is
> still possible to abstract a generic, cross-architecture kvm-pmu-filter
> object and provide users with a sufficiently generic or near-consistent
> QAPI interface.
>
> That's what I did in this series, a new kvm-pmu-filter object, with the
> API like:
>
> -object '{"qom-type":"kvm-pmu-filter","id":"f0","action":"allow","events":[{"format":"raw","code":196}]}'
>
> For x86, this object is inserted into kvm accelerator and is extended
> to support fixed-counter and more formats ("x86-default" and
> "x86-masked-entry"):
>
> -accel kvm,pmu-filter=f0 \
> -object '{"qom-type":"kvm-pmu-filter","id":"f0","action":"allow","x86-fixed-counter":0,"events":[{"format":"x86-masked-entry","select":196,"mask":255,"match":0,"exclude":true},{"format":"x86-masked-entry","select":197,"mask":255,"match":0,"exclude":true}]}'
>
> This object can still be added as the property to the arch CPU if it is
> desired as a per CPU feature (as Shaoqin did for arm before).
>
>
> Introduction
> ============
>
>
> Formats supported in kvm-pmu-filter
> -----------------------------------
>
> This series supports 3 formats:
>
> * raw format (general format).
>
> This format indicates the code that has been encoded to be able to
> index the PMU events, and which can be delivered directly to the KVM
> ioctl. For arm, this means the event code, and for i386, this means
> the raw event with the layout like:
>
> select high bit | umask | select low bits
>
> * x86-select-umask format (i386 specific)
>
> x86 commonly uses select&umask to identify PMU events, and this format
> is used to support the select&umask. Then QEMU will encode select and
> umask into a raw format code.
>
> * x86-masked-entry (i386 specific)
>
> This is a special format that x86's KVM_SET_PMU_EVENT_FILTER supports.
>
>
> CPU property v.s. KVM property
> ------------------------------
>
> In Shaoqin's previous implementation [2], KVM PMU filter is made as a
> arm CPU property. This is because arm uses a per CPU ioctl
> (KVM_SET_DEVICE_ATTR) to configure KVM PMU filter.
>
> However, for x86, the dependent ioctl (KVM_SET_PMU_EVENT_FILTER) is per
> VM. In the meantime, considering that for hybrid architecture, maybe in
> the future there will be a new per vCPU ioctl, or there will be
> practices to support filter fixed counter by configuring CPUIDs.
>
> Based on the above thoughts, for x86, it is not appropriate to make the
> current per-VM ioctl-based PMU filter a CPU property. Instead, I make it
> a kvm property and configure it via "-accel kvm,pmu-filter=obj_id".
>
> So in summary, it is feasible to use the KVM PMU filter as either a CPU
> or a KVM property, depending on whether it is used as a CPU feature or a
> VM feature.
>
> The kvm-pmu-filter object, as an abstraction, is general enough to
> support filter configurations for different scopes (per-CPU or per-VM).
>
> [1]: https://lore.kernel.org/qemu-devel/20250122090517.294083-1-zhao1.liu@intel.com/
> [2]: https://lore.kernel.org/qemu-devel/20240409024940.180107-1-shahuang@redhat.com/
>
> Thanks and Best Regards,
> Zhao
> ---
> Zhao Liu (5):
> qapi/qom: Introduce kvm-pmu-filter object
> i386/kvm: Support basic KVM PMU filter
> i386/kvm: Support event with select & umask format in KVM PMU filter
> i386/kvm: Support event with masked entry format in KVM PMU filter
> i386/kvm: Support fixed counter in KVM PMU filter
>
> MAINTAINERS | 2 +
> accel/kvm/kvm-pmu.c | 177 +++++++++++++++++++++++++++++++++++++++
> accel/kvm/meson.build | 1 +
> include/system/kvm-pmu.h | 51 +++++++++++
> include/system/kvm_int.h | 2 +
> qapi/accelerator.json | 14 ++++
> qapi/kvm.json | 130 ++++++++++++++++++++++++++++
> qapi/meson.build | 1 +
> qapi/qapi-schema.json | 1 +
> qapi/qom.json | 3 +
> qemu-options.hx | 67 ++++++++++++++-
> target/i386/kvm/kvm.c | 176 ++++++++++++++++++++++++++++++++++++++
> 12 files changed, 624 insertions(+), 1 deletion(-)
> create mode 100644 accel/kvm/kvm-pmu.c
> create mode 100644 include/system/kvm-pmu.h
> create mode 100644 qapi/accelerator.json
> create mode 100644 qapi/kvm.json
>
--
Shaoqin