Bug#993612: Patch "of/address: Return an error when no valid dma-ranges are found" has been added to the 5.15-stable tree
This is a note to let you know that I've just added the patch titled of/address: Return an error when no valid dma-ranges are found to the 5.15-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: of-address-return-an-error-when-no-valid-dma-ranges-are-found.patch and it can be found in the queue-5.15 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let know about it. >From f6933c01e42d2fc83b9133ed755609e4aac6eadd Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 28 Jan 2023 17:47:50 + Subject: of/address: Return an error when no valid dma-ranges are found From: Mark Brown commit f6933c01e42d2fc83b9133ed755609e4aac6eadd upstream. Commit 7a8b64d17e35 ("of/address: use range parser for of_dma_get_range") converted the parsing of dma-range properties to use code shared with the PCI range parser. The intent was to introduce no functional changes however in the case where we fail to translate the first resource instead of returning -EINVAL the new code we return 0. Restore the previous behaviour by returning an error if we find no valid ranges, the original code only handled the first range but subsequently support for parsing all supplied ranges was added. This avoids confusing code using the parsed ranges which doesn't expect to successfully parse ranges but have only a list terminator returned, this fixes breakage with so far as I can tell all DMA for on SoC devices on the Socionext Synquacer platform which has a firmware supplied DT. A bisect identified the original conversion as triggering the issues there. Fixes: 7a8b64d17e35 ("of/address: use range parser for of_dma_get_range") Signed-off-by: Mark Brown Cc: Luca Di Stefano Cc: 993...@bugs.debian.org Cc: sta...@kernel.org Link: https://lore.kernel.org/r/20230126-synquacer-boot-v2-1-cb80fd23c...@kernel.org Signed-off-by: Rob Herring Signed-off-by: Greg Kroah-Hartman --- drivers/of/address.c | 21 +++-- 1 file changed, 15 insertions(+), 6 deletions(-) --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -963,8 +963,19 @@ int of_dma_get_range(struct device_node } of_dma_range_parser_init(, node); - for_each_of_range(, ) + for_each_of_range(, ) { + if (range.cpu_addr == OF_BAD_ADDR) { + pr_err("translation of DMA address(%llx) to CPU address failed node(%pOF)\n", + range.bus_addr, node); + continue; + } num_ranges++; + } + + if (!num_ranges) { + ret = -EINVAL; + goto out; + } r = kcalloc(num_ranges + 1, sizeof(*r), GFP_KERNEL); if (!r) { @@ -973,18 +984,16 @@ int of_dma_get_range(struct device_node } /* -* Record all info in the generic DMA ranges array for struct device. +* Record all info in the generic DMA ranges array for struct device, +* returning an error if we don't find any parsable ranges. */ *map = r; of_dma_range_parser_init(, node); for_each_of_range(, ) { pr_debug("dma_addr(%llx) cpu_addr(%llx) size(%llx)\n", range.bus_addr, range.cpu_addr, range.size); - if (range.cpu_addr == OF_BAD_ADDR) { - pr_err("translation of DMA address(%llx) to CPU address failed node(%pOF)\n", - range.bus_addr, node); + if (range.cpu_addr == OF_BAD_ADDR) continue; - } r->cpu_start = range.cpu_addr; r->dma_start = range.bus_addr; r->size = range.size; Patches currently in stable-queue which might be from broo...@kernel.org are queue-5.15/of-address-return-an-error-when-no-valid-dma-ranges-are-found.patch
Bug#993612: Patch "of/address: Return an error when no valid dma-ranges are found" has been added to the 5.10-stable tree
This is a note to let you know that I've just added the patch titled of/address: Return an error when no valid dma-ranges are found to the 5.10-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: of-address-return-an-error-when-no-valid-dma-ranges-are-found.patch and it can be found in the queue-5.10 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let know about it. >From f6933c01e42d2fc83b9133ed755609e4aac6eadd Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 28 Jan 2023 17:47:50 + Subject: of/address: Return an error when no valid dma-ranges are found From: Mark Brown commit f6933c01e42d2fc83b9133ed755609e4aac6eadd upstream. Commit 7a8b64d17e35 ("of/address: use range parser for of_dma_get_range") converted the parsing of dma-range properties to use code shared with the PCI range parser. The intent was to introduce no functional changes however in the case where we fail to translate the first resource instead of returning -EINVAL the new code we return 0. Restore the previous behaviour by returning an error if we find no valid ranges, the original code only handled the first range but subsequently support for parsing all supplied ranges was added. This avoids confusing code using the parsed ranges which doesn't expect to successfully parse ranges but have only a list terminator returned, this fixes breakage with so far as I can tell all DMA for on SoC devices on the Socionext Synquacer platform which has a firmware supplied DT. A bisect identified the original conversion as triggering the issues there. Fixes: 7a8b64d17e35 ("of/address: use range parser for of_dma_get_range") Signed-off-by: Mark Brown Cc: Luca Di Stefano Cc: 993...@bugs.debian.org Cc: sta...@kernel.org Link: https://lore.kernel.org/r/20230126-synquacer-boot-v2-1-cb80fd23c...@kernel.org Signed-off-by: Rob Herring Signed-off-by: Greg Kroah-Hartman --- drivers/of/address.c | 21 +++-- 1 file changed, 15 insertions(+), 6 deletions(-) --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -990,8 +990,19 @@ int of_dma_get_range(struct device_node } of_dma_range_parser_init(, node); - for_each_of_range(, ) + for_each_of_range(, ) { + if (range.cpu_addr == OF_BAD_ADDR) { + pr_err("translation of DMA address(%llx) to CPU address failed node(%pOF)\n", + range.bus_addr, node); + continue; + } num_ranges++; + } + + if (!num_ranges) { + ret = -EINVAL; + goto out; + } r = kcalloc(num_ranges + 1, sizeof(*r), GFP_KERNEL); if (!r) { @@ -1000,18 +1011,16 @@ int of_dma_get_range(struct device_node } /* -* Record all info in the generic DMA ranges array for struct device. +* Record all info in the generic DMA ranges array for struct device, +* returning an error if we don't find any parsable ranges. */ *map = r; of_dma_range_parser_init(, node); for_each_of_range(, ) { pr_debug("dma_addr(%llx) cpu_addr(%llx) size(%llx)\n", range.bus_addr, range.cpu_addr, range.size); - if (range.cpu_addr == OF_BAD_ADDR) { - pr_err("translation of DMA address(%llx) to CPU address failed node(%pOF)\n", - range.bus_addr, node); + if (range.cpu_addr == OF_BAD_ADDR) continue; - } r->cpu_start = range.cpu_addr; r->dma_start = range.bus_addr; r->size = range.size; Patches currently in stable-queue which might be from broo...@kernel.org are queue-5.10/of-address-return-an-error-when-no-valid-dma-ranges-are-found.patch
Bug#993612: Patch "of/address: Return an error when no valid dma-ranges are found" has been added to the 6.1-stable tree
This is a note to let you know that I've just added the patch titled of/address: Return an error when no valid dma-ranges are found to the 6.1-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: of-address-return-an-error-when-no-valid-dma-ranges-are-found.patch and it can be found in the queue-6.1 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let know about it. >From f6933c01e42d2fc83b9133ed755609e4aac6eadd Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 28 Jan 2023 17:47:50 + Subject: of/address: Return an error when no valid dma-ranges are found From: Mark Brown commit f6933c01e42d2fc83b9133ed755609e4aac6eadd upstream. Commit 7a8b64d17e35 ("of/address: use range parser for of_dma_get_range") converted the parsing of dma-range properties to use code shared with the PCI range parser. The intent was to introduce no functional changes however in the case where we fail to translate the first resource instead of returning -EINVAL the new code we return 0. Restore the previous behaviour by returning an error if we find no valid ranges, the original code only handled the first range but subsequently support for parsing all supplied ranges was added. This avoids confusing code using the parsed ranges which doesn't expect to successfully parse ranges but have only a list terminator returned, this fixes breakage with so far as I can tell all DMA for on SoC devices on the Socionext Synquacer platform which has a firmware supplied DT. A bisect identified the original conversion as triggering the issues there. Fixes: 7a8b64d17e35 ("of/address: use range parser for of_dma_get_range") Signed-off-by: Mark Brown Cc: Luca Di Stefano Cc: 993...@bugs.debian.org Cc: sta...@kernel.org Link: https://lore.kernel.org/r/20230126-synquacer-boot-v2-1-cb80fd23c...@kernel.org Signed-off-by: Rob Herring Signed-off-by: Greg Kroah-Hartman --- drivers/of/address.c | 21 +++-- 1 file changed, 15 insertions(+), 6 deletions(-) --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -965,8 +965,19 @@ int of_dma_get_range(struct device_node } of_dma_range_parser_init(, node); - for_each_of_range(, ) + for_each_of_range(, ) { + if (range.cpu_addr == OF_BAD_ADDR) { + pr_err("translation of DMA address(%llx) to CPU address failed node(%pOF)\n", + range.bus_addr, node); + continue; + } num_ranges++; + } + + if (!num_ranges) { + ret = -EINVAL; + goto out; + } r = kcalloc(num_ranges + 1, sizeof(*r), GFP_KERNEL); if (!r) { @@ -975,18 +986,16 @@ int of_dma_get_range(struct device_node } /* -* Record all info in the generic DMA ranges array for struct device. +* Record all info in the generic DMA ranges array for struct device, +* returning an error if we don't find any parsable ranges. */ *map = r; of_dma_range_parser_init(, node); for_each_of_range(, ) { pr_debug("dma_addr(%llx) cpu_addr(%llx) size(%llx)\n", range.bus_addr, range.cpu_addr, range.size); - if (range.cpu_addr == OF_BAD_ADDR) { - pr_err("translation of DMA address(%llx) to CPU address failed node(%pOF)\n", - range.bus_addr, node); + if (range.cpu_addr == OF_BAD_ADDR) continue; - } r->cpu_start = range.cpu_addr; r->dma_start = range.bus_addr; r->size = range.size; Patches currently in stable-queue which might be from broo...@kernel.org are queue-6.1/of-address-return-an-error-when-no-valid-dma-ranges-are-found.patch
Bug#993612: [PATCH] of/address: Return an error when no valid dma-ranges are found
On Fri, Jan 27, 2023 at 12:37:35PM -0600, Rob Herring wrote: > Looks to me like we are leaking 'r' with this change. Oh, probably now that you mention it. Usually the OF code keeps track of more things than I expect... > Wouldn't this change work: > diff --git a/drivers/of/address.c b/drivers/of/address.c > index c34ac33b7338..f43311f01c32 100644 > --- a/drivers/of/address.c > +++ b/drivers/of/address.c > @@ -968,6 +968,11 @@ int of_dma_get_range(struct device_node *np, > const struct bus_dma_region **map) > for_each_of_range(, ) > num_ranges++; > > + if (!num_ranges) { > + ret = -EINVAL; > + goto out; > + } > + Not as-is, there is a range counted by that first loop but it's then rejected by the check in the second loop for cpu_addr == OF_BAD_ADDR. We'd need to add a similar check in the first loop. It should work otherwise though and avoids doing the allocation in this case. signature.asc Description: PGP signature
Bug#993612: [PATCH] of/address: Return an error when no valid dma-ranges are found
On Thu, Jan 26, 2023 at 10:27 AM Mark Brown wrote: > > Commit 7a8b64d17e35 ("of/address: use range parser for of_dma_get_range") > converted the parsing of dma-range properties to use code shared with the > PCI range parser. The intent was to introduce no functional changes however > in the case where we fail to translate the first resource instead of > returning -EINVAL the new code we return 0. Restore the previous behaviour > by returning an error if we find no valid ranges, the original code only > handled the first range but subsequently support for parsing all supplied > ranges was added. > > This avoids confusing code using the parsed ranges which doesn't expect to > successfully parse ranges but have only a list terminator returned, this > fixes breakage with so far as I can tell all DMA for on SoC devices on the > Socionext Synquacer platform which has a firmware supplied DT. A bisect > identified the original conversion as triggering the issues there. Looks like maybe it was fixed by Colin in commit f49c7faf776f ("of/address: check for invalid range.cpu_addr") as that commit refers to Synquacer. But then was it possibly reintroduced by commit e0d072782c73 ("dma-mapping: introduce DMA range map, supplanting dma_pfn_offset")? > Fixes: 7a8b64d17e35 ("of/address: use range parser for of_dma_get_range") > Signed-off-by: Mark Brown > Cc: Luca Di Stefano > Cc: 993...@bugs.debian.org > Cc: sta...@kernel.org > --- > drivers/of/address.c | 5 - > 1 file changed, 4 insertions(+), 1 deletion(-) > > diff --git a/drivers/of/address.c b/drivers/of/address.c > index c34ac33b7338..21342223b8e5 100644 > --- a/drivers/of/address.c > +++ b/drivers/of/address.c > @@ -975,10 +975,12 @@ int of_dma_get_range(struct device_node *np, const > struct bus_dma_region **map) > } > > /* > -* Record all info in the generic DMA ranges array for struct device. > +* Record all info in the generic DMA ranges array for struct device, > +* returning an error if we don't find any parsable ranges. > */ > *map = r; > of_dma_range_parser_init(, node); > + ret = -EINVAL; Looks to me like we are leaking 'r' with this change. Wouldn't this change work: diff --git a/drivers/of/address.c b/drivers/of/address.c index c34ac33b7338..f43311f01c32 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -968,6 +968,11 @@ int of_dma_get_range(struct device_node *np, const struct bus_dma_region **map) for_each_of_range(, ) num_ranges++; + if (!num_ranges) { + ret = -EINVAL; + goto out; + } + r = kcalloc(num_ranges + 1, sizeof(*r), GFP_KERNEL); if (!r) { ret = -ENOMEM;
Bug#993612: [PATCH] of/address: Return an error when no valid dma-ranges are found
Commit 7a8b64d17e35 ("of/address: use range parser for of_dma_get_range") converted the parsing of dma-range properties to use code shared with the PCI range parser. The intent was to introduce no functional changes however in the case where we fail to translate the first resource instead of returning -EINVAL the new code we return 0. Restore the previous behaviour by returning an error if we find no valid ranges, the original code only handled the first range but subsequently support for parsing all supplied ranges was added. This avoids confusing code using the parsed ranges which doesn't expect to successfully parse ranges but have only a list terminator returned, this fixes breakage with so far as I can tell all DMA for on SoC devices on the Socionext Synquacer platform which has a firmware supplied DT. A bisect identified the original conversion as triggering the issues there. Fixes: 7a8b64d17e35 ("of/address: use range parser for of_dma_get_range") Signed-off-by: Mark Brown Cc: Luca Di Stefano Cc: 993...@bugs.debian.org Cc: sta...@kernel.org --- drivers/of/address.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/of/address.c b/drivers/of/address.c index c34ac33b7338..21342223b8e5 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -975,10 +975,12 @@ int of_dma_get_range(struct device_node *np, const struct bus_dma_region **map) } /* -* Record all info in the generic DMA ranges array for struct device. +* Record all info in the generic DMA ranges array for struct device, +* returning an error if we don't find any parsable ranges. */ *map = r; of_dma_range_parser_init(, node); + ret = -EINVAL; for_each_of_range(, ) { pr_debug("dma_addr(%llx) cpu_addr(%llx) size(%llx)\n", range.bus_addr, range.cpu_addr, range.size); @@ -992,6 +994,7 @@ int of_dma_get_range(struct device_node *np, const struct bus_dma_region **map) r->size = range.size; r->offset = range.cpu_addr - range.bus_addr; r++; + ret = 0; } out: of_node_put(node); --- base-commit: 1b929c02afd37871d5afb9d498426f83432e71c2 change-id: 20230126-synquacer-boot-243bd1b87f64 Best regards, -- Mark Brown