pgtable-invert.h 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef _ASM_PGTABLE_INVERT_H
  3. #define _ASM_PGTABLE_INVERT_H 1
  4. #ifndef __ASSEMBLY__
  5. /*
  6. * A clear pte value is special, and doesn't get inverted.
  7. *
  8. * Note that even users that only pass a pgprot_t (rather
  9. * than a full pte) won't trigger the special zero case,
  10. * because even PAGE_NONE has _PAGE_PROTNONE | _PAGE_ACCESSED
  11. * set. So the all zero case really is limited to just the
  12. * cleared page table entry case.
  13. */
  14. static inline bool __pte_needs_invert(u64 val)
  15. {
  16. return val && !(val & _PAGE_PRESENT);
  17. }
  18. /* Get a mask to xor with the page table entry to get the correct pfn. */
  19. static inline u64 protnone_mask(u64 val)
  20. {
  21. return __pte_needs_invert(val) ? ~0ull : 0;
  22. }
  23. static inline u64 flip_protnone_guard(u64 oldval, u64 val, u64 mask)
  24. {
  25. /*
  26. * When a PTE transitions from NONE to !NONE or vice-versa
  27. * invert the PFN part to stop speculation.
  28. * pte_pfn undoes this when needed.
  29. */
  30. if (__pte_needs_invert(oldval) != __pte_needs_invert(val))
  31. val = (val & ~mask) | (~val & mask);
  32. return val;
  33. }
  34. #endif /* __ASSEMBLY__ */
  35. #endif