of: fix reserved memory handling 26/252826/3 accepted/tizen/unified/20210204.134610 submit/tizen/20210204.012538
authorMarek Szyprowski <m.szyprowski@samsung.com>
Tue, 2 Feb 2021 10:24:36 +0000 (11:24 +0100)
committerSeung-Woo Kim <sw0312.kim@samsung.com>
Wed, 3 Feb 2021 04:03:13 +0000 (04:03 +0000)
Mainline u-boot marks some secure monitor relate memory with the
/memreserve/ device-tree method. On the other hand, the same memory is
already defined in /reserved-memory node with the all details needed to
use it by the respective secure monitor deamon. Check for such case and
properly initialize such reserved memory regions instead of returning a
failure.

This allows to use vendor kernel with mainline u-boot on Amlogic SoCs.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Change-Id: I0bd3b51899cc17f17d1bcbd0c2c5a0d88686b245

drivers/of/of_reserved_mem.c
include/linux/memblock.h
mm/memblock.c

index c4a7b04..aa5ed94 100644 (file)
@@ -43,6 +43,14 @@ int __init __weak early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
        phys_addr_t *res_base)
 {
        phys_addr_t base;
+
+       /* check if the region has been alredy reserved by the bootloader */
+       if (start && end && memblock_is_region_reserved(start, end - start)) {
+               pr_info("OF: region (%pa--%pa) is reserved both in /memreserve/ and /reserved-memory, fixing\n",
+                       &start, &end);
+               memblock_unreserve(start, end - start);
+       }
+
        /*
         * We use __memblock_alloc_base() because memblock_alloc_base()
         * panic()s on allocation failure.
index 4024af0..debfcb9 100644 (file)
@@ -84,6 +84,7 @@ int memblock_add(phys_addr_t base, phys_addr_t size);
 int memblock_remove(phys_addr_t base, phys_addr_t size);
 int memblock_free(phys_addr_t base, phys_addr_t size);
 int memblock_reserve(phys_addr_t base, phys_addr_t size);
+int memblock_unreserve(phys_addr_t base, phys_addr_t size);
 void memblock_trim_memory(phys_addr_t align);
 bool memblock_overlaps_region(struct memblock_type *type,
                              phys_addr_t base, phys_addr_t size);
index 42b98af..71867c2 100644 (file)
@@ -733,6 +733,16 @@ int __init_memblock memblock_reserve(phys_addr_t base, phys_addr_t size)
        return memblock_add_range(&memblock.reserved, base, size, MAX_NUMNODES, 0);
 }
 
+int __init_memblock memblock_unreserve(phys_addr_t base, phys_addr_t size)
+{
+       memblock_dbg("   memblock_unreserve: [%#016llx-%#016llx] %pF\n",
+                    (unsigned long long)base,
+                    (unsigned long long)base + size - 1,
+                    (void *)_RET_IP_);
+
+       return memblock_remove_range(&memblock.reserved, base, size);
+}
+
 /**
  *
  * This function isolates region [@base, @base + @size), and sets/clears flag