In message <4be9102c.6040...@axio.ms> you wrote:
> 
> add_dyn_reconf_usable_mem_property() iterates over memory spans
> in /ibm,dynamic-reconfiguration-memory/ibm,dynamic-memory and intersects
> these with usablemem_rgns ranges.  Not only did it seem to write
> null properties for every range that didn't match, but it used an unchecked
> fixed-size array which will overrun on machines with lots of LMBs.
> 
> This patch stops add_dyn_reconf_usable_mem_property() from adding null ranges
> to the linux,drconf-usable-memory property and removes its fixed-size array,
> as well as the array in add_usable_mem_property, in lieu of malloc/realloc/fr
ee.
> 

Thanks matt!

Acked-by: Michael Neuling <mi...@neuling.org>


> Signed-off-by: Matt Evans <m...@ozlabs.org>
> ---
>  kexec/arch/ppc64/fs2dt.c |   66 +++++++++++++++++++++++++++++++++++++-------
-
>  1 files changed, 54 insertions(+), 12 deletions(-)
> 
> diff --git a/kexec/arch/ppc64/fs2dt.c b/kexec/arch/ppc64/fs2dt.c
> index 762bf04..7470132 100644
> --- a/kexec/arch/ppc64/fs2dt.c
> +++ b/kexec/arch/ppc64/fs2dt.c
> @@ -37,7 +37,7 @@
>  #define NAMESPACE 16384              /* max bytes for property names */
>  #define INIT_TREE_WORDS 65536        /* Initial num words for prop values */
>  #define MEMRESERVE 256               /* max number of reserved memory blocks
 */
> -#define MAX_MEMORY_RANGES 1024
> +#define MEM_RANGE_CHUNK_SZ 2048 /* Initial num dwords for mem ranges */
>  
>  static char pathname[MAXPATH], *pathstart;
>  static char propnames[NAMESPACE] = { 0 };
> @@ -148,7 +148,8 @@ static void add_dyn_reconf_usable_mem_property(int fd)
>  {
>       char fname[MAXPATH], *bname;
>       uint64_t buf[32];
> -     uint64_t ranges[2*MAX_MEMORY_RANGES];
> +     uint64_t *ranges;
> +     int ranges_size = MEM_RANGE_CHUNK_SZ;
>       uint64_t base, end, loc_base, loc_end;
>       size_t i, rngs_cnt, range;
>       int rlen = 0;
> @@ -165,6 +166,11 @@ static void add_dyn_reconf_usable_mem_property(int fd)
>               die("unrecoverable error: error seeking in \"%s\": %s\n",
>                       pathname, strerror(errno));
>  
> +     ranges = malloc(ranges_size*8);
> +     if (!ranges)
> +             die("unrecoverable error: can't alloc %d bytes for ranges.\n",
> +                 ranges_size*8);
> +
>       rlen = 0;
>       for (i = 0; i < num_of_lmbs; i++) {
>               if (read(fd, buf, 24) < 0)
> @@ -180,24 +186,41 @@ static void add_dyn_reconf_usable_mem_property(int fd)
>  
>               rngs_cnt = 0;
>               for (range = 0; range < usablemem_rgns.size; range++) {
> +                     int add = 0;
>                       loc_base = usablemem_rgns.ranges[range].start;
>                       loc_end = usablemem_rgns.ranges[range].end;
>                       if (loc_base >= base && loc_end <= end) {
> -                             ranges[rlen++] = loc_base;
> -                             ranges[rlen++] = loc_end - loc_base;
> -                             rngs_cnt++;
> +                             add = 1;
>                       } else if (base < loc_end && end > loc_base) {
>                               if (loc_base < base)
>                                       loc_base = base;
>                               if (loc_end > end)
>                                       loc_end = end;
> +                             add = 1;
> +                     }
> +
> +                     if (add) {
> +                             if (rlen >= (ranges_size-2)) {
> +                                     ranges_size += MEM_RANGE_CHUNK_SZ;
> +                                     ranges = realloc(ranges, ranges_size*8)
;
> +                                     if (!ranges)
> +                                             die("unrecoverable error: can't
"
> +                                                 " realloc %d bytes for"
> +                                                 " ranges.\n",
> +                                                 ranges_size*8);
> +                             }
>                               ranges[rlen++] = loc_base;
>                               ranges[rlen++] = loc_end - loc_base;
>                               rngs_cnt++;
>                       }
>               }
> -             /* Store the count of (base, size) duple */
> -             ranges[tmp_indx] = rngs_cnt;
> +             if (rngs_cnt == 0) {
> +                     /* Don't store anything for unwritten iterations! */
> +                     rlen = tmp_indx;
> +             } else {
> +                     /* Store the count of (base, size) duple */
> +                     ranges[tmp_indx] = rngs_cnt;
> +             }
>       }
>               
>       rlen = rlen * sizeof(uint64_t);
> @@ -210,7 +233,8 @@ static void add_dyn_reconf_usable_mem_property(int fd)
>       *dt++ = propnum("linux,drconf-usable-memory");
>       if ((rlen >= 8) && ((unsigned long)dt & 0x4))
>               dt++;
> -     memcpy(dt, &ranges, rlen);
> +     memcpy(dt, ranges, rlen);
> +     free(ranges);
>       dt += (rlen + 3)/4;
>  }
>  
> @@ -218,7 +242,8 @@ static void add_usable_mem_property(int fd, size_t len)
>  {
>       char fname[MAXPATH], *bname;
>       uint64_t buf[2];
> -     uint64_t ranges[2*MAX_MEMORY_RANGES];
> +     uint64_t *ranges;
> +     int ranges_size = MEM_RANGE_CHUNK_SZ;
>       uint64_t base, end, loc_base, loc_end;
>       size_t range;
>       int rlen = 0;
> @@ -247,17 +272,33 @@ static void add_usable_mem_property(int fd, size_t len)
>       base = buf[0];
>       end = base + buf[1];
>  
> +     ranges = malloc(ranges_size*8);
> +     if (!ranges)
> +             die("unrecoverable error: can't alloc %d bytes for ranges.\n",
> +                 ranges_size*8);
> +
>       for (range = 0; range < usablemem_rgns.size; range++) {
> +             int add = 0;
>               loc_base = usablemem_rgns.ranges[range].start;
>               loc_end = usablemem_rgns.ranges[range].end;
>               if (loc_base >= base && loc_end <= end) {
> -                     ranges[rlen++] = loc_base;
> -                     ranges[rlen++] = loc_end - loc_base;
> +                     add = 1;
>               } else if (base < loc_end && end > loc_base) {
>                       if (loc_base < base)
>                               loc_base = base;
>                       if (loc_end > end)
>                               loc_end = end;
> +                     add = 1;
> +             }
> +             if (add) {
> +                     if (rlen >= (ranges_size-2)) {
> +                             ranges_size += MEM_RANGE_CHUNK_SZ;
> +                             ranges = realloc(ranges, ranges_size*8);
> +                             if (!ranges) 
> +                                     die("unrecoverable error: can't realloc
"
> +                                         "%d bytes for ranges.\n",
> +                                         ranges_size*8);
> +                     }
>                       ranges[rlen++] = loc_base;
>                       ranges[rlen++] = loc_end - loc_base;
>               }
> @@ -283,7 +324,8 @@ static void add_usable_mem_property(int fd, size_t len)
>       *dt++ = propnum("linux,usable-memory");
>       if ((rlen >= 8) && ((unsigned long)dt & 0x4))
>               dt++;
> -     memcpy(dt,&ranges,rlen);
> +     memcpy(dt, ranges, rlen);
> +     free(ranges);
>       dt += (rlen + 3)/4;
>  }
>  
> -- 
> 1.6.3.3
> 
> 
> _______________________________________________
> kexec mailing list
> ke...@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec
> 
_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Reply via email to