* AT_BASE_PLATFORM (v2) @ 2008-07-15 23:58 Nathan Lynch 2008-07-15 23:58 ` [PATCH] elf loader support for auxvec base platform string Nathan Lynch 2008-07-15 23:58 ` [PATCH] enable AT_BASE_PLATFORM aux vector for powerpc Nathan Lynch 0 siblings, 2 replies; 20+ messages in thread From: Nathan Lynch @ 2008-07-15 23:58 UTC (permalink / raw) To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, linux-kernel, roland Background: Some IBM POWER-based systems have the ability to run in a "compatibility" mode which mostly appears to the OS as a different processor from the actual hardware. This feature of the platform is useful for live partition migration and for backwards compatibility with old kernels on new hardware. For example, a Power6 system may appear to be a Power5+, which makes the AT_PLATFORM value "power5+". Problem: Booting a system in a compatibility mode means that ld.so may load libraries that are inappropriately tuned for the real microarchitecture, and apps that use JIT techniques do not have the right information for generating tuned code. While the AT_PLATFORM auxiliary vector entry correctly indicates the ISA supported, it does not accurately reflect the underlying microarchitecture in this case, and there is no good way for userspace to get this information. Proposed solution: Add an AT_BASE_PLATFORM auxiliary vector entry which indicates the microarchitecture. This entry uses the same string format as AT_PLATFORM, and is readily usable by ld.so and other applications. Other solutions that have been suggested but found wanting: - Use a bit in AT_HWCAP to indicate compat mode -- this is not expressive enough. It's not possible to derive the microarchitecture from the combination of AT_PLATFORM's value and a single bit. - Use dsocaps -- this seems to be a ld.so-specific interface and not easily usable by other programs. ld.so/glibc is not the only program that can use knowledge of the microarchitecture. The following two patches: - add the base support to binfmt_elf.c for AT_BASE_PLATFORM - implement AT_BASE_PLATFORM for powerpc Changes since v1: - increment AT_VECTOR_SIZE_BASE - define AT_BASE_PLATFORM in generic code instead of powerpc ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH] elf loader support for auxvec base platform string 2008-07-15 23:58 AT_BASE_PLATFORM (v2) Nathan Lynch @ 2008-07-15 23:58 ` Nathan Lynch 2008-07-17 6:35 ` Benjamin Herrenschmidt 2008-07-15 23:58 ` [PATCH] enable AT_BASE_PLATFORM aux vector for powerpc Nathan Lynch 1 sibling, 1 reply; 20+ messages in thread From: Nathan Lynch @ 2008-07-15 23:58 UTC (permalink / raw) To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, linux-kernel, roland Some IBM POWER-based platforms have the ability to run in a mode which mostly appears to the OS as a different processor from the actual hardware. For example, a Power6 system may appear to be a Power5+, which makes the AT_PLATFORM value "power5+". This means that programs are restricted to the ISA supported by Power5+; Power6-specific instructions are treated as illegal. However, some applications (virtual machines, optimized libraries) can benefit from knowledge of the underlying CPU model. A new aux vector entry, AT_BASE_PLATFORM, will denote the actual hardware. For example, on a Power6 system in Power5+ compatibility mode, AT_PLATFORM will be "power5+" and AT_BASE_PLATFORM will be "power6". The idea is that AT_PLATFORM indicates the instruction set supported, while AT_BASE_PLATFORM indicates the underlying microarchitecture. If the architecture has defined ELF_BASE_PLATFORM, copy that value to the user stack in the same manner as ELF_PLATFORM. Signed-off-by: Nathan Lynch <ntl@pobox.com> --- fs/binfmt_elf.c | 23 +++++++++++++++++++++++ include/linux/auxvec.h | 5 ++++- 2 files changed, 27 insertions(+), 1 deletions(-) diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index d48ff5f..834c2c4 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -131,6 +131,10 @@ static int padzero(unsigned long elf_bss) #define STACK_ALLOC(sp, len) ({ sp -= len ; sp; }) #endif +#ifndef ELF_BASE_PLATFORM +#define ELF_BASE_PLATFORM NULL +#endif + static int create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, unsigned long load_addr, unsigned long interp_load_addr) @@ -142,7 +146,9 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, elf_addr_t __user *envp; elf_addr_t __user *sp; elf_addr_t __user *u_platform; + elf_addr_t __user *u_base_platform; const char *k_platform = ELF_PLATFORM; + const char *k_base_platform = ELF_BASE_PLATFORM; int items; elf_addr_t *elf_info; int ei_index = 0; @@ -172,6 +178,19 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, return -EFAULT; } + /* + * If this architecture has a "base" platform capability + * string, copy it to userspace. + */ + u_base_platform = NULL; + if (k_base_platform) { + size_t len = strlen(k_base_platform) + 1; + + u_base_platform = (elf_addr_t __user *)STACK_ALLOC(p, len); + if (__copy_to_user(u_base_platform, k_base_platform, len)) + return -EFAULT; + } + /* Create the ELF interpreter info */ elf_info = (elf_addr_t *)current->mm->saved_auxv; /* update AT_VECTOR_SIZE_BASE if the number of NEW_AUX_ENT() changes */ @@ -208,6 +227,10 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, NEW_AUX_ENT(AT_PLATFORM, (elf_addr_t)(unsigned long)u_platform); } + if (k_base_platform) { + NEW_AUX_ENT(AT_BASE_PLATFORM, + (elf_addr_t)(unsigned long)u_base_platform); + } if (bprm->interp_flags & BINPRM_FLAGS_EXECFD) { NEW_AUX_ENT(AT_EXECFD, bprm->interp_data); } diff --git a/include/linux/auxvec.h b/include/linux/auxvec.h index ad89545..1adc61d 100644 --- a/include/linux/auxvec.h +++ b/include/linux/auxvec.h @@ -26,8 +26,11 @@ #define AT_SECURE 23 /* secure mode boolean */ +#define AT_BASE_PLATFORM 38 /* string identifying real platform, may + * differ from AT_PLATFORM. */ + #ifdef __KERNEL__ -#define AT_VECTOR_SIZE_BASE (14 + 2) /* NEW_AUX_ENT entries in auxiliary table */ +#define AT_VECTOR_SIZE_BASE (14 + 3) /* NEW_AUX_ENT entries in auxiliary table */ #endif #endif /* _LINUX_AUXVEC_H */ -- 1.5.6.2 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH] elf loader support for auxvec base platform string 2008-07-15 23:58 ` [PATCH] elf loader support for auxvec base platform string Nathan Lynch @ 2008-07-17 6:35 ` Benjamin Herrenschmidt 2008-07-17 7:09 ` Andrew Morton 2008-07-17 16:10 ` [PATCH] " Linus Torvalds 0 siblings, 2 replies; 20+ messages in thread From: Benjamin Herrenschmidt @ 2008-07-17 6:35 UTC (permalink / raw) To: Linus Torvalds, Andrew Morton Cc: linuxppc-dev, Nathan Lynch, linux-kernel, roland Hi Linus, Andrew ! Should I seek somebody's ack before merging a patch like the one below ? I'm a bit reluctant to merge via the powerpc.git tree some changes to generic files without at least an ack from somebody else :-) There have been some debate on whether this AT_BASE_PLATFORM is the right approach, though I haven't seen them reach any useful conclusion and our toolchain people internally are screaming for it... Cheers, Ben. On Tue, 2008-07-15 at 18:58 -0500, Nathan Lynch wrote: > Some IBM POWER-based platforms have the ability to run in a > mode which mostly appears to the OS as a different processor from the > actual hardware. For example, a Power6 system may appear to be a > Power5+, which makes the AT_PLATFORM value "power5+". This means that > programs are restricted to the ISA supported by Power5+; > Power6-specific instructions are treated as illegal. > > However, some applications (virtual machines, optimized libraries) can > benefit from knowledge of the underlying CPU model. A new aux vector > entry, AT_BASE_PLATFORM, will denote the actual hardware. For > example, on a Power6 system in Power5+ compatibility mode, AT_PLATFORM > will be "power5+" and AT_BASE_PLATFORM will be "power6". The idea is > that AT_PLATFORM indicates the instruction set supported, while > AT_BASE_PLATFORM indicates the underlying microarchitecture. > > If the architecture has defined ELF_BASE_PLATFORM, copy that value to > the user stack in the same manner as ELF_PLATFORM. > > Signed-off-by: Nathan Lynch <ntl@pobox.com> > --- > fs/binfmt_elf.c | 23 +++++++++++++++++++++++ > include/linux/auxvec.h | 5 ++++- > 2 files changed, 27 insertions(+), 1 deletions(-) > > diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c > index d48ff5f..834c2c4 100644 > --- a/fs/binfmt_elf.c > +++ b/fs/binfmt_elf.c > @@ -131,6 +131,10 @@ static int padzero(unsigned long elf_bss) > #define STACK_ALLOC(sp, len) ({ sp -= len ; sp; }) > #endif > > +#ifndef ELF_BASE_PLATFORM > +#define ELF_BASE_PLATFORM NULL > +#endif > + > static int > create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, > unsigned long load_addr, unsigned long interp_load_addr) > @@ -142,7 +146,9 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, > elf_addr_t __user *envp; > elf_addr_t __user *sp; > elf_addr_t __user *u_platform; > + elf_addr_t __user *u_base_platform; > const char *k_platform = ELF_PLATFORM; > + const char *k_base_platform = ELF_BASE_PLATFORM; > int items; > elf_addr_t *elf_info; > int ei_index = 0; > @@ -172,6 +178,19 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, > return -EFAULT; > } > > + /* > + * If this architecture has a "base" platform capability > + * string, copy it to userspace. > + */ > + u_base_platform = NULL; > + if (k_base_platform) { > + size_t len = strlen(k_base_platform) + 1; > + > + u_base_platform = (elf_addr_t __user *)STACK_ALLOC(p, len); > + if (__copy_to_user(u_base_platform, k_base_platform, len)) > + return -EFAULT; > + } > + > /* Create the ELF interpreter info */ > elf_info = (elf_addr_t *)current->mm->saved_auxv; > /* update AT_VECTOR_SIZE_BASE if the number of NEW_AUX_ENT() changes */ > @@ -208,6 +227,10 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, > NEW_AUX_ENT(AT_PLATFORM, > (elf_addr_t)(unsigned long)u_platform); > } > + if (k_base_platform) { > + NEW_AUX_ENT(AT_BASE_PLATFORM, > + (elf_addr_t)(unsigned long)u_base_platform); > + } > if (bprm->interp_flags & BINPRM_FLAGS_EXECFD) { > NEW_AUX_ENT(AT_EXECFD, bprm->interp_data); > } > diff --git a/include/linux/auxvec.h b/include/linux/auxvec.h > index ad89545..1adc61d 100644 > --- a/include/linux/auxvec.h > +++ b/include/linux/auxvec.h > @@ -26,8 +26,11 @@ > > #define AT_SECURE 23 /* secure mode boolean */ > > +#define AT_BASE_PLATFORM 38 /* string identifying real platform, may > + * differ from AT_PLATFORM. */ > + > #ifdef __KERNEL__ > -#define AT_VECTOR_SIZE_BASE (14 + 2) /* NEW_AUX_ENT entries in auxiliary table */ > +#define AT_VECTOR_SIZE_BASE (14 + 3) /* NEW_AUX_ENT entries in auxiliary table */ > #endif > > #endif /* _LINUX_AUXVEC_H */ ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] elf loader support for auxvec base platform string 2008-07-17 6:35 ` Benjamin Herrenschmidt @ 2008-07-17 7:09 ` Andrew Morton 2008-07-17 17:39 ` Nathan Lynch 2008-07-17 22:19 ` [PATCH v3] " Nathan Lynch 2008-07-17 16:10 ` [PATCH] " Linus Torvalds 1 sibling, 2 replies; 20+ messages in thread From: Andrew Morton @ 2008-07-17 7:09 UTC (permalink / raw) To: benh; +Cc: linuxppc-dev, Nathan Lynch, Linus Torvalds, linux-kernel, roland On Thu, 17 Jul 2008 16:35:39 +1000 Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote: > Hi Linus, Andrew ! > > Should I seek somebody's ack before merging a patch like the one below ? I think it's good to do so. > I'm a bit reluctant to merge via the powerpc.git tree some changes to > generic files without at least an ack from somebody else :-) It tends to happen. People often don't notice unless it a) crashes or b) spits warnings or c) screws up my tree or d) all the above plus more. > There have been some debate on whether this AT_BASE_PLATFORM is the > right approach, though I haven't seen them reach any useful conclusion > and our toolchain people internally are screaming for it... > > Cheers, > Ben. > > On Tue, 2008-07-15 at 18:58 -0500, Nathan Lynch wrote: > > Some IBM POWER-based platforms have the ability to run in a > > mode which mostly appears to the OS as a different processor from the > > actual hardware. For example, a Power6 system may appear to be a > > Power5+, which makes the AT_PLATFORM value "power5+". This means that > > programs are restricted to the ISA supported by Power5+; > > Power6-specific instructions are treated as illegal. > > > > However, some applications (virtual machines, optimized libraries) can > > benefit from knowledge of the underlying CPU model. A new aux vector > > entry, AT_BASE_PLATFORM, will denote the actual hardware. For > > example, on a Power6 system in Power5+ compatibility mode, AT_PLATFORM > > will be "power5+" and AT_BASE_PLATFORM will be "power6". The idea is > > that AT_PLATFORM indicates the instruction set supported, while > > AT_BASE_PLATFORM indicates the underlying microarchitecture. > > > > If the architecture has defined ELF_BASE_PLATFORM, copy that value to > > the user stack in the same manner as ELF_PLATFORM. > > > > Signed-off-by: Nathan Lynch <ntl@pobox.com> > > --- > > fs/binfmt_elf.c | 23 +++++++++++++++++++++++ > > include/linux/auxvec.h | 5 ++++- > > 2 files changed, 27 insertions(+), 1 deletions(-) > > > > diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c > > index d48ff5f..834c2c4 100644 > > --- a/fs/binfmt_elf.c > > +++ b/fs/binfmt_elf.c > > @@ -131,6 +131,10 @@ static int padzero(unsigned long elf_bss) > > #define STACK_ALLOC(sp, len) ({ sp -= len ; sp; }) > > #endif > > > > +#ifndef ELF_BASE_PLATFORM > > +#define ELF_BASE_PLATFORM NULL > > +#endif Please add a comment which explains what this is. Please also add a comment telling the world in which header file the architecture *must* define this macro and then ensure that that header is included into this file by reliable means. asm/elf.h looks OK. > > static int > > create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, > > unsigned long load_addr, unsigned long interp_load_addr) > > @@ -142,7 +146,9 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, > > elf_addr_t __user *envp; > > elf_addr_t __user *sp; > > elf_addr_t __user *u_platform; > > + elf_addr_t __user *u_base_platform; > > const char *k_platform = ELF_PLATFORM; > > + const char *k_base_platform = ELF_BASE_PLATFORM; > > int items; > > elf_addr_t *elf_info; > > int ei_index = 0; > > @@ -172,6 +178,19 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, > > return -EFAULT; > > } > > > > + /* > > + * If this architecture has a "base" platform capability > > + * string, copy it to userspace. > > + */ > > + u_base_platform = NULL; > > + if (k_base_platform) { > > + size_t len = strlen(k_base_platform) + 1; > > + > > + u_base_platform = (elf_addr_t __user *)STACK_ALLOC(p, len); > > + if (__copy_to_user(u_base_platform, k_base_platform, len)) > > + return -EFAULT; > > + } >From my reading, this change will result in no additional code generation on non-powerpc architectures. This is good. If poss, could you please verify that theory and perhaps drop a note in the changelog about that? Apart from that - acked-by-me ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] elf loader support for auxvec base platform string 2008-07-17 7:09 ` Andrew Morton @ 2008-07-17 17:39 ` Nathan Lynch 2008-07-17 22:19 ` [PATCH v3] " Nathan Lynch 1 sibling, 0 replies; 20+ messages in thread From: Nathan Lynch @ 2008-07-17 17:39 UTC (permalink / raw) To: Andrew Morton; +Cc: Linus Torvalds, linux-kernel, roland, linuxppc-dev Andrew Morton wrote: > > On Tue, 2008-07-15 at 18:58 -0500, Nathan Lynch wrote: > > > diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c > > > index d48ff5f..834c2c4 100644 > > > --- a/fs/binfmt_elf.c > > > +++ b/fs/binfmt_elf.c > > > @@ -131,6 +131,10 @@ static int padzero(unsigned long elf_bss) > > > #define STACK_ALLOC(sp, len) ({ sp -= len ; sp; }) > > > #endif > > > > > > +#ifndef ELF_BASE_PLATFORM > > > +#define ELF_BASE_PLATFORM NULL > > > +#endif > > Please add a comment which explains what this is. > > Please also add a comment telling the world in which header file the > architecture *must* define this macro and then ensure that that header is > included into this file by reliable means. asm/elf.h looks OK. Okay. > > > @@ -172,6 +178,19 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, > > > return -EFAULT; > > > } > > > > > > + /* > > > + * If this architecture has a "base" platform capability > > > + * string, copy it to userspace. > > > + */ > > > + u_base_platform = NULL; > > > + if (k_base_platform) { > > > + size_t len = strlen(k_base_platform) + 1; > > > + > > > + u_base_platform = (elf_addr_t __user *)STACK_ALLOC(p, len); > > > + if (__copy_to_user(u_base_platform, k_base_platform, len)) > > > + return -EFAULT; > > > + } > > >From my reading, this change will result in no additional code > generation on non-powerpc architectures. This is good. If poss, could > you please verify that theory and perhaps drop a note in the changelog > about that? That was the intent, yes. However: $ scripts/bloat-o-meter vmlinux-x86-{before,after} add/remove: 0/0 grow/shrink: 2/0 up/down: 18/0 (18) function old new delta init_mm 784 800 +16 load_elf_binary 11946 11948 +2 (x86_64_defconfig, gcc 4.2.3) The init_mm/mm_struct bloat is expected (although I'd like to avoid that), but evidently it has some small effect on load_elf_binary. ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v3] elf loader support for auxvec base platform string 2008-07-17 7:09 ` Andrew Morton 2008-07-17 17:39 ` Nathan Lynch @ 2008-07-17 22:19 ` Nathan Lynch 2008-07-17 22:42 ` Andrew Morton 1 sibling, 1 reply; 20+ messages in thread From: Nathan Lynch @ 2008-07-17 22:19 UTC (permalink / raw) To: Andrew Morton; +Cc: Linus Torvalds, linux-kernel, roland, linuxppc-dev Some IBM POWER-based platforms have the ability to run in a mode which mostly appears to the OS as a different processor from the actual hardware. For example, a Power6 system may appear to be a Power5+, which makes the AT_PLATFORM value "power5+". This means that programs are restricted to the ISA supported by Power5+; Power6-specific instructions are treated as illegal. However, some applications (virtual machines, optimized libraries) can benefit from knowledge of the underlying CPU model. A new aux vector entry, AT_BASE_PLATFORM, will denote the actual hardware. For example, on a Power6 system in Power5+ compatibility mode, AT_PLATFORM will be "power5+" and AT_BASE_PLATFORM will be "power6". The idea is that AT_PLATFORM indicates the instruction set supported, while AT_BASE_PLATFORM indicates the underlying microarchitecture. If the architecture has defined ELF_BASE_PLATFORM, copy that value to the user stack in the same manner as ELF_PLATFORM. Signed-off-by: Nathan Lynch <ntl@pobox.com> --- Added comment explaining ELF_BASE_PLATFORM. fs/binfmt_elf.c | 28 ++++++++++++++++++++++++++++ include/linux/auxvec.h | 5 ++++- 2 files changed, 32 insertions(+), 1 deletions(-) diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index d48ff5f..d8a7cc0 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -131,6 +131,15 @@ static int padzero(unsigned long elf_bss) #define STACK_ALLOC(sp, len) ({ sp -= len ; sp; }) #endif +#ifndef ELF_BASE_PLATFORM +/* + * AT_BASE_PLATFORM indicates the "real" hardware/microarchitecture. + * If the arch defines ELF_BASE_PLATFORM (in asm/elf.h), the value + * will be copied to the user stack in the same manner as AT_PLATFORM. + */ +#define ELF_BASE_PLATFORM NULL +#endif + static int create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, unsigned long load_addr, unsigned long interp_load_addr) @@ -142,7 +151,9 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, elf_addr_t __user *envp; elf_addr_t __user *sp; elf_addr_t __user *u_platform; + elf_addr_t __user *u_base_platform; const char *k_platform = ELF_PLATFORM; + const char *k_base_platform = ELF_BASE_PLATFORM; int items; elf_addr_t *elf_info; int ei_index = 0; @@ -172,6 +183,19 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, return -EFAULT; } + /* + * If this architecture has a "base" platform capability + * string, copy it to userspace. + */ + u_base_platform = NULL; + if (k_base_platform) { + size_t len = strlen(k_base_platform) + 1; + + u_base_platform = (elf_addr_t __user *)STACK_ALLOC(p, len); + if (__copy_to_user(u_base_platform, k_base_platform, len)) + return -EFAULT; + } + /* Create the ELF interpreter info */ elf_info = (elf_addr_t *)current->mm->saved_auxv; /* update AT_VECTOR_SIZE_BASE if the number of NEW_AUX_ENT() changes */ @@ -208,6 +232,10 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, NEW_AUX_ENT(AT_PLATFORM, (elf_addr_t)(unsigned long)u_platform); } + if (k_base_platform) { + NEW_AUX_ENT(AT_BASE_PLATFORM, + (elf_addr_t)(unsigned long)u_base_platform); + } if (bprm->interp_flags & BINPRM_FLAGS_EXECFD) { NEW_AUX_ENT(AT_EXECFD, bprm->interp_data); } diff --git a/include/linux/auxvec.h b/include/linux/auxvec.h index ad89545..1adc61d 100644 --- a/include/linux/auxvec.h +++ b/include/linux/auxvec.h @@ -26,8 +26,11 @@ #define AT_SECURE 23 /* secure mode boolean */ +#define AT_BASE_PLATFORM 38 /* string identifying real platform, may + * differ from AT_PLATFORM. */ + #ifdef __KERNEL__ -#define AT_VECTOR_SIZE_BASE (14 + 2) /* NEW_AUX_ENT entries in auxiliary table */ +#define AT_VECTOR_SIZE_BASE (14 + 3) /* NEW_AUX_ENT entries in auxiliary table */ #endif #endif /* _LINUX_AUXVEC_H */ -- 1.5.6.2 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH v3] elf loader support for auxvec base platform string 2008-07-17 22:19 ` [PATCH v3] " Nathan Lynch @ 2008-07-17 22:42 ` Andrew Morton 2008-07-17 23:35 ` John Reiser 2008-07-21 18:48 ` [PATCH v4] " Nathan Lynch 0 siblings, 2 replies; 20+ messages in thread From: Andrew Morton @ 2008-07-17 22:42 UTC (permalink / raw) To: Nathan Lynch; +Cc: John Reiser, linux-kernel, linuxppc-dev, torvalds, roland On Thu, 17 Jul 2008 17:19:32 -0500 Nathan Lynch <ntl@pobox.com> wrote: > Some IBM POWER-based platforms have the ability to run in a > mode which mostly appears to the OS as a different processor from the > actual hardware. For example, a Power6 system may appear to be a > Power5+, which makes the AT_PLATFORM value "power5+". This means that > programs are restricted to the ISA supported by Power5+; > Power6-specific instructions are treated as illegal. > > However, some applications (virtual machines, optimized libraries) can > benefit from knowledge of the underlying CPU model. A new aux vector > entry, AT_BASE_PLATFORM, will denote the actual hardware. For > example, on a Power6 system in Power5+ compatibility mode, AT_PLATFORM > will be "power5+" and AT_BASE_PLATFORM will be "power6". The idea is > that AT_PLATFORM indicates the instruction set supported, while > AT_BASE_PLATFORM indicates the underlying microarchitecture. > > If the architecture has defined ELF_BASE_PLATFORM, copy that value to > the user stack in the same manner as ELF_PLATFORM. > > Signed-off-by: Nathan Lynch <ntl@pobox.com> > > --- > > Added comment explaining ELF_BASE_PLATFORM. > > fs/binfmt_elf.c | 28 ++++++++++++++++++++++++++++ > include/linux/auxvec.h | 5 ++++- > 2 files changed, 32 insertions(+), 1 deletions(-) > > diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c > index d48ff5f..d8a7cc0 100644 > --- a/fs/binfmt_elf.c > +++ b/fs/binfmt_elf.c > @@ -131,6 +131,15 @@ static int padzero(unsigned long elf_bss) > #define STACK_ALLOC(sp, len) ({ sp -= len ; sp; }) > #endif > > +#ifndef ELF_BASE_PLATFORM > +/* > + * AT_BASE_PLATFORM indicates the "real" hardware/microarchitecture. > + * If the arch defines ELF_BASE_PLATFORM (in asm/elf.h), the value > + * will be copied to the user stack in the same manner as AT_PLATFORM. > + */ > +#define ELF_BASE_PLATFORM NULL > +#endif > + > static int > create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, > unsigned long load_addr, unsigned long interp_load_addr) > @@ -142,7 +151,9 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, > elf_addr_t __user *envp; > elf_addr_t __user *sp; > elf_addr_t __user *u_platform; > + elf_addr_t __user *u_base_platform; > const char *k_platform = ELF_PLATFORM; > + const char *k_base_platform = ELF_BASE_PLATFORM; > int items; > elf_addr_t *elf_info; > int ei_index = 0; > @@ -172,6 +183,19 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, > return -EFAULT; > } > > + /* > + * If this architecture has a "base" platform capability > + * string, copy it to userspace. > + */ > + u_base_platform = NULL; > + if (k_base_platform) { > + size_t len = strlen(k_base_platform) + 1; > + > + u_base_platform = (elf_addr_t __user *)STACK_ALLOC(p, len); > + if (__copy_to_user(u_base_platform, k_base_platform, len)) > + return -EFAULT; > + } > + > /* Create the ELF interpreter info */ > elf_info = (elf_addr_t *)current->mm->saved_auxv; > /* update AT_VECTOR_SIZE_BASE if the number of NEW_AUX_ENT() changes */ > @@ -208,6 +232,10 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, > NEW_AUX_ENT(AT_PLATFORM, > (elf_addr_t)(unsigned long)u_platform); > } > + if (k_base_platform) { > + NEW_AUX_ENT(AT_BASE_PLATFORM, > + (elf_addr_t)(unsigned long)u_base_platform); > + } > if (bprm->interp_flags & BINPRM_FLAGS_EXECFD) { > NEW_AUX_ENT(AT_EXECFD, bprm->interp_data); > } > diff --git a/include/linux/auxvec.h b/include/linux/auxvec.h > index ad89545..1adc61d 100644 > --- a/include/linux/auxvec.h > +++ b/include/linux/auxvec.h > @@ -26,8 +26,11 @@ > > #define AT_SECURE 23 /* secure mode boolean */ > > +#define AT_BASE_PLATFORM 38 /* string identifying real platform, may > + * differ from AT_PLATFORM. */ > + > #ifdef __KERNEL__ > -#define AT_VECTOR_SIZE_BASE (14 + 2) /* NEW_AUX_ENT entries in auxiliary table */ > +#define AT_VECTOR_SIZE_BASE (14 + 3) /* NEW_AUX_ENT entries in auxiliary table */ > #endif > > #endif /* _LINUX_AUXVEC_H */ OK. But it conflicts directly with the already-queued execve-filename-document-and-export-via-auxiliary-vector.patch (which various potential reviewers blithely deleted - don't come complaining to me!): From: John Reiser <jreiser@BitWagon.com> The Linux kernel puts the filename argument of execve() into the new address space. Many developers are surprised to learn this. Those who know and could use it, object "But it's not documented." Those who want to use it dislike the expression (char *)(1+ strlen(env[-1+ n_env]) + env[-1+ n_env]) because it requires locating the last original environment variable, and assumes that the filename follows the characters. This patch documents the insertion of the filename, and makes it easier to find by adding a new tag AT_EXECFN in the ElfXX_auxv_t; see <elf.h>. In many cases readlink("/proc/self/exe",) gives the same answer. But if all the original pages get unmapped, then the kernel erases the symlink for /proc/self/exe. This can happen when a program decompressor does a good job of cleaning up after uncompressing directly to memory, so that the address space of the target program looks the same as if compression had never happened. One example is http://upx.sourceforge.net . One notable use of the underlying concept (what path containED the executable) is glibc expanding $ORIGIN in DT_RUNPATH. In practice for the near term, it may be a good idea for user-mode code to use both /proc/self/exe and AT_EXECFN as fall-back methods for each other. /proc/self/exe can fail due to unmapping, AT_EXECFN can fail because it won't be present on non-new systems. The auxvec or {AT_EXECFN}.d_val also can get overwritten, although in nearly all cases this would be the result of a bug. The runtime cost is one NEW_AUX_ENT using two words of stack space. The underlying value is maintained already as bprm->exec; setup_arg_pages() in fs/exec.c slides it for stack_shift, etc. Signed-off-by: John Reiser <jreiser@BitWagon.com> Cc: Roland McGrath <roland@redhat.com> Cc: Jakub Jelinek <jakub@redhat.com> Cc: Ulrich Drepper <drepper@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> --- fs/binfmt_elf.c | 1 + include/linux/auxvec.h | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff -puN fs/binfmt_elf.c~execve-filename-document-and-export-via-auxiliary-vector fs/binfmt_elf.c --- a/fs/binfmt_elf.c~execve-filename-document-and-export-via-auxiliary-vector +++ a/fs/binfmt_elf.c @@ -204,6 +204,7 @@ create_elf_tables(struct linux_binprm *b NEW_AUX_ENT(AT_GID, tsk->gid); NEW_AUX_ENT(AT_EGID, tsk->egid); NEW_AUX_ENT(AT_SECURE, security_bprm_secureexec(bprm)); + NEW_AUX_ENT(AT_EXECFN, bprm->exec); if (k_platform) { NEW_AUX_ENT(AT_PLATFORM, (elf_addr_t)(unsigned long)u_platform); diff -puN include/linux/auxvec.h~execve-filename-document-and-export-via-auxiliary-vector include/linux/auxvec.h --- a/include/linux/auxvec.h~execve-filename-document-and-export-via-auxiliary-vector +++ a/include/linux/auxvec.h @@ -26,8 +26,10 @@ #define AT_SECURE 23 /* secure mode boolean */ +#define AT_EXECFN 31 /* filename of program */ #ifdef __KERNEL__ -#define AT_VECTOR_SIZE_BASE (14 + 2) /* NEW_AUX_ENT entries in auxiliary table */ +#define AT_VECTOR_SIZE_BASE 17 /* NEW_AUX_ENT entries in auxiliary table */ + /* number of "#define AT_.*" above, minus {AT_NULL, AT_IGNORE, AT_NOTELF} */ #endif #endif /* _LINUX_AUXVEC_H */ _ ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3] elf loader support for auxvec base platform string 2008-07-17 22:42 ` Andrew Morton @ 2008-07-17 23:35 ` John Reiser 2008-07-18 18:28 ` Nathan Lynch 2008-07-21 18:48 ` [PATCH v4] " Nathan Lynch 1 sibling, 1 reply; 20+ messages in thread From: John Reiser @ 2008-07-17 23:35 UTC (permalink / raw) To: Andrew Morton; +Cc: linux-kernel, linuxppc-dev, Nathan Lynch, torvalds, roland Andrew Morton wrote: > On Thu, 17 Jul 2008 17:19:32 -0500 > Nathan Lynch <ntl@pobox.com> wrote: > > >> [snip] >> A new aux vector entry, AT_BASE_PLATFORM, will denote the actual hardware. [snip] > OK. > > But it conflicts directly with the already-queued > execve-filename-document-and-export-via-auxiliary-vector.patch [snip] It seems to me that most of the patch conflicts are mechanical and could be merged mechanically. However I believe that the documentation change to this comment is important: ----- > #ifdef __KERNEL__ > -#define AT_VECTOR_SIZE_BASE (14 + 2) /* NEW_AUX_ENT entries in auxiliary table */ > +#define AT_VECTOR_SIZE_BASE 17 /* NEW_AUX_ENT entries in auxiliary table */ > + /* number of "#define AT_.*" above, minus {AT_NULL, AT_IGNORE, AT_NOTELF} */ > #endif ----- I scratched my head for a while to figure out that AT_NOTELF also was a subtraction as far as AT_VECTOR_SIZE_BASE was concerned. -- John Reiser, jreiser@BitWagon.com ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3] elf loader support for auxvec base platform string 2008-07-17 23:35 ` John Reiser @ 2008-07-18 18:28 ` Nathan Lynch 2008-07-18 20:31 ` John Reiser 2008-07-21 3:24 ` Benjamin Herrenschmidt 0 siblings, 2 replies; 20+ messages in thread From: Nathan Lynch @ 2008-07-18 18:28 UTC (permalink / raw) To: John Reiser; +Cc: linux-kernel, linuxppc-dev, Andrew Morton, torvalds, roland John Reiser wrote: > Andrew Morton wrote: > > On Thu, 17 Jul 2008 17:19:32 -0500 > > Nathan Lynch <ntl@pobox.com> wrote: > > > > > >> [snip] > >> A new aux vector entry, AT_BASE_PLATFORM, will denote the actual hardware. > [snip] > > > OK. > > > > But it conflicts directly with the already-queued > > execve-filename-document-and-export-via-auxiliary-vector.patch Okay, I can rebase on -mm. > It seems to me that most of the patch conflicts are mechanical > and could be merged mechanically. > > However I believe that the documentation change to this comment is important: > ----- > > #ifdef __KERNEL__ > > -#define AT_VECTOR_SIZE_BASE (14 + 2) /* NEW_AUX_ENT entries in auxiliary table */ > > +#define AT_VECTOR_SIZE_BASE 17 /* NEW_AUX_ENT entries in auxiliary table */ > > + /* number of "#define AT_.*" above, minus {AT_NULL, AT_IGNORE, AT_NOTELF} */ > > #endif > ----- > I scratched my head for a while to figure out that AT_NOTELF also was > a subtraction as far as AT_VECTOR_SIZE_BASE was concerned. John, from your patch: +#define AT_EXECFN 31 /* filename of program */ How did you arrive at 31 for the value of AT_EXECFN? I haven't been able to find out how AT_* values are "allocated", or what the reason is for the gap between AT_SECURE and AT_SYSINFO. ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3] elf loader support for auxvec base platform string 2008-07-18 18:28 ` Nathan Lynch @ 2008-07-18 20:31 ` John Reiser 2008-07-18 20:52 ` Andrew Morton 2008-07-21 3:24 ` Benjamin Herrenschmidt 1 sibling, 1 reply; 20+ messages in thread From: John Reiser @ 2008-07-18 20:31 UTC (permalink / raw) To: Nathan Lynch; +Cc: linux-kernel, linuxppc-dev, Andrew Morton, torvalds, roland Nathan Lynch wrote: > +#define AT_EXECFN 31 /* filename of program */ > > How did you arrive at 31 for the value of AT_EXECFN? I haven't been > able to find out how AT_* values are "allocated", or what the reason > is for the gap between AT_SECURE and AT_SYSINFO. The numbers are chosen by experience, taste, and fiat. Hopefully new choices do not conflict with existing ones, but there is no formal "issuing authority." In history the auxiliary vector has been not well standardized and many times has been hidden from view of applications, although some SysV-based systems have made it visible as a fourth argument to main(). Linux has /proc/pid/auxv, although the implementation suffers from being exposed to overwriting by the user. From long experience at virtualization in user mode, I favor better access, more use, and better understanding of what the auxiliary vector provides. AT_SYSINFO at 32 was chosen to avoid conflicts with [0,31] partly on the theory that the first 32 might be considered to be reserved for use across all UNIX-like systems, while AT_SYSINFO definitely was Linux-specific. I chose AT_EXECFN at 31 because I considered the concept to be applicable to any system having execve(), even if AT_EXECFN is not universally implemented. I had not seen any new tags below 32 in a long time. The concept of AT_EXECFN allows a nice interface for a virtualizer. The somewhat-related AT_EXECFD already exists below 32. Elsewhere, I've staked out use of a new AT_WINE_PRELOAD_INFO at 30. Avoid that one, please. :-) -- John Reiser, jreiser@BitWagon.com ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3] elf loader support for auxvec base platform string 2008-07-18 20:31 ` John Reiser @ 2008-07-18 20:52 ` Andrew Morton 0 siblings, 0 replies; 20+ messages in thread From: Andrew Morton @ 2008-07-18 20:52 UTC (permalink / raw) To: John Reiser; +Cc: linux-kernel, linuxppc-dev, ntl, torvalds, roland On Fri, 18 Jul 2008 13:31:29 -0700 John Reiser <jreiser@BitWagon.com> wrote: > Elsewhere, I've staked out use of a new AT_WINE_PRELOAD_INFO > at 30. Avoid that one, please. :-) The reliable way in which to reserve these numbers is to patch the header file. ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3] elf loader support for auxvec base platform string 2008-07-18 18:28 ` Nathan Lynch 2008-07-18 20:31 ` John Reiser @ 2008-07-21 3:24 ` Benjamin Herrenschmidt 2008-07-21 3:40 ` Andrew Morton 1 sibling, 1 reply; 20+ messages in thread From: Benjamin Herrenschmidt @ 2008-07-21 3:24 UTC (permalink / raw) To: Andrew Morton Cc: John Reiser, linux-kernel, linuxppc-dev, Nathan Lynch, torvalds, roland On Fri, 2008-07-18 at 13:28 -0500, Nathan Lynch wrote: > John Reiser wrote: > > Andrew Morton wrote: > > > On Thu, 17 Jul 2008 17:19:32 -0500 > > > Nathan Lynch <ntl@pobox.com> wrote: > > > > > > > > >> [snip] > > >> A new aux vector entry, AT_BASE_PLATFORM, will denote the actual hardware. > > [snip] > > > > > OK. > > > > > > But it conflicts directly with the already-queued > > > execve-filename-document-and-export-via-auxiliary-vector.patch > > Okay, I can rebase on -mm. Andrew, we have one other patch (the powerpc bits) on top of that one. Do you want to carry both in -mm on top of John's patch ? We would like that in .27 though, I don't know what your merge plans are for John's patch. Cheers, Ben. ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3] elf loader support for auxvec base platform string 2008-07-21 3:24 ` Benjamin Herrenschmidt @ 2008-07-21 3:40 ` Andrew Morton 2008-07-21 9:33 ` Benjamin Herrenschmidt 0 siblings, 1 reply; 20+ messages in thread From: Andrew Morton @ 2008-07-21 3:40 UTC (permalink / raw) To: benh Cc: John Reiser, linux-kernel, linuxppc-dev, Nathan Lynch, torvalds, roland On Mon, 21 Jul 2008 13:24:15 +1000 Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote: > On Fri, 2008-07-18 at 13:28 -0500, Nathan Lynch wrote: > > John Reiser wrote: > > > Andrew Morton wrote: > > > > On Thu, 17 Jul 2008 17:19:32 -0500 > > > > Nathan Lynch <ntl@pobox.com> wrote: > > > > > > > > > > > >> [snip] > > > >> A new aux vector entry, AT_BASE_PLATFORM, will denote the actual hardware. > > > [snip] > > > > > > > OK. > > > > > > > > But it conflicts directly with the already-queued > > > > execve-filename-document-and-export-via-auxiliary-vector.patch > > > > Okay, I can rebase on -mm. > > Andrew, we have one other patch (the powerpc bits) on top of that one. > Do you want to carry both in -mm on top of John's patch ? We would like > that in .27 though, I don't know what your merge plans are for John's > patch. > How about I send John's patch Linuswards right now? ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3] elf loader support for auxvec base platform string 2008-07-21 3:40 ` Andrew Morton @ 2008-07-21 9:33 ` Benjamin Herrenschmidt 0 siblings, 0 replies; 20+ messages in thread From: Benjamin Herrenschmidt @ 2008-07-21 9:33 UTC (permalink / raw) To: Andrew Morton Cc: John Reiser, linux-kernel, linuxppc-dev, Nathan Lynch, torvalds, roland > > Andrew, we have one other patch (the powerpc bits) on top of that one. > > Do you want to carry both in -mm on top of John's patch ? We would like > > that in .27 though, I don't know what your merge plans are for John's > > patch. > > > > How about I send John's patch Linuswards right now? No objection. Cheers, Ben. ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v4] elf loader support for auxvec base platform string 2008-07-17 22:42 ` Andrew Morton 2008-07-17 23:35 ` John Reiser @ 2008-07-21 18:48 ` Nathan Lynch 2008-07-22 2:03 ` Benjamin Herrenschmidt 1 sibling, 1 reply; 20+ messages in thread From: Nathan Lynch @ 2008-07-21 18:48 UTC (permalink / raw) To: Andrew Morton; +Cc: John Reiser, linux-kernel, linuxppc-dev, torvalds, roland Some IBM POWER-based platforms have the ability to run in a mode which mostly appears to the OS as a different processor from the actual hardware. For example, a Power6 system may appear to be a Power5+, which makes the AT_PLATFORM value "power5+". This means that programs are restricted to the ISA supported by Power5+; Power6-specific instructions are treated as illegal. However, some applications (virtual machines, optimized libraries) can benefit from knowledge of the underlying CPU model. A new aux vector entry, AT_BASE_PLATFORM, will denote the actual hardware. For example, on a Power6 system in Power5+ compatibility mode, AT_PLATFORM will be "power5+" and AT_BASE_PLATFORM will be "power6". The idea is that AT_PLATFORM indicates the instruction set supported, while AT_BASE_PLATFORM indicates the underlying microarchitecture. If the architecture has defined ELF_BASE_PLATFORM, copy that value to the user stack in the same manner as ELF_PLATFORM. Signed-off-by: Nathan Lynch <ntl@pobox.com> --- Andrew Morton wrote: > OK. > > But it conflicts directly with the already-queued > execve-filename-document-and-export-via-auxiliary-vector.patch (which > various potential reviewers blithely deleted - don't come complaining > to me!): > Rebased to -mm to resolve conflicts with execve-filename-document-and-export-via-auxiliary-vector.patch, and changed AT_BASE_PLATFORM to lowest unclaimed value (24). fs/binfmt_elf.c | 28 ++++++++++++++++++++++++++++ include/linux/auxvec.h | 6 +++++- 2 files changed, 33 insertions(+), 1 deletions(-) diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index bad7d87..180f92b 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -131,6 +131,15 @@ static int padzero(unsigned long elf_bss) #define STACK_ALLOC(sp, len) ({ sp -= len ; sp; }) #endif +#ifndef ELF_BASE_PLATFORM +/* + * AT_BASE_PLATFORM indicates the "real" hardware/microarchitecture. + * If the arch defines ELF_BASE_PLATFORM (in asm/elf.h), the value + * will be copied to the user stack in the same manner as AT_PLATFORM. + */ +#define ELF_BASE_PLATFORM NULL +#endif + static int create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, unsigned long load_addr, unsigned long interp_load_addr) @@ -142,7 +151,9 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, elf_addr_t __user *envp; elf_addr_t __user *sp; elf_addr_t __user *u_platform; + elf_addr_t __user *u_base_platform; const char *k_platform = ELF_PLATFORM; + const char *k_base_platform = ELF_BASE_PLATFORM; int items; elf_addr_t *elf_info; int ei_index = 0; @@ -172,6 +183,19 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, return -EFAULT; } + /* + * If this architecture has a "base" platform capability + * string, copy it to userspace. + */ + u_base_platform = NULL; + if (k_base_platform) { + size_t len = strlen(k_base_platform) + 1; + + u_base_platform = (elf_addr_t __user *)STACK_ALLOC(p, len); + if (__copy_to_user(u_base_platform, k_base_platform, len)) + return -EFAULT; + } + /* Create the ELF interpreter info */ elf_info = (elf_addr_t *)current->mm->saved_auxv; /* update AT_VECTOR_SIZE_BASE if the number of NEW_AUX_ENT() changes */ @@ -209,6 +233,10 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, NEW_AUX_ENT(AT_PLATFORM, (elf_addr_t)(unsigned long)u_platform); } + if (k_base_platform) { + NEW_AUX_ENT(AT_BASE_PLATFORM, + (elf_addr_t)(unsigned long)u_base_platform); + } if (bprm->interp_flags & BINPRM_FLAGS_EXECFD) { NEW_AUX_ENT(AT_EXECFD, bprm->interp_data); } diff --git a/include/linux/auxvec.h b/include/linux/auxvec.h index 0da17d1..d7afa9d 100644 --- a/include/linux/auxvec.h +++ b/include/linux/auxvec.h @@ -26,9 +26,13 @@ #define AT_SECURE 23 /* secure mode boolean */ +#define AT_BASE_PLATFORM 24 /* string identifying real platform, may + * differ from AT_PLATFORM. */ + #define AT_EXECFN 31 /* filename of program */ + #ifdef __KERNEL__ -#define AT_VECTOR_SIZE_BASE 17 /* NEW_AUX_ENT entries in auxiliary table */ +#define AT_VECTOR_SIZE_BASE 18 /* NEW_AUX_ENT entries in auxiliary table */ /* number of "#define AT_.*" above, minus {AT_NULL, AT_IGNORE, AT_NOTELF} */ #endif -- 1.5.6.2 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH v4] elf loader support for auxvec base platform string 2008-07-21 18:48 ` [PATCH v4] " Nathan Lynch @ 2008-07-22 2:03 ` Benjamin Herrenschmidt 0 siblings, 0 replies; 20+ messages in thread From: Benjamin Herrenschmidt @ 2008-07-22 2:03 UTC (permalink / raw) To: Nathan Lynch Cc: John Reiser, linux-kernel, linuxppc-dev, Andrew Morton, torvalds, roland On Mon, 2008-07-21 at 13:48 -0500, Nathan Lynch wrote: > Some IBM POWER-based platforms have the ability to run in a > mode which mostly appears to the OS as a different processor from the > actual hardware. For example, a Power6 system may appear to be a > Power5+, which makes the AT_PLATFORM value "power5+". This means that > programs are restricted to the ISA supported by Power5+; > Power6-specific instructions are treated as illegal. > > However, some applications (virtual machines, optimized libraries) can > benefit from knowledge of the underlying CPU model. A new aux vector > entry, AT_BASE_PLATFORM, will denote the actual hardware. For > example, on a Power6 system in Power5+ compatibility mode, AT_PLATFORM > will be "power5+" and AT_BASE_PLATFORM will be "power6". The idea is > that AT_PLATFORM indicates the instruction set supported, while > AT_BASE_PLATFORM indicates the underlying microarchitecture. > > If the architecture has defined ELF_BASE_PLATFORM, copy that value to > the user stack in the same manner as ELF_PLATFORM. > > Signed-off-by: Nathan Lynch <ntl@pobox.com> Andrew, I'll merge that after John patch shows up if you give me your Ack :-) Cheers, Ben. > --- > > Andrew Morton wrote: > > OK. > > > > But it conflicts directly with the already-queued > > execve-filename-document-and-export-via-auxiliary-vector.patch (which > > various potential reviewers blithely deleted - don't come complaining > > to me!): > > > > Rebased to -mm to resolve conflicts with > execve-filename-document-and-export-via-auxiliary-vector.patch, and > changed AT_BASE_PLATFORM to lowest unclaimed value (24). > > > fs/binfmt_elf.c | 28 ++++++++++++++++++++++++++++ > include/linux/auxvec.h | 6 +++++- > 2 files changed, 33 insertions(+), 1 deletions(-) > > diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c > index bad7d87..180f92b 100644 > --- a/fs/binfmt_elf.c > +++ b/fs/binfmt_elf.c > @@ -131,6 +131,15 @@ static int padzero(unsigned long elf_bss) > #define STACK_ALLOC(sp, len) ({ sp -= len ; sp; }) > #endif > > +#ifndef ELF_BASE_PLATFORM > +/* > + * AT_BASE_PLATFORM indicates the "real" hardware/microarchitecture. > + * If the arch defines ELF_BASE_PLATFORM (in asm/elf.h), the value > + * will be copied to the user stack in the same manner as AT_PLATFORM. > + */ > +#define ELF_BASE_PLATFORM NULL > +#endif > + > static int > create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, > unsigned long load_addr, unsigned long interp_load_addr) > @@ -142,7 +151,9 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, > elf_addr_t __user *envp; > elf_addr_t __user *sp; > elf_addr_t __user *u_platform; > + elf_addr_t __user *u_base_platform; > const char *k_platform = ELF_PLATFORM; > + const char *k_base_platform = ELF_BASE_PLATFORM; > int items; > elf_addr_t *elf_info; > int ei_index = 0; > @@ -172,6 +183,19 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, > return -EFAULT; > } > > + /* > + * If this architecture has a "base" platform capability > + * string, copy it to userspace. > + */ > + u_base_platform = NULL; > + if (k_base_platform) { > + size_t len = strlen(k_base_platform) + 1; > + > + u_base_platform = (elf_addr_t __user *)STACK_ALLOC(p, len); > + if (__copy_to_user(u_base_platform, k_base_platform, len)) > + return -EFAULT; > + } > + > /* Create the ELF interpreter info */ > elf_info = (elf_addr_t *)current->mm->saved_auxv; > /* update AT_VECTOR_SIZE_BASE if the number of NEW_AUX_ENT() changes */ > @@ -209,6 +233,10 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, > NEW_AUX_ENT(AT_PLATFORM, > (elf_addr_t)(unsigned long)u_platform); > } > + if (k_base_platform) { > + NEW_AUX_ENT(AT_BASE_PLATFORM, > + (elf_addr_t)(unsigned long)u_base_platform); > + } > if (bprm->interp_flags & BINPRM_FLAGS_EXECFD) { > NEW_AUX_ENT(AT_EXECFD, bprm->interp_data); > } > diff --git a/include/linux/auxvec.h b/include/linux/auxvec.h > index 0da17d1..d7afa9d 100644 > --- a/include/linux/auxvec.h > +++ b/include/linux/auxvec.h > @@ -26,9 +26,13 @@ > > #define AT_SECURE 23 /* secure mode boolean */ > > +#define AT_BASE_PLATFORM 24 /* string identifying real platform, may > + * differ from AT_PLATFORM. */ > + > #define AT_EXECFN 31 /* filename of program */ > + > #ifdef __KERNEL__ > -#define AT_VECTOR_SIZE_BASE 17 /* NEW_AUX_ENT entries in auxiliary table */ > +#define AT_VECTOR_SIZE_BASE 18 /* NEW_AUX_ENT entries in auxiliary table */ > /* number of "#define AT_.*" above, minus {AT_NULL, AT_IGNORE, AT_NOTELF} */ > #endif > ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] elf loader support for auxvec base platform string 2008-07-17 6:35 ` Benjamin Herrenschmidt 2008-07-17 7:09 ` Andrew Morton @ 2008-07-17 16:10 ` Linus Torvalds 2008-07-17 19:35 ` Nathan Lynch 2008-07-21 3:19 ` Benjamin Herrenschmidt 1 sibling, 2 replies; 20+ messages in thread From: Linus Torvalds @ 2008-07-17 16:10 UTC (permalink / raw) To: Benjamin Herrenschmidt Cc: linuxppc-dev, Andrew Morton, Nathan Lynch, linux-kernel, roland On Thu, 17 Jul 2008, Benjamin Herrenschmidt wrote: > > Should I seek somebody's ack before merging a patch like the one below ? > > I'm a bit reluctant to merge via the powerpc.git tree some changes to > generic files without at least an ack from somebody else :-) Gaah. Generally we don't, but you're right to ask. The ELF loading keeps on accumulating these things, and I'm not sure we have the right process for things like this. They're all individually small and insignificant, and they are all individually never going away and making the ELF loader messier and messier. I dunno. Linus ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] elf loader support for auxvec base platform string 2008-07-17 16:10 ` [PATCH] " Linus Torvalds @ 2008-07-17 19:35 ` Nathan Lynch 2008-07-21 3:19 ` Benjamin Herrenschmidt 1 sibling, 0 replies; 20+ messages in thread From: Nathan Lynch @ 2008-07-17 19:35 UTC (permalink / raw) To: Linus Torvalds; +Cc: Andrew Morton, linux-kernel, roland, linuxppc-dev Linus Torvalds wrote: > > > On Thu, 17 Jul 2008, Benjamin Herrenschmidt wrote: > > > > Should I seek somebody's ack before merging a patch like the one below ? > > > > I'm a bit reluctant to merge via the powerpc.git tree some changes to > > generic files without at least an ack from somebody else :-) > > Gaah. Generally we don't, but you're right to ask. The ELF loading keeps > on accumulating these things, and I'm not sure we have the right process > for things like this. They're all individually small and insignificant, > and they are all individually never going away and making the ELF loader > messier and messier. FWIW, I was initially reluctant to do it this way, but the ELF aux vector seems to be the only reasonable mechanism for getting this information to all interested users. And the only reason the patch touches the generic code is because we have to copy a string to userspace (just like AT_PLATFORM). Otherwise it could be done in powerpc's ARCH_DLINFO. ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] elf loader support for auxvec base platform string 2008-07-17 16:10 ` [PATCH] " Linus Torvalds 2008-07-17 19:35 ` Nathan Lynch @ 2008-07-21 3:19 ` Benjamin Herrenschmidt 1 sibling, 0 replies; 20+ messages in thread From: Benjamin Herrenschmidt @ 2008-07-21 3:19 UTC (permalink / raw) To: Linus Torvalds Cc: linuxppc-dev, Andrew Morton, Nathan Lynch, linux-kernel, roland On Thu, 2008-07-17 at 09:10 -0700, Linus Torvalds wrote: > > On Thu, 17 Jul 2008, Benjamin Herrenschmidt wrote: > > > > Should I seek somebody's ack before merging a patch like the one below ? > > > > I'm a bit reluctant to merge via the powerpc.git tree some changes to > > generic files without at least an ack from somebody else :-) > > Gaah. Generally we don't, but you're right to ask. The ELF loading keeps > on accumulating these things, and I'm not sure we have the right process > for things like this. They're all individually small and insignificant, > and they are all individually never going away and making the ELF loader > messier and messier. Yeah, annoying. Oh well, this one at least is now getting Andrew's scrutinity... Cheers, Ben. ^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH] enable AT_BASE_PLATFORM aux vector for powerpc 2008-07-15 23:58 AT_BASE_PLATFORM (v2) Nathan Lynch 2008-07-15 23:58 ` [PATCH] elf loader support for auxvec base platform string Nathan Lynch @ 2008-07-15 23:58 ` Nathan Lynch 1 sibling, 0 replies; 20+ messages in thread From: Nathan Lynch @ 2008-07-15 23:58 UTC (permalink / raw) To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, linux-kernel, roland Stash the first platform string matched by identify_cpu() in powerpc_base_platform, and supply that to the ELF loader for the value of AT_BASE_PLATFORM. Signed-off-by: Nathan Lynch <ntl@pobox.com> --- arch/powerpc/kernel/cputable.c | 11 +++++++++++ include/asm-powerpc/cputable.h | 2 ++ include/asm-powerpc/elf.h | 8 ++++++++ 3 files changed, 21 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index f7f3c21..89d8731 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -23,6 +23,9 @@ struct cpu_spec* cur_cpu_spec = NULL; EXPORT_SYMBOL(cur_cpu_spec); +/* The platform string corresponding to the real PVR */ +const char *powerpc_base_platform; + /* NOTE: * Unlike ppc32, ppc64 will only call this once for the boot CPU, it's * the responsibility of the appropriate CPU save/restore functions to @@ -1632,6 +1635,14 @@ struct cpu_spec * __init identify_cpu(unsigned long offset, unsigned int pvr) } else *t = *s; *PTRRELOC(&cur_cpu_spec) = &the_cpu_spec; + + /* + * Set the base platform string once; assumes + * we're called with real pvr first. + */ + if (powerpc_base_platform == NULL) + powerpc_base_platform = t->platform; + #if defined(CONFIG_PPC64) || defined(CONFIG_BOOKE) /* ppc64 and booke expect identify_cpu to also call * setup_cpu for that processor. I will consolidate diff --git a/include/asm-powerpc/cputable.h b/include/asm-powerpc/cputable.h index 2a3e907..ef8a248 100644 --- a/include/asm-powerpc/cputable.h +++ b/include/asm-powerpc/cputable.h @@ -127,6 +127,8 @@ extern struct cpu_spec *identify_cpu(unsigned long offset, unsigned int pvr); extern void do_feature_fixups(unsigned long value, void *fixup_start, void *fixup_end); +extern const char *powerpc_base_platform; + #endif /* __ASSEMBLY__ */ /* CPU kernel features */ diff --git a/include/asm-powerpc/elf.h b/include/asm-powerpc/elf.h index 8966467..80d1f39 100644 --- a/include/asm-powerpc/elf.h +++ b/include/asm-powerpc/elf.h @@ -217,6 +217,14 @@ typedef elf_vrregset_t elf_fpxregset_t; #define ELF_PLATFORM (cur_cpu_spec->platform) +/* While ELF_PLATFORM indicates the ISA supported by the platform, it + * may not accurately reflect the underlying behavior of the hardware + * (as in the case of running in Power5+ compatibility mode on a + * Power6 machine). ELF_BASE_PLATFORM allows ld.so to load libraries + * that are tuned for the real hardware. + */ +#define ELF_BASE_PLATFORM (powerpc_base_platform) + #ifdef __powerpc64__ # define ELF_PLAT_INIT(_r, load_addr) do { \ _r->gpr[2] = load_addr; \ -- 1.5.6.2 ^ permalink raw reply related [flat|nested] 20+ messages in thread
end of thread, other threads:[~2008-07-22 2:03 UTC | newest] Thread overview: 20+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-07-15 23:58 AT_BASE_PLATFORM (v2) Nathan Lynch 2008-07-15 23:58 ` [PATCH] elf loader support for auxvec base platform string Nathan Lynch 2008-07-17 6:35 ` Benjamin Herrenschmidt 2008-07-17 7:09 ` Andrew Morton 2008-07-17 17:39 ` Nathan Lynch 2008-07-17 22:19 ` [PATCH v3] " Nathan Lynch 2008-07-17 22:42 ` Andrew Morton 2008-07-17 23:35 ` John Reiser 2008-07-18 18:28 ` Nathan Lynch 2008-07-18 20:31 ` John Reiser 2008-07-18 20:52 ` Andrew Morton 2008-07-21 3:24 ` Benjamin Herrenschmidt 2008-07-21 3:40 ` Andrew Morton 2008-07-21 9:33 ` Benjamin Herrenschmidt 2008-07-21 18:48 ` [PATCH v4] " Nathan Lynch 2008-07-22 2:03 ` Benjamin Herrenschmidt 2008-07-17 16:10 ` [PATCH] " Linus Torvalds 2008-07-17 19:35 ` Nathan Lynch 2008-07-21 3:19 ` Benjamin Herrenschmidt 2008-07-15 23:58 ` [PATCH] enable AT_BASE_PLATFORM aux vector for powerpc Nathan Lynch
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).