[v16,2/3] vfio/pci: implement range_intesect_range to determine range overlap

Message ID 20240115211516.635852-3-ankita@nvidia.com
State New
Headers
Series vfio/nvgrace-gpu: Add vfio pci variant module for grace hopper |

Commit Message

Ankit Agrawal Jan. 15, 2024, 9:15 p.m. UTC
  From: Ankit Agrawal <ankita@nvidia.com>

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@nvidia.com

Signed-off-by: Ankit Agrawal <ankita@nvidia.com>
Tested-by: Ankit Agrawal <ankita@nvidia.com>
---
 drivers/vfio/pci/vfio_pci_config.c | 28 ++++++++++++++++++++++++++++
 include/linux/vfio_pci_core.h      |  6 ++++++
 2 files changed, 34 insertions(+)
  

Comments

Rahul Rameshbabu Jan. 16, 2024, 5:19 a.m. UTC | #1
On Mon, 15 Jan, 2024 21:15:15 +0000 <ankita@nvidia.com> wrote:
> From: Ankit Agrawal <ankita@nvidia.com>
>
> 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@nvidia.com
>
> Signed-off-by: Ankit Agrawal <ankita@nvidia.com>
> Tested-by: Ankit Agrawal <ankita@nvidia.com>
> ---
>  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);

If this function is being exported, shouldn't the function name follow
the pattern of having the vfio_pci_core_* prefix like the rest of the
symbols exported in this file. Something like
vfio_pci_core_range_intersect_range?

--
Thanks,

Rahul Rameshbabu
  
Ankit Agrawal Jan. 16, 2024, 5:58 a.m. UTC | #2
>> +}
>> +EXPORT_SYMBOL_GPL(range_intersect_range);
>
> If this function is being exported, shouldn't the function name follow
> the pattern of having the vfio_pci_core_* prefix like the rest of the
> symbols exported in this file. Something like
> vfio_pci_core_range_intersect_range?

Yes, that would be apt. Will make the change.
  
Alex Williamson Jan. 17, 2024, 9:34 p.m. UTC | #3
On Mon, 15 Jan 2024 21:15:15 +0000
<ankita@nvidia.com> wrote:

> From: Ankit Agrawal <ankita@nvidia.com>
> 
> 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@nvidia.com

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@nvidia.com>
> Tested-by: Ankit Agrawal <ankita@nvidia.com>
> ---
>  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 */
  
Ankit Agrawal Jan. 19, 2024, 3:34 a.m. UTC | #4
>> 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@nvidia.com
>
> 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.

Thanks for pointing that out. I'll rebase it with v6.8-rc1.

> 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,

Ack.
  

Patch

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 */