[RFC PATCH 1/6] mm/hmm: Add flag to track device private PFNs

Jordan Niethe posted 6 patches 3 days, 16 hours ago
[RFC PATCH 1/6] mm/hmm: Add flag to track device private PFNs
Posted by Jordan Niethe 3 days, 16 hours ago
A future change will remove device private pages from the physical
address space. This will mean that device private pages no longer have
normal PFN and must be handled separately.

Prepare for this by adding a HMM_PFN_DEVICE_PRIVATE flag to indicate
that a hmm_pfn contains a PFN for a device private page.

Signed-off-by: Jordan Niethe <jniethe@nvidia.com>
Signed-off-by: Alistair Popple <apopple@nvidia.com>
---
 include/linux/hmm.h | 2 ++
 mm/hmm.c            | 2 +-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/include/linux/hmm.h b/include/linux/hmm.h
index db75ffc949a7..df571fa75a44 100644
--- a/include/linux/hmm.h
+++ b/include/linux/hmm.h
@@ -23,6 +23,7 @@ struct mmu_interval_notifier;
  * HMM_PFN_WRITE - if the page memory can be written to (requires HMM_PFN_VALID)
  * HMM_PFN_ERROR - accessing the pfn is impossible and the device should
  *                 fail. ie poisoned memory, special pages, no vma, etc
+ * HMM_PFN_DEVICE_PRIVATE - the pfn field contains a DEVICE_PRIVATE pfn.
  * HMM_PFN_P2PDMA - P2P page
  * HMM_PFN_P2PDMA_BUS - Bus mapped P2P transfer
  * HMM_PFN_DMA_MAPPED - Flag preserved on input-to-output transformation
@@ -40,6 +41,7 @@ enum hmm_pfn_flags {
 	HMM_PFN_VALID = 1UL << (BITS_PER_LONG - 1),
 	HMM_PFN_WRITE = 1UL << (BITS_PER_LONG - 2),
 	HMM_PFN_ERROR = 1UL << (BITS_PER_LONG - 3),
+	HMM_PFN_DEVICE_PRIVATE = 1UL << (BITS_PER_LONG - 7),
 	/*
 	 * Sticky flags, carried from input to output,
 	 * don't forget to update HMM_PFN_INOUT_FLAGS
diff --git a/mm/hmm.c b/mm/hmm.c
index 87562914670a..1cff68ade1d4 100644
--- a/mm/hmm.c
+++ b/mm/hmm.c
@@ -262,7 +262,7 @@ static int hmm_vma_handle_pte(struct mm_walk *walk, unsigned long addr,
 		if (is_device_private_entry(entry) &&
 		    page_pgmap(pfn_swap_entry_to_page(entry))->owner ==
 		    range->dev_private_owner) {
-			cpu_flags = HMM_PFN_VALID;
+			cpu_flags = HMM_PFN_VALID | HMM_PFN_DEVICE_PRIVATE;
 			if (is_writable_device_private_entry(entry))
 				cpu_flags |= HMM_PFN_WRITE;
 			new_pfn_flags = swp_offset_pfn(entry) | cpu_flags;
-- 
2.34.1
Re: [RFC PATCH 1/6] mm/hmm: Add flag to track device private PFNs
Posted by Matthew Brost 3 days, 2 hours ago
On Fri, Nov 28, 2025 at 03:41:41PM +1100, Jordan Niethe wrote:
> A future change will remove device private pages from the physical
> address space. This will mean that device private pages no longer have
> normal PFN and must be handled separately.
> 
> Prepare for this by adding a HMM_PFN_DEVICE_PRIVATE flag to indicate
> that a hmm_pfn contains a PFN for a device private page.
> 
> Signed-off-by: Jordan Niethe <jniethe@nvidia.com>
> Signed-off-by: Alistair Popple <apopple@nvidia.com>
> ---
>  include/linux/hmm.h | 2 ++
>  mm/hmm.c            | 2 +-
>  2 files changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/include/linux/hmm.h b/include/linux/hmm.h
> index db75ffc949a7..df571fa75a44 100644
> --- a/include/linux/hmm.h
> +++ b/include/linux/hmm.h
> @@ -23,6 +23,7 @@ struct mmu_interval_notifier;
>   * HMM_PFN_WRITE - if the page memory can be written to (requires HMM_PFN_VALID)
>   * HMM_PFN_ERROR - accessing the pfn is impossible and the device should
>   *                 fail. ie poisoned memory, special pages, no vma, etc
> + * HMM_PFN_DEVICE_PRIVATE - the pfn field contains a DEVICE_PRIVATE pfn.
>   * HMM_PFN_P2PDMA - P2P page
>   * HMM_PFN_P2PDMA_BUS - Bus mapped P2P transfer
>   * HMM_PFN_DMA_MAPPED - Flag preserved on input-to-output transformation
> @@ -40,6 +41,7 @@ enum hmm_pfn_flags {
>  	HMM_PFN_VALID = 1UL << (BITS_PER_LONG - 1),
>  	HMM_PFN_WRITE = 1UL << (BITS_PER_LONG - 2),
>  	HMM_PFN_ERROR = 1UL << (BITS_PER_LONG - 3),
> +	HMM_PFN_DEVICE_PRIVATE = 1UL << (BITS_PER_LONG - 7),
>  	/*
>  	 * Sticky flags, carried from input to output,
>  	 * don't forget to update HMM_PFN_INOUT_FLAGS
> diff --git a/mm/hmm.c b/mm/hmm.c
> index 87562914670a..1cff68ade1d4 100644
> --- a/mm/hmm.c
> +++ b/mm/hmm.c
> @@ -262,7 +262,7 @@ static int hmm_vma_handle_pte(struct mm_walk *walk, unsigned long addr,
>  		if (is_device_private_entry(entry) &&
>  		    page_pgmap(pfn_swap_entry_to_page(entry))->owner ==
>  		    range->dev_private_owner) {
> -			cpu_flags = HMM_PFN_VALID;
> +			cpu_flags = HMM_PFN_VALID | HMM_PFN_DEVICE_PRIVATE;

I think you’ll need to set this flag in hmm_vma_handle_absent_pmd as
well. That function handles 2M device pages. Support for 2M device
pages, I believe, will be included in the 6.19 PR, but
hmm_vma_handle_absent_pmd is already upstream.

Matt

>  			if (is_writable_device_private_entry(entry))
>  				cpu_flags |= HMM_PFN_WRITE;
>  			new_pfn_flags = swp_offset_pfn(entry) | cpu_flags;
> -- 
> 2.34.1
>