0004-ARM-9124-1-uncompress-Parse-linux-usable-memory-rang.patch 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. From 48342ae751c797ac73ac9c894b3f312df18ffd21 Mon Sep 17 00:00:00 2001
  2. From: Geert Uytterhoeven <[email protected]>
  3. Date: Wed, 15 Sep 2021 13:46:20 +0100
  4. Subject: [PATCH] ARM: 9124/1: uncompress: Parse "linux,usable-memory-range" DT
  5. property
  6. Add support for parsing the "linux,usable-memory-range" DT property.
  7. This property is used to describe the usable memory reserved for the
  8. crash dump kernel, and thus makes the memory reservation explicit.
  9. If present, Linux no longer needs to mask the program counter, and rely
  10. on the "mem=" kernel parameter to obtain the start and size of usable
  11. memory.
  12. For backwards compatibility, the traditional method to derive the start
  13. of memory is still used if "linux,usable-memory-range" is absent.
  14. Signed-off-by: Geert Uytterhoeven <[email protected]>
  15. Signed-off-by: Russell King (Oracle) <[email protected]>
  16. Signed-off-by: Daniel Danzberger <[email protected]>
  17. ---
  18. .../arm/boot/compressed/fdt_check_mem_start.c | 48 ++++++++++++++++---
  19. 1 file changed, 42 insertions(+), 6 deletions(-)
  20. --- a/arch/arm/boot/compressed/fdt_check_mem_start.c
  21. +++ b/arch/arm/boot/compressed/fdt_check_mem_start.c
  22. @@ -55,16 +55,17 @@ static uint64_t get_val(const fdt32_t *c
  23. * DTB, and, if out-of-range, replace it by the real start address.
  24. * To preserve backwards compatibility (systems reserving a block of memory
  25. * at the start of physical memory, kdump, ...), the traditional method is
  26. - * always used if it yields a valid address.
  27. + * used if it yields a valid address, unless the "linux,usable-memory-range"
  28. + * property is present.
  29. *
  30. * Return value: start address of physical memory to use
  31. */
  32. uint32_t fdt_check_mem_start(uint32_t mem_start, const void *fdt)
  33. {
  34. - uint32_t addr_cells, size_cells, base;
  35. + uint32_t addr_cells, size_cells, usable_base, base;
  36. uint32_t fdt_mem_start = 0xffffffff;
  37. - const fdt32_t *reg, *endp;
  38. - uint64_t size, end;
  39. + const fdt32_t *usable, *reg, *endp;
  40. + uint64_t size, usable_end, end;
  41. const char *type;
  42. int offset, len;
  43. @@ -80,6 +81,27 @@ uint32_t fdt_check_mem_start(uint32_t me
  44. if (addr_cells > 2 || size_cells > 2)
  45. return mem_start;
  46. + /*
  47. + * Usable memory in case of a crash dump kernel
  48. + * This property describes a limitation: memory within this range is
  49. + * only valid when also described through another mechanism
  50. + */
  51. + usable = get_prop(fdt, "/chosen", "linux,usable-memory-range",
  52. + (addr_cells + size_cells) * sizeof(fdt32_t));
  53. + if (usable) {
  54. + size = get_val(usable + addr_cells, size_cells);
  55. + if (!size)
  56. + return mem_start;
  57. +
  58. + if (addr_cells > 1 && fdt32_ld(usable)) {
  59. + /* Outside 32-bit address space */
  60. + return mem_start;
  61. + }
  62. +
  63. + usable_base = fdt32_ld(usable + addr_cells - 1);
  64. + usable_end = usable_base + size;
  65. + }
  66. +
  67. /* Walk all memory nodes and regions */
  68. for (offset = fdt_next_node(fdt, -1, NULL); offset >= 0;
  69. offset = fdt_next_node(fdt, offset, NULL)) {
  70. @@ -107,7 +129,20 @@ uint32_t fdt_check_mem_start(uint32_t me
  71. base = fdt32_ld(reg + addr_cells - 1);
  72. end = base + size;
  73. - if (mem_start >= base && mem_start < end) {
  74. + if (usable) {
  75. + /*
  76. + * Clip to usable range, which takes precedence
  77. + * over mem_start
  78. + */
  79. + if (base < usable_base)
  80. + base = usable_base;
  81. +
  82. + if (end > usable_end)
  83. + end = usable_end;
  84. +
  85. + if (end <= base)
  86. + continue;
  87. + } else if (mem_start >= base && mem_start < end) {
  88. /* Calculated address is valid, use it */
  89. return mem_start;
  90. }
  91. @@ -123,7 +158,8 @@ uint32_t fdt_check_mem_start(uint32_t me
  92. }
  93. /*
  94. - * The calculated address is not usable.
  95. + * The calculated address is not usable, or was overridden by the
  96. + * "linux,usable-memory-range" property.
  97. * Use the lowest usable physical memory address from the DTB instead,
  98. * and make sure this is a multiple of 2 MiB for phys/virt patching.
  99. */