[U-Boot] [PATCH 0/3] make ERR_PTR/PTR_ERR architecture specific

Some U-Boot pointers have redundant information, so we can use a scheme where we can return either an error code or a pointer with the same return value. The default implementation just casts the pointer to a number, however, this may fail on platforms where the end of the address range is used for valid pointers (e.g. 0xffffff00 is a valid heap pointer in socfpga SPL). For such platforms, this value provides an upper range of those error pointer values - up to 'MAX_ERRNO' bytes below this value must be unused/invalid addresses.
Simon Goldschmidt (3): Kconfig add config ERR_PTR_OFFSET linux err: make ERR_PTR/PTR_ERR architecture specific arm: socfpga: gen5: fix ERR_PTR_OFFSET
Kconfig | 14 ++++++++++++++ arch/arm/mach-socfpga/Kconfig | 3 +++ include/linux/err.h | 8 ++++---- 3 files changed, 21 insertions(+), 4 deletions(-)

Some U-Boot pointers have redundant information, so we can use a scheme where we can return either an error code or a pointer with the same return value. The default implementation just casts the pointer to a number, however, this may fail on platforms where the end of the address range is used for valid pointers (e.g. 0xffffff00 is a valid heap pointer in socfpga SPL). For such platforms, this value provides an upper range of those error pointer values - up to 'MAX_ERRNO' bytes below this value must be unused/invalid addresses.
Signed-off-by: Simon Goldschmidt simon.k.r.goldschmidt@gmail.com ---
Kconfig | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
diff --git a/Kconfig b/Kconfig index 66b059f749..cda4f58ff7 100644 --- a/Kconfig +++ b/Kconfig @@ -281,6 +281,20 @@ config SYS_LDSCRIPT Path within the source tree to the linker script to use for the main U-Boot binary.
+config ERR_PTR_OFFSET + hex + default 0x0 + help + Some U-Boot pointers have redundant information, so we can use a + scheme where we can return either an error code or a pointer with the + same return value. The default implementation just casts the pointer + to a number, however, this may fail on platforms where the end of the + address range is used for valid pointers (e.g. 0xffffff00 is a valid + heap pointer in socfpga SPL). + For such platforms, this value provides an upper range of those error + pointer values - up to 'MAX_ERRNO' bytes below this value must be + unused/invalid addresses. + endmenu # General setup
menu "Boot images"

On Tue, Oct 22, 2019 at 09:29:46PM +0200, Simon Goldschmidt wrote:
Some U-Boot pointers have redundant information, so we can use a scheme where we can return either an error code or a pointer with the same return value. The default implementation just casts the pointer to a number, however, this may fail on platforms where the end of the address range is used for valid pointers (e.g. 0xffffff00 is a valid heap pointer in socfpga SPL). For such platforms, this value provides an upper range of those error pointer values - up to 'MAX_ERRNO' bytes below this value must be unused/invalid addresses.
Signed-off-by: Simon Goldschmidt simon.k.r.goldschmidt@gmail.com
Applied to u-boot/master, thanks!

This patch changes ERR_PTR/PTR_ERR to use CONFIG_ERR_PTR_OFFSET to map errno values into a pointer region that cannot contain valid pointers.
IS_ERR and IS_ERR_OR_NULL have to be converted to use PTR_ERR, too, for this to work.
Signed-off-by: Simon Goldschmidt simon.k.r.goldschmidt@gmail.com ---
include/linux/err.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/include/linux/err.h b/include/linux/err.h index 22e5756edd..5ede82432d 100644 --- a/include/linux/err.h +++ b/include/linux/err.h @@ -23,22 +23,22 @@
static inline void *ERR_PTR(long error) { - return (void *) error; + return (void *)(CONFIG_ERR_PTR_OFFSET + error); }
static inline long PTR_ERR(const void *ptr) { - return (long) ptr; + return ((long)ptr - CONFIG_ERR_PTR_OFFSET); }
static inline long IS_ERR(const void *ptr) { - return IS_ERR_VALUE((unsigned long)ptr); + return IS_ERR_VALUE((unsigned long)PTR_ERR(ptr)); }
static inline bool IS_ERR_OR_NULL(const void *ptr) { - return !ptr || IS_ERR_VALUE((unsigned long)ptr); + return !ptr || IS_ERR_VALUE((unsigned long)PTR_ERR(ptr)); }
/**

On Tue, Oct 22, 2019 at 09:29:47PM +0200, Simon Goldschmidt wrote:
This patch changes ERR_PTR/PTR_ERR to use CONFIG_ERR_PTR_OFFSET to map errno values into a pointer region that cannot contain valid pointers.
IS_ERR and IS_ERR_OR_NULL have to be converted to use PTR_ERR, too, for this to work.
Signed-off-by: Simon Goldschmidt simon.k.r.goldschmidt@gmail.com
Applied to u-boot/master, thanks!

The default implementation of ERR_PTR/PTR_ERR maps errno values at the and of the address range (e.g. -EINVAL/-22 gets 0xFFFFFFEA).
For socfpga gen5 SPL, this doesn't really work, as the heap is nearly at the end of the 32 bit address range.
This patch adjusts the ERR_PTR_OFFSET to map errno values into the range of the Boot ROM, which should not be used for valid pointers.
Signed-off-by: Simon Goldschmidt simon.k.r.goldschmidt@gmail.com ---
arch/arm/mach-socfpga/Kconfig | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/arch/arm/mach-socfpga/Kconfig b/arch/arm/mach-socfpga/Kconfig index fc0a54214f..3770e07258 100644 --- a/arch/arm/mach-socfpga/Kconfig +++ b/arch/arm/mach-socfpga/Kconfig @@ -1,5 +1,8 @@ if ARCH_SOCFPGA
+config ERR_PTR_OFFSET + default 0xfffec000 if TARGET_SOCFPGA_GEN5 # Boot ROM range + config NR_DRAM_BANKS default 1

On Tue, Oct 22, 2019 at 09:29:48PM +0200, Simon Goldschmidt wrote:
The default implementation of ERR_PTR/PTR_ERR maps errno values at the and of the address range (e.g. -EINVAL/-22 gets 0xFFFFFFEA).
For socfpga gen5 SPL, this doesn't really work, as the heap is nearly at the end of the 32 bit address range.
This patch adjusts the ERR_PTR_OFFSET to map errno values into the range of the Boot ROM, which should not be used for valid pointers.
Signed-off-by: Simon Goldschmidt simon.k.r.goldschmidt@gmail.com
Applied to u-boot/master, thanks!
participants (2)
-
Simon Goldschmidt
-
Tom Rini