Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

vduse: return internal vq group struct as map token

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 <jasowang@redhat.com>
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20260119143306.1818855-5-eperezma@redhat.com>

authored by

Eugenio Pérez and committed by
Michael S. Tsirkin
02e3f7ff 9350a09a

+94 -12
+91 -9
drivers/vdpa/vdpa_user/vduse_dev.c
··· 22 22 #include <linux/uio.h> 23 23 #include <linux/vdpa.h> 24 24 #include <linux/nospec.h> 25 + #include <linux/virtio.h> 25 26 #include <linux/vmalloc.h> 26 27 #include <linux/sched/mm.h> 27 28 #include <uapi/linux/vduse.h> ··· 86 85 struct mm_struct *mm; 87 86 }; 88 87 88 + struct vduse_vq_group { 89 + struct vduse_dev *dev; 90 + }; 91 + 89 92 struct vduse_dev { 90 93 struct vduse_vdpa *vdev; 91 94 struct device *dev; ··· 123 118 u32 vq_align; 124 119 u32 ngroups; 125 120 struct vduse_umem *umem; 121 + struct vduse_vq_group *groups; 126 122 struct mutex mem_lock; 127 123 unsigned int bounce_size; 128 124 struct mutex domain_lock; ··· 611 605 return dev->vqs[idx]->group; 612 606 } 613 607 608 + static union virtio_map vduse_get_vq_map(struct vdpa_device *vdpa, u16 idx) 609 + { 610 + struct vduse_dev *dev = vdpa_to_vduse(vdpa); 611 + u32 vq_group = vduse_get_vq_group(vdpa, idx); 612 + union virtio_map ret = { 613 + .group = &dev->groups[vq_group], 614 + }; 615 + 616 + return ret; 617 + } 618 + 614 619 static int vduse_vdpa_get_vq_state(struct vdpa_device *vdpa, u16 idx, 615 620 struct vdpa_vq_state *state) 616 621 { ··· 842 825 .get_vq_affinity = vduse_vdpa_get_vq_affinity, 843 826 .reset = vduse_vdpa_reset, 844 827 .set_map = vduse_vdpa_set_map, 828 + .get_vq_map = vduse_get_vq_map, 845 829 .free = vduse_vdpa_free, 846 830 }; 847 831 ··· 850 832 dma_addr_t dma_addr, size_t size, 851 833 enum dma_data_direction dir) 852 834 { 853 - struct vduse_iova_domain *domain = token.iova_domain; 835 + struct vduse_dev *vdev; 836 + struct vduse_iova_domain *domain; 837 + 838 + if (!token.group) 839 + return; 840 + 841 + vdev = token.group->dev; 842 + domain = vdev->domain; 854 843 855 844 vduse_domain_sync_single_for_device(domain, dma_addr, size, dir); 856 845 } ··· 866 841 dma_addr_t dma_addr, size_t size, 867 842 enum dma_data_direction dir) 868 843 { 869 - struct vduse_iova_domain *domain = token.iova_domain; 844 + struct vduse_dev *vdev; 845 + struct vduse_iova_domain *domain; 846 + 847 + if (!token.group) 848 + return; 849 + 850 + vdev = token.group->dev; 851 + domain = vdev->domain; 870 852 871 853 vduse_domain_sync_single_for_cpu(domain, dma_addr, size, dir); 872 854 } ··· 883 851 enum dma_data_direction dir, 884 852 unsigned long attrs) 885 853 { 886 - struct vduse_iova_domain *domain = token.iova_domain; 854 + struct vduse_dev *vdev; 855 + struct vduse_iova_domain *domain; 856 + 857 + if (!token.group) 858 + return DMA_MAPPING_ERROR; 859 + 860 + vdev = token.group->dev; 861 + domain = vdev->domain; 887 862 888 863 return vduse_domain_map_page(domain, page, offset, size, dir, attrs); 889 864 } ··· 899 860 size_t size, enum dma_data_direction dir, 900 861 unsigned long attrs) 901 862 { 902 - struct vduse_iova_domain *domain = token.iova_domain; 863 + struct vduse_dev *vdev; 864 + struct vduse_iova_domain *domain; 865 + 866 + if (!token.group) 867 + return; 868 + 869 + vdev = token.group->dev; 870 + domain = vdev->domain; 903 871 904 872 return vduse_domain_unmap_page(domain, dma_addr, size, dir, attrs); 905 873 } ··· 914 868 static void *vduse_dev_alloc_coherent(union virtio_map token, size_t size, 915 869 dma_addr_t *dma_addr, gfp_t flag) 916 870 { 917 - struct vduse_iova_domain *domain = token.iova_domain; 871 + struct vduse_dev *vdev; 872 + struct vduse_iova_domain *domain; 918 873 unsigned long iova; 919 874 void *addr; 920 875 921 876 *dma_addr = DMA_MAPPING_ERROR; 877 + if (!token.group) 878 + return NULL; 879 + 880 + vdev = token.group->dev; 881 + domain = vdev->domain; 922 882 addr = vduse_domain_alloc_coherent(domain, size, 923 883 (dma_addr_t *)&iova, flag); 924 884 if (!addr) ··· 939 887 void *vaddr, dma_addr_t dma_addr, 940 888 unsigned long attrs) 941 889 { 942 - struct vduse_iova_domain *domain = token.iova_domain; 890 + struct vduse_dev *vdev; 891 + struct vduse_iova_domain *domain; 892 + 893 + if (!token.group) 894 + return; 895 + 896 + vdev = token.group->dev; 897 + domain = vdev->domain; 943 898 944 899 vduse_domain_free_coherent(domain, size, vaddr, dma_addr, attrs); 945 900 } 946 901 947 902 static bool vduse_dev_need_sync(union virtio_map token, dma_addr_t dma_addr) 948 903 { 949 - struct vduse_iova_domain *domain = token.iova_domain; 904 + struct vduse_dev *vdev; 905 + struct vduse_iova_domain *domain; 906 + 907 + if (!token.group) 908 + return false; 909 + 910 + vdev = token.group->dev; 911 + domain = vdev->domain; 950 912 951 913 return dma_addr < domain->bounce_size; 952 914 } ··· 974 908 975 909 static size_t vduse_dev_max_mapping_size(union virtio_map token) 976 910 { 977 - struct vduse_iova_domain *domain = token.iova_domain; 911 + struct vduse_dev *vdev; 912 + struct vduse_iova_domain *domain; 913 + 914 + if (!token.group) 915 + return 0; 916 + 917 + vdev = token.group->dev; 918 + domain = vdev->domain; 978 919 979 920 return domain->bounce_size; 980 921 } ··· 1799 1726 if (dev->domain) 1800 1727 vduse_domain_destroy(dev->domain); 1801 1728 kfree(dev->name); 1729 + kfree(dev->groups); 1802 1730 vduse_dev_destroy(dev); 1803 1731 module_put(THIS_MODULE); 1804 1732 ··· 1969 1895 dev->ngroups = (dev->api_version < VDUSE_API_VERSION_1) 1970 1896 ? 1 1971 1897 : config->ngroups; 1898 + dev->groups = kcalloc(dev->ngroups, sizeof(dev->groups[0]), 1899 + GFP_KERNEL); 1900 + if (!dev->groups) 1901 + goto err_vq_groups; 1902 + for (u32 i = 0; i < dev->ngroups; ++i) 1903 + dev->groups[i].dev = dev; 1904 + 1972 1905 dev->name = kstrdup(config->name, GFP_KERNEL); 1973 1906 if (!dev->name) 1974 1907 goto err_str; ··· 2012 1931 err_idr: 2013 1932 kfree(dev->name); 2014 1933 err_str: 1934 + kfree(dev->groups); 1935 + err_vq_groups: 2015 1936 vduse_dev_destroy(dev); 2016 1937 err: 2017 1938 return ret; ··· 2175 2092 return -ENOMEM; 2176 2093 } 2177 2094 2178 - dev->vdev->vdpa.vmap.iova_domain = dev->domain; 2179 2095 ret = _vdpa_register_device(&dev->vdev->vdpa, dev->vq_num); 2180 2096 if (ret) { 2181 2097 put_device(&dev->vdev->vdpa.dev);
+3 -3
include/linux/virtio.h
··· 43 43 void *priv; 44 44 }; 45 45 46 - struct vduse_iova_domain; 46 + struct vduse_vq_group; 47 47 48 48 union virtio_map { 49 49 /* Device that performs DMA */ 50 50 struct device *dma_dev; 51 - /* VDUSE specific mapping data */ 52 - struct vduse_iova_domain *iova_domain; 51 + /* VDUSE specific virtqueue group for doing map */ 52 + struct vduse_vq_group *group; 53 53 }; 54 54 55 55 int virtqueue_add_outbuf(struct virtqueue *vq,