LCOV - code coverage report
Current view: top level - include/linux - pfn_t.h (source / functions) Hit Total Coverage
Test: landlock.info Lines: 9 18 50.0 %
Date: 2021-04-22 12:43:58 Functions: 0 0 -

          Line data    Source code
       1             : /* SPDX-License-Identifier: GPL-2.0 */
       2             : #ifndef _LINUX_PFN_T_H_
       3             : #define _LINUX_PFN_T_H_
       4             : #include <linux/mm.h>
       5             : 
       6             : /*
       7             :  * PFN_FLAGS_MASK - mask of all the possible valid pfn_t flags
       8             :  * PFN_SG_CHAIN - pfn is a pointer to the next scatterlist entry
       9             :  * PFN_SG_LAST - pfn references a page and is the last scatterlist entry
      10             :  * PFN_DEV - pfn is not covered by system memmap by default
      11             :  * PFN_MAP - pfn has a dynamic page mapping established by a device driver
      12             :  * PFN_SPECIAL - for CONFIG_FS_DAX_LIMITED builds to allow XIP, but not
      13             :  *               get_user_pages
      14             :  */
      15             : #define PFN_FLAGS_MASK (((u64) (~PAGE_MASK)) << (BITS_PER_LONG_LONG - PAGE_SHIFT))
      16             : #define PFN_SG_CHAIN (1ULL << (BITS_PER_LONG_LONG - 1))
      17             : #define PFN_SG_LAST (1ULL << (BITS_PER_LONG_LONG - 2))
      18             : #define PFN_DEV (1ULL << (BITS_PER_LONG_LONG - 3))
      19             : #define PFN_MAP (1ULL << (BITS_PER_LONG_LONG - 4))
      20             : #define PFN_SPECIAL (1ULL << (BITS_PER_LONG_LONG - 5))
      21             : 
      22             : #define PFN_FLAGS_TRACE \
      23             :         { PFN_SPECIAL,  "SPECIAL" }, \
      24             :         { PFN_SG_CHAIN, "SG_CHAIN" }, \
      25             :         { PFN_SG_LAST,  "SG_LAST" }, \
      26             :         { PFN_DEV,      "DEV" }, \
      27             :         { PFN_MAP,      "MAP" }
      28             : 
      29         266 : static inline pfn_t __pfn_to_pfn_t(unsigned long pfn, u64 flags)
      30             : {
      31         266 :         pfn_t pfn_t = { .val = pfn | (flags & PFN_FLAGS_MASK), };
      32             : 
      33         133 :         return pfn_t;
      34             : }
      35             : 
      36             : /* a default pfn to pfn_t conversion assumes that @pfn is pfn_valid() */
      37             : static inline pfn_t pfn_to_pfn_t(unsigned long pfn)
      38             : {
      39             :         return __pfn_to_pfn_t(pfn, 0);
      40             : }
      41             : 
      42             : static inline pfn_t phys_to_pfn_t(phys_addr_t addr, u64 flags)
      43             : {
      44             :         return __pfn_to_pfn_t(addr >> PAGE_SHIFT, flags);
      45             : }
      46             : 
      47             : static inline bool pfn_t_has_page(pfn_t pfn)
      48             : {
      49             :         return (pfn.val & PFN_MAP) == PFN_MAP || (pfn.val & PFN_DEV) == 0;
      50             : }
      51             : 
      52         133 : static inline unsigned long pfn_t_to_pfn(pfn_t pfn)
      53             : {
      54           0 :         return pfn.val & ~PFN_FLAGS_MASK;
      55             : }
      56             : 
      57             : static inline struct page *pfn_t_to_page(pfn_t pfn)
      58             : {
      59             :         if (pfn_t_has_page(pfn))
      60             :                 return pfn_to_page(pfn_t_to_pfn(pfn));
      61             :         return NULL;
      62             : }
      63             : 
      64           0 : static inline phys_addr_t pfn_t_to_phys(pfn_t pfn)
      65             : {
      66           0 :         return PFN_PHYS(pfn_t_to_pfn(pfn));
      67             : }
      68             : 
      69             : static inline pfn_t page_to_pfn_t(struct page *page)
      70             : {
      71             :         return pfn_to_pfn_t(page_to_pfn(page));
      72             : }
      73             : 
      74             : static inline int pfn_t_valid(pfn_t pfn)
      75             : {
      76             :         return pfn_valid(pfn_t_to_pfn(pfn));
      77             : }
      78             : 
      79             : #ifdef CONFIG_MMU
      80         133 : static inline pte_t pfn_t_pte(pfn_t pfn, pgprot_t pgprot)
      81             : {
      82         133 :         return pfn_pte(pfn_t_to_pfn(pfn), pgprot);
      83             : }
      84             : #endif
      85             : 
      86             : #ifdef CONFIG_TRANSPARENT_HUGEPAGE
      87           0 : static inline pmd_t pfn_t_pmd(pfn_t pfn, pgprot_t pgprot)
      88             : {
      89           0 :         return pfn_pmd(pfn_t_to_pfn(pfn), pgprot);
      90             : }
      91             : 
      92             : #ifdef CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD
      93           0 : static inline pud_t pfn_t_pud(pfn_t pfn, pgprot_t pgprot)
      94             : {
      95           0 :         return pfn_pud(pfn_t_to_pfn(pfn), pgprot);
      96             : }
      97             : #endif
      98             : #endif
      99             : 
     100             : #ifdef CONFIG_ARCH_HAS_PTE_DEVMAP
     101         133 : static inline bool pfn_t_devmap(pfn_t pfn)
     102             : {
     103         133 :         const u64 flags = PFN_DEV|PFN_MAP;
     104             : 
     105         133 :         return (pfn.val & flags) == flags;
     106             : }
     107             : #else
     108             : static inline bool pfn_t_devmap(pfn_t pfn)
     109             : {
     110             :         return false;
     111             : }
     112             : pte_t pte_mkdevmap(pte_t pte);
     113             : pmd_t pmd_mkdevmap(pmd_t pmd);
     114             : #if defined(CONFIG_TRANSPARENT_HUGEPAGE) && \
     115             :         defined(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD)
     116             : pud_t pud_mkdevmap(pud_t pud);
     117             : #endif
     118             : #endif /* CONFIG_ARCH_HAS_PTE_DEVMAP */
     119             : 
     120             : #ifdef CONFIG_ARCH_HAS_PTE_SPECIAL
     121           0 : static inline bool pfn_t_special(pfn_t pfn)
     122             : {
     123           0 :         return (pfn.val & PFN_SPECIAL) == PFN_SPECIAL;
     124             : }
     125             : #else
     126             : static inline bool pfn_t_special(pfn_t pfn)
     127             : {
     128             :         return false;
     129             : }
     130             : #endif /* CONFIG_ARCH_HAS_PTE_SPECIAL */
     131             : #endif /* _LINUX_PFN_T_H_ */

Generated by: LCOV version 1.14