On Mon, 15 Jan 2024 21:15:15 +0000 <ankita@xxxxxxxxxx> wrote: > From: Ankit Agrawal <ankita@xxxxxxxxxx> > > Add a helper function to determine an overlap between two ranges. > If an overlap, the function returns the overlapping offset and size. > > The VFIO PCI variant driver emulates the PCI config space BAR offset > registers. These offset may be accessed for read/write with a variety > of lengths including sub-word sizes from sub-word offsets. The driver > makes use of this helper function to read/write the targeted part of > the emulated register. > > This is replicated from Yishai's work in > https://lore.kernel.org/all/20231207102820.74820-10-yishaih@xxxxxxxxxx The virtio-vfio-net changes have been accepted, so this will need to be rebased on the vfio next branch or v6.8-rc1 when Linus comes back online to process the pull request. The revised patch should consolidate so that virtio-vfio-pci also uses the new shared function. As noted by Rahul, the name should be updated to align with the vfio-pci-core namespace. Kerneldoc would also be a nice addition since this is a somewhat complicated helper. Thanks, Alex > Signed-off-by: Ankit Agrawal <ankita@xxxxxxxxxx> > Tested-by: Ankit Agrawal <ankita@xxxxxxxxxx> > --- > drivers/vfio/pci/vfio_pci_config.c | 28 ++++++++++++++++++++++++++++ > include/linux/vfio_pci_core.h | 6 ++++++ > 2 files changed, 34 insertions(+) > > diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci_config.c > index 7e2e62ab0869..b77c96fbc4b2 100644 > --- a/drivers/vfio/pci/vfio_pci_config.c > +++ b/drivers/vfio/pci/vfio_pci_config.c > @@ -1966,3 +1966,31 @@ ssize_t vfio_pci_config_rw(struct vfio_pci_core_device *vdev, char __user *buf, > > return done; > } > + > +bool range_intersect_range(loff_t range1_start, size_t count1, > + loff_t range2_start, size_t count2, > + loff_t *start_offset, > + size_t *intersect_count, > + size_t *register_offset) > +{ > + if (range1_start <= range2_start && > + range1_start + count1 > range2_start) { > + *start_offset = range2_start - range1_start; > + *intersect_count = min_t(size_t, count2, > + range1_start + count1 - range2_start); > + *register_offset = 0; > + return true; > + } > + > + if (range1_start > range2_start && > + range1_start < range2_start + count2) { > + *start_offset = 0; > + *intersect_count = min_t(size_t, count1, > + range2_start + count2 - range1_start); > + *register_offset = range1_start - range2_start; > + return true; > + } > + > + return false; > +} > +EXPORT_SYMBOL_GPL(range_intersect_range); > diff --git a/include/linux/vfio_pci_core.h b/include/linux/vfio_pci_core.h > index d478e6f1be02..8a11047ac6c9 100644 > --- a/include/linux/vfio_pci_core.h > +++ b/include/linux/vfio_pci_core.h > @@ -133,4 +133,10 @@ ssize_t vfio_pci_core_do_io_rw(struct vfio_pci_core_device *vdev, bool test_mem, > void __iomem *io, char __user *buf, > loff_t off, size_t count, size_t x_start, > size_t x_end, bool iswrite); > + > +bool range_intersect_range(loff_t range1_start, size_t count1, > + loff_t range2_start, size_t count2, > + loff_t *start_offset, > + size_t *intersect_count, > + size_t *register_offset); > #endif /* VFIO_PCI_CORE_H */