diff --git a/drivers/of/address.c b/drivers/of/address.c index cf4aab11e9b1..499d37ceae21 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -753,6 +753,7 @@ EXPORT_SYMBOL(of_property_read_reg); static int parser_init(struct of_pci_range_parser *parser, struct device_node *node, const char *name) { + const __be32 *range; int rlen; parser->node = node; @@ -761,12 +762,20 @@ static int parser_init(struct of_pci_range_parser *parser, parser->ns = of_bus_n_size_cells(node); parser->dma = !strcmp(name, "dma-ranges"); parser->bus = of_match_bus(node); + parser->range = NULL; + parser->end = NULL; - parser->range = of_get_property(node, name, &rlen); - if (parser->range == NULL) + range = of_get_property(node, name, &rlen); + if (!range) return -ENOENT; - parser->end = parser->range + rlen / sizeof(__be32); + if (!parser->bus || + !OF_CHECK_COUNTS(parser->na, parser->ns) || + !OF_CHECK_ADDR_COUNT(parser->pna)) + return -EINVAL; + + parser->range = range; + parser->end = range + rlen / sizeof(__be32); return 0; } @@ -792,7 +801,7 @@ struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser, int na = parser->na; int ns = parser->ns; int np = parser->pna + na + ns; - int busflag_na = parser->bus->flag_cells; + int busflag_na; if (!range) return NULL; @@ -800,6 +809,8 @@ struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser, if (!parser->range || parser->range + np > parser->end) return NULL; + busflag_na = parser->bus->flag_cells; + range->flags = parser->bus->get_flags(parser->range); range->bus_addr = of_read_number(parser->range + busflag_na, na - busflag_na); @@ -976,8 +987,7 @@ phys_addr_t __init of_dma_get_max_cpu_address(struct device_node *np) np = of_root; ranges = of_get_property(np, "dma-ranges", &len); - if (ranges && len) { - of_dma_range_parser_init(&parser, np); + if (ranges && len && !of_dma_range_parser_init(&parser, np)) { for_each_of_range(&parser, &range) if (range.cpu_addr + range.size > cpu_end) cpu_end = range.cpu_addr + range.size - 1; diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c index 82222bd45ac6..42e3e2d8a2b8 100644 --- a/drivers/of/of_reserved_mem.c +++ b/drivers/of/of_reserved_mem.c @@ -359,6 +359,7 @@ int __init fdt_scan_reserved_mem(void) err = __reserved_mem_reserve_reg(child, uname); if (!err) count++; + /* * Save the nodes for the dynamically-placed regions * into an array which will be used for allocation right @@ -366,10 +367,17 @@ int __init fdt_scan_reserved_mem(void) * or marked as no-map. This is done to avoid dynamically * allocating from one of the statically-placed regions. */ - if (err == -ENOENT && of_get_flat_dt_prop(child, "size", NULL)) { - dynamic_nodes[dynamic_nodes_cnt] = child; - dynamic_nodes_cnt++; + if (err != -ENOENT || !of_get_flat_dt_prop(child, "size", NULL)) + continue; + + if (dynamic_nodes_cnt == MAX_RESERVED_REGIONS) { + pr_err("too many defined dynamic regions, skip '%s'\n", + uname); + continue; } + + dynamic_nodes[dynamic_nodes_cnt] = child; + dynamic_nodes_cnt++; } for (int i = 0; i < dynamic_nodes_cnt; i++) { const char *uname;