@@ -259,24 +259,34 @@ static inline int is_module_addr(void *addr)
259259#define _REGION1_ENTRY_EMPTY (_REGION_ENTRY_TYPE_R1 | _REGION_ENTRY_INVALID)
260260#define _REGION2_ENTRY (_REGION_ENTRY_TYPE_R2 | _REGION_ENTRY_LENGTH)
261261#define _REGION2_ENTRY_EMPTY (_REGION_ENTRY_TYPE_R2 | _REGION_ENTRY_INVALID)
262- #define _REGION3_ENTRY (_REGION_ENTRY_TYPE_R3 | _REGION_ENTRY_LENGTH)
262+ #define _REGION3_ENTRY (_REGION_ENTRY_TYPE_R3 | _REGION_ENTRY_LENGTH | \
263+ _REGION3_ENTRY_PRESENT)
263264#define _REGION3_ENTRY_EMPTY (_REGION_ENTRY_TYPE_R3 | _REGION_ENTRY_INVALID)
264265
265266#define _REGION3_ENTRY_ORIGIN_LARGE ~0x7fffffffUL /* large page address */
266267#define _REGION3_ENTRY_DIRTY 0x2000 /* SW region dirty bit */
267268#define _REGION3_ENTRY_YOUNG 0x1000 /* SW region young bit */
269+ #define _REGION3_ENTRY_COMM 0x0010 /* Common-Region, marks swap entry */
268270#define _REGION3_ENTRY_LARGE 0x0400 /* RTTE-format control, large page */
269- #define _REGION3_ENTRY_READ 0x0002 /* SW region read bit */
270- #define _REGION3_ENTRY_WRITE 0x0001 /* SW region write bit */
271+ #define _REGION3_ENTRY_WRITE 0x8000 /* SW region write bit */
272+ #define _REGION3_ENTRY_READ 0x4000 /* SW region read bit */
271273
272274#ifdef CONFIG_MEM_SOFT_DIRTY
273- #define _REGION3_ENTRY_SOFT_DIRTY 0x4000 /* SW region soft dirty bit */
275+ #define _REGION3_ENTRY_SOFT_DIRTY 0x0002 /* SW region soft dirty bit */
274276#else
275277#define _REGION3_ENTRY_SOFT_DIRTY 0x0000 /* SW region soft dirty bit */
276278#endif
277279
278280#define _REGION_ENTRY_BITS 0xfffffffffffff22fUL
279281
282+ /*
283+ * SW region present bit. For non-leaf region-third-table entries, bits 62-63
284+ * indicate the TABLE LENGTH and both must be set to 1. But such entries
285+ * would always be considered as present, so it is safe to use bit 63 as
286+ * PRESENT bit for PUD.
287+ */
288+ #define _REGION3_ENTRY_PRESENT 0x0001
289+
280290/* Bits in the segment table entry */
281291#define _SEGMENT_ENTRY_BITS 0xfffffffffffffe33UL
282292#define _SEGMENT_ENTRY_HARDWARE_BITS 0xfffffffffffffe30UL
@@ -288,21 +298,29 @@ static inline int is_module_addr(void *addr)
288298#define _SEGMENT_ENTRY_INVALID 0x20 /* invalid segment table entry */
289299#define _SEGMENT_ENTRY_TYPE_MASK 0x0c /* segment table type mask */
290300
291- #define _SEGMENT_ENTRY (0 )
301+ #define _SEGMENT_ENTRY (_SEGMENT_ENTRY_PRESENT )
292302#define _SEGMENT_ENTRY_EMPTY (_SEGMENT_ENTRY_INVALID)
293303
294304#define _SEGMENT_ENTRY_DIRTY 0x2000 /* SW segment dirty bit */
295305#define _SEGMENT_ENTRY_YOUNG 0x1000 /* SW segment young bit */
306+
307+ #define _SEGMENT_ENTRY_COMM 0x0010 /* Common-Segment, marks swap entry */
296308#define _SEGMENT_ENTRY_LARGE 0x0400 /* STE-format control, large page */
297- #define _SEGMENT_ENTRY_WRITE 0x0002 /* SW segment write bit */
298- #define _SEGMENT_ENTRY_READ 0x0001 /* SW segment read bit */
309+ #define _SEGMENT_ENTRY_WRITE 0x8000 /* SW segment write bit */
310+ #define _SEGMENT_ENTRY_READ 0x4000 /* SW segment read bit */
299311
300312#ifdef CONFIG_MEM_SOFT_DIRTY
301- #define _SEGMENT_ENTRY_SOFT_DIRTY 0x4000 /* SW segment soft dirty bit */
313+ #define _SEGMENT_ENTRY_SOFT_DIRTY 0x0002 /* SW segment soft dirty bit */
302314#else
303315#define _SEGMENT_ENTRY_SOFT_DIRTY 0x0000 /* SW segment soft dirty bit */
304316#endif
305317
318+ #define _SEGMENT_ENTRY_PRESENT 0x0001 /* SW segment present bit */
319+
320+ /* Common bits in region and segment table entries, for swap entries */
321+ #define _RST_ENTRY_COMM 0x0010 /* Common-Region/Segment, marks swap entry */
322+ #define _RST_ENTRY_INVALID 0x0020 /* invalid region/segment table entry */
323+
306324#define _CRST_ENTRIES 2048 /* number of region/segment table entries */
307325#define _PAGE_ENTRIES 256 /* number of page table entries */
308326
@@ -434,17 +452,22 @@ static inline int is_module_addr(void *addr)
434452/*
435453 * Segment entry (large page) protection definitions.
436454 */
437- #define SEGMENT_NONE __pgprot(_SEGMENT_ENTRY_INVALID | \
455+ #define SEGMENT_NONE __pgprot(_SEGMENT_ENTRY_PRESENT | \
456+ _SEGMENT_ENTRY_INVALID | \
438457 _SEGMENT_ENTRY_PROTECT)
439- #define SEGMENT_RO __pgprot(_SEGMENT_ENTRY_PROTECT | \
458+ #define SEGMENT_RO __pgprot(_SEGMENT_ENTRY_PRESENT | \
459+ _SEGMENT_ENTRY_PROTECT | \
440460 _SEGMENT_ENTRY_READ | \
441461 _SEGMENT_ENTRY_NOEXEC)
442- #define SEGMENT_RX __pgprot(_SEGMENT_ENTRY_PROTECT | \
462+ #define SEGMENT_RX __pgprot(_SEGMENT_ENTRY_PRESENT | \
463+ _SEGMENT_ENTRY_PROTECT | \
443464 _SEGMENT_ENTRY_READ)
444- #define SEGMENT_RW __pgprot(_SEGMENT_ENTRY_READ | \
465+ #define SEGMENT_RW __pgprot(_SEGMENT_ENTRY_PRESENT | \
466+ _SEGMENT_ENTRY_READ | \
445467 _SEGMENT_ENTRY_WRITE | \
446468 _SEGMENT_ENTRY_NOEXEC)
447- #define SEGMENT_RWX __pgprot(_SEGMENT_ENTRY_READ | \
469+ #define SEGMENT_RWX __pgprot(_SEGMENT_ENTRY_PRESENT | \
470+ _SEGMENT_ENTRY_READ | \
448471 _SEGMENT_ENTRY_WRITE)
449472#define SEGMENT_KERNEL __pgprot(_SEGMENT_ENTRY | \
450473 _SEGMENT_ENTRY_LARGE | \
@@ -471,19 +494,22 @@ static inline int is_module_addr(void *addr)
471494 */
472495
473496#define REGION3_KERNEL __pgprot(_REGION_ENTRY_TYPE_R3 | \
497+ _REGION3_ENTRY_PRESENT | \
474498 _REGION3_ENTRY_LARGE | \
475499 _REGION3_ENTRY_READ | \
476500 _REGION3_ENTRY_WRITE | \
477501 _REGION3_ENTRY_YOUNG | \
478502 _REGION3_ENTRY_DIRTY | \
479503 _REGION_ENTRY_NOEXEC)
480504#define REGION3_KERNEL_RO __pgprot(_REGION_ENTRY_TYPE_R3 | \
505+ _REGION3_ENTRY_PRESENT | \
481506 _REGION3_ENTRY_LARGE | \
482507 _REGION3_ENTRY_READ | \
483508 _REGION3_ENTRY_YOUNG | \
484509 _REGION_ENTRY_PROTECT | \
485510 _REGION_ENTRY_NOEXEC)
486511#define REGION3_KERNEL_EXEC __pgprot(_REGION_ENTRY_TYPE_R3 | \
512+ _REGION3_ENTRY_PRESENT | \
487513 _REGION3_ENTRY_LARGE | \
488514 _REGION3_ENTRY_READ | \
489515 _REGION3_ENTRY_WRITE | \
@@ -705,7 +731,7 @@ static inline int pud_present(pud_t pud)
705731{
706732 if (pud_folded (pud ))
707733 return 1 ;
708- return (pud_val (pud ) & _REGION_ENTRY_ORIGIN ) != 0UL ;
734+ return (pud_val (pud ) & _REGION3_ENTRY_PRESENT ) != 0 ;
709735}
710736
711737static inline int pud_none (pud_t pud )
@@ -720,13 +746,18 @@ static inline bool pud_leaf(pud_t pud)
720746{
721747 if ((pud_val (pud ) & _REGION_ENTRY_TYPE_MASK ) != _REGION_ENTRY_TYPE_R3 )
722748 return 0 ;
723- return !!(pud_val (pud ) & _REGION3_ENTRY_LARGE );
749+ return (pud_present (pud ) && (pud_val (pud ) & _REGION3_ENTRY_LARGE ) != 0 );
750+ }
751+
752+ static inline int pmd_present (pmd_t pmd )
753+ {
754+ return (pmd_val (pmd ) & _SEGMENT_ENTRY_PRESENT ) != 0 ;
724755}
725756
726757#define pmd_leaf pmd_leaf
727758static inline bool pmd_leaf (pmd_t pmd )
728759{
729- return (pmd_val (pmd ) & _SEGMENT_ENTRY_LARGE ) != 0 ;
760+ return (pmd_present ( pmd ) && ( pmd_val (pmd ) & _SEGMENT_ENTRY_LARGE ) != 0 ) ;
730761}
731762
732763static inline int pmd_bad (pmd_t pmd )
@@ -758,11 +789,6 @@ static inline int p4d_bad(p4d_t p4d)
758789 return (p4d_val (p4d ) & ~_REGION_ENTRY_BITS ) != 0 ;
759790}
760791
761- static inline int pmd_present (pmd_t pmd )
762- {
763- return pmd_val (pmd ) != _SEGMENT_ENTRY_EMPTY ;
764- }
765-
766792static inline int pmd_none (pmd_t pmd )
767793{
768794 return pmd_val (pmd ) == _SEGMENT_ENTRY_EMPTY ;
@@ -1807,7 +1833,7 @@ static inline pmd_t pmdp_collapse_flush(struct vm_area_struct *vma,
18071833
18081834static inline int pmd_trans_huge (pmd_t pmd )
18091835{
1810- return pmd_val (pmd ) & _SEGMENT_ENTRY_LARGE ;
1836+ return pmd_leaf (pmd );
18111837}
18121838
18131839#define has_transparent_hugepage has_transparent_hugepage
@@ -1867,6 +1893,53 @@ static inline swp_entry_t __swp_entry(unsigned long type, unsigned long offset)
18671893#define __pte_to_swp_entry (pte ) ((swp_entry_t) { pte_val(pte) })
18681894#define __swp_entry_to_pte (x ) ((pte_t) { (x).val })
18691895
1896+ /*
1897+ * 64 bit swap entry format for REGION3 and SEGMENT table entries (RSTE)
1898+ * Bits 59 and 63 are used to indicate the swap entry. Bit 58 marks the rste
1899+ * as invalid.
1900+ * A swap entry is indicated by bit pattern (rste & 0x011) == 0x010
1901+ * | offset |Xtype |11TT|S0|
1902+ * |0000000000111111111122222222223333333333444444444455|555555|5566|66|
1903+ * |0123456789012345678901234567890123456789012345678901|234567|8901|23|
1904+ *
1905+ * Bits 0-51 store the offset.
1906+ * Bits 53-57 store the type.
1907+ * Bit 62 (S) is used for softdirty tracking.
1908+ * Bits 60-61 (TT) indicate the table type: 0x01 for REGION3 and 0x00 for SEGMENT.
1909+ * Bit 52 (X) is unused.
1910+ */
1911+
1912+ #define __SWP_OFFSET_MASK_RSTE ((1UL << 52) - 1)
1913+ #define __SWP_OFFSET_SHIFT_RSTE 12
1914+ #define __SWP_TYPE_MASK_RSTE ((1UL << 5) - 1)
1915+ #define __SWP_TYPE_SHIFT_RSTE 6
1916+
1917+ /*
1918+ * TT bits set to 0x00 == SEGMENT. For REGION3 entries, caller must add R3
1919+ * bits 0x01. See also __set_huge_pte_at().
1920+ */
1921+ static inline unsigned long mk_swap_rste (unsigned long type , unsigned long offset )
1922+ {
1923+ unsigned long rste ;
1924+
1925+ rste = _RST_ENTRY_INVALID | _RST_ENTRY_COMM ;
1926+ rste |= (offset & __SWP_OFFSET_MASK_RSTE ) << __SWP_OFFSET_SHIFT_RSTE ;
1927+ rste |= (type & __SWP_TYPE_MASK_RSTE ) << __SWP_TYPE_SHIFT_RSTE ;
1928+ return rste ;
1929+ }
1930+
1931+ static inline unsigned long __swp_type_rste (swp_entry_t entry )
1932+ {
1933+ return (entry .val >> __SWP_TYPE_SHIFT_RSTE ) & __SWP_TYPE_MASK_RSTE ;
1934+ }
1935+
1936+ static inline unsigned long __swp_offset_rste (swp_entry_t entry )
1937+ {
1938+ return (entry .val >> __SWP_OFFSET_SHIFT_RSTE ) & __SWP_OFFSET_MASK_RSTE ;
1939+ }
1940+
1941+ #define __rste_to_swp_entry (rste ) ((swp_entry_t) { rste })
1942+
18701943extern int vmem_add_mapping (unsigned long start , unsigned long size );
18711944extern void vmem_remove_mapping (unsigned long start , unsigned long size );
18721945extern int __vmem_map_4k_page (unsigned long addr , unsigned long phys , pgprot_t prot , bool alloc );
0 commit comments