* [PATCH 0/2] Fix Random Kernel panic from when fail to reserve memory
@ 2023-04-06 15:14 Lucas Tanure
2023-04-06 15:14 ` [PATCH 1/2] memblock: Differentiate regions overlap from both regions being the same Lucas Tanure
2023-04-06 15:14 ` [PATCH 2/2] of: fdt: Allow the kernel to mark nomap regions received from fdt Lucas Tanure
0 siblings, 2 replies; 5+ messages in thread
From: Lucas Tanure @ 2023-04-06 15:14 UTC (permalink / raw)
To: Rob Herring, Frank Rowand, Mike Rapoport, Andrew Morton
Cc: devicetree, linux-kernel, linux-mm, jbrunet, linux-amlogic,
linux-arm-kernel, martin.blumenstingl, narmstrong, stefan,
Lucas Tanure
I am trying to fix an issue where the kernel panics randomly on my Vim3 board.
The issue happens when the ARM Trusted Firmware memory is not removed from the
available ram.
This happens because my u-boot provides this region as a /memreserve/, but it
doesn't flag it as nomap. And the kernel can't map as nomap as the region is
already reserved.
My proposal here is to allow the kernel to mark as nomap if the region from
the device tree and FDT have the same base and size.
arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi:
/* 3 MiB reserved for ARM Trusted Firmware (BL31) */
secmon_reserved: secmon@5000000 {
reg = <0x0 0x05000000 0x0 0x300000>;
no-map;
};
Previos Threads:
#regzbot link: https://lore.kernel.org/linux-arm-kernel/40ca11f84b7cdbfb9ad2ddd480cb204a@agner.ch/#regzbot
#regzbot link: https://lore.kernel.org/all/CAJX_Q+1Tjc+-TjZ6JW9X0NxEdFe=82a9626yL63j7uVD4LpxEA@mail.gmail.com/
Lucas Tanure (2):
memblock: Differentiate regions overlap from both regions being the
same
of: fdt: Allow the kernel to mark nomap regions received from fdt
drivers/of/fdt.c | 10 ++++++----
include/linux/memblock.h | 18 +++++++++++++++---
mm/memblock.c | 37 ++++++++++++++++++++++++-------------
3 files changed, 45 insertions(+), 20 deletions(-)
--
2.40.0
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH 1/2] memblock: Differentiate regions overlap from both regions being the same 2023-04-06 15:14 [PATCH 0/2] Fix Random Kernel panic from when fail to reserve memory Lucas Tanure @ 2023-04-06 15:14 ` Lucas Tanure 2023-04-06 15:14 ` [PATCH 2/2] of: fdt: Allow the kernel to mark nomap regions received from fdt Lucas Tanure 1 sibling, 0 replies; 5+ messages in thread From: Lucas Tanure @ 2023-04-06 15:14 UTC (permalink / raw) To: Rob Herring, Frank Rowand, Mike Rapoport, Andrew Morton Cc: devicetree, linux-kernel, linux-mm, jbrunet, linux-amlogic, linux-arm-kernel, martin.blumenstingl, narmstrong, stefan, Lucas Tanure Add support for memblock_addrs_overlap to return a different value when both regions are exactly the same region, where base and size are equal between the regions. Signed-off-by: Lucas Tanure <tanure@linux.com> --- include/linux/memblock.h | 18 +++++++++++++++--- mm/memblock.c | 37 ++++++++++++++++++++++++------------- 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/include/linux/memblock.h b/include/linux/memblock.h index 50ad19662a32..c7ba8b01a637 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -49,6 +49,18 @@ enum memblock_flags { MEMBLOCK_DRIVER_MANAGED = 0x8, /* always detected via a driver */ }; +/** + * enum memblock_overlap_type - result of comparison between two memory regions + * @MEMBLOCK_NO_OVERLAPS: there is no overlap between the two regions + * @MEMBLOCK_OVERLAPS: the two regions overlap each other, but are not the same + * @MEMBLOCK_EQUAL: both bases and sizes are equal, so the two regions are exactly the same + */ +enum memblock_overlap_type { + MEMBLOCK_NO_OVERLAPS, + MEMBLOCK_OVERLAPS, + MEMBLOCK_EQUAL, +}; + /** * struct memblock_region - represents a memory region * @base: base address of the region @@ -118,8 +130,8 @@ int memblock_reserve(phys_addr_t base, phys_addr_t size); int memblock_physmem_add(phys_addr_t base, phys_addr_t size); #endif void memblock_trim_memory(phys_addr_t align); -bool memblock_overlaps_region(struct memblock_type *type, - phys_addr_t base, phys_addr_t size); +unsigned int memblock_overlaps_region(struct memblock_type *type, + phys_addr_t base, phys_addr_t size); int memblock_mark_hotplug(phys_addr_t base, phys_addr_t size); int memblock_clear_hotplug(phys_addr_t base, phys_addr_t size); int memblock_mark_mirror(phys_addr_t base, phys_addr_t size); @@ -486,7 +498,7 @@ bool memblock_is_memory(phys_addr_t addr); bool memblock_is_map_memory(phys_addr_t addr); bool memblock_is_region_memory(phys_addr_t base, phys_addr_t size); bool memblock_is_reserved(phys_addr_t addr); -bool memblock_is_region_reserved(phys_addr_t base, phys_addr_t size); +unsigned int memblock_is_region_reserved(phys_addr_t base, phys_addr_t size); void memblock_dump_all(void); diff --git a/mm/memblock.c b/mm/memblock.c index 25fd0626a9e7..948cc1bc3edf 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -175,24 +175,33 @@ static inline phys_addr_t memblock_cap_size(phys_addr_t base, phys_addr_t *size) /* * Address comparison utilities */ -static unsigned long __init_memblock memblock_addrs_overlap(phys_addr_t base1, phys_addr_t size1, - phys_addr_t base2, phys_addr_t size2) +static unsigned int __init_memblock memblock_addrs_overlap(phys_addr_t base1, phys_addr_t size1, + phys_addr_t base2, phys_addr_t size2) { - return ((base1 < (base2 + size2)) && (base2 < (base1 + size1))); + if (base1 == base2 && size1 == size2) + return MEMBLOCK_EQUAL; + + if ((base1 < (base2 + size2)) && (base2 < (base1 + size1))) + return MEMBLOCK_OVERLAPS; + + return MEMBLOCK_NO_OVERLAPS; } -bool __init_memblock memblock_overlaps_region(struct memblock_type *type, - phys_addr_t base, phys_addr_t size) +unsigned int __init_memblock memblock_overlaps_region(struct memblock_type *type, + phys_addr_t base, phys_addr_t size) { - unsigned long i; + unsigned long i, ret; memblock_cap_size(base, &size); - for (i = 0; i < type->cnt; i++) - if (memblock_addrs_overlap(base, size, type->regions[i].base, - type->regions[i].size)) - break; - return i < type->cnt; + for (i = 0; i < type->cnt; i++) { + ret = memblock_addrs_overlap(base, size, type->regions[i].base, + type->regions[i].size); + if (ret) + return ret; + } + + return MEMBLOCK_NO_OVERLAPS; } /** @@ -1857,9 +1866,11 @@ bool __init_memblock memblock_is_region_memory(phys_addr_t base, phys_addr_t siz * memory block. * * Return: - * True if they intersect, false if not. + * MEMBLOCK_NO_OVERLAPS if there is no intersection, + * MEMBLOCK_OVERLAPS if they only intersect, + * MEMBLOCK_EQUAL if the region matches base and size to an reserved memory. */ -bool __init_memblock memblock_is_region_reserved(phys_addr_t base, phys_addr_t size) +unsigned int __init_memblock memblock_is_region_reserved(phys_addr_t base, phys_addr_t size) { return memblock_overlaps_region(&memblock.reserved, base, size); } -- 2.40.0 ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 2/2] of: fdt: Allow the kernel to mark nomap regions received from fdt 2023-04-06 15:14 [PATCH 0/2] Fix Random Kernel panic from when fail to reserve memory Lucas Tanure 2023-04-06 15:14 ` [PATCH 1/2] memblock: Differentiate regions overlap from both regions being the same Lucas Tanure @ 2023-04-06 15:14 ` Lucas Tanure 2023-04-06 15:48 ` Rob Herring 1 sibling, 1 reply; 5+ messages in thread From: Lucas Tanure @ 2023-04-06 15:14 UTC (permalink / raw) To: Rob Herring, Frank Rowand, Mike Rapoport, Andrew Morton Cc: devicetree, linux-kernel, linux-mm, jbrunet, linux-amlogic, linux-arm-kernel, martin.blumenstingl, narmstrong, stefan, Lucas Tanure Reserved regions can be described in FDT and device trees, but FDT doesn't provide the related flags, like nomap. So allow the kernel to mark regions where the base and size received from the device tree are the same as the base and region on FDT. Here we trust that the device tree has a more updated description of the region than the one received from FDT. Signed-off-by: Lucas Tanure <tanure@linux.com> --- drivers/of/fdt.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index d1a68b6d03b3..754a7ea4f45c 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -482,11 +482,13 @@ static int __init early_init_dt_reserve_memory(phys_addr_t base, if (nomap) { /* * If the memory is already reserved (by another region), we - * should not allow it to be marked nomap, but don't worry - * if the region isn't memory as it won't be mapped. + * should not allow it to be marked nomap, unless is the exact same region + * (same base and size), which the kernel knows better and should be allowed to mark + * it as nomap. + * But don't worry if the region isn't memory as it won't be mapped. */ - if (memblock_overlaps_region(&memblock.memory, base, size) && - memblock_is_region_reserved(base, size)) + if (memblock_overlaps_region(&memblock.memory, base, size) == MEMBLOCK_OVERLAPS && + memblock_is_region_reserved(base, size) == MEMBLOCK_OVERLAPS) return -EBUSY; return memblock_mark_nomap(base, size); -- 2.40.0 ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 2/2] of: fdt: Allow the kernel to mark nomap regions received from fdt 2023-04-06 15:14 ` [PATCH 2/2] of: fdt: Allow the kernel to mark nomap regions received from fdt Lucas Tanure @ 2023-04-06 15:48 ` Rob Herring 2023-04-06 16:06 ` Neil Armstrong 0 siblings, 1 reply; 5+ messages in thread From: Rob Herring @ 2023-04-06 15:48 UTC (permalink / raw) To: Lucas Tanure Cc: Frank Rowand, Mike Rapoport, Andrew Morton, devicetree, linux-kernel, linux-mm, jbrunet, linux-amlogic, linux-arm-kernel, martin.blumenstingl, narmstrong, stefan On Thu, Apr 6, 2023 at 10:14 AM Lucas Tanure <tanure@linux.com> wrote: > > Reserved regions can be described in FDT and device trees, but FDT doesn't > provide the related flags, like nomap. It took me a minute to understand what you meant by FDT vs. device trees. Use the exact things you are talking about: /memreserve/ and /reserved-memory node. > So allow the kernel to mark regions where the base and size received from > the device tree are the same as the base and region on FDT. > Here we trust that the device tree has a more updated description of the > region than the one received from FDT. > > Signed-off-by: Lucas Tanure <tanure@linux.com> > --- > drivers/of/fdt.c | 10 ++++++---- > 1 file changed, 6 insertions(+), 4 deletions(-) > > diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c > index d1a68b6d03b3..754a7ea4f45c 100644 > --- a/drivers/of/fdt.c > +++ b/drivers/of/fdt.c > @@ -482,11 +482,13 @@ static int __init early_init_dt_reserve_memory(phys_addr_t base, > if (nomap) { > /* > * If the memory is already reserved (by another region), we > - * should not allow it to be marked nomap, but don't worry > - * if the region isn't memory as it won't be mapped. > + * should not allow it to be marked nomap, unless is the exact same region > + * (same base and size), which the kernel knows better and should be allowed to mark > + * it as nomap. > + * But don't worry if the region isn't memory as it won't be mapped. > */ > - if (memblock_overlaps_region(&memblock.memory, base, size) && > - memblock_is_region_reserved(base, size)) > + if (memblock_overlaps_region(&memblock.memory, base, size) == MEMBLOCK_OVERLAPS && > + memblock_is_region_reserved(base, size) == MEMBLOCK_OVERLAPS) Won't this fail to work as IIRC memblock will merge regions when they are adjacent and have the same atrributes. Perhaps instead, the DT code should ignore any /memreserve/ entries that are also in /reserved-memory. I would suggest just reverse the order they are processed, but I suspect that might cause some regression. This code is all fragile especially with platforms putting in 100 regions. Finally, perhaps fix u-boot. The reason the reserved location goes in both places was to support an OS not supporting /reserved-memory. I think that support has been in place for a lot longer than anyone would care about. Rob ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 2/2] of: fdt: Allow the kernel to mark nomap regions received from fdt 2023-04-06 15:48 ` Rob Herring @ 2023-04-06 16:06 ` Neil Armstrong 0 siblings, 0 replies; 5+ messages in thread From: Neil Armstrong @ 2023-04-06 16:06 UTC (permalink / raw) To: Rob Herring, Lucas Tanure Cc: Frank Rowand, Mike Rapoport, Andrew Morton, devicetree, linux-kernel, linux-mm, jbrunet, linux-amlogic, linux-arm-kernel, martin.blumenstingl, narmstrong, stefan On 06/04/2023 17:48, Rob Herring wrote: > On Thu, Apr 6, 2023 at 10:14 AM Lucas Tanure <tanure@linux.com> wrote: >> >> Reserved regions can be described in FDT and device trees, but FDT doesn't >> provide the related flags, like nomap. > > It took me a minute to understand what you meant by FDT vs. device > trees. Use the exact things you are talking about: /memreserve/ and > /reserved-memory node. > >> So allow the kernel to mark regions where the base and size received from >> the device tree are the same as the base and region on FDT. >> Here we trust that the device tree has a more updated description of the >> region than the one received from FDT. >> >> Signed-off-by: Lucas Tanure <tanure@linux.com> >> --- >> drivers/of/fdt.c | 10 ++++++---- >> 1 file changed, 6 insertions(+), 4 deletions(-) >> >> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c >> index d1a68b6d03b3..754a7ea4f45c 100644 >> --- a/drivers/of/fdt.c >> +++ b/drivers/of/fdt.c >> @@ -482,11 +482,13 @@ static int __init early_init_dt_reserve_memory(phys_addr_t base, >> if (nomap) { >> /* >> * If the memory is already reserved (by another region), we >> - * should not allow it to be marked nomap, but don't worry >> - * if the region isn't memory as it won't be mapped. >> + * should not allow it to be marked nomap, unless is the exact same region >> + * (same base and size), which the kernel knows better and should be allowed to mark >> + * it as nomap. >> + * But don't worry if the region isn't memory as it won't be mapped. >> */ >> - if (memblock_overlaps_region(&memblock.memory, base, size) && >> - memblock_is_region_reserved(base, size)) >> + if (memblock_overlaps_region(&memblock.memory, base, size) == MEMBLOCK_OVERLAPS && >> + memblock_is_region_reserved(base, size) == MEMBLOCK_OVERLAPS) > > Won't this fail to work as IIRC memblock will merge regions when they > are adjacent and have the same atrributes. > > Perhaps instead, the DT code should ignore any /memreserve/ entries > that are also in /reserved-memory. > > I would suggest just reverse the order they are processed, but I > suspect that might cause some regression. This code is all fragile > especially with platforms putting in 100 regions. > > Finally, perhaps fix u-boot. The reason the reserved location goes in > both places was to support an OS not supporting /reserved-memory. I > think that support has been in place for a lot longer than anyone > would care about. Fixing U-Boot won't fix already tagged and in-the-field mainline u-boot releases that adds /memreserve/ entries, so yes u-boot should be definitely fixed but Linux should ignore the /memreserve/ entries when they matches an /reserved-memory node like when the U-Boot /memreserve/ code was added. Neil > > Rob > > _______________________________________________ > linux-amlogic mailing list > linux-amlogic@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-amlogic ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2023-04-06 16:06 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2023-04-06 15:14 [PATCH 0/2] Fix Random Kernel panic from when fail to reserve memory Lucas Tanure 2023-04-06 15:14 ` [PATCH 1/2] memblock: Differentiate regions overlap from both regions being the same Lucas Tanure 2023-04-06 15:14 ` [PATCH 2/2] of: fdt: Allow the kernel to mark nomap regions received from fdt Lucas Tanure 2023-04-06 15:48 ` Rob Herring 2023-04-06 16:06 ` Neil Armstrong
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox