From nobody Thu Oct 22 19:27:18 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=google.com ARC-Seal: i=1; a=rsa-sha256; t=1791568470; cv=none; d=zohomail.com; s=zohoarc; b=ddHfbPtL7ZqVQDqX/XakmYGRAzriZcQi0lS6MdoX1eNchBcBUKNfTFNtRPcJGatAMh4ACEXolw+a+QC5aZlBMcQA52TzvUQiTW6EG0Mr7HxdturESx1FdrLcQFbuE6EowuX7pDwKXSt7/48vbO1HYfkUUU5g/t3IzotZM6ZuuAI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1791568470; h=Content-Type:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=uJhji8KzI8trzCpun7JOSJlJxfJog9XiC3iPL51zwpg=; b=elTLQRv1/q5MVJuf+TwzugZbtZUEkVZam0Hi2htK62nAdAOKlTBYrWC0Jm1wd/jCEnhSQKhNUgM0haQvLNbxareGRdY7nvFKn12xKUc7y2TjgVn2Y2yCt/71sPzcoi5BzeNnT++i7P/zC05cIvOOAkflDN60+ThoPHC+0/ok4kw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1791568470106198.81375852139206; Fri, 9 Oct 2026 10:54:30 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1xFEnG-0000WE-UO; Fri, 09 Oct 2026 13:54:10 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from <3LSrJagsKCgQreqerkypexmksskpi.gsquiqy-hiziprsrkry.svk@flex--namangulati.bounces.google.com>) id 1xFEn3-0000UV-VW for qemu-devel@nongnu.org; Fri, 09 Oct 2026 13:53:54 -0400 Received: from mail-qt1-x847.google.com ([2607:f8b0:4864:20::847]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from <3LSrJagsKCgQreqerkypexmksskpi.gsquiqy-hiziprsrkry.svk@flex--namangulati.bounces.google.com>) id 1xFEn1-0006F9-Vm for qemu-devel@nongnu.org; Fri, 09 Oct 2026 13:53:53 -0400 Received: by mail-qt1-x847.google.com with SMTP id d75a77b69052e-532f343a55bso113570111cf.3 for ; Fri, 09 Oct 2026 10:53:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1791568430; x=1792173230; darn=nongnu.org; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:from:to:cc:subject:date:message-id:reply-to :content-type; bh=uJhji8KzI8trzCpun7JOSJlJxfJog9XiC3iPL51zwpg=; b=Cjtsv7vEpKEfSWt7X8KWDzPEDqEyGOICL0sJWLcOsrQqnhH4XXcbtAwPcEL96L9opo ftkJcOMYqfz4l2hcodUyilRuOKbC86boZuTsgL9xQsM/pqags9qIe6B56b5WwDSeff5W nDOGnfkuhXCBCr9MD/LZXwFrCeJJjmHVuCDD1hzwOq7nzEVlb6J88BQunb3JeHtaf7TG pF1o2PWg0tJRrQGuYsrrAADrctRbFx6eqXa2N+Dvwy/N0y9IOuuh/3e+GzIrjpwg8tc8 QEe5dM0z1xlqarHbl5iXxvWRHS71Jpo8uolaKs5XNRjW0XrfMHC7Ij1LARIV2NeAopoI 5yhA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1791568430; x=1792173230; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=uJhji8KzI8trzCpun7JOSJlJxfJog9XiC3iPL51zwpg=; b=iPdOEDagO1gkarDtiHO6QaYTEcvIXBzZ6gGeKz/q6oZzmKiU9D7hE7+77mjw3gHpMY UVFFXsBDv/IGtL/OBKdIILXrffl6eJFMeih5ST6Rs8TF46HYXT5GDCHBXopC9D6k6qG3 /kwoas4CBoGB9UQJ4b62pmhpkAFnlkXQCMOyhiqTuGQa9brqyV3YfMSKy0V3mGIez0Z0 Svxq37eaHUHtYgotbjnEOvwlToCTYWjK9f+B0Isolj6HMugYvyXO3xjkMJ8CS00IqiAe JD67xGWKa4TxwvfN6LTBtp522izxHSNaLcojSqgxPcWFcXCcmc5Swhmv9O0CfztUbhzM viEA== X-Gm-Message-State: AFuF++ndXO1vZZJxKJXvg1mL8xcuyi689FsOQNIClogIrMr1Pc9W4dyi Bm2m5plJ7cnbg/oyUY+UPa+NNOWf1FGoe1fj31IP2acpsuD7alJU0Bn6kQgY8aTFwgYv9kBuPz5 KBldMNZ5v10zH724bAmQdOVdayHTwVkmSAcIqk+P7fft2vtsa8mMTXwuwHwanl8Hi5Drr8qaZSz nJ2ndr3SSfdwBKxMpA6eb4cBOFSqgPzTTp/u2V99WVDEUz6eklWwQrV8z2y3iBaQ== X-Received: from qtoh12.prod.google.com ([2002:ac8:46cc:0:b0:532:a6a3:7aae]) (user=namangulati job=prod-delivery.src-stubby-dispatcher) by 2002:a05:622a:345:b0:535:23ee:eb7f with SMTP id d75a77b69052e-5359f460649mr47447291cf.1.1791568429266; Fri, 09 Oct 2026 10:53:49 -0700 (PDT) Date: Fri, 9 Oct 2026 17:53:11 +0000 In-Reply-To: <20261009175314.1823347-1-namangulati@google.com> Mime-Version: 1.0 References: <20261009175314.1823347-1-namangulati@google.com> X-Mailer: git-send-email 2.56.0.385.gd3acb90ef8-goog Message-ID: <20261009175314.1823347-2-namangulati@google.com> Subject: [PATCH v4 1/4] vfio-user: add multi-fd region mmap capability From: Naman Gulati To: qemu-devel@nongnu.org Cc: John Levon , Thanos Makatos , "=?UTF-8?q?C=C3=A9dric=20Le=20Goater?=" , Alex Williamson , Pierrick Bouvier , Matt Evans , Naman Gulati Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::847; envelope-from=3LSrJagsKCgQreqerkypexmksskpi.gsquiqy-hiziprsrkry.svk@flex--namangulati.bounces.google.com; helo=mail-qt1-x847.google.com X-Spam_score_int: -95 X-Spam_score: -9.6 X-Spam_bar: --------- X-Spam_report: (-9.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_MED=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, USER_IN_DEF_DKIM_WL=-7.5, WEIRD_QUOTING=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @google.com) X-ZM-MESSAGEID: 1791568472458158500 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Extend the vfio-user protocol specification to allow servers to pass multiple file descriptors for different sparse memory areas within a single device region with capability VFIO_REGION_INFO_CAP_SPARSE_MMAP_FDS (0x8001), negotiated via the "sparse_mmap_fds" capability in VFIO_USER_VERSION. VFIO_REGION_INFO_CAP_SPARSE_MMAP_FDS defines an array of sparse mmap areas where each area contains: - offset: Start of the area within the device region (BAR). - fd_offset: Start of the mapping within the backing file descriptor. - size: Size of the mappable area. - fd_index: Zero-based index into the array of file descriptors received in the SCM_RIGHTS ancillary data of the VFIO_USER_DEVICE_GET_REGION_INFO reply message. Signed-off-by: Naman Gulati --- docs/interop/vfio-user.rst | 86 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 82 insertions(+), 4 deletions(-) diff --git a/docs/interop/vfio-user.rst b/docs/interop/vfio-user.rst index 1c92f442d2..b49781a755 100644 --- a/docs/interop/vfio-user.rst +++ b/docs/interop/vfio-user.rst @@ -125,7 +125,13 @@ Sparse Regions A region can be memory-mappable in whole or in part. When only a subset of= a region can be mapped by the client, a ``VFIO_REGION_INFO_CAP_SPARSE_MMAP`` capability is included in the region info reply. This capability describes -which portions can be mapped by the client. +which portions can be mapped by the client. When sparse mmap areas are bac= ked +by multiple distinct file descriptors, a +``VFIO_REGION_INFO_CAP_SPARSE_MMAP_FDS`` capability is included in the reg= ion +info reply instead. ``VFIO_REGION_INFO_CAP_SPARSE_MMAP`` and +``VFIO_REGION_INFO_CAP_SPARSE_MMAP_FDS`` cannot both be specified for the = same +region; however, different regions of a device may independently use either +capability. =20 .. Note:: For example, in a virtual NVMe controller, sparse regions can be used so @@ -536,6 +542,10 @@ Capabilities: | write_multiple | boolean | ``VFIO_USER_REGION_WRITE_MULTI`` messages= | | | | are supported if the value is ``true``. = | +--------------------+---------+------------------------------------------= -----+ +| sparse_mmap_fds | boolean | ``VFIO_REGION_INFO_CAP_SPARSE_MMAP_FDS`` = | +| | | capability is supported if the value is = | +| | | ``true``. = | ++--------------------+---------+------------------------------------------= -----+ =20 The ``twin_socket`` capability object holds these name/value pairs: =20 @@ -859,9 +869,11 @@ Reply * ``VFIO_REGION_INFO_FLAG_READ`` allows client read access to the region. * ``VFIO_REGION_INFO_FLAG_WRITE`` allows client write access to the regi= on. * ``VFIO_REGION_INFO_FLAG_MMAP`` specifies the client can mmap() the reg= ion. - When this flag is set, the reply will include a file descriptor in its - meta-data. On ``AF_UNIX`` sockets, the file descriptors will be passed= as - ``SCM_RIGHTS`` type ancillary data. + When this flag is set, the reply will include one or more file descrip= tors + in its meta-data (up to the number of sparse mmap areas when + ``VFIO_REGION_INFO_CAP_SPARSE_MMAP_FDS`` is present, or a single file + descriptor otherwise). On ``AF_UNIX`` sockets, the file descriptors wi= ll be + passed as ``SCM_RIGHTS`` type ancillary data. * ``VFIO_REGION_INFO_FLAG_CAPS`` indicates additional capabilities found= in the reply. =20 @@ -950,6 +962,72 @@ The VFIO sparse mmap area is defined in ```` (``struct vfio_region_info_cap_sparse_mmap``). =20 =20 +VFIO sparse mmap fds cap header +""""""""""""""""""""""""""""""" + ++----------------------+--------------------------------------+ +| Name | Value | ++=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+ +| id | VFIO_REGION_INFO_CAP_SPARSE_MMAP_FDS | ++----------------------+--------------------------------------+ +| version | 0x1 | ++----------------------+--------------------------------------+ +| next | | ++----------------------+--------------------------------------+ +| sparse mmap fds info | VFIO region info sparse mmap fds | ++----------------------+--------------------------------------+ + +This capability is defined when a region supports direct access by the cli= ent +via mmap() where different sparse mmap areas are backed by distinct file +descriptors in the ``SCM_RIGHTS`` ancillary data array. The server may only +include this capability if the client advertised ``sparse_mmap_fds`` as +``true`` in ``VFIO_USER_VERSION``. Capability ID +``VFIO_REGION_INFO_CAP_SPARSE_MMAP_FDS`` is defined as ``0x8001`` to avoid +clashing with kernel VFIO capabilities. + +VFIO region info cap sparse mmap fds +"""""""""""""""""""""""""""""""""""" + ++-----------+--------+------+ +| Name | Offset | Size | ++=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D= =3D=3D+ +| nr_areas | 0 | 4 | ++-----------+--------+------+ +| reserved | 4 | 4 | ++-----------+--------+------+ +| offset | 8 | 8 | ++-----------+--------+------+ +| fd_offset | 16 | 8 | ++-----------+--------+------+ +| size | 24 | 8 | ++-----------+--------+------+ +| fd_index | 32 | 4 | ++-----------+--------+------+ +| pad | 36 | 4 | ++-----------+--------+------+ +| ... | | | ++-----------+--------+------+ + +* *nr_areas* is the number of sparse mmap areas in the region. +* *offset*, *fd_offset*, *size*, and *fd_index* describe a single area tha= t can be + mapped by the client. There will be *nr_areas* tuples of offset, fd_offs= et, size, + fd_index, and pad. Sparse mmap areas must not overlap. +* *offset* specifies the start of the area within the device region (BAR). +* *fd_offset* specifies the start of the mapping within the backing file d= escriptor + referenced by *fd_index*. +* *size* specifies the size of the area. Zero-sized areas (*size* equal to= 0) + are not permitted, and *offset* + *size* must not exceed the region *siz= e*. +* *fd_index* is the zero-based index into the array of file descriptors + received in the ``SCM_RIGHTS`` ancillary data of the + ``VFIO_USER_DEVICE_GET_REGION_INFO`` reply message. The number of file + descriptors sent in ``SCM_RIGHTS`` must be at least 1 and must not exceed + *nr_areas*. + +If all sparse mmap areas are backed by a single file descriptor, the server +may instead send ``VFIO_REGION_INFO_CAP_SPARSE_MMAP`` and exactly one file +descriptor in ``SCM_RIGHTS`` for compatibility with older clients. + + ``VFIO_USER_DEVICE_GET_REGION_IO_FDS`` -------------------------------------- =20 --=20 2.56.0.385.gd3acb90ef8-goog From nobody Thu Oct 22 19:27:18 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=google.com ARC-Seal: i=1; a=rsa-sha256; t=1791568484; cv=none; d=zohomail.com; s=zohoarc; b=iPMe85JcdOShsGwBT770vki62VjBxGlbX5cL5R7Q1mPo7XVmEdCzkzz707ctRlXwi0yVbdjOxPIion02Oca9hlxHfDrxrPi9GIs3Q3+LwTj2H+vQm7q+RQWzTkcV4YB1jgPHdUvHeM6O/COdMtbmbJwkSoxny218verl+iyYjZw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1791568484; h=Content-Type:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=FppzXirk5nbi9kcMOQQwDE1EGZz6Q2GpCC2ECGaKeOQ=; b=Zs1hXMFcK2h4WSg7pknqr/7tRzr7MTeuDYXzyZrhxzScf6/fIwlti+cQyZ4I+3SVLgX5ylvaAreMd4zkedzXiL+nNiioysWAIq2Kkh5Sp2GmAJ2TLj7HE5xBouHrXfaGK0GReu29z2WnGzx7SIShU8x2esbw3P8DX635FRxZQM8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1791568484382895.7586617518837; Fri, 9 Oct 2026 10:54:44 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1xFEnU-0000h7-5S; Fri, 09 Oct 2026 13:54:20 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from <3LirJagsKCgUsfrfslzqfynlttlqj.htrvjrz-ij0jqstslsz.twl@flex--namangulati.bounces.google.com>) id 1xFEn5-0000V2-F2 for qemu-devel@nongnu.org; Fri, 09 Oct 2026 13:53:55 -0400 Received: from mail-qv1-xf47.google.com ([2607:f8b0:4864:20::f47]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from <3LirJagsKCgUsfrfslzqfynlttlqj.htrvjrz-ij0jqstslsz.twl@flex--namangulati.bounces.google.com>) id 1xFEn3-0006FD-28 for qemu-devel@nongnu.org; Fri, 09 Oct 2026 13:53:55 -0400 Received: by mail-qv1-xf47.google.com with SMTP id 6a1803df08f44-917a2de2cc1so1399566d6.1 for ; Fri, 09 Oct 2026 10:53:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1791568431; x=1792173231; darn=nongnu.org; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:from:to:cc:subject:date:message-id:reply-to :content-type; bh=FppzXirk5nbi9kcMOQQwDE1EGZz6Q2GpCC2ECGaKeOQ=; b=WnAdPo+wVSnt6K0X0Ap+f32VUcsY9j4b7l4JCXMYMbqpT+dIujpECn632YZiuBHVMM BHce5UriMJoIbScB7nD3Js0uX8qh3hqkKbRoZW5EP8ZUwmYO0HXeEoTm+Sc5HB3H/ep/ TtueyI9yamMwTtP7GHw+CNkkG/8dK2k9uEjGSRQ6N6U5RcebpSnWSj0pZ26W4ewnSFY9 Akc/2rutUbvKz6drdt3vO3oMz+oZKUpwq1k+f7gWfeokGWDzyAmwyTysgClWko5CPw/1 dv4hzZhSN9smQAg+zS8RRgZ0VRgjd6im128c+BkzBdaTNpaVYCjIEjnCAt8RO5uiz2RU CkPw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1791568431; x=1792173231; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=FppzXirk5nbi9kcMOQQwDE1EGZz6Q2GpCC2ECGaKeOQ=; b=cnj6abxkMHurDo7lzOYKXrm8exE83OEFKa39s0hQevpMeaVV5hH/K6lR9b0qq3iA0G n/Jsb8KF4P4+2dVm15dhprCVHu3wQ6w4bhqYAryG49gEvHh+SK2f/NPulPkTSPvS/7J0 JwcLI01baYKZaj1uJXd04qDe4B7naLL95VxJ/zENRCdUed8zsuTKu/cYcV7QoDrjdwJR XaXM0m3LNt2Z0gp+9jbsziTUU7B5VmJojBHMRY2nx1NtMpOz6T4FL/HTn4Ngxfx427af n/3AIqFDQqwb5dsLy+hKsEJ3p2ch5eBepV+5UF9uvHI68OV9jd8QynnYLchnMafyu32f //cg== X-Gm-Message-State: AFq9FYIJ5pTZCsK1hp8Ijd/tqnACEPCKSPnO87VdcDWuitm23QS6z/lt LbID7/egJfbaOHBFWrTi+6R8DudUhUXbhLazTE8eBXyUnpsff9spswYAeuyB5uU3pBmOz5MnJ4x 67WeLiGIHrVtFIMnMjMUxSB3zG9+iAp4Op9lj9/JSshxBt1DC7TLwjSZIfx8QkJ/pMsbHqiL6QH 8DUHVSeStP/2rHfT3P0v7cmjAgcU3EBa0GnqfX+L7T2YmGCoQWuM69auUrdcmeWQ== X-Received: from qtbkc3.prod.google.com ([2002:a05:622a:44c3:b0:535:27c9:d69f]) (user=namangulati job=prod-delivery.src-stubby-dispatcher) by 2002:a05:622a:1c15:b0:533:21c6:f4e2 with SMTP id d75a77b69052e-5359fa9087cmr41452201cf.20.1791568430294; Fri, 09 Oct 2026 10:53:50 -0700 (PDT) Date: Fri, 9 Oct 2026 17:53:12 +0000 In-Reply-To: <20261009175314.1823347-1-namangulati@google.com> Mime-Version: 1.0 References: <20261009175314.1823347-1-namangulati@google.com> X-Mailer: git-send-email 2.56.0.385.gd3acb90ef8-goog Message-ID: <20261009175314.1823347-3-namangulati@google.com> Subject: [PATCH v4 2/4] vfio: add 'fd' and 'fd_offset' to VFIOMmap From: Naman Gulati To: qemu-devel@nongnu.org Cc: John Levon , Thanos Makatos , "=?UTF-8?q?C=C3=A9dric=20Le=20Goater?=" , Alex Williamson , Pierrick Bouvier , Matt Evans , Naman Gulati Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::f47; envelope-from=3LirJagsKCgUsfrfslzqfynlttlqj.htrvjrz-ij0jqstslsz.twl@flex--namangulati.bounces.google.com; helo=mail-qv1-xf47.google.com X-Spam_score_int: -95 X-Spam_score: -9.6 X-Spam_bar: --------- X-Spam_report: (-9.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_MED=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, USER_IN_DEF_DKIM_WL=-7.5 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @google.com) X-ZM-MESSAGEID: 1791568486451158500 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Allow each sparse mmap subregion to specify its own file descriptor and file offset for the mmap call. Add 'fd' (set to -1 when the region fd should be used) and 'fd_offset' to VFIOMmap, and update vfio_region_mmap() to use them. Reviewed-by: Thanos Makatos Signed-off-by: Naman Gulati --- hw/vfio/vfio-region.h | 4 +++- hw/vfio/pci.c | 2 ++ hw/vfio/region.c | 26 +++++++++++++++++++------- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/hw/vfio/vfio-region.h b/hw/vfio/vfio-region.h index 58b236f113..9f6a5cf7d5 100644 --- a/hw/vfio/vfio-region.h +++ b/hw/vfio/vfio-region.h @@ -14,8 +14,10 @@ typedef struct VFIOMmap { MemoryRegion mem; void *mmap; - off_t offset; + off_t offset; /* offset within the region */ size_t size; + int fd; /* per-mmap fd, or -1 to use the region fd */ + uint64_t fd_offset; /* offset within fd for the mmap call */ } VFIOMmap; =20 typedef struct VFIODevice VFIODevice; diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index 428ab2f069..f851082114 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -1623,6 +1623,7 @@ static void vfio_pci_fixup_msix_region(VFIOPCIDevice = *vdev) vdev->msix->table_bar, 0, 0); } else { region->mmaps[0].offset =3D end; + region->mmaps[0].fd_offset +=3D end; region->mmaps[0].size =3D region->size - end; trace_vfio_msix_fixup(vdev->vbasedev.name, vdev->msix->table_bar, region->mmaps[0].offs= et, @@ -1649,6 +1650,7 @@ static void vfio_pci_fixup_msix_region(VFIOPCIDevice = *vdev) region->mmaps[0].offset + region->mmaps[0].s= ize); =20 region->mmaps[1].offset =3D end; + region->mmaps[1].fd_offset +=3D end; region->mmaps[1].size =3D region->size - end; trace_vfio_msix_fixup(vdev->vbasedev.name, vdev->msix->table_bar, region->mmaps[1].offs= et, diff --git a/hw/vfio/region.c b/hw/vfio/region.c index 54ad11a6c8..16efed2fce 100644 --- a/hw/vfio/region.c +++ b/hw/vfio/region.c @@ -189,6 +189,9 @@ static int vfio_setup_region_sparse_mmaps(VFIORegion *r= egion, sparse->areas[i].size - 1); region->mmaps[j].offset =3D sparse->areas[i].offset; region->mmaps[j].size =3D sparse->areas[i].size; + region->mmaps[j].fd =3D -1; + region->mmaps[j].fd_offset =3D region->fd_offset + + sparse->areas[i].offset; j++; } } @@ -262,6 +265,8 @@ int vfio_region_setup(Object *obj, VFIODevice *vbasedev= , VFIORegion *region, region->mmaps =3D g_new0(VFIOMmap, region->nr_mmaps); region->mmaps[0].offset =3D 0; region->mmaps[0].size =3D region->size; + region->mmaps[0].fd =3D -1; + region->mmaps[0].fd_offset =3D region->fd_offset; } else if (ret) { return ret; } @@ -354,7 +359,6 @@ int vfio_region_mmap(VFIORegion *region) off_t map_offset =3D 0; size_t align; char *name; - int fd; =20 if (!region->mem || !region->nr_mmaps) { return 0; @@ -391,8 +395,6 @@ int vfio_region_mmap(VFIORegion *region) return ret; } =20 - fd =3D vfio_device_get_region_fd(region->vbasedev, region->nr); - map_align =3D (void *)ROUND_UP((uintptr_t)map_base, (uintptr_t)align); munmap(map_base, map_align - map_base); munmap(map_align + region->size, @@ -404,12 +406,22 @@ int vfio_region_mmap(VFIORegion *region) * offsets being in ascending order. */ for (i =3D 0; i < region->nr_mmaps; i++) { + int fd =3D region->mmaps[i].fd; + + if (fd < 0) { + fd =3D vfio_device_get_region_fd(region->vbasedev, region->nr); + } + if (fd < 0) { + ret =3D -EINVAL; + munmap(map_align + map_offset, region->size - map_offset); + goto no_mmap; + } + munmap(map_align + map_offset, region->mmaps[i].offset - map_offse= t); region->mmaps[i].mmap =3D mmap(map_align + region->mmaps[i].offset, region->mmaps[i].size, prot, MAP_SHARED | MAP_FIXED, fd, - region->fd_offset + - region->mmaps[i].offset); + region->mmaps[i].fd_offset); if (region->mmaps[i].mmap =3D=3D MAP_FAILED) { ret =3D -errno; /* @@ -454,8 +466,8 @@ int vfio_region_mmap(VFIORegion *region) =20 no_mmap: trace_vfio_region_mmap_fault(memory_region_name(region->mem), i, - region->fd_offset + region->mmaps[i].offs= et, - region->fd_offset + region->mmaps[i].offs= et + + region->mmaps[i].fd_offset, + region->mmaps[i].fd_offset + region->mmaps[i].size - 1, ret); =20 region->mmaps[i].mmap =3D NULL; --=20 2.56.0.385.gd3acb90ef8-goog From nobody Thu Oct 22 19:27:18 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=google.com ARC-Seal: i=1; a=rsa-sha256; t=1791568474; cv=none; d=zohomail.com; s=zohoarc; b=YGaKDlh/brmpLwUcG3F+mLCd7034SxfI5MG/i05lA64+sy4aUM+XVtXQPqsIX3QaBugCc9/OBWn+SxLG/94ltrSLMmaYwvohUmFQTrbkVQe09cedb9NdkKXQQSS5xLSw3qJAO03d2kOOloQ6iiHZLt8cd4f9YYccM65aqmGcE6E= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1791568474; h=Content-Type:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=Mzd5o5IQRC5mpUnF9WcyCQ/We7DI2JhVUFlgIldA7t8=; b=bjH7jT0YWaWQ+LuAtMnVZJr5nW8qHZB92lJ5daQd85HNO5ZerY1dEjKjSOYEARdMS18t8ElpL2+o3BHYI2YoZSnohYgvfWKrttosoJBwxYXrR2dQ1lnre6Fxpkx5JEiHHhdUNGDkSxDh06VCTbNwfMImP9ix4B4oIamIHduUPfs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1791568474099523.9462289742626; Fri, 9 Oct 2026 10:54:34 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1xFEnA-0000VO-Dd; Fri, 09 Oct 2026 13:54:00 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from <3LyrJagsKCgYtgsgtm0rgzomuumrk.iuswks0-jk1krtutmt0.uxm@flex--namangulati.bounces.google.com>) id 1xFEn5-0000V1-Bm for qemu-devel@nongnu.org; Fri, 09 Oct 2026 13:53:55 -0400 Received: from mail-qt1-x845.google.com ([2607:f8b0:4864:20::845]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from <3LyrJagsKCgYtgsgtm0rgzomuumrk.iuswks0-jk1krtutmt0.uxm@flex--namangulati.bounces.google.com>) id 1xFEn3-0006FP-7s for qemu-devel@nongnu.org; Fri, 09 Oct 2026 13:53:55 -0400 Received: by mail-qt1-x845.google.com with SMTP id d75a77b69052e-5358515b4easo53176091cf.0 for ; Fri, 09 Oct 2026 10:53:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1791568432; x=1792173232; darn=nongnu.org; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:from:to:cc:subject:date:message-id:reply-to :content-type; bh=Mzd5o5IQRC5mpUnF9WcyCQ/We7DI2JhVUFlgIldA7t8=; b=tt6oXVZSkBHt5bl4Ieed3ElpbaEqod20BFbzxE/v/X7N+rIr/jLAYdUz0ao6Vj5A8x tGCrk8WxZX71GcXmXRV/oZL1/+WsjOQrFDt36H9wQQ2Ku/rQNJ1LF3ipFE2aUYwbKnyy GkTx6VD23HXskRACh0LWidblBXnDBtTGUtLjelqkDLB9C+2bhEFwuZGzkjqJE97T9AuG uNpPFOXgVCftW90tHMT6UEb38I2QcjkHjZRxiciwiZg3lIbT7z6V8Dmkws6cufIaDuab ttALiquoKQt1qZbA1buL7gT9KWk2y6U9/ExgAFu87QJr5d3I8Xg2XqSHv2U2FESmy+WH Q95g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1791568432; x=1792173232; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=Mzd5o5IQRC5mpUnF9WcyCQ/We7DI2JhVUFlgIldA7t8=; b=PZF6d9ogh2Q9hq2qkJAm1UQL9gxnFm6DYseJemWjn7kLoAOyivN2pE4bPx3ltKVk7h fNFPKZpw49Z7fX/AJJ21xbwt6gwSgllm7ffC74IZu84w2eK+9Glhl1Y+RXQBZd4CgwMV pddX95MGByDpzBILZV53wTiquFkipqmPUaiUvsjaqISvgfMbPMKByAxNULIKECcxXnLF GuTZOmLf7yCtsXkN8uMWkmZjX9bd5v+4pu/3idZ4HHT1dSoiNbw0Mf2+sQ+18K7ikN6o kZi0KotHgy+dfbWuwvVcqD/scEbShrPqdSGTcMunYKrnhaw9iaQB/SProhYKJZ0gbYYd ji6Q== X-Gm-Message-State: AFuF++nqWpIn4tUAU9xprA4dgMwrMh7/JWs6/1q2ggoS7udqJtad5kHw e0lnpvuKwnEzDcUt+zvqvU+ZsZHiGl0n2P4Pq3tdi33qNyBfnq48kbexyGWqMOwKtbV54Zb+CTn Q8gt/D2Kluj90/fpgLncHOyCuICLbW6OYEJVK6TTuObkSKCBqiyw2ZZ6GaZ6+t/Fc7bzOtHWzFT aWmClGxYaJV+UziGIeYZXTnEa3jpVpT9cUtqHQYGaUZpf1t90zvNEEsEJ11RGZWw== X-Received: from qvwl14.prod.google.com ([2002:ad4:4bce:0:b0:919:ad7f:e1aa]) (user=namangulati job=prod-delivery.src-stubby-dispatcher) by 2002:a05:622a:2506:b0:533:3868:1f6d with SMTP id d75a77b69052e-5359fdf53f0mr42174941cf.59.1791568431508; Fri, 09 Oct 2026 10:53:51 -0700 (PDT) Date: Fri, 9 Oct 2026 17:53:13 +0000 In-Reply-To: <20261009175314.1823347-1-namangulati@google.com> Mime-Version: 1.0 References: <20261009175314.1823347-1-namangulati@google.com> X-Mailer: git-send-email 2.56.0.385.gd3acb90ef8-goog Message-ID: <20261009175314.1823347-4-namangulati@google.com> Subject: [PATCH v4 3/4] vfio: add setup_sparse_mmaps hook to VFIODeviceIOOps From: Naman Gulati To: qemu-devel@nongnu.org Cc: John Levon , Thanos Makatos , "=?UTF-8?q?C=C3=A9dric=20Le=20Goater?=" , Alex Williamson , Pierrick Bouvier , Matt Evans , Naman Gulati Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::845; envelope-from=3LyrJagsKCgYtgsgtm0rgzomuumrk.iuswks0-jk1krtutmt0.uxm@flex--namangulati.bounces.google.com; helo=mail-qt1-x845.google.com X-Spam_score_int: -95 X-Spam_score: -9.6 X-Spam_bar: --------- X-Spam_report: (-9.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_MED=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, USER_IN_DEF_DKIM_WL=-7.5 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @google.com) X-ZM-MESSAGEID: 1791568476068158500 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a setup_sparse_mmaps callback to VFIODeviceIOOps so transport backends (such as vfio-user) can parse custom sparse mmap capabilities, falling back to vfio_default_setup_sparse_mmaps() to process shared VFIO mmap capabilities. Signed-off-by: Naman Gulati Reviewed-by: Thanos Makatos --- hw/vfio/vfio-region.h | 5 +++++ include/hw/vfio/vfio-device.h | 16 ++++++++++++++++ hw/vfio/region.c | 25 ++++++++++++++++++++++--- 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/hw/vfio/vfio-region.h b/hw/vfio/vfio-region.h index 9f6a5cf7d5..a0c9533f9f 100644 --- a/hw/vfio/vfio-region.h +++ b/hw/vfio/vfio-region.h @@ -46,4 +46,9 @@ void vfio_region_mmaps_set_enabled(VFIORegion *region, bo= ol enabled); void vfio_region_exit(VFIORegion *region); void vfio_region_finalize(VFIORegion *region); =20 +struct vfio_region_info; +int vfio_default_setup_sparse_mmaps(VFIORegion *region, + struct vfio_region_info *info, + Error **errp); + #endif /* HW_VFIO_REGION_H */ diff --git a/include/hw/vfio/vfio-device.h b/include/hw/vfio/vfio-device.h index 8472420d3f..3136e152f2 100644 --- a/include/hw/vfio/vfio-device.h +++ b/include/hw/vfio/vfio-device.h @@ -43,6 +43,7 @@ enum { =20 typedef struct VFIODeviceOps VFIODeviceOps; typedef struct VFIODeviceIOOps VFIODeviceIOOps; +typedef struct VFIORegion VFIORegion; typedef struct VFIOMigration VFIOMigration; =20 typedef struct IOMMUFDBackend IOMMUFDBackend; @@ -218,6 +219,21 @@ struct VFIODeviceIOOps { int (*get_region_info)(VFIODevice *vdev, struct vfio_region_info *info, int *fd); =20 + /** + * @setup_sparse_mmaps + * + * Parse sparse mmap capabilities for a region and initialize region->= mmaps. + * + * @region: #VFIORegion to set up + * @info: region info struct containing capabilities + * @errp: pointer to Error*, to store an error if it happens + * + * Returns 0 on success, -ENODEV if not sparse, or negative error code. + */ + int (*setup_sparse_mmaps)(VFIORegion *region, + struct vfio_region_info *info, + Error **errp); + /** * @get_irq_info * diff --git a/hw/vfio/region.c b/hw/vfio/region.c index 16efed2fce..d6cd5d4743 100644 --- a/hw/vfio/region.c +++ b/hw/vfio/region.c @@ -162,9 +162,9 @@ static int vfio_mmap_compare_offset(const void *a, cons= t void *b) return 0; } =20 -static int vfio_setup_region_sparse_mmaps(VFIORegion *region, - struct vfio_region_info *info, - Error **errp) +int vfio_default_setup_sparse_mmaps(VFIORegion *region, + struct vfio_region_info *info, + Error **errp) { struct vfio_info_cap_header *hdr; struct vfio_region_info_cap_sparse_mmap *sparse; @@ -198,6 +198,25 @@ static int vfio_setup_region_sparse_mmaps(VFIORegion *= region, =20 region->nr_mmaps =3D j; region->mmaps =3D g_realloc(region->mmaps, j * sizeof(VFIOMmap)); + return 0; +} + +static int vfio_setup_region_sparse_mmaps(VFIORegion *region, + struct vfio_region_info *info, + Error **errp) +{ + int ret, i; + + if (region->vbasedev->io_ops && + region->vbasedev->io_ops->setup_sparse_mmaps) { + ret =3D region->vbasedev->io_ops->setup_sparse_mmaps(region, info,= errp); + } else { + ret =3D vfio_default_setup_sparse_mmaps(region, info, errp); + } + + if (ret) { + return ret; + } =20 /* * Sort sparse mmaps by offset to ensure proper handling of gaps --=20 2.56.0.385.gd3acb90ef8-goog From nobody Thu Oct 22 19:27:18 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=google.com ARC-Seal: i=1; a=rsa-sha256; t=1791568456; cv=none; d=zohomail.com; s=zohoarc; b=nHMbeVD+iE9HQSVxI/T/eJNd0h0qdkPWEcrbiylSIDpPSi88mENjYZgvD/VNczkOqPfCStv791zNiCAjuBZWUAWdNSu/vK2oV8WASFzCaXqu+t49Kod1dm2RthiSj4jNH2ky5mKdXWT4jipZazfahnue0JJSfkinA2bakPuT4rg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1791568456; h=Content-Type:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=neFlIRomAUzJHtB2qDbjA3qGPB5L9JPvsWNz4Rrq2mo=; b=EsIBqEbXmRcOkhcojf6N9J7fmbOK6QBIjE2w4qW6AkFLFd+K3qsVfnHkd5M9PlDtJRBfFj0y5XZDvN7QhfGiifD2XgU1YrD0IqTrvuF9oLfnPU/OghaCRLUf531e7whCm1aLgNFRrXw75aH5OKlzxz8aMIvheJ46hlntZth8J+M= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1791568456219115.12889921524959; Fri, 9 Oct 2026 10:54:16 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1xFEnG-0000WK-TY; Fri, 09 Oct 2026 13:54:10 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from <3MCrJagsKCgcuhthun1sh0pnvvnsl.jvtxlt1-kl2lsuvunu1.vyn@flex--namangulati.bounces.google.com>) id 1xFEn6-0000VN-IT for qemu-devel@nongnu.org; Fri, 09 Oct 2026 13:54:00 -0400 Received: from mail-qt1-x847.google.com ([2607:f8b0:4864:20::847]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from <3MCrJagsKCgcuhthun1sh0pnvvnsl.jvtxlt1-kl2lsuvunu1.vyn@flex--namangulati.bounces.google.com>) id 1xFEn4-0006FT-Ca for qemu-devel@nongnu.org; Fri, 09 Oct 2026 13:53:56 -0400 Received: by mail-qt1-x847.google.com with SMTP id d75a77b69052e-53397338004so183464331cf.2 for ; Fri, 09 Oct 2026 10:53:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1791568433; x=1792173233; darn=nongnu.org; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:from:to:cc:subject:date:message-id:reply-to :content-type; bh=neFlIRomAUzJHtB2qDbjA3qGPB5L9JPvsWNz4Rrq2mo=; b=XQVckcX4FotB5bR2RnEYmFZrGRC4wbldcjPTxY23Q268CmndgNjmnZr3MeQMlcnrYZ qn7ThEpCueJYbm6JbIHKoxNHbCQmAhngWDTTzxapUJ4ud6DYjbupjEmHrvwHCh/MoyYU i3/L6ySFh2fqugSmmprFgNTEBcMrz9oILFXHAd8KSZymLD+maQs7FQ66tPkqYI7qaEL9 LDnGKxhHiZTzy9Cp4+dLI64cunzeWEELGRzfQ8uFGFnVOrf6X0WWPiGJ897cENJswJGY Uywg5maiE0gULuXg+pL9BooEhJoH529K5xN7Qj5qw1TxFVs043Xo5kXBsyuRLXt1xBsU luNA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1791568433; x=1792173233; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=neFlIRomAUzJHtB2qDbjA3qGPB5L9JPvsWNz4Rrq2mo=; b=pJQ6yi1HwwugwRCiq8FGk2l6hj8yw4Pfipsi3La8YPyaFNqH+ll0ilbn9XAyqxGI0X QuW+fpMjuQ59wTIBceW1Ha+qMBo98uQPqQRnhfnVctCr2adUvrys1oojQvdn9LZh6QnO l4k+9MT7KswdgEYlNAs+PSv47Uweu76vf0S+OjjNPNZ70KZCnhg/WY7hWb9MWOFKZVRS w+GGQA/Fi/PB68CT6PRKPtE9WGvrNxySBJF5hi5+OUsAvAdmo73bMq1vOtOyulhe1NnL lN49i1RraMUt2GbDZ69q1bOp7l+pjleEQI6iGIIvwhTTvixb5ttetGdAcuWTv1hNV+22 zY/A== X-Gm-Message-State: AFq9FYJUWJ0TFTa4GZZzLswQza9yxLto0anUD3b6gWyj6qTcM05xZ0/+ V0ZZlOka+mL9tw+A/UniW9UwDbDf45mjbtM6CTm7I9eV+hZkTvH4N/thE0oYoWEi4CaqJAvS1pa 5YQB7tP25OPHuzk/SJ5iUxp/95kaCtSor7JfIdn+ktZjPh090SwlqBL2I6ZxeX/sBrcb8XXpjeO xFwBpTqhbjG27w3gguR2B5x2Sk0pUQSj/2Mts8jo26eMUbGYC2IoZgu6XyA/1bqw== X-Received: from qtbp17-n2.prod.google.com ([2002:a05:622b:d1:20b0:535:7a68:6636]) (user=namangulati job=prod-delivery.src-stubby-dispatcher) by 2002:a05:622b:97:20b0:535:a5f8:a5c9 with SMTP id d75a77b69052e-535a5f8b5bemr22008941cf.73.1791568432502; Fri, 09 Oct 2026 10:53:52 -0700 (PDT) Date: Fri, 9 Oct 2026 17:53:14 +0000 In-Reply-To: <20261009175314.1823347-1-namangulati@google.com> Mime-Version: 1.0 References: <20261009175314.1823347-1-namangulati@google.com> X-Mailer: git-send-email 2.56.0.385.gd3acb90ef8-goog Message-ID: <20261009175314.1823347-5-namangulati@google.com> Subject: [PATCH v4 4/4] vfio-user: support multiple FDs for sparse mmap regions From: Naman Gulati To: qemu-devel@nongnu.org Cc: John Levon , Thanos Makatos , "=?UTF-8?q?C=C3=A9dric=20Le=20Goater?=" , Alex Williamson , Pierrick Bouvier , Matt Evans , Naman Gulati Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::847; envelope-from=3MCrJagsKCgcuhthun1sh0pnvvnsl.jvtxlt1-kl2lsuvunu1.vyn@flex--namangulati.bounces.google.com; helo=mail-qt1-x847.google.com X-Spam_score_int: -95 X-Spam_score: -9.6 X-Spam_bar: --------- X-Spam_report: (-9.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_MED=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, USER_IN_DEF_DKIM_WL=-7.5 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @google.com) X-ZM-MESSAGEID: 1791568458032158500 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add client support for capability VFIO_REGION_INFO_CAP_SPARSE_MMAP_FDS (capability ID 0x8001) in vfio-user, and advertise support via the "sparse_mmap_fds" capability in VFIO_USER_VERSION. Update vfio_user_device_io_get_region_info() to receive multiple file descriptors passed in SCM_RIGHTS ancillary data for a region, store them in VFIOUserProxy, and implement setup_sparse_mmaps in vfio_user_device_io_ops_sock to validate and populate per-area file descriptors and fd_offset values. Signed-off-by: Naman Gulati --- hw/vfio-user/protocol.h | 35 +++++++++++--- hw/vfio-user/proxy.h | 2 + hw/vfio-user/device.c | 102 +++++++++++++++++++++++++++++++++++++--- hw/vfio-user/proxy.c | 46 ++++++++++++++++-- 4 files changed, 168 insertions(+), 17 deletions(-) diff --git a/hw/vfio-user/protocol.h b/hw/vfio-user/protocol.h index c478d1353f..b823689254 100644 --- a/hw/vfio-user/protocol.h +++ b/hw/vfio-user/protocol.h @@ -15,6 +15,8 @@ * SPDX-License-Identifier: GPL-2.0-or-later */ =20 +#define VFIO_USER_MAX_REGIONS 100 + typedef struct { uint16_t id; uint16_t command; @@ -69,12 +71,13 @@ typedef struct { #define VFIO_USER_CAP "capabilities" =20 /* "capabilities" members */ -#define VFIO_USER_CAP_MAX_FDS "max_msg_fds" -#define VFIO_USER_CAP_MAX_XFER "max_data_xfer_size" -#define VFIO_USER_CAP_PGSIZES "pgsizes" -#define VFIO_USER_CAP_MAP_MAX "max_dma_maps" -#define VFIO_USER_CAP_MIGR "migration" -#define VFIO_USER_CAP_MULTI "write_multiple" +#define VFIO_USER_CAP_MAX_FDS "max_msg_fds" +#define VFIO_USER_CAP_MAX_XFER "max_data_xfer_size" +#define VFIO_USER_CAP_PGSIZES "pgsizes" +#define VFIO_USER_CAP_MAP_MAX "max_dma_maps" +#define VFIO_USER_CAP_MIGR "migration" +#define VFIO_USER_CAP_MULTI "write_multiple" +#define VFIO_USER_CAP_SPARSE_MMAP_FDS "sparse_mmap_fds" =20 /* "migration" members */ #define VFIO_USER_CAP_PGSIZE "pgsize" @@ -166,6 +169,26 @@ typedef struct { uint64_t offset; } VFIOUserRegionInfo; =20 +/* + * VFIO_REGION_INFO_CAP_SPARSE_MMAP_FDS + */ +#define VFIO_REGION_INFO_CAP_SPARSE_MMAP_FDS 0x8001 + +struct vfio_region_sparse_mmap_fd_area { + uint64_t offset; + uint64_t fd_offset; + uint64_t size; + uint32_t fd_index; + uint32_t pad; +}; + +struct vfio_region_info_cap_sparse_mmap_fds { + struct vfio_info_cap_header header; + uint32_t nr_areas; + uint32_t reserved; + struct vfio_region_sparse_mmap_fd_area areas[]; +}; + /* * VFIO_USER_DEVICE_GET_IRQ_INFO * imported from struct vfio_irq_info diff --git a/hw/vfio-user/proxy.h b/hw/vfio-user/proxy.h index 7b97460cc5..4b9834a436 100644 --- a/hw/vfio-user/proxy.h +++ b/hw/vfio-user/proxy.h @@ -72,6 +72,7 @@ typedef struct VFIOUserProxy { AioContext *ctx; QEMUBH *req_bh; bool async_ops; + VFIOUserFDs *region_fds[VFIO_USER_MAX_REGIONS]; =20 /* * above only changed when BQL is held @@ -111,6 +112,7 @@ bool vfio_user_validate_version(VFIOUserProxy *proxy, E= rror **errp); =20 VFIOUserFDs *vfio_user_getfds(int numfds); void vfio_user_putfds(VFIOUserMsg *msg); +void vfio_user_free_fds(VFIOUserFDs *fds); =20 void vfio_user_disable_posted_writes(VFIOUserProxy *proxy); =20 diff --git a/hw/vfio-user/device.c b/hw/vfio-user/device.c index 1a01e748cd..5c63c83a7c 100644 --- a/hw/vfio-user/device.c +++ b/hw/vfio-user/device.c @@ -14,12 +14,14 @@ =20 #include "hw/vfio-user/device.h" #include "hw/vfio-user/trace.h" +#include "hw/vfio/vfio-region.h" +#include "hw/vfio/vfio-helpers.h" +#include "hw/vfio/trace.h" =20 /* * These are to defend against a malign server trying * to force us to run out of memory. */ -#define VFIO_USER_MAX_REGIONS 100 #define VFIO_USER_MAX_IRQS 50 =20 bool vfio_user_get_device_info(VFIOUserProxy *proxy, @@ -209,14 +211,17 @@ static int vfio_user_device_io_get_region_info(VFIODe= vice *vbasedev, struct vfio_region_info *in= fo, int *fd) { - VFIOUserFDs fds =3D { 0, 1, fd}; - int ret; + int fds[VFIO_USER_MAX_MAX_FDS]; + VFIOUserFDs user_fds =3D { 0, VFIO_USER_MAX_MAX_FDS, fds }; + int i, ret; + + *fd =3D -1; =20 if (info->index > vbasedev->num_initial_regions) { return -EINVAL; } =20 - ret =3D vfio_user_get_region_info(vbasedev->proxy, info, &fds); + ret =3D vfio_user_get_region_info(vbasedev->proxy, info, &user_fds); if (ret) { return ret; } @@ -225,10 +230,29 @@ static int vfio_user_device_io_get_region_info(VFIODe= vice *vbasedev, if ((info->flags & VFIO_REGION_INFO_FLAG_CAPS) && (info->cap_offset < sizeof(*info) || info->cap_offset + sizeof(struct vfio_info_cap_header) > info-= >argsz)) { - return -EINVAL; + ret =3D -EINVAL; + } else if (vfio_get_region_info_cap(info, + VFIO_REGION_INFO_CAP_SPARSE_MMAP_F= DS)) { + if (info->index < VFIO_USER_MAX_REGIONS && user_fds.recv_fds > 0) { + VFIOUserFDs *saved =3D vfio_user_getfds(user_fds.recv_fds); + + saved->recv_fds =3D user_fds.recv_fds; + memcpy(saved->fds, fds, user_fds.recv_fds * sizeof(int)); + vfio_user_free_fds(vbasedev->proxy->region_fds[info->index]); + vbasedev->proxy->region_fds[info->index] =3D saved; + return 0; + } + } else if (user_fds.recv_fds > 0) { + *fd =3D fds[0]; + fds[0] =3D -1; } =20 - return 0; + for (i =3D 0; i < user_fds.recv_fds; i++) { + if (fds[i] >=3D 0) { + close(fds[i]); + } + } + return ret; } =20 static int vfio_user_device_io_get_irq_info(VFIODevice *vbasedev, @@ -518,12 +542,76 @@ static int vfio_user_device_io_region_write(VFIODevic= e *vbasedev, uint8_t index, /* * Socket-based io_ops */ +static int vfio_user_device_io_setup_sparse_mmaps(VFIORegion *region, + struct vfio_region_info = *info, + Error **errp) +{ + struct vfio_info_cap_header *hdr; + struct vfio_region_info_cap_sparse_mmap_fds *sparse_fds; + VFIOUserFDs *user_fds =3D NULL; + int i; + + hdr =3D vfio_get_region_info_cap(info, VFIO_REGION_INFO_CAP_SPARSE_MMA= P_FDS); + if (!hdr) { + return vfio_default_setup_sparse_mmaps(region, info, errp); + } + + if (vfio_get_region_info_cap(info, VFIO_REGION_INFO_CAP_SPARSE_MMAP)) { + error_setg(errp, "%s: region %d cannot specify both " + "SPARSE_MMAP and SPARSE_MMAP_FDS", __func__, region->nr= ); + return -EINVAL; + } + + sparse_fds =3D container_of(hdr, struct vfio_region_info_cap_sparse_mm= ap_fds, + header); + + trace_vfio_region_sparse_mmap_header(region->vbasedev->name, + region->nr, sparse_fds->nr_areas); + + if (region->nr < VFIO_USER_MAX_REGIONS) { + user_fds =3D region->vbasedev->proxy->region_fds[region->nr]; + } + if (!user_fds || user_fds->recv_fds > sparse_fds->nr_areas) { + error_setg(errp, "%s: invalid fd count %d for %u sparse mmap areas= " + "in region %d", __func__, + user_fds ? user_fds->recv_fds : 0, + sparse_fds->nr_areas, region->nr); + return -EINVAL; + } + + region->mmaps =3D g_new0(VFIOMmap, sparse_fds->nr_areas); + + for (i =3D 0; i < sparse_fds->nr_areas; i++) { + struct vfio_region_sparse_mmap_fd_area *area =3D &sparse_fds->area= s[i]; + + if (area->size =3D=3D 0 || area->offset > region->size || + area->size > region->size - area->offset || + area->fd_index >=3D user_fds->recv_fds) { + error_setg(errp, "%s: invalid sparse mmap area %d in region %d= ", + __func__, i, region->nr); + g_free(region->mmaps); + region->mmaps =3D NULL; + return -EINVAL; + } + + trace_vfio_region_sparse_mmap_entry(i, area->offset, + area->offset + area->size - 1); + region->mmaps[i].offset =3D area->offset; + region->mmaps[i].fd_offset =3D area->fd_offset; + region->mmaps[i].size =3D area->size; + region->mmaps[i].fd =3D user_fds->fds[area->fd_index]; + } + + region->nr_mmaps =3D sparse_fds->nr_areas; + return 0; +} + VFIODeviceIOOps vfio_user_device_io_ops_sock =3D { .device_feature =3D vfio_user_device_io_device_feature, .get_region_info =3D vfio_user_device_io_get_region_info, + .setup_sparse_mmaps =3D vfio_user_device_io_setup_sparse_mmaps, .get_irq_info =3D vfio_user_device_io_get_irq_info, .set_irqs =3D vfio_user_device_io_set_irqs, .region_read =3D vfio_user_device_io_region_read, .region_write =3D vfio_user_device_io_region_write, - }; diff --git a/hw/vfio-user/proxy.c b/hw/vfio-user/proxy.c index 197aee07bf..44e2a839b0 100644 --- a/hw/vfio-user/proxy.c +++ b/hw/vfio-user/proxy.c @@ -363,6 +363,8 @@ static int vfio_user_recv_one(VFIOUserProxy *proxy, Err= or **errp) } =20 memcpy(msg->fds->fds, fdp, numfds * sizeof(int)); + } else if (msg->fds !=3D NULL) { + msg->fds->recv_fds =3D 0; } =20 /* @@ -740,6 +742,10 @@ bool vfio_user_send_wait(VFIOUserProxy *proxy, VFIOUse= rHdr *hdr, =20 qemu_mutex_unlock(&proxy->lock); =20 + if (!ok && fds !=3D NULL) { + fds->recv_fds =3D 0; + } + return ok; } =20 @@ -867,17 +873,30 @@ void vfio_user_send_error(VFIOUserProxy *proxy, VFIOU= serHdr *hdr, int error) } =20 /* - * Close FDs erroneously received in an incoming request. + * Close and free received FDs. */ -void vfio_user_putfds(VFIOUserMsg *msg) +void vfio_user_free_fds(VFIOUserFDs *fds) { - VFIOUserFDs *fds =3D msg->fds; int i; =20 + if (!fds) { + return; + } + for (i =3D 0; i < fds->recv_fds; i++) { - close(fds->fds[i]); + if (fds->fds[i] >=3D 0) { + close(fds->fds[i]); + } } g_free(fds); +} + +/* + * Close FDs erroneously received in an incoming request. + */ +void vfio_user_putfds(VFIOUserMsg *msg) +{ + vfio_user_free_fds(msg->fds); msg->fds =3D NULL; } =20 @@ -967,6 +986,7 @@ void vfio_user_set_handler(VFIODevice *vbasedev, void vfio_user_disconnect(VFIOUserProxy *proxy) { VFIOUserMsg *r1, *r2; + int i; =20 qemu_mutex_lock(&proxy->lock); =20 @@ -1027,6 +1047,10 @@ void vfio_user_disconnect(VFIOUserProxy *proxy) vfio_user_iothread =3D NULL; } =20 + for (i =3D 0; i < VFIO_USER_MAX_REGIONS; i++) { + vfio_user_free_fds(proxy->region_fds[i]); + } + g_free(proxy->sockname); g_free(proxy); } @@ -1214,6 +1238,18 @@ static bool check_multi(VFIOUserProxy *proxy, QObjec= t *qobj, Error **errp) return true; } =20 +static bool check_sparse_mmap_fds(VFIOUserProxy *proxy, QObject *qobj, + Error **errp) +{ + QBool *qb =3D qobject_to(QBool, qobj); + + if (qb =3D=3D NULL) { + error_setg(errp, "malformed %s", VFIO_USER_CAP_SPARSE_MMAP_FDS); + return false; + } + return true; +} + static struct cap_entry caps_cap[] =3D { { VFIO_USER_CAP_MAX_FDS, check_max_fds }, { VFIO_USER_CAP_MAX_XFER, check_max_xfer }, @@ -1221,6 +1257,7 @@ static struct cap_entry caps_cap[] =3D { { VFIO_USER_CAP_MAP_MAX, check_max_dma }, { VFIO_USER_CAP_MIGR, check_migr }, { VFIO_USER_CAP_MULTI, check_multi }, + { VFIO_USER_CAP_SPARSE_MMAP_FDS, check_sparse_mmap_fds }, { NULL } }; =20 @@ -1280,6 +1317,7 @@ static GString *caps_json(void) qdict_put_int(capdict, VFIO_USER_CAP_PGSIZES, VFIO_USER_DEF_PGSIZE); qdict_put_int(capdict, VFIO_USER_CAP_MAP_MAX, VFIO_USER_DEF_MAP_MAX); qdict_put_bool(capdict, VFIO_USER_CAP_MULTI, true); + qdict_put_bool(capdict, VFIO_USER_CAP_SPARSE_MMAP_FDS, true); =20 qdict_put_obj(dict, VFIO_USER_CAP, QOBJECT(capdict)); =20 --=20 2.56.0.385.gd3acb90ef8-goog