[PATCH v0] kvm: decode arguments of KVM_IOEVENTFD, KVM_IRQFD, and KVM_SET_GSI_ROUTING

Daniel Cohen Hillel danielcohenhillel at gmail.com
Sat Oct 21 01:23:09 UTC 2023


* configure.ac (AC_CHECK_TYPES): Add structs kvm_irqfd, kvm_irq_routing,
           kvm_irq_routing_entry, and kvm_ioeventfd.
* xlat/kvm_ioeventfd_flags.in: New file.
* xlat/kvm_irqfd_flags.in: New file.
* xlat/kvm_irq_routing_types.in: New file.
* xlat/kvm_irq_routing_entry_flags.in: New file.
* kvm.c [HAVE_STRUCT_KVM_IOEVENTFD]: Include "xlat/kvm_ioeventfd_flags.h"
          (kvm_ioctl_decode_ioeventfd): New function
[HAVE_STRUCT_KVM_IRQFD]: Include "xlat/kvm_irqfd_flags.h"
          (kvm_ioctl_decode_irqfd): New function
[HAVE_STRUCT_KVM_IRQ_ROUTING]: Include "xlat/kvm_irq_routing_types.h"
          and "xlat/kvm_irq_routing_types.h".
          (print_kvm_irq_routing_entrym kvm_ioctl_decode_irq_routing): New functions
(kvm_ioctl) [HAVE_STRUCT_KVM_IOEVENTFD]: Use function kvm_ioctl_decode_ioeventfd
(kvm_ioctl) [HAVE_STRUCT_KVM_IRQFD]: Use function kvm_ioctl_decode_irqfd
(kvm_ioctl) [HAVE_STRUCT_KVM_IRQ_ROUTING]: Use functions (print_kvm_irq_routing_entrym kvm_ioctl_decode_irq_routing)
* NEWS: Mention this improvement.
---
 configure.ac                            |   6 +-
 src/kvm.c                               | 131 ++++++++++++++++++++++++
 src/xlat/kvm_ioeventfd_flags.in         |   4 +
 src/xlat/kvm_irq_routing_entry_flags.in |   1 +
 src/xlat/kvm_irq_routing_types.in       |   4 +
 src/xlat/kvm_irqfd_flags.in             |   2 +
 6 files changed, 147 insertions(+), 1 deletion(-)
 create mode 100644 src/xlat/kvm_ioeventfd_flags.in
 create mode 100644 src/xlat/kvm_irq_routing_entry_flags.in
 create mode 100644 src/xlat/kvm_irq_routing_types.in
 create mode 100644 src/xlat/kvm_irqfd_flags.in

diff --git a/configure.ac b/configure.ac
index 21c7265bf..125f37208 100644
--- a/configure.ac
+++ b/configure.ac
@@ -538,7 +538,11 @@ AC_CHECK_TYPES(m4_normalize([
 	struct kvm_cpuid2,
 	struct kvm_regs,
 	struct kvm_sregs,
-	struct kvm_userspace_memory_region
+	struct kvm_userspace_memory_region,
+	struct kvm_irqfd,
+	struct kvm_irq_routing,
+	struct kvm_irq_routing_entry,
+	struct kvm_ioeventfd
 ]),,, [#include <linux/kvm.h>])
 
 AC_CHECK_TYPES(m4_normalize([
diff --git a/src/kvm.c b/src/kvm.c
index 7d1304b2c..79312b26b 100644
--- a/src/kvm.c
+++ b/src/kvm.c
@@ -314,6 +314,122 @@ kvm_ioctl_decode_sregs(struct tcb *const tcp, const unsigned int code,
 }
 # endif /* HAVE_STRUCT_KVM_SREGS */
 
+# ifdef HAVE_STRUCT_KVM_IOEVENTFD
+#  include "xlat/kvm_ioeventfd_flags.h"
+static int
+kvm_ioctl_decode_ioeventfd(struct tcb *const tcp, const unsigned int code,
+		       const kernel_ulong_t arg)
+{
+	struct kvm_ioeventfd ioeventfd;
+
+	tprint_arg_next();
+	if (umove_or_printaddr(tcp, arg, &ioeventfd))
+		return RVAL_IOCTL_DECODED;
+
+	tprint_struct_begin();
+
+	PRINT_FIELD_X(ioeventfd, datamatch);
+	tprint_struct_next();
+	PRINT_FIELD_X(ioeventfd, addr);
+	tprint_struct_next();
+	PRINT_FIELD_U(ioeventfd, len);
+	tprint_struct_next();
+	PRINT_FIELD_U(ioeventfd, fd);
+	tprint_struct_next();
+	PRINT_FIELD_FLAGS(ioeventfd, flags, kvm_ioeventfd_flags, "KVM_IOEVENTFD_FLAG_???");
+
+	tprint_struct_end();
+
+	return RVAL_IOCTL_DECODED;}
+# endif /* HAVE_STRUCT_KVM_IOEVENTFD */
+
+
+# ifdef HAVE_STRUCT_KVM_IRQFD
+#  include "xlat/kvm_irqfd_flags.h"
+static int
+kvm_ioctl_decode_irqfd(struct tcb *const tcp, const unsigned int code,
+		       const kernel_ulong_t arg)
+{
+	struct kvm_irqfd irqfd;
+
+	tprint_arg_next();
+	if (umove_or_printaddr(tcp, arg, &irqfd))
+		return RVAL_IOCTL_DECODED;
+
+	tprint_struct_begin();
+
+	PRINT_FIELD_U(irqfd, fd);
+	tprint_struct_next();
+	PRINT_FIELD_U(irqfd, gsi);
+	tprint_struct_next();
+	PRINT_FIELD_FLAGS(irqfd, flags, kvm_irqfd_flags, "KVM_IRQFD_???");
+
+	tprint_struct_end();
+
+	return RVAL_IOCTL_DECODED;}
+# endif /* HAVE_STRUCT_KVM_IRQFD */
+
+# ifdef HAVE_STRUCT_KVM_IRQ_ROUTING
+#  include "xlat/kvm_irq_routing_types.h"
+#  include "xlat/kvm_irq_routing_entry_flags.h"
+static bool
+print_kvm_irq_routing_entry(struct tcb *const tcp,
+		      void* elem_buf, size_t elem_size, void* data)
+{
+	struct kvm_irq_routing_entry entry = *((struct kvm_irq_routing_entry *)elem_buf);
+
+	tprint_struct_begin();
+
+	PRINT_FIELD_U(entry, gsi);
+	tprint_struct_next();
+	PRINT_FIELD_XVAL(entry, type, kvm_irq_routing_types, "KVM_IRQ_ROUTING_???");
+	tprint_struct_next();
+	PRINT_FIELD_FLAGS(entry, flags, kvm_irq_routing_entry_flags, "KVM_???");
+
+	tprint_struct_end();
+
+	return true;
+}
+
+static int
+kvm_ioctl_decode_irq_routing(struct tcb *const tcp, const unsigned int code,
+		       const kernel_ulong_t arg)
+{
+	struct kvm_irq_routing irq_routing_hdr;
+
+	tprint_arg_next();
+
+	if (umove_or_printaddr(tcp, arg, &irq_routing_hdr))
+		return RVAL_IOCTL_DECODED;
+
+	tprint_struct_begin();
+
+	PRINT_FIELD_U(irq_routing_hdr, nr);
+	tprint_struct_next();
+
+	// No flags specified so far, hence this field is always 0 (see kvm/api.txt)
+	PRINT_FIELD_U(irq_routing_hdr, flags);
+
+	tprint_struct_next();
+
+	if (abbrev(tcp)) {
+		tprint_array_begin();
+		if (irq_routing_hdr.nr)
+			tprint_more_data_follows();
+		tprint_array_end();
+	} else {
+		struct kvm_irq_routing_entry entry;
+		print_array(tcp, arg + sizeof(irq_routing_hdr), irq_routing_hdr.nr,
+			&entry, sizeof(entry), tfetch_mem,
+			print_kvm_irq_routing_entry, NULL);
+	}
+
+	tprint_struct_end();
+
+	return RVAL_IOCTL_DECODED;
+}
+# endif /* HAVE_STRUCT_KVM_IRQ_ROUTING */
+
 # include "xlat/kvm_cap.h"
 static int
 kvm_ioctl_decode_check_extension(struct tcb *const tcp, const unsigned int code,
@@ -403,6 +519,21 @@ kvm_ioctl(struct tcb *const tcp, const unsigned int code, const kernel_ulong_t a
                return kvm_ioctl_decode_cpuid2(tcp, code, arg);
 # endif
 
+#  ifdef HAVE_STRUCT_KVM_IOEVENTFD
+	case KVM_IOEVENTFD:
+		return kvm_ioctl_decode_ioeventfd(tcp, code, arg);
+# endif
+
+#  ifdef HAVE_STRUCT_KVM_IRQFD
+	case KVM_IRQFD:
+		return kvm_ioctl_decode_irqfd(tcp, code, arg);
+# endif
+
+#  ifdef HAVE_STRUCT_KVM_IRQ_ROUTING
+	case KVM_SET_GSI_ROUTING:
+		return kvm_ioctl_decode_irq_routing(tcp, code, arg);
+# endif
+
 	case KVM_CHECK_EXTENSION:
 		return kvm_ioctl_decode_check_extension(tcp, code, arg);
 
diff --git a/src/xlat/kvm_ioeventfd_flags.in b/src/xlat/kvm_ioeventfd_flags.in
new file mode 100644
index 000000000..609be13e4
--- /dev/null
+++ b/src/xlat/kvm_ioeventfd_flags.in
@@ -0,0 +1,4 @@
+KVM_IOEVENTFD_FLAG_DATAMATCH	(1 << 0)
+KVM_IOEVENTFD_FLAG_PIO	(1 << 1)
+KVM_IOEVENTFD_FLAG_DEASSIGN 	(1 << 2)
+KVM_IOEVENTFD_FLAG_VIRTIO_CCW_NOTIFY	(1 << 3)
\ No newline at end of file
diff --git a/src/xlat/kvm_irq_routing_entry_flags.in b/src/xlat/kvm_irq_routing_entry_flags.in
new file mode 100644
index 000000000..bda526102
--- /dev/null
+++ b/src/xlat/kvm_irq_routing_entry_flags.in
@@ -0,0 +1 @@
+KVM_MSI_VALID_DEVID	(1 << 0)
\ No newline at end of file
diff --git a/src/xlat/kvm_irq_routing_types.in b/src/xlat/kvm_irq_routing_types.in
new file mode 100644
index 000000000..be5b579da
--- /dev/null
+++ b/src/xlat/kvm_irq_routing_types.in
@@ -0,0 +1,4 @@
+KVM_IRQ_ROUTING_IRQCHIP 1
+KVM_IRQ_ROUTING_MSI 2
+KVM_IRQ_ROUTING_S390_ADAPTER    3
+KVM_IRQ_ROUTING_HV_SINT 4
\ No newline at end of file
diff --git a/src/xlat/kvm_irqfd_flags.in b/src/xlat/kvm_irqfd_flags.in
new file mode 100644
index 000000000..59ae4c4c7
--- /dev/null
+++ b/src/xlat/kvm_irqfd_flags.in
@@ -0,0 +1,2 @@
+KVM_IRQFD_FLAG_DEASSIGN (1 << 0)
+KVM_IRQFD_FLAG_RESAMPLE (1 << 1)
\ No newline at end of file
-- 
2.34.1



More information about the Strace-devel mailing list