1 From 9ea8e954812efc4fc9b27e553019295d4dcd0407 Mon Sep 17 00:00:00 2001
2 From: Diana Craciun <diana.craciun@nxp.com>
3 Date: Tue, 15 Oct 2019 11:22:26 +0300
4 Subject: [PATCH] vfio/fsl-mc: Added lock support in preparation for interrupt
7 All the devices in a DPRC share the same pool of interrupts.
8 Because of this the access to the pool of interrupts must be
9 protected with a lock. Extend the current lock implementation
10 to have a lock per DPRC.
12 Signed-off-by: Diana Craciun <diana.craciun@nxp.com>
14 drivers/vfio/fsl-mc/vfio_fsl_mc.c | 90 ++++++++++++++++++++++++++++---
15 drivers/vfio/fsl-mc/vfio_fsl_mc_private.h | 7 ++-
16 2 files changed, 89 insertions(+), 8 deletions(-)
18 --- a/drivers/vfio/fsl-mc/vfio_fsl_mc.c
19 +++ b/drivers/vfio/fsl-mc/vfio_fsl_mc.c
22 #include "vfio_fsl_mc_private.h"
24 +static DEFINE_MUTEX(reflck_lock);
26 +static void vfio_fsl_mc_reflck_get(struct vfio_fsl_mc_reflck *reflck)
28 + kref_get(&reflck->kref);
31 +static void vfio_fsl_mc_reflck_release(struct kref *kref)
33 + struct vfio_fsl_mc_reflck *reflck = container_of(kref,
34 + struct vfio_fsl_mc_reflck,
38 + mutex_unlock(&reflck_lock);
41 +static void vfio_fsl_mc_reflck_put(struct vfio_fsl_mc_reflck *reflck)
43 + kref_put_mutex(&reflck->kref, vfio_fsl_mc_reflck_release, &reflck_lock);
46 +static struct vfio_fsl_mc_reflck *vfio_fsl_mc_reflck_alloc(void)
48 + struct vfio_fsl_mc_reflck *reflck;
50 + reflck = kzalloc(sizeof(*reflck), GFP_KERNEL);
52 + return ERR_PTR(-ENOMEM);
54 + kref_init(&reflck->kref);
55 + mutex_init(&reflck->lock);
60 +static int vfio_fsl_mc_reflck_attach(struct vfio_fsl_mc_device *vdev)
64 + mutex_lock(&reflck_lock);
65 + if (is_fsl_mc_bus_dprc(vdev->mc_dev)) {
66 + vdev->reflck = vfio_fsl_mc_reflck_alloc();
68 + struct device *mc_cont_dev = vdev->mc_dev->dev.parent;
69 + struct vfio_device *device;
70 + struct vfio_fsl_mc_device *cont_vdev;
72 + device = vfio_device_get_from_dev(mc_cont_dev);
78 + cont_vdev = vfio_device_data(device);
79 + if (!cont_vdev->reflck) {
80 + vfio_device_put(device);
84 + vfio_fsl_mc_reflck_get(cont_vdev->reflck);
85 + vdev->reflck = cont_vdev->reflck;
86 + vfio_device_put(device);
90 + mutex_unlock(&reflck_lock);
94 static int vfio_fsl_mc_regions_init(struct vfio_fsl_mc_device *vdev)
96 @@ -55,7 +124,7 @@ static int vfio_fsl_mc_open(void *device
97 if (!try_module_get(THIS_MODULE))
100 - mutex_lock(&vdev->driver_lock);
101 + mutex_lock(&vdev->reflck->lock);
103 ret = vfio_fsl_mc_regions_init(vdev);
105 @@ -63,11 +132,11 @@ static int vfio_fsl_mc_open(void *device
109 - mutex_unlock(&vdev->driver_lock);
110 + mutex_unlock(&vdev->reflck->lock);
114 - mutex_unlock(&vdev->driver_lock);
115 + mutex_unlock(&vdev->reflck->lock);
116 module_put(THIS_MODULE);
119 @@ -76,12 +145,12 @@ static void vfio_fsl_mc_release(void *de
121 struct vfio_fsl_mc_device *vdev = device_data;
123 - mutex_lock(&vdev->driver_lock);
124 + mutex_lock(&vdev->reflck->lock);
126 if (!(--vdev->refcnt))
127 vfio_fsl_mc_regions_cleanup(vdev);
129 - mutex_unlock(&vdev->driver_lock);
130 + mutex_unlock(&vdev->reflck->lock);
132 module_put(THIS_MODULE);
134 @@ -180,7 +249,6 @@ static int vfio_fsl_mc_mmap_mmio(struct
137 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
139 vma->vm_pgoff = (region.addr >> PAGE_SHIFT) + pgoff;
141 return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
142 @@ -335,12 +403,18 @@ static int vfio_fsl_mc_probe(struct fsl_
146 + ret = vfio_fsl_mc_reflck_attach(vdev);
148 + vfio_iommu_group_put(group, dev);
152 ret = vfio_fsl_mc_init_device(vdev);
154 + vfio_fsl_mc_reflck_put(vdev->reflck);
155 vfio_iommu_group_put(group, dev);
158 - mutex_init(&vdev->driver_lock);
162 @@ -374,6 +448,8 @@ static int vfio_fsl_mc_remove(struct fsl
166 + vfio_fsl_mc_reflck_put(vdev->reflck);
168 if (is_fsl_mc_bus_dprc(mc_dev))
169 vfio_fsl_mc_cleanup_dprc(vdev->mc_dev);
171 --- a/drivers/vfio/fsl-mc/vfio_fsl_mc_private.h
172 +++ b/drivers/vfio/fsl-mc/vfio_fsl_mc_private.h
174 #define VFIO_FSL_MC_INDEX_TO_OFFSET(index) \
175 ((u64)(index) << VFIO_FSL_MC_OFFSET_SHIFT)
177 +struct vfio_fsl_mc_reflck {
182 struct vfio_fsl_mc_region {
185 @@ -27,7 +32,7 @@ struct vfio_fsl_mc_device {
188 struct vfio_fsl_mc_region *regions;
189 - struct mutex driver_lock;
190 + struct vfio_fsl_mc_reflck *reflck;
193 #endif /* VFIO_PCI_PRIVATE_H */