From: Zhao Liu <zhao1.liu@intel.com>
To: "Paolo Bonzini" <pbonzini@redhat.com>,
"Eric Blake" <eblake@redhat.com>,
"Markus Armbruster" <armbru@redhat.com>,
"Michael Roth" <michael.roth@amd.com>,
"Daniel P . Berrangé" <berrange@redhat.com>,
"Eduardo Habkost" <eduardo@habkost.net>,
"Marcelo Tosatti" <mtosatti@redhat.com>,
"Shaoqin Huang" <shahuang@redhat.com>,
"Eric Auger" <eauger@redhat.com>,
"Peter Maydell" <peter.maydell@linaro.org>,
"Laurent Vivier" <lvivier@redhat.com>,
"Thomas Huth" <thuth@redhat.com>,
"Sebastian Ott" <sebott@redhat.com>,
"Gavin Shan" <gshan@redhat.com>
Cc: qemu-devel@nongnu.org, kvm@vger.kernel.org, qemu-arm@nongnu.org,
Dapeng Mi <dapeng1.mi@intel.com>, Yi Lai <yi1.lai@intel.com>,
Zhao Liu <zhao1.liu@intel.com>
Subject: [PATCH 1/5] qapi/qom: Introduce kvm-pmu-filter object
Date: Wed, 9 Apr 2025 16:26:45 +0800 [thread overview]
Message-ID: <20250409082649.14733-2-zhao1.liu@intel.com> (raw)
In-Reply-To: <20250409082649.14733-1-zhao1.liu@intel.com>
Introduce the kvm-pmu-filter object and support the PMU event with raw
format.
The raw format, as a native PMU event code representation, can be used
for several architectures.
Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
Tested-by: Yi Lai <yi1.lai@intel.com>
---
Changes since RFC v2:
* Drop hexadecimal variants and support numeric version in QAPI
directly. (Daniel)
* Define three-level sections with new accelerator.json. (Markus)
* QAPI style fixes:
- KVMPMU* stuff -> KvmPmu*.
- KVMPMUFilterProperty -> KVMPMUFilterProperties.
- KVMPMUEventEncodeFmt -> KvmPmuEventFormat.
- drop prefix in KvmPmuFilterAction and KvmPmuEventFormat.
* Bump up the supported QAPI version to v10.1.
* Add Tested-by from Yi.
Changes since RFC v1:
* Make "action" as a global (per filter object) item, not a per-event
parameter. (Dapeng)
* Bump up the supported QAPI version to v10.0.
---
MAINTAINERS | 2 +
accel/kvm/kvm-pmu.c | 114 +++++++++++++++++++++++++++++++++++++++
accel/kvm/meson.build | 1 +
include/system/kvm-pmu.h | 35 ++++++++++++
qapi/accelerator.json | 14 +++++
qapi/kvm.json | 84 +++++++++++++++++++++++++++++
qapi/meson.build | 1 +
qapi/qapi-schema.json | 1 +
qapi/qom.json | 3 ++
9 files changed, 255 insertions(+)
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
diff --git a/MAINTAINERS b/MAINTAINERS
index d54b5578f883..3ca551025fb8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -434,6 +434,7 @@ F: accel/kvm/
F: accel/stubs/kvm-stub.c
F: include/hw/kvm/
F: include/system/kvm*.h
+F: qapi/kvm.json
F: scripts/kvm/kvm_flightrecorder
ARM KVM CPUs
@@ -503,6 +504,7 @@ F: accel/Makefile.objs
F: accel/stubs/Makefile.objs
F: cpu-common.c
F: cpu-target.c
+F: qapi/accelerator.c
F: system/cpus.c
Apple Silicon HVF CPUs
diff --git a/accel/kvm/kvm-pmu.c b/accel/kvm/kvm-pmu.c
new file mode 100644
index 000000000000..22f749bf9183
--- /dev/null
+++ b/accel/kvm/kvm-pmu.c
@@ -0,0 +1,114 @@
+/*
+ * QEMU KVM PMU Related Abstractions
+ *
+ * Copyright (C) 2025 Intel Corporation.
+ *
+ * Author: Zhao Liu <zhao1.liu@intel.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+
+#include "qapi/error.h"
+#include "qapi/qapi-visit-kvm.h"
+#include "qemu/cutils.h"
+#include "qom/object_interfaces.h"
+#include "system/kvm-pmu.h"
+
+static void kvm_pmu_filter_set_action(Object *obj, int value,
+ Error **errp G_GNUC_UNUSED)
+{
+ KVMPMUFilter *filter = KVM_PMU_FILTER(obj);
+
+ filter->action = value;
+}
+
+static int kvm_pmu_filter_get_action(Object *obj,
+ Error **errp G_GNUC_UNUSED)
+{
+ KVMPMUFilter *filter = KVM_PMU_FILTER(obj);
+
+ return filter->action;
+}
+
+static void kvm_pmu_filter_get_event(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ KVMPMUFilter *filter = KVM_PMU_FILTER(obj);
+
+ visit_type_KvmPmuFilterEventList(v, name, &filter->events, errp);
+}
+
+static void kvm_pmu_filter_set_event(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ KVMPMUFilter *filter = KVM_PMU_FILTER(obj);
+ KvmPmuFilterEventList *head = NULL, *old_head, *node;
+ int nevents = 0;
+
+ old_head = filter->events;
+ if (!visit_type_KvmPmuFilterEventList(v, name, &head, errp)) {
+ return;
+ }
+
+ for (node = head; node; node = node->next) {
+ switch (node->value->format) {
+ case KVM_PMU_EVENT_FORMAT_RAW:
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ nevents++;
+ }
+
+ filter->nevents = nevents;
+ filter->events = head;
+ qapi_free_KvmPmuFilterEventList(old_head);
+ return;
+}
+
+static void kvm_pmu_filter_class_init(ObjectClass *oc, void *data)
+{
+ object_class_property_add_enum(oc, "action", "KvmPmuFilterAction",
+ &KvmPmuFilterAction_lookup,
+ kvm_pmu_filter_get_action,
+ kvm_pmu_filter_set_action);
+ object_class_property_set_description(oc, "action",
+ "KVM PMU event action");
+
+ object_class_property_add(oc, "events", "KvmPmuFilterEventList",
+ kvm_pmu_filter_get_event,
+ kvm_pmu_filter_set_event,
+ NULL, NULL);
+ object_class_property_set_description(oc, "events",
+ "KVM PMU event list");
+}
+
+static void kvm_pmu_filter_instance_init(Object *obj)
+{
+ KVMPMUFilter *filter = KVM_PMU_FILTER(obj);
+
+ filter->action = KVM_PMU_FILTER_ACTION_ALLOW;
+ filter->nevents = 0;
+}
+
+static const TypeInfo kvm_pmu_filter_info = {
+ .parent = TYPE_OBJECT,
+ .name = TYPE_KVM_PMU_FILTER,
+ .class_init = kvm_pmu_filter_class_init,
+ .instance_size = sizeof(KVMPMUFilter),
+ .instance_init = kvm_pmu_filter_instance_init,
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_USER_CREATABLE },
+ { }
+ }
+};
+
+static void kvm_pmu_event_register_type(void)
+{
+ type_register_static(&kvm_pmu_filter_info);
+}
+
+type_init(kvm_pmu_event_register_type);
diff --git a/accel/kvm/meson.build b/accel/kvm/meson.build
index 397a1fe1fd1e..dfab2854f3a8 100644
--- a/accel/kvm/meson.build
+++ b/accel/kvm/meson.build
@@ -2,6 +2,7 @@ kvm_ss = ss.source_set()
kvm_ss.add(files(
'kvm-all.c',
'kvm-accel-ops.c',
+ 'kvm-pmu.c',
))
specific_ss.add_all(when: 'CONFIG_KVM', if_true: kvm_ss)
diff --git a/include/system/kvm-pmu.h b/include/system/kvm-pmu.h
new file mode 100644
index 000000000000..818fa309c191
--- /dev/null
+++ b/include/system/kvm-pmu.h
@@ -0,0 +1,35 @@
+/*
+ * QEMU KVM PMU Related Abstraction Header
+ *
+ * Copyright (C) 2025 Intel Corporation.
+ *
+ * Author: Zhao Liu <zhao1.liu@intel.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef KVM_PMU_H
+#define KVM_PMU_H
+
+#include "qapi/qapi-types-kvm.h"
+#include "qom/object.h"
+
+#define TYPE_KVM_PMU_FILTER "kvm-pmu-filter"
+OBJECT_DECLARE_SIMPLE_TYPE(KVMPMUFilter, KVM_PMU_FILTER)
+
+/**
+ * KVMPMUFilter:
+ * @action: action that KVM PMU filter will take for selected PMU events.
+ * @nevents: number of PMU event entries listed in @events
+ * @events: list of PMU event entries. A PMU event entry may represent one
+ * event or multiple events due to its format.
+ */
+struct KVMPMUFilter {
+ Object parent_obj;
+
+ KvmPmuFilterAction action;
+ uint32_t nevents;
+ KvmPmuFilterEventList *events;
+};
+
+#endif /* KVM_PMU_H */
diff --git a/qapi/accelerator.json b/qapi/accelerator.json
new file mode 100644
index 000000000000..1fe0d64be113
--- /dev/null
+++ b/qapi/accelerator.json
@@ -0,0 +1,14 @@
+# -*- Mode: Python -*-
+# vim: filetype=python
+#
+# Copyright (C) 2025 Intel Corporation.
+#
+# Author: Zhao Liu <zhao1.liu@intel.com>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+##
+# = Accelerators
+##
+
+{ 'include': 'kvm.json' }
diff --git a/qapi/kvm.json b/qapi/kvm.json
new file mode 100644
index 000000000000..1861d86a9726
--- /dev/null
+++ b/qapi/kvm.json
@@ -0,0 +1,84 @@
+# -*- Mode: Python -*-
+# vim: filetype=python
+#
+# Copyright (C) 2025 Intel Corporation.
+#
+# Author: Zhao Liu <zhao1.liu@intel.com>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+##
+# == KVM
+##
+
+##
+# === PMU stuff (KVM related)
+##
+
+##
+# @KvmPmuFilterAction:
+#
+# Actions that KVM PMU filter supports.
+#
+# @deny: disable the PMU event/counter in KVM PMU filter.
+#
+# @allow: enable the PMU event/counter in KVM PMU filter.
+#
+# Since 10.1
+##
+{ 'enum': 'KvmPmuFilterAction',
+ 'data': ['allow', 'deny'] }
+
+##
+# @KvmPmuEventFormat:
+#
+# Encoding formats of PMU event that QEMU/KVM supports.
+#
+# @raw: the encoded event code that KVM can directly consume.
+#
+# Since 10.1
+##
+{ 'enum': 'KvmPmuEventFormat',
+ 'data': ['raw'] }
+
+##
+# @KvmPmuRawEvent:
+#
+# Raw PMU event code.
+#
+# @code: the raw value that has been encoded, and QEMU could deliver
+# to KVM directly.
+#
+# Since 10.1
+##
+{ 'struct': 'KvmPmuRawEvent',
+ 'data': { 'code': 'uint64' } }
+
+##
+# @KvmPmuFilterEvent:
+#
+# PMU event filtered by KVM.
+#
+# @format: PMU event format.
+#
+# Since 10.1
+##
+{ 'union': 'KvmPmuFilterEvent',
+ 'base': { 'format': 'KvmPmuEventFormat' },
+ 'discriminator': 'format',
+ 'data': { 'raw': 'KvmPmuRawEvent' } }
+
+##
+# @KvmPmuFilterProperties:
+#
+# Properties of KVM PMU Filter.
+#
+# @action: action that KVM PMU filter will take for selected PMU events.
+#
+# @events: list of selected PMU events.
+#
+# Since 10.1
+##
+{ 'struct': 'KvmPmuFilterProperties',
+ 'data': { 'action': 'KvmPmuFilterAction',
+ '*events': ['KvmPmuFilterEvent'] } }
diff --git a/qapi/meson.build b/qapi/meson.build
index eadde4db307f..dba27ebc7489 100644
--- a/qapi/meson.build
+++ b/qapi/meson.build
@@ -37,6 +37,7 @@ qapi_all_modules = [
'error',
'introspect',
'job',
+ 'kvm',
'machine-common',
'machine',
'machine-target',
diff --git a/qapi/qapi-schema.json b/qapi/qapi-schema.json
index c41c01eb2ab9..c7fed7940af7 100644
--- a/qapi/qapi-schema.json
+++ b/qapi/qapi-schema.json
@@ -66,6 +66,7 @@
{ 'include': 'compat.json' }
{ 'include': 'control.json' }
{ 'include': 'introspect.json' }
+{ 'include': 'accelerator.json' }
{ 'include': 'qom.json' }
{ 'include': 'qdev.json' }
{ 'include': 'machine-common.json' }
diff --git a/qapi/qom.json b/qapi/qom.json
index 28ce24cd8d08..517f4c06c260 100644
--- a/qapi/qom.json
+++ b/qapi/qom.json
@@ -8,6 +8,7 @@
{ 'include': 'block-core.json' }
{ 'include': 'common.json' }
{ 'include': 'crypto.json' }
+{ 'include': 'kvm.json' }
##
# = QEMU Object Model (QOM)
@@ -1108,6 +1109,7 @@
'if': 'CONFIG_LINUX' },
'iommufd',
'iothread',
+ 'kvm-pmu-filter',
'main-loop',
{ 'name': 'memory-backend-epc',
'if': 'CONFIG_LINUX' },
@@ -1183,6 +1185,7 @@
'if': 'CONFIG_LINUX' },
'iommufd': 'IOMMUFDProperties',
'iothread': 'IothreadProperties',
+ 'kvm-pmu-filter': 'KvmPmuFilterProperties',
'main-loop': 'MainLoopProperties',
'memory-backend-epc': { 'type': 'MemoryBackendEpcProperties',
'if': 'CONFIG_LINUX' },
--
2.34.1
next prev parent reply other threads:[~2025-04-09 8:08 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-04-09 8:26 [PATCH 0/5] accel/kvm: Support KVM PMU filter Zhao Liu
2025-04-09 8:26 ` Zhao Liu [this message]
2025-04-10 14:21 ` [PATCH 1/5] qapi/qom: Introduce kvm-pmu-filter object Markus Armbruster
2025-04-11 4:03 ` Zhao Liu
2025-04-11 4:38 ` Markus Armbruster
2025-04-11 6:34 ` Zhao Liu
2025-04-16 8:17 ` Markus Armbruster
2025-04-24 6:33 ` Zhao Liu
2025-04-25 10:35 ` Philippe Mathieu-Daudé
2025-04-27 7:26 ` Zhao Liu
2025-04-24 12:18 ` Markus Armbruster
2025-04-24 15:34 ` Zhao Liu
2025-04-25 9:19 ` Markus Armbruster
2025-04-09 8:26 ` [PATCH 2/5] i386/kvm: Support basic KVM PMU filter Zhao Liu
2025-04-25 9:19 ` Markus Armbruster
2025-04-27 8:34 ` Zhao Liu
2025-04-28 6:12 ` Markus Armbruster
2025-04-28 14:12 ` Zhao Liu
2025-04-09 8:26 ` [PATCH 3/5] i386/kvm: Support event with select & umask format in " Zhao Liu
2025-04-25 9:33 ` Markus Armbruster
2025-04-27 6:49 ` Zhao Liu
2025-04-28 7:19 ` Markus Armbruster
2025-04-28 14:42 ` Zhao Liu
2025-04-28 16:24 ` Markus Armbruster
2025-04-29 6:24 ` Zhao Liu
2025-04-09 8:26 ` [PATCH 4/5] i386/kvm: Support event with masked entry " Zhao Liu
2025-04-25 9:37 ` Markus Armbruster
2025-04-09 8:26 ` [PATCH 5/5] i386/kvm: Support fixed counter " Zhao Liu
2025-04-24 8:17 ` Mi, Dapeng
2025-04-24 15:35 ` Zhao Liu
2025-04-25 10:32 ` Philippe Mathieu-Daudé
2025-04-27 7:35 ` Zhao Liu
2025-04-15 7:49 ` [PATCH 0/5] accel/kvm: Support " Shaoqin Huang
2025-04-15 9:59 ` Zhao Liu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250409082649.14733-2-zhao1.liu@intel.com \
--to=zhao1.liu@intel.com \
--cc=armbru@redhat.com \
--cc=berrange@redhat.com \
--cc=dapeng1.mi@intel.com \
--cc=eauger@redhat.com \
--cc=eblake@redhat.com \
--cc=eduardo@habkost.net \
--cc=gshan@redhat.com \
--cc=kvm@vger.kernel.org \
--cc=lvivier@redhat.com \
--cc=michael.roth@amd.com \
--cc=mtosatti@redhat.com \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=sebott@redhat.com \
--cc=shahuang@redhat.com \
--cc=thuth@redhat.com \
--cc=yi1.lai@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).