Loading arch/s390/include/asm/pgtable.h +10 −0 Original line number Diff line number Diff line Loading @@ -345,6 +345,8 @@ extern unsigned long MODULES_END; #define _REGION3_ENTRY (_REGION_ENTRY_TYPE_R3 | _REGION_ENTRY_LENGTH) #define _REGION3_ENTRY_EMPTY (_REGION_ENTRY_TYPE_R3 | _REGION_ENTRY_INV) #define _REGION3_ENTRY_LARGE 0x400 /* RTTE-format control, large page */ /* Bits in the segment table entry */ #define _SEGMENT_ENTRY_ORIGIN ~0x7ffUL/* segment table origin */ #define _SEGMENT_ENTRY_RO 0x200 /* page protection bit */ Loading Loading @@ -444,6 +446,7 @@ static inline int pgd_bad(pgd_t pgd) { return 0; } static inline int pud_present(pud_t pud) { return 1; } static inline int pud_none(pud_t pud) { return 0; } static inline int pud_large(pud_t pud) { return 0; } static inline int pud_bad(pud_t pud) { return 0; } #else /* CONFIG_64BIT */ Loading Loading @@ -489,6 +492,13 @@ static inline int pud_none(pud_t pud) return (pud_val(pud) & _REGION_ENTRY_INV) != 0UL; } static inline int pud_large(pud_t pud) { if ((pud_val(pud) & _REGION_ENTRY_TYPE_MASK) != _REGION_ENTRY_TYPE_R3) return 0; return !!(pud_val(pud) & _REGION3_ENTRY_LARGE); } static inline int pud_bad(pud_t pud) { /* Loading arch/s390/mm/dump_pagetables.c +6 −1 Original line number Diff line number Diff line Loading @@ -150,6 +150,7 @@ static void walk_pmd_level(struct seq_file *m, struct pg_state *st, static void walk_pud_level(struct seq_file *m, struct pg_state *st, pgd_t *pgd, unsigned long addr) { unsigned int prot; pud_t *pud; int i; Loading @@ -157,6 +158,10 @@ static void walk_pud_level(struct seq_file *m, struct pg_state *st, st->current_address = addr; pud = pud_offset(pgd, addr); if (!pud_none(*pud)) if (pud_large(*pud)) { prot = pud_val(*pud) & _PAGE_RO; note_page(m, st, prot, 2); } else walk_pmd_level(m, st, pud, addr); else note_page(m, st, _PAGE_INVALID, 2); Loading arch/s390/mm/pageattr.c +1 −1 Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ static pte_t *walk_page_table(unsigned long addr) if (pgd_none(*pgdp)) return NULL; pudp = pud_offset(pgdp, addr); if (pud_none(*pudp)) if (pud_none(*pudp) || pud_large(*pudp)) return NULL; pmdp = pmd_offset(pudp, addr); if (pmd_none(*pmdp) || pmd_large(*pmdp)) Loading arch/s390/mm/vmem.c +16 −4 Original line number Diff line number Diff line Loading @@ -89,6 +89,7 @@ static int vmem_add_mem(unsigned long start, unsigned long size, int ro) int ret = -ENOMEM; while (address < end) { pte = mk_pte_phys(address, __pgprot(ro ? _PAGE_RO : 0)); pg_dir = pgd_offset_k(address); if (pgd_none(*pg_dir)) { pu_dir = vmem_pud_alloc(); Loading @@ -96,18 +97,24 @@ static int vmem_add_mem(unsigned long start, unsigned long size, int ro) goto out; pgd_populate(&init_mm, pg_dir, pu_dir); } pu_dir = pud_offset(pg_dir, address); #if defined(CONFIG_64BIT) && !defined(CONFIG_DEBUG_PAGEALLOC) if (MACHINE_HAS_EDAT2 && pud_none(*pu_dir) && address && !(address & ~PUD_MASK) && (address + PUD_SIZE <= end)) { pte_val(pte) |= _REGION3_ENTRY_LARGE; pte_val(pte) |= _REGION_ENTRY_TYPE_R3; pud_val(*pu_dir) = pte_val(pte); address += PUD_SIZE; continue; } #endif if (pud_none(*pu_dir)) { pm_dir = vmem_pmd_alloc(); if (!pm_dir) goto out; pud_populate(&init_mm, pu_dir, pm_dir); } pte = mk_pte_phys(address, __pgprot(ro ? _PAGE_RO : 0)); pm_dir = pmd_offset(pu_dir, address); #if defined(CONFIG_64BIT) && !defined(CONFIG_DEBUG_PAGEALLOC) if (MACHINE_HAS_EDAT1 && pmd_none(*pm_dir) && address && !(address & ~PMD_MASK) && (address + PMD_SIZE <= end)) { Loading Loading @@ -160,6 +167,11 @@ static void vmem_remove_range(unsigned long start, unsigned long size) address += PUD_SIZE; continue; } if (pud_large(*pu_dir)) { pud_clear(pu_dir); address += PUD_SIZE; continue; } pm_dir = pmd_offset(pu_dir, address); if (pmd_none(*pm_dir)) { address += PMD_SIZE; Loading Loading
arch/s390/include/asm/pgtable.h +10 −0 Original line number Diff line number Diff line Loading @@ -345,6 +345,8 @@ extern unsigned long MODULES_END; #define _REGION3_ENTRY (_REGION_ENTRY_TYPE_R3 | _REGION_ENTRY_LENGTH) #define _REGION3_ENTRY_EMPTY (_REGION_ENTRY_TYPE_R3 | _REGION_ENTRY_INV) #define _REGION3_ENTRY_LARGE 0x400 /* RTTE-format control, large page */ /* Bits in the segment table entry */ #define _SEGMENT_ENTRY_ORIGIN ~0x7ffUL/* segment table origin */ #define _SEGMENT_ENTRY_RO 0x200 /* page protection bit */ Loading Loading @@ -444,6 +446,7 @@ static inline int pgd_bad(pgd_t pgd) { return 0; } static inline int pud_present(pud_t pud) { return 1; } static inline int pud_none(pud_t pud) { return 0; } static inline int pud_large(pud_t pud) { return 0; } static inline int pud_bad(pud_t pud) { return 0; } #else /* CONFIG_64BIT */ Loading Loading @@ -489,6 +492,13 @@ static inline int pud_none(pud_t pud) return (pud_val(pud) & _REGION_ENTRY_INV) != 0UL; } static inline int pud_large(pud_t pud) { if ((pud_val(pud) & _REGION_ENTRY_TYPE_MASK) != _REGION_ENTRY_TYPE_R3) return 0; return !!(pud_val(pud) & _REGION3_ENTRY_LARGE); } static inline int pud_bad(pud_t pud) { /* Loading
arch/s390/mm/dump_pagetables.c +6 −1 Original line number Diff line number Diff line Loading @@ -150,6 +150,7 @@ static void walk_pmd_level(struct seq_file *m, struct pg_state *st, static void walk_pud_level(struct seq_file *m, struct pg_state *st, pgd_t *pgd, unsigned long addr) { unsigned int prot; pud_t *pud; int i; Loading @@ -157,6 +158,10 @@ static void walk_pud_level(struct seq_file *m, struct pg_state *st, st->current_address = addr; pud = pud_offset(pgd, addr); if (!pud_none(*pud)) if (pud_large(*pud)) { prot = pud_val(*pud) & _PAGE_RO; note_page(m, st, prot, 2); } else walk_pmd_level(m, st, pud, addr); else note_page(m, st, _PAGE_INVALID, 2); Loading
arch/s390/mm/pageattr.c +1 −1 Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ static pte_t *walk_page_table(unsigned long addr) if (pgd_none(*pgdp)) return NULL; pudp = pud_offset(pgdp, addr); if (pud_none(*pudp)) if (pud_none(*pudp) || pud_large(*pudp)) return NULL; pmdp = pmd_offset(pudp, addr); if (pmd_none(*pmdp) || pmd_large(*pmdp)) Loading
arch/s390/mm/vmem.c +16 −4 Original line number Diff line number Diff line Loading @@ -89,6 +89,7 @@ static int vmem_add_mem(unsigned long start, unsigned long size, int ro) int ret = -ENOMEM; while (address < end) { pte = mk_pte_phys(address, __pgprot(ro ? _PAGE_RO : 0)); pg_dir = pgd_offset_k(address); if (pgd_none(*pg_dir)) { pu_dir = vmem_pud_alloc(); Loading @@ -96,18 +97,24 @@ static int vmem_add_mem(unsigned long start, unsigned long size, int ro) goto out; pgd_populate(&init_mm, pg_dir, pu_dir); } pu_dir = pud_offset(pg_dir, address); #if defined(CONFIG_64BIT) && !defined(CONFIG_DEBUG_PAGEALLOC) if (MACHINE_HAS_EDAT2 && pud_none(*pu_dir) && address && !(address & ~PUD_MASK) && (address + PUD_SIZE <= end)) { pte_val(pte) |= _REGION3_ENTRY_LARGE; pte_val(pte) |= _REGION_ENTRY_TYPE_R3; pud_val(*pu_dir) = pte_val(pte); address += PUD_SIZE; continue; } #endif if (pud_none(*pu_dir)) { pm_dir = vmem_pmd_alloc(); if (!pm_dir) goto out; pud_populate(&init_mm, pu_dir, pm_dir); } pte = mk_pte_phys(address, __pgprot(ro ? _PAGE_RO : 0)); pm_dir = pmd_offset(pu_dir, address); #if defined(CONFIG_64BIT) && !defined(CONFIG_DEBUG_PAGEALLOC) if (MACHINE_HAS_EDAT1 && pmd_none(*pm_dir) && address && !(address & ~PMD_MASK) && (address + PMD_SIZE <= end)) { Loading Loading @@ -160,6 +167,11 @@ static void vmem_remove_range(unsigned long start, unsigned long size) address += PUD_SIZE; continue; } if (pud_large(*pu_dir)) { pud_clear(pu_dir); address += PUD_SIZE; continue; } pm_dir = pmd_offset(pu_dir, address); if (pmd_none(*pm_dir)) { address += PMD_SIZE; Loading