@@ -156,6 +156,25 @@ static inline int ioremap_pud_range(p4d_t *p4d, unsigned long addr,
156156 return 0 ;
157157}
158158
159+ static int ioremap_try_huge_p4d (p4d_t * p4d , unsigned long addr ,
160+ unsigned long end , phys_addr_t phys_addr ,
161+ pgprot_t prot )
162+ {
163+ if (!ioremap_p4d_enabled ())
164+ return 0 ;
165+
166+ if ((end - addr ) != P4D_SIZE )
167+ return 0 ;
168+
169+ if (!IS_ALIGNED (phys_addr , P4D_SIZE ))
170+ return 0 ;
171+
172+ if (p4d_present (* p4d ) && !p4d_free_pud_page (p4d , addr ))
173+ return 0 ;
174+
175+ return p4d_set_huge (p4d , phys_addr , prot );
176+ }
177+
159178static inline int ioremap_p4d_range (pgd_t * pgd , unsigned long addr ,
160179 unsigned long end , phys_addr_t phys_addr , pgprot_t prot )
161180{
@@ -168,12 +187,8 @@ static inline int ioremap_p4d_range(pgd_t *pgd, unsigned long addr,
168187 do {
169188 next = p4d_addr_end (addr , end );
170189
171- if (ioremap_p4d_enabled () &&
172- ((next - addr ) == P4D_SIZE ) &&
173- IS_ALIGNED (phys_addr , P4D_SIZE )) {
174- if (p4d_set_huge (p4d , phys_addr , prot ))
175- continue ;
176- }
190+ if (ioremap_try_huge_p4d (p4d , addr , next , phys_addr , prot ))
191+ continue ;
177192
178193 if (ioremap_pud_range (p4d , addr , next , phys_addr , prot ))
179194 return - ENOMEM ;
0 commit comments