diff mbox series

[RFC,2/2] KVM: arm64: vgic-its: Add tracepoints for VGIC ITS commands

Message ID 20250113193128.1533449-3-jingzhangos@google.com (mailing list archive)
State New
Headers show
Series KVM: arm64: vgic-its: Enhance debugging with debugfs and tracepoints | expand

Commit Message

Jing Zhang Jan. 13, 2025, 7:31 p.m. UTC
This commit adds tracepoints to the KVM VGIC ITS on ARM64 to improve
observability and debuggability. The following ITS commands now have
associated tracepoints: MAPI, DISCARD, CLEAR, INT, INV, MAPD, MAPC,
MOVI, MOVALL, and INVALL.

Each tracepoint captures essential information such as device ID, event
ID, and other relevant parameters, allowing for detailed monitoring of
ITS operations.

These tracepoints are useful for:

*   Debugging interrupt routing issues.
*   Performance analysis and optimization.
*   Understanding ITS behavior.
*   Root-causing interrupt handling errors.

This enhancement provides crucial insights into interrupt handling in
ARM64 virtualized environments, aiding in development, debugging, and
maintenance.

Signed-off-by: Jing Zhang <jingzhangos@google.com>
---
 arch/arm64/kvm/vgic/trace.h    | 135 +++++++++++++++++++++++++++++++++
 arch/arm64/kvm/vgic/vgic-its.c |  19 +++++
 2 files changed, 154 insertions(+)
diff mbox series

Patch

diff --git a/arch/arm64/kvm/vgic/trace.h b/arch/arm64/kvm/vgic/trace.h
index 83c64401a7fc..22953c0ef159 100644
--- a/arch/arm64/kvm/vgic/trace.h
+++ b/arch/arm64/kvm/vgic/trace.h
@@ -27,6 +27,141 @@  TRACE_EVENT(vgic_update_irq_pending,
 		  __entry->vcpu_id, __entry->irq, __entry->level)
 );
 
+DECLARE_EVENT_CLASS(vgic_its_cmd_class,
+	TP_PROTO(__u32 device_id, __u32 event_id),
+	TP_ARGS(device_id, event_id),
+
+	TP_STRUCT__entry(
+		__field(	__u32,		device_id		)
+		__field(	__u32,		event_id		)
+	),
+
+	TP_fast_assign(
+		__entry->device_id		= device_id;
+		__entry->event_id		= event_id;
+	),
+
+	TP_printk("Device ID: %u, Event ID: %u",
+		  __entry->device_id, __entry->event_id)
+);
+
+DEFINE_EVENT(vgic_its_cmd_class, vgic_its_cmd_mapi,
+	TP_PROTO(__u32 device_id, __u32 event_id),
+	TP_ARGS(device_id, event_id));
+
+DEFINE_EVENT(vgic_its_cmd_class, vgic_its_cmd_discard,
+	TP_PROTO(__u32 device_id, __u32 event_id),
+	TP_ARGS(device_id, event_id));
+
+DEFINE_EVENT(vgic_its_cmd_class, vgic_its_cmd_clear,
+	TP_PROTO(__u32 device_id, __u32 event_id),
+	TP_ARGS(device_id, event_id));
+
+DEFINE_EVENT(vgic_its_cmd_class, vgic_its_cmd_int,
+	TP_PROTO(__u32 device_id, __u32 event_id),
+	TP_ARGS(device_id, event_id));
+
+DEFINE_EVENT(vgic_its_cmd_class, vgic_its_cmd_inv,
+	TP_PROTO(__u32 device_id, __u32 event_id),
+	TP_ARGS(device_id, event_id));
+
+TRACE_EVENT(vgic_its_cmd_mapd,
+	TP_PROTO(__u32 device_id, bool valid, __u8 num_eventid_bits, __u64 itt_addr),
+	TP_ARGS(device_id, valid, num_eventid_bits, itt_addr),
+
+	TP_STRUCT__entry(
+		__field(	__u32,		device_id		)
+		__field(	bool,		valid			)
+		__field(	__u8,		num_eventid_bits	)
+		__field(	__u64,		itt_addr		)
+	),
+
+	TP_fast_assign(
+		__entry->device_id		= device_id;
+		__entry->valid			= valid;
+		__entry->num_eventid_bits	= num_eventid_bits;
+		__entry->itt_addr		= itt_addr;
+	),
+
+	TP_printk("Device ID: %u, valid: %d, num_eventid_bits: %u, itt_addr: %llx",
+		  __entry->device_id, __entry->valid,
+		  __entry->num_eventid_bits, __entry->itt_addr)
+);
+
+TRACE_EVENT(vgic_its_cmd_mapc,
+	TP_PROTO(__u32 collection_id, bool valid),
+	TP_ARGS(collection_id, valid),
+
+	TP_STRUCT__entry(
+		__field(	__u32,		collection_id		)
+		__field(	bool,		valid			)
+	),
+
+	TP_fast_assign(
+		__entry->collection_id		= collection_id;
+		__entry->valid			= valid;
+	),
+
+	TP_printk("Collection ID: %u, valid: %d",
+		  __entry->collection_id, __entry->valid)
+);
+
+TRACE_EVENT(vgic_its_cmd_movi,
+	TP_PROTO(__u32 device_id, __u32 event_id, __u32 collection_id),
+	TP_ARGS(device_id, event_id, collection_id),
+
+	TP_STRUCT__entry(
+		__field(	__u32,		device_id		)
+		__field(	__u32,		event_id		)
+		__field(	__u32,		collection_id		)
+	),
+
+	TP_fast_assign(
+		__entry->device_id		= device_id;
+		__entry->event_id		= event_id;
+		__entry->collection_id		= collection_id;
+	),
+
+	TP_printk("Device ID: %u, Event ID: %u, Collection ID: %u",
+		  __entry->device_id, __entry->event_id, __entry->collection_id)
+);
+
+TRACE_EVENT(vgic_its_cmd_movall,
+	TP_PROTO(int vcpu_source, int vcpu_target),
+	TP_ARGS(vcpu_source, vcpu_target),
+
+	TP_STRUCT__entry(
+		__field(	int,		vcpu_source		)
+		__field(	int,		vcpu_target		)
+	),
+
+	TP_fast_assign(
+		__entry->vcpu_source		= vcpu_source;
+		__entry->vcpu_target		= vcpu_target;
+	),
+
+	TP_printk("Source VCPU: %d, Target VCPU: %d",
+		  __entry->vcpu_source, __entry->vcpu_target)
+);
+
+TRACE_EVENT(vgic_its_cmd_invall,
+	TP_PROTO(__u32 collection_id, int vcpu_id),
+	TP_ARGS(collection_id, vcpu_id),
+
+	TP_STRUCT__entry(
+		__field(	__u32,		collection_id		)
+		__field(	int,		vcpu_id			)
+	),
+
+	TP_fast_assign(
+		__entry->collection_id		= collection_id;
+		__entry->vcpu_id		= vcpu_id;
+	),
+
+	TP_printk("Collection ID: %u, VCPU ID: %d",
+		  __entry->collection_id, __entry->vcpu_id)
+);
+
 #endif /* _TRACE_VGIC_H */
 
 #undef TRACE_INCLUDE_PATH
diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c
index 569f9da9049f..d7524e3abad6 100644
--- a/arch/arm64/kvm/vgic/vgic-its.c
+++ b/arch/arm64/kvm/vgic/vgic-its.c
@@ -22,6 +22,7 @@ 
 
 #include "vgic.h"
 #include "vgic-mmio.h"
+#include "trace.h"
 
 static struct kvm_device_ops kvm_arm_vgic_its_ops;
 
@@ -795,6 +796,8 @@  static int vgic_its_cmd_handle_discard(struct kvm *kvm, struct vgic_its *its,
 	u32 event_id = its_cmd_get_id(its_cmd);
 	struct its_ite *ite;
 
+	trace_vgic_its_cmd_discard(device_id, event_id);
+
 	ite = find_ite(its, device_id, event_id);
 	if (ite && its_is_collection_mapped(ite->collection)) {
 		struct its_device *device = find_its_device(its, device_id);
@@ -829,6 +832,8 @@  static int vgic_its_cmd_handle_movi(struct kvm *kvm, struct vgic_its *its,
 	struct its_ite *ite;
 	struct its_collection *collection;
 
+	trace_vgic_its_cmd_movi(device_id, event_id, coll_id);
+
 	ite = find_ite(its, device_id, event_id);
 	if (!ite)
 		return E_ITS_MOVI_UNMAPPED_INTERRUPT;
@@ -1035,6 +1040,8 @@  static int vgic_its_cmd_handle_mapi(struct kvm *kvm, struct vgic_its *its,
 	struct vgic_irq *irq;
 	int lpi_nr;
 
+	trace_vgic_its_cmd_mapi(device_id, event_id);
+
 	device = find_its_device(its, device_id);
 	if (!device)
 		return E_ITS_MAPTI_UNMAPPED_DEVICE;
@@ -1161,6 +1168,8 @@  static int vgic_its_cmd_handle_mapd(struct kvm *kvm, struct vgic_its *its,
 	struct its_device *device;
 	gpa_t gpa;
 
+	trace_vgic_its_cmd_mapd(device_id, valid, num_eventid_bits, itt_addr);
+
 	if (!vgic_its_check_id(its, its->baser_device_table, device_id, &gpa))
 		return E_ITS_MAPD_DEVICE_OOR;
 
@@ -1204,6 +1213,8 @@  static int vgic_its_cmd_handle_mapc(struct kvm *kvm, struct vgic_its *its,
 	valid = its_cmd_get_validbit(its_cmd);
 	coll_id = its_cmd_get_collection(its_cmd);
 
+	trace_vgic_its_cmd_mapc(coll_id, valid);
+
 	if (!valid) {
 		vgic_its_free_collection(its, coll_id);
 		vgic_its_invalidate_cache(its);
@@ -1248,6 +1259,7 @@  static int vgic_its_cmd_handle_clear(struct kvm *kvm, struct vgic_its *its,
 	u32 event_id = its_cmd_get_id(its_cmd);
 	struct its_ite *ite;
 
+	trace_vgic_its_cmd_clear(device_id, event_id);
 
 	ite = find_ite(its, device_id, event_id);
 	if (!ite)
@@ -1278,6 +1290,7 @@  static int vgic_its_cmd_handle_inv(struct kvm *kvm, struct vgic_its *its,
 	u32 event_id = its_cmd_get_id(its_cmd);
 	struct its_ite *ite;
 
+	trace_vgic_its_cmd_inv(device_id, event_id);
 
 	ite = find_ite(its, device_id, event_id);
 	if (!ite)
@@ -1338,6 +1351,8 @@  static int vgic_its_cmd_handle_invall(struct kvm *kvm, struct vgic_its *its,
 	vcpu = collection_to_vcpu(kvm, collection);
 	vgic_its_invall(vcpu);
 
+	trace_vgic_its_cmd_invall(coll_id, vcpu->vcpu_id);
+
 	return 0;
 }
 
@@ -1364,6 +1379,8 @@  static int vgic_its_cmd_handle_movall(struct kvm *kvm, struct vgic_its *its,
 	if (!vcpu1 || !vcpu2)
 		return E_ITS_MOVALL_PROCNUM_OOR;
 
+	trace_vgic_its_cmd_movall(vcpu1->vcpu_id, vcpu2->vcpu_id);
+
 	if (vcpu1 == vcpu2)
 		return 0;
 
@@ -1392,6 +1409,8 @@  static int vgic_its_cmd_handle_int(struct kvm *kvm, struct vgic_its *its,
 	u32 msi_data = its_cmd_get_id(its_cmd);
 	u64 msi_devid = its_cmd_get_deviceid(its_cmd);
 
+	trace_vgic_its_cmd_int(msi_devid, msi_data);
+
 	return vgic_its_trigger_msi(kvm, its, msi_devid, msi_data);
 }