at v4.8 104 lines 2.5 kB view raw
1#ifndef _LINUX_PFN_T_H_ 2#define _LINUX_PFN_T_H_ 3#include <linux/mm.h> 4 5/* 6 * PFN_FLAGS_MASK - mask of all the possible valid pfn_t flags 7 * PFN_SG_CHAIN - pfn is a pointer to the next scatterlist entry 8 * PFN_SG_LAST - pfn references a page and is the last scatterlist entry 9 * PFN_DEV - pfn is not covered by system memmap by default 10 * PFN_MAP - pfn has a dynamic page mapping established by a device driver 11 */ 12#define PFN_FLAGS_MASK (((u64) ~PAGE_MASK) << (BITS_PER_LONG_LONG - PAGE_SHIFT)) 13#define PFN_SG_CHAIN (1ULL << (BITS_PER_LONG_LONG - 1)) 14#define PFN_SG_LAST (1ULL << (BITS_PER_LONG_LONG - 2)) 15#define PFN_DEV (1ULL << (BITS_PER_LONG_LONG - 3)) 16#define PFN_MAP (1ULL << (BITS_PER_LONG_LONG - 4)) 17 18static inline pfn_t __pfn_to_pfn_t(unsigned long pfn, u64 flags) 19{ 20 pfn_t pfn_t = { .val = pfn | (flags & PFN_FLAGS_MASK), }; 21 22 return pfn_t; 23} 24 25/* a default pfn to pfn_t conversion assumes that @pfn is pfn_valid() */ 26static inline pfn_t pfn_to_pfn_t(unsigned long pfn) 27{ 28 return __pfn_to_pfn_t(pfn, 0); 29} 30 31static inline pfn_t phys_to_pfn_t(phys_addr_t addr, u64 flags) 32{ 33 return __pfn_to_pfn_t(addr >> PAGE_SHIFT, flags); 34} 35 36static inline bool pfn_t_has_page(pfn_t pfn) 37{ 38 return (pfn.val & PFN_MAP) == PFN_MAP || (pfn.val & PFN_DEV) == 0; 39} 40 41static inline unsigned long pfn_t_to_pfn(pfn_t pfn) 42{ 43 return pfn.val & ~PFN_FLAGS_MASK; 44} 45 46static inline struct page *pfn_t_to_page(pfn_t pfn) 47{ 48 if (pfn_t_has_page(pfn)) 49 return pfn_to_page(pfn_t_to_pfn(pfn)); 50 return NULL; 51} 52 53static inline phys_addr_t pfn_t_to_phys(pfn_t pfn) 54{ 55 return PFN_PHYS(pfn_t_to_pfn(pfn)); 56} 57 58static inline void *pfn_t_to_virt(pfn_t pfn) 59{ 60 if (pfn_t_has_page(pfn)) 61 return __va(pfn_t_to_phys(pfn)); 62 return NULL; 63} 64 65static inline pfn_t page_to_pfn_t(struct page *page) 66{ 67 return pfn_to_pfn_t(page_to_pfn(page)); 68} 69 70static inline int pfn_t_valid(pfn_t pfn) 71{ 72 return pfn_valid(pfn_t_to_pfn(pfn)); 73} 74 75#ifdef CONFIG_MMU 76static inline pte_t pfn_t_pte(pfn_t pfn, pgprot_t pgprot) 77{ 78 return pfn_pte(pfn_t_to_pfn(pfn), pgprot); 79} 80#endif 81 82#ifdef CONFIG_TRANSPARENT_HUGEPAGE 83static inline pmd_t pfn_t_pmd(pfn_t pfn, pgprot_t pgprot) 84{ 85 return pfn_pmd(pfn_t_to_pfn(pfn), pgprot); 86} 87#endif 88 89#ifdef __HAVE_ARCH_PTE_DEVMAP 90static inline bool pfn_t_devmap(pfn_t pfn) 91{ 92 const u64 flags = PFN_DEV|PFN_MAP; 93 94 return (pfn.val & flags) == flags; 95} 96#else 97static inline bool pfn_t_devmap(pfn_t pfn) 98{ 99 return false; 100} 101pte_t pte_mkdevmap(pte_t pte); 102pmd_t pmd_mkdevmap(pmd_t pmd); 103#endif 104#endif /* _LINUX_PFN_T_H_ */