of: Miscellaneous fixes and cleanups
cover of: Miscellaneous fixes and cleanups
Hi all,
This patch series contains a fix and two cleanups for the OF code.
Thanks!
Geert Uytterhoeven (3):
of: Fix truncation of memory sizes on 32-bit platforms
of: Remove superfluous casts when printing u64 values
of: kexec: Always use FDT_PROP_INITRD_START and FDT_PROP_INITRD_END
drivers/of/address.c | 14 ++++---------- drivers/of/fdt.c | 14 ++++++-------- drivers/of/kexec.c | 4 ++-- drivers/of/of_reserved_mem.c | 8 ++++---- 4 files changed, 16 insertions(+), 24 deletions(-)
Signature · 12 lines
2.25.1
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus TorvaldsPATCH 1/3 of: Fix truncation of memory sizes on 32-bit platforms
Variable "size" has type "phys_addr_t", which can be either 32-bit or 64-bit on 32-bit systems, while "unsigned long" is always 32-bit on 32-bit systems. Hence the cast in
(unsigned long)size / SZ_1M
may truncate a 64-bit size to 32-bit, as casts have a higher operator precedence than divisions.
Fix this by inverting the order of the cast and division, which should be safe for memory blocks smaller than 4 PiB. Note that the division is actually a shift, as SZ_1M is a power-of-two constant, hence there is no need to use div_u64().
While at it, use "%lu" to format "unsigned long".
--- drivers/of/fdt.c | 8 ++++---- drivers/of/of_reserved_mem.c | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-)
drivers/of/fdt.c +4 -4
@@ -510,11 +510,11 @@ static int __init __reserved_mem_reserve_reg(unsigned long node,if (size &&early_init_dt_reserve_memory_arch (base, size, nomap) ==0 ) -pr_debug ("Reserved memory: reserved region for node '%s': base %pa, size %ld MiB\n" , - uname, &base, (unsigned long )size /SZ_1M ); +pr_debug ("Reserved memory: reserved region for node '%s': base %pa, size %lu MiB\n" , + uname, &base, (unsigned long )(size /SZ_1M ));else -pr_info ("Reserved memory: failed to reserve memory for node '%s': base %pa, size %ld MiB\n" , - uname, &base, (unsigned long )size /SZ_1M ); +pr_info ("Reserved memory: failed to reserve memory for node '%s': base %pa, size %lu MiB\n" , + uname, &base, (unsigned long )(size /SZ_1M )); len -= t_len;if (first) {
drivers/of/of_reserved_mem.c +4 -4
@@ -136,9 +136,9 @@ static int __init __reserved_mem_alloc_size(unsigned long node, ret =early_init_dt_alloc_reserved_memory_arch (size, align, start, end, nomap, &base);if (ret ==0 ) { -pr_debug ("allocated memory for '%s' node: base %pa, size %ld MiB\n" , +pr_debug ("allocated memory for '%s' node: base %pa, size %lu MiB\n" , uname, &base, - (unsigned long )size /SZ_1M ); + (unsigned long )(size /SZ_1M ));break ; } len -= t_len;
@@ -148,8 +148,8 @@ static int __init __reserved_mem_alloc_size(unsigned long node, ret =early_init_dt_alloc_reserved_memory_arch (size, align,0 ,0 , nomap, &base);if (ret ==0 ) -pr_debug ("allocated memory for '%s' node: base %pa, size %ld MiB\n" , - uname, &base, (unsigned long )size /SZ_1M ); +pr_debug ("allocated memory for '%s' node: base %pa, size %lu MiB\n" , + uname, &base, (unsigned long )(size /SZ_1M )); }if (base ==0 ) {
Signature · 1 line
2.25.1
Re: [PATCH 1/3] of: Fix truncation of memory sizes on 32-bit platforms
Quoted 14 lines · Geert Uytterhoeven
Variable "size" has type "
phys_addr_t", which can be either 32-bit or 64-bit on 32-bit systems, while "unsigned long" is always 32-bit on 32-bit systems. Hence the cast in(unsigned long)size /
SZ_1Mmay truncate a 64-bit size to 32-bit, as casts have a higher operator precedence than divisions.
Fix this by inverting the order of the cast and division, which should be safe for memory blocks smaller than 4 PiB. Note that the division is actually a shift, as
SZ_1Mis a power-of-two constant, hence there is no need to usediv_u64().
Quoted 5 lines
While at it, use "%lu" to format "unsigned long".
Fixes e8d9d1f5485b52ec ("drivers: of: add initialization code for static reserved memory")Fixes 3f0c8206644836e4 ("drivers: of: add initialization code for dynamic reserved memory")Signed-off-by Geert Uytterhoeven <[email protected]>
Quoted 42 lines
--- drivers/of/fdt.c | 8 ++++---- drivers/of/of_reserved_mem.c | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-)drivers/of/fdt.c +4
-4@@ -510,11 +510,11 @@ static int __init __reserved_mem_reserve_reg(unsigned long node,if (size &&early_init_dt_reserve_memory_arch (base, size, nomap) ==0 ) -pr_debug ("Reserved memory: reserved region for node '%s': base %pa, size %ld MiB\n" , - uname, &base, (unsigned long )size /SZ_1M ); +pr_debug ("Reserved memory: reserved region for node '%s': base %pa, size %lu MiB\n" , + uname, &base, (unsigned long )(size /SZ_1M ));else -pr_info ("Reserved memory: failed to reserve memory for node '%s': base %pa, size %ld MiB\n" , - uname, &base, (unsigned long )size /SZ_1M ); +pr_info ("Reserved memory: failed to reserve memory for node '%s': base %pa, size %lu MiB\n" , + uname, &base, (unsigned long )(size /SZ_1M )); len -= t_len;if (first) {drivers/of/of_reserved_mem.c +2
-2@@ -136,9 +136,9 @@ static int __init __reserved_mem_alloc_size(unsigned long node, ret =early_init_dt_alloc_reserved_memory_arch (size, align, start, end, nomap, &base);if (ret ==0 ) { -pr_debug ("allocated memory for '%s' node: base %pa, size %ld MiB\n" , +pr_debug ("allocated memory for '%s' node: base %pa, size %lu MiB\n" , uname, &base, - (unsigned long )size /SZ_1M ); + (unsigned long )(size /SZ_1M ));break ; } len -= t_len;
drivers/of/of_reserved_mem.c static int __init __reserved_mem_alloc_size(unsigned long node, · line 155
Quoted 10 lines
drivers/of/of_reserved_mem.c +2
-2@@ -148,8 +148,8 @@ static int __init __reserved_mem_alloc_size(unsigned long node, ret =early_init_dt_alloc_reserved_memory_arch (size, align,0 ,0 , nomap, &base);if (ret ==0 ) -pr_debug ("allocated memory for '%s' node: base %pa, size %ld MiB\n" , - uname, &base, (unsigned long )size /SZ_1M ); +pr_debug ("allocated memory for '%s' node: base %pa, size %lu MiB\n" , + uname, &base, (unsigned long )(size /SZ_1M )); }if (base ==0 ) {
Best regards
Signature · 2 lines
Marek Szyprowski, PhD Samsung R&D Institute Poland
Re: [PATCH 1/3] of: Fix truncation of memory sizes on 32-bit platforms
In reply to Geert UytterhoevenQuoted 16 lines · Geert Uytterhoeven
Variable "size" has type "
phys_addr_t", which can be either 32-bit or 64-bit on 32-bit systems, while "unsigned long" is always 32-bit on 32-bit systems. Hence the cast in(unsigned long)size /
SZ_1Mmay truncate a 64-bit size to 32-bit, as casts have a higher operator precedence than divisions.
Fix this by inverting the order of the cast and division, which should be safe for memory blocks smaller than 4 PiB. Note that the division is actually a shift, as
SZ_1Mis a power-of-two constant, hence there is no need to usediv_u64().While at it, use "%lu" to format "unsigned long".
Quoted 8 lines
Fixes e8d9d1f5485b52ec ("drivers: of: add initialization code for static reserved memory")Fixes 3f0c8206644836e4 ("drivers: of: add initialization code for dynamic reserved memory")Signed-off-by Geert Uytterhoeven <[email protected]>--- drivers/of/fdt.c | 8 ++++---- drivers/of/of_reserved_mem.c | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-)
Applied, thanks!
PATCH 2/3 of: Remove superfluous casts when printing u64 values
In reply to Geert Uytterhoeven"u64" is "unsigned long long" on all architectures now. Hence there is no longer a need to use casts when formatting using the "ll" length modifier.
--- drivers/of/address.c | 14 ++++---------- drivers/of/fdt.c | 6 ++---- 2 files changed, 6 insertions(+), 14 deletions(-)
drivers/of/address.c +4 -10
@@ -78,9 +78,7 @@ static u64 of_bus_default_map(__be32 *addr, const __be32 *range, s =of_read_number (range + na + pna, ns); da =of_read_number (addr, na); -pr_debug ("default map, cp=%llx, s=%llx, da=%llx\n" , - (unsigned long long )cp, (unsigned long long )s, - (unsigned long long )da); +pr_debug ("default map, cp=%llx, s=%llx, da=%llx\n" , cp, s, da);if (da < cp || da >= (cp + s))return OF_BAD_ADDR ;
@@ -187,9 +185,7 @@ static u64 of_bus_pci_map(__be32 *addr, const __be32 *range, int na, int ns, s =of_read_number (range + na + pna, ns); da =of_read_number (addr +1 , na -1 ); -pr_debug ("PCI map, cp=%llx, s=%llx, da=%llx\n" , - (unsigned long long )cp, (unsigned long long )s, - (unsigned long long )da); +pr_debug ("PCI map, cp=%llx, s=%llx, da=%llx\n" , cp, s, da);if (da < cp || da >= (cp + s))return OF_BAD_ADDR ;
@@ -302,9 +298,7 @@ static u64 of_bus_isa_map(__be32 *addr, const __be32 *range, int na, int ns, s =of_read_number (range + na + pna, ns); da =of_read_number (addr +1 , na -1 ); -pr_debug ("ISA map, cp=%llx, s=%llx, da=%llx\n" , - (unsigned long long )cp, (unsigned long long )s, - (unsigned long long )da); +pr_debug ("ISA map, cp=%llx, s=%llx, da=%llx\n" , cp, s, da);if (da < cp || da >= (cp + s))return OF_BAD_ADDR ;
@@ -459,7 +453,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus, finish:of_dump_addr ("parent translation for:" , addr, pna); -pr_debug ("with offset: %llx\n" , (unsigned long long )offset); +pr_debug ("with offset: %llx\n" , offset);/* Translate it into parent bus space */ return pbus->translate (addr, offset, pna);
drivers/of/fdt.c +2 -4
@@ -900,8 +900,7 @@ static void __init early_init_dt_check_for_initrd(unsigned long node) phys_initrd_start = start; phys_initrd_size = end - start; -pr_debug ("initrd_start=0x%llx initrd_end=0x%llx\n" , - (unsigned long long)start, (unsigned long long)end); + pr_debug("initrd_start=0x%llx initrd_end=0x%llx\n", start, end); }#else static inline void early_init_dt_check_for_initrd (unsigned long node)
@@ -1027,8 +1026,7 @@ int __init early_init_dt_scan_memory(unsigned long node, const char *uname,if (size ==0 )continue ; -pr_debug (" - %llx , %llx\n" , (unsigned long long )base, - (unsigned long long )size); +pr_debug (" - %llx, %llx\n" , base, size);early_init_dt_add_memory_arch (base, size);
Signature · 1 line
2.25.1
Re: [PATCH 2/3] of: Remove superfluous casts when printing u64 values
Quoted 10 lines · Geert Uytterhoeven
"u64" is "unsigned long long" on all architectures now. Hence there is no longer a need to use casts when formatting using the "ll" length modifier.
Signed-off-by Geert Uytterhoeven <[email protected]>--- drivers/of/address.c | 14 ++++---------- drivers/of/fdt.c | 6 ++---- 2 files changed, 6 insertions(+), 14 deletions(-)
Applied, thanks!
PATCH 3/3 of: kexec: Always use FDT_PROP_INITRD_START and FDT_PROP_INITRD_END
In reply to Geert UytterhoevenCommit b30be4dc733e5067 ("of: Add a common kexec FDT setup function") introduced macros FDT_PROP_INITRD_* to refer to initrd properties, but didn't use them everywhere. Convert the remaining users from string literals to macros.
--- drivers/of/kexec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/of/kexec.c +2 -2
@@ -318,13 +318,13 @@ void *of_kexec_alloc_and_setup_fdt(const struct kimage *image, goto out;/* Did we boot using an initrd? */ - prop =fdt_getprop (fdt, chosen_node,"linux,initrd-start" ,NULL ); + prop =fdt_getprop (fdt, chosen_node,FDT_PROP_INITRD_START ,NULL );if (prop) {u64 tmp_start, tmp_end, tmp_size; tmp_start =fdt64_to_cpu (*((const fdt64_t *) prop)); - prop =fdt_getprop (fdt, chosen_node,"linux,initrd-end" ,NULL ); + prop =fdt_getprop (fdt, chosen_node,FDT_PROP_INITRD_END ,NULL );if (!prop) { ret = -EINVAL ; goto out;
Signature · 1 line
2.25.1
Re: [PATCH 3/3] of: kexec: Always use FDT_PROP_INITRD_START and FDT_PROP_INITRD_END
Quoted 5 lines · Geert Uytterhoeven
Commit
b30be4dc733e5067("of: Add a common kexec FDT setup function") introduced macros FDT_PROP_INITRD_* to refer to initrd properties, but didn't use them everywhere. Convert the remaining users from string literals to macros.
I'm not really a fan of the defines, so if anything I'd get rid of them. But the bigger problem is what you brought to light with the variable size. As I mentioned, we should refactor this and the fdt.c code to have a common function to read the initrd start and end.
Quoted 28 lines
Signed-off-by Geert Uytterhoeven <[email protected]>--- drivers/of/kexec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)drivers/of/kexec.c +2
-3@@ -318,13 +318,13 @@ void *of_kexec_alloc_and_setup_fdt(const struct kimage *image, goto out;/* Did we boot using an initrd? */ - prop =fdt_getprop (fdt, chosen_node,"linux,initrd-start" ,NULL ); + prop =fdt_getprop (fdt, chosen_node,FDT_PROP_INITRD_START ,NULL );if (prop) {u64 tmp_start, tmp_end, tmp_size; tmp_start =fdt64_to_cpu (*((const fdt64_t *) prop)); - prop =fdt_getprop (fdt, chosen_node,"linux,initrd-end" ,NULL ); + prop =fdt_getprop (fdt, chosen_node,FDT_PROP_INITRD_END ,NULL );if (!prop) { ret = -EINVAL ; goto out; --2.25.1
Re: [PATCH 3/3] of: kexec: Always use FDT_PROP_INITRD_START and FDT_PROP_INITRD_END
Hi Rob,
Quoted 8 lines · Rob Herring
Quoted 4 lines · Geert Uytterhoeven
Commit
b30be4dc733e5067("of: Add a common kexec FDT setup function") introduced macros FDT_PROP_INITRD_* to refer to initrd properties, but didn't use them everywhere. Convert the remaining users from string literals to macros.I'm not really a fan of the defines, so if anything I'd get rid of
Oh, as you authored that patch, I thought you liked them ;-) And I was thinking of moving them to a header file, so they can be used by other .c files, too...
Upon closer inspection, I see you just copied them from arm64, which was not that visible due to commit ac10be5cdbfa8521 ("arm64: Use common of_kexec_alloc_and_setup_fdt()") being a separate commit...
Quoted 2 lines
them. But the bigger problem is what you brought to light with the variable size. As I mentioned, we should refactor this and the
fdt.c
The number of cells to use for the initrd properties doesn't seem to be well-defined.drivers/of/fdt.c derives it from the length of the property, which more or less always works ("be strict when sending, be liberal when receiving"). Some code hardcodes it to 1 or 2. I suspect (didn't check) there's also code out there that uses the root number of cells?
Quoted 1 line
code to have a common function to read the initrd start and end.
What with code that needs to set the start and end? It needs to use what the receiving end will expect...
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]
In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
Re: [PATCH 3/3] of: kexec: Always use FDT_PROP_INITRD_START and FDT_PROP_INITRD_END
Quoted 13 lines · Geert Uytterhoeven
Hi Rob,
Quoted 8 lines · Rob Herring
Quoted 4 lines · Geert Uytterhoeven
Commit
b30be4dc733e5067("of: Add a common kexec FDT setup function") introduced macros FDT_PROP_INITRD_* to refer to initrd properties, but didn't use them everywhere. Convert the remaining users from string literals to macros.I'm not really a fan of the defines, so if anything I'd get rid of
Quoted 7 lines
Oh, as you authored that patch, I thought you liked them ;-) And I was thinking of moving them to a header file, so they can be used by other .c files, too...
Upon closer inspection, I see you just copied them from arm64, which was not that visible due to commit
ac10be5cdbfa8521("arm64: Use commonof_kexec_alloc_and_setup_fdt()") being a separate commit...
That all was largely a 'this is what you need to implement' review.
Quoted 8 lines
Quoted 2 lines
them. But the bigger problem is what you brought to light with the variable size. As I mentioned, we should refactor this and the
fdt.cThe number of cells to use for the initrd properties doesn't seem to be well-defined.
drivers/of/fdt.cderives it from the length of the property, which more or less always works ("be strict when sending, be liberal when receiving"). Some code hardcodes it to 1 or 2.
The not well defined ship has sailed, so we need to support either.
Quoted 2 lines
I suspect (didn't
check) there's also code out there that uses the root number of cells?
Given it's a single value, there's not really any need to do that. Unlike some of the kexec properties which combine the start and length for example.
Quoted 3 lines
Quoted 1 line
code to have a common function to read the initrd start and end.
What with code that needs to set the start and end?
I'm not sure we can consolidate that as those are mostly in early arch boot code.
Quoted 1 line
It needs to use what the receiving end will expect...
That should be fine given fdt.c is flexible already.
Rob