2019-06-10 21:22:29

by Christoph Hellwig

[permalink] [raw]
Subject: binfmt_flat cleanups and RISC-V support

Hi Greg,

below is a larger stash of cleanups for the binfmt_misc code,
preparing for the last patch that now trivially adds RISC-V
support, which will be used for the RISC-V nommu series I am
about to post.


2019-06-10 21:22:39

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 01/15] binfmt_flat: remove flat_reloc_valid

This helper is the same for all architectures, open code it in the only
caller.

Signed-off-by: Christoph Hellwig <[email protected]>
---
arch/arm/include/asm/flat.h | 1 -
arch/c6x/include/asm/flat.h | 1 -
arch/h8300/include/asm/flat.h | 1 -
arch/m68k/include/asm/flat.h | 1 -
arch/microblaze/include/asm/flat.h | 1 -
arch/sh/include/asm/flat.h | 1 -
arch/xtensa/include/asm/flat.h | 1 -
fs/binfmt_flat.c | 2 +-
8 files changed, 1 insertion(+), 8 deletions(-)

diff --git a/arch/arm/include/asm/flat.h b/arch/arm/include/asm/flat.h
index f0c75ddeea23..10cce9ecf151 100644
--- a/arch/arm/include/asm/flat.h
+++ b/arch/arm/include/asm/flat.h
@@ -10,7 +10,6 @@

#define flat_argvp_envp_on_stack() 1
#define flat_old_ram_flag(flags) (flags)
-#define flat_reloc_valid(reloc, size) ((reloc) <= (size))

static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags,
u32 *addr, u32 *persistent)
diff --git a/arch/c6x/include/asm/flat.h b/arch/c6x/include/asm/flat.h
index 76fd0bb962a3..ecc6aea6606c 100644
--- a/arch/c6x/include/asm/flat.h
+++ b/arch/c6x/include/asm/flat.h
@@ -6,7 +6,6 @@

#define flat_argvp_envp_on_stack() 0
#define flat_old_ram_flag(flags) (flags)
-#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags,
u32 *addr, u32 *persistent)
{
diff --git a/arch/h8300/include/asm/flat.h b/arch/h8300/include/asm/flat.h
index f4cdfcbdd2ba..dcc7775115dd 100644
--- a/arch/h8300/include/asm/flat.h
+++ b/arch/h8300/include/asm/flat.h
@@ -10,7 +10,6 @@

#define flat_argvp_envp_on_stack() 1
#define flat_old_ram_flag(flags) 1
-#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
#define flat_set_persistent(relval, p) 0

/*
diff --git a/arch/m68k/include/asm/flat.h b/arch/m68k/include/asm/flat.h
index 4f1d1e373420..a631caf5e18f 100644
--- a/arch/m68k/include/asm/flat.h
+++ b/arch/m68k/include/asm/flat.h
@@ -10,7 +10,6 @@

#define flat_argvp_envp_on_stack() 1
#define flat_old_ram_flag(flags) (flags)
-#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags,
u32 *addr, u32 *persistent)
{
diff --git a/arch/microblaze/include/asm/flat.h b/arch/microblaze/include/asm/flat.h
index 3d2747d4c967..34be5ed011be 100644
--- a/arch/microblaze/include/asm/flat.h
+++ b/arch/microblaze/include/asm/flat.h
@@ -15,7 +15,6 @@

#define flat_argvp_envp_on_stack() 0
#define flat_old_ram_flag(flags) (flags)
-#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
#define flat_set_persistent(relval, p) 0

/*
diff --git a/arch/sh/include/asm/flat.h b/arch/sh/include/asm/flat.h
index 843d458b8329..8f2929b32f2e 100644
--- a/arch/sh/include/asm/flat.h
+++ b/arch/sh/include/asm/flat.h
@@ -13,7 +13,6 @@

#define flat_argvp_envp_on_stack() 0
#define flat_old_ram_flag(flags) (flags)
-#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags,
u32 *addr, u32 *persistent)
{
diff --git a/arch/xtensa/include/asm/flat.h b/arch/xtensa/include/asm/flat.h
index b8532d7877b3..6ee5a35eb0ec 100644
--- a/arch/xtensa/include/asm/flat.h
+++ b/arch/xtensa/include/asm/flat.h
@@ -6,7 +6,6 @@

#define flat_argvp_envp_on_stack() 0
#define flat_old_ram_flag(flags) (flags)
-#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags,
u32 *addr, u32 *persistent)
{
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index 82a48e830018..afddea583999 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -345,7 +345,7 @@ calc_reloc(unsigned long r, struct lib_info *p, int curid, int internalp)
start_code = p->lib_list[id].start_code;
text_len = p->lib_list[id].text_len;

- if (!flat_reloc_valid(r, start_brk - start_data + text_len)) {
+ if (r > start_brk - start_data + text_len) {
pr_err("reloc outside program 0x%lx (0 - 0x%lx/0x%lx)",
r, start_brk-start_data+text_len, text_len);
goto failed;
--
2.20.1

2019-06-10 21:22:43

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 09/15] binfmt_flat: add a ARCH_HAS_BINFMT_FLAT option

Allow architectures to opt into ARCH_HAS_BINFMT_FLAT support instead of
assuming that all nommu ports support the format.

Signed-off-by: Christoph Hellwig <[email protected]>
---
arch/arm/Kconfig | 1 +
arch/c6x/Kconfig | 1 +
arch/h8300/Kconfig | 1 +
arch/m68k/Kconfig | 1 +
arch/microblaze/Kconfig | 1 +
arch/sh/Kconfig | 1 +
arch/xtensa/Kconfig | 1 +
fs/Kconfig.binfmt | 5 ++++-
8 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index b1b48c0bde76..695a26c68064 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -4,6 +4,7 @@ config ARM
default y
select ARCH_32BIT_OFF_T
select ARCH_CLOCKSOURCE_DATA
+ select ARCH_HAS_BINFMT_FLAT
select ARCH_HAS_DEBUG_VIRTUAL if MMU
select ARCH_HAS_DEVMEM_IS_ALLOWED
select ARCH_HAS_ELF_RANDOMIZE
diff --git a/arch/c6x/Kconfig b/arch/c6x/Kconfig
index eeb0471268a0..78dfe186d708 100644
--- a/arch/c6x/Kconfig
+++ b/arch/c6x/Kconfig
@@ -7,6 +7,7 @@
config C6X
def_bool y
select ARCH_32BIT_OFF_T
+ select ARCH_HAS_BINFMT_FLAT
select ARCH_HAS_SYNC_DMA_FOR_CPU
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
select CLKDEV_LOOKUP
diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig
index 7457f190caaa..ec800e9d5aad 100644
--- a/arch/h8300/Kconfig
+++ b/arch/h8300/Kconfig
@@ -2,6 +2,7 @@
config H8300
def_bool y
select ARCH_32BIT_OFF_T
+ select ARCH_HAS_BINFMT_FLAT
select BINFMT_FLAT_ARGVP_ENVP_ON_STACK
select BINFMT_FLAT_OLD_ALWAYS_RAM
select GENERIC_ATOMIC64
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index fd69ee5ad6ab..c0c43c624afa 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -3,6 +3,7 @@ config M68K
bool
default y
select ARCH_32BIT_OFF_T
+ select ARCH_HAS_BINFMT_FLAT
select ARCH_HAS_SYNC_DMA_FOR_DEVICE if HAS_DMA
select ARCH_MIGHT_HAVE_PC_PARPORT if ISA
select ARCH_NO_COHERENT_DMA_MMAP if !MMU
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
index f11433daab4a..d411de05b628 100644
--- a/arch/microblaze/Kconfig
+++ b/arch/microblaze/Kconfig
@@ -3,6 +3,7 @@ config MICROBLAZE
def_bool y
select ARCH_32BIT_OFF_T
select ARCH_NO_SWAP
+ select ARCH_HAS_BINFMT_FLAT if !MMU
select ARCH_HAS_DMA_COHERENT_TO_PFN if MMU
select ARCH_HAS_GCOV_PROFILE_ALL
select ARCH_HAS_SYNC_DMA_FOR_CPU
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index b77f512bb176..df3e6215b78c 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
config SUPERH
def_bool y
+ select ARCH_HAS_BINFMT_FLAT if !MMU
select ARCH_HAS_PTE_SPECIAL
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
select ARCH_MIGHT_HAVE_PC_PARPORT
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index 6ec1b75eabc5..ebc135bda921 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -2,6 +2,7 @@
config XTENSA
def_bool y
select ARCH_32BIT_OFF_T
+ select ARCH_HAS_BINFMT_FLAT if !MMU
select ARCH_HAS_SYNC_DMA_FOR_CPU
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
select ARCH_NO_COHERENT_DMA_MMAP if !MMU
diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
index 82f7d7f234f3..286b425b30b9 100644
--- a/fs/Kconfig.binfmt
+++ b/fs/Kconfig.binfmt
@@ -91,9 +91,12 @@ config BINFMT_SCRIPT

Most systems will not boot if you say M or N here. If unsure, say Y.

+config ARCH_HAS_BINFMT_FLAT
+ bool
+
config BINFMT_FLAT
bool "Kernel support for flat binaries"
- depends on !MMU || ARM || M68K
+ depends on ARCH_HAS_BINFMT_FLAT
help
Support uClinux FLAT format binaries.

--
2.20.1

2019-06-10 21:23:27

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 07/15] binfmt_flat: use __be32 for the on-disk format

So far binfmt_flat has onl been supported on 32-bit platforms, so the
variable size of the fields didn't matter. But the upcoming RISC-V
nommu port supports 64-bit CPUs, and we now have a conflict between
the elf2flt creation tool that always uses 32-bit fields and the kernel
that uses (unsigned) long field. Switch to the userspace view as the
rest of the binfmt_flat format is completely architecture neutral,
and binfmt_flat isn't the right binary format for huge executables to
start with.

While we're at it also ensure these fields are using __be types as
they big endian and are byteswapped when loaded.

Signed-off-by: Christoph Hellwig <[email protected]>

wip
---
include/linux/flat.h | 48 ++++++++++++++++++++++----------------------
1 file changed, 24 insertions(+), 24 deletions(-)

diff --git a/include/linux/flat.h b/include/linux/flat.h
index 21d901ba191b..59e892d5fadb 100644
--- a/include/linux/flat.h
+++ b/include/linux/flat.h
@@ -24,26 +24,26 @@
*/

struct flat_hdr {
- char magic[4];
- unsigned long rev; /* version (as above) */
- unsigned long entry; /* Offset of first executable instruction
- with text segment from beginning of file */
- unsigned long data_start; /* Offset of data segment from beginning of
- file */
- unsigned long data_end; /* Offset of end of data segment
- from beginning of file */
- unsigned long bss_end; /* Offset of end of bss segment from beginning
- of file */
+ char magic[4];
+ __be32 rev; /* version (as above) */
+ __be32 entry; /* Offset of first executable instruction
+ with text segment from beginning of file */
+ __be32 data_start; /* Offset of data segment from beginning of
+ file */
+ __be32 data_end; /* Offset of end of data segment from beginning
+ of file */
+ __be32 bss_end; /* Offset of end of bss segment from beginning
+ of file */

/* (It is assumed that data_end through bss_end forms the bss segment.) */

- unsigned long stack_size; /* Size of stack, in bytes */
- unsigned long reloc_start; /* Offset of relocation records from
- beginning of file */
- unsigned long reloc_count; /* Number of relocation records */
- unsigned long flags;
- unsigned long build_date; /* When the program/library was built */
- unsigned long filler[5]; /* Reservered, set to zero */
+ __be32 stack_size; /* Size of stack, in bytes */
+ __be32 reloc_start; /* Offset of relocation records from beginning of
+ file */
+ __be32 reloc_count; /* Number of relocation records */
+ __be32 flags;
+ __be32 build_date; /* When the program/library was built */
+ __u32 filler[5]; /* Reservered, set to zero */
};

#define FLAT_FLAG_RAM 0x0001 /* load program entirely into RAM */
@@ -67,19 +67,19 @@ struct flat_hdr {
#define OLD_FLAT_RELOC_TYPE_BSS 2

typedef union {
- unsigned long value;
+ u32 value;
struct {
# if defined(mc68000) && !defined(CONFIG_COLDFIRE)
- signed long offset : 30;
- unsigned long type : 2;
+ s32 offset : 30;
+ u32 type : 2;
# define OLD_FLAT_FLAG_RAM 0x1 /* load program entirely into RAM */
# elif defined(__BIG_ENDIAN_BITFIELD)
- unsigned long type : 2;
- signed long offset : 30;
+ u32 type : 2;
+ s32 offset : 30;
# define OLD_FLAT_FLAG_RAM 0x1 /* load program entirely into RAM */
# elif defined(__LITTLE_ENDIAN_BITFIELD)
- signed long offset : 30;
- unsigned long type : 2;
+ s32 offset : 30;
+ u32 type : 2;
# define OLD_FLAT_FLAG_RAM 0x1 /* load program entirely into RAM */
# else
# error "Unknown bitfield order for flat files."
--
2.20.1

2019-06-10 21:23:34

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 03/15] binfmt_flat: provide a default version of flat_get_relocate_addr

This way only the two architectures that do masking need to provide
the helper.

Signed-off-by: Christoph Hellwig <[email protected]>
---
arch/arm/include/asm/flat.h | 2 --
arch/c6x/include/asm/flat.h | 1 -
arch/m68k/include/asm/flat.h | 1 -
arch/sh/include/asm/flat.h | 1 -
arch/xtensa/include/asm/flat.h | 1 -
fs/binfmt_flat.c | 4 ++++
6 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/arch/arm/include/asm/flat.h b/arch/arm/include/asm/flat.h
index 576241d74704..a185fe023b60 100644
--- a/arch/arm/include/asm/flat.h
+++ b/arch/arm/include/asm/flat.h
@@ -30,6 +30,4 @@ static inline int flat_put_addr_at_rp(u32 __user *rp, u32 addr, u32 rel)
#endif
}

-#define flat_get_relocate_addr(rel) (rel)
-
#endif /* __ARM_FLAT_H__ */
diff --git a/arch/c6x/include/asm/flat.h b/arch/c6x/include/asm/flat.h
index ac87368efad1..c4d703b454c6 100644
--- a/arch/c6x/include/asm/flat.h
+++ b/arch/c6x/include/asm/flat.h
@@ -17,6 +17,5 @@ static inline int flat_put_addr_at_rp(u32 __user *rp, u32 addr, u32 rel)
put_unaligned(addr, (__force u32 *)rp);
return 0;
}
-#define flat_get_relocate_addr(rel) (rel)

#endif /* __ASM_C6X_FLAT_H */
diff --git a/arch/m68k/include/asm/flat.h b/arch/m68k/include/asm/flat.h
index 955617bb937b..217fa89c8e34 100644
--- a/arch/m68k/include/asm/flat.h
+++ b/arch/m68k/include/asm/flat.h
@@ -28,7 +28,6 @@ static inline int flat_put_addr_at_rp(u32 __user *rp, u32 addr, u32 rel)
return put_user(addr, rp);
#endif
}
-#define flat_get_relocate_addr(rel) (rel)

#define FLAT_PLAT_INIT(regs) \
do { \
diff --git a/arch/sh/include/asm/flat.h b/arch/sh/include/asm/flat.h
index 6f3b18679a98..0d520b4cc5ea 100644
--- a/arch/sh/include/asm/flat.h
+++ b/arch/sh/include/asm/flat.h
@@ -24,7 +24,6 @@ static inline int flat_put_addr_at_rp(u32 __user *rp, u32 addr, u32 rel)
put_unaligned(addr, (__force u32 *)rp);
return 0;
}
-#define flat_get_relocate_addr(rel) (rel)

#define FLAT_PLAT_INIT(_r) \
do { _r->regs[0]=0; _r->regs[1]=0; _r->regs[2]=0; _r->regs[3]=0; \
diff --git a/arch/xtensa/include/asm/flat.h b/arch/xtensa/include/asm/flat.h
index b1bc0d9a8d4e..a1d88aa3ef8a 100644
--- a/arch/xtensa/include/asm/flat.h
+++ b/arch/xtensa/include/asm/flat.h
@@ -17,6 +17,5 @@ static inline int flat_put_addr_at_rp(u32 __user *rp, u32 addr, u32 rel)
put_unaligned(addr, (__force u32 *)rp);
return 0;
}
-#define flat_get_relocate_addr(rel) (rel)

#endif /* __ASM_XTENSA_FLAT_H */
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index a4c0b245ab1f..c0e4535dc1ec 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -43,6 +43,10 @@
#include <asm/cacheflush.h>
#include <asm/page.h>

+#ifndef flat_get_relocate_addr
+#define flat_get_relocate_addr(rel) (rel)
+#endif
+
/****************************************************************************/

/*
--
2.20.1

2019-06-11 07:00:48

by Greg Ungerer

[permalink] [raw]
Subject: Re: binfmt_flat cleanups and RISC-V support

Hi Christoph,

On 11/6/19 7:20 am, Christoph Hellwig wrote:
> below is a larger stash of cleanups for the binfmt_misc code,
> preparing for the last patch that now trivially adds RISC-V
> support, which will be used for the RISC-V nommu series I am
> about to post.

Whole series looks pretty good. Just the one comment I made.

I normally take these through the m68knommu git tree,
if you have no problem with that I'll push it in there.
It will hit linux-next from there.

Thanks
Greg


2019-06-11 07:40:24

by Christoph Hellwig

[permalink] [raw]
Subject: Re: binfmt_flat cleanups and RISC-V support

On Tue, Jun 11, 2019 at 04:51:02PM +1000, Greg Ungerer wrote:
> Hi Christoph,
>
> On 11/6/19 7:20 am, Christoph Hellwig wrote:
>> below is a larger stash of cleanups for the binfmt_misc code,
>> preparing for the last patch that now trivially adds RISC-V
>> support, which will be used for the RISC-V nommu series I am
>> about to post.
>
> Whole series looks pretty good. Just the one comment I made.
>
> I normally take these through the m68knommu git tree,
> if you have no problem with that I'll push it in there.
> It will hit linux-next from there.

Yes, that's fine. We'll need it to bring up riscv nommu support,
but there is no actual dependency on the patches for it to compile,
just for it to actually be useful.

Btw, it seems like the uclinux-dev list is dead, is there a replacement
for it?

2019-06-11 08:13:27

by Vladimir Murzin

[permalink] [raw]
Subject: Re: binfmt_flat cleanups and RISC-V support

Hi Christoph,

On 6/10/19 10:20 PM, Christoph Hellwig wrote:
> Hi Greg,
>
> below is a larger stash of cleanups for the binfmt_misc code,
> preparing for the last patch that now trivially adds RISC-V
> support, which will be used for the RISC-V nommu series I am
> about to post.


I'm wondering if you have a branch with these changes so I can give
it a try on ARM NOMMU platforms?

Cheers
Vladimir

>
> _______________________________________________
> linux-arm-kernel mailing list
> [email protected]
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>

2019-06-11 08:14:20

by Christoph Hellwig

[permalink] [raw]
Subject: Re: binfmt_flat cleanups and RISC-V support

On Tue, Jun 11, 2019 at 09:05:45AM +0100, Vladimir Murzin wrote:
> I'm wondering if you have a branch with these changes so I can give
> it a try on ARM NOMMU platforms?


git://git.infradead.org/users/hch/riscv.git riscv-flat

2019-06-11 08:26:41

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH 07/15] binfmt_flat: use __be32 for the on-disk format

Hi Christoph,

On Mon, Jun 10, 2019 at 11:21 PM Christoph Hellwig <[email protected]> wrote:
> So far binfmt_flat has onl been supported on 32-bit platforms, so the
> variable size of the fields didn't matter. But the upcoming RISC-V
> nommu port supports 64-bit CPUs, and we now have a conflict between
> the elf2flt creation tool that always uses 32-bit fields and the kernel
> that uses (unsigned) long field. Switch to the userspace view as the
> rest of the binfmt_flat format is completely architecture neutral,
> and binfmt_flat isn't the right binary format for huge executables to
> start with.
>
> While we're at it also ensure these fields are using __be types as
> they big endian and are byteswapped when loaded.
>
> Signed-off-by: Christoph Hellwig <[email protected]>

> --- a/include/linux/flat.h
> +++ b/include/linux/flat.h

> @@ -67,19 +67,19 @@ struct flat_hdr {
> #define OLD_FLAT_RELOC_TYPE_BSS 2
>
> typedef union {
> - unsigned long value;
> + u32 value;
> struct {
> # if defined(mc68000) && !defined(CONFIG_COLDFIRE)
> - signed long offset : 30;
> - unsigned long type : 2;
> + s32 offset : 30;
> + u32 type : 2;
> # define OLD_FLAT_FLAG_RAM 0x1 /* load program entirely into RAM */
> # elif defined(__BIG_ENDIAN_BITFIELD)
> - unsigned long type : 2;
> - signed long offset : 30;
> + u32 type : 2;
> + s32 offset : 30;
> # define OLD_FLAT_FLAG_RAM 0x1 /* load program entirely into RAM */
> # elif defined(__LITTLE_ENDIAN_BITFIELD)
> - signed long offset : 30;
> - unsigned long type : 2;
> + s32 offset : 30;
> + u32 type : 2;
> # define OLD_FLAT_FLAG_RAM 0x1 /* load program entirely into RAM */

The definitions of OLD_FLAT_FLAG_RAM are identical, so could be
factored out.
However, they appear to be unused.

> # else
> # error "Unknown bitfield order for flat files."

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

2019-06-11 09:54:36

by Vladimir Murzin

[permalink] [raw]
Subject: Re: [PATCH 01/15] binfmt_flat: remove flat_reloc_valid

On 6/10/19 10:20 PM, Christoph Hellwig wrote:
> This helper is the same for all architectures, open code it in the only
> caller.
>
> Signed-off-by: Christoph Hellwig <[email protected]>
> ---
> arch/arm/include/asm/flat.h | 1 -
> arch/c6x/include/asm/flat.h | 1 -
> arch/h8300/include/asm/flat.h | 1 -
> arch/m68k/include/asm/flat.h | 1 -
> arch/microblaze/include/asm/flat.h | 1 -
> arch/sh/include/asm/flat.h | 1 -
> arch/xtensa/include/asm/flat.h | 1 -
> fs/binfmt_flat.c | 2 +-
> 8 files changed, 1 insertion(+), 8 deletions(-)

For ARM bits:

Tested-by: Vladimir Murzin <[email protected]>
Reviewed-by: Vladimir Murzin <[email protected]>


>
> diff --git a/arch/arm/include/asm/flat.h b/arch/arm/include/asm/flat.h
> index f0c75ddeea23..10cce9ecf151 100644
> --- a/arch/arm/include/asm/flat.h
> +++ b/arch/arm/include/asm/flat.h
> @@ -10,7 +10,6 @@
>
> #define flat_argvp_envp_on_stack() 1
> #define flat_old_ram_flag(flags) (flags)
> -#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
>
> static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags,
> u32 *addr, u32 *persistent)
> diff --git a/arch/c6x/include/asm/flat.h b/arch/c6x/include/asm/flat.h
> index 76fd0bb962a3..ecc6aea6606c 100644
> --- a/arch/c6x/include/asm/flat.h
> +++ b/arch/c6x/include/asm/flat.h
> @@ -6,7 +6,6 @@
>
> #define flat_argvp_envp_on_stack() 0
> #define flat_old_ram_flag(flags) (flags)
> -#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
> static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags,
> u32 *addr, u32 *persistent)
> {
> diff --git a/arch/h8300/include/asm/flat.h b/arch/h8300/include/asm/flat.h
> index f4cdfcbdd2ba..dcc7775115dd 100644
> --- a/arch/h8300/include/asm/flat.h
> +++ b/arch/h8300/include/asm/flat.h
> @@ -10,7 +10,6 @@
>
> #define flat_argvp_envp_on_stack() 1
> #define flat_old_ram_flag(flags) 1
> -#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
> #define flat_set_persistent(relval, p) 0
>
> /*
> diff --git a/arch/m68k/include/asm/flat.h b/arch/m68k/include/asm/flat.h
> index 4f1d1e373420..a631caf5e18f 100644
> --- a/arch/m68k/include/asm/flat.h
> +++ b/arch/m68k/include/asm/flat.h
> @@ -10,7 +10,6 @@
>
> #define flat_argvp_envp_on_stack() 1
> #define flat_old_ram_flag(flags) (flags)
> -#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
> static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags,
> u32 *addr, u32 *persistent)
> {
> diff --git a/arch/microblaze/include/asm/flat.h b/arch/microblaze/include/asm/flat.h
> index 3d2747d4c967..34be5ed011be 100644
> --- a/arch/microblaze/include/asm/flat.h
> +++ b/arch/microblaze/include/asm/flat.h
> @@ -15,7 +15,6 @@
>
> #define flat_argvp_envp_on_stack() 0
> #define flat_old_ram_flag(flags) (flags)
> -#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
> #define flat_set_persistent(relval, p) 0
>
> /*
> diff --git a/arch/sh/include/asm/flat.h b/arch/sh/include/asm/flat.h
> index 843d458b8329..8f2929b32f2e 100644
> --- a/arch/sh/include/asm/flat.h
> +++ b/arch/sh/include/asm/flat.h
> @@ -13,7 +13,6 @@
>
> #define flat_argvp_envp_on_stack() 0
> #define flat_old_ram_flag(flags) (flags)
> -#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
> static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags,
> u32 *addr, u32 *persistent)
> {
> diff --git a/arch/xtensa/include/asm/flat.h b/arch/xtensa/include/asm/flat.h
> index b8532d7877b3..6ee5a35eb0ec 100644
> --- a/arch/xtensa/include/asm/flat.h
> +++ b/arch/xtensa/include/asm/flat.h
> @@ -6,7 +6,6 @@
>
> #define flat_argvp_envp_on_stack() 0
> #define flat_old_ram_flag(flags) (flags)
> -#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
> static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags,
> u32 *addr, u32 *persistent)
> {
> diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
> index 82a48e830018..afddea583999 100644
> --- a/fs/binfmt_flat.c
> +++ b/fs/binfmt_flat.c
> @@ -345,7 +345,7 @@ calc_reloc(unsigned long r, struct lib_info *p, int curid, int internalp)
> start_code = p->lib_list[id].start_code;
> text_len = p->lib_list[id].text_len;
>
> - if (!flat_reloc_valid(r, start_brk - start_data + text_len)) {
> + if (r > start_brk - start_data + text_len) {
> pr_err("reloc outside program 0x%lx (0 - 0x%lx/0x%lx)",
> r, start_brk-start_data+text_len, text_len);
> goto failed;
>

2019-06-11 09:55:09

by Vladimir Murzin

[permalink] [raw]
Subject: Re: [PATCH 03/15] binfmt_flat: provide a default version of flat_get_relocate_addr

On 6/10/19 10:20 PM, Christoph Hellwig wrote:
> This way only the two architectures that do masking need to provide
> the helper.
>
> Signed-off-by: Christoph Hellwig <[email protected]>
> ---
> arch/arm/include/asm/flat.h | 2 --
> arch/c6x/include/asm/flat.h | 1 -
> arch/m68k/include/asm/flat.h | 1 -
> arch/sh/include/asm/flat.h | 1 -
> arch/xtensa/include/asm/flat.h | 1 -
> fs/binfmt_flat.c | 4 ++++
> 6 files changed, 4 insertions(+), 6 deletions(-)


For ARM bits:

Tested-by: Vladimir Murzin <[email protected]>
Reviewed-by: Vladimir Murzin <[email protected]>


>
> diff --git a/arch/arm/include/asm/flat.h b/arch/arm/include/asm/flat.h
> index 576241d74704..a185fe023b60 100644
> --- a/arch/arm/include/asm/flat.h
> +++ b/arch/arm/include/asm/flat.h
> @@ -30,6 +30,4 @@ static inline int flat_put_addr_at_rp(u32 __user *rp, u32 addr, u32 rel)
> #endif
> }
>
> -#define flat_get_relocate_addr(rel) (rel)
> -
> #endif /* __ARM_FLAT_H__ */
> diff --git a/arch/c6x/include/asm/flat.h b/arch/c6x/include/asm/flat.h
> index ac87368efad1..c4d703b454c6 100644
> --- a/arch/c6x/include/asm/flat.h
> +++ b/arch/c6x/include/asm/flat.h
> @@ -17,6 +17,5 @@ static inline int flat_put_addr_at_rp(u32 __user *rp, u32 addr, u32 rel)
> put_unaligned(addr, (__force u32 *)rp);
> return 0;
> }
> -#define flat_get_relocate_addr(rel) (rel)
>
> #endif /* __ASM_C6X_FLAT_H */
> diff --git a/arch/m68k/include/asm/flat.h b/arch/m68k/include/asm/flat.h
> index 955617bb937b..217fa89c8e34 100644
> --- a/arch/m68k/include/asm/flat.h
> +++ b/arch/m68k/include/asm/flat.h
> @@ -28,7 +28,6 @@ static inline int flat_put_addr_at_rp(u32 __user *rp, u32 addr, u32 rel)
> return put_user(addr, rp);
> #endif
> }
> -#define flat_get_relocate_addr(rel) (rel)
>
> #define FLAT_PLAT_INIT(regs) \
> do { \
> diff --git a/arch/sh/include/asm/flat.h b/arch/sh/include/asm/flat.h
> index 6f3b18679a98..0d520b4cc5ea 100644
> --- a/arch/sh/include/asm/flat.h
> +++ b/arch/sh/include/asm/flat.h
> @@ -24,7 +24,6 @@ static inline int flat_put_addr_at_rp(u32 __user *rp, u32 addr, u32 rel)
> put_unaligned(addr, (__force u32 *)rp);
> return 0;
> }
> -#define flat_get_relocate_addr(rel) (rel)
>
> #define FLAT_PLAT_INIT(_r) \
> do { _r->regs[0]=0; _r->regs[1]=0; _r->regs[2]=0; _r->regs[3]=0; \
> diff --git a/arch/xtensa/include/asm/flat.h b/arch/xtensa/include/asm/flat.h
> index b1bc0d9a8d4e..a1d88aa3ef8a 100644
> --- a/arch/xtensa/include/asm/flat.h
> +++ b/arch/xtensa/include/asm/flat.h
> @@ -17,6 +17,5 @@ static inline int flat_put_addr_at_rp(u32 __user *rp, u32 addr, u32 rel)
> put_unaligned(addr, (__force u32 *)rp);
> return 0;
> }
> -#define flat_get_relocate_addr(rel) (rel)
>
> #endif /* __ASM_XTENSA_FLAT_H */
> diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
> index a4c0b245ab1f..c0e4535dc1ec 100644
> --- a/fs/binfmt_flat.c
> +++ b/fs/binfmt_flat.c
> @@ -43,6 +43,10 @@
> #include <asm/cacheflush.h>
> #include <asm/page.h>
>
> +#ifndef flat_get_relocate_addr
> +#define flat_get_relocate_addr(rel) (rel)
> +#endif
> +
> /****************************************************************************/
>
> /*
>

2019-06-11 09:58:03

by Vladimir Murzin

[permalink] [raw]
Subject: Re: [PATCH 07/15] binfmt_flat: use __be32 for the on-disk format

On 6/10/19 10:20 PM, Christoph Hellwig wrote:
> So far binfmt_flat has onl been supported on 32-bit platforms, so the
^^^^
only
> variable size of the fields didn't matter. But the upcoming RISC-V
> nommu port supports 64-bit CPUs, and we now have a conflict between
> the elf2flt creation tool that always uses 32-bit fields and the kernel
> that uses (unsigned) long field. Switch to the userspace view as the
> rest of the binfmt_flat format is completely architecture neutral,
> and binfmt_flat isn't the right binary format for huge executables to
> start with.
>
> While we're at it also ensure these fields are using __be types as
> they big endian and are byteswapped when loaded.
>
> Signed-off-by: Christoph Hellwig <[email protected]>
>
> wip
^^^
Unintended?

> ---
> include/linux/flat.h | 48 ++++++++++++++++++++++----------------------
> 1 file changed, 24 insertions(+), 24 deletions(-)


With comment message fixed:

Reviewed-by: Vladimir Murzin <[email protected]>

>
> diff --git a/include/linux/flat.h b/include/linux/flat.h
> index 21d901ba191b..59e892d5fadb 100644
> --- a/include/linux/flat.h
> +++ b/include/linux/flat.h
> @@ -24,26 +24,26 @@
> */
>
> struct flat_hdr {
> - char magic[4];
> - unsigned long rev; /* version (as above) */
> - unsigned long entry; /* Offset of first executable instruction
> - with text segment from beginning of file */
> - unsigned long data_start; /* Offset of data segment from beginning of
> - file */
> - unsigned long data_end; /* Offset of end of data segment
> - from beginning of file */
> - unsigned long bss_end; /* Offset of end of bss segment from beginning
> - of file */
> + char magic[4];
> + __be32 rev; /* version (as above) */
> + __be32 entry; /* Offset of first executable instruction
> + with text segment from beginning of file */
> + __be32 data_start; /* Offset of data segment from beginning of
> + file */
> + __be32 data_end; /* Offset of end of data segment from beginning
> + of file */
> + __be32 bss_end; /* Offset of end of bss segment from beginning
> + of file */
>
> /* (It is assumed that data_end through bss_end forms the bss segment.) */
>
> - unsigned long stack_size; /* Size of stack, in bytes */
> - unsigned long reloc_start; /* Offset of relocation records from
> - beginning of file */
> - unsigned long reloc_count; /* Number of relocation records */
> - unsigned long flags;
> - unsigned long build_date; /* When the program/library was built */
> - unsigned long filler[5]; /* Reservered, set to zero */
> + __be32 stack_size; /* Size of stack, in bytes */
> + __be32 reloc_start; /* Offset of relocation records from beginning of
> + file */
> + __be32 reloc_count; /* Number of relocation records */
> + __be32 flags;
> + __be32 build_date; /* When the program/library was built */
> + __u32 filler[5]; /* Reservered, set to zero */
> };
>
> #define FLAT_FLAG_RAM 0x0001 /* load program entirely into RAM */
> @@ -67,19 +67,19 @@ struct flat_hdr {
> #define OLD_FLAT_RELOC_TYPE_BSS 2
>
> typedef union {
> - unsigned long value;
> + u32 value;
> struct {
> # if defined(mc68000) && !defined(CONFIG_COLDFIRE)
> - signed long offset : 30;
> - unsigned long type : 2;
> + s32 offset : 30;
> + u32 type : 2;
> # define OLD_FLAT_FLAG_RAM 0x1 /* load program entirely into RAM */
> # elif defined(__BIG_ENDIAN_BITFIELD)
> - unsigned long type : 2;
> - signed long offset : 30;
> + u32 type : 2;
> + s32 offset : 30;
> # define OLD_FLAT_FLAG_RAM 0x1 /* load program entirely into RAM */
> # elif defined(__LITTLE_ENDIAN_BITFIELD)
> - signed long offset : 30;
> - unsigned long type : 2;
> + s32 offset : 30;
> + u32 type : 2;
> # define OLD_FLAT_FLAG_RAM 0x1 /* load program entirely into RAM */
> # else
> # error "Unknown bitfield order for flat files."
>

2019-06-11 10:00:16

by Vladimir Murzin

[permalink] [raw]
Subject: Re: [PATCH 09/15] binfmt_flat: add a ARCH_HAS_BINFMT_FLAT option

On 6/10/19 10:20 PM, Christoph Hellwig wrote:
> Allow architectures to opt into ARCH_HAS_BINFMT_FLAT support instead of
> assuming that all nommu ports support the format.
>
> Signed-off-by: Christoph Hellwig <[email protected]>
> ---
> arch/arm/Kconfig | 1 +
> arch/c6x/Kconfig | 1 +
> arch/h8300/Kconfig | 1 +
> arch/m68k/Kconfig | 1 +
> arch/microblaze/Kconfig | 1 +
> arch/sh/Kconfig | 1 +
> arch/xtensa/Kconfig | 1 +
> fs/Kconfig.binfmt | 5 ++++-
> 8 files changed, 11 insertions(+), 1 deletion(-)


For ARM bits:

Reviewed-by: Vladimir Murzin <[email protected]>


>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index b1b48c0bde76..695a26c68064 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -4,6 +4,7 @@ config ARM
> default y
> select ARCH_32BIT_OFF_T
> select ARCH_CLOCKSOURCE_DATA
> + select ARCH_HAS_BINFMT_FLAT
> select ARCH_HAS_DEBUG_VIRTUAL if MMU
> select ARCH_HAS_DEVMEM_IS_ALLOWED
> select ARCH_HAS_ELF_RANDOMIZE
> diff --git a/arch/c6x/Kconfig b/arch/c6x/Kconfig
> index eeb0471268a0..78dfe186d708 100644
> --- a/arch/c6x/Kconfig
> +++ b/arch/c6x/Kconfig
> @@ -7,6 +7,7 @@
> config C6X
> def_bool y
> select ARCH_32BIT_OFF_T
> + select ARCH_HAS_BINFMT_FLAT
> select ARCH_HAS_SYNC_DMA_FOR_CPU
> select ARCH_HAS_SYNC_DMA_FOR_DEVICE
> select CLKDEV_LOOKUP
> diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig
> index 7457f190caaa..ec800e9d5aad 100644
> --- a/arch/h8300/Kconfig
> +++ b/arch/h8300/Kconfig
> @@ -2,6 +2,7 @@
> config H8300
> def_bool y
> select ARCH_32BIT_OFF_T
> + select ARCH_HAS_BINFMT_FLAT
> select BINFMT_FLAT_ARGVP_ENVP_ON_STACK
> select BINFMT_FLAT_OLD_ALWAYS_RAM
> select GENERIC_ATOMIC64
> diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
> index fd69ee5ad6ab..c0c43c624afa 100644
> --- a/arch/m68k/Kconfig
> +++ b/arch/m68k/Kconfig
> @@ -3,6 +3,7 @@ config M68K
> bool
> default y
> select ARCH_32BIT_OFF_T
> + select ARCH_HAS_BINFMT_FLAT
> select ARCH_HAS_SYNC_DMA_FOR_DEVICE if HAS_DMA
> select ARCH_MIGHT_HAVE_PC_PARPORT if ISA
> select ARCH_NO_COHERENT_DMA_MMAP if !MMU
> diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
> index f11433daab4a..d411de05b628 100644
> --- a/arch/microblaze/Kconfig
> +++ b/arch/microblaze/Kconfig
> @@ -3,6 +3,7 @@ config MICROBLAZE
> def_bool y
> select ARCH_32BIT_OFF_T
> select ARCH_NO_SWAP
> + select ARCH_HAS_BINFMT_FLAT if !MMU
> select ARCH_HAS_DMA_COHERENT_TO_PFN if MMU
> select ARCH_HAS_GCOV_PROFILE_ALL
> select ARCH_HAS_SYNC_DMA_FOR_CPU
> diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
> index b77f512bb176..df3e6215b78c 100644
> --- a/arch/sh/Kconfig
> +++ b/arch/sh/Kconfig
> @@ -1,6 +1,7 @@
> # SPDX-License-Identifier: GPL-2.0
> config SUPERH
> def_bool y
> + select ARCH_HAS_BINFMT_FLAT if !MMU
> select ARCH_HAS_PTE_SPECIAL
> select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
> select ARCH_MIGHT_HAVE_PC_PARPORT
> diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
> index 6ec1b75eabc5..ebc135bda921 100644
> --- a/arch/xtensa/Kconfig
> +++ b/arch/xtensa/Kconfig
> @@ -2,6 +2,7 @@
> config XTENSA
> def_bool y
> select ARCH_32BIT_OFF_T
> + select ARCH_HAS_BINFMT_FLAT if !MMU
> select ARCH_HAS_SYNC_DMA_FOR_CPU
> select ARCH_HAS_SYNC_DMA_FOR_DEVICE
> select ARCH_NO_COHERENT_DMA_MMAP if !MMU
> diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
> index 82f7d7f234f3..286b425b30b9 100644
> --- a/fs/Kconfig.binfmt
> +++ b/fs/Kconfig.binfmt
> @@ -91,9 +91,12 @@ config BINFMT_SCRIPT
>
> Most systems will not boot if you say M or N here. If unsure, say Y.
>
> +config ARCH_HAS_BINFMT_FLAT
> + bool
> +
> config BINFMT_FLAT
> bool "Kernel support for flat binaries"
> - depends on !MMU || ARM || M68K
> + depends on ARCH_HAS_BINFMT_FLAT
> help
> Support uClinux FLAT format binaries.
>
>

2019-06-11 10:09:31

by Vladimir Murzin

[permalink] [raw]
Subject: Re: binfmt_flat cleanups and RISC-V support

On 6/11/19 9:11 AM, Christoph Hellwig wrote:
> On Tue, Jun 11, 2019 at 09:05:45AM +0100, Vladimir Murzin wrote:
>> I'm wondering if you have a branch with these changes so I can give
>> it a try on ARM NOMMU platforms?
>
>
> git://git.infradead.org/users/hch/riscv.git riscv-flat
>

Thanks! I gave it a go and provided my tags for relevant patches.

Cheers
Vladimir

2019-06-11 13:59:05

by Greg Ungerer

[permalink] [raw]
Subject: Re: binfmt_flat cleanups and RISC-V support


On 11/6/19 5:38 pm, Christoph Hellwig wrote:
> On Tue, Jun 11, 2019 at 04:51:02PM +1000, Greg Ungerer wrote:
>> Hi Christoph,
>>
>> On 11/6/19 7:20 am, Christoph Hellwig wrote:
>>> below is a larger stash of cleanups for the binfmt_misc code,
>>> preparing for the last patch that now trivially adds RISC-V
>>> support, which will be used for the RISC-V nommu series I am
>>> about to post.
>>
>> Whole series looks pretty good. Just the one comment I made.
>>
>> I normally take these through the m68knommu git tree,
>> if you have no problem with that I'll push it in there.
>> It will hit linux-next from there.
>
> Yes, that's fine. We'll need it to bring up riscv nommu support,
> but there is no actual dependency on the patches for it to compile,
> just for it to actually be useful.
>
> Btw, it seems like the uclinux-dev list is dead, is there a replacement
> for it?

No, unfortunately no replacement. Generally I think anything that comes
up goes to the architecture list that issues come up on. Probably not
ideal, especially for things like this that are across all arches.

Regards
Greg