From nobody Wed Aug 26 07:25:09 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=1786491627; cv=none; d=zohomail.com; s=zohoarc; b=aQBCLJsLqe0tsQpCpRb5Q6B6Rbc9E+J0HA6Zz4G0yPppXYqEHUuanP9pNZdBgALjS6y22FtYVB+rxhZ4Hov+Sxh2hiltuIUsmzWAN9vPu3uQwLAYJwOF1YKUT1oHSXGGV8PM4es0bTt16V496Xs6TqZY7RSLTnWEZAc+4dxLRV8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1786491627; 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:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=ccKPU2BAjELGM/MWXQjgcWGJFuMdQ51Hoatxp1Nt9uM=; b=OYyng3Cjhh1neKouCg6ACBJNDrUMSFXsD5yUVIAaFTzBoFomF4YMGTFPoRu5A35rkVZapyhrvjMQB5QrlZVooeRO9x2rZn+GG9yyzTTR9A9QHau/6tc8m9ENC/OrHhmicFIwwG12nlfawjXTEh7IKNVYv6YsAVizkWFqkQjmBPs= 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 1786491627217396.82376084364626; Tue, 11 Aug 2026 16:40:27 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wtw4i-0004T7-QO; Tue, 11 Aug 2026 19:40:04 -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 <3wbJ7agsKCnAbOaObUiZOhWUccUZS.QcaeSai-RSjSZbcbUbi.cfU@flex--namangulati.bounces.google.com>) id 1wtw4e-0004RS-Ab for qemu-devel@nongnu.org; Tue, 11 Aug 2026 19:40:00 -0400 Received: from mail-qk1-x745.google.com ([2607:f8b0:4864:20::745]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from <3wbJ7agsKCnAbOaObUiZOhWUccUZS.QcaeSai-RSjSZbcbUbi.cfU@flex--namangulati.bounces.google.com>) id 1wtw4b-00089M-8v for qemu-devel@nongnu.org; Tue, 11 Aug 2026 19:40:00 -0400 Received: by mail-qk1-x745.google.com with SMTP id af79cd13be357-934956beec8so90517085a.0 for ; Tue, 11 Aug 2026 16:39:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1786491586; x=1787096386; 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=ccKPU2BAjELGM/MWXQjgcWGJFuMdQ51Hoatxp1Nt9uM=; b=Io5lt9Oqvi7jcv5DkupRcLoJdMB1q2gmoz/b0qbxbPo974JNN9a0RxWmsP2qKlrgJG XLYktVZgguIwFIY9Plt40QVMYckwqYFAUYDGit2Ux5veHcYceWnFPOeuykqbV7s5DnGE KDWacKBOviMJ6cWAXHDBzxuyg1yV1oPyYLwn6mdMY3JTtIkRWr8XeB6iho1+GwoXYYLH EZ0YZJ80w5Lj6s7YZSx0AVW3say7lsjXqo1lWlxI0K48gHGYEnQAza7nq5FTGWWnZPWI a993VZQjs/tXMXZ+m03JLLcD3/22cRdK/yqvu++Q8iA90aC2ICPxKepbpfer8ec2Ke+Y ANUQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786491586; x=1787096386; 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=ccKPU2BAjELGM/MWXQjgcWGJFuMdQ51Hoatxp1Nt9uM=; b=Do1M5WJHYVLkQo/mqFdQ+9p914BwxkKfN5FT53cONmvFPzE7LKXS+YQ5Buv5exewrz yulqOStRhPOcalii9/lYLoUIGLzHwPfvDPQdgf1IEC4zYjEnUjtSy0b0swFoC+pJVkih uojaxNuSrVWEn2n33fQFaGjVdCP8obXH/EyCzDsrqkycl/xYjS2nUhLz/A2NoNf0JWR2 YdlDYnsvCZBBBryJ8/m6hBMGS8r8oHKclInwVS2GG2/RZZaqbXl/dxDbanJy3+JX3s8D OPw4D5A8mOHRkskaojCC6zcHpv1SSfCH76NMv/6MfjyIaw2Dp5N29CJqFOavfjMpti14 QfYQ== X-Gm-Message-State: AOJu0YxzNrFSRWtmGwaUYoUzQFfsfu5KS6II9VEZiJywW2dY6vgx2Zsw jM156r0JLLTZfRKRvzcSAPbmA4OPn8a5aZL17sz7kvXb5ClgVEbtsDcwt1kXmiplUPYtrx6+4U9 L1d/TnUJKmKWj4PBEDvuHNnePB5qGsRCTeaGDXrPWeaniQvh4+wYhbAKBQgWpplxnXOva9mRkPj fDY8G8t/LT0n3d67OpiPwVknhCA0PKMo4TxJ1+zKprYC33jlFdwabFjavrIQ9iwA== X-Received: from qknqw9.prod.google.com ([2002:a05:620a:8b09:b0:930:f7e0:e8b4]) (user=namangulati job=prod-delivery.src-stubby-dispatcher) by 2002:a05:620a:a707:b0:936:8c1e:b531 with SMTP id af79cd13be357-936b3a30c58mr108855285a.10.1786491585389; Tue, 11 Aug 2026 16:39:45 -0700 (PDT) Date: Tue, 11 Aug 2026 23:39:28 +0000 In-Reply-To: <20260811233930.401797-1-namangulati@google.com> Mime-Version: 1.0 References: <20260811233930.401797-1-namangulati@google.com> X-Mailer: git-send-email 2.55.0.679.g6767b8d81c-goog Message-ID: <20260811233930.401797-2-namangulati@google.com> Subject: [RFC PATCH 1/3] 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::745; envelope-from=3wbJ7agsKCnAbOaObUiZOhWUccUZS.QcaeSai-RSjSZbcbUbi.cfU@flex--namangulati.bounces.google.com; helo=mail-qk1-x745.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: 1786491629477158500 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. 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 | 71 +++++++++++++++++++++++++++++++++++--- 1 file changed, 67 insertions(+), 4 deletions(-) diff --git a/docs/interop/vfio-user.rst b/docs/interop/vfio-user.rst index 1c92f442d2..5744f58e31 100644 --- a/docs/interop/vfio-user.rst +++ b/docs/interop/vfio-user.rst @@ -125,7 +125,10 @@ 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. =20 .. Note:: For example, in a virtual NVMe controller, sparse regions can be used so @@ -859,9 +862,9 @@ 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. On ``AF_UNIX`` sockets, the file descriptors will be= passed + as ``SCM_RIGHTS`` type ancillary data. * ``VFIO_REGION_INFO_FLAG_CAPS`` indicates additional capabilities found= in the reply. =20 @@ -950,6 +953,66 @@ 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. Capability ID +``VFIO_REGION_INFO_CAP_SPARSE_MMAP_FDS`` is defined as 16 (0x10) 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. +* *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*. +* *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. + +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.55.0.679.g6767b8d81c-goog From nobody Wed Aug 26 07:25:09 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=1786491634; cv=none; d=zohomail.com; s=zohoarc; b=U7wFc7/Rfd6feQ30Ht8MOyP/rIv6yVYA8EoKB3HmbrEi7BbaCH0cKw4kDwl9snmtADg0LxbF3W977hX0NldD2zS24Umfm5HAmgVCX2VuAr5aZPs8VZytj/fBWKDgjpI1uowbvtRmaWpQ6MuWDpXAtdJILnnzyJ012nIdGDD2hxo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1786491634; 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:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=vsSsUaWkE9fwhAgZ2+bdUQDI55jmxvdXVAy5V/8lZmU=; b=kAfLGIgNaiZmPnkvPOdrWV/OLEkodqiMvF7nIVyR6grnQccmC2ZX09TJTb8iw6rZH8L/rlE82j8Wtw710FYtVeNK9nRuE5QsrVLiZLf+gJp9lL1kJYnE8HpztSr2BPJp5RElhqcjhs7BHw4LG/RsRbDgrhB4+0r4oKEREeKgpLo= 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 1786491634299276.9399528306626; Tue, 11 Aug 2026 16:40:34 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wtw4k-0004UJ-LF; Tue, 11 Aug 2026 19:40:06 -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 <3wrJ7agsKCnEcPbPcVjaPiXVddVaT.RdbfTbj-STkTacdcVcj.dgV@flex--namangulati.bounces.google.com>) id 1wtw4i-0004Sh-9M for qemu-devel@nongnu.org; Tue, 11 Aug 2026 19:40:04 -0400 Received: from mail-qt1-x848.google.com ([2607:f8b0:4864:20::848]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from <3wrJ7agsKCnEcPbPcVjaPiXVddVaT.RdbfTbj-STkTacdcVcj.dgV@flex--namangulati.bounces.google.com>) id 1wtw4b-00089g-8y for qemu-devel@nongnu.org; Tue, 11 Aug 2026 19:40:00 -0400 Received: by mail-qt1-x848.google.com with SMTP id d75a77b69052e-52d28f8737eso8118511cf.2 for ; Tue, 11 Aug 2026 16:39:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1786491587; x=1787096387; 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=vsSsUaWkE9fwhAgZ2+bdUQDI55jmxvdXVAy5V/8lZmU=; b=WMiSRB97fC+zFmx283T9vqJ7+yXQ1thLozqu6FHVAZEXF9p+GXt9Bs1KlpWpa/Xd/f xGPkdicplRUn9CesehwiwvOEXIwPEAwRwhVz42GZe4RNb/3dey/vGIeU53Z0FQXbSHDp BnGRAmdEIzR9HVycVVXZh6VgBvI+DDO1X1Oe3yvhlPNvClpMuKJKyGuETxWbG+XtwP26 ssvQQpiJFjU2y7DX+lcpZCxqM0AqdMyhM4NfCSJieHCp+8B5udS3zHqpBF0jypT+5IWS 7ed1BCqgN0k+35pNWZJwaPKaOvZ7M2B0RpEQ4m7d0EFrqQqc/Xk66ihKQt4qinK1tAdG P0Lw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786491587; x=1787096387; 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=vsSsUaWkE9fwhAgZ2+bdUQDI55jmxvdXVAy5V/8lZmU=; b=P2ZE6eDv95EYRps+zk2eC6FwbaCKysyFl9eQzFpLqSi+HPUjn0P4Ah7Y8fpHD+ENMW OwUEajAJNjyHEauGXh8y8XsE63kZ54MtMh8Z99wF2zCvkeqGS6U90Rpa6LxpwzFlQ4ou Tz5qRUNuVvUNhlRv+9CcP0zBCpRSLGEmvHmbQbn2rkgW1XR7Uo3bYPAnt6oI7doTTDxn CLmdzyHaxm685EGRmm6NxPTG6GccRG9ScUnByx+5Bg6ICacqncEodKE3QCdNcyLNbpun pn3Bw/CprhzN/3olmxnMTZjmJ+QKFlmEMY3DJ14GhGSyiqpaRynJVZmJ/Ezg9WPWi6rz VTcw== X-Gm-Message-State: AOJu0YxV0PNkYnk5gTaYmnC3Ffn+GHOpKCrjVn2+EiWQD6W07Go62aR3 i/tobOMakz4QmmD26A7e3RaOVVExyYosy8RGu4Uo3bH3flNdlWFYGjQbp7Vo68+G50wo9H10Mgi J7eUVpcZBPDWUNrEV8HVzsI5RhjLdRV+R4WFI43nTA6KLK+L/JGwLPMsEi1LZ5NLwPAH43aHhJD kjr9n0608EmLPCe22Xcxp04F9saQSCSGG9BZkczQYJ6czx/EwogJa+UpbzVMdeKQ== X-Received: from qtvl9.prod.google.com ([2002:ac8:4cc9:0:b0:51c:9d78:8252]) (user=namangulati job=prod-delivery.src-stubby-dispatcher) by 2002:a05:622a:1a8c:b0:519:55c0:a1e5 with SMTP id d75a77b69052e-52d646afa6fmr8285021cf.8.1786491586365; Tue, 11 Aug 2026 16:39:46 -0700 (PDT) Date: Tue, 11 Aug 2026 23:39:29 +0000 In-Reply-To: <20260811233930.401797-1-namangulati@google.com> Mime-Version: 1.0 References: <20260811233930.401797-1-namangulati@google.com> X-Mailer: git-send-email 2.55.0.679.g6767b8d81c-goog Message-ID: <20260811233930.401797-3-namangulati@google.com> Subject: [RFC PATCH 2/3] vfio: mmap sparse regions backed by multiple FDs 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::848; envelope-from=3wrJ7agsKCnEcPbPcVjaPiXVddVaT.RdbfTbj-STkTacdcVcj.dgV@flex--namangulati.bounces.google.com; helo=mail-qt1-x848.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: 1786491636520158500 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Generalize QEMU's VFIO core layer to support mapping sparse memory subregions from distinct file descriptors within a single device region. Replace list of region_fds in VFIODevice with a collection of struct VFIORegionFDs that internally holds a collection of FDs to mmap per region. Add setup_sparse_mmaps hook to VFIODeviceIOOps to allow transport backends (such as vfio-user) to handle custom sparse mmap capabilities, falling back to default kernel VFIO sparse parsing. Store per-subregion fd_offset in struct VFIOMmap to properly address the mmap call for a subregion. Signed-off-by: Naman Gulati --- hw/vfio-user/device.c | 12 ++++++--- hw/vfio/device.c | 50 +++++++++++++++++++---------------- hw/vfio/region.c | 41 ++++++++++++++++++++++------ hw/vfio/vfio-region.h | 8 ++++++ include/hw/vfio/vfio-device.h | 29 +++++++++++++++++--- 5 files changed, 102 insertions(+), 38 deletions(-) diff --git a/hw/vfio-user/device.c b/hw/vfio-user/device.c index b8d2b7c1a8..9c4e10c1fd 100644 --- a/hw/vfio-user/device.c +++ b/hw/vfio-user/device.c @@ -169,10 +169,10 @@ static int vfio_user_get_region_info(VFIOUserProxy *p= roxy, } =20 static int vfio_user_device_io_get_region_info(VFIODevice *vbasedev, - struct vfio_region_info *in= fo, - int *fd) + struct vfio_region_info *in= fo) { - VFIOUserFDs fds =3D { 0, 1, fd}; + int fd =3D -1; + VFIOUserFDs fds =3D { 0, 1, &fd }; int ret; =20 if (info->index > vbasedev->num_initial_regions) { @@ -184,6 +184,12 @@ static int vfio_user_device_io_get_region_info(VFIODev= ice *vbasedev, return ret; } =20 + if (fds.recv_fds > 0 && info->index < vbasedev->num_initial_regions) { + vbasedev->region_fds[info->index].fds =3D g_new0(int, 1); + vbasedev->region_fds[info->index].nr_fds =3D 1; + vbasedev->region_fds[info->index].fds[0] =3D fd; + } + /* cap_offset in valid area */ if ((info->flags & VFIO_REGION_INFO_FLAG_CAPS) && (info->cap_offset < sizeof(*info) || info->cap_offset > info->args= z)) { diff --git a/hw/vfio/device.c b/hw/vfio/device.c index 1a7f8088aa..ea571e33ba 100644 --- a/hw/vfio/device.c +++ b/hw/vfio/device.c @@ -202,7 +202,6 @@ int vfio_device_get_region_info(VFIODevice *vbasedev, i= nt index, struct vfio_region_info **info) { size_t argsz =3D sizeof(struct vfio_region_info); - int fd =3D -1; int ret; =20 /* @@ -226,7 +225,7 @@ int vfio_device_get_region_info(VFIODevice *vbasedev, i= nt index, retry: (*info)->argsz =3D argsz; =20 - ret =3D vbasedev->io_ops->get_region_info(vbasedev, *info, &fd); + ret =3D vbasedev->io_ops->get_region_info(vbasedev, *info); if (ret !=3D 0) { g_free(*info); *info =3D NULL; @@ -237,9 +236,14 @@ retry: argsz =3D (*info)->argsz; *info =3D g_realloc(*info, argsz); =20 - if (fd !=3D -1) { - close(fd); - fd =3D -1; + if (index < vbasedev->num_initial_regions && + vbasedev->region_fds !=3D NULL) { + for (int j =3D 0; j < vbasedev->region_fds[index].nr_fds; j++)= { + close(vbasedev->region_fds[index].fds[j]); + } + g_free(vbasedev->region_fds[index].fds); + vbasedev->region_fds[index].fds =3D NULL; + vbasedev->region_fds[index].nr_fds =3D 0; } =20 goto retry; @@ -248,19 +252,22 @@ retry: if (index < vbasedev->num_initial_regions) { /* fill cache */ vbasedev->reginfo[index] =3D *info; - if (vbasedev->region_fds !=3D NULL) { - vbasedev->region_fds[index] =3D fd; - } } =20 return 0; } =20 -int vfio_device_get_region_fd(VFIODevice *vbasedev, int index) +int vfio_device_get_region_fd(VFIODevice *vbasedev, int index, + uint32_t fd_index) { - return vbasedev->region_fds ? - vbasedev->region_fds[index] : - vbasedev->fd; + if (!vbasedev->region_fds) { + return vbasedev->fd; + } + if (index < 0 || index >=3D vbasedev->num_initial_regions || + fd_index >=3D vbasedev->region_fds[index].nr_fds) { + return -1; + } + return vbasedev->region_fds[index].fds[fd_index]; } =20 int vfio_device_get_region_info_type(VFIODevice *vbasedev, uint32_t type, @@ -480,7 +487,6 @@ void vfio_device_detach(VFIODevice *vbasedev) void vfio_device_prepare(VFIODevice *vbasedev, VFIOContainer *bcontainer, struct vfio_device_info *info) { - int i; =20 vbasedev->num_irqs =3D info->num_irqs; vbasedev->num_initial_regions =3D info->num_regions; @@ -495,10 +501,8 @@ void vfio_device_prepare(VFIODevice *vbasedev, VFIOCon= tainer *bcontainer, vbasedev->reginfo =3D g_new0(struct vfio_region_info *, vbasedev->num_initial_regions); if (vbasedev->use_region_fds) { - vbasedev->region_fds =3D g_new0(int, vbasedev->num_initial_regions= ); - for (i =3D 0; i < vbasedev->num_initial_regions; i++) { - vbasedev->region_fds[i] =3D -1; - } + vbasedev->region_fds =3D g_new0(VFIORegionFDs, + vbasedev->num_initial_regions); } } =20 @@ -508,8 +512,11 @@ void vfio_device_unprepare(VFIODevice *vbasedev) =20 for (i =3D 0; i < vbasedev->num_initial_regions; i++) { g_free(vbasedev->reginfo[i]); - if (vbasedev->region_fds !=3D NULL && vbasedev->region_fds[i] !=3D= -1) { - close(vbasedev->region_fds[i]); + if (vbasedev->region_fds !=3D NULL) { + for (int j =3D 0; j < vbasedev->region_fds[i].nr_fds; j++) { + close(vbasedev->region_fds[i].fds[j]); + } + g_free(vbasedev->region_fds[i].fds); } } =20 @@ -592,13 +599,10 @@ static int vfio_device_io_device_feature(VFIODevice *= vbasedev, } =20 static int vfio_device_io_get_region_info(VFIODevice *vbasedev, - struct vfio_region_info *info, - int *fd) + struct vfio_region_info *info) { int ret; =20 - *fd =3D -1; - ret =3D ioctl(vbasedev->fd, VFIO_DEVICE_GET_REGION_INFO, info); =20 return ret < 0 ? -errno : ret; diff --git a/hw/vfio/region.c b/hw/vfio/region.c index dbde339180..3a555e574c 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; @@ -188,6 +188,8 @@ static int vfio_setup_region_sparse_mmaps(VFIORegion *r= egion, sparse->areas[i].offset + sparse->areas[i].size - 1); region->mmaps[j].offset =3D sparse->areas[i].offset; + region->mmaps[j].fd_offset =3D region->fd_offset + + sparse->areas[i].offset; region->mmaps[j].size =3D sparse->areas[i].size; j++; } @@ -195,6 +197,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 @@ -261,6 +282,7 @@ int vfio_region_setup(Object *obj, VFIODevice *vbasedev= , VFIORegion *region, region->nr_mmaps =3D 1; region->mmaps =3D g_new0(VFIOMmap, region->nr_mmaps); region->mmaps[0].offset =3D 0; + region->mmaps[0].fd_offset =3D region->fd_offset; region->mmaps[0].size =3D region->size; } else if (ret) { return ret; @@ -355,7 +377,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; @@ -392,8 +413,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, @@ -405,12 +424,18 @@ int vfio_region_mmap(VFIORegion *region) * offsets being in ascending order. */ for (i =3D 0; i < region->nr_mmaps; i++) { + int fd =3D vfio_device_get_region_fd(region->vbasedev, region->nr, + region->mmaps[i].fd_index); + if (fd < 0) { + ret =3D -EINVAL; + 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; /* diff --git a/hw/vfio/vfio-region.h b/hw/vfio/vfio-region.h index 58b236f113..0bb082e9a6 100644 --- a/hw/vfio/vfio-region.h +++ b/hw/vfio/vfio-region.h @@ -10,12 +10,17 @@ #define HW_VFIO_REGION_H =20 #include "system/memory.h" +#ifdef CONFIG_LINUX +#include +#endif =20 typedef struct VFIOMmap { MemoryRegion mem; void *mmap; off_t offset; size_t size; + uint32_t fd_index; + uint64_t fd_offset; } VFIOMmap; =20 typedef struct VFIODevice VFIODevice; @@ -43,5 +48,8 @@ int vfio_region_mmap(VFIORegion *region); void vfio_region_mmaps_set_enabled(VFIORegion *region, bool enabled); void vfio_region_exit(VFIORegion *region); void vfio_region_finalize(VFIORegion *region); +int vfio_default_setup_sparse_mmaps(VFIORegion *region, + struct vfio_region_info *info, + Error **errp); =20 #endif /* HW_VFIO_REGION_H */ diff --git a/include/hw/vfio/vfio-device.h b/include/hw/vfio/vfio-device.h index 8472420d3f..c97a35fa80 100644 --- a/include/hw/vfio/vfio-device.h +++ b/include/hw/vfio/vfio-device.h @@ -43,12 +43,18 @@ enum { =20 typedef struct VFIODeviceOps VFIODeviceOps; typedef struct VFIODeviceIOOps VFIODeviceIOOps; +typedef struct VFIORegion VFIORegion; typedef struct VFIOMigration VFIOMigration; =20 typedef struct IOMMUFDBackend IOMMUFDBackend; typedef struct VFIOIOASHwpt VFIOIOASHwpt; typedef struct VFIOUserProxy VFIOUserProxy; =20 +typedef struct VFIORegionFDs { + int *fds; + int nr_fds; +} VFIORegionFDs; + typedef struct VFIODevice { QLIST_ENTRY(VFIODevice) next; QLIST_ENTRY(VFIODevice) container_next; @@ -89,7 +95,7 @@ typedef struct VFIODevice { VFIOIOASHwpt *hwpt; QLIST_ENTRY(VFIODevice) hwpt_next; struct vfio_region_info **reginfo; - int *region_fds; + struct VFIORegionFDs *region_fds; VFIODeviceCPR cpr; VFIOUserProxy *proxy; } VFIODevice; @@ -211,12 +217,26 @@ struct VFIODeviceIOOps { * @vdev: #VFIODevice to use * @info: set @info->index to the region index to look up; the rest of= the * struct will be filled in on success - * @fd: pointer to the fd for the region; will be -1 if not found * * Returns 0 on success or -errno. */ int (*get_region_info)(VFIODevice *vdev, - struct vfio_region_info *info, int *fd); + struct vfio_region_info *info); + + /** + * @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); =20 /** * @get_irq_info @@ -317,7 +337,8 @@ int vfio_device_get_region_info_type(VFIODevice *vbased= ev, uint32_t type, * * Returns the fd. */ -int vfio_device_get_region_fd(VFIODevice *vbasedev, int index); +int vfio_device_get_region_fd(VFIODevice *vbasedev, int index, + uint32_t fd_index); =20 bool vfio_device_has_region_cap(VFIODevice *vbasedev, int region, uint16_t= cap_type); =20 --=20 2.55.0.679.g6767b8d81c-goog From nobody Wed Aug 26 07:25:09 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=1786491627; cv=none; d=zohomail.com; s=zohoarc; b=kgAgCJVwo8fMQkKz6bymFtY4cXByI8V6UKwbpEwegTDQT7OkGxYrmH75zvIm1zrsw4+KopWZh99S0VT92mQ1wdC0k4aZuQLAKu4rNebV4hFMR98dQ45IXze7ylKJsfHgR0E6u67gWeu8Z4IQmlxauu5ZG84SLkV7LEPHR9wstuw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1786491627; 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:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=zoecSgXF0jz6AVCJIPmOWnugkxgSmyxGxo8IvlDkpE8=; b=VT7L8NTKLaD9+SJItfTORZlD8eKud+3pdHSwh8jQUkeC+kUOAQ0oRU1MjM9qD4D5U1KOLPEQfLoUGIGdhzs2zazwMQ0EZlxqqYM+6krnITMbDUSDOQ7E7wfe3V6cBYCswY7OorLGWIyJotNxYLeregB4BrtP+s9R9eAboprjL2A= 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 1786491627924241.22952675526415; Tue, 11 Aug 2026 16:40:27 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wtw4e-0004RX-JN; Tue, 11 Aug 2026 19:40: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 <3w7J7agsKCnIdQcQdWkbQjYWeeWbU.SecgUck-TUlUbdedWdk.ehW@flex--namangulati.bounces.google.com>) id 1wtw4c-0004RJ-V6 for qemu-devel@nongnu.org; Tue, 11 Aug 2026 19:39:58 -0400 Received: from mail-qv1-xf46.google.com ([2607:f8b0:4864:20::f46]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from <3w7J7agsKCnIdQcQdWkbQjYWeeWbU.SecgUck-TUlUbdedWdk.ehW@flex--namangulati.bounces.google.com>) id 1wtw4b-00089o-8w for qemu-devel@nongnu.org; Tue, 11 Aug 2026 19:39:58 -0400 Received: by mail-qv1-xf46.google.com with SMTP id 6a1803df08f44-907ca5abf1bso2013936d6.0 for ; Tue, 11 Aug 2026 16:39:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1786491588; x=1787096388; 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=zoecSgXF0jz6AVCJIPmOWnugkxgSmyxGxo8IvlDkpE8=; b=L9Xb1ss/tVTsEFc0Ve/itMKsalf6IwsA9jvBt4WhVlDVgNVZ2gCJMN3oE4dc9ZZ0t/ rsErdcGfYJf4p8dvjxi0K7m0QKzEZCviHIX0pxn+ZRKeP6+AXucYXtiYPHtEnhR1cEBl u0pWFAH+j7RB0C1LQvLuS4FcTn/UB/UPY6aZxk01ej5p014+WCCKHgSYFiYVCuxl0QPF b6OtCoYlGsoxBj4DdDwxCKA8DLfHSPzwawxM8d+Flr938T4k6oLDRzlEuiVIpWNdxiPw suXqVlwLQdob4J47CXWE8d5ZBsuB4hkA2O/CtDdHNpJxJJQjLKJkWBlYXg8y4gnKgB4g SHsw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786491588; x=1787096388; 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=zoecSgXF0jz6AVCJIPmOWnugkxgSmyxGxo8IvlDkpE8=; b=moTuv7M0eXQ9kDQ3e5kp7XpQDqqI1PMhKThgAGxTovt9X9SCk3BcCDs5e0ec3LoQug 6yUFGx085IeHGqCuNEuYJENUTmXf3qRE+3ceheQ6LvA7/+7XN89yF3vqVtjPxJkew+6W EIbQi4HJ5tlCOUD1WkcwG4rLnwDqG5gP8azmLSlxe6caYSSv5NLU9fBMyi5MUV2uyIkv EAMEhS/1H7wZ6+0F+lNjAvri0Wz/0Gv061LAJEalY4UhMVgRtoAqXsqTiiZMum9Y8RXf pz/hOIBXIx/8R3tlwIJhfoLB30mT+YWKzoaTHyoN46pM+EHyE4RniNTy5ZZDzvnY+Ma5 qBkg== X-Gm-Message-State: AOJu0YwANhjSERoOB3asbC0aS3zF3GRGdVDyHBsgAnmncyuERDw6fcms WSOt2TqzJn9sUfTjcsemCQULFa+HDpD5dsmX7mYttrNIJNae4DkHmkKjzY3Vurd3ANAY0Zo7MJu LlUKYeYDPkZlLi4SK1liW9W0J9h//cQWdSPj7wS5vpApM0P/GOOfJr6RjH4dBRbofTEGaSa+Qan Ajw4T86fZoJF5HjonB2C49Bs8juQwhbNa78sLHHRYK0rw9RuU34AejXkQXZe2DTg== X-Received: from qvpt8.prod.google.com ([2002:a0c:ea28:0:b0:905:7485:50e3]) (user=namangulati job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6214:2dca:b0:8fd:7913:b345 with SMTP id 6a1803df08f44-90a7004ba71mr7477406d6.22.1786491587666; Tue, 11 Aug 2026 16:39:47 -0700 (PDT) Date: Tue, 11 Aug 2026 23:39:30 +0000 In-Reply-To: <20260811233930.401797-1-namangulati@google.com> Mime-Version: 1.0 References: <20260811233930.401797-1-namangulati@google.com> X-Mailer: git-send-email 2.55.0.679.g6767b8d81c-goog Message-ID: <20260811233930.401797-4-namangulati@google.com> Subject: [RFC PATCH 3/3] vfio-user: implement client support for multi-fd region mmap 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::f46; envelope-from=3w7J7agsKCnIdQcQdWkbQjYWeeWbU.SecgUck-TUlUbdedWdk.ehW@flex--namangulati.bounces.google.com; helo=mail-qv1-xf46.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: 1786491632764158500 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 16) in vfio-user. Update vfio_user_device_io_get_region_info() to receive multiple file descriptors passed in SCM_RIGHTS ancillary data for a region, and implement setup_sparse_mmaps in vfio_user_device_io_ops_sock to parse per-area file descriptor indices and fd_offset values. Signed-off-by: Naman Gulati --- hw/vfio-user/device.c | 63 ++++++++++++++++++++++++++++++++++++----- hw/vfio-user/protocol.h | 20 +++++++++++++ 2 files changed, 76 insertions(+), 7 deletions(-) diff --git a/hw/vfio-user/device.c b/hw/vfio-user/device.c index 9c4e10c1fd..48b1cd8f1e 100644 --- a/hw/vfio-user/device.c +++ b/hw/vfio-user/device.c @@ -14,6 +14,9 @@ =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 @@ -171,23 +174,26 @@ static int vfio_user_get_region_info(VFIOUserProxy *p= roxy, static int vfio_user_device_io_get_region_info(VFIODevice *vbasedev, struct vfio_region_info *in= fo) { - int fd =3D -1; - VFIOUserFDs fds =3D { 0, 1, &fd }; + int fds[VFIO_USER_MAX_MAX_FDS]; + int num_fds =3D VFIO_USER_MAX_MAX_FDS; + VFIOUserFDs user_fds =3D { 0, num_fds, fds }; int ret; =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; } =20 - if (fds.recv_fds > 0 && info->index < vbasedev->num_initial_regions) { - vbasedev->region_fds[info->index].fds =3D g_new0(int, 1); - vbasedev->region_fds[info->index].nr_fds =3D 1; - vbasedev->region_fds[info->index].fds[0] =3D fd; + if (user_fds.recv_fds > 0 && info->index < vbasedev->num_initial_regio= ns) { + vbasedev->region_fds[info->index].fds =3D g_new0(int, user_fds.rec= v_fds); + vbasedev->region_fds[info->index].nr_fds =3D user_fds.recv_fds; + for (int i =3D 0; i < user_fds.recv_fds; i++) { + vbasedev->region_fds[info->index].fds[i] =3D fds[i]; + } } =20 /* cap_offset in valid area */ @@ -478,9 +484,52 @@ static int vfio_user_device_io_region_write(VFIODevice= *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; + int i, j =3D 0; + + hdr =3D vfio_get_region_info_cap(info, VFIO_REGION_INFO_CAP_SPARSE_MMA= P_FDS); + if (hdr) { + struct vfio_region_info_cap_sparse_mmap_fds *sparse_fds =3D + container_of(hdr, struct vfio_region_info_cap_sparse_mmap_fds, + header); + + trace_vfio_region_sparse_mmap_header(region->vbasedev->name, + region->nr, sparse_fds->nr_ar= eas); + + region->mmaps =3D g_new0(VFIOMmap, sparse_fds->nr_areas); + + for (i =3D 0; i < sparse_fds->nr_areas; i++) { + if (sparse_fds->areas[i].size) { + uint64_t end =3D sparse_fds->areas[i].offset + + sparse_fds->areas[i].size - 1; + + trace_vfio_region_sparse_mmap_entry(i, + sparse_fds->areas[i].o= ffset, + end); + region->mmaps[j].offset =3D sparse_fds->areas[i].offset; + region->mmaps[j].fd_offset =3D sparse_fds->areas[i].fd_off= set; + region->mmaps[j].size =3D sparse_fds->areas[i].size; + region->mmaps[j].fd_index =3D sparse_fds->areas[i].fd_inde= x; + j++; + } + } + + region->nr_mmaps =3D j; + region->mmaps =3D g_realloc(region->mmaps, j * sizeof(VFIOMmap)); + return 0; + } + + return vfio_default_setup_sparse_mmaps(region, info, errp); +} + 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, diff --git a/hw/vfio-user/protocol.h b/hw/vfio-user/protocol.h index c478d1353f..135b965d99 100644 --- a/hw/vfio-user/protocol.h +++ b/hw/vfio-user/protocol.h @@ -166,6 +166,26 @@ typedef struct { uint64_t offset; } VFIOUserRegionInfo; =20 +/* + * VFIO_REGION_INFO_CAP_SPARSE_MMAP_FDS + */ +#define VFIO_REGION_INFO_CAP_SPARSE_MMAP_FDS 16 + +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 --=20 2.55.0.679.g6767b8d81c-goog