From nobody Wed Aug 26 08:12:20 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=1787720505; cv=none; d=zohomail.com; s=zohoarc; b=LRRU5v3eLeBwoLbXoleDP+r7QPu/MXv9GcqzE02Ksefbj5v3u7HIJbpMznRY0yunXGn2RG34/Y4hreCi79v5eJyDAV4d5FXQ/tZ5DRllKXt1jzwNG0WQhNoFedudiXfhPQrMnba72k0mJ4oabOEtIM+7iA3DLE6iJhVh+UbTXqA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1787720505; 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=jJZqG8fc901hWJs08nmGGzzLEXEJU/5Q9OPlRQKLan4=; b=bkEt3viMJWXgLXYRx6P9YOo3WB5ZaBOBl2x4YMdzknJuR3a1b3T+D3Xo4TMu5BbjR1OaY+t/QyyTfcjyFhuYkAGH/YjYDAmrm+XxYkvDoV9kzObjTQeVYvwqggX5jTQC41y9/pGU0atdmnoVuB7aLWnjl2zvXDUcuzhlpVaZ5KA= 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 1787720505671527.2523323135749; Tue, 25 Aug 2026 22:01:45 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wz5ky-0002jb-0U; Wed, 26 Aug 2026 01:01: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 <3AXOOagsKCnwsfrfslzqfynlttlqj.htrvjrz-ij0jqstslsz.twl@flex--namangulati.bounces.google.com>) id 1wz5ks-0002iS-Cl for qemu-devel@nongnu.org; Wed, 26 Aug 2026 01:00:54 -0400 Received: from mail-qk1-x747.google.com ([2607:f8b0:4864:20::747]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from <3AXOOagsKCnwsfrfslzqfynlttlqj.htrvjrz-ij0jqstslsz.twl@flex--namangulati.bounces.google.com>) id 1wz5kq-0003sX-75 for qemu-devel@nongnu.org; Wed, 26 Aug 2026 01:00:53 -0400 Received: by mail-qk1-x747.google.com with SMTP id af79cd13be357-92e5e38fbc5so51049985a.2 for ; Tue, 25 Aug 2026 22:00:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1787720450; x=1788325250; 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=jJZqG8fc901hWJs08nmGGzzLEXEJU/5Q9OPlRQKLan4=; b=jSisrcfrsrlrR4Nuvgnyxvlrp5aa5IDocT1MYafR0OLbtiBWLUjHBXhWyoVCgjejLE akLoZqYzR0ChlKltWsvVTUSLhlGuYyum1LuElBXpX1Tv0Gl8QFvB+vgvbAWS+FJeIhCu NKuEwPC4d69yQfp04deQJ7AMMheWEotOFTFyxWlZ7hHsAVobsGxOQ21t++OsTG2cUvrE mTewHAmls+8AbA9fCDUjU9ePFBoMMvM3moubhRA4p35KQEdIWRp0rDIoK9R18RbEPERW bDS+nrbyyT9C1iAwM4T8rfKfSOaFa6WUS9QxdDGI/9GcbTHu3WsnLyDPav1aCANf9A+s QBMg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787720450; x=1788325250; 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=jJZqG8fc901hWJs08nmGGzzLEXEJU/5Q9OPlRQKLan4=; b=eHK+uWgeJ08DQCW1Sxnwhx6cJF634O61yXaKZyHLBmc1LEtrtIX1eIj7q+FyUk4/Lb PQDlODShS7HRuUdaS74/bgzLJ6QWAXPOig4ye0izEB9ueZHeSxfNHamBf0yKsaAVkR95 ihWtDjj5bF6Hy4Mg5LTA1EyjtGQYBQSwXQ0MBqKqilzhLGPaGP0nDh1QCXZer86u5luQ CTDX4Y88DKrIqlMn9gwvqNJRIkebpU0uQcqhtUjm+jWaEfaLvIOZ+2mtCUCl4bYglyiU J7wQtM327tjW8LhE3FjnqHpQsr4P9Zu20qBIaBd+u3AwYzl+tVW35oMyod+Pp804S3zr csbQ== X-Gm-Message-State: AFuF++mEfqTXXYMy/bNX6dJ1+b1ZcvO476aPZuLAknI2soDxTVGPOxlV kNdxivc0zBGHFeYMXjiDnq/hCTJ33LDYB0C+Rp7yUrj1GyTukJpK1WywolMgnKJX4ApQyQzSF7P jBksn/Fc6yIr2GZ+PRy2OjntyATfLIJoVS9SDMRxAFnu1u8jH+YzRIBypdDW+TdEUBaI1CEzCCw nHh8Xts9JG+IDfBgvRZf5Ei5KQa62Ogn/Ot9bNGn+iemyJA1FYusI+zv4X9a/wIQ== X-Received: from qknwg19.prod.google.com ([2002:a05:620a:5693:b0:936:db3c:c8b0]) (user=namangulati job=prod-delivery.src-stubby-dispatcher) by 2002:a05:620a:480a:b0:915:9e84:85d1 with SMTP id af79cd13be357-937803e5042mr352226485a.23.1787720449833; Tue, 25 Aug 2026 22:00:49 -0700 (PDT) Date: Wed, 26 Aug 2026 05:00:37 +0000 In-Reply-To: <20260826050039.2068138-1-namangulati@google.com> Mime-Version: 1.0 References: <20260826050039.2068138-1-namangulati@google.com> X-Mailer: git-send-email 2.55.0.860.g4b6b3295ed-goog Message-ID: <20260826050039.2068138-2-namangulati@google.com> Subject: [PATCH v2 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::747; envelope-from=3AXOOagsKCnwsfrfslzqfynlttlqj.htrvjrz-ij0jqstslsz.twl@flex--namangulati.bounces.google.com; helo=mail-qk1-x747.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: 1787720508798158500 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.860.g4b6b3295ed-goog From nobody Wed Aug 26 08:12:20 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=1787720489; cv=none; d=zohomail.com; s=zohoarc; b=hQb59JZi48Vj7fgyma0bNkwtTfGvDr4QN9bvcIggsMdthAmSOJtV5sZOAxbhsa7DKMyBX7na4Gm8aLWQOU+IYN2QydeeAJ5AITWS11SZumXUIOsZ1fkyvuTPP/hMWtC5AKzgm2r91Yx8Ekp8cIu/ksSRAgooQy2g+woAMR3uFAo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1787720489; 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=6xMItJf4TYuNfvPYTr8J8AIJOtQHPCjMmKBa8MDGAF8=; b=Af6Yoq7Kk/dR+N21akcgf+fghCdxzL9/gi0zALdYbDgrRXoxsQT7/cShiXywjSxPo9vO/EoX8VKMz2+iNkffDIMF7ngltJaO+PnFFElACwx/KSh2dUk8CtXprjC/v9iy1s2ZAeEF3aSWyQZo72EmqHHjOuoWwA7FrDZ5nPE9Yss= 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 178772048923410.832805981392312; Tue, 25 Aug 2026 22:01:29 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wz5kz-0002jf-OU; Wed, 26 Aug 2026 01:01:01 -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 <3AnOOagsKCn0obnbohvmbujhpphmf.dpnrfnv-efwfmopohov.psh@flex--namangulati.bounces.google.com>) id 1wz5kw-0002j1-4a for qemu-devel@nongnu.org; Wed, 26 Aug 2026 01:00:59 -0400 Received: from mail-qk1-x748.google.com ([2607:f8b0:4864:20::748]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from <3AnOOagsKCn0obnbohvmbujhpphmf.dpnrfnv-efwfmopohov.psh@flex--namangulati.bounces.google.com>) id 1wz5ks-0003sb-74 for qemu-devel@nongnu.org; Wed, 26 Aug 2026 01:00:57 -0400 Received: by mail-qk1-x748.google.com with SMTP id af79cd13be357-934956beec8so91032285a.0 for ; Tue, 25 Aug 2026 22:00:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1787720451; x=1788325251; 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=6xMItJf4TYuNfvPYTr8J8AIJOtQHPCjMmKBa8MDGAF8=; b=IaIamuT598AbrjUiM2mYVsoL4v0vLWwY5Ys/c2gTy2vWbHbQDkU86Jr8ErFA5oggyY Mm0XGtM5w/sfDcHHtswlOUMEhZMaYRC6ltjsIvCaNhC77F1tP4OBZLvcImmfUdVxX/aZ 5+nHvohGVIdIYI7AwFFUoetDaKe8ZKPwy4JkE94TktX38fF5J2oNuSfXiZ2Ge30PdGjq GzTYEvpssw1+8nnHBdX7+IOWv2F/rb7YVeQvNNuh4hXkalXlCbMu/lUf/6JlE/5RFytR K4gQO9nfUkJNAHNJV78lXA7O+IwPP8EXy4/xzz2534qJ8tWTIYzK7GLyo/wzh/YVxWt3 v+wA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787720451; x=1788325251; 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=6xMItJf4TYuNfvPYTr8J8AIJOtQHPCjMmKBa8MDGAF8=; b=KALEvu/Vl2xEKXsKU4iTsZxAWVFYFBidOg4Jdh0XRocdDarFikqeZb0RYsguKt2I7O tQowaBlvdgop7eCI1mw/KSzewp4DIcSENmudTW4nK3Spu9HAezbzkHuKWkxCpP1JPNXs 06uP7+RL0N6CrqDao9UNWS+YMJv+3o8t7pcjVnAJ5rg0p59iyZVPM5PJZKGVo4Qs2JXM tTWiCOIK5xAVkcz/sfCzYAp88fpz2T93vTtrAaLhyY2z57cq86N/M1X/70g3O8en99QQ HNfFWZ0LeX5CwrcGORNbekaagvo8/usx6CMsCZ0Pw4KthGKvLJdOd8ofy7XVBMzL3x7j 4Ndw== X-Gm-Message-State: AFuF++mMPf/wL/s2pYolL1yIq0Ksdy6xmSScxOZ4+OJP7v5YN+r6rqJb AkAR2Y52EUlRG78h9UXv/Ddyiu84yaA3WwZQJ2ZmOvG3tCJUOWGyV1eo4B0lq3GJkVV6TPEBJ41 xNudCoUASifczwhlH2dMsZ6c+07YNxujcF/jX5Yd4F+XLXpFd0xAXuX524zLzwHip0f6GAr8AsC PF9xGbmQwcjRjfHiv2uRw95Nh/P0YRMoUhiqCd51I5gOM/9/F1YVXUoAyahHqKFw== X-Received: from qknoq18.prod.google.com ([2002:a05:620a:6112:b0:915:7c23:5aa]) (user=namangulati job=prod-delivery.src-stubby-dispatcher) by 2002:a05:620a:6087:b0:92b:32d4:4af5 with SMTP id af79cd13be357-9378019f525mr418139685a.5.1787720450998; Tue, 25 Aug 2026 22:00:50 -0700 (PDT) Date: Wed, 26 Aug 2026 05:00:38 +0000 In-Reply-To: <20260826050039.2068138-1-namangulati@google.com> Mime-Version: 1.0 References: <20260826050039.2068138-1-namangulati@google.com> X-Mailer: git-send-email 2.55.0.860.g4b6b3295ed-goog Message-ID: <20260826050039.2068138-3-namangulati@google.com> Subject: [PATCH v2 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::748; envelope-from=3AnOOagsKCn0obnbohvmbujhpphmf.dpnrfnv-efwfmopohov.psh@flex--namangulati.bounces.google.com; helo=mail-qk1-x748.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: 1787720492847158500 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 | 15 +++++++++-- hw/vfio/device.c | 49 +++++++++++++++++++++-------------- hw/vfio/region.c | 41 +++++++++++++++++++++++------ hw/vfio/vfio-region.h | 8 ++++++ include/hw/vfio/vfio-device.h | 32 ++++++++++++++++++++--- 5 files changed, 112 insertions(+), 33 deletions(-) diff --git a/hw/vfio-user/device.c b/hw/vfio-user/device.c index b8d2b7c1a8..03a7026778 100644 --- a/hw/vfio-user/device.c +++ b/hw/vfio-user/device.c @@ -170,11 +170,15 @@ 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 VFIORegionFDs *regio= n_fds) { - VFIOUserFDs fds =3D { 0, 1, fd}; + int fd =3D -1; + VFIOUserFDs fds =3D { 0, 1, &fd }; int ret; =20 + region_fds->fds =3D NULL; + region_fds->nr_fds =3D 0; + if (info->index > vbasedev->num_initial_regions) { return -EINVAL; } @@ -190,6 +194,13 @@ static int vfio_user_device_io_get_region_info(VFIODev= ice *vbasedev, return -EINVAL; } =20 + if (fds.recv_fds > 0) { + region_fds->fds =3D g_new0(int, 1); + region_fds->nr_fds =3D 1; + region_fds->fds[0] =3D fd; + } + + return 0; } =20 diff --git a/hw/vfio/device.c b/hw/vfio/device.c index 1a7f8088aa..5dc459dbf7 100644 --- a/hw/vfio/device.c +++ b/hw/vfio/device.c @@ -201,8 +201,8 @@ int vfio_device_get_irq_info(VFIODevice *vbasedev, int = index, int vfio_device_get_region_info(VFIODevice *vbasedev, int index, struct vfio_region_info **info) { + struct VFIORegionFDs region_fds =3D {.fds =3D NULL, .nr_fds =3D 0}; size_t argsz =3D sizeof(struct vfio_region_info); - int fd =3D -1; int ret; =20 /* @@ -226,7 +226,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, ®ion_fds= ); if (ret !=3D 0) { g_free(*info); *info =3D NULL; @@ -237,10 +237,14 @@ retry: argsz =3D (*info)->argsz; *info =3D g_realloc(*info, argsz); =20 - if (fd !=3D -1) { - close(fd); - fd =3D -1; + if (region_fds.nr_fds) { + for (int j =3D 0; j < region_fds.nr_fds; j++) { + close(region_fds.fds[j]); + } + g_free(region_fds.fds); + region_fds.nr_fds =3D 0; } + region_fds.fds =3D NULL; =20 goto retry; } @@ -249,18 +253,24 @@ retry: /* fill cache */ vbasedev->reginfo[index] =3D *info; if (vbasedev->region_fds !=3D NULL) { - vbasedev->region_fds[index] =3D fd; + vbasedev->region_fds[index] =3D region_fds; } } =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 +490,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 +504,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 +515,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 @@ -593,11 +603,12 @@ 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 VFIORegionFDs *fds) { int ret; =20 - *fd =3D -1; + fds->nr_fds =3D 0; + fds->fds =3D NULL; =20 ret =3D ioctl(vbasedev->fd, VFIO_DEVICE_GET_REGION_INFO, info); =20 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..c63a867188 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,29 @@ 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 + * @fds: pointer to the collection of fds for the region, will have nr= _fds =3D + * 0 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, + struct VFIORegionFDs *fds); + + /** + * @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 +340,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.860.g4b6b3295ed-goog From nobody Wed Aug 26 08:12:20 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=1787720521; cv=none; d=zohomail.com; s=zohoarc; b=lfOtVxr/0Z8v3wgSbI3oEzljAjuEW1B5kg+w2+NZKoITmugK0UEUboDmjixDagssZV42Ak+tv1I75ze/8ISeBIDrUv4ep0C1oBrlsthaVIbgtN/udenMwgB3Py6ODPO2/glBcix0YOq2Rvsh3HlWW5hBxY/E9CUdfAggzpeNUac= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1787720521; 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=b12QXxLcUt6BFDnnymY2XfEHw+7hm2Vsk4uRaVQQ38k=; b=NBsAgiwW1oxwvDT8axURDctMZFowKRkuIZPTn4BRRz0T8hbrSa6gPbgfBhVVb4yeJ+KyrImV7WdEijcHdvcDazhSnQCVdYDydstnVof6yWyqHfAcx7nUlT5+ESNJ+x0ilkX7UzHCifCKw507WDhL0R+/k1Cc69gqhtHEA2HnfHU= 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 1787720521592139.09967344858694; Tue, 25 Aug 2026 22:02:01 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wz5kz-0002jg-O5; Wed, 26 Aug 2026 01:01:01 -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 <3BHOOagsKCn8qdpdqjxodwljrrjoh.frpthpx-ghyhoqrqjqx.ruj@flex--namangulati.bounces.google.com>) id 1wz5kw-0002j0-4d for qemu-devel@nongnu.org; Wed, 26 Aug 2026 01:00:59 -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 <3BHOOagsKCn8qdpdqjxodwljrrjoh.frpthpx-ghyhoqrqjqx.ruj@flex--namangulati.bounces.google.com>) id 1wz5ks-0003sk-5R for qemu-devel@nongnu.org; Wed, 26 Aug 2026 01:00:56 -0400 Received: by mail-qt1-x848.google.com with SMTP id d75a77b69052e-526da7e3c9dso5317901cf.1 for ; Tue, 25 Aug 2026 22:00:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1787720452; x=1788325252; 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=b12QXxLcUt6BFDnnymY2XfEHw+7hm2Vsk4uRaVQQ38k=; b=U8sjpstL9ZFid42vvPYBhWi3dJ3Km9E2AuQHv4L4zzG69Y6dOTqbSRXVPNe2sJJBHG xc3ePSfpjIbDJLQvtosA8Q9rDoKUWaAy8xPscdB9znrahU9X3q9LEwuxto22XQDpDj8c m5L4PDvUqz2ZygeKRju53Ym1JrWJx8rt2OtnG22FN7ZMh5RfuxBLLcjVsAXjPtCniBJ7 o+8gWcGw25UtZUozIEHc5W4f/UatjaqPOkpjspbt5x3BNa4i530y0kptVxTQoXghNpaf lkFFFFTp0sNe/kXXX3ZaVT5mn+jhy6p7JM68BZ2byP+IZjiduxzXgsKFN8NOKIgbx0MS 9sow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787720452; x=1788325252; 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=b12QXxLcUt6BFDnnymY2XfEHw+7hm2Vsk4uRaVQQ38k=; b=TFrxY6JIBD4pQ20z1v4zcxbiXXsFtMqF6Ls7d/QES6T0Dbqk96PDdv1MG1mZkRK6sb 2Twgi/EgGSCxLg78hASlDCPwX3s6NDfQtB6d2zBxiY+uNJHzjeAY2sLF4XkN+6JGKv7M rVndBVZBeBBHmxKqynJ0RvIm42dC/1K1IhKoNwAI4UsMLau4eoLqZGZVY0XODq3/cpq2 jpap6qwYRClWb4/fCcKXhfJ8hTxC4eS6+hH345QkR8TRmB9SMnDEKwv38UoSgIW74RBz nxaj0y6nsTLzlnMR2Mp1FCRiK6sPK4fZhPXOmvMhNYSDd30mF6yoiSR9xY+Zfg8zbUqe h/Dw== X-Gm-Message-State: AFuF++nS7HVyFC68t89ci+PZiY2v/1iOMAOScn0J/YedDbasgsnwQxPi 77JDiFAYdd5pyLdsoSwLXORWCMokRJWb/5SlDS7L9Lveg5yVRP/OG6g41PJoYxUyOq82Ln4xOMS ulxzuvmmltCxrkhZEi4gU4akqJNodniMIfS5xprwzqrahAmvC2fnbHrjKir/BL3VUdkACbte5Il PWDqvL1h0qYCfKhdEvPDxDK1EGPJtZBsvB0xa6kB9zpbgweYyyQjvVQXsqCCW+cQ== X-Received: from qtbfc18.prod.google.com ([2002:a05:622a:4892:b0:51c:a432:e62]) (user=namangulati job=prod-delivery.src-stubby-dispatcher) by 2002:a05:622a:1347:b0:51c:8432:1753 with SMTP id d75a77b69052e-52e423a77e0mr36007831cf.30.1787720452021; Tue, 25 Aug 2026 22:00:52 -0700 (PDT) Date: Wed, 26 Aug 2026 05:00:39 +0000 In-Reply-To: <20260826050039.2068138-1-namangulati@google.com> Mime-Version: 1.0 References: <20260826050039.2068138-1-namangulati@google.com> X-Mailer: git-send-email 2.55.0.860.g4b6b3295ed-goog Message-ID: <20260826050039.2068138-4-namangulati@google.com> Subject: [PATCH v2 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::848; envelope-from=3BHOOagsKCn8qdpdqjxodwljrrjoh.frpthpx-ghyhoqrqjqx.ruj@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: 1787720524538158500 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 03a7026778..58a691601c 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 @@ -172,8 +175,9 @@ static int vfio_user_device_io_get_region_info(VFIODevi= ce *vbasedev, struct vfio_region_info *in= fo, struct VFIORegionFDs *regio= n_fds) { - 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 region_fds->fds =3D NULL; @@ -183,7 +187,7 @@ static int vfio_user_device_io_get_region_info(VFIODevi= ce *vbasedev, 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; } @@ -194,10 +198,12 @@ static int vfio_user_device_io_get_region_info(VFIODe= vice *vbasedev, return -EINVAL; } =20 - if (fds.recv_fds > 0) { - region_fds->fds =3D g_new0(int, 1); - region_fds->nr_fds =3D 1; - region_fds->fds[0] =3D fd; + if (user_fds.recv_fds > 0) { + region_fds->fds =3D g_new0(int, user_fds.recv_fds); + region_fds->nr_fds =3D user_fds.recv_fds; + for (int i =3D 0; i < user_fds.recv_fds; i++) { + region_fds->fds[i] =3D fds[i]; + } } =20 =20 @@ -483,9 +489,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.860.g4b6b3295ed-goog