From nobody Sat Feb 7 08:44:20 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 76BBD221F20 for ; Mon, 19 Jan 2026 14:33:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768833204; cv=none; b=DSU2vcMeIkqm+uUZXI1SVVxMM5so6idSDmi7/Hq6/6aA0NSueoN/k2+L78mZF+K8aekXycN6H+/yuiVWP14LRXn/hbiaN/854otEnseAz+Hd8QqOdVyv7J1/KmWSKhMq+goxOp/HOkknxJ2pTRdaugoDMRD6GZ+FrJMrXBqBxRg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768833204; c=relaxed/simple; bh=pdymbnmF1kP13IRiopT8k7r3dtoiRjxf5iEhRO9RvPE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=klpa9DsmzFtqc0zjkWpyQdIKgYRP+loRniGC+cLJsYH5Fi5twKsy3aWN5G4ZTNPUgE51TaXwcMEef/jclOEtV+bgO8dZFbRd8Wicxg/FiY9pPt6umGh7Zt/rNgZVCTyOTp2VRKoktKqOgQCQgzboUEGDWjKJb/PiD9k+LQ0ExzM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=QLNLoHnm; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="QLNLoHnm" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1768833202; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=wZOclRq+0Ufg6FQk0Ys944pSukFzpwFzpFG8HAyD5A8=; b=QLNLoHnm191sYksH//bbqEvweH6p8Wgs8F8duwA1hebO6dyeqT9Czzeiue/jNhRj6A7nIz 27dsWCfX7YaFR0u8r00xoxt0gKUisbBn73ORensD14QG6YhQcQA+yzTHSfx6HBBch3Bw9D rlrhfe5WzvK0PUZcw3JVL/ekquh1f9Y= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-159-b65oAtAlMKCRwKhKHGXuTg-1; Mon, 19 Jan 2026 09:33:17 -0500 X-MC-Unique: b65oAtAlMKCRwKhKHGXuTg-1 X-Mimecast-MFC-AGG-ID: b65oAtAlMKCRwKhKHGXuTg_1768833196 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 02C101954237; Mon, 19 Jan 2026 14:33:16 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.44.33.172]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 8F61F1800577; Mon, 19 Jan 2026 14:33:12 +0000 (UTC) From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= To: "Michael S . Tsirkin " Cc: virtualization@lists.linux.dev, Yongji Xie , Xuan Zhuo , Maxime Coquelin , Stefano Garzarella , jasowang@redhat.com, =?UTF-8?q?Eugenio=20P=C3=A9rez?= , Laurent Vivier , Cindy Lu , linux-kernel@vger.kernel.org Subject: [PATCH v15 01/13] vhost: move vdpa group bound check to vhost_vdpa Date: Mon, 19 Jan 2026 15:32:54 +0100 Message-ID: <20260119143306.1818855-2-eperezma@redhat.com> In-Reply-To: <20260119143306.1818855-1-eperezma@redhat.com> References: <20260119143306.1818855-1-eperezma@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 Remove duplication by consolidating these here. This reduces the posibility of a parent driver missing them. While we're at it, fix a bug in vdpa_sim where a valid ASID can be assigned to a group equal to ngroups, causing an out of bound write. Cc: stable@vger.kernel.org Fixes: bda324fd037a ("vdpasim: control virtqueue support") Acked-by: Jason Wang Signed-off-by: Eugenio P=C3=A9rez --- v12: Add Fixes tag (MST). --- drivers/vdpa/mlx5/net/mlx5_vnet.c | 3 --- drivers/vdpa/vdpa_sim/vdpa_sim.c | 6 ------ drivers/vhost/vdpa.c | 2 +- 3 files changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5= _vnet.c index ddaa1366704b..44062e9d68f0 100644 --- a/drivers/vdpa/mlx5/net/mlx5_vnet.c +++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c @@ -3640,9 +3640,6 @@ static int mlx5_set_group_asid(struct vdpa_device *vd= ev, u32 group, struct mlx5_vdpa_dev *mvdev =3D to_mvdev(vdev); int err =3D 0; =20 - if (group >=3D MLX5_VDPA_NUMVQ_GROUPS) - return -EINVAL; - mvdev->mres.group2asid[group] =3D asid; =20 mutex_lock(&mvdev->mres.lock); diff --git a/drivers/vdpa/vdpa_sim/vdpa_sim.c b/drivers/vdpa/vdpa_sim/vdpa_= sim.c index c1c6431950e1..df9c7ddc5d78 100644 --- a/drivers/vdpa/vdpa_sim/vdpa_sim.c +++ b/drivers/vdpa/vdpa_sim/vdpa_sim.c @@ -606,12 +606,6 @@ static int vdpasim_set_group_asid(struct vdpa_device *= vdpa, unsigned int group, struct vhost_iotlb *iommu; int i; =20 - if (group > vdpasim->dev_attr.ngroups) - return -EINVAL; - - if (asid >=3D vdpasim->dev_attr.nas) - return -EINVAL; - iommu =3D &vdpasim->iommu[asid]; =20 mutex_lock(&vdpasim->mutex); diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c index 05a481e4c385..9d25b735b43d 100644 --- a/drivers/vhost/vdpa.c +++ b/drivers/vhost/vdpa.c @@ -680,7 +680,7 @@ static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v= , unsigned int cmd, case VHOST_VDPA_SET_GROUP_ASID: if (copy_from_user(&s, argp, sizeof(s))) return -EFAULT; - if (s.num >=3D vdpa->nas) + if (idx >=3D vdpa->ngroups || s.num >=3D vdpa->nas) return -EINVAL; if (!ops->set_group_asid) return -EOPNOTSUPP; --=20 2.52.0 From nobody Sat Feb 7 08:44:20 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8FEEB363C4A for ; Mon, 19 Jan 2026 14:33:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768833207; cv=none; b=fvLpkbUsMExTC946IKM4oa5D3W4i+/jTiKye3eL7DFxSeg4JJqOzbk3Yusuvz0FZUsGqDXb2zTya0fMAo1JO1PYbjHTFZ+22RSCZXDpLpWg6DaZaOnSFKDOcyfT2zL2MxU0/cG4p7Vy4P5ZyWBeIj2Nq9U3VqOoWv+Vfti31v6s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768833207; c=relaxed/simple; bh=5ECYxaYeBJVIOWeqy/iDdDa/H00cLiMfLM4EhoJhPCA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=nL73ilQYG8lLFCWQ0OsYl5eXGiGYDfqyxlr0FPSaFJkl5Ck40ERStNeVDft9hcv1se5D3otzGSBcG1un5qeqUK3i2V8CNqvffNkiPzeqfUrET+IAlEtkdCJQfCWfURhIl0uogi+bJVmPR9jD75G/f+Rj6dy0PeEGZDHkTGd2oD4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=AVyqIJPB; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="AVyqIJPB" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1768833205; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=o5hO8Psqd6yn9uKa/WLE0Q8XbzNZAyPQD8caCcDa5fs=; b=AVyqIJPB3G3AimE7fxFYr8U8VhxhO6ABHPt3PwTx2VA8QMTPdVe7fxHvZA56ZBbYXigs6R 7ItHOa8/KAdu+0MVdnVgvYJnMRU0DooPkCMI/eDrGuZRotC89MyGN9vcqYV175BpoUqlK5 bsBSu4Y2XRwIKSlJE3QqFjBrv7zXs7w= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-576-80WxeZXpPuCM4FYIP0hNXQ-1; Mon, 19 Jan 2026 09:33:21 -0500 X-MC-Unique: 80WxeZXpPuCM4FYIP0hNXQ-1 X-Mimecast-MFC-AGG-ID: 80WxeZXpPuCM4FYIP0hNXQ_1768833200 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 0DFE31956054; Mon, 19 Jan 2026 14:33:20 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.44.33.172]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 7DE7F18001D5; Mon, 19 Jan 2026 14:33:16 +0000 (UTC) From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= To: "Michael S . Tsirkin " Cc: virtualization@lists.linux.dev, Yongji Xie , Xuan Zhuo , Maxime Coquelin , Stefano Garzarella , jasowang@redhat.com, =?UTF-8?q?Eugenio=20P=C3=A9rez?= , Laurent Vivier , Cindy Lu , linux-kernel@vger.kernel.org Subject: [PATCH v15 02/13] vduse: add v1 API definition Date: Mon, 19 Jan 2026 15:32:55 +0100 Message-ID: <20260119143306.1818855-3-eperezma@redhat.com> In-Reply-To: <20260119143306.1818855-1-eperezma@redhat.com> References: <20260119143306.1818855-1-eperezma@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 This allows the kernel to detect whether the userspace VDUSE device supports the VQ group and ASID features. VDUSE devices that don't set the V1 API will not receive the new messages, and vdpa device will be created with only one vq group and asid. The next patches implement the new feature incrementally, only enabling the VDUSE device to set the V1 API version by the end of the series. Acked-by: Jason Wang Reviewed-by: Xie Yongji Signed-off-by: Eugenio P=C3=A9rez --- include/uapi/linux/vduse.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/uapi/linux/vduse.h b/include/uapi/linux/vduse.h index 10ad71aa00d6..ccb92a1efce0 100644 --- a/include/uapi/linux/vduse.h +++ b/include/uapi/linux/vduse.h @@ -10,6 +10,10 @@ =20 #define VDUSE_API_VERSION 0 =20 +/* VQ groups and ASID support */ + +#define VDUSE_API_VERSION_1 1 + /* * Get the version of VDUSE API that kernel supported (VDUSE_API_VERSION). * This is used for future extension. --=20 2.52.0 From nobody Sat Feb 7 08:44:20 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 389AD35EDBA for ; Mon, 19 Jan 2026 14:33:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768833210; cv=none; b=XaBAKjolfRre0+RycjGfgL0sKRe/bCJMInLN6isUOSEwvpVXJ9mHTkqRTjXBJMk4aaESS6oIjY5B7SFKTr6CWp0Dy1iHKzoZHYbaWp658j+IijDaG4n2fW/BeDc/cwGfQO2uFgMxHzDv8Fw/JVCPCnqdKja8EteBXlgvBcY6Dbg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768833210; c=relaxed/simple; bh=68Rv2zV+IH8ejpZkWV3TYUJiEfMMJYeNAhvl7aY2Lsk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=BSbXaGMgQlQNxc9R+bBBjVoLQzt6oobkxyYZvbt9+fYymaHrVwV1quXiGvfLgcKCPKb1EZAiBRY5CN8IUsMBJrwiXbgsnlZBPzM62fraRnZpvrOdHYJesv8b3jsBLTw9MQXg9+iRihPfjf5b+lwgrfvXBE+13ZTp64swg5O67Vc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=PZ4gUpuN; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="PZ4gUpuN" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1768833208; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=URhy/eVdYPWYFT6arANROkh3If2bK/p/7S6HuKXpigM=; b=PZ4gUpuNcSgH55viuaLsHqu62dBbYFn38MoFYC4xggM62UX4qiPMJYDk1lcHavSPfLkFCY 5oKQP5RXi1KQHIQ+GlyRoinTptBMRJmREz7jylsZdXMicb7Pez9AVoELom4lITxIHrPpVE 7TyGDgX2DDuVPCIAmKpD8zJZFF44zOI= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-673-clagpylANAa8WVWGPegg5Q-1; Mon, 19 Jan 2026 09:33:25 -0500 X-MC-Unique: clagpylANAa8WVWGPegg5Q-1 X-Mimecast-MFC-AGG-ID: clagpylANAa8WVWGPegg5Q_1768833204 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id EFC5B1800342; Mon, 19 Jan 2026 14:33:23 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.44.33.172]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 895D018001D5; Mon, 19 Jan 2026 14:33:20 +0000 (UTC) From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= To: "Michael S . Tsirkin " Cc: virtualization@lists.linux.dev, Yongji Xie , Xuan Zhuo , Maxime Coquelin , Stefano Garzarella , jasowang@redhat.com, =?UTF-8?q?Eugenio=20P=C3=A9rez?= , Laurent Vivier , Cindy Lu , linux-kernel@vger.kernel.org Subject: [PATCH v15 03/13] vduse: add vq group support Date: Mon, 19 Jan 2026 15:32:56 +0100 Message-ID: <20260119143306.1818855-4-eperezma@redhat.com> In-Reply-To: <20260119143306.1818855-1-eperezma@redhat.com> References: <20260119143306.1818855-1-eperezma@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 This allows separate the different virtqueues in groups that shares the same address space. Asking the VDUSE device for the groups of the vq at the beginning as they're needed for the DMA API. Allocating 3 vq groups as net is the device that need the most groups: * Dataplane (guest passthrough) * CVQ * Shadowed vrings. Future versions of the series can include dynamic allocation of the groups array so VDUSE can declare more groups. Acked-by: Jason Wang Reviewed-by: Xie Yongji Signed-off-by: Eugenio P=C3=A9rez --- v12: * Change the style of checking for vq group =3D=3D 0 in VDUSE_VQ_SETUP dev ioctl if api_version < 1 (MST). v11: * Rename vq->vq_group to vq->group (Jason). * Do not reset vq group at virtio reset (Jason). v6: * s/sepparate/separate (MST). * s/dev->api_version < 1/dev->api_version < VDUSE_API_VERSION_1 v5: * Revert core vdpa changes (Jason). * Fix group =3D=3D ngroup case in checking VQ_SETUP argument (Jason). v4: * Revert the "invalid vq group" concept and assume 0 if not set (Jason). * Make config->ngroups =3D=3D 0 invalid (Jason). v3: * Make the default group an invalid group as long as VDUSE device does not set it to some valid u32 value. Modify the vdpa core to take that into account (Jason). * Create the VDUSE_DEV_MAX_GROUPS instead of using a magic number v2: * Now the vq group is in vduse_vq_config struct instead of issuing one VDUSE message per vq. v1: * Fix: Remove BIT_ULL(VIRTIO_S_*), as _S_ is already the bit (Maxime) RFC v3: * Increase VDUSE_MAX_VQ_GROUPS to 0xffff (Jason). It was set to a lower value to reduce memory consumption, but vqs are already limited to that value and userspace VDUSE is able to allocate that many vqs. * Remove the descs vq group capability as it will not be used and we can add it on top. * Do not ask for vq groups in number of vq groups < 2. * Move the valid vq groups range check to vduse_validate_config. RFC v2: * Cache group information in kernel, as we need to provide the vq map tokens properly. * Add descs vq group to optimize SVQ forwarding and support indirect descriptors out of the box. --- drivers/vdpa/vdpa_user/vduse_dev.c | 47 ++++++++++++++++++++++++++---- include/uapi/linux/vduse.h | 12 ++++++-- 2 files changed, 51 insertions(+), 8 deletions(-) diff --git a/drivers/vdpa/vdpa_user/vduse_dev.c b/drivers/vdpa/vdpa_user/vd= use_dev.c index ae357d014564..5bffc25a266e 100644 --- a/drivers/vdpa/vdpa_user/vduse_dev.c +++ b/drivers/vdpa/vdpa_user/vduse_dev.c @@ -39,6 +39,7 @@ #define DRV_LICENSE "GPL v2" =20 #define VDUSE_DEV_MAX (1U << MINORBITS) +#define VDUSE_DEV_MAX_GROUPS 0xffff #define VDUSE_MAX_BOUNCE_SIZE (1024 * 1024 * 1024) #define VDUSE_MIN_BOUNCE_SIZE (1024 * 1024) #define VDUSE_BOUNCE_SIZE (64 * 1024 * 1024) @@ -58,6 +59,7 @@ struct vduse_virtqueue { struct vdpa_vq_state state; bool ready; bool kicked; + u32 group; spinlock_t kick_lock; spinlock_t irq_lock; struct eventfd_ctx *kickfd; @@ -114,6 +116,7 @@ struct vduse_dev { u8 status; u32 vq_num; u32 vq_align; + u32 ngroups; struct vduse_umem *umem; struct mutex mem_lock; unsigned int bounce_size; @@ -592,6 +595,16 @@ static int vduse_vdpa_set_vq_state(struct vdpa_device = *vdpa, u16 idx, return 0; } =20 +static u32 vduse_get_vq_group(struct vdpa_device *vdpa, u16 idx) +{ + struct vduse_dev *dev =3D vdpa_to_vduse(vdpa); + + if (dev->api_version < VDUSE_API_VERSION_1) + return 0; + + return dev->vqs[idx]->group; +} + static int vduse_vdpa_get_vq_state(struct vdpa_device *vdpa, u16 idx, struct vdpa_vq_state *state) { @@ -789,6 +802,7 @@ static const struct vdpa_config_ops vduse_vdpa_config_o= ps =3D { .set_vq_cb =3D vduse_vdpa_set_vq_cb, .set_vq_num =3D vduse_vdpa_set_vq_num, .get_vq_size =3D vduse_vdpa_get_vq_size, + .get_vq_group =3D vduse_get_vq_group, .set_vq_ready =3D vduse_vdpa_set_vq_ready, .get_vq_ready =3D vduse_vdpa_get_vq_ready, .set_vq_state =3D vduse_vdpa_set_vq_state, @@ -1252,12 +1266,24 @@ static long vduse_dev_ioctl(struct file *file, unsi= gned int cmd, if (config.index >=3D dev->vq_num) break; =20 - if (!is_mem_zero((const char *)config.reserved, - sizeof(config.reserved))) + if (dev->api_version < VDUSE_API_VERSION_1) { + if (config.group) + break; + } else { + if (config.group >=3D dev->ngroups) + break; + if (dev->status & VIRTIO_CONFIG_S_DRIVER_OK) + break; + } + + if (config.reserved1 || + !is_mem_zero((const char *)config.reserved2, + sizeof(config.reserved2))) break; =20 index =3D array_index_nospec(config.index, dev->vq_num); dev->vqs[index]->num_max =3D config.max_size; + dev->vqs[index]->group =3D config.group; ret =3D 0; break; } @@ -1737,12 +1763,20 @@ static bool features_is_valid(struct vduse_dev_conf= ig *config) return true; } =20 -static bool vduse_validate_config(struct vduse_dev_config *config) +static bool vduse_validate_config(struct vduse_dev_config *config, + u64 api_version) { if (!is_mem_zero((const char *)config->reserved, sizeof(config->reserved))) return false; =20 + if (api_version < VDUSE_API_VERSION_1 && config->ngroups) + return false; + + if (api_version >=3D VDUSE_API_VERSION_1 && + (!config->ngroups || config->ngroups > VDUSE_DEV_MAX_GROUPS)) + return false; + if (config->vq_align > PAGE_SIZE) return false; =20 @@ -1858,6 +1892,9 @@ static int vduse_create_dev(struct vduse_dev_config *= config, dev->device_features =3D config->features; dev->device_id =3D config->device_id; dev->vendor_id =3D config->vendor_id; + dev->ngroups =3D (dev->api_version < VDUSE_API_VERSION_1) + ? 1 + : config->ngroups; dev->name =3D kstrdup(config->name, GFP_KERNEL); if (!dev->name) goto err_str; @@ -1936,7 +1973,7 @@ static long vduse_ioctl(struct file *file, unsigned i= nt cmd, break; =20 ret =3D -EINVAL; - if (vduse_validate_config(&config) =3D=3D false) + if (!vduse_validate_config(&config, control->api_version)) break; =20 buf =3D vmemdup_user(argp + size, config.config_size); @@ -2017,7 +2054,7 @@ static int vduse_dev_init_vdpa(struct vduse_dev *dev,= const char *name) =20 vdev =3D vdpa_alloc_device(struct vduse_vdpa, vdpa, dev->dev, &vduse_vdpa_config_ops, &vduse_map_ops, - 1, 1, name, true); + dev->ngroups, 1, name, true); if (IS_ERR(vdev)) return PTR_ERR(vdev); =20 diff --git a/include/uapi/linux/vduse.h b/include/uapi/linux/vduse.h index ccb92a1efce0..a3d51cf6df3a 100644 --- a/include/uapi/linux/vduse.h +++ b/include/uapi/linux/vduse.h @@ -31,6 +31,7 @@ * @features: virtio features * @vq_num: the number of virtqueues * @vq_align: the allocation alignment of virtqueue's metadata + * @ngroups: number of vq groups that VDUSE device declares * @reserved: for future use, needs to be initialized to zero * @config_size: the size of the configuration space * @config: the buffer of the configuration space @@ -45,7 +46,8 @@ struct vduse_dev_config { __u64 features; __u32 vq_num; __u32 vq_align; - __u32 reserved[13]; + __u32 ngroups; /* if VDUSE_API_VERSION >=3D 1 */ + __u32 reserved[12]; __u32 config_size; __u8 config[]; }; @@ -122,14 +124,18 @@ struct vduse_config_data { * struct vduse_vq_config - basic configuration of a virtqueue * @index: virtqueue index * @max_size: the max size of virtqueue - * @reserved: for future use, needs to be initialized to zero + * @reserved1: for future use, needs to be initialized to zero + * @group: virtqueue group + * @reserved2: for future use, needs to be initialized to zero * * Structure used by VDUSE_VQ_SETUP ioctl to setup a virtqueue. */ struct vduse_vq_config { __u32 index; __u16 max_size; - __u16 reserved[13]; + __u16 reserved1; + __u32 group; + __u16 reserved2[10]; }; =20 /* --=20 2.52.0 From nobody Sat Feb 7 08:44:20 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F346E238C23 for ; Mon, 19 Jan 2026 14:33:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768833215; cv=none; b=HF5uJTAthapZ+AHKk0DPmB4hzxjkFved/7ijiqNmPAgW8Xahcur4F1yLYC5GoiKjT9GHPkN0XAULCQyhkXfA7zy1NbJ7Dl11GuK1Xzs3lxyCLDGxfdW+8c+854VuhvtcXhNlzy10TrSU6kRpewkUXNgVxmKtDrFMnf5+KpXPXT4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768833215; c=relaxed/simple; bh=CiqFAFo0WDR804JWtfwk3WwevL0erCZWnX1WfmpHOj8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=gc78hAANQsI679NzSu+PBdGq9H9PZLxrvEuA/3ufW1fADuxH/n7hXXVl6KtQkMb/erRAoIRqBXSAGnimBh1nF4arGlkANMDCldFBuQheGkTBEdq4DLpFUJtXESapkdUQLYQmj2kcEepoYeFST+3gBW+k6XmTRYk9I268hycaE0w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=LhwHidLC; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="LhwHidLC" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1768833213; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=4VErfqdLYyFyuCzrhCOdrIXdRDtffqApgjrtHfkACR0=; b=LhwHidLC5x9EnVtuVVr7dXc5v8yGx3sN8KIf1DQRoZqOIAM7TEvRdMQ5ngrGFC3PKI+Zj0 3K/R2D6tr0szCpgGukTJdJicMLYARClcsNBZ9VXnyAqVpQas9FZi37oh+isjygkd3M8peS JOfs3vTueRdyRaTA9f8SKcF+z0zll+A= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-35-vRJRP2TsP7G-Q4pEGEHqcw-1; Mon, 19 Jan 2026 09:33:29 -0500 X-MC-Unique: vRJRP2TsP7G-Q4pEGEHqcw-1 X-Mimecast-MFC-AGG-ID: vRJRP2TsP7G-Q4pEGEHqcw_1768833208 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 7B1A0195605F; Mon, 19 Jan 2026 14:33:28 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.44.33.172]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id A41021800577; Mon, 19 Jan 2026 14:33:24 +0000 (UTC) From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= To: "Michael S . Tsirkin " Cc: virtualization@lists.linux.dev, Yongji Xie , Xuan Zhuo , Maxime Coquelin , Stefano Garzarella , jasowang@redhat.com, =?UTF-8?q?Eugenio=20P=C3=A9rez?= , Laurent Vivier , Cindy Lu , linux-kernel@vger.kernel.org Subject: [PATCH v15 04/13] vduse: return internal vq group struct as map token Date: Mon, 19 Jan 2026 15:32:57 +0100 Message-ID: <20260119143306.1818855-5-eperezma@redhat.com> In-Reply-To: <20260119143306.1818855-1-eperezma@redhat.com> References: <20260119143306.1818855-1-eperezma@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 Return the internal struct that represents the vq group as virtqueue map token, instead of the device. This allows the map functions to access the information per group. At this moment all the virtqueues share the same vq group, that only can point to ASID 0. This change prepares the infrastructure for actual per-group address space handling Acked-by: Jason Wang Signed-off-by: Eugenio P=C3=A9rez --- v4: * Revert the "invalid vq group" concept, and assume 0 by default. * Revert unnecesary blank line addition (Jason) v3: * Adapt all virtio_map_ops callbacks to handle empty tokens in case of invalid groups. * Make setting status DRIVER_OK fail if vq group is not valid. * Remove the _int name suffix from struct vduse_vq_group. RFC v3: * Make the vq groups a dynamic array to support an arbitrary number of them. --- drivers/vdpa/vdpa_user/vduse_dev.c | 100 ++++++++++++++++++++++++++--- include/linux/virtio.h | 6 +- 2 files changed, 94 insertions(+), 12 deletions(-) diff --git a/drivers/vdpa/vdpa_user/vduse_dev.c b/drivers/vdpa/vdpa_user/vd= use_dev.c index 5bffc25a266e..68290c3d9d8f 100644 --- a/drivers/vdpa/vdpa_user/vduse_dev.c +++ b/drivers/vdpa/vdpa_user/vduse_dev.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -85,6 +86,10 @@ struct vduse_umem { struct mm_struct *mm; }; =20 +struct vduse_vq_group { + struct vduse_dev *dev; +}; + struct vduse_dev { struct vduse_vdpa *vdev; struct device *dev; @@ -118,6 +123,7 @@ struct vduse_dev { u32 vq_align; u32 ngroups; struct vduse_umem *umem; + struct vduse_vq_group *groups; struct mutex mem_lock; unsigned int bounce_size; struct mutex domain_lock; @@ -605,6 +611,17 @@ static u32 vduse_get_vq_group(struct vdpa_device *vdpa= , u16 idx) return dev->vqs[idx]->group; } =20 +static union virtio_map vduse_get_vq_map(struct vdpa_device *vdpa, u16 idx) +{ + struct vduse_dev *dev =3D vdpa_to_vduse(vdpa); + u32 vq_group =3D vduse_get_vq_group(vdpa, idx); + union virtio_map ret =3D { + .group =3D &dev->groups[vq_group], + }; + + return ret; +} + static int vduse_vdpa_get_vq_state(struct vdpa_device *vdpa, u16 idx, struct vdpa_vq_state *state) { @@ -825,6 +842,7 @@ static const struct vdpa_config_ops vduse_vdpa_config_o= ps =3D { .get_vq_affinity =3D vduse_vdpa_get_vq_affinity, .reset =3D vduse_vdpa_reset, .set_map =3D vduse_vdpa_set_map, + .get_vq_map =3D vduse_get_vq_map, .free =3D vduse_vdpa_free, }; =20 @@ -832,7 +850,14 @@ static void vduse_dev_sync_single_for_device(union vir= tio_map token, dma_addr_t dma_addr, size_t size, enum dma_data_direction dir) { - struct vduse_iova_domain *domain =3D token.iova_domain; + struct vduse_dev *vdev; + struct vduse_iova_domain *domain; + + if (!token.group) + return; + + vdev =3D token.group->dev; + domain =3D vdev->domain; =20 vduse_domain_sync_single_for_device(domain, dma_addr, size, dir); } @@ -841,7 +866,14 @@ static void vduse_dev_sync_single_for_cpu(union virtio= _map token, dma_addr_t dma_addr, size_t size, enum dma_data_direction dir) { - struct vduse_iova_domain *domain =3D token.iova_domain; + struct vduse_dev *vdev; + struct vduse_iova_domain *domain; + + if (!token.group) + return; + + vdev =3D token.group->dev; + domain =3D vdev->domain; =20 vduse_domain_sync_single_for_cpu(domain, dma_addr, size, dir); } @@ -851,7 +883,14 @@ static dma_addr_t vduse_dev_map_page(union virtio_map = token, struct page *page, enum dma_data_direction dir, unsigned long attrs) { - struct vduse_iova_domain *domain =3D token.iova_domain; + struct vduse_dev *vdev; + struct vduse_iova_domain *domain; + + if (!token.group) + return DMA_MAPPING_ERROR; + + vdev =3D token.group->dev; + domain =3D vdev->domain; =20 return vduse_domain_map_page(domain, page, offset, size, dir, attrs); } @@ -860,7 +899,14 @@ static void vduse_dev_unmap_page(union virtio_map toke= n, dma_addr_t dma_addr, size_t size, enum dma_data_direction dir, unsigned long attrs) { - struct vduse_iova_domain *domain =3D token.iova_domain; + struct vduse_dev *vdev; + struct vduse_iova_domain *domain; + + if (!token.group) + return; + + vdev =3D token.group->dev; + domain =3D vdev->domain; =20 return vduse_domain_unmap_page(domain, dma_addr, size, dir, attrs); } @@ -868,11 +914,17 @@ static void vduse_dev_unmap_page(union virtio_map tok= en, dma_addr_t dma_addr, static void *vduse_dev_alloc_coherent(union virtio_map token, size_t size, dma_addr_t *dma_addr, gfp_t flag) { - struct vduse_iova_domain *domain =3D token.iova_domain; + struct vduse_dev *vdev; + struct vduse_iova_domain *domain; unsigned long iova; void *addr; =20 *dma_addr =3D DMA_MAPPING_ERROR; + if (!token.group) + return NULL; + + vdev =3D token.group->dev; + domain =3D vdev->domain; addr =3D vduse_domain_alloc_coherent(domain, size, (dma_addr_t *)&iova, flag); if (!addr) @@ -887,14 +939,28 @@ static void vduse_dev_free_coherent(union virtio_map = token, size_t size, void *vaddr, dma_addr_t dma_addr, unsigned long attrs) { - struct vduse_iova_domain *domain =3D token.iova_domain; + struct vduse_dev *vdev; + struct vduse_iova_domain *domain; + + if (!token.group) + return; + + vdev =3D token.group->dev; + domain =3D vdev->domain; =20 vduse_domain_free_coherent(domain, size, vaddr, dma_addr, attrs); } =20 static bool vduse_dev_need_sync(union virtio_map token, dma_addr_t dma_add= r) { - struct vduse_iova_domain *domain =3D token.iova_domain; + struct vduse_dev *vdev; + struct vduse_iova_domain *domain; + + if (!token.group) + return false; + + vdev =3D token.group->dev; + domain =3D vdev->domain; =20 return dma_addr < domain->bounce_size; } @@ -908,7 +974,14 @@ static int vduse_dev_mapping_error(union virtio_map to= ken, dma_addr_t dma_addr) =20 static size_t vduse_dev_max_mapping_size(union virtio_map token) { - struct vduse_iova_domain *domain =3D token.iova_domain; + struct vduse_dev *vdev; + struct vduse_iova_domain *domain; + + if (!token.group) + return 0; + + vdev =3D token.group->dev; + domain =3D vdev->domain; =20 return domain->bounce_size; } @@ -1726,6 +1799,7 @@ static int vduse_destroy_dev(char *name) if (dev->domain) vduse_domain_destroy(dev->domain); kfree(dev->name); + kfree(dev->groups); vduse_dev_destroy(dev); module_put(THIS_MODULE); =20 @@ -1895,6 +1969,13 @@ static int vduse_create_dev(struct vduse_dev_config = *config, dev->ngroups =3D (dev->api_version < VDUSE_API_VERSION_1) ? 1 : config->ngroups; + dev->groups =3D kcalloc(dev->ngroups, sizeof(dev->groups[0]), + GFP_KERNEL); + if (!dev->groups) + goto err_vq_groups; + for (u32 i =3D 0; i < dev->ngroups; ++i) + dev->groups[i].dev =3D dev; + dev->name =3D kstrdup(config->name, GFP_KERNEL); if (!dev->name) goto err_str; @@ -1931,6 +2012,8 @@ static int vduse_create_dev(struct vduse_dev_config *= config, err_idr: kfree(dev->name); err_str: + kfree(dev->groups); +err_vq_groups: vduse_dev_destroy(dev); err: return ret; @@ -2092,7 +2175,6 @@ static int vdpa_dev_add(struct vdpa_mgmt_dev *mdev, c= onst char *name, return -ENOMEM; } =20 - dev->vdev->vdpa.vmap.iova_domain =3D dev->domain; ret =3D _vdpa_register_device(&dev->vdev->vdpa, dev->vq_num); if (ret) { put_device(&dev->vdev->vdpa.dev); diff --git a/include/linux/virtio.h b/include/linux/virtio.h index 63bb05ece8c5..3bbc4cb6a672 100644 --- a/include/linux/virtio.h +++ b/include/linux/virtio.h @@ -43,13 +43,13 @@ struct virtqueue { void *priv; }; =20 -struct vduse_iova_domain; +struct vduse_vq_group; =20 union virtio_map { /* Device that performs DMA */ struct device *dma_dev; - /* VDUSE specific mapping data */ - struct vduse_iova_domain *iova_domain; + /* VDUSE specific virtqueue group for doing map */ + struct vduse_vq_group *group; }; =20 int virtqueue_add_outbuf(struct virtqueue *vq, --=20 2.52.0 From nobody Sat Feb 7 08:44:20 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A94DA36AB7A for ; Mon, 19 Jan 2026 14:33:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768833219; cv=none; b=q97N0iIXKjNohXZyQd/F1Ky7m/yIyqGc9wLJFYecfSTZO6w++LQtnatALde2VWnZpnjlqkwtyTIX+j9Xry0iUWqSERnSf2iakWAPpMUyHb5zdD5SHqsG9Gos9U/XKiX/ssosbqawclvTIrmYyMzL9fJSu8tLVbnye2930mdIcDU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768833219; c=relaxed/simple; bh=WvaWFkgvzchUZXLO23A+T5t6Ue7xXVAlqjtGBYlixZU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=La63HDLHmmmjj3XpgXwS/1szO2RJjCBKqevrEuiSxMlSWgQ2pGxBtIUI9mB+agD6w8v/kobmpjGYesM+oxPX8/I6csa631GE96eRD5h4ey045cR7Gi3OcTp/zz/mU6dMzmv7oE3ur4t6Tiow8/m+ypaxqgIYDtpESTjfOLRm3B8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=S9HW2ca4; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="S9HW2ca4" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1768833216; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=VaNLbM0Xd0ri4i+Zhc5YrPBWzg2GZI57dccxp+Nyuaw=; b=S9HW2ca4EAWfYD0lZ2OAkxGwn4ZBnmhNMank4rOjVcKwj8bpIsG9lKWYdZSy6y7Y/nW/rb iZiP/c6ZO8nqNPoXxh9YJOXGqpE3968bpqFwOdiPTxf6QxaOXaUB5K+/aYxU0q0MxuVFNN j8cnoBckOgSUfJ3aOm70J08yQ5e1Wzc= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-286-qarqllUfOAWkmLEpgVPtag-1; Mon, 19 Jan 2026 09:33:33 -0500 X-MC-Unique: qarqllUfOAWkmLEpgVPtag-1 X-Mimecast-MFC-AGG-ID: qarqllUfOAWkmLEpgVPtag_1768833212 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 70C501956070; Mon, 19 Jan 2026 14:33:32 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.44.33.172]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 029B418001D5; Mon, 19 Jan 2026 14:33:28 +0000 (UTC) From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= To: "Michael S . Tsirkin " Cc: virtualization@lists.linux.dev, Yongji Xie , Xuan Zhuo , Maxime Coquelin , Stefano Garzarella , jasowang@redhat.com, =?UTF-8?q?Eugenio=20P=C3=A9rez?= , Laurent Vivier , Cindy Lu , linux-kernel@vger.kernel.org Subject: [PATCH v15 05/13] vdpa: document set_group_asid thread safety Date: Mon, 19 Jan 2026 15:32:58 +0100 Message-ID: <20260119143306.1818855-6-eperezma@redhat.com> In-Reply-To: <20260119143306.1818855-1-eperezma@redhat.com> References: <20260119143306.1818855-1-eperezma@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 Document that the function races with the check of DRIVER_OK. Acked-by: Jason Wang Signed-off-by: Eugenio P=C3=A9rez --- Requested at https://lore.kernel.org/lkml/CACGkMEvXdV4ukZE6xhLL0sSN70G=3DAWVQgpRnH98Fr4b= tzMkK9g@mail.gmail.com/ v12: Reword comment (MST). --- include/linux/vdpa.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/linux/vdpa.h b/include/linux/vdpa.h index 4cf21d6e9cfd..2bfe3baa63f4 100644 --- a/include/linux/vdpa.h +++ b/include/linux/vdpa.h @@ -312,7 +312,9 @@ struct vdpa_map_file { * @idx: virtqueue index * Returns the affinity mask * @set_group_asid: Set address space identifier for a - * virtqueue group (optional) + * virtqueue group (optional). Caller must + * prevent this from being executed concurrently + * with set_status. * @vdev: vdpa device * @group: virtqueue group * @asid: address space id for this group --=20 2.52.0 From nobody Sat Feb 7 08:44:20 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BB3C136CE11 for ; Mon, 19 Jan 2026 14:33:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768833221; cv=none; b=XeQ/sL0R6yfcjg+jUV7ohmLSkJyucEwwVY3Yup+ocXI52HBbhYZWIGViJItAEVXUtUtpTKiyWbpajArhodzrxYuFoQWLkHO+OPUxeHi0kOHIruuiIfu80JDufTVfx6Gu4mhXrkXE9CSBBOnuMyrJdVph5dzoqqo6y1xXnBLmnmo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768833221; c=relaxed/simple; bh=RTbGQMeS3TGwfkL0TUsU4PKOT1MwFgKm80XeeFGh0Xc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=WHcO+ETsJDmkR8LFkpYmQ4WHgR5C1VtcFrxLCni7+dIXDv+zLihDh1Fay0vuE4X6Z3C/j2vd0q30YgS7UJhFXttX4cy+A488isZMd0lJGSFzIaIdrEYOBnP2ud3mZwr8b1vuUNquEpHIiSLseFFzTIzKTQDXDU9qIRj0Njc6EEA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=itZSwCHI; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="itZSwCHI" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1768833219; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=t45TFxqr8WLK9tsMFvmjqb5HYGHWI8QhdKDpDAmNJlY=; b=itZSwCHI5BBugLSNkb/VWViPqBGl7BH0QtjAN5R7OUrngwE4o5hfcnb6VGOC+50JIpXW7n B2pTFDzNG24AuQ4dWOCoko3rnDJihAswSiDxnCJ+79VgDx8sByM9dzJQVlkMt+OypK0IxW NRdxcG4AkhRIoL5lcPANPUg7h8lA45k= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-451-F4Rw9Rv5O_WG3uemhIEpRQ-1; Mon, 19 Jan 2026 09:33:37 -0500 X-MC-Unique: F4Rw9Rv5O_WG3uemhIEpRQ-1 X-Mimecast-MFC-AGG-ID: F4Rw9Rv5O_WG3uemhIEpRQ_1768833216 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 63BC7180060F; Mon, 19 Jan 2026 14:33:36 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.44.33.172]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id EA9B31800577; Mon, 19 Jan 2026 14:33:32 +0000 (UTC) From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= To: "Michael S . Tsirkin " Cc: virtualization@lists.linux.dev, Yongji Xie , Xuan Zhuo , Maxime Coquelin , Stefano Garzarella , jasowang@redhat.com, =?UTF-8?q?Eugenio=20P=C3=A9rez?= , Laurent Vivier , Cindy Lu , linux-kernel@vger.kernel.org Subject: [PATCH v15 06/13] vhost: forbid change vq groups ASID if DRIVER_OK is set Date: Mon, 19 Jan 2026 15:32:59 +0100 Message-ID: <20260119143306.1818855-7-eperezma@redhat.com> In-Reply-To: <20260119143306.1818855-1-eperezma@redhat.com> References: <20260119143306.1818855-1-eperezma@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 Only vdpa_sim support it. Forbid this behaviour as there is no use for it right now, we can always enable it in the future with a feature flag. Acked-by: Jason Wang Signed-off-by: Eugenio P=C3=A9rez --- v12: Fix typo in patch message (MST). --- drivers/vhost/vdpa.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c index 9d25b735b43d..3f0184d42075 100644 --- a/drivers/vhost/vdpa.c +++ b/drivers/vhost/vdpa.c @@ -682,6 +682,8 @@ static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v= , unsigned int cmd, return -EFAULT; if (idx >=3D vdpa->ngroups || s.num >=3D vdpa->nas) return -EINVAL; + if (ops->get_status(vdpa) & VIRTIO_CONFIG_S_DRIVER_OK) + return -EBUSY; if (!ops->set_group_asid) return -EOPNOTSUPP; return ops->set_group_asid(vdpa, idx, s.num); --=20 2.52.0 From nobody Sat Feb 7 08:44:20 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5EA0B3803F1 for ; Mon, 19 Jan 2026 14:33:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768833226; cv=none; b=LWxkxIgTJGPojSkY/8y5Fa8XKRs9cWcWOfM2djYjPelkT2TRhMQmCiuCwDJfVfO45bwqbdjGQSKEFsfof/pr+SRR+fRkYJudmZANpgtscsXgVwKi4aXMNPhDPln94WBmf8vwVKGBpPD5UDDodyQmx/S8jJTxuFWNn8/VqIzHhDE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768833226; c=relaxed/simple; bh=7WkiaFQXSJ9rftIhsrRPJDimmW5NW0HIRoiDY1dK0Yc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=d9E2odDVWWPe1W+lzc4eFBIsPuq6LEBTf/er5l1l20KasuxIetj3xTZR9mFZGH6y84frVy2CkaRjfy+lXQEk0YdNA4jBpWfhYhU05sL4/DuFsSCIKj0DhhPhdL6KEiCoCRv57IEZe+V9dSIip41XaRjT8rX9hXrRNX9HGgXQQlU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=LsYlHg9Y; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="LsYlHg9Y" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1768833224; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=f3i9Zfy1TusGrkGCrHl6HZAZANNAsOmF+dD9gg6kSpw=; b=LsYlHg9Y/lKHYtro4Mrp2/wycR3I7lTYPN1A3Gon+mZ/C61bpwcgm8SGvz9FBU/yCcYx6D ahq14wZa5Mn0Vygo5CdaOtWTADdLBoxtm14e3oyxWf4iRn3iFw8LTESBF4/lMvTVxFXVD1 xtdhoNqbqD7TRB0Bt9FHD1saipavPYc= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-600-WQGgtf7nMUmilmjflzxOVg-1; Mon, 19 Jan 2026 09:33:41 -0500 X-MC-Unique: WQGgtf7nMUmilmjflzxOVg-1 X-Mimecast-MFC-AGG-ID: WQGgtf7nMUmilmjflzxOVg_1768833220 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 4C3901800350; Mon, 19 Jan 2026 14:33:40 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.44.33.172]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id DE6541800577; Mon, 19 Jan 2026 14:33:36 +0000 (UTC) From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= To: "Michael S . Tsirkin " Cc: virtualization@lists.linux.dev, Yongji Xie , Xuan Zhuo , Maxime Coquelin , Stefano Garzarella , jasowang@redhat.com, =?UTF-8?q?Eugenio=20P=C3=A9rez?= , Laurent Vivier , Cindy Lu , linux-kernel@vger.kernel.org Subject: [PATCH v15 07/13] vduse: refactor vdpa_dev_add for goto err handling Date: Mon, 19 Jan 2026 15:33:00 +0100 Message-ID: <20260119143306.1818855-8-eperezma@redhat.com> In-Reply-To: <20260119143306.1818855-1-eperezma@redhat.com> References: <20260119143306.1818855-1-eperezma@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 Next patches introduce more error paths in this function. Refactor it so they can be accommodated through gotos. Acked-by: Jason Wang Reviewed-by: Xie Yongji Signed-off-by: Eugenio P=C3=A9rez --- v12: Fix typo in patch message (MST). v6: New in v6. --- drivers/vdpa/vdpa_user/vduse_dev.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/drivers/vdpa/vdpa_user/vduse_dev.c b/drivers/vdpa/vdpa_user/vd= use_dev.c index 68290c3d9d8f..43851b0711ac 100644 --- a/drivers/vdpa/vdpa_user/vduse_dev.c +++ b/drivers/vdpa/vdpa_user/vduse_dev.c @@ -2171,21 +2171,27 @@ static int vdpa_dev_add(struct vdpa_mgmt_dev *mdev,= const char *name, dev->bounce_size); mutex_unlock(&dev->domain_lock); if (!dev->domain) { - put_device(&dev->vdev->vdpa.dev); - return -ENOMEM; + ret =3D -ENOMEM; + goto domain_err; } =20 ret =3D _vdpa_register_device(&dev->vdev->vdpa, dev->vq_num); if (ret) { - put_device(&dev->vdev->vdpa.dev); - mutex_lock(&dev->domain_lock); - vduse_domain_destroy(dev->domain); - dev->domain =3D NULL; - mutex_unlock(&dev->domain_lock); - return ret; + goto register_err; } =20 return 0; + +register_err: + mutex_lock(&dev->domain_lock); + vduse_domain_destroy(dev->domain); + dev->domain =3D NULL; + mutex_unlock(&dev->domain_lock); + +domain_err: + put_device(&dev->vdev->vdpa.dev); + + return ret; } =20 static void vdpa_dev_del(struct vdpa_mgmt_dev *mdev, struct vdpa_device *d= ev) --=20 2.52.0 From nobody Sat Feb 7 08:44:20 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 97B5138736B for ; Mon, 19 Jan 2026 14:33:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768833230; cv=none; b=MR1qY/bKNIya++8wIoB1nFrnVkun3VL6OCniRhPy7CK7hG5wxL3MUB6Sk1QkmEi8ZX3uQwxryKHHfjfYjGnVUIwJIrA9iymDxATB4ZYuFWrObEZUn6rRVk4bvDVyC3Ae+k4WsV72W1mz0A1z/sWCmzletOGJtVfmH+knZjOZ2GE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768833230; c=relaxed/simple; bh=h1ix4/OpVOP1YodydNrqu+/k/yp+QcMNM+RWjSLIAnI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=LVpE0zjDK/rAle7lT9YCsZud8ka8MUJvCoyyPauxbASMJfedKPHpVLxdZ6WrMkDo94lAy9Su9f3PbdHuWFSV6K5N1pj5vxlxS/uHYaEjfRKYuhhP1jp/EXjPKEL4Zy+Y89MUc1yDnA1OHfjKMQlWYlQzH508e1HQfGZSPH3K3B8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=OJo7hLc0; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="OJo7hLc0" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1768833228; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=t8r37IrWlL6TNwvrTbZ9d4b9SIJ0stlyZpgQwTmkyS4=; b=OJo7hLc0lw+D5+6kxbfMF1ZPpqflbT2LPnMKazEPYgcKNzMY9AWI9J+L2mJ5h9UmjpLZoe ztpzq9ZL06uznJn7yChk+whwD9XnGP+j/VYbPoND6vPEYRch+o6mSnFBPd1MQTIR5DycWS Kp2tr+Akw8hHOFLIlkjQejKOgbJ2AV4= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-628-YS9zLvdGPiup-F2WwAIabA-1; Mon, 19 Jan 2026 09:33:45 -0500 X-MC-Unique: YS9zLvdGPiup-F2WwAIabA-1 X-Mimecast-MFC-AGG-ID: YS9zLvdGPiup-F2WwAIabA_1768833224 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 779BA1956094; Mon, 19 Jan 2026 14:33:44 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.44.33.172]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 00CC11800240; Mon, 19 Jan 2026 14:33:40 +0000 (UTC) From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= To: "Michael S . Tsirkin " Cc: virtualization@lists.linux.dev, Yongji Xie , Xuan Zhuo , Maxime Coquelin , Stefano Garzarella , jasowang@redhat.com, =?UTF-8?q?Eugenio=20P=C3=A9rez?= , Laurent Vivier , Cindy Lu , linux-kernel@vger.kernel.org Subject: [PATCH v15 08/13] vduse: remove unused vaddr parameter of vduse_domain_free_coherent Date: Mon, 19 Jan 2026 15:33:01 +0100 Message-ID: <20260119143306.1818855-9-eperezma@redhat.com> In-Reply-To: <20260119143306.1818855-1-eperezma@redhat.com> References: <20260119143306.1818855-1-eperezma@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 We will modify the function in next patches so let's clean it first. Signed-off-by: Eugenio P=C3=A9rez --- drivers/vdpa/vdpa_user/iova_domain.c | 3 +-- drivers/vdpa/vdpa_user/iova_domain.h | 3 +-- drivers/vdpa/vdpa_user/vduse_dev.c | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/vdpa/vdpa_user/iova_domain.c b/drivers/vdpa/vdpa_user/= iova_domain.c index 4352b5cf74f0..309cd5a039d1 100644 --- a/drivers/vdpa/vdpa_user/iova_domain.c +++ b/drivers/vdpa/vdpa_user/iova_domain.c @@ -528,8 +528,7 @@ void *vduse_domain_alloc_coherent(struct vduse_iova_dom= ain *domain, } =20 void vduse_domain_free_coherent(struct vduse_iova_domain *domain, size_t s= ize, - void *vaddr, dma_addr_t dma_addr, - unsigned long attrs) + dma_addr_t dma_addr, unsigned long attrs) { struct iova_domain *iovad =3D &domain->consistent_iovad; struct vhost_iotlb_map *map; diff --git a/drivers/vdpa/vdpa_user/iova_domain.h b/drivers/vdpa/vdpa_user/= iova_domain.h index a923971a64f5..081f06c52cdc 100644 --- a/drivers/vdpa/vdpa_user/iova_domain.h +++ b/drivers/vdpa/vdpa_user/iova_domain.h @@ -70,8 +70,7 @@ void *vduse_domain_alloc_coherent(struct vduse_iova_domai= n *domain, gfp_t flag); =20 void vduse_domain_free_coherent(struct vduse_iova_domain *domain, size_t s= ize, - void *vaddr, dma_addr_t dma_addr, - unsigned long attrs); + dma_addr_t dma_addr, unsigned long attrs); =20 void vduse_domain_reset_bounce_map(struct vduse_iova_domain *domain); =20 diff --git a/drivers/vdpa/vdpa_user/vduse_dev.c b/drivers/vdpa/vdpa_user/vd= use_dev.c index 43851b0711ac..0e3cf5128ad0 100644 --- a/drivers/vdpa/vdpa_user/vduse_dev.c +++ b/drivers/vdpa/vdpa_user/vduse_dev.c @@ -948,7 +948,7 @@ static void vduse_dev_free_coherent(union virtio_map to= ken, size_t size, vdev =3D token.group->dev; domain =3D vdev->domain; =20 - vduse_domain_free_coherent(domain, size, vaddr, dma_addr, attrs); + vduse_domain_free_coherent(domain, size, dma_addr, attrs); } =20 static bool vduse_dev_need_sync(union virtio_map token, dma_addr_t dma_add= r) --=20 2.52.0 From nobody Sat Feb 7 08:44:20 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3D9DC38735A for ; Mon, 19 Jan 2026 14:33:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768833233; cv=none; b=nKhsh+QR7e5aktsncpskidkr78WSbkcYQ4AFo6ZEesgEJ4y1zUw9To2j/J76s3G6vLwTKQG9B47nb7QvyoU/4lw9RwuDvKegah/jxgmzse1Q032actxMhEU8nIOrPWkdgzixb8WQIs/mMUXIMp0wXlO9Q7kqbGyW/emAK5VCQIw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768833233; c=relaxed/simple; bh=76EIoIOaG6/VJajsr8Jtx+vVzMJQ7SRBLU3Sfot2koE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=rQ4s/ZyedDldTPxitiR1mbVX9cQWA0Nz1VogXSc03uzhlJrtSryKsjxIOHjig7eNPRuIEQFIfRmdlgzr/+huXFE63lKnu8a1/spO1KAIiXJDbz2+NbYLj62TowOH2/Wy5WKoqUFufyInKEm7ocpu/P3uJTDpI083bpvTyMFUQYM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=LPWTrChv; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="LPWTrChv" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1768833231; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=s81dUgqwYas7OncME6/Tc3HamdjySXE8XHF7PknnqC0=; b=LPWTrChvV1QipuiYdlo09l8pBKz54V2oriHztys82CihfEyXE5VVZuHK0RVATnP1tspU4Z 8paWdZqD1x7H4nQ/tRZ4nqQuatTAtQneZlNUJZ0lB8ygwKa6X0KvSp+amJL9r8SSu/lu4h JM6phVR12mW58n4MMSn7hYoLdAmTtqM= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-338-o7isd5N-NeCu3b31O0AOcA-1; Mon, 19 Jan 2026 09:33:49 -0500 X-MC-Unique: o7isd5N-NeCu3b31O0AOcA-1 X-Mimecast-MFC-AGG-ID: o7isd5N-NeCu3b31O0AOcA_1768833228 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id C7AD41956046; Mon, 19 Jan 2026 14:33:48 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.44.33.172]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id F29411800577; Mon, 19 Jan 2026 14:33:44 +0000 (UTC) From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= To: "Michael S . Tsirkin " Cc: virtualization@lists.linux.dev, Yongji Xie , Xuan Zhuo , Maxime Coquelin , Stefano Garzarella , jasowang@redhat.com, =?UTF-8?q?Eugenio=20P=C3=A9rez?= , Laurent Vivier , Cindy Lu , linux-kernel@vger.kernel.org Subject: [PATCH v15 09/13] vduse: take out allocations from vduse_dev_alloc_coherent Date: Mon, 19 Jan 2026 15:33:02 +0100 Message-ID: <20260119143306.1818855-10-eperezma@redhat.com> In-Reply-To: <20260119143306.1818855-1-eperezma@redhat.com> References: <20260119143306.1818855-1-eperezma@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 The function vduse_dev_alloc_coherent will be called under rwlock in next patches. Make it out of the lock to avoid increasing its fail rate. Acked-by: Jason Wang Signed-off-by: Eugenio P=C3=A9rez --- v12: * Avoid free_pages_exact(NULL, size) in case vduse_domain_alloc_coherent fails (MST). v11: Remove duplicated call to free_pages_exact (Jason). --- drivers/vdpa/vdpa_user/iova_domain.c | 24 +++++++----------------- drivers/vdpa/vdpa_user/iova_domain.h | 5 ++--- drivers/vdpa/vdpa_user/vduse_dev.c | 17 +++++++++++------ 3 files changed, 20 insertions(+), 26 deletions(-) diff --git a/drivers/vdpa/vdpa_user/iova_domain.c b/drivers/vdpa/vdpa_user/= iova_domain.c index 309cd5a039d1..0a9f668467a8 100644 --- a/drivers/vdpa/vdpa_user/iova_domain.c +++ b/drivers/vdpa/vdpa_user/iova_domain.c @@ -493,17 +493,15 @@ void vduse_domain_unmap_page(struct vduse_iova_domain= *domain, vduse_domain_free_iova(iovad, dma_addr, size); } =20 -void *vduse_domain_alloc_coherent(struct vduse_iova_domain *domain, - size_t size, dma_addr_t *dma_addr, - gfp_t flag) +dma_addr_t vduse_domain_alloc_coherent(struct vduse_iova_domain *domain, + size_t size, void *orig) { struct iova_domain *iovad =3D &domain->consistent_iovad; unsigned long limit =3D domain->iova_limit; dma_addr_t iova =3D vduse_domain_alloc_iova(iovad, size, limit); - void *orig =3D alloc_pages_exact(size, flag); =20 - if (!iova || !orig) - goto err; + if (!iova) + return DMA_MAPPING_ERROR; =20 spin_lock(&domain->iotlb_lock); if (vduse_iotlb_add_range(domain, (u64)iova, (u64)iova + size - 1, @@ -514,17 +512,12 @@ void *vduse_domain_alloc_coherent(struct vduse_iova_d= omain *domain, } spin_unlock(&domain->iotlb_lock); =20 - *dma_addr =3D iova; + return iova; =20 - return orig; err: - *dma_addr =3D DMA_MAPPING_ERROR; - if (orig) - free_pages_exact(orig, size); - if (iova) - vduse_domain_free_iova(iovad, iova, size); + vduse_domain_free_iova(iovad, iova, size); =20 - return NULL; + return DMA_MAPPING_ERROR; } =20 void vduse_domain_free_coherent(struct vduse_iova_domain *domain, size_t s= ize, @@ -533,7 +526,6 @@ void vduse_domain_free_coherent(struct vduse_iova_domai= n *domain, size_t size, struct iova_domain *iovad =3D &domain->consistent_iovad; struct vhost_iotlb_map *map; struct vdpa_map_file *map_file; - phys_addr_t pa; =20 spin_lock(&domain->iotlb_lock); map =3D vhost_iotlb_itree_first(domain->iotlb, (u64)dma_addr, @@ -545,12 +537,10 @@ void vduse_domain_free_coherent(struct vduse_iova_dom= ain *domain, size_t size, map_file =3D (struct vdpa_map_file *)map->opaque; fput(map_file->file); kfree(map_file); - pa =3D map->addr; vhost_iotlb_map_free(domain->iotlb, map); spin_unlock(&domain->iotlb_lock); =20 vduse_domain_free_iova(iovad, dma_addr, size); - free_pages_exact(phys_to_virt(pa), size); } =20 static vm_fault_t vduse_domain_mmap_fault(struct vm_fault *vmf) diff --git a/drivers/vdpa/vdpa_user/iova_domain.h b/drivers/vdpa/vdpa_user/= iova_domain.h index 081f06c52cdc..e50e55d1396f 100644 --- a/drivers/vdpa/vdpa_user/iova_domain.h +++ b/drivers/vdpa/vdpa_user/iova_domain.h @@ -65,9 +65,8 @@ void vduse_domain_unmap_page(struct vduse_iova_domain *do= main, dma_addr_t dma_addr, size_t size, enum dma_data_direction dir, unsigned long attrs); =20 -void *vduse_domain_alloc_coherent(struct vduse_iova_domain *domain, - size_t size, dma_addr_t *dma_addr, - gfp_t flag); +dma_addr_t vduse_domain_alloc_coherent(struct vduse_iova_domain *domain, + size_t size, void *orig); =20 void vduse_domain_free_coherent(struct vduse_iova_domain *domain, size_t s= ize, dma_addr_t dma_addr, unsigned long attrs); diff --git a/drivers/vdpa/vdpa_user/vduse_dev.c b/drivers/vdpa/vdpa_user/vd= use_dev.c index 0e3cf5128ad0..6dba1f3224d9 100644 --- a/drivers/vdpa/vdpa_user/vduse_dev.c +++ b/drivers/vdpa/vdpa_user/vduse_dev.c @@ -916,23 +916,27 @@ static void *vduse_dev_alloc_coherent(union virtio_ma= p token, size_t size, { struct vduse_dev *vdev; struct vduse_iova_domain *domain; - unsigned long iova; void *addr; =20 *dma_addr =3D DMA_MAPPING_ERROR; if (!token.group) return NULL; =20 - vdev =3D token.group->dev; - domain =3D vdev->domain; - addr =3D vduse_domain_alloc_coherent(domain, size, - (dma_addr_t *)&iova, flag); + addr =3D alloc_pages_exact(size, flag); if (!addr) return NULL; =20 - *dma_addr =3D (dma_addr_t)iova; + vdev =3D token.group->dev; + domain =3D vdev->domain; + *dma_addr =3D vduse_domain_alloc_coherent(domain, size, addr); + if (*dma_addr =3D=3D DMA_MAPPING_ERROR) + goto err; =20 return addr; + +err: + free_pages_exact(addr, size); + return NULL; } =20 static void vduse_dev_free_coherent(union virtio_map token, size_t size, @@ -949,6 +953,7 @@ static void vduse_dev_free_coherent(union virtio_map to= ken, size_t size, domain =3D vdev->domain; =20 vduse_domain_free_coherent(domain, size, dma_addr, attrs); + free_pages_exact(vaddr, size); } =20 static bool vduse_dev_need_sync(union virtio_map token, dma_addr_t dma_add= r) --=20 2.52.0 From nobody Sat Feb 7 08:44:20 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 143D036A016 for ; Mon, 19 Jan 2026 14:33:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768833240; cv=none; b=tQfPuDk1uRZzPBqZZCH1pIOTiPY4tXMwA/0593maAJF4nNzwmb2p2MYHUI3Zrmxb2nvUngYUK4/Qd114A1yrX//5feSPGSfN1lCxdEJCH7MZYmPBSBmZ8XfIihEcN5eCu1a2Mh9s5++HDmNHCQioHllaRj3yFMcZQ6JkwC12/44= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768833240; c=relaxed/simple; bh=AimIqLwDwFqU/VYLHq9pcqceqsnZeo0vk/CGh+mOb0I=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=s5HtnBAOQdExP6dBr/baj6jLVVjcZB4CqSFm8ynbfz8kquzbKEaq93ixWpU4LYO8sUrAVzp2Xt8poUJohHdxUuI2QlCbe/gy75mQNRM9PwTlytm4ERHF087q1B9ywiAvfAPXdR9OElaDl3rYlJZ5jVz+cSZChe7IC3ZzGKxnEHo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=iIhzv2z4; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="iIhzv2z4" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1768833238; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=39uS40AgwdLdJUDJkmzk5mWP425u+w5wovCFEBCRmyA=; b=iIhzv2z4A9ucZDMg0+g+TsLmAtlt2TirmApIXu8rDpxJ/D1qCfgR+8+vOc5e6SHqyIPkwL BAU48nTSccpsp3Fk8rX6wWduKw2DADD3la6IGGK/OWqtc7A62ldB0LNuSGqzV5I4k4ONos sOAt0FjrnYnVGVr8fEnjrVlzNu7Z+CU= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-483-fTFor_B9OzS7RnUJQt9X2Q-1; Mon, 19 Jan 2026 09:33:54 -0500 X-MC-Unique: fTFor_B9OzS7RnUJQt9X2Q-1 X-Mimecast-MFC-AGG-ID: fTFor_B9OzS7RnUJQt9X2Q_1768833232 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id C62A51956080; Mon, 19 Jan 2026 14:33:52 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.44.33.172]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 4E9661800577; Mon, 19 Jan 2026 14:33:49 +0000 (UTC) From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= To: "Michael S . Tsirkin " Cc: virtualization@lists.linux.dev, Yongji Xie , Xuan Zhuo , Maxime Coquelin , Stefano Garzarella , jasowang@redhat.com, =?UTF-8?q?Eugenio=20P=C3=A9rez?= , Laurent Vivier , Cindy Lu , linux-kernel@vger.kernel.org Subject: [PATCH v15 10/13] vduse: merge tree search logic of IOTLB_GET_FD and IOTLB_GET_INFO ioctls Date: Mon, 19 Jan 2026 15:33:03 +0100 Message-ID: <20260119143306.1818855-11-eperezma@redhat.com> In-Reply-To: <20260119143306.1818855-1-eperezma@redhat.com> References: <20260119143306.1818855-1-eperezma@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 The next patch adds new ioctl with the ASID member per entry. Abstract these two so it can be build on top easily. Acked-by: Jason Wang Signed-off-by: Eugenio P=C3=A9rez --- v12: * Avoid dereferencing map_file if not assigned in vduse_dev_iotlb_entry function (MST). v11: New in v11 --- drivers/vdpa/vdpa_user/vduse_dev.c | 102 ++++++++++++++++------------- 1 file changed, 56 insertions(+), 46 deletions(-) diff --git a/drivers/vdpa/vdpa_user/vduse_dev.c b/drivers/vdpa/vdpa_user/vd= use_dev.c index 6dba1f3224d9..d658f3e1cebf 100644 --- a/drivers/vdpa/vdpa_user/vduse_dev.c +++ b/drivers/vdpa/vdpa_user/vduse_dev.c @@ -1243,6 +1243,51 @@ static void vduse_vq_update_effective_cpu(struct vdu= se_virtqueue *vq) vq->irq_effective_cpu =3D curr_cpu; } =20 +static int vduse_dev_iotlb_entry(struct vduse_dev *dev, + struct vduse_iotlb_entry *entry, + struct file **f, uint64_t *capability) +{ + int r =3D -EINVAL; + struct vhost_iotlb_map *map; + + if (entry->start > entry->last) + return -EINVAL; + + mutex_lock(&dev->domain_lock); + if (!dev->domain) + goto out; + + spin_lock(&dev->domain->iotlb_lock); + map =3D vhost_iotlb_itree_first(dev->domain->iotlb, entry->start, + entry->last); + if (map) { + if (f) { + const struct vdpa_map_file *map_file; + + map_file =3D (struct vdpa_map_file *)map->opaque; + entry->offset =3D map_file->offset; + *f =3D get_file(map_file->file); + } + entry->start =3D map->start; + entry->last =3D map->last; + entry->perm =3D map->perm; + if (capability) { + *capability =3D 0; + + if (dev->domain->bounce_map && map->start =3D=3D 0 && + map->last =3D=3D dev->domain->bounce_size - 1) + *capability |=3D VDUSE_IOVA_CAP_UMEM; + } + + r =3D 0; + } + spin_unlock(&dev->domain->iotlb_lock); + +out: + mutex_unlock(&dev->domain_lock); + return r; +} + static long vduse_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { @@ -1256,36 +1301,16 @@ static long vduse_dev_ioctl(struct file *file, unsi= gned int cmd, switch (cmd) { case VDUSE_IOTLB_GET_FD: { struct vduse_iotlb_entry entry; - struct vhost_iotlb_map *map; - struct vdpa_map_file *map_file; struct file *f =3D NULL; =20 ret =3D -EFAULT; if (copy_from_user(&entry, argp, sizeof(entry))) break; =20 - ret =3D -EINVAL; - if (entry.start > entry.last) + ret =3D vduse_dev_iotlb_entry(dev, &entry, &f, NULL); + if (ret) break; =20 - mutex_lock(&dev->domain_lock); - if (!dev->domain) { - mutex_unlock(&dev->domain_lock); - break; - } - spin_lock(&dev->domain->iotlb_lock); - map =3D vhost_iotlb_itree_first(dev->domain->iotlb, - entry.start, entry.last); - if (map) { - map_file =3D (struct vdpa_map_file *)map->opaque; - f =3D get_file(map_file->file); - entry.offset =3D map_file->offset; - entry.start =3D map->start; - entry.last =3D map->last; - entry.perm =3D map->perm; - } - spin_unlock(&dev->domain->iotlb_lock); - mutex_unlock(&dev->domain_lock); ret =3D -EINVAL; if (!f) break; @@ -1475,41 +1500,26 @@ static long vduse_dev_ioctl(struct file *file, unsi= gned int cmd, } case VDUSE_IOTLB_GET_INFO: { struct vduse_iova_info info; - struct vhost_iotlb_map *map; + struct vduse_iotlb_entry entry; =20 ret =3D -EFAULT; if (copy_from_user(&info, argp, sizeof(info))) break; =20 - ret =3D -EINVAL; - if (info.start > info.last) - break; - if (!is_mem_zero((const char *)info.reserved, sizeof(info.reserved))) break; =20 - mutex_lock(&dev->domain_lock); - if (!dev->domain) { - mutex_unlock(&dev->domain_lock); - break; - } - spin_lock(&dev->domain->iotlb_lock); - map =3D vhost_iotlb_itree_first(dev->domain->iotlb, - info.start, info.last); - if (map) { - info.start =3D map->start; - info.last =3D map->last; - info.capability =3D 0; - if (dev->domain->bounce_map && map->start =3D=3D 0 && - map->last =3D=3D dev->domain->bounce_size - 1) - info.capability |=3D VDUSE_IOVA_CAP_UMEM; - } - spin_unlock(&dev->domain->iotlb_lock); - mutex_unlock(&dev->domain_lock); - if (!map) + entry.start =3D info.start; + entry.last =3D info.last; + ret =3D vduse_dev_iotlb_entry(dev, &entry, NULL, + &info.capability); + if (ret < 0) break; =20 + info.start =3D entry.start; + info.last =3D entry.last; + ret =3D -EFAULT; if (copy_to_user(argp, &info, sizeof(info))) break; --=20 2.52.0 From nobody Sat Feb 7 08:44:20 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 988F5368261 for ; Mon, 19 Jan 2026 14:34:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768833247; cv=none; b=mCx5YKw5AMDRhxT5GClQsJvpxn62ZfR36F5lJLHfEUju6XJbjxi6vVskC63Keimf7WgMNGDmASEk0BYQpcBGVa0YciCHXH1yoh18f/bthLCvsLihOnupx+CvIA9v0GHjX2dkQknMkmN4fJ8cGR3F85UdAosyvdueFk7ih9phD2w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768833247; c=relaxed/simple; bh=BcdUoZxF9PhEagE7qYf3YHZPnuZv9qE5ZFPYKMsFwfo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=QJGIFZRTNNlNRQgbbFat5XexdMLaMDsTKREEQj1SkchR0nkSCcTSL/a1il39+Dhgig1d/DOIbMBZ0Hwb2VPKiFaiTyHBDQxlnY+CkduSq/s5fe90eT7NAFj+anJVTCjRlaDeuOLx083zkA6dqYZ3CppKpMlrY9MGA0xkbaxAiQI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=aeZ+2A3D; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="aeZ+2A3D" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1768833243; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=lvcEyg4/KWesHt9o6s3Qi82wNGFYIbHPJhprxpEagJE=; b=aeZ+2A3DV0drl2BVX4d6EVdIHmiZfsZdTEUYd3mBaEj+SDyfTdoW1YefJiMTQ5KjcsnEGx pDJip9uJTe8mkHYp+F+668euLtBgxApVRf99az+AYVQSZI7nMa8aXHXReHKJ5Xg04ZiGSB TNnSleii1hnMPk5vM2VTqQLpoPTwVqA= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-437-W-PyALbsOJ2MpwfIO_wFzw-1; Mon, 19 Jan 2026 09:33:58 -0500 X-MC-Unique: W-PyALbsOJ2MpwfIO_wFzw-1 X-Mimecast-MFC-AGG-ID: W-PyALbsOJ2MpwfIO_wFzw_1768833237 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 14DC81956054; Mon, 19 Jan 2026 14:33:57 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.44.33.172]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 4CBB91800240; Mon, 19 Jan 2026 14:33:53 +0000 (UTC) From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= To: "Michael S . Tsirkin " Cc: virtualization@lists.linux.dev, Yongji Xie , Xuan Zhuo , Maxime Coquelin , Stefano Garzarella , jasowang@redhat.com, =?UTF-8?q?Eugenio=20P=C3=A9rez?= , Laurent Vivier , Cindy Lu , linux-kernel@vger.kernel.org Subject: [PATCH v15 11/13] vduse: add vq group asid support Date: Mon, 19 Jan 2026 15:33:04 +0100 Message-ID: <20260119143306.1818855-12-eperezma@redhat.com> In-Reply-To: <20260119143306.1818855-1-eperezma@redhat.com> References: <20260119143306.1818855-1-eperezma@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 Add support for assigning Address Space Identifiers (ASIDs) to each VQ group. This enables mapping each group into a distinct memory space. The vq group to ASID association is protected by a rwlock now. But the mutex domain_lock keeps protecting the domains of all ASIDs, as some operations like the one related with the bounce buffer size still requires to lock all the ASIDs. Acked-by: Jason Wang Signed-off-by: Eugenio P=C3=A9rez --- Future improvements can include performance optimizations on top like ore to RCU or thread synchronized atomics, or hardening by tracking ASID or ASID hashes on unused bits of the DMA address. Tested virtio_vdpa by adding manually two threads in vduse_set_status: one of them modifies the vq group 0 ASID and the other one map and unmap memory continuously. After a while, the two threads stop and the usual work continues. Test with version 0, version 1 with the old ioctl, and version 1 with the new ioctl. Tested with vhost_vdpa by migrating a VM while ping on OVS+VDUSE. A few workaround were needed in some parts: * Do not enable CVQ before data vqs in QEMU, as VDUSE does not forward the enable message to the userland device. This will be solved in the future. * Share the suspended state between all vhost devices in QEMU: https://lists.nongnu.org/archive/html/qemu-devel/2025-11/msg02947.html * Implement a fake VDUSE suspend vdpa operation callback that always returns true in the kernel. DPDK suspend the device at the first GET_VRING_BASE. * Remove the CVQ blocker in ASID. The driver vhost_vdpa was also tested with version 0, version 1 with the old ioctl, version 1 with the new ioctl but only one ASID, and version 1 with many ASID. --- v15: * Fix doc typo (Alok). * Document vduse config @nas member. v13: * Add documentation for VDUSE_SET_VQ_READY VDUSE message to userspace. v12: * Using scoped guards for vq group rwlock, so the one queue optimization is not missed (Jason proposed to factor them into helpers). * Add the _v2 suffix to vduse_iova_range_v2 struct name fixing the doc (MST). * s/verion/version/ in patch message. * Remove trailing ; after a comment (Jason). v11: * Remove duplicated free_pages_exact in vduse_domain_free_coherent (Jason). * Do not take the vq groups lock if nas =3D=3D 1. * Do not reset the vq group ASID in vq reset (Jason). Removed extra function vduse_set_group_asid_nomsg, not needed anymore. * Move the vduse_iotlb_entry_v2 argument to a new ioctl, as argument didn't match the previous VDUSE_IOTLB_GET_FD. * Move the asid < dev->nas check to vdpa core. v10: * Back to rwlock version so stronger locks are used. * Take out allocations from rwlock. * Forbid changing ASID of a vq group after DRIVER_OK (Jason) * Remove bad fetching again of domain variable in vduse_dev_max_mapping_size (Yongji). * Remove unused vdev definition in vdpa map_ops callbacks (kernel test robot). v9: * Replace mutex with rwlock, as the vdpa map_ops can run from atomic context. v8: * Revert the mutex to rwlock change, it needs proper profiling to justify it. v7: * Take write lock in the error path (Jason). v6: * Make vdpa_dev_add use gotos for error handling (MST). * s/(dev->api_version < 1) ?/(dev->api_version < VDUSE_API_VERSION_1) ?/ (MST). * Fix struct name not matching in the doc. v5: * Properly return errno if copy_to_user returns >0 in VDUSE_IOTLB_GET_FD ioctl (Jason). * Properly set domain bounce size to divide equally between nas (Jason). * Exclude "padding" member from the only >V1 members in vduse_dev_request. v4: * Divide each domain bounce size between the device bounce size (Jason). * revert unneeded addr =3D NULL assignment (Jason) * Change if (x && (y || z)) return to if (x) { if (y) return; if (z) return; } (Jason) * Change a bad multiline comment, using @ caracter instead of * (Jason). * Consider config->nas =3D=3D 0 as a fail (Jason). v3: * Get the vduse domain through the vduse_as in the map functions (Jason). * Squash with the patch creating the vduse_as struct (Jason). * Create VDUSE_DEV_MAX_AS instead of comparing agains a magic number (Jason) v2: * Convert the use of mutex to rwlock. RFC v3: * Increase VDUSE_MAX_VQ_GROUPS to 0xffff (Jason). It was set to a lower value to reduce memory consumption, but vqs are already limited to that value and userspace VDUSE is able to allocate that many vqs. * Remove TODO about merging VDUSE_IOTLB_GET_FD ioctl with VDUSE_IOTLB_GET_INFO. * Use of array_index_nospec in VDUSE device ioctls. * Embed vduse_iotlb_entry into vduse_iotlb_entry_v2. * Move the umem mutex to asid struct so there is no contention between ASIDs. RFC v2: * Make iotlb entry the last one of vduse_iotlb_entry_v2 so the first part of the struct is the same. --- drivers/vdpa/vdpa_user/vduse_dev.c | 385 +++++++++++++++++++---------- include/uapi/linux/vduse.h | 66 ++++- 2 files changed, 315 insertions(+), 136 deletions(-) diff --git a/drivers/vdpa/vdpa_user/vduse_dev.c b/drivers/vdpa/vdpa_user/vd= use_dev.c index d658f3e1cebf..2727c0c26003 100644 --- a/drivers/vdpa/vdpa_user/vduse_dev.c +++ b/drivers/vdpa/vdpa_user/vduse_dev.c @@ -9,6 +9,7 @@ */ =20 #include "linux/virtio_net.h" +#include #include #include #include @@ -41,6 +42,7 @@ =20 #define VDUSE_DEV_MAX (1U << MINORBITS) #define VDUSE_DEV_MAX_GROUPS 0xffff +#define VDUSE_DEV_MAX_AS 0xffff #define VDUSE_MAX_BOUNCE_SIZE (1024 * 1024 * 1024) #define VDUSE_MIN_BOUNCE_SIZE (1024 * 1024) #define VDUSE_BOUNCE_SIZE (64 * 1024 * 1024) @@ -86,7 +88,15 @@ struct vduse_umem { struct mm_struct *mm; }; =20 +struct vduse_as { + struct vduse_iova_domain *domain; + struct vduse_umem *umem; + struct mutex mem_lock; +}; + struct vduse_vq_group { + rwlock_t as_lock; + struct vduse_as *as; /* Protected by as_lock */ struct vduse_dev *dev; }; =20 @@ -94,7 +104,7 @@ struct vduse_dev { struct vduse_vdpa *vdev; struct device *dev; struct vduse_virtqueue **vqs; - struct vduse_iova_domain *domain; + struct vduse_as *as; char *name; struct mutex lock; spinlock_t msg_lock; @@ -122,9 +132,8 @@ struct vduse_dev { u32 vq_num; u32 vq_align; u32 ngroups; - struct vduse_umem *umem; + u32 nas; struct vduse_vq_group *groups; - struct mutex mem_lock; unsigned int bounce_size; struct mutex domain_lock; }; @@ -314,7 +323,7 @@ static int vduse_dev_set_status(struct vduse_dev *dev, = u8 status) return vduse_dev_msg_sync(dev, &msg); } =20 -static int vduse_dev_update_iotlb(struct vduse_dev *dev, +static int vduse_dev_update_iotlb(struct vduse_dev *dev, u32 asid, u64 start, u64 last) { struct vduse_dev_msg msg =3D { 0 }; @@ -323,8 +332,14 @@ static int vduse_dev_update_iotlb(struct vduse_dev *de= v, return -EINVAL; =20 msg.req.type =3D VDUSE_UPDATE_IOTLB; - msg.req.iova.start =3D start; - msg.req.iova.last =3D last; + if (dev->api_version < VDUSE_API_VERSION_1) { + msg.req.iova.start =3D start; + msg.req.iova.last =3D last; + } else { + msg.req.iova_v2.start =3D start; + msg.req.iova_v2.last =3D last; + msg.req.iova_v2.asid =3D asid; + } =20 return vduse_dev_msg_sync(dev, &msg); } @@ -439,11 +454,14 @@ static __poll_t vduse_dev_poll(struct file *file, pol= l_table *wait) static void vduse_dev_reset(struct vduse_dev *dev) { int i; - struct vduse_iova_domain *domain =3D dev->domain; =20 /* The coherent mappings are handled in vduse_dev_free_coherent() */ - if (domain && domain->bounce_map) - vduse_domain_reset_bounce_map(domain); + for (i =3D 0; i < dev->nas; i++) { + struct vduse_iova_domain *domain =3D dev->as[i].domain; + + if (domain && domain->bounce_map) + vduse_domain_reset_bounce_map(domain); + } =20 down_write(&dev->rwsem); =20 @@ -622,6 +640,42 @@ static union virtio_map vduse_get_vq_map(struct vdpa_d= evice *vdpa, u16 idx) return ret; } =20 +DEFINE_GUARD(vq_group_as_read_lock, struct vduse_vq_group *, + if (_T->dev->nas > 1) + read_lock(&_T->as_lock), + if (_T->dev->nas > 1) + read_unlock(&_T->as_lock)) + +DEFINE_GUARD(vq_group_as_write_lock, struct vduse_vq_group *, + if (_T->dev->nas > 1) + write_lock(&_T->as_lock), + if (_T->dev->nas > 1) + write_unlock(&_T->as_lock)) + +static int vduse_set_group_asid(struct vdpa_device *vdpa, unsigned int gro= up, + unsigned int asid) +{ + struct vduse_dev *dev =3D vdpa_to_vduse(vdpa); + struct vduse_dev_msg msg =3D { 0 }; + int r; + + if (dev->api_version < VDUSE_API_VERSION_1) + return -EINVAL; + + msg.req.type =3D VDUSE_SET_VQ_GROUP_ASID; + msg.req.vq_group_asid.group =3D group; + msg.req.vq_group_asid.asid =3D asid; + + r =3D vduse_dev_msg_sync(dev, &msg); + if (r < 0) + return r; + + guard(vq_group_as_write_lock)(&dev->groups[group]); + dev->groups[group].as =3D &dev->as[asid]; + + return 0; +} + static int vduse_vdpa_get_vq_state(struct vdpa_device *vdpa, u16 idx, struct vdpa_vq_state *state) { @@ -793,13 +847,13 @@ static int vduse_vdpa_set_map(struct vdpa_device *vdp= a, struct vduse_dev *dev =3D vdpa_to_vduse(vdpa); int ret; =20 - ret =3D vduse_domain_set_map(dev->domain, iotlb); + ret =3D vduse_domain_set_map(dev->as[asid].domain, iotlb); if (ret) return ret; =20 - ret =3D vduse_dev_update_iotlb(dev, 0ULL, ULLONG_MAX); + ret =3D vduse_dev_update_iotlb(dev, asid, 0ULL, ULLONG_MAX); if (ret) { - vduse_domain_clear_map(dev->domain, iotlb); + vduse_domain_clear_map(dev->as[asid].domain, iotlb); return ret; } =20 @@ -842,6 +896,7 @@ static const struct vdpa_config_ops vduse_vdpa_config_o= ps =3D { .get_vq_affinity =3D vduse_vdpa_get_vq_affinity, .reset =3D vduse_vdpa_reset, .set_map =3D vduse_vdpa_set_map, + .set_group_asid =3D vduse_set_group_asid, .get_vq_map =3D vduse_get_vq_map, .free =3D vduse_vdpa_free, }; @@ -850,15 +905,13 @@ static void vduse_dev_sync_single_for_device(union vi= rtio_map token, dma_addr_t dma_addr, size_t size, enum dma_data_direction dir) { - struct vduse_dev *vdev; struct vduse_iova_domain *domain; =20 if (!token.group) return; =20 - vdev =3D token.group->dev; - domain =3D vdev->domain; - + guard(vq_group_as_read_lock)(token.group); + domain =3D token.group->as->domain; vduse_domain_sync_single_for_device(domain, dma_addr, size, dir); } =20 @@ -866,15 +919,13 @@ static void vduse_dev_sync_single_for_cpu(union virti= o_map token, dma_addr_t dma_addr, size_t size, enum dma_data_direction dir) { - struct vduse_dev *vdev; struct vduse_iova_domain *domain; =20 if (!token.group) return; =20 - vdev =3D token.group->dev; - domain =3D vdev->domain; - + guard(vq_group_as_read_lock)(token.group); + domain =3D token.group->as->domain; vduse_domain_sync_single_for_cpu(domain, dma_addr, size, dir); } =20 @@ -883,15 +934,13 @@ static dma_addr_t vduse_dev_map_page(union virtio_map= token, struct page *page, enum dma_data_direction dir, unsigned long attrs) { - struct vduse_dev *vdev; struct vduse_iova_domain *domain; =20 if (!token.group) return DMA_MAPPING_ERROR; =20 - vdev =3D token.group->dev; - domain =3D vdev->domain; - + guard(vq_group_as_read_lock)(token.group); + domain =3D token.group->as->domain; return vduse_domain_map_page(domain, page, offset, size, dir, attrs); } =20 @@ -899,23 +948,19 @@ static void vduse_dev_unmap_page(union virtio_map tok= en, dma_addr_t dma_addr, size_t size, enum dma_data_direction dir, unsigned long attrs) { - struct vduse_dev *vdev; struct vduse_iova_domain *domain; =20 if (!token.group) return; =20 - vdev =3D token.group->dev; - domain =3D vdev->domain; - - return vduse_domain_unmap_page(domain, dma_addr, size, dir, attrs); + guard(vq_group_as_read_lock)(token.group); + domain =3D token.group->as->domain; + vduse_domain_unmap_page(domain, dma_addr, size, dir, attrs); } =20 static void *vduse_dev_alloc_coherent(union virtio_map token, size_t size, dma_addr_t *dma_addr, gfp_t flag) { - struct vduse_dev *vdev; - struct vduse_iova_domain *domain; void *addr; =20 *dma_addr =3D DMA_MAPPING_ERROR; @@ -926,11 +971,15 @@ static void *vduse_dev_alloc_coherent(union virtio_ma= p token, size_t size, if (!addr) return NULL; =20 - vdev =3D token.group->dev; - domain =3D vdev->domain; - *dma_addr =3D vduse_domain_alloc_coherent(domain, size, addr); - if (*dma_addr =3D=3D DMA_MAPPING_ERROR) - goto err; + { + struct vduse_iova_domain *domain; + + guard(vq_group_as_read_lock)(token.group); + domain =3D token.group->as->domain; + *dma_addr =3D vduse_domain_alloc_coherent(domain, size, addr); + if (*dma_addr =3D=3D DMA_MAPPING_ERROR) + goto err; + } =20 return addr; =20 @@ -943,31 +992,27 @@ static void vduse_dev_free_coherent(union virtio_map = token, size_t size, void *vaddr, dma_addr_t dma_addr, unsigned long attrs) { - struct vduse_dev *vdev; - struct vduse_iova_domain *domain; - if (!token.group) return; =20 - vdev =3D token.group->dev; - domain =3D vdev->domain; + { + struct vduse_iova_domain *domain; + + guard(vq_group_as_read_lock)(token.group); + domain =3D token.group->as->domain; + vduse_domain_free_coherent(domain, size, dma_addr, attrs); + } =20 - vduse_domain_free_coherent(domain, size, dma_addr, attrs); free_pages_exact(vaddr, size); } =20 static bool vduse_dev_need_sync(union virtio_map token, dma_addr_t dma_add= r) { - struct vduse_dev *vdev; - struct vduse_iova_domain *domain; - if (!token.group) return false; =20 - vdev =3D token.group->dev; - domain =3D vdev->domain; - - return dma_addr < domain->bounce_size; + guard(vq_group_as_read_lock)(token.group); + return dma_addr < token.group->as->domain->bounce_size; } =20 static int vduse_dev_mapping_error(union virtio_map token, dma_addr_t dma_= addr) @@ -979,16 +1024,11 @@ static int vduse_dev_mapping_error(union virtio_map = token, dma_addr_t dma_addr) =20 static size_t vduse_dev_max_mapping_size(union virtio_map token) { - struct vduse_dev *vdev; - struct vduse_iova_domain *domain; - if (!token.group) return 0; =20 - vdev =3D token.group->dev; - domain =3D vdev->domain; - - return domain->bounce_size; + guard(vq_group_as_read_lock)(token.group); + return token.group->as->domain->bounce_size; } =20 static const struct virtio_map_ops vduse_map_ops =3D { @@ -1128,39 +1168,40 @@ static int vduse_dev_queue_irq_work(struct vduse_de= v *dev, return ret; } =20 -static int vduse_dev_dereg_umem(struct vduse_dev *dev, +static int vduse_dev_dereg_umem(struct vduse_dev *dev, u32 asid, u64 iova, u64 size) { int ret; =20 - mutex_lock(&dev->mem_lock); + mutex_lock(&dev->as[asid].mem_lock); ret =3D -ENOENT; - if (!dev->umem) + if (!dev->as[asid].umem) goto unlock; =20 ret =3D -EINVAL; - if (!dev->domain) + if (!dev->as[asid].domain) goto unlock; =20 - if (dev->umem->iova !=3D iova || size !=3D dev->domain->bounce_size) + if (dev->as[asid].umem->iova !=3D iova || + size !=3D dev->as[asid].domain->bounce_size) goto unlock; =20 - vduse_domain_remove_user_bounce_pages(dev->domain); - unpin_user_pages_dirty_lock(dev->umem->pages, - dev->umem->npages, true); - atomic64_sub(dev->umem->npages, &dev->umem->mm->pinned_vm); - mmdrop(dev->umem->mm); - vfree(dev->umem->pages); - kfree(dev->umem); - dev->umem =3D NULL; + vduse_domain_remove_user_bounce_pages(dev->as[asid].domain); + unpin_user_pages_dirty_lock(dev->as[asid].umem->pages, + dev->as[asid].umem->npages, true); + atomic64_sub(dev->as[asid].umem->npages, &dev->as[asid].umem->mm->pinned_= vm); + mmdrop(dev->as[asid].umem->mm); + vfree(dev->as[asid].umem->pages); + kfree(dev->as[asid].umem); + dev->as[asid].umem =3D NULL; ret =3D 0; unlock: - mutex_unlock(&dev->mem_lock); + mutex_unlock(&dev->as[asid].mem_lock); return ret; } =20 static int vduse_dev_reg_umem(struct vduse_dev *dev, - u64 iova, u64 uaddr, u64 size) + u32 asid, u64 iova, u64 uaddr, u64 size) { struct page **page_list =3D NULL; struct vduse_umem *umem =3D NULL; @@ -1168,14 +1209,14 @@ static int vduse_dev_reg_umem(struct vduse_dev *dev, unsigned long npages, lock_limit; int ret; =20 - if (!dev->domain || !dev->domain->bounce_map || - size !=3D dev->domain->bounce_size || + if (!dev->as[asid].domain || !dev->as[asid].domain->bounce_map || + size !=3D dev->as[asid].domain->bounce_size || iova !=3D 0 || uaddr & ~PAGE_MASK) return -EINVAL; =20 - mutex_lock(&dev->mem_lock); + mutex_lock(&dev->as[asid].mem_lock); ret =3D -EEXIST; - if (dev->umem) + if (dev->as[asid].umem) goto unlock; =20 ret =3D -ENOMEM; @@ -1199,7 +1240,7 @@ static int vduse_dev_reg_umem(struct vduse_dev *dev, goto out; } =20 - ret =3D vduse_domain_add_user_bounce_pages(dev->domain, + ret =3D vduse_domain_add_user_bounce_pages(dev->as[asid].domain, page_list, pinned); if (ret) goto out; @@ -1212,7 +1253,7 @@ static int vduse_dev_reg_umem(struct vduse_dev *dev, umem->mm =3D current->mm; mmgrab(current->mm); =20 - dev->umem =3D umem; + dev->as[asid].umem =3D umem; out: if (ret && pinned > 0) unpin_user_pages(page_list, pinned); @@ -1223,7 +1264,7 @@ static int vduse_dev_reg_umem(struct vduse_dev *dev, vfree(page_list); kfree(umem); } - mutex_unlock(&dev->mem_lock); + mutex_unlock(&dev->as[asid].mem_lock); return ret; } =20 @@ -1244,44 +1285,47 @@ static void vduse_vq_update_effective_cpu(struct vd= use_virtqueue *vq) } =20 static int vduse_dev_iotlb_entry(struct vduse_dev *dev, - struct vduse_iotlb_entry *entry, + struct vduse_iotlb_entry_v2 *entry, struct file **f, uint64_t *capability) { + u32 asid; int r =3D -EINVAL; struct vhost_iotlb_map *map; =20 - if (entry->start > entry->last) + if (entry->v1.start > entry->v1.last || entry->asid >=3D dev->nas) return -EINVAL; =20 + asid =3D array_index_nospec(entry->asid, dev->nas); mutex_lock(&dev->domain_lock); - if (!dev->domain) + + if (!dev->as[asid].domain) goto out; =20 - spin_lock(&dev->domain->iotlb_lock); - map =3D vhost_iotlb_itree_first(dev->domain->iotlb, entry->start, - entry->last); + spin_lock(&dev->as[asid].domain->iotlb_lock); + map =3D vhost_iotlb_itree_first(dev->as[asid].domain->iotlb, + entry->v1.start, entry->v1.last); if (map) { if (f) { const struct vdpa_map_file *map_file; =20 map_file =3D (struct vdpa_map_file *)map->opaque; - entry->offset =3D map_file->offset; + entry->v1.offset =3D map_file->offset; *f =3D get_file(map_file->file); } - entry->start =3D map->start; - entry->last =3D map->last; - entry->perm =3D map->perm; + entry->v1.start =3D map->start; + entry->v1.last =3D map->last; + entry->v1.perm =3D map->perm; if (capability) { *capability =3D 0; =20 - if (dev->domain->bounce_map && map->start =3D=3D 0 && - map->last =3D=3D dev->domain->bounce_size - 1) + if (dev->as[asid].domain->bounce_map && map->start =3D=3D 0 && + map->last =3D=3D dev->as[asid].domain->bounce_size - 1) *capability |=3D VDUSE_IOVA_CAP_UMEM; } =20 r =3D 0; } - spin_unlock(&dev->domain->iotlb_lock); + spin_unlock(&dev->as[asid].domain->iotlb_lock); =20 out: mutex_unlock(&dev->domain_lock); @@ -1299,12 +1343,29 @@ static long vduse_dev_ioctl(struct file *file, unsi= gned int cmd, return -EPERM; =20 switch (cmd) { - case VDUSE_IOTLB_GET_FD: { - struct vduse_iotlb_entry entry; + case VDUSE_IOTLB_GET_FD: + case VDUSE_IOTLB_GET_FD2: { + struct vduse_iotlb_entry_v2 entry =3D {0}; struct file *f =3D NULL; =20 + ret =3D -ENOIOCTLCMD; + if (dev->api_version < VDUSE_API_VERSION_1 && + cmd =3D=3D VDUSE_IOTLB_GET_FD2) + break; + ret =3D -EFAULT; - if (copy_from_user(&entry, argp, sizeof(entry))) + if (cmd =3D=3D VDUSE_IOTLB_GET_FD2) { + if (copy_from_user(&entry, argp, sizeof(entry))) + break; + } else { + if (copy_from_user(&entry.v1, argp, + sizeof(entry.v1))) + break; + } + + ret =3D -EINVAL; + if (!is_mem_zero((const char *)entry.reserved, + sizeof(entry.reserved))) break; =20 ret =3D vduse_dev_iotlb_entry(dev, &entry, &f, NULL); @@ -1315,12 +1376,19 @@ static long vduse_dev_ioctl(struct file *file, unsi= gned int cmd, if (!f) break; =20 - ret =3D -EFAULT; - if (copy_to_user(argp, &entry, sizeof(entry))) { + if (cmd =3D=3D VDUSE_IOTLB_GET_FD2) + ret =3D copy_to_user(argp, &entry, + sizeof(entry)); + else + ret =3D copy_to_user(argp, &entry.v1, + sizeof(entry.v1)); + + if (ret) { + ret =3D -EFAULT; fput(f); break; } - ret =3D receive_fd(f, NULL, perm_to_file_flags(entry.perm)); + ret =3D receive_fd(f, NULL, perm_to_file_flags(entry.v1.perm)); fput(f); break; } @@ -1465,6 +1533,7 @@ static long vduse_dev_ioctl(struct file *file, unsign= ed int cmd, } case VDUSE_IOTLB_REG_UMEM: { struct vduse_iova_umem umem; + u32 asid; =20 ret =3D -EFAULT; if (copy_from_user(&umem, argp, sizeof(umem))) @@ -1472,17 +1541,21 @@ static long vduse_dev_ioctl(struct file *file, unsi= gned int cmd, =20 ret =3D -EINVAL; if (!is_mem_zero((const char *)umem.reserved, - sizeof(umem.reserved))) + sizeof(umem.reserved)) || + (dev->api_version < VDUSE_API_VERSION_1 && + umem.asid !=3D 0) || umem.asid >=3D dev->nas) break; =20 mutex_lock(&dev->domain_lock); - ret =3D vduse_dev_reg_umem(dev, umem.iova, + asid =3D array_index_nospec(umem.asid, dev->nas); + ret =3D vduse_dev_reg_umem(dev, asid, umem.iova, umem.uaddr, umem.size); mutex_unlock(&dev->domain_lock); break; } case VDUSE_IOTLB_DEREG_UMEM: { struct vduse_iova_umem umem; + u32 asid; =20 ret =3D -EFAULT; if (copy_from_user(&umem, argp, sizeof(umem))) @@ -1490,17 +1563,22 @@ static long vduse_dev_ioctl(struct file *file, unsi= gned int cmd, =20 ret =3D -EINVAL; if (!is_mem_zero((const char *)umem.reserved, - sizeof(umem.reserved))) + sizeof(umem.reserved)) || + (dev->api_version < VDUSE_API_VERSION_1 && + umem.asid !=3D 0) || + umem.asid >=3D dev->nas) break; + mutex_lock(&dev->domain_lock); - ret =3D vduse_dev_dereg_umem(dev, umem.iova, + asid =3D array_index_nospec(umem.asid, dev->nas); + ret =3D vduse_dev_dereg_umem(dev, asid, umem.iova, umem.size); mutex_unlock(&dev->domain_lock); break; } case VDUSE_IOTLB_GET_INFO: { struct vduse_iova_info info; - struct vduse_iotlb_entry entry; + struct vduse_iotlb_entry_v2 entry; =20 ret =3D -EFAULT; if (copy_from_user(&info, argp, sizeof(info))) @@ -1510,15 +1588,23 @@ static long vduse_dev_ioctl(struct file *file, unsi= gned int cmd, sizeof(info.reserved))) break; =20 - entry.start =3D info.start; - entry.last =3D info.last; + if (dev->api_version < VDUSE_API_VERSION_1) { + if (info.asid) + break; + } else if (info.asid >=3D dev->nas) + break; + + entry.v1.start =3D info.start; + entry.v1.last =3D info.last; + entry.asid =3D info.asid; ret =3D vduse_dev_iotlb_entry(dev, &entry, NULL, &info.capability); if (ret < 0) break; =20 - info.start =3D entry.start; - info.last =3D entry.last; + info.start =3D entry.v1.start; + info.last =3D entry.v1.last; + info.asid =3D entry.asid; =20 ret =3D -EFAULT; if (copy_to_user(argp, &info, sizeof(info))) @@ -1540,8 +1626,10 @@ static int vduse_dev_release(struct inode *inode, st= ruct file *file) struct vduse_dev *dev =3D file->private_data; =20 mutex_lock(&dev->domain_lock); - if (dev->domain) - vduse_dev_dereg_umem(dev, 0, dev->domain->bounce_size); + for (int i =3D 0; i < dev->nas; i++) + if (dev->as[i].domain) + vduse_dev_dereg_umem(dev, i, 0, + dev->as[i].domain->bounce_size); mutex_unlock(&dev->domain_lock); spin_lock(&dev->msg_lock); /* Make sure the inflight messages can processed after reconncection */ @@ -1760,7 +1848,6 @@ static struct vduse_dev *vduse_dev_create(void) return NULL; =20 mutex_init(&dev->lock); - mutex_init(&dev->mem_lock); mutex_init(&dev->domain_lock); spin_lock_init(&dev->msg_lock); INIT_LIST_HEAD(&dev->send_list); @@ -1811,8 +1898,11 @@ static int vduse_destroy_dev(char *name) idr_remove(&vduse_idr, dev->minor); kvfree(dev->config); vduse_dev_deinit_vqs(dev); - if (dev->domain) - vduse_domain_destroy(dev->domain); + for (int i =3D 0; i < dev->nas; i++) { + if (dev->as[i].domain) + vduse_domain_destroy(dev->as[i].domain); + } + kfree(dev->as); kfree(dev->name); kfree(dev->groups); vduse_dev_destroy(dev); @@ -1859,12 +1949,17 @@ static bool vduse_validate_config(struct vduse_dev_= config *config, sizeof(config->reserved))) return false; =20 - if (api_version < VDUSE_API_VERSION_1 && config->ngroups) + if (api_version < VDUSE_API_VERSION_1 && + (config->ngroups || config->nas)) return false; =20 - if (api_version >=3D VDUSE_API_VERSION_1 && - (!config->ngroups || config->ngroups > VDUSE_DEV_MAX_GROUPS)) - return false; + if (api_version >=3D VDUSE_API_VERSION_1) { + if (!config->ngroups || config->ngroups > VDUSE_DEV_MAX_GROUPS) + return false; + + if (!config->nas || config->nas > VDUSE_DEV_MAX_AS) + return false; + } =20 if (config->vq_align > PAGE_SIZE) return false; @@ -1929,7 +2024,8 @@ static ssize_t bounce_size_store(struct device *devic= e, =20 ret =3D -EPERM; mutex_lock(&dev->domain_lock); - if (dev->domain) + /* Assuming that if the first domain is allocated, all are allocated */ + if (dev->as[0].domain) goto unlock; =20 ret =3D kstrtouint(buf, 10, &bounce_size); @@ -1981,6 +2077,14 @@ static int vduse_create_dev(struct vduse_dev_config = *config, dev->device_features =3D config->features; dev->device_id =3D config->device_id; dev->vendor_id =3D config->vendor_id; + + dev->nas =3D (dev->api_version < VDUSE_API_VERSION_1) ? 1 : config->nas; + dev->as =3D kcalloc(dev->nas, sizeof(dev->as[0]), GFP_KERNEL); + if (!dev->as) + goto err_as; + for (int i =3D 0; i < dev->nas; i++) + mutex_init(&dev->as[i].mem_lock); + dev->ngroups =3D (dev->api_version < VDUSE_API_VERSION_1) ? 1 : config->ngroups; @@ -1988,8 +2092,11 @@ static int vduse_create_dev(struct vduse_dev_config = *config, GFP_KERNEL); if (!dev->groups) goto err_vq_groups; - for (u32 i =3D 0; i < dev->ngroups; ++i) + for (u32 i =3D 0; i < dev->ngroups; ++i) { dev->groups[i].dev =3D dev; + rwlock_init(&dev->groups[i].as_lock); + dev->groups[i].as =3D &dev->as[0]; + } =20 dev->name =3D kstrdup(config->name, GFP_KERNEL); if (!dev->name) @@ -2029,6 +2136,8 @@ static int vduse_create_dev(struct vduse_dev_config *= config, err_str: kfree(dev->groups); err_vq_groups: + kfree(dev->as); +err_as: vduse_dev_destroy(dev); err: return ret; @@ -2152,7 +2261,7 @@ static int vduse_dev_init_vdpa(struct vduse_dev *dev,= const char *name) =20 vdev =3D vdpa_alloc_device(struct vduse_vdpa, vdpa, dev->dev, &vduse_vdpa_config_ops, &vduse_map_ops, - dev->ngroups, 1, name, true); + dev->ngroups, dev->nas, name, true); if (IS_ERR(vdev)) return PTR_ERR(vdev); =20 @@ -2167,7 +2276,8 @@ static int vdpa_dev_add(struct vdpa_mgmt_dev *mdev, c= onst char *name, const struct vdpa_dev_set_config *config) { struct vduse_dev *dev; - int ret; + size_t domain_bounce_size; + int ret, i; =20 mutex_lock(&vduse_lock); dev =3D vduse_find_dev(name); @@ -2181,29 +2291,38 @@ static int vdpa_dev_add(struct vdpa_mgmt_dev *mdev,= const char *name, return ret; =20 mutex_lock(&dev->domain_lock); - if (!dev->domain) - dev->domain =3D vduse_domain_create(VDUSE_IOVA_SIZE - 1, - dev->bounce_size); - mutex_unlock(&dev->domain_lock); - if (!dev->domain) { - ret =3D -ENOMEM; - goto domain_err; + ret =3D 0; + + domain_bounce_size =3D dev->bounce_size / dev->nas; + for (i =3D 0; i < dev->nas; ++i) { + dev->as[i].domain =3D vduse_domain_create(VDUSE_IOVA_SIZE - 1, + domain_bounce_size); + if (!dev->as[i].domain) { + ret =3D -ENOMEM; + goto err; + } } =20 + mutex_unlock(&dev->domain_lock); + ret =3D _vdpa_register_device(&dev->vdev->vdpa, dev->vq_num); - if (ret) { - goto register_err; - } + if (ret) + goto err_register; =20 return 0; =20 -register_err: +err_register: mutex_lock(&dev->domain_lock); - vduse_domain_destroy(dev->domain); - dev->domain =3D NULL; + +err: + for (int j =3D 0; j < i; j++) { + if (dev->as[j].domain) { + vduse_domain_destroy(dev->as[j].domain); + dev->as[j].domain =3D NULL; + } + } mutex_unlock(&dev->domain_lock); =20 -domain_err: put_device(&dev->vdev->vdpa.dev); =20 return ret; diff --git a/include/uapi/linux/vduse.h b/include/uapi/linux/vduse.h index a3d51cf6df3a..68b4287f9fac 100644 --- a/include/uapi/linux/vduse.h +++ b/include/uapi/linux/vduse.h @@ -32,6 +32,7 @@ * @vq_num: the number of virtqueues * @vq_align: the allocation alignment of virtqueue's metadata * @ngroups: number of vq groups that VDUSE device declares + * @nas: number of address spaces that VDUSE device declares * @reserved: for future use, needs to be initialized to zero * @config_size: the size of the configuration space * @config: the buffer of the configuration space @@ -47,7 +48,8 @@ struct vduse_dev_config { __u32 vq_num; __u32 vq_align; __u32 ngroups; /* if VDUSE_API_VERSION >=3D 1 */ - __u32 reserved[12]; + __u32 nas; /* if VDUSE_API_VERSION >=3D 1 */ + __u32 reserved[11]; __u32 config_size; __u8 config[]; }; @@ -166,6 +168,16 @@ struct vduse_vq_state_packed { __u16 last_used_idx; }; =20 +/** + * struct vduse_vq_group_asid - virtqueue group ASID + * @group: Index of the virtqueue group + * @asid: Address space ID of the group + */ +struct vduse_vq_group_asid { + __u32 group; + __u32 asid; +}; + /** * struct vduse_vq_info - information of a virtqueue * @index: virtqueue index @@ -225,6 +237,7 @@ struct vduse_vq_eventfd { * @uaddr: start address of userspace memory, it must be aligned to page s= ize * @iova: start of the IOVA region * @size: size of the IOVA region + * @asid: Address space ID of the IOVA region * @reserved: for future use, needs to be initialized to zero * * Structure used by VDUSE_IOTLB_REG_UMEM and VDUSE_IOTLB_DEREG_UMEM @@ -234,7 +247,8 @@ struct vduse_iova_umem { __u64 uaddr; __u64 iova; __u64 size; - __u64 reserved[3]; + __u32 asid; + __u32 reserved[5]; }; =20 /* Register userspace memory for IOVA regions */ @@ -248,6 +262,7 @@ struct vduse_iova_umem { * @start: start of the IOVA region * @last: last of the IOVA region * @capability: capability of the IOVA region + * @asid: Address space ID of the IOVA region, only if device API version = >=3D 1 * @reserved: for future use, needs to be initialized to zero * * Structure used by VDUSE_IOTLB_GET_INFO ioctl to get information of @@ -258,7 +273,8 @@ struct vduse_iova_info { __u64 last; #define VDUSE_IOVA_CAP_UMEM (1 << 0) __u64 capability; - __u64 reserved[3]; + __u32 asid; /* Only if device API version >=3D 1 */ + __u32 reserved[5]; }; =20 /* @@ -267,6 +283,28 @@ struct vduse_iova_info { */ #define VDUSE_IOTLB_GET_INFO _IOWR(VDUSE_BASE, 0x1a, struct vduse_iova_inf= o) =20 +/** + * struct vduse_iotlb_entry_v2 - entry of IOTLB to describe one IOVA region + * + * @v1: the original vduse_iotlb_entry + * @asid: address space ID of the IOVA region + * @reserved: for future use, needs to be initialized to zero + * + * Structure used by VDUSE_IOTLB_GET_FD2 ioctl to find an overlapped IOVA = region. + */ +struct vduse_iotlb_entry_v2 { + struct vduse_iotlb_entry v1; + __u32 asid; + __u32 reserved[12]; +}; + +/* + * Same as VDUSE_IOTLB_GET_FD but with vduse_iotlb_entry_v2 argument that + * support extra fields. + */ +#define VDUSE_IOTLB_GET_FD2 _IOWR(VDUSE_BASE, 0x1b, struct vduse_iotlb_ent= ry_v2) + + /* The control messages definition for read(2)/write(2) on /dev/vduse/$NAM= E */ =20 /** @@ -275,11 +313,14 @@ struct vduse_iova_info { * @VDUSE_SET_STATUS: set the device status * @VDUSE_UPDATE_IOTLB: Notify userspace to update the memory mapping for * specified IOVA range via VDUSE_IOTLB_GET_FD ioctl + * @VDUSE_SET_VQ_GROUP_ASID: Notify userspace to update the address space = of a + * virtqueue group. */ enum vduse_req_type { VDUSE_GET_VQ_STATE, VDUSE_SET_STATUS, VDUSE_UPDATE_IOTLB, + VDUSE_SET_VQ_GROUP_ASID, }; =20 /** @@ -314,6 +355,18 @@ struct vduse_iova_range { __u64 last; }; =20 +/** + * struct vduse_iova_range_v2 - IOVA range [start, last] if API_VERSION >= =3D 1 + * @start: start of the IOVA range + * @last: last of the IOVA range + * @asid: address space ID of the IOVA range + */ +struct vduse_iova_range_v2 { + __u64 start; + __u64 last; + __u32 asid; +}; + /** * struct vduse_dev_request - control request * @type: request type @@ -322,6 +375,8 @@ struct vduse_iova_range { * @vq_state: virtqueue state, only index field is available * @s: device status * @iova: IOVA range for updating + * @iova_v2: IOVA range for updating if API_VERSION >=3D 1 + * @vq_group_asid: ASID of a virtqueue group * @padding: padding * * Structure used by read(2) on /dev/vduse/$NAME. @@ -334,6 +389,11 @@ struct vduse_dev_request { struct vduse_vq_state vq_state; struct vduse_dev_status s; struct vduse_iova_range iova; + /* Following members but padding exist only if vduse api + * version >=3D 1 + */ + struct vduse_iova_range_v2 iova_v2; + struct vduse_vq_group_asid vq_group_asid; __u32 padding[32]; }; }; --=20 2.52.0 From nobody Sat Feb 7 08:44:20 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 427AB3644BE for ; Mon, 19 Jan 2026 14:34:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768833247; cv=none; b=p2ZTQYeyOHz9nakxZ0QCM3dzAxxAMLeMjoDpxNWBo5BdeirmrWyofYxJZnyIw5rCRMTg87ST3nRvpWIO+XWFsizXP2y15a0cfR41g6O8Omp8KPempmnwzTmbJjAk05M3KDvDPkdYuVpdjrWMtlrYf85c34Nxm5RTIVPlJBp5Auo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768833247; c=relaxed/simple; bh=ZEwIUft5mx5CW/4ulfS862jC6CLgCDryKYDMnVaFu3o=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=rc8g++fwfVLWZ4/nIFRa7DyT1DwgPQZbRnj7TkZ6oUuTN7wD0ZOAa1+uGM9smSAXpkRTSRmMpy24sBJQNWKr0Tl/mJMSYmk3DDaVF/JQPzKp4mYYwooJWY/rv45QpYKV5nkWwxuz0sf8xtFTCoH7r5BLH3vh9PVRojpsCnLbeWE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=hb9ZhIZJ; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="hb9ZhIZJ" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1768833245; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=h3hDO6t8VeCQA0bPh+vN6I1ffVNFUX+xgA11LjWeZ9k=; b=hb9ZhIZJpRRZ4WH7mop4EhGbiB/wEMahuoXMnNJMEtdoT2Rt+hynvuRdGgtC2QvwrqW+/Y SHFLLq3nNszqWgC/3YHQdy9Md8zH2NMQTRwSujIVR+iZGNYinq8uiQcEjrD9McnuPaUtTs sr6UKpoXMcABzh/co5OfrzSJ1cyhInA= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-662-xDBZyirZNq6pB3SGyd9_XQ-1; Mon, 19 Jan 2026 09:34:02 -0500 X-MC-Unique: xDBZyirZNq6pB3SGyd9_XQ-1 X-Mimecast-MFC-AGG-ID: xDBZyirZNq6pB3SGyd9_XQ_1768833241 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 16949195605B; Mon, 19 Jan 2026 14:34:01 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.44.33.172]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id A5A271800240; Mon, 19 Jan 2026 14:33:57 +0000 (UTC) From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= To: "Michael S . Tsirkin " Cc: virtualization@lists.linux.dev, Yongji Xie , Xuan Zhuo , Maxime Coquelin , Stefano Garzarella , jasowang@redhat.com, =?UTF-8?q?Eugenio=20P=C3=A9rez?= , Laurent Vivier , Cindy Lu , linux-kernel@vger.kernel.org Subject: [PATCH v15 12/13] vduse: bump version number Date: Mon, 19 Jan 2026 15:33:05 +0100 Message-ID: <20260119143306.1818855-13-eperezma@redhat.com> In-Reply-To: <20260119143306.1818855-1-eperezma@redhat.com> References: <20260119143306.1818855-1-eperezma@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 Finalize the series by advertising VDUSE API v1 support to userspace. Now that all required infrastructure for v1 (ASIDs, VQ groups, update_iotlb_v2) is in place, VDUSE devices can opt in to the new features. Assume API version 0 if the VDUSE instance does not call VDUSE_GET_API_VERSION to maintain compatibility. Acked-by: Jason Wang Signed-off-by: Eugenio P=C3=A9rez --- v12: * Assume API version 0 by default if the VDUSE instance does not ask (Jason). --- drivers/vdpa/vdpa_user/vduse_dev.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/vdpa/vdpa_user/vduse_dev.c b/drivers/vdpa/vdpa_user/vd= use_dev.c index 2727c0c26003..73d1d517dc6c 100644 --- a/drivers/vdpa/vdpa_user/vduse_dev.c +++ b/drivers/vdpa/vdpa_user/vduse_dev.c @@ -52,6 +52,15 @@ =20 #define IRQ_UNBOUND -1 =20 +/* + * VDUSE instance have not asked the vduse API version, so assume 0. + * + * Old devices may not ask for the device version and assume it is 0. Keep + * this value for these. From the moment the VDUSE instance ask for the + * version, convert to the latests supported one and continue regular flow + */ +#define VDUSE_API_VERSION_NOT_ASKED U64_MAX + struct vduse_virtqueue { u16 index; u16 num_max; @@ -2153,6 +2162,8 @@ static long vduse_ioctl(struct file *file, unsigned i= nt cmd, mutex_lock(&vduse_lock); switch (cmd) { case VDUSE_GET_API_VERSION: + if (control->api_version =3D=3D VDUSE_API_VERSION_NOT_ASKED) + control->api_version =3D VDUSE_API_VERSION_1; ret =3D put_user(control->api_version, (u64 __user *)argp); break; case VDUSE_SET_API_VERSION: { @@ -2163,7 +2174,7 @@ static long vduse_ioctl(struct file *file, unsigned i= nt cmd, break; =20 ret =3D -EINVAL; - if (api_version > VDUSE_API_VERSION) + if (api_version > VDUSE_API_VERSION_1) break; =20 ret =3D 0; @@ -2180,6 +2191,8 @@ static long vduse_ioctl(struct file *file, unsigned i= nt cmd, break; =20 ret =3D -EINVAL; + if (control->api_version =3D=3D VDUSE_API_VERSION_NOT_ASKED) + control->api_version =3D VDUSE_API_VERSION; if (!vduse_validate_config(&config, control->api_version)) break; =20 @@ -2230,7 +2243,7 @@ static int vduse_open(struct inode *inode, struct fil= e *file) if (!control) return -ENOMEM; =20 - control->api_version =3D VDUSE_API_VERSION; + control->api_version =3D VDUSE_API_VERSION_NOT_ASKED; file->private_data =3D control; =20 return 0; --=20 2.52.0 From nobody Sat Feb 7 08:44:20 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 84B673803CB for ; Mon, 19 Jan 2026 14:34:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768833252; cv=none; b=GB8yMd0rJK1pe7drypyzQEtLyPrP7yEFJ+Tig5EVhKiN7ZnR8x+8gH1BzLW/DY8YGjlC73ZZaoT2i3PznG3/nse6uXsAhbH7DJkhNbj6v3FZgfjY8AnleCosooc2/yMMHbZnKV9gf5wQF6CG2uIcEvXrsDjr3bClhXCwbeqA5vk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768833252; c=relaxed/simple; bh=NGjKeFkyq5Uv2V+Ni6SJXTtK6+OYA6I44gdWE4xJQEM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=URIcmWgknv17Gw/ePodGXCNUvQQaQ3dD3zS7Y5wFSgahaOtSeSr+YoRbLEuAz8PFL34O/7o2dvW2Z9Bszgc168wJ2uMfWTVHwr0PXlg53IWaqXYzp3GzpnYppHFl9J1Z9ZPm13oELU4BsgKKYDjw0Y0QYhkN0nVK3alK/tdm4lk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=Mqp8GNEl; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="Mqp8GNEl" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1768833249; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=eO8a1JRlFjaf2mdpm87e4EhF46DWNQB8lolOsRlRRHs=; b=Mqp8GNElsWtoo0zn5/OivAwOJQ/od60WH5i5LMN0IElP9DbEECBHx/vQ2SrAl/bZuLeDnX Cji8Y8l5hjyDTNYqPukQYarOhkjhjRz+GwMVA9h4DB+KjJpF5WXsM9ouuGrlzJlItFgDs0 8Wj8QvlcXooz90fXpcf8O3gUTAsNFic= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-91-OQHaO85gMvS0LD_e-uoRKA-1; Mon, 19 Jan 2026 09:34:06 -0500 X-MC-Unique: OQHaO85gMvS0LD_e-uoRKA-1 X-Mimecast-MFC-AGG-ID: OQHaO85gMvS0LD_e-uoRKA_1768833245 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 1426A18005B4; Mon, 19 Jan 2026 14:34:05 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.44.33.172]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 91BE5180066A; Mon, 19 Jan 2026 14:34:01 +0000 (UTC) From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= To: "Michael S . Tsirkin " Cc: virtualization@lists.linux.dev, Yongji Xie , Xuan Zhuo , Maxime Coquelin , Stefano Garzarella , jasowang@redhat.com, =?UTF-8?q?Eugenio=20P=C3=A9rez?= , Laurent Vivier , Cindy Lu , linux-kernel@vger.kernel.org Subject: [PATCH v15 13/13] Documentation: Add documentation for VDUSE Address Space IDs Date: Mon, 19 Jan 2026 15:33:06 +0100 Message-ID: <20260119143306.1818855-14-eperezma@redhat.com> In-Reply-To: <20260119143306.1818855-1-eperezma@redhat.com> References: <20260119143306.1818855-1-eperezma@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 Address Space IDs allows the VDUSE framework to support devices able to expose different virtqueues to different part of the drivers. For example, to let QEMU handle the net device control virtqueue, so QEMU always knows the state of the device like mac address or number of queues enabled, while leaving the dataplane passthrough to the guest intact. This enables live migration. Expands the VDUSE documentation to explain how to use the new ioctls or the new struct members of old ioctls. Acked-by: Jason Wang Signed-off-by: Eugenio P=C3=A9rez --- v15: * Fix doc typo (Alok). v13: * Fix s/VDUSE_IOTLB_GET_INFO/VDUSE_VQ_SETUP/. * Document VDUSE_SET_VQ_GROUP_ASID VDUSE message (Jason). * Fix typos (MST and Jason). v12: New in V12. Requested by Jason. --- Documentation/userspace-api/vduse.rst | 53 +++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/Documentation/userspace-api/vduse.rst b/Documentation/userspac= e-api/vduse.rst index bdb880e01132..81479d47c8b9 100644 --- a/Documentation/userspace-api/vduse.rst +++ b/Documentation/userspace-api/vduse.rst @@ -230,4 +230,57 @@ able to start the dataplane processing as follows: 5. Inject an interrupt for specific virtqueue with the VDUSE_INJECT_VQ_IRQ= ioctl after the used ring is filled. =20 +Enabling ASID (API version 1) +------------------------------ + +VDUSE supports per-address-space identifiers (ASIDs) starting with API +version 1. Set it up with ioctl(VDUSE_SET_API_VERSION) on `/dev/vduse/cont= rol` +and pass `VDUSE_API_VERSION_1` before creating a new VDUSE instance with +ioctl(VDUSE_CREATE_DEV). + +Afterwards, you can use the member asid of ioctl(VDUSE_VQ_SETUP) argument = to +select the address space of the IOTLB you are querying. The driver could +change the address space of any virtqueue group by using the +VDUSE_SET_VQ_GROUP_ASID VDUSE message type, and the VDUSE instance needs to +reply with VDUSE_REQ_RESULT_OK if it was possible to change it. + +Similarly, you can use ioctl(VDUSE_IOTLB_GET_FD2) to obtain the file descr= iptor +describing an IOVA region of a specific ASID. Example usage: + +.. code-block:: c + + static void *iova_to_va(int dev_fd, uint32_t asid, uint64_t iova, + uint64_t *len) + { + int fd; + void *addr; + size_t size; + struct vduse_iotlb_entry_v2 entry =3D { 0 }; + + entry.v1.start =3D iova; + entry.v1.last =3D iova; + entry.asid =3D asid; + + fd =3D ioctl(dev_fd, VDUSE_IOTLB_GET_FD2, &entry); + if (fd < 0) + return NULL; + + size =3D entry.v1.last - entry.v1.start + 1; + *len =3D entry.v1.last - iova + 1; + addr =3D mmap(0, size, perm_to_prot(entry.v1.perm), MAP_SHARED, + fd, entry.v1.offset); + close(fd); + if (addr =3D=3D MAP_FAILED) + return NULL; + + /* + * Using some data structures such as linked list to store + * the iotlb mapping. The munmap(2) should be called for the + * cached mapping when the corresponding VDUSE_UPDATE_IOTLB + * message is received or the device is reset. + */ + + return addr + iova - entry.v1.start; + } + For more details on the uAPI, please see include/uapi/linux/vduse.h. --=20 2.52.0