Commit 9cc2323feebdde500f50f7abb855045dbde765cb

Authored by Simon Goldschmidt
Committed by Tom Rini
1 parent e3b4fc9598

lmb: handle more than one DRAM BANK

This fixes the automatic lmb initialization and reservation for boards
with more than one DRAM bank.

This fixes the CVE-2018-18439 and -18440 fixes that only allowed to load
files into the firs DRAM bank from fs and via tftp.

Found-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
Tested-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Reviewed-by: Simon Glass <sjg@chromium.org>

Showing 5 changed files with 41 additions and 13 deletions Side-by-side Diff

... ... @@ -59,8 +59,8 @@
59 59 mem_start = env_get_bootm_low();
60 60 mem_size = env_get_bootm_size();
61 61  
62   - lmb_init_and_reserve(&images->lmb, (phys_addr_t)mem_start, mem_size,
63   - NULL);
  62 + lmb_init_and_reserve_range(&images->lmb, (phys_addr_t)mem_start,
  63 + mem_size, NULL);
64 64 }
65 65 #else
66 66 #define lmb_reserve(lmb, base, size)
... ... @@ -454,8 +454,7 @@
454 454 if (len && len < read_len)
455 455 read_len = len;
456 456  
457   - lmb_init_and_reserve(&lmb, gd->bd->bi_dram[0].start,
458   - gd->bd->bi_dram[0].size, (void *)gd->fdt_blob);
  457 + lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob);
459 458 lmb_dump_all(&lmb);
460 459  
461 460 if (lmb_alloc_addr(&lmb, addr, read_len) == addr)
... ... @@ -4,6 +4,8 @@
4 4 #ifdef __KERNEL__
5 5  
6 6 #include <asm/types.h>
  7 +#include <asm/u-boot.h>
  8 +
7 9 /*
8 10 * Logical memory blocks.
9 11 *
... ... @@ -29,8 +31,9 @@
29 31 };
30 32  
31 33 extern void lmb_init(struct lmb *lmb);
32   -extern void lmb_init_and_reserve(struct lmb *lmb, phys_addr_t base,
33   - phys_size_t size, void *fdt_blob);
  34 +extern void lmb_init_and_reserve(struct lmb *lmb, bd_t *bd, void *fdt_blob);
  35 +extern void lmb_init_and_reserve_range(struct lmb *lmb, phys_addr_t base,
  36 + phys_size_t size, void *fdt_blob);
34 37 extern long lmb_add(struct lmb *lmb, phys_addr_t base, phys_size_t size);
35 38 extern long lmb_reserve(struct lmb *lmb, phys_addr_t base, phys_size_t size);
36 39 extern phys_addr_t lmb_alloc(struct lmb *lmb, phys_size_t size, ulong align);
... ... @@ -98,17 +98,44 @@
98 98 lmb->reserved.size = 0;
99 99 }
100 100  
101   -/* Initialize the struct, add memory and call arch/board reserve functions */
102   -void lmb_init_and_reserve(struct lmb *lmb, phys_addr_t base, phys_size_t size,
103   - void *fdt_blob)
  101 +static void lmb_reserve_common(struct lmb *lmb, void *fdt_blob)
104 102 {
105   - lmb_init(lmb);
106   - lmb_add(lmb, base, size);
107 103 arch_lmb_reserve(lmb);
108 104 board_lmb_reserve(lmb);
109 105  
110 106 if (IMAGE_ENABLE_OF_LIBFDT && fdt_blob)
111 107 boot_fdt_add_mem_rsv_regions(lmb, fdt_blob);
  108 +}
  109 +
  110 +/* Initialize the struct, add memory and call arch/board reserve functions */
  111 +void lmb_init_and_reserve(struct lmb *lmb, bd_t *bd, void *fdt_blob)
  112 +{
  113 +#ifdef CONFIG_NR_DRAM_BANKS
  114 + int i;
  115 +#endif
  116 +
  117 + lmb_init(lmb);
  118 +#ifdef CONFIG_NR_DRAM_BANKS
  119 + for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
  120 + if (bd->bi_dram[i].size) {
  121 + lmb_add(lmb, bd->bi_dram[i].start,
  122 + bd->bi_dram[i].size);
  123 + }
  124 + }
  125 +#else
  126 + if (bd->bi_memsize)
  127 + lmb_add(lmb, bd->bi_memstart, bd->bi_memsize);
  128 +#endif
  129 + lmb_reserve_common(lmb, fdt_blob);
  130 +}
  131 +
  132 +/* Initialize the struct, add memory and call arch/board reserve functions */
  133 +void lmb_init_and_reserve_range(struct lmb *lmb, phys_addr_t base,
  134 + phys_size_t size, void *fdt_blob)
  135 +{
  136 + lmb_init(lmb);
  137 + lmb_add(lmb, base, size);
  138 + lmb_reserve_common(lmb, fdt_blob);
112 139 }
113 140  
114 141 /* This routine called with relocation disabled. */
... ... @@ -606,8 +606,7 @@
606 606 struct lmb lmb;
607 607 phys_size_t max_size;
608 608  
609   - lmb_init_and_reserve(&lmb, gd->bd->bi_dram[0].start,
610   - gd->bd->bi_dram[0].size, (void *)gd->fdt_blob);
  609 + lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob);
611 610  
612 611 max_size = lmb_get_free_size(&lmb, load_addr);
613 612 if (!max_size)