mmu_change_region_attr_nobreak() operates at page granularity and
cannot handle sub-page reserved-memory regions. Align reserved
regions to page boundaries before updating their attributes.

Also increase N_RESERVED_REGIONS to accommodate newer SoCs

Signed-off-by: Aswin Murugan <[email protected]>
---
This change requires the patch series [1] to be applied first.

[1] 
https://lore.kernel.org/u-boot/[email protected]/
---
 arch/arm/mach-snapdragon/mem_map.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-snapdragon/mem_map.c 
b/arch/arm/mach-snapdragon/mem_map.c
index f64ec0c674e..2718d7f280e 100644
--- a/arch/arm/mach-snapdragon/mem_map.c
+++ b/arch/arm/mach-snapdragon/mem_map.c
@@ -83,7 +83,7 @@ static int fdt_cmp_res(const void *v1, const void *v2)
        return res1->start - res2->start;
 }
 
-#define N_RESERVED_REGIONS 64
+#define N_RESERVED_REGIONS 256
 
 /* Map and unmap reserved memory regions as appropriate.
  * Mark all no-map regions as PTE_TYPE_FAULT to prevent speculative access.
@@ -131,11 +131,21 @@ static void configure_reserved_memory(void)
                 */
                ptr = fdt_getprop(gd->fdt_blob, rmem, "reg", NULL);
                if (ptr) {
-                       /* Qualcomm devices use #address/size-cells = <2> but 
all reserved regions are within
-                        * the 32-bit address space. So we can cheat here for 
speed.
+                       u64 rstart, rend;
+
+                       /* Qualcomm devices use #address/size-cells = <2>. 
Reserved regions
+                        * are within the 32-bit space, so the low cells hold 
addr/size.
+                        */
+                       rstart = fdt32_to_cpu(ptr[1]);
+                       rend = rstart + fdt32_to_cpu(ptr[3]);
+
+                       /* The MMU works at page (4K) granularity: 
mmu_change_region_attr_nobreak()
+                        * cannot map a sub-page region and would spin forever 
on one.
+                        * so reserved-memory regions must be expanded to page 
boundaries before
+                        * their attributes are updated.
                         */
-                       res[i].start = fdt32_to_cpu(ptr[1]);
-                       res[i].size = fdt32_to_cpu(ptr[3]);
+                       res[i].start = rstart & ~((u64)SZ_4K - 1);
+                       res[i].size = ALIGN(rend, SZ_4K) - res[i].start;
                        res[i].attrs = attrs;
                        i++;
                }
-- 
2.34.1

Reply via email to