Linux IOMMU Development
 help / color / mirror / Atom feed
* [PATCH] iommufd: Fix offset handling in folio subroutines
@ 2025-04-02  1:44 Alexey Kardashevskiy
  2025-04-07  5:12 ` Tian, Kevin
  0 siblings, 1 reply; 3+ messages in thread
From: Alexey Kardashevskiy @ 2025-04-02  1:44 UTC (permalink / raw)
  To: iommu
  Cc: Jason Gunthorpe, Kevin Tian, Joerg Roedel, Will Deacon,
	Robin Murphy, Steve Sistare, Alexey Kardashevskiy

The @offset from memfd_pin_folios() is pgoff_t and is bytes, not
a number of pages as batch_from_folios() treats it.

Convert byte offset to pfn offset and use that.

Fixes: ed9178fbfd4e ("iommufd: Folio subroutines")
Signed-off-by: Alexey Kardashevskiy <aik@amd.com>
---

Found this when tried mapping a bunch of folios (>64) with an offset and
the first folio was used for all the mappings in the batch.

---
 drivers/iommu/iommufd/pages.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/iommufd/pages.c b/drivers/iommu/iommufd/pages.c
index 3427749bc5ce..6075d11691a6 100644
--- a/drivers/iommu/iommufd/pages.c
+++ b/drivers/iommu/iommufd/pages.c
@@ -646,8 +646,9 @@ static int batch_from_folios(struct pfn_batch *batch, struct folio ***folios_p,
 
 	while (npages) {
 		struct folio *folio = *folios;
-		unsigned long nr = folio_nr_pages(folio) - offset;
-		unsigned long pfn = page_to_pfn(folio_page(folio, offset));
+		unsigned long offset_nr = offset >> PAGE_SHIFT;
+		unsigned long nr = folio_nr_pages(folio) - offset_nr;
+		unsigned long pfn = page_to_pfn(folio_page(folio, offset_nr));
 
 		nr = min(nr, npages);
 		npages -= nr;
-- 
2.47.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* RE: [PATCH] iommufd: Fix offset handling in folio subroutines
  2025-04-02  1:44 [PATCH] iommufd: Fix offset handling in folio subroutines Alexey Kardashevskiy
@ 2025-04-07  5:12 ` Tian, Kevin
  2025-04-07  6:53   ` Alexey Kardashevskiy
  0 siblings, 1 reply; 3+ messages in thread
From: Tian, Kevin @ 2025-04-07  5:12 UTC (permalink / raw)
  To: Alexey Kardashevskiy, iommu@lists.linux.dev
  Cc: Jason Gunthorpe, Joerg Roedel, Will Deacon, Robin Murphy,
	Steve Sistare

> From: Alexey Kardashevskiy <aik@amd.com>
> Sent: Wednesday, April 2, 2025 9:44 AM
> 
> The @offset from memfd_pin_folios() is pgoff_t and is bytes, not
> a number of pages as batch_from_folios() treats it.
> 
> Convert byte offset to pfn offset and use that.
> 
> Fixes: ed9178fbfd4e ("iommufd: Folio subroutines")
> Signed-off-by: Alexey Kardashevskiy <aik@amd.com>
> ---
> 
> Found this when tried mapping a bunch of folios (>64) with an offset and
> the first folio was used for all the mappings in the batch.
> 
> ---
>  drivers/iommu/iommufd/pages.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/iommu/iommufd/pages.c
> b/drivers/iommu/iommufd/pages.c
> index 3427749bc5ce..6075d11691a6 100644
> --- a/drivers/iommu/iommufd/pages.c
> +++ b/drivers/iommu/iommufd/pages.c
> @@ -646,8 +646,9 @@ static int batch_from_folios(struct pfn_batch *batch,
> struct folio ***folios_p,
> 
>  	while (npages) {
>  		struct folio *folio = *folios;
> -		unsigned long nr = folio_nr_pages(folio) - offset;
> -		unsigned long pfn = page_to_pfn(folio_page(folio, offset));
> +		unsigned long offset_nr = offset >> PAGE_SHIFT;
> +		unsigned long nr = folio_nr_pages(folio) - offset_nr;
> +		unsigned long pfn = page_to_pfn(folio_page(folio, offset_nr));

pin_memfd_pages():
	nfolios = memfd_pin_folios(user->file, start, end, user->ufolios,
				      nfolios, &offset);
	offset >>= PAGE_SHIFT;
	user->ufolios_next = user->ufolios;
	user->ufolios_offset = offset;

pfn_reader_fill_span():
	if (!user->file)
		batch_from_pages(&pfns->batch, user->upages + start_index,
				    npages);
	else
		rc = batch_from_folios(&pfns->batch, &user->ufolios_next,
					&user->ufolios_offset, npages); 

So the offset is already about a page number as batch_from_folios() expects.

> 
>  		nr = min(nr, npages);
>  		npages -= nr;
> --
> 2.47.1


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] iommufd: Fix offset handling in folio subroutines
  2025-04-07  5:12 ` Tian, Kevin
@ 2025-04-07  6:53   ` Alexey Kardashevskiy
  0 siblings, 0 replies; 3+ messages in thread
From: Alexey Kardashevskiy @ 2025-04-07  6:53 UTC (permalink / raw)
  To: Tian, Kevin, iommu@lists.linux.dev
  Cc: Jason Gunthorpe, Joerg Roedel, Will Deacon, Robin Murphy,
	Steve Sistare



On 7/4/25 15:12, Tian, Kevin wrote:
>> From: Alexey Kardashevskiy <aik@amd.com>
>> Sent: Wednesday, April 2, 2025 9:44 AM
>>
>> The @offset from memfd_pin_folios() is pgoff_t and is bytes, not
>> a number of pages as batch_from_folios() treats it.
>>
>> Convert byte offset to pfn offset and use that.
>>
>> Fixes: ed9178fbfd4e ("iommufd: Folio subroutines")
>> Signed-off-by: Alexey Kardashevskiy <aik@amd.com>
>> ---
>>
>> Found this when tried mapping a bunch of folios (>64) with an offset and
>> the first folio was used for all the mappings in the batch.
>>
>> ---
>>   drivers/iommu/iommufd/pages.c | 5 +++--
>>   1 file changed, 3 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/iommu/iommufd/pages.c
>> b/drivers/iommu/iommufd/pages.c
>> index 3427749bc5ce..6075d11691a6 100644
>> --- a/drivers/iommu/iommufd/pages.c
>> +++ b/drivers/iommu/iommufd/pages.c
>> @@ -646,8 +646,9 @@ static int batch_from_folios(struct pfn_batch *batch,
>> struct folio ***folios_p,
>>
>>   	while (npages) {
>>   		struct folio *folio = *folios;
>> -		unsigned long nr = folio_nr_pages(folio) - offset;
>> -		unsigned long pfn = page_to_pfn(folio_page(folio, offset));
>> +		unsigned long offset_nr = offset >> PAGE_SHIFT;
>> +		unsigned long nr = folio_nr_pages(folio) - offset_nr;
>> +		unsigned long pfn = page_to_pfn(folio_page(folio, offset_nr));
> 
> pin_memfd_pages():
> 	nfolios = memfd_pin_folios(user->file, start, end, user->ufolios,
> 				      nfolios, &offset);
> 	offset >>= PAGE_SHIFT;

Aaaaahhh missed that so there is a bug in my variant of 
memfd_pin_folios() for gmemfd and sorry for the noise. Thanks,


> 	user->ufolios_next = user->ufolios;
> 	user->ufolios_offset = offset;
> 
> pfn_reader_fill_span():
> 	if (!user->file)
> 		batch_from_pages(&pfns->batch, user->upages + start_index,
> 				    npages);
> 	else
> 		rc = batch_from_folios(&pfns->batch, &user->ufolios_next,
> 					&user->ufolios_offset, npages);
> 
> So the offset is already about a page number as batch_from_folios() expects.
> 
>>
>>   		nr = min(nr, npages);
>>   		npages -= nr;
>> --
>> 2.47.1
> 

-- 
Alexey


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2025-04-07  6:53 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-02  1:44 [PATCH] iommufd: Fix offset handling in folio subroutines Alexey Kardashevskiy
2025-04-07  5:12 ` Tian, Kevin
2025-04-07  6:53   ` Alexey Kardashevskiy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox