From nobody Wed Oct 1 23:32:05 2025 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 4BAEB2DE717 for ; Fri, 26 Sep 2025 10:15:04 +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=1758881706; cv=none; b=K1T+0a7uvx7/P2h6jVIFtqr3z+yekayd+n8JzByAO3um5uEMbtpaZx1qwastWQscs+kNxCLbuhHxgtqQBNZohl5yux8qMZr/Hjui5MtKEXRtSo8h/IkOhOXJAKYgzkbzQgqAhUJp0CS/tzegRMzLLWHuF5PGl4b0VAsroDaxo7g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758881706; c=relaxed/simple; bh=sAg5bTcRpQnHUvvVSOQQzyojRnn6uK9ni9FHWT3kybQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=qosO+JO1GATjKZkw1lrjhh3bcS2AwU2ADY29Rz7J+f/H9XVx/JOdRQzw0rhpuIGTSkPe0aCj30GdUbc1J596sge37KmXHeDqpEn0NLSU05B9KgFyUDuA4KHexap4BxPbnhwuNwfpUoKuCdt+ZuqpqTT19+VmfEefLCY8697C/1M= 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=ZlgkKxRE; 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="ZlgkKxRE" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1758881702; 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=mX7LtGzBlNBJeAw6lUtq55BskT/Sz/qvUIrYc02PHmk=; b=ZlgkKxRERCUROu/YGvkZOAX6jUzewWvItV5by7kpYjpknTQCEkEK9tsGMN8sbezVdoZggL RGDPrl0UVqzKQw+NFHm1Ib4xkbUtVzRWrni0Fm7IOmPTpFl8s2cm0pS99sOHRzSR7DzVUg JlMqQawiuyj0311/QNyI5AEG3e9VxUU= 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-284-Kl2aDCKvPLulq0YQpX3I4w-1; Fri, 26 Sep 2025 06:14:58 -0400 X-MC-Unique: Kl2aDCKvPLulq0YQpX3I4w-1 X-Mimecast-MFC-AGG-ID: Kl2aDCKvPLulq0YQpX3I4w_1758881696 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (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 98427180057E; Fri, 26 Sep 2025 10:14:56 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.44.32.141]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id D048319540EB; Fri, 26 Sep 2025 10:14:52 +0000 (UTC) From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= To: "Michael S . Tsirkin " Cc: Yongji Xie , linux-kernel@vger.kernel.org, Maxime Coquelin , =?UTF-8?q?Eugenio=20P=C3=A9rez?= , Stefano Garzarella , Xuan Zhuo , Cindy Lu , virtualization@lists.linux.dev, Laurent Vivier , jasowang@redhat.com Subject: [PATCH v5 4/6] vduse: return internal vq group struct as map token Date: Fri, 26 Sep 2025 12:14:30 +0200 Message-ID: <20250926101432.2251301-5-eperezma@redhat.com> In-Reply-To: <20250926101432.2251301-1-eperezma@redhat.com> References: <20250926101432.2251301-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.0 on 10.30.177.17 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 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 99e37def7a83..3ce70e6524d5 100644 --- a/drivers/vdpa/vdpa_user/vduse_dev.c +++ b/drivers/vdpa/vdpa_user/vduse_dev.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -86,6 +87,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; @@ -119,6 +124,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; rwlock_t domain_lock; @@ -607,6 +613,17 @@ static u32 vduse_get_vq_group(struct vdpa_device *vdpa= , u16 idx) return dev->vqs[idx]->vq_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) { @@ -827,6 +844,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 @@ -834,7 +852,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); } @@ -843,7 +868,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); } @@ -853,7 +885,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); } @@ -862,7 +901,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); } @@ -870,11 +916,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) @@ -889,14 +941,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; } @@ -910,7 +976,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; } @@ -1728,6 +1801,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->device_id =3D config->device_id; dev->vendor_id =3D config->vendor_id; dev->ngroups =3D (dev->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 96c66126c074..302109029700 100644 --- a/include/linux/virtio.h +++ b/include/linux/virtio.h @@ -41,13 +41,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.51.0