Skip to content

Commit d414b83

Browse files
misalehjoergroedel
authored andcommitted
mm/page_ext: Add page_ext_get_from_phys()
The IOMMU code operates on physical addresses which can be outside of system RAM. Add a new function page_ext_get_from_phys() to abstract the logic of checking the address and returning the page_ext. Signed-off-by: Mostafa Saleh <smostafa@google.com> Acked-by: Vlastimil Babka <vbabka@suse.cz> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
1 parent 2e2f6b0 commit d414b83

2 files changed

Lines changed: 29 additions & 0 deletions

File tree

include/linux/page_ext.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ static inline bool page_ext_iter_next_fast_possible(unsigned long next_pfn)
9393
#endif
9494

9595
extern struct page_ext *page_ext_get(const struct page *page);
96+
extern struct page_ext *page_ext_from_phys(phys_addr_t phys);
9697
extern void page_ext_put(struct page_ext *page_ext);
9798
extern struct page_ext *page_ext_lookup(unsigned long pfn);
9899

@@ -215,6 +216,11 @@ static inline struct page_ext *page_ext_get(const struct page *page)
215216
return NULL;
216217
}
217218

219+
static inline struct page_ext *page_ext_from_phys(phys_addr_t phys)
220+
{
221+
return NULL;
222+
}
223+
218224
static inline void page_ext_put(struct page_ext *page_ext)
219225
{
220226
}

mm/page_ext.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,29 @@ struct page_ext *page_ext_get(const struct page *page)
538538
return page_ext;
539539
}
540540

541+
/**
542+
* page_ext_from_phys() - Get the page_ext structure for a physical address.
543+
* @phys: The physical address to query.
544+
*
545+
* This function safely gets the `struct page_ext` associated with a given
546+
* physical address. It performs validation to ensure the address corresponds
547+
* to a valid, online struct page before attempting to access it.
548+
* It returns NULL for MMIO, ZONE_DEVICE, holes and offline memory.
549+
*
550+
* Return: NULL if no page_ext exists for this physical address.
551+
* Context: Any context. Caller may not sleep until they have called
552+
* page_ext_put().
553+
*/
554+
struct page_ext *page_ext_from_phys(phys_addr_t phys)
555+
{
556+
struct page *page = pfn_to_online_page(__phys_to_pfn(phys));
557+
558+
if (!page)
559+
return NULL;
560+
561+
return page_ext_get(page);
562+
}
563+
541564
/**
542565
* page_ext_put() - Working with page extended information is done.
543566
* @page_ext: Page extended information received from page_ext_get().

0 commit comments

Comments
 (0)