{"id":2226030,"url":"http://patchwork.ozlabs.org/api/patches/2226030/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-pci/patch/20260422023239.1171963-7-mrathor@linux.microsoft.com/","project":{"id":28,"url":"http://patchwork.ozlabs.org/api/projects/28/?format=json","name":"Linux PCI development","link_name":"linux-pci","list_id":"linux-pci.vger.kernel.org","list_email":"linux-pci@vger.kernel.org","web_url":null,"scm_url":null,"webscm_url":null,"list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<20260422023239.1171963-7-mrathor@linux.microsoft.com>","list_archive_url":null,"date":"2026-04-22T02:32:32","name":"[V1,06/13] mshv: Implement mshv bridge device for VFIO","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"57b83c081036d8fc9d0851be3139095762050fd0","submitter":{"id":91512,"url":"http://patchwork.ozlabs.org/api/people/91512/?format=json","name":"Mukesh R","email":"mrathor@linux.microsoft.com"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/linux-pci/patch/20260422023239.1171963-7-mrathor@linux.microsoft.com/mbox/","series":[{"id":500915,"url":"http://patchwork.ozlabs.org/api/series/500915/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-pci/list/?series=500915","date":"2026-04-22T02:32:26","name":"PCI passthru on Hyper-V (Part I)","version":1,"mbox":"http://patchwork.ozlabs.org/series/500915/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2226030/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2226030/checks/","tags":{},"related":[],"headers":{"Return-Path":"\n <linux-pci+bounces-52901-incoming=patchwork.ozlabs.org@vger.kernel.org>","X-Original-To":["incoming@patchwork.ozlabs.org","linux-pci@vger.kernel.org"],"Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=linux.microsoft.com header.i=@linux.microsoft.com\n header.a=rsa-sha256 header.s=default header.b=GgLzpdJZ;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2600:3c04:e001:36c::12fc:5321; helo=tor.lore.kernel.org;\n envelope-from=linux-pci+bounces-52901-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)","smtp.subspace.kernel.org;\n\tdkim=pass (1024-bit key) header.d=linux.microsoft.com\n header.i=@linux.microsoft.com header.b=\"GgLzpdJZ\"","smtp.subspace.kernel.org;\n arc=none smtp.client-ip=13.77.154.182","smtp.subspace.kernel.org;\n dmarc=pass (p=none dis=none) header.from=linux.microsoft.com","smtp.subspace.kernel.org;\n spf=pass smtp.mailfrom=linux.microsoft.com"],"Received":["from tor.lore.kernel.org (tor.lore.kernel.org\n [IPv6:2600:3c04:e001:36c::12fc:5321])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g0k1D1bRqz1yD5\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 22 Apr 2026 12:38:24 +1000 (AEST)","from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby tor.lore.kernel.org (Postfix) with ESMTP id DECD0308FFF0\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 22 Apr 2026 02:34:45 +0000 (UTC)","from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 3200938425B;\n\tWed, 22 Apr 2026 02:34:08 +0000 (UTC)","from linux.microsoft.com (linux.microsoft.com [13.77.154.182])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 59BA7382F28;\n\tWed, 22 Apr 2026 02:33:45 +0000 (UTC)","from mrdev.corp.microsoft.com\n (192-184-212-33.fiber.dynamic.sonic.net [192.184.212.33])\n\tby linux.microsoft.com (Postfix) with ESMTPSA id 4F8A320B6F1F;\n\tTue, 21 Apr 2026 19:33:44 -0700 (PDT)"],"ARC-Seal":"i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1776825238; cv=none;\n b=CH3KS8gmXPPRB9m6XYJksBcEuggtP1YZ2G6ffjjyuPZPcPKCw3OFMUaGKK8EGJ5j2cFkjvRY/emPqGB21NOu+NQwXJ9o6osJJd0zNALps4m0t5in4isyKl2MSakb6OaddNQQFae0a9i9aDn2X0L8sLNvQTJ4C1+7zX3Y5Y8pqcg=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1776825238; c=relaxed/simple;\n\tbh=jYrebEGyLACqbZL/w3y9a7O0xWgw6FHchfvbYBMKEM0=;\n\th=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:\n\t MIME-Version;\n b=eRc/AUM1OY/zrRDaaTIkMHvLUV8piHXbpsJdlLiYBguWKJqxuG3TGFqsq1wxmq6GXDVY6FYCux3a7FXPS0fIrqo1YEfP/j/2Gj7QlIELF8mcooRiI3IzjVnhuPpUEyGzAtv5NEvfvoN7kJyJtUqFpGvaAoIkypaeJcVkVmQ90MU=","ARC-Authentication-Results":"i=1; smtp.subspace.kernel.org;\n dmarc=pass (p=none dis=none) header.from=linux.microsoft.com;\n spf=pass smtp.mailfrom=linux.microsoft.com;\n dkim=pass (1024-bit key) header.d=linux.microsoft.com\n header.i=@linux.microsoft.com header.b=GgLzpdJZ;\n arc=none smtp.client-ip=13.77.154.182","DKIM-Filter":"OpenDKIM Filter v2.11.0 linux.microsoft.com 4F8A320B6F1F","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com;\n\ts=default; t=1776825225;\n\tbh=YnF+uI+QwqeYTK6oQpqBg7HAiFmqfGlkyQt6D84StzY=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=GgLzpdJZ9nmTE/p4NZSlFoqA8wfROdvtb29VmC5gy4u/g+sAFKx15pHMNK0ZG8yfE\n\t ZZXvc8Tcv/AFHSLs7vfDcTEqxfvehzsr5Ba8763F99tj78RMpsTTOAbzlpVQ1i8sAI\n\t YdWhJVQ0mYd+YLMldvIq5xIVa5h4ubRqYaMgZAfk=","From":"Mukesh R <mrathor@linux.microsoft.com>","To":"hpa@zytor.com,\n\trobin.murphy@arm.com,\n\trobh@kernel.org,\n\twei.liu@kernel.org,\n\tmrathor@linux.microsoft.com,\n\tmhklinux@outlook.com,\n\tmuislam@microsoft.com,\n\tnamjain@linux.microsoft.com,\n\tmagnuskulke@linux.microsoft.com,\n\tanbelski@linux.microsoft.com,\n\tlinux-kernel@vger.kernel.org,\n\tlinux-hyperv@vger.kernel.org,\n\tiommu@lists.linux.dev,\n\tlinux-pci@vger.kernel.org,\n\tlinux-arch@vger.kernel.org","Cc":"kys@microsoft.com,\n\thaiyangz@microsoft.com,\n\tdecui@microsoft.com,\n\tlongli@microsoft.com,\n\ttglx@kernel.org,\n\tmingo@redhat.com,\n\tbp@alien8.de,\n\tdave.hansen@linux.intel.com,\n\tx86@kernel.org,\n\tjoro@8bytes.org,\n\twill@kernel.org,\n\tlpieralisi@kernel.org,\n\tkwilczynski@kernel.org,\n\tbhelgaas@google.com,\n\tarnd@arndb.de","Subject":"[PATCH V1 06/13] mshv: Implement mshv bridge device for VFIO","Date":"Tue, 21 Apr 2026 19:32:32 -0700","Message-ID":"<20260422023239.1171963-7-mrathor@linux.microsoft.com>","X-Mailer":"git-send-email 2.51.2.vfs.0.1","In-Reply-To":"<20260422023239.1171963-1-mrathor@linux.microsoft.com>","References":"<20260422023239.1171963-1-mrathor@linux.microsoft.com>","Precedence":"bulk","X-Mailing-List":"linux-pci@vger.kernel.org","List-Id":"<linux-pci.vger.kernel.org>","List-Subscribe":"<mailto:linux-pci+subscribe@vger.kernel.org>","List-Unsubscribe":"<mailto:linux-pci+unsubscribe@vger.kernel.org>","MIME-Version":"1.0","Content-Transfer-Encoding":"8bit"},"content":"Add a new file to implement VFIO-MSHV bridge pseudo device. These\nfunctions are called in the VFIO framework, and credits to kvm/vfio.c\nas this file was adapted from it.\n\nCo-developed-by: Wei Liu <wei.liu@kernel.org>\nSigned-off-by: Wei Liu <wei.liu@kernel.org>\nSigned-off-by: Mukesh R <mrathor@linux.microsoft.com>\n---\n drivers/hv/Makefile       |   3 +-\n drivers/hv/mshv_vfio.c    | 211 ++++++++++++++++++++++++++++++++++++++\n include/uapi/linux/mshv.h |   1 +\n 3 files changed, 214 insertions(+), 1 deletion(-)\n create mode 100644 drivers/hv/mshv_vfio.c","diff":"diff --git a/drivers/hv/Makefile b/drivers/hv/Makefile\nindex 888a748cc7cb..9ab6fc254c38 100644\n--- a/drivers/hv/Makefile\n+++ b/drivers/hv/Makefile\n@@ -14,7 +14,8 @@ hv_vmbus-y := vmbus_drv.o \\\n hv_vmbus-$(CONFIG_HYPERV_TESTING)\t+= hv_debugfs.o\n hv_utils-y := hv_util.o hv_kvp.o hv_snapshot.o hv_utils_transport.o\n mshv_root-y := mshv_root_main.o mshv_synic.o mshv_eventfd.o mshv_irq.o \\\n-\t       mshv_root_hv_call.o mshv_portid_table.o mshv_regions.o\n+\t       mshv_root_hv_call.o mshv_portid_table.o mshv_regions.o  \\\n+               mshv_vfio.o\n mshv_root-$(CONFIG_DEBUG_FS) += mshv_debugfs.o\n mshv_root-$(CONFIG_TRACEPOINTS) += mshv_trace.o\n mshv_vtl-y := mshv_vtl_main.o\ndiff --git a/drivers/hv/mshv_vfio.c b/drivers/hv/mshv_vfio.c\nnew file mode 100644\nindex 000000000000..00a97920e25b\n--- /dev/null\n+++ b/drivers/hv/mshv_vfio.c\n@@ -0,0 +1,211 @@\n+// SPDX-License-Identifier: GPL-2.0-only\n+/*\n+ * VFIO-MSHV bridge pseudo device\n+ *\n+ * Heavily inspired by the VFIO-KVM bridge pseudo device.\n+ */\n+#include <linux/errno.h>\n+#include <linux/file.h>\n+#include <linux/list.h>\n+#include <linux/module.h>\n+#include <linux/mutex.h>\n+#include <linux/slab.h>\n+#include <linux/vfio.h>\n+#include <asm/mshyperv.h>\n+\n+#include \"mshv.h\"\n+#include \"mshv_root.h\"\n+\n+struct mshv_vfio_file {\n+\tstruct list_head node;\n+\tstruct file *file;\t/* list of struct mshv_vfio_file */\n+};\n+\n+struct mshv_vfio {\n+\tstruct list_head file_list;\n+\tstruct mutex lock;\n+};\n+\n+static bool mshv_vfio_file_is_valid(struct file *file)\n+{\n+\tbool (*fn)(struct file *file);\n+\tbool ret;\n+\n+\tfn = symbol_get(vfio_file_is_valid);\n+\tif (!fn)\n+\t\treturn false;\n+\n+\tret = fn(file);\n+\n+\tsymbol_put(vfio_file_is_valid);\n+\n+\treturn ret;\n+}\n+\n+static long mshv_vfio_file_add(struct mshv_device *mshvdev, unsigned int fd)\n+{\n+\tstruct mshv_vfio *mshv_vfio = mshvdev->device_private;\n+\tstruct mshv_vfio_file *mvf;\n+\tstruct file *filp;\n+\tlong ret = 0;\n+\n+\tfilp = fget(fd);\n+\tif (!filp)\n+\t\treturn -EBADF;\n+\n+\t/* Ensure the FD is a vfio FD. */\n+\tif (!mshv_vfio_file_is_valid(filp)) {\n+\t\tret = -EINVAL;\n+\t\tgoto out_fput;\n+\t}\n+\n+\tmutex_lock(&mshv_vfio->lock);\n+\n+\tlist_for_each_entry(mvf, &mshv_vfio->file_list, node) {\n+\t\tif (mvf->file == filp) {\n+\t\t\tret = -EEXIST;\n+\t\t\tgoto out_unlock;\n+\t\t}\n+\t}\n+\n+\tmvf = kzalloc(sizeof(*mvf), GFP_KERNEL_ACCOUNT);\n+\tif (!mvf) {\n+\t\tret = -ENOMEM;\n+\t\tgoto out_unlock;\n+\t}\n+\n+\tmvf->file = get_file(filp);\n+\tlist_add_tail(&mvf->node, &mshv_vfio->file_list);\n+\n+out_unlock:\n+\tmutex_unlock(&mshv_vfio->lock);\n+out_fput:\n+\tfput(filp);\n+\treturn ret;\n+}\n+\n+static long mshv_vfio_file_del(struct mshv_device *mshvdev, unsigned int fd)\n+{\n+\tstruct mshv_vfio *mshv_vfio = mshvdev->device_private;\n+\tstruct mshv_vfio_file *mvf;\n+\tlong ret;\n+\n+\tCLASS(fd, f)(fd);\n+\n+\tif (fd_empty(f))\n+\t\treturn -EBADF;\n+\n+\tret = -ENOENT;\n+\tmutex_lock(&mshv_vfio->lock);\n+\n+\tlist_for_each_entry(mvf, &mshv_vfio->file_list, node) {\n+\t\tif (mvf->file != fd_file(f))\n+\t\t\tcontinue;\n+\n+\t\tlist_del(&mvf->node);\n+\t\tfput(mvf->file);\n+\t\tkfree(mvf);\n+\t\tret = 0;\n+\t\tbreak;\n+\t}\n+\n+\tmutex_unlock(&mshv_vfio->lock);\n+\treturn ret;\n+}\n+\n+static long mshv_vfio_set_file(struct mshv_device *mshvdev, long attr,\n+\t\t\t      void __user *arg)\n+{\n+\tint32_t __user *argp = arg;\n+\tint32_t fd;\n+\n+\tswitch (attr) {\n+\tcase MSHV_DEV_VFIO_FILE_ADD:\n+\t\tif (get_user(fd, argp))\n+\t\t\treturn -EFAULT;\n+\t\treturn mshv_vfio_file_add(mshvdev, fd);\n+\n+\tcase MSHV_DEV_VFIO_FILE_DEL:\n+\t\tif (get_user(fd, argp))\n+\t\t\treturn -EFAULT;\n+\t\treturn mshv_vfio_file_del(mshvdev, fd);\n+\t}\n+\n+\treturn -ENXIO;\n+}\n+\n+static long mshv_vfio_set_attr(struct mshv_device *mshvdev,\n+\t\t\t      struct mshv_device_attr *attr)\n+{\n+\tswitch (attr->group) {\n+\tcase MSHV_DEV_VFIO_FILE:\n+\t\treturn mshv_vfio_set_file(mshvdev, attr->attr,\n+\t\t\t\t\t  u64_to_user_ptr(attr->addr));\n+\t}\n+\n+\treturn -ENXIO;\n+}\n+\n+static long mshv_vfio_has_attr(struct mshv_device *mshvdev,\n+\t\t\t      struct mshv_device_attr *attr)\n+{\n+\tswitch (attr->group) {\n+\tcase MSHV_DEV_VFIO_FILE:\n+\t\tswitch (attr->attr) {\n+\t\tcase MSHV_DEV_VFIO_FILE_ADD:\n+\t\tcase MSHV_DEV_VFIO_FILE_DEL:\n+\t\t\treturn 0;\n+\t\t}\n+\n+\t\tbreak;\n+\t}\n+\n+\treturn -ENXIO;\n+}\n+\n+static long mshv_vfio_create_device(struct mshv_device *mshvdev)\n+{\n+\tstruct mshv_device *tmp;\n+\tstruct mshv_vfio *mshv_vfio;\n+\n+\t/* Only one VFIO \"device\" per VM */\n+\thlist_for_each_entry(tmp, &mshvdev->device_pt->pt_devices,\n+\t\t\t     device_ptnode)\n+\t\tif (tmp->device_ops == &mshv_vfio_device_ops)\n+\t\t\treturn -EBUSY;\n+\n+\tmshv_vfio = kzalloc(sizeof(*mshv_vfio), GFP_KERNEL_ACCOUNT);\n+\tif (mshv_vfio == NULL)\n+\t\treturn -ENOMEM;\n+\n+\tINIT_LIST_HEAD(&mshv_vfio->file_list);\n+\tmutex_init(&mshv_vfio->lock);\n+\n+\tmshvdev->device_private = mshv_vfio;\n+\n+\treturn 0;\n+}\n+\n+/* This is called from mshv_device_fop_release() */\n+static void mshv_vfio_release_device(struct mshv_device *mshvdev)\n+{\n+\tstruct mshv_vfio *mv = mshvdev->device_private;\n+\tstruct mshv_vfio_file *mvf, *tmp;\n+\n+\tlist_for_each_entry_safe(mvf, tmp, &mv->file_list, node) {\n+\t\tfput(mvf->file);\n+\t\tlist_del(&mvf->node);\n+\t\tkfree(mvf);\n+\t}\n+\n+\tkfree(mv);\n+\tkfree(mshvdev);\n+}\n+\n+struct mshv_device_ops mshv_vfio_device_ops = {\n+\t.device_name = \"mshv-vfio\",\n+\t.device_create = mshv_vfio_create_device,\n+\t.device_release = mshv_vfio_release_device,\n+\t.device_set_attr = mshv_vfio_set_attr,\n+\t.device_has_attr = mshv_vfio_has_attr,\n+};\ndiff --git a/include/uapi/linux/mshv.h b/include/uapi/linux/mshv.h\nindex 4373a8243951..6404e8a98237 100644\n--- a/include/uapi/linux/mshv.h\n+++ b/include/uapi/linux/mshv.h\n@@ -254,6 +254,7 @@ struct mshv_root_hvcall {\n #define MSHV_GET_GPAP_ACCESS_BITMAP\t_IOWR(MSHV_IOCTL, 0x06, struct mshv_gpap_access_bitmap)\n /* Generic hypercall */\n #define MSHV_ROOT_HVCALL\t\t_IOWR(MSHV_IOCTL, 0x07, struct mshv_root_hvcall)\n+#define MSHV_CREATE_DEVICE             _IOWR(MSHV_IOCTL, 0x08, struct mshv_create_device)\n \n /*\n  ********************************\n","prefixes":["V1","06/13"]}