Kernel KVM virtualization development
 help / color / mirror / Atom feed
From: Mostafa Saleh <smostafa@google.com>
To: kvm@vger.kernel.org
Cc: will@kernel.org, julien.thierry.kdev@gmail.com, praan@google.com,
	 eric.auger@redhat.com, alex@shazbot.org,
	Mostafa Saleh <smostafa@google.com>
Subject: [PATCH kvmtool 9/9] vfio: platform: Take the guest node from a device tree template
Date: Sat, 24 Oct 2026 16:19:02 +0000	[thread overview]
Message-ID: <20261024161902.2093581-10-smostafa@google.com> (raw)
In-Reply-To: <20261024161902.2093581-1-smostafa@google.com>

At this point the device node has interrupts and regs, which is not
enough to probe a driver in the guest, it at least needs a compatible
string and other device bindings.
To avoid hardcoding those, let the user supply them as a compiled
device tree blob:

  --vfio-platform <device>[,<template.dtb>]

Every property of the template's root node, and every subnode, is
copied into the generated node with fdt__copy_node().

Signed-off-by: Mostafa Saleh <smostafa@google.com>
---
 builtin-run.c      |  2 +-
 include/kvm/vfio.h |  2 ++
 vfio/core.c        | 16 ++++++++++++++-
 vfio/platform.c    | 50 ++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 68 insertions(+), 2 deletions(-)

diff --git a/builtin-run.c b/builtin-run.c
index b09fc2e..a6fd8ec 100644
--- a/builtin-run.c
+++ b/builtin-run.c
@@ -262,7 +262,7 @@ static int loglevel_parser(const struct option *opt, const char *arg, int unset)
 	OPT_CALLBACK('\0', "vfio-pci", NULL, "[domain:]bus:dev.fn",	\
 		     "Assign a PCI device to the virtual machine",	\
 		     vfio_device_parser, kvm),				\
-	OPT_CALLBACK('\0', "vfio-platform", NULL, "device",		\
+	OPT_CALLBACK('\0', "vfio-platform", NULL, "device[,template.dtb]",	\
 		     "Assign a platform device to the virtual machine",	\
 		     vfio_device_parser, kvm),				\
 									\
diff --git a/include/kvm/vfio.h b/include/kvm/vfio.h
index b3034a0..de24ba1 100644
--- a/include/kvm/vfio.h
+++ b/include/kvm/vfio.h
@@ -121,6 +121,8 @@ struct vfio_device {
 
 struct vfio_device_params {
 	char				*name;
+	/* Platform devices: DTB whose root node is copied into the guest node */
+	char				*dt_template;
 	const char			*bus;
 	enum vfio_device_type		type;
 };
diff --git a/vfio/core.c b/vfio/core.c
index 6823a95..3ce1ffd 100644
--- a/vfio/core.c
+++ b/vfio/core.c
@@ -41,16 +41,30 @@ static int vfio_device_pci_parser(const struct option *opt, char *arg,
 	return 0;
 }
 
-/* @arg is the name of the device under /sys/bus/platform/devices */
+/*
+ * @arg is the name of the device under /sys/bus/platform/devices, optionally
+ * followed by ",<template.dtb>".
+ */
 static int vfio_device_platform_parser(const struct option *opt, char *arg,
 				       struct vfio_device_params *dev)
 {
+	char *dt_template = strtok(NULL, ",");
+
 	dev->type = VFIO_DEVICE_PLATFORM;
 	dev->bus = "platform";
+	dev->dt_template = NULL;
 	dev->name = strdup(arg);
 	if (!dev->name)
 		return -ENOMEM;
 
+	if (dt_template) {
+		dev->dt_template = strdup(dt_template);
+		if (!dev->dt_template) {
+			free(dev->name);
+			return -ENOMEM;
+		}
+	}
+
 	return 0;
 }
 
diff --git a/vfio/platform.c b/vfio/platform.c
index 22052a6..2d08f73 100644
--- a/vfio/platform.c
+++ b/vfio/platform.c
@@ -8,7 +8,11 @@
 
 #include <sys/ioctl.h>
 #include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
 #include "kvm/fdt.h"
+#include "kvm/read-write.h"
 
 static u64 vfio_mmio_io_space_next = KVM_VFIO_MMIO_AREA;
 
@@ -29,6 +33,48 @@ static int vfio_mmio_alloc_io_space(u64 size, u64 *addr)
 }
 
 #ifdef CONFIG_HAS_LIBFDT
+static void vfio_platform_generate_fdt_from_template(void *fdt,
+						     struct vfio_device *vdev)
+{
+	int fd;
+	struct stat st;
+	void *tmp_fdt;
+	int root_offset;
+
+	if (!vdev->params->dt_template)
+		return;
+
+	fd = open(vdev->params->dt_template, O_RDONLY);
+	if (fd < 0)
+		die("Failed to open device tree template '%s'", vdev->params->dt_template);
+
+	if (fstat(fd, &st) < 0)
+		die("Failed to stat device tree template");
+
+	if (st.st_size < (off_t)sizeof(struct fdt_header))
+		die("Invalid device tree blob (DTB) provided in '%s'",
+		    vdev->params->dt_template);
+
+	tmp_fdt = malloc(st.st_size);
+	if (!tmp_fdt)
+		die("Failed to allocate memory for device tree template");
+
+	if (read_in_full(fd, tmp_fdt, st.st_size) != st.st_size)
+		die("Failed to read device tree template");
+
+	if (fdt_check_header(tmp_fdt))
+		die("Invalid DTB: '%s'", vdev->params->dt_template);
+
+	root_offset = fdt_path_offset(tmp_fdt, "/");
+	if (root_offset < 0)
+		die("Failed to parse device tree template");
+
+	fdt__copy_node(fdt, tmp_fdt, root_offset);
+
+	free(tmp_fdt);
+	close(fd);
+}
+
 static void generate_interrupts_prop(void *fdt, struct vfio_device *vdev,
 				     fdt_irq_fn generate_irq_prop)
 {
@@ -82,6 +128,9 @@ static void generate_mmio_fdt_node(void *fdt,
 		 vdev->params->name, vdev->regions[0].guest_phys_addr);
 
 	_FDT(fdt_begin_node(fdt, node_name));
+	/* Extra user supplied binding. */
+	vfio_platform_generate_fdt_from_template(fdt, vdev);
+
 	_FDT(fdt_property(fdt, "reg", reg_prop,
 			  2 * sizeof(*reg_prop) * num_regions));
 	generate_interrupts_prop(fdt, vdev, generate_irq_prop);
@@ -264,4 +313,5 @@ void vfio_platform_teardown_device(struct kvm *kvm, struct vfio_device *vdev)
 
 	device__unregister(&vdev->dev_hdr);
 	free(pdev->irqs);
+	free(vdev->params->dt_template);
 }
-- 
2.56.0.307.g5fe7bd680c-goog


      parent reply	other threads:[~2026-10-24 16:20 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-24 16:18 [PATCH kvmtool 0/9] vfio: Add support for platform devices Mostafa Saleh
2026-10-24 16:18 ` [PATCH kvmtool 1/9] vfio: Fix fd leak in vfio_group_get_for_dev() Mostafa Saleh
2026-10-24 16:18 ` [PATCH kvmtool 2/9] vfio: Factor out wired IRQ setup and teardown Mostafa Saleh
2026-10-24 16:18 ` [PATCH kvmtool 3/9] vfio: Support edge-triggered wired IRQs Mostafa Saleh
2026-10-24 16:18 ` [PATCH kvmtool 4/9] fdt: Allow fdt_irq_fn to generate multiple interrupts Mostafa Saleh
2026-10-24 16:18 ` [PATCH kvmtool 5/9] fdt: Add helper to copy an FDT node Mostafa Saleh
2026-10-24 16:18 ` [PATCH kvmtool 6/9] vfio: Reserve guest address space for VFIO platform Mostafa Saleh
2026-10-24 16:19 ` [PATCH kvmtool 7/9] vfio: Add basic support for vfio-platform Mostafa Saleh
2026-10-24 16:19 ` [PATCH kvmtool 8/9] vfio: platform: Add interrupts support Mostafa Saleh
2026-10-24 16:19 ` Mostafa Saleh [this message]

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=20261024161902.2093581-10-smostafa@google.com \
    --to=smostafa@google.com \
    --cc=alex@shazbot.org \
    --cc=eric.auger@redhat.com \
    --cc=julien.thierry.kdev@gmail.com \
    --cc=kvm@vger.kernel.org \
    --cc=praan@google.com \
    --cc=will@kernel.org \
    /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