cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

pfn_t.h (3287B)


      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
     29static inline pfn_t __pfn_to_pfn_t(unsigned long pfn, u64 flags)
     30{
     31	pfn_t pfn_t = { .val = pfn | (flags & PFN_FLAGS_MASK), };
     32
     33	return pfn_t;
     34}
     35
     36/* a default pfn to pfn_t conversion assumes that @pfn is pfn_valid() */
     37static inline pfn_t pfn_to_pfn_t(unsigned long pfn)
     38{
     39	return __pfn_to_pfn_t(pfn, 0);
     40}
     41
     42static 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
     47static 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
     52static inline unsigned long pfn_t_to_pfn(pfn_t pfn)
     53{
     54	return pfn.val & ~PFN_FLAGS_MASK;
     55}
     56
     57static 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
     64static inline phys_addr_t pfn_t_to_phys(pfn_t pfn)
     65{
     66	return PFN_PHYS(pfn_t_to_pfn(pfn));
     67}
     68
     69static inline pfn_t page_to_pfn_t(struct page *page)
     70{
     71	return pfn_to_pfn_t(page_to_pfn(page));
     72}
     73
     74static inline int pfn_t_valid(pfn_t pfn)
     75{
     76	return pfn_valid(pfn_t_to_pfn(pfn));
     77}
     78
     79#ifdef CONFIG_MMU
     80static inline pte_t pfn_t_pte(pfn_t pfn, pgprot_t pgprot)
     81{
     82	return pfn_pte(pfn_t_to_pfn(pfn), pgprot);
     83}
     84#endif
     85
     86#ifdef CONFIG_TRANSPARENT_HUGEPAGE
     87static inline pmd_t pfn_t_pmd(pfn_t pfn, pgprot_t pgprot)
     88{
     89	return pfn_pmd(pfn_t_to_pfn(pfn), pgprot);
     90}
     91
     92#ifdef CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD
     93static inline pud_t pfn_t_pud(pfn_t pfn, pgprot_t pgprot)
     94{
     95	return pfn_pud(pfn_t_to_pfn(pfn), pgprot);
     96}
     97#endif
     98#endif
     99
    100#ifdef CONFIG_ARCH_HAS_PTE_DEVMAP
    101static inline bool pfn_t_devmap(pfn_t pfn)
    102{
    103	const u64 flags = PFN_DEV|PFN_MAP;
    104
    105	return (pfn.val & flags) == flags;
    106}
    107#else
    108static inline bool pfn_t_devmap(pfn_t pfn)
    109{
    110	return false;
    111}
    112pte_t pte_mkdevmap(pte_t pte);
    113pmd_t pmd_mkdevmap(pmd_t pmd);
    114#if defined(CONFIG_TRANSPARENT_HUGEPAGE) && \
    115	defined(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD)
    116pud_t pud_mkdevmap(pud_t pud);
    117#endif
    118#endif /* CONFIG_ARCH_HAS_PTE_DEVMAP */
    119
    120#ifdef CONFIG_ARCH_HAS_PTE_SPECIAL
    121static inline bool pfn_t_special(pfn_t pfn)
    122{
    123	return (pfn.val & PFN_SPECIAL) == PFN_SPECIAL;
    124}
    125#else
    126static 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_ */