Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef _ASM_PGTABLE_INVERT_H
0003 #define _ASM_PGTABLE_INVERT_H 1
0004 
0005 #ifndef __ASSEMBLY__
0006 
0007 /*
0008  * A clear pte value is special, and doesn't get inverted.
0009  *
0010  * Note that even users that only pass a pgprot_t (rather
0011  * than a full pte) won't trigger the special zero case,
0012  * because even PAGE_NONE has _PAGE_PROTNONE | _PAGE_ACCESSED
0013  * set. So the all zero case really is limited to just the
0014  * cleared page table entry case.
0015  */
0016 static inline bool __pte_needs_invert(u64 val)
0017 {
0018     return val && !(val & _PAGE_PRESENT);
0019 }
0020 
0021 /* Get a mask to xor with the page table entry to get the correct pfn. */
0022 static inline u64 protnone_mask(u64 val)
0023 {
0024     return __pte_needs_invert(val) ?  ~0ull : 0;
0025 }
0026 
0027 static inline u64 flip_protnone_guard(u64 oldval, u64 val, u64 mask)
0028 {
0029     /*
0030      * When a PTE transitions from NONE to !NONE or vice-versa
0031      * invert the PFN part to stop speculation.
0032      * pte_pfn undoes this when needed.
0033      */
0034     if (__pte_needs_invert(oldval) != __pte_needs_invert(val))
0035         val = (val & ~mask) | (~val & mask);
0036     return val;
0037 }
0038 
0039 #endif /* __ASSEMBLY__ */
0040 
0041 #endif