Clean up and unify the vDSO
Subsystems (8)
v5 cover Clean up and unify the vDSO
This rewrites a bunch of the vdso code. After these patches, the vvar and hpet pages are mapped directly after the vdso text on all five vdso variants. The fixmaps are gone on 64-bit systems.
It would be possible to build the x32 vdso the normal way on top of these patches.
I haven't touched the pvclock code. In a discussion with Marcello Tosatti, I think we concluded that the kvmclock code could be significantly simplified and sped up without breaking anything, but I want to save that for later.
There's a further change for 32-bit in here: the fixmap is now always aligned to a PMD (i.e. 4M) boundary. This may waste up to 4M-4k of address space if a hypervisor is in use. If that's a problem, then that part of this change could be reverted, but the existing code was asking for trouble.
This should apply to -linus or to tip/x86/vdso. It's also here:
https://git.kernel.org/cgit/linux/kernel/git/luto/linux.git/log/?h=vdso/cleanups
Changed from v4:
- Fixed the alignment of fixmap (build / functionality fix)
Changes from v3:
- Improve the changelog message for patch 2.
Changes from v2:
- Fixed the 32-bit build. Hopefully I didn't screw
up bisection.
Changes from v1:
- Rebased
- I think Gold is working (this is a side effect of the rebase)
Andy Lutomirski (7):
x86,mm: Ensure correct alignment of the fixmap
x86: Clean up 32-bit vs 64-bit vdso params
x86: Move syscall and sysenter setup into kernel/cpu/common.c
x86: Reimplement vdso.so preparation in build-time C
x86: Move the 32-bit vdso special pages after the text
x86: Move the vvar and hpet mappings next to the 64-bit vDSO
x86: Remove vestiges of VDSO_PRELINK and some outdated comments
arch/x86/ia32/ia32_signal.c | 8 +- arch/x86/include/asm/elf.h | 35 +++--- arch/x86/include/asm/fixmap.h | 11 +- arch/x86/include/asm/mmu.h | 2 +- arch/x86/include/asm/proto.h | 2 - arch/x86/include/asm/vdso.h | 74 +++++------- arch/x86/include/asm/vdso32.h | 11 -- arch/x86/include/asm/vvar.h | 20 +--- arch/x86/include/uapi/asm/vsyscall.h | 7 +- arch/x86/kernel/cpu/common.c | 33 ++++++ arch/x86/kernel/hpet.c | 3 - arch/x86/kernel/signal.c | 6 +- arch/x86/kernel/vsyscall_64.c | 15 +-- arch/x86/mm/fault.c | 5 +- arch/x86/mm/init_64.c | 13 +- arch/x86/mm/ioremap.c | 6 + arch/x86/mm/pgtable.c | 6 +- arch/x86/um/vdso/vma.c | 2 +- arch/x86/vdso/.gitignore | 5 +- arch/x86/vdso/Makefile | 90 +++++--------- arch/x86/vdso/vclock_gettime.c | 26 ++-- arch/x86/vdso/vdso-layout.lds.S | 40 ++++--- arch/x86/vdso/vdso.S | 3 - arch/x86/vdso/vdso.lds.S | 7 +- arch/x86/vdso/vdso2c.c | 156 ++++++++++++++++++++++++ arch/x86/vdso/vdso2c.h | 154 ++++++++++++++++++++++++ arch/x86/vdso/vdso32-setup.c | 196 ++++--------------------------- arch/x86/vdso/vdso32.S | 9 -- arch/x86/vdso/vdso32/vdso32.lds.S | 15 +-- arch/x86/vdso/vdsox32.S | 3 - arch/x86/vdso/vdsox32.lds.S | 7 +- arch/x86/vdso/vma.c | 222 +++++++++++++++++++---------------- arch/x86/xen/mmu.c | 8 +- arch/x86/xen/setup.c | 11 +- kernel/sysctl.c | 5 + 35 files changed, 657 insertions(+), 559 deletions(-) delete mode 100644 arch/x86/include/asm/vdso32.h delete mode 100644 arch/x86/vdso/vdso.S create mode 100644 arch/x86/vdso/vdso2c.c create mode 100644 arch/x86/vdso/vdso2c.h delete mode 100644 arch/x86/vdso/vdso32.S delete mode 100644 arch/x86/vdso/vdsox32.S
Signature · 1 line
1.9.0
PATCH v5 1/7 x86,mm: Ensure correct alignment of the fixmap
The early_ioremap code requires that its buffers not span a PMD boundary. The logic for ensuring that only works if the fixmap is aligned, so assert that it's aligned correctly.
To make this work reliably, reserve_top_address needs to be adjusted.
--- arch/x86/mm/ioremap.c | 6 ++++++ arch/x86/mm/pgtable.c | 6 +++--- 2 files changed, 9 insertions(+), 3 deletions(-)
arch/x86/mm/ioremap.c +6 -0
@@ -355,6 +355,12 @@ void __init early_ioremap_init(void) {pmd_t *pmd; +#ifdef CONFIG_X86_64 +BUILD_BUG_ON ((fix_to_virt (0 ) +PAGE_SIZE ) & ((1 <<PMD_SHIFT ) -1 )); +#else +WARN_ON ((fix_to_virt (0 ) +PAGE_SIZE ) & ((1 <<PMD_SHIFT ) -1 )); +#endif +early_ioremap_setup (); pmd =early_ioremap_pmd (fix_to_virt (FIX_BTMAP_BEGIN ));
arch/x86/mm/pgtable.c +3 -3
@@ -449,9 +449,9 @@ void __init reserve_top_address(unsigned long reserve) {#ifdef CONFIG_X86_32 BUG_ON (fixmaps_set >0 ); -printk (KERN_INFO "Reserving virtual address space above 0x%08x\n" , - (int )-reserve); - __FIXADDR_TOP = -reserve -PAGE_SIZE ; + __FIXADDR_TOP =round_down (-reserve,1 <<PMD_SHIFT ) -PAGE_SIZE ; +printk (KERN_INFO "Reserving virtual address space above 0x%08lx (rounded to 0x%08lx)\n" , + -reserve, __FIXADDR_TOP +PAGE_SIZE );#endif }
Signature · 1 line
1.9.0
tip-bot for Andy Lutomirski
merge bot[tip:x86/vdso] x86, mm: Ensure correct alignment of the fixmap
x86, mm: Ensure correct alignment of the fixmap
Commit-ID: 73159fdcdb9be3eda61b846864352c29371baeb6 Gitweb: http://git.kernel.org/tip/73159fdcdb9be3eda61b846864352c29371baeb6 Author: Andy Lutomirski <[email protected]> AuthorDate: Mon, 5 May 2014 12:19:31 -0700 Committer: H. Peter Anvin <[email protected]> CommitDate: Mon, 5 May 2014 13:18:25 -0700
x86, mm: Ensure correct alignment of the fixmap
The early_ioremap code requires that its buffers not span a PMD boundary. The logic for ensuring that only works if the fixmap is aligned, so assert that it's aligned correctly.
To make this work reliably, reserve_top_address needs to be adjusted.
--- arch/x86/mm/ioremap.c | 6 ++++++ arch/x86/mm/pgtable.c | 6 +++--- 2 files changed, 9 insertions(+), 3 deletions(-)
arch/x86/mm/ioremap.c +6 -0
@@ -355,6 +355,12 @@ void __init early_ioremap_init(void) {pmd_t *pmd; +#ifdef CONFIG_X86_64 +BUILD_BUG_ON ((fix_to_virt (0 ) +PAGE_SIZE ) & ((1 <<PMD_SHIFT ) -1 )); +#else +WARN_ON ((fix_to_virt (0 ) +PAGE_SIZE ) & ((1 <<PMD_SHIFT ) -1 )); +#endif +early_ioremap_setup (); pmd =early_ioremap_pmd (fix_to_virt (FIX_BTMAP_BEGIN ));
arch/x86/mm/pgtable.c +3 -3
@@ -449,9 +449,9 @@ void __init reserve_top_address(unsigned long reserve) {#ifdef CONFIG_X86_32 BUG_ON (fixmaps_set >0 ); -printk (KERN_INFO "Reserving virtual address space above 0x%08x\n" , - (int )-reserve); - __FIXADDR_TOP = -reserve -PAGE_SIZE ; + __FIXADDR_TOP =round_down (-reserve,1 <<PMD_SHIFT ) -PAGE_SIZE ; +printk (KERN_INFO "Reserving virtual address space above 0x%08lx (rounded to 0x%08lx)\n" , + -reserve, __FIXADDR_TOP +PAGE_SIZE );#endif }
PATCH v5 2/7 x86: Clean up 32-bit vs 64-bit vdso params
In reply to Andy LutomirskiRather than using 'vdso_enabled' and an awful #define, just call the parameters vdso32_enabled and vdso64_enabled.
--- arch/x86/include/asm/elf.h | 20 +++++++++++++------- arch/x86/um/vdso/vma.c | 2 +- arch/x86/vdso/vdso32-setup.c | 19 ++++++++----------- arch/x86/vdso/vma.c | 6 +++--- kernel/sysctl.c | 5 +++++ 5 files changed, 30 insertions(+), 22 deletions(-)
arch/x86/include/asm/elf.h +13 -7
@@ -75,7 +75,12 @@ typedef struct user_fxsr_struct elf_fpxregset_t;#include <asm/vdso.h> -extern unsigned int vdso_enabled; +#ifdef CONFIG_X86_64 +extern unsigned int vdso64_enabled; +#endif +#if defined(CONFIG_X86_32 ) || defined(CONFIG_COMPAT ) +extern unsigned int vdso32_enabled; +#endif /* * This is used to ensure we don't load something for the wrong architecture.
@@ -269,9 +274,9 @@ extern int force_personality32;struct task_struct ; -#define ARCH_DLINFO_IA32 (vdso_enabled) \ +#define ARCH_DLINFO_IA32 \ do { \ - if (vdso_enabled) { \ + if (vdso32_enabled) { \ NEW_AUX_ENT(AT_SYSINFO, VDSO_ENTRY); \ NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_CURRENT_BASE); \ } \
@@ -281,7 +286,7 @@ do { \#define STACK_RND_MASK (0x7ff) -#define ARCH_DLINFO ARCH_DLINFO_IA32(vdso_enabled) +#define ARCH_DLINFO ARCH_DLINFO_IA32/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
@@ -292,14 +297,15 @@ do { \#define ARCH_DLINFO \ do { \ - if (vdso_enabled) \ + if (vdso64_enabled) \ NEW_AUX_ENT(AT_SYSINFO_EHDR, \ (unsigned long)current->mm->context.vdso); \ } while (0) +/* As a historical oddity, the x32 and x86_64 vDSOs are controlled together. */ #define ARCH_DLINFO_X32 \ do { \ - if (vdso_enabled) \ + if (vdso64_enabled) \ NEW_AUX_ENT(AT_SYSINFO_EHDR, \ (unsigned long)current->mm->context.vdso); \ } while (0)
@@ -310,7 +316,7 @@ do { \if (test_thread_flag (TIF_X32 )) \ARCH_DLINFO_X32 ; \else \ - ARCH_DLINFO_IA32(sysctl_vsyscall32) + ARCH_DLINFO_IA32#define COMPAT_ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
arch/x86/um/vdso/vma.c +1 -1
@@ -12,7 +12,7 @@#include <asm/page.h> #include <linux/init.h> -unsigned int __read_mostly vdso_enabled =1 ; +static unsigned int __read_mostly vdso_enabled =1 ;unsigned long um_vdso_addr;extern unsigned long task_size;
arch/x86/vdso/vdso32-setup.c +8 -11
@@ -37,7 +37,6 @@#endif #ifdef CONFIG_X86_64 -#define vdso_enabled sysctl_vsyscall32#define arch_setup_additional_pages syscall32_setup_pages#endif
@@ -45,13 +44,13 @@* Should the kernel map a VDSO page into processes and pass its * address down to glibc upon exec()? */ -unsigned int __read_mostly vdso_enabled =VDSO_DEFAULT ; +unsigned int __read_mostly vdso32_enabled =VDSO_DEFAULT ; -static int __init vdso_setup (char *s) +static int __init vdso32_setup (char *s) { - vdso_enabled =simple_strtoul (s,NULL ,0 ); + vdso32_enabled =simple_strtoul (s,NULL ,0 ); -if (vdso_enabled >1 ) +if (vdso32_enabled >1 )pr_warn ("vdso32 values other than 0 and 1 are no longer allowed; vdso disabled\n" );return 1 ;
@@ -62,12 +61,10 @@ static int __init vdso_setup(char *s)* behavior on both 64-bit and 32-bit kernels. * On 32-bit kernels, vdso=[012] means the same thing. */ -__setup ("vdso32=" , vdso_setup); +__setup ("vdso32=" , vdso32_setup);#ifdef CONFIG_X86_32 -__setup_param ("vdso=" , vdso32_setup, vdso_setup,0 ); - -EXPORT_SYMBOL_GPL (vdso_enabled); +__setup_param ("vdso=" , vdso_setup, vdso32_setup,0 );#endif static struct page **vdso32_pages;
@@ -160,7 +157,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)return x32_setup_additional_pages (bprm, uses_interp);#endif -if (vdso_enabled !=1 )/* Other values all mean "disabled" */ +if (vdso32_enabled !=1 )/* Other values all mean "disabled" */ return 0 ;down_write (&mm->mmap_sem);
@@ -244,7 +241,7 @@ subsys_initcall(sysenter_setup);static struct ctl_table abi_table2[] = { { .procname ="vsyscall32" , - .data = &sysctl_vsyscall32, + .data = &vdso32_enabled, .maxlen =sizeof (int ), .mode =0644 , .proc_handler = proc_dointvec
arch/x86/vdso/vma.c +3 -3
@@ -17,7 +17,7 @@#include <asm/page.h> #if defined(CONFIG_X86_64 ) -unsigned int __read_mostly vdso_enabled =1 ; +unsigned int __read_mostly vdso64_enabled =1 ;DECLARE_VDSO_IMAGE (vdso);extern unsigned short vdso_sync_cpuid;
@@ -160,7 +160,7 @@ static int setup_additional_pages(struct linux_binprm *bprm,unsigned long addr;int ret; -if (!vdso_enabled) +if (!vdso64_enabled)return 0 ;down_write (&mm->mmap_sem);
@@ -203,7 +203,7 @@ int x32_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)static __init int vdso_setup (char *s) { - vdso_enabled =simple_strtoul (s,NULL ,0 ); + vdso64_enabled =simple_strtoul (s,NULL ,0 );return 0 ; }__setup ("vdso=" , vdso_setup);
kernel/sysctl.c +5 -0
@@ -1418,8 +1418,13 @@ static struct ctl_table vm_table[] = { (defined (CONFIG_SUPERH ) &&defined (CONFIG_VSYSCALL )) { .procname ="vdso_enabled" , +#ifdef CONFIG_X86_32 + .data = &vdso32_enabled, + .maxlen = sizeof(vdso32_enabled), +#else .data = &vdso_enabled, .maxlen = sizeof(vdso_enabled), +#endif .mode =0644 , .proc_handler = proc_dointvec, .extra1 = &zero,
Signature · 1 line
1.9.0
tip-bot for Andy Lutomirski
merge bot[tip:x86/vdso] x86, vdso: Clean up 32-bit vs 64-bit vdso params
x86, vdso: Clean up 32-bit vs 64-bit vdso params
Commit-ID: 3d7ee969bffcc984c8aeaffc6ac6816fd929ace1 Gitweb: http://git.kernel.org/tip/3d7ee969bffcc984c8aeaffc6ac6816fd929ace1 Author: Andy Lutomirski <[email protected]> AuthorDate: Mon, 5 May 2014 12:19:32 -0700 Committer: H. Peter Anvin <[email protected]> CommitDate: Mon, 5 May 2014 13:18:40 -0700
x86, vdso: Clean up 32-bit vs 64-bit vdso params
Rather than using 'vdso_enabled' and an awful #define, just call the parameters vdso32_enabled and vdso64_enabled.
--- arch/x86/include/asm/elf.h | 20 +++++++++++++------- arch/x86/um/vdso/vma.c | 2 +- arch/x86/vdso/vdso32-setup.c | 19 ++++++++----------- arch/x86/vdso/vma.c | 6 +++--- kernel/sysctl.c | 5 +++++ 5 files changed, 30 insertions(+), 22 deletions(-)
arch/x86/include/asm/elf.h +13 -7
@@ -75,7 +75,12 @@ typedef struct user_fxsr_struct elf_fpxregset_t;#include <asm/vdso.h> -extern unsigned int vdso_enabled; +#ifdef CONFIG_X86_64 +extern unsigned int vdso64_enabled; +#endif +#if defined(CONFIG_X86_32 ) || defined(CONFIG_COMPAT ) +extern unsigned int vdso32_enabled; +#endif /* * This is used to ensure we don't load something for the wrong architecture.
@@ -269,9 +274,9 @@ extern int force_personality32;struct task_struct ; -#define ARCH_DLINFO_IA32 (vdso_enabled) \ +#define ARCH_DLINFO_IA32 \ do { \ - if (vdso_enabled) { \ + if (vdso32_enabled) { \ NEW_AUX_ENT(AT_SYSINFO, VDSO_ENTRY); \ NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_CURRENT_BASE); \ } \
@@ -281,7 +286,7 @@ do { \#define STACK_RND_MASK (0x7ff) -#define ARCH_DLINFO ARCH_DLINFO_IA32(vdso_enabled) +#define ARCH_DLINFO ARCH_DLINFO_IA32/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
@@ -292,14 +297,15 @@ do { \#define ARCH_DLINFO \ do { \ - if (vdso_enabled) \ + if (vdso64_enabled) \ NEW_AUX_ENT(AT_SYSINFO_EHDR, \ (unsigned long)current->mm->context.vdso); \ } while (0) +/* As a historical oddity, the x32 and x86_64 vDSOs are controlled together. */ #define ARCH_DLINFO_X32 \ do { \ - if (vdso_enabled) \ + if (vdso64_enabled) \ NEW_AUX_ENT(AT_SYSINFO_EHDR, \ (unsigned long)current->mm->context.vdso); \ } while (0)
@@ -310,7 +316,7 @@ do { \if (test_thread_flag (TIF_X32 )) \ARCH_DLINFO_X32 ; \else \ - ARCH_DLINFO_IA32(sysctl_vsyscall32) + ARCH_DLINFO_IA32#define COMPAT_ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
arch/x86/um/vdso/vma.c +1 -1
@@ -12,7 +12,7 @@#include <asm/page.h> #include <linux/init.h> -unsigned int __read_mostly vdso_enabled =1 ; +static unsigned int __read_mostly vdso_enabled =1 ;unsigned long um_vdso_addr;extern unsigned long task_size;
arch/x86/vdso/vdso32-setup.c +8 -11
@@ -37,7 +37,6 @@#endif #ifdef CONFIG_X86_64 -#define vdso_enabled sysctl_vsyscall32#define arch_setup_additional_pages syscall32_setup_pages#endif
@@ -45,13 +44,13 @@* Should the kernel map a VDSO page into processes and pass its * address down to glibc upon exec()? */ -unsigned int __read_mostly vdso_enabled =VDSO_DEFAULT ; +unsigned int __read_mostly vdso32_enabled =VDSO_DEFAULT ; -static int __init vdso_setup (char *s) +static int __init vdso32_setup (char *s) { - vdso_enabled =simple_strtoul (s,NULL ,0 ); + vdso32_enabled =simple_strtoul (s,NULL ,0 ); -if (vdso_enabled >1 ) +if (vdso32_enabled >1 )pr_warn ("vdso32 values other than 0 and 1 are no longer allowed; vdso disabled\n" );return 1 ;
@@ -62,12 +61,10 @@ static int __init vdso_setup(char *s)* behavior on both 64-bit and 32-bit kernels. * On 32-bit kernels, vdso=[012] means the same thing. */ -__setup ("vdso32=" , vdso_setup); +__setup ("vdso32=" , vdso32_setup);#ifdef CONFIG_X86_32 -__setup_param ("vdso=" , vdso32_setup, vdso_setup,0 ); - -EXPORT_SYMBOL_GPL (vdso_enabled); +__setup_param ("vdso=" , vdso_setup, vdso32_setup,0 );#endif static struct page **vdso32_pages;
@@ -160,7 +157,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)return x32_setup_additional_pages (bprm, uses_interp);#endif -if (vdso_enabled !=1 )/* Other values all mean "disabled" */ +if (vdso32_enabled !=1 )/* Other values all mean "disabled" */ return 0 ;down_write (&mm->mmap_sem);
@@ -244,7 +241,7 @@ subsys_initcall(sysenter_setup);static struct ctl_table abi_table2[] = { { .procname ="vsyscall32" , - .data = &sysctl_vsyscall32, + .data = &vdso32_enabled, .maxlen =sizeof (int ), .mode =0644 , .proc_handler = proc_dointvec
arch/x86/vdso/vma.c +3 -3
@@ -17,7 +17,7 @@#include <asm/page.h> #if defined(CONFIG_X86_64 ) -unsigned int __read_mostly vdso_enabled =1 ; +unsigned int __read_mostly vdso64_enabled =1 ;DECLARE_VDSO_IMAGE (vdso);extern unsigned short vdso_sync_cpuid;
@@ -160,7 +160,7 @@ static int setup_additional_pages(struct linux_binprm *bprm,unsigned long addr;int ret; -if (!vdso_enabled) +if (!vdso64_enabled)return 0 ;down_write (&mm->mmap_sem);
@@ -203,7 +203,7 @@ int x32_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)static __init int vdso_setup (char *s) { - vdso_enabled =simple_strtoul (s,NULL ,0 ); + vdso64_enabled =simple_strtoul (s,NULL ,0 );return 0 ; }__setup ("vdso=" , vdso_setup);
kernel/sysctl.c +5 -0
@@ -1418,8 +1418,13 @@ static struct ctl_table vm_table[] = { (defined (CONFIG_SUPERH ) &&defined (CONFIG_VSYSCALL )) { .procname ="vdso_enabled" , +#ifdef CONFIG_X86_32 + .data = &vdso32_enabled, + .maxlen = sizeof(vdso32_enabled), +#else .data = &vdso_enabled, .maxlen = sizeof(vdso_enabled), +#endif .mode =0644 , .proc_handler = proc_dointvec, .extra1 = &zero,
PATCH v5 3/7 x86: Move syscall and sysenter setup into kernel/cpu/common.c
In reply to Andy LutomirskiThis code is used during CPU setup, and it isn't strictly speaking related to the 32-bit vdso. It's easier to understand how this works when the code is closer to its callers.
This also lets syscall32_cpu_init be static, which might save some trivial amount of kernel text.
--- arch/x86/include/asm/proto.h | 2 -- arch/x86/kernel/cpu/common.c | 32 ++++++++++++++++++++++++++++++++ arch/x86/vdso/vdso32-setup.c | 30 ------------------------------ 3 files changed, 32 insertions(+), 32 deletions(-)
arch/x86/include/asm/proto.h +0 -2
@@ -12,8 +12,6 @@ void ia32_syscall(void);void ia32_cstar_target (void );void ia32_sysenter_target (void ); -void syscall32_cpu_init (void ); -void x86_configure_nx (void );void x86_report_nx (void );
arch/x86/kernel/cpu/common.c +32 -0
@@ -953,6 +953,38 @@ static void vgetcpu_set_mode(void) else vgetcpu_mode = VGETCPU_LSL; } + +/* May not be __init: called during resume */ +static void syscall32_cpu_init (void ) +{ +/* Load these always in case some future AMD CPU supports +SYSENTER from compat mode too. */ +wrmsrl_safe (MSR_IA32_SYSENTER_CS , (u64 )__KERNEL_CS); +wrmsrl_safe (MSR_IA32_SYSENTER_ESP ,0ULL ); +wrmsrl_safe (MSR_IA32_SYSENTER_EIP , (u64 )ia32_sysenter_target); + +wrmsrl (MSR_CSTAR , ia32_cstar_target); +} +#endif + +#ifdef CONFIG_X86_32 +void enable_sep_cpu (void ) +{ +int cpu =get_cpu (); +struct tss_struct *tss = &per_cpu (init_tss, cpu); + +if (!boot_cpu_has (X86_FEATURE_SEP )) { +put_cpu (); +return ; + } + + tss->x86_tss.ss1 = __KERNEL_CS; + tss->x86_tss.sp1 =sizeof (struct tss_struct ) + (unsigned long ) tss; +wrmsr (MSR_IA32_SYSENTER_CS , __KERNEL_CS,0 ); +wrmsr (MSR_IA32_SYSENTER_ESP , tss->x86_tss.sp1,0 ); +wrmsr (MSR_IA32_SYSENTER_EIP , (unsigned long ) ia32_sysenter_target,0 ); +put_cpu (); +}#endif void __init identify_boot_cpu (void )
arch/x86/vdso/vdso32-setup.c +0 -30
@@ -75,41 +75,11 @@ static unsigned vdso32_size;#define vdso32_sysenter () (boot_cpu_has(X86_FEATURE_SYSENTER32))#define vdso32_syscall () (boot_cpu_has(X86_FEATURE_SYSCALL32)) -/* May not be __init: called during resume */ -void syscall32_cpu_init (void ) -{ -/* Load these always in case some future AMD CPU supports -SYSENTER from compat mode too. */ -wrmsrl_safe (MSR_IA32_SYSENTER_CS , (u64 )__KERNEL_CS); -wrmsrl_safe (MSR_IA32_SYSENTER_ESP ,0ULL ); -wrmsrl_safe (MSR_IA32_SYSENTER_EIP , (u64 )ia32_sysenter_target); - -wrmsrl (MSR_CSTAR , ia32_cstar_target); -} -#else /* CONFIG_X86_32 */ #define vdso32_sysenter () (boot_cpu_has(X86_FEATURE_SEP))#define vdso32_syscall () (0) -void enable_sep_cpu (void ) -{ -int cpu =get_cpu (); -struct tss_struct *tss = &per_cpu (init_tss, cpu); - -if (!boot_cpu_has (X86_FEATURE_SEP )) { -put_cpu (); -return ; - } - - tss->x86_tss.ss1 = __KERNEL_CS; - tss->x86_tss.sp1 =sizeof (struct tss_struct ) + (unsigned long ) tss; -wrmsr (MSR_IA32_SYSENTER_CS , __KERNEL_CS,0 ); -wrmsr (MSR_IA32_SYSENTER_ESP , tss->x86_tss.sp1,0 ); -wrmsr (MSR_IA32_SYSENTER_EIP , (unsigned long ) ia32_sysenter_target,0 ); -put_cpu (); -} -#endif /* CONFIG_X86_64 */ int __init sysenter_setup (void )
Signature · 1 line
1.9.0
tip-bot for Andy Lutomirski
merge bot[tip:x86/vdso] x86, vdso: Move syscall and sysenter setup into kernel/cpu/common.c
x86, vdso: Move syscall and sysenter setup into kernel/cpu/common.c
Commit-ID: cfda7bb9ecbf9d96264bb5bade33a842966d1062 Gitweb: http://git.kernel.org/tip/cfda7bb9ecbf9d96264bb5bade33a842966d1062 Author: Andy Lutomirski <[email protected]> AuthorDate: Mon, 5 May 2014 12:19:33 -0700 Committer: H. Peter Anvin <[email protected]> CommitDate: Mon, 5 May 2014 13:18:47 -0700
x86, vdso: Move syscall and sysenter setup into kernel/cpu/common.c
This code is used during CPU setup, and it isn't strictly speaking related to the 32-bit vdso. It's easier to understand how this works when the code is closer to its callers.
This also lets syscall32_cpu_init be static, which might save some trivial amount of kernel text.
--- arch/x86/include/asm/proto.h | 2 -- arch/x86/kernel/cpu/common.c | 32 ++++++++++++++++++++++++++++++++ arch/x86/vdso/vdso32-setup.c | 30 ------------------------------ 3 files changed, 32 insertions(+), 32 deletions(-)
arch/x86/include/asm/proto.h +0 -2
@@ -12,8 +12,6 @@ void ia32_syscall(void);void ia32_cstar_target (void );void ia32_sysenter_target (void ); -void syscall32_cpu_init (void ); -void x86_configure_nx (void );void x86_report_nx (void );
arch/x86/kernel/cpu/common.c +32 -0
@@ -953,6 +953,38 @@ static void vgetcpu_set_mode(void) else vgetcpu_mode = VGETCPU_LSL; } + +/* May not be __init: called during resume */ +static void syscall32_cpu_init (void ) +{ +/* Load these always in case some future AMD CPU supports +SYSENTER from compat mode too. */ +wrmsrl_safe (MSR_IA32_SYSENTER_CS , (u64 )__KERNEL_CS); +wrmsrl_safe (MSR_IA32_SYSENTER_ESP ,0ULL ); +wrmsrl_safe (MSR_IA32_SYSENTER_EIP , (u64 )ia32_sysenter_target); + +wrmsrl (MSR_CSTAR , ia32_cstar_target); +} +#endif + +#ifdef CONFIG_X86_32 +void enable_sep_cpu (void ) +{ +int cpu =get_cpu (); +struct tss_struct *tss = &per_cpu (init_tss, cpu); + +if (!boot_cpu_has (X86_FEATURE_SEP )) { +put_cpu (); +return ; + } + + tss->x86_tss.ss1 = __KERNEL_CS; + tss->x86_tss.sp1 =sizeof (struct tss_struct ) + (unsigned long ) tss; +wrmsr (MSR_IA32_SYSENTER_CS , __KERNEL_CS,0 ); +wrmsr (MSR_IA32_SYSENTER_ESP , tss->x86_tss.sp1,0 ); +wrmsr (MSR_IA32_SYSENTER_EIP , (unsigned long ) ia32_sysenter_target,0 ); +put_cpu (); +}#endif void __init identify_boot_cpu (void )
arch/x86/vdso/vdso32-setup.c +0 -30
@@ -75,41 +75,11 @@ static unsigned vdso32_size;#define vdso32_sysenter () (boot_cpu_has(X86_FEATURE_SYSENTER32))#define vdso32_syscall () (boot_cpu_has(X86_FEATURE_SYSCALL32)) -/* May not be __init: called during resume */ -void syscall32_cpu_init (void ) -{ -/* Load these always in case some future AMD CPU supports -SYSENTER from compat mode too. */ -wrmsrl_safe (MSR_IA32_SYSENTER_CS , (u64 )__KERNEL_CS); -wrmsrl_safe (MSR_IA32_SYSENTER_ESP ,0ULL ); -wrmsrl_safe (MSR_IA32_SYSENTER_EIP , (u64 )ia32_sysenter_target); - -wrmsrl (MSR_CSTAR , ia32_cstar_target); -} -#else /* CONFIG_X86_32 */ #define vdso32_sysenter () (boot_cpu_has(X86_FEATURE_SEP))#define vdso32_syscall () (0) -void enable_sep_cpu (void ) -{ -int cpu =get_cpu (); -struct tss_struct *tss = &per_cpu (init_tss, cpu); - -if (!boot_cpu_has (X86_FEATURE_SEP )) { -put_cpu (); -return ; - } - - tss->x86_tss.ss1 = __KERNEL_CS; - tss->x86_tss.sp1 =sizeof (struct tss_struct ) + (unsigned long ) tss; -wrmsr (MSR_IA32_SYSENTER_CS , __KERNEL_CS,0 ); -wrmsr (MSR_IA32_SYSENTER_ESP , tss->x86_tss.sp1,0 ); -wrmsr (MSR_IA32_SYSENTER_EIP , (unsigned long ) ia32_sysenter_target,0 ); -put_cpu (); -} -#endif /* CONFIG_X86_64 */ int __init sysenter_setup (void )
PATCH v5 4/7 x86: Reimplement vdso.so preparation in build-time C
In reply to Andy LutomirskiCurrently, vdso.so files are prepared and analyzed by a combination of objcopy, nm, some linker script tricks, and some simple ELF parsers in the kernel. Replace all of that with plain C code that runs at build time.
All five vdso images now generate .c files that are compiled and linked in to the kernel image.
This should cause only one userspace-visible change: the loaded vDSO images are stripped more heavily than they used to be. Everything outside the loadable segment is dropped. In particular, this causes the section table and section name strings to be missing. This should be fine: real dynamic loaders don't load or inspect these tables anyway. The result is roughly equivalent to eu-strip's --strip-sections option.
The purpose of this change is to enable the vvar and hpet mappings to be moved to the page following the vDSO load segment. Currently, it is possible for the section table to extend into the page after the load segment, so, if we map it, it risks overlapping the vvar or hpet page. This happens whenever the load segment is just under a multiple of PAGE_SIZE.
The only real subtlety here is that the old code had a C file with inline assembler that did 'call VDSO32_vsyscall' and a linker script that defined 'VDSO32_vsyscall = __kernel_vsyscall'. This most likely worked by accident: the linker script entry defines a symbol associated with an address as opposed to an alias for the real dynamic symbol __kernel_vsyscall. That caused ld to relocate the reference at link time instead of leaving an interposable dynamic relocation. Since the VDSO32_vsyscall hack is no longer needed, I now use 'call __kernel_vsyscall', and I added -Bsymbolic to make it work. vdso2c will generate an error and abort the build if the resulting image contains any dynamic relocations, so we won't silently generate bad vdso images.
(Dynamic relocations are a problem because nothing will even attempt to relocate the vdso.)
--- arch/x86/ia32/ia32_signal.c | 8 +-- arch/x86/include/asm/elf.h | 7 +- arch/x86/include/asm/mmu.h | 2 +- arch/x86/include/asm/vdso.h | 70 +++++++------------ arch/x86/kernel/signal.c | 6 +- arch/x86/mm/init_64.c | 3 +- arch/x86/vdso/.gitignore | 5 +- arch/x86/vdso/Makefile | 90 +++++++++--------------- arch/x86/vdso/vclock_gettime.c | 4 +- arch/x86/vdso/vdso.S | 3 - arch/x86/vdso/vdso2c.c | 142 ++++++++++++++++++++++++++++++++++++++ arch/x86/vdso/vdso2c.h | 137 ++++++++++++++++++++++++++++++++++++ arch/x86/vdso/vdso32-setup.c | 50 ++++++-------- arch/x86/vdso/vdso32.S | 9 --- arch/x86/vdso/vdso32/vdso32.lds.S | 10 --- arch/x86/vdso/vdsox32.S | 3 - arch/x86/vdso/vma.c | 100 +++++---------------------- arch/x86/xen/setup.c | 11 ++- 18 files changed, 400 insertions(+), 260 deletions(-) delete mode 100644 arch/x86/vdso/vdso.S create mode 100644 arch/x86/vdso/vdso2c.c create mode 100644 arch/x86/vdso/vdso2c.h delete mode 100644 arch/x86/vdso/vdso32.S delete mode 100644 arch/x86/vdso/vdsox32.S
arch/x86/ia32/ia32_signal.c +4 -4
@@ -383,8 +383,8 @@ int ia32_setup_frame(int sig, struct ksignal *ksig, }else {/* Return stub is in 32bit vsyscall page */ if (current->mm->context.vdso) - restorer =VDSO32_SYMBOL (current->mm->context.vdso, - sigreturn); + restorer = current->mm->context.vdso + + selected_vdso32->sym___kernel_sigreturn;else restorer = &frame->retcode; }
@@ -462,8 +462,8 @@ int ia32_setup_rt_frame(int sig, struct ksignal *ksig,if (ksig->ka.sa.sa_flags &SA_RESTORER ) restorer = ksig->ka.sa.sa_restorer;else - restorer =VDSO32_SYMBOL (current->mm->context.vdso, - rt_sigreturn); + restorer = current->mm->context.vdso + + selected_vdso32->sym___kernel_rt_sigreturn;put_user_ex (ptr_to_compat (restorer), &frame->pretcode);/*
arch/x86/include/asm/elf.h +4 -3
@@ -299,7 +299,7 @@ do { \do { \if (vdso64_enabled) \NEW_AUX_ENT (AT_SYSINFO_EHDR , \ - (unsigned long )current->mm->context.vdso); \ + (unsigned long __force )current->mm->context.vdso); \ }while (0 )/* As a historical oddity, the x32 and x86_64 vDSOs are controlled together. */
@@ -307,7 +307,7 @@ do { \do { \if (vdso64_enabled) \NEW_AUX_ENT (AT_SYSINFO_EHDR , \ - (unsigned long )current->mm->context.vdso); \ + (unsigned long __force )current->mm->context.vdso); \ } while (0)#define AT_SYSINFO 32
@@ -325,7 +325,8 @@ else \#define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso)#define VDSO_ENTRY \ - ((unsigned long)VDSO32_SYMBOL(VDSO_CURRENT_BASE, vsyscall)) + ((unsigned long)current->mm->context.vdso + \ + selected_vdso32->sym___kernel_vsyscall)struct linux_binprm ;
arch/x86/include/asm/mmu.h +1 -1
@@ -18,7 +18,7 @@ typedef struct {#endif struct mutex lock; -void *vdso; +void __user *vdso; } mm_context_t;#ifdef CONFIG_SMP
arch/x86/include/asm/vdso.h +25 -45
88 lines not on this page · raw message
arch/x86/kernel/signal.c +4 -2
@@ -298,7 +298,8 @@ __setup_frame(int sig, struct ksignal *ksig, sigset_t *set, }if (current->mm->context.vdso) - restorer =VDSO32_SYMBOL (current->mm->context.vdso, sigreturn); + restorer = current->mm->context.vdso + + selected_vdso32->sym___kernel_sigreturn;else restorer = &frame->retcode;if (ksig->ka.sa.sa_flags &SA_RESTORER )
@@ -361,7 +362,8 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,save_altstack_ex (&frame->uc.uc_stack, regs->sp);/* Set up to return from userspace. */ - restorer =VDSO32_SYMBOL (current->mm->context.vdso, rt_sigreturn); + restorer = current->mm->context.vdso + + selected_vdso32->sym___kernel_sigreturn;if (ksig->ka.sa.sa_flags &SA_RESTORER ) restorer = ksig->ka.sa.sa_restorer;put_user_ex (restorer, &frame->pretcode);
arch/x86/mm/init_64.c +2 -1
@@ -1223,7 +1223,8 @@ int in_gate_area_no_mm(unsigned long addr)const char *arch_vma_name (struct vm_area_struct *vma) { -if (vma->vm_mm && vma->vm_start == (long )vma->vm_mm->context.vdso) +if (vma->vm_mm && vma->vm_start == + (long __force )vma->vm_mm->context.vdso)return "[vdso]" ;if (vma == &gate_vma)return "[vsyscall]" ;
arch/x86/vdso/.gitignore +2 -3
@@ -1,8 +1,7 @@ vdso.lds -vdso-syms.lds vdsox32.lds -vdsox32-syms.lds -vdso32-syms.lds vdso32-syscall-syms.lds vdso32-sysenter-syms.lds vdso32-int80-syms.lds +vdso-image-*.c +vdso2c
arch/x86/vdso/Makefile +32 -58
152 lines not on this page · raw message
arch/x86/vdso/vclock_gettime.c +2 -2
@@ -154,7 +154,7 @@ notrace static long vdso_fallback_gettime(long clock, struct timespec *ts) asm("mov %%ebx, %%edx \n" "mov %2, %%ebx \n" -"call VDSO32_vsyscall \n" +"call __kernel_vsyscall \n" "mov %%edx, %%ebx \n" :"=a" (ret) : "0" (__NR_clock_gettime), "g" (clock), "c" (ts)
@@ -169,7 +169,7 @@ notrace static long vdso_fallback_gtod(struct timeval *tv, struct timezone *tz) asm("mov %%ebx, %%edx \n" "mov %2, %%ebx \n" -"call VDSO32_vsyscall \n" +"call __kernel_vsyscall \n" "mov %%edx, %%ebx \n" :"=a" (ret) : "0" (__NR_gettimeofday), "g" (tv), "c" (tz)
arch/x86/vdso/vdso.S deleted +0 -3
@@ -1,3 +0,0 @@ -#include <asm/vdso.h> - -DEFINE_VDSO_IMAGE(vdso, "arch/x86/vdso/vdso.so")
arch/x86/vdso/vdso2c.c new file +142 -0
142 lines not on this page · raw message
arch/x86/vdso/vdso2c.h new file +137 -0
137 lines not on this page · raw message
arch/x86/vdso/vdso32-setup.c +20 -30
97 lines not on this page · raw message
arch/x86/vdso/vdso32.S deleted +0 -9
@@ -1,9 +0,0 @@ -#include <asm/vdso.h> - -DEFINE_VDSO_IMAGE(vdso32_int80, "arch/x86/vdso/vdso32-int80.so") - -#ifdef CONFIG_COMPAT -DEFINE_VDSO_IMAGE(vdso32_syscall, "arch/x86/vdso/vdso32-syscall.so") -#endif - -DEFINE_VDSO_IMAGE(vdso32_sysenter, "arch/x86/vdso/vdso32-sysenter.so")
arch/x86/vdso/vdso32/vdso32.lds.S +0 -10
@@ -38,13 +38,3 @@ VERSION local: *; }; } - -/* - * Symbols we define here called VDSO* get their values into vdso32-syms.h. - */ -VDSO32_vsyscall = __kernel_vsyscall; -VDSO32_sigreturn = __kernel_sigreturn; -VDSO32_rt_sigreturn = __kernel_rt_sigreturn; -VDSO32_clock_gettime = clock_gettime; -VDSO32_gettimeofday = gettimeofday; -VDSO32_time = time;
arch/x86/vdso/vdsox32.S deleted +0 -3
@@ -1,3 +0,0 @@ -#include <asm/vdso.h> - -DEFINE_VDSO_IMAGE(vdsox32, "arch/x86/vdso/vdsox32.so")
arch/x86/vdso/vma.c +16 -84
137 lines not on this page · raw message
arch/x86/xen/setup.c +9 -2
@@ -516,10 +516,17 @@ char * __init xen_memory_setup(void)static void __init fiddle_vdso (void ) {#ifdef CONFIG_X86_32 +/* +* This could be called before selected_vdso32 is initialized, so +* just fiddle with both possible images. vdso_image_32_syscall +* can't be selected, since it only exists on 64-bit systems. +*/ u32 *mask; - mask =VDSO32_SYMBOL (&vdso32_int80_start,NOTE_MASK ); + mask = vdso_image_32_int80.data + + vdso_image_32_int80.sym_VDSO32_NOTE_MASK; *mask |=1 <<VDSO_NOTE_NONEGSEG_BIT ; - mask =VDSO32_SYMBOL (&vdso32_sysenter_start,NOTE_MASK ); + mask = vdso_image_32_sysenter.data + + vdso_image_32_sysenter.sym_VDSO32_NOTE_MASK; *mask |=1 <<VDSO_NOTE_NONEGSEG_BIT ;#endif }
Signature · 1 line
1.9.0
tip-bot for Andy Lutomirski
merge bot[tip:x86/vdso] x86, vdso: Reimplement vdso.so preparation in build-time C
x86, vdso: Reimplement vdso.so preparation in build-time C
Commit-ID: 6f121e548f83674ab4920a4e60afb58d4f61b829 Gitweb: http://git.kernel.org/tip/6f121e548f83674ab4920a4e60afb58d4f61b829 Author: Andy Lutomirski <[email protected]> AuthorDate: Mon, 5 May 2014 12:19:34 -0700 Committer: H. Peter Anvin <[email protected]> CommitDate: Mon, 5 May 2014 13:18:51 -0700
x86, vdso: Reimplement vdso.so preparation in build-time C
Currently, vdso.so files are prepared and analyzed by a combination of objcopy, nm, some linker script tricks, and some simple ELF parsers in the kernel. Replace all of that with plain C code that runs at build time.
All five vdso images now generate .c files that are compiled and linked in to the kernel image.
This should cause only one userspace-visible change: the loaded vDSO images are stripped more heavily than they used to be. Everything outside the loadable segment is dropped. In particular, this causes the section table and section name strings to be missing. This should be fine: real dynamic loaders don't load or inspect these tables anyway. The result is roughly equivalent to eu-strip's --strip-sections option.
The purpose of this change is to enable the vvar and hpet mappings to be moved to the page following the vDSO load segment. Currently, it is possible for the section table to extend into the page after the load segment, so, if we map it, it risks overlapping the vvar or hpet page. This happens whenever the load segment is just under a multiple of PAGE_SIZE.
The only real subtlety here is that the old code had a C file with inline assembler that did 'call VDSO32_vsyscall' and a linker script that defined 'VDSO32_vsyscall = __kernel_vsyscall'. This most likely worked by accident: the linker script entry defines a symbol associated with an address as opposed to an alias for the real dynamic symbol __kernel_vsyscall. That caused ld to relocate the reference at link time instead of leaving an interposable dynamic relocation. Since the VDSO32_vsyscall hack is no longer needed, I now use 'call __kernel_vsyscall', and I added -Bsymbolic to make it work. vdso2c will generate an error and abort the build if the resulting image contains any dynamic relocations, so we won't silently generate bad vdso images.
(Dynamic relocations are a problem because nothing will even attempt to relocate the vdso.)
--- arch/x86/ia32/ia32_signal.c | 8 +-- arch/x86/include/asm/elf.h | 7 +- arch/x86/include/asm/mmu.h | 2 +- arch/x86/include/asm/vdso.h | 70 +++++++------------ arch/x86/kernel/signal.c | 6 +- arch/x86/mm/init_64.c | 3 +- arch/x86/vdso/.gitignore | 5 +- arch/x86/vdso/Makefile | 90 +++++++++--------------- arch/x86/vdso/vclock_gettime.c | 4 +- arch/x86/vdso/vdso.S | 3 - arch/x86/vdso/vdso2c.c | 142 ++++++++++++++++++++++++++++++++++++++ arch/x86/vdso/vdso2c.h | 137 ++++++++++++++++++++++++++++++++++++ arch/x86/vdso/vdso32-setup.c | 50 ++++++-------- arch/x86/vdso/vdso32.S | 9 --- arch/x86/vdso/vdso32/vdso32.lds.S | 10 --- arch/x86/vdso/vdsox32.S | 3 - arch/x86/vdso/vma.c | 100 +++++---------------------- arch/x86/xen/setup.c | 11 ++- 18 files changed, 400 insertions(+), 260 deletions(-)
arch/x86/ia32/ia32_signal.c +4 -4
@@ -383,8 +383,8 @@ int ia32_setup_frame(int sig, struct ksignal *ksig, }else {/* Return stub is in 32bit vsyscall page */ if (current->mm->context.vdso) - restorer =VDSO32_SYMBOL (current->mm->context.vdso, - sigreturn); + restorer = current->mm->context.vdso + + selected_vdso32->sym___kernel_sigreturn;else restorer = &frame->retcode; }
@@ -462,8 +462,8 @@ int ia32_setup_rt_frame(int sig, struct ksignal *ksig,if (ksig->ka.sa.sa_flags &SA_RESTORER ) restorer = ksig->ka.sa.sa_restorer;else - restorer =VDSO32_SYMBOL (current->mm->context.vdso, - rt_sigreturn); + restorer = current->mm->context.vdso + + selected_vdso32->sym___kernel_rt_sigreturn;put_user_ex (ptr_to_compat (restorer), &frame->pretcode);/*
arch/x86/include/asm/elf.h +4 -3
@@ -299,7 +299,7 @@ do { \do { \if (vdso64_enabled) \NEW_AUX_ENT (AT_SYSINFO_EHDR , \ - (unsigned long )current->mm->context.vdso); \ + (unsigned long __force )current->mm->context.vdso); \ }while (0 )/* As a historical oddity, the x32 and x86_64 vDSOs are controlled together. */
@@ -307,7 +307,7 @@ do { \do { \if (vdso64_enabled) \NEW_AUX_ENT (AT_SYSINFO_EHDR , \ - (unsigned long )current->mm->context.vdso); \ + (unsigned long __force )current->mm->context.vdso); \ } while (0)#define AT_SYSINFO 32
@@ -325,7 +325,8 @@ else \#define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso)#define VDSO_ENTRY \ - ((unsigned long)VDSO32_SYMBOL(VDSO_CURRENT_BASE, vsyscall)) + ((unsigned long)current->mm->context.vdso + \ + selected_vdso32->sym___kernel_vsyscall)struct linux_binprm ;
arch/x86/include/asm/mmu.h +1 -1
@@ -18,7 +18,7 @@ typedef struct {#endif struct mutex lock; -void *vdso; +void __user *vdso; } mm_context_t;#ifdef CONFIG_SMP
arch/x86/include/asm/vdso.h +25 -45
88 lines not on this page · raw message
arch/x86/kernel/signal.c +4 -2
@@ -298,7 +298,8 @@ __setup_frame(int sig, struct ksignal *ksig, sigset_t *set, }if (current->mm->context.vdso) - restorer =VDSO32_SYMBOL (current->mm->context.vdso, sigreturn); + restorer = current->mm->context.vdso + + selected_vdso32->sym___kernel_sigreturn;else restorer = &frame->retcode;if (ksig->ka.sa.sa_flags &SA_RESTORER )
@@ -361,7 +362,8 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,save_altstack_ex (&frame->uc.uc_stack, regs->sp);/* Set up to return from userspace. */ - restorer =VDSO32_SYMBOL (current->mm->context.vdso, rt_sigreturn); + restorer = current->mm->context.vdso + + selected_vdso32->sym___kernel_sigreturn;if (ksig->ka.sa.sa_flags &SA_RESTORER ) restorer = ksig->ka.sa.sa_restorer;put_user_ex (restorer, &frame->pretcode);
arch/x86/mm/init_64.c +2 -1
@@ -1223,7 +1223,8 @@ int in_gate_area_no_mm(unsigned long addr)const char *arch_vma_name (struct vm_area_struct *vma) { -if (vma->vm_mm && vma->vm_start == (long )vma->vm_mm->context.vdso) +if (vma->vm_mm && vma->vm_start == + (long __force )vma->vm_mm->context.vdso)return "[vdso]" ;if (vma == &gate_vma)return "[vsyscall]" ;
arch/x86/vdso/.gitignore +2 -3
@@ -1,8 +1,7 @@ vdso.lds -vdso-syms.lds vdsox32.lds -vdsox32-syms.lds -vdso32-syms.lds vdso32-syscall-syms.lds vdso32-sysenter-syms.lds vdso32-int80-syms.lds +vdso-image-*.c +vdso2c
arch/x86/vdso/Makefile +32 -58
152 lines not on this page · raw message
arch/x86/vdso/vclock_gettime.c +2 -2
@@ -154,7 +154,7 @@ notrace static long vdso_fallback_gettime(long clock, struct timespec *ts) asm("mov %%ebx, %%edx \n" "mov %2, %%ebx \n" -"call VDSO32_vsyscall \n" +"call __kernel_vsyscall \n" "mov %%edx, %%ebx \n" :"=a" (ret) : "0" (__NR_clock_gettime), "g" (clock), "c" (ts)
@@ -169,7 +169,7 @@ notrace static long vdso_fallback_gtod(struct timeval *tv, struct timezone *tz) asm("mov %%ebx, %%edx \n" "mov %2, %%ebx \n" -"call VDSO32_vsyscall \n" +"call __kernel_vsyscall \n" "mov %%edx, %%ebx \n" :"=a" (ret) : "0" (__NR_gettimeofday), "g" (tv), "c" (tz)
arch/x86/vdso/vdso.S deleted +0 -3
@@ -1,3 +0,0 @@ -#include <asm/vdso.h> - -DEFINE_VDSO_IMAGE(vdso, "arch/x86/vdso/vdso.so")
arch/x86/vdso/vdso2c.c new file +142 -0
142 lines not on this page · raw message
arch/x86/vdso/vdso2c.h new file +137 -0
137 lines not on this page · raw message
arch/x86/vdso/vdso32-setup.c +20 -30
97 lines not on this page · raw message
arch/x86/vdso/vdso32.S deleted +0 -9
@@ -1,9 +0,0 @@ -#include <asm/vdso.h> - -DEFINE_VDSO_IMAGE(vdso32_int80, "arch/x86/vdso/vdso32-int80.so") - -#ifdef CONFIG_COMPAT -DEFINE_VDSO_IMAGE(vdso32_syscall, "arch/x86/vdso/vdso32-syscall.so") -#endif - -DEFINE_VDSO_IMAGE(vdso32_sysenter, "arch/x86/vdso/vdso32-sysenter.so")
arch/x86/vdso/vdso32/vdso32.lds.S +0 -10
@@ -38,13 +38,3 @@ VERSION local: *; }; } - -/* - * Symbols we define here called VDSO* get their values into vdso32-syms.h. - */ -VDSO32_vsyscall = __kernel_vsyscall; -VDSO32_sigreturn = __kernel_sigreturn; -VDSO32_rt_sigreturn = __kernel_rt_sigreturn; -VDSO32_clock_gettime = clock_gettime; -VDSO32_gettimeofday = gettimeofday; -VDSO32_time = time;
arch/x86/vdso/vdsox32.S deleted +0 -3
@@ -1,3 +0,0 @@ -#include <asm/vdso.h> - -DEFINE_VDSO_IMAGE(vdsox32, "arch/x86/vdso/vdsox32.so")
arch/x86/vdso/vma.c +16 -84
137 lines not on this page · raw message
arch/x86/xen/setup.c +9 -2
@@ -516,10 +516,17 @@ char * __init xen_memory_setup(void)static void __init fiddle_vdso (void ) {#ifdef CONFIG_X86_32 +/* +* This could be called before selected_vdso32 is initialized, so +* just fiddle with both possible images. vdso_image_32_syscall +* can't be selected, since it only exists on 64-bit systems. +*/ u32 *mask; - mask =VDSO32_SYMBOL (&vdso32_int80_start,NOTE_MASK ); + mask = vdso_image_32_int80.data + + vdso_image_32_int80.sym_VDSO32_NOTE_MASK; *mask |=1 <<VDSO_NOTE_NONEGSEG_BIT ; - mask =VDSO32_SYMBOL (&vdso32_sysenter_start,NOTE_MASK ); + mask = vdso_image_32_sysenter.data + + vdso_image_32_sysenter.sym_VDSO32_NOTE_MASK; *mask |=1 <<VDSO_NOTE_NONEGSEG_BIT ;#endif }
Re: [tip:x86/vdso] x86, vdso: Reimplement vdso.so preparation in build-time C
Quoted 8 lines · tip-bot for Andy Lutomirski
Commit-ID: 6f121e548f83674ab4920a4e60afb58d4f61b829 Gitweb: http://git.kernel.org/tip/6f121e548f83674ab4920a4e60afb58d4f61b829 Author: Andy Lutomirski <[email protected]> AuthorDate: Mon, 5 May 2014 12:19:34 -0700 Committer: H. Peter Anvin <[email protected]> CommitDate: Mon, 5 May 2014 13:18:51 -0700x86, vdso: Reimplement vdso.so preparation in build-time C
Just a heads up in case it hasn't been mentioned already; the x86 builds in linux-next which IIRC are done as cross compile on a powerpc box are failing as follows:
VDSO2C arch/x86/vdso/vdso-image-64.c/bin/sh: line 1: 15995 Segmentation fault arch/x86/vdso/vdso2carch/x86/vdso/vdso64.so.dbg arch/x86/vdso/vdso-image-64.c make[3]: *** [arch/x86/vdso/vdso-image-64.c] Error 139
http://kisskb.ellerman.id.au/kisskb/buildresult/11265454/
Paul.
--
Quoted 44 lines
Currently, vdso.so files are prepared and analyzed by a combination of objcopy, nm, some linker script tricks, and some simple ELF parsers in the kernel. Replace all of that with plain C code that runs at build time.
All five vdso images now generate .c files that are compiled and linked in to the kernel image.
This should cause only one userspace-visible change: the loaded vDSO images are stripped more heavily than they used to be. Everything outside the loadable segment is dropped. In particular, this causes the section table and section name strings to be missing. This should be fine: real dynamic loaders don't load or inspect these tables anyway. The result is roughly equivalent to eu-strip's --strip-sections option.
The purpose of this change is to enable the vvar and hpet mappings to be moved to the page following the vDSO load segment. Currently, it is possible for the section table to extend into the page after the load segment, so, if we map it, it risks overlapping the vvar or hpet page. This happens whenever the load segment is just under a multiple of
PAGE_SIZE.The only real subtlety here is that the old code had a C file with inline assembler that did 'call
VDSO32_vsyscall' and a linker script that defined 'VDSO32_vsyscall=__kernel_vsyscall'. This most likely worked by accident: the linker script entry defines a symbol associated with an address as opposed to an alias for the real dynamic symbol__kernel_vsyscall. That caused ld to relocate the reference at link time instead of leaving an interposable dynamic relocation. Since theVDSO32_vsyscallhack is no longer needed, I now use 'call__kernel_vsyscall', and I added -Bsymbolic to make it work. vdso2c will generate an error and abort the build if the resulting image contains any dynamic relocations, so we won't silently generate bad vdso images.(Dynamic relocations are a problem because nothing will even attempt to relocate the vdso.)
Signed-off-by Andy Lutomirski <[email protected]>Link http://lkml.kernel.org/r/2c4fcf45524162a34d87fdda1eb046b2a5cecee7.1399317206.git.luto@amacapital.net open hereSigned-off-by H. Peter Anvin <[email protected]>---
Re: [tip:x86/vdso] x86, vdso: Reimplement vdso.so preparation in build-time C
Quoted 15 lines · Paul Gortmaker
Quoted 8 lines · tip-bot for Andy Lutomirski
Commit-ID: 6f121e548f83674ab4920a4e60afb58d4f61b829 Gitweb: http://git.kernel.org/tip/6f121e548f83674ab4920a4e60afb58d4f61b829 Author: Andy Lutomirski <[email protected]> AuthorDate: Mon, 5 May 2014 12:19:34 -0700 Committer: H. Peter Anvin <[email protected]> CommitDate: Mon, 5 May 2014 13:18:51 -0700x86, vdso: Reimplement vdso.so preparation in build-time C
Just a heads up in case it hasn't been mentioned already; the x86 builds in linux-next which IIRC are done as cross compile on a powerpc box are failing as follows:
Quoted 7 lines
VDSO2C
arch/x86/vdso/vdso-image-64.c/bin/sh: line 1: 15995 Segmentation faultarch/x86/vdso/vdso2carch/x86/vdso/vdso64.so.dbgarch/x86/vdso/vdso-image-64.cmake[3]: *** [arch/x86/vdso/vdso-image-64.c] Error 139
Egads. This wouldn't be a big-endian host by any chance?
--Andy
Re: [tip:x86/vdso] x86, vdso: Reimplement vdso.so preparation in build-time C
Quoted 22 lines · Andy Lutomirski
Quoted 20 lines · Paul Gortmaker
Quoted 8 lines · tip-bot for Andy Lutomirski
Commit-ID: 6f121e548f83674ab4920a4e60afb58d4f61b829 Gitweb: http://git.kernel.org/tip/6f121e548f83674ab4920a4e60afb58d4f61b829 Author: Andy Lutomirski <[email protected]> AuthorDate: Mon, 5 May 2014 12:19:34 -0700 Committer: H. Peter Anvin <[email protected]> CommitDate: Mon, 5 May 2014 13:18:51 -0700x86, vdso: Reimplement vdso.so preparation in build-time C
Just a heads up in case it hasn't been mentioned already; the x86 builds in linux-next which IIRC are done as cross compile on a powerpc box are failing as follows:
VDSO2C
arch/x86/vdso/vdso-image-64.c/bin/sh: line 1: 15995 Segmentation faultarch/x86/vdso/vdso2carch/x86/vdso/vdso64.so.dbgarch/x86/vdso/vdso-image-64.cmake[3]: *** [arch/x86/vdso/vdso-image-64.c] Error 139
Quoted 4 lines
Egads. This wouldn't be a big-endian host by any chance?
Likely if it's really a cross compile on a powerpc machine. Virtually all existing powerpc machines are big-endian.
josh
H. Peter Anvin
reviewerRe: [tip:x86/vdso] x86, vdso: Reimplement vdso.so preparation in build-time C
In reply to Andy LutomirskiQuoted 22 lines · Andy Lutomirski
Quoted 20 lines · Paul Gortmaker
Quoted 8 lines · tip-bot for Andy Lutomirski
Commit-ID: 6f121e548f83674ab4920a4e60afb58d4f61b829 Gitweb: http://git.kernel.org/tip/6f121e548f83674ab4920a4e60afb58d4f61b829 Author: Andy Lutomirski <[email protected]> AuthorDate: Mon, 5 May 2014 12:19:34 -0700 Committer: H. Peter Anvin <[email protected]> CommitDate: Mon, 5 May 2014 13:18:51 -0700x86, vdso: Reimplement vdso.so preparation in build-time C
Just a heads up in case it hasn't been mentioned already; the x86 builds in linux-next which IIRC are done as cross compile on a powerpc box are failing as follows:
VDSO2C
arch/x86/vdso/vdso-image-64.c/bin/sh: line 1: 15995 Segmentation faultarch/x86/vdso/vdso2carch/x86/vdso/vdso64.so.dbgarch/x86/vdso/vdso-image-64.cmake[3]: *** [arch/x86/vdso/vdso-image-64.c] Error 139
Quoted 5 lines
Egads. This wouldn't be a big-endian host by any chance?
He said PowerPC; most but not all PowerPC systems are bigendian. Seems like a fair assumption to make.
-hpa
Re: [tip:x86/vdso] x86, vdso: Reimplement vdso.so preparation in build-time C
Quoted 23 lines · H. Peter Anvin
Quoted 22 lines · Andy Lutomirski
Quoted 20 lines · Paul Gortmaker
Quoted 8 lines · tip-bot for Andy Lutomirski
Commit-ID: 6f121e548f83674ab4920a4e60afb58d4f61b829 Gitweb: http://git.kernel.org/tip/6f121e548f83674ab4920a4e60afb58d4f61b829 Author: Andy Lutomirski <[email protected]> AuthorDate: Mon, 5 May 2014 12:19:34 -0700 Committer: H. Peter Anvin <[email protected]> CommitDate: Mon, 5 May 2014 13:18:51 -0700x86, vdso: Reimplement vdso.so preparation in build-time C
Just a heads up in case it hasn't been mentioned already; the x86 builds in linux-next which IIRC are done as cross compile on a powerpc box are failing as follows:
VDSO2C
arch/x86/vdso/vdso-image-64.c/bin/sh: line 1: 15995 Segmentation faultarch/x86/vdso/vdso2carch/x86/vdso/vdso64.so.dbgarch/x86/vdso/vdso-image-64.cmake[3]: *** [arch/x86/vdso/vdso-image-64.c] Error 139
Quoted 9 lines
Quoted 5 lines
Egads. This wouldn't be a big-endian host by any chance?
He said PowerPC; most but not all PowerPC systems are bigendian. Seems like a fair assumption to make.
I suppose I shouldn't have assumed that code in arch/x86 would always run on little-endian machines. I'll fix it.
--Andy
cover x86,vdso: vdso build fixes and improvements
Patch 1 causes make;make to behave similarly to make if vdso2c fails. Patch 2 hopefully fixes x86 crossbuilds on big-endian machines. I don't have a big-endian machine to test on, though.
Andy Lutomirski (2):
x86,vdso: When vdso2c fails, unlink the output x86,vdso: Fix cross-compilation from big-endian architectures
arch/x86/vdso/vdso2c.c | 35 ++++++++++++++++++------- arch/x86/vdso/vdso2c.h | 69 ++++++++++++++++++++++++++------------------------ 2 files changed, 62 insertions(+), 42 deletions(-)
Signature · 1 line
1.9.3
PATCH 1/2 x86,vdso: When vdso2c fails, unlink the output
This avoids bizarre failures if make is run again.
--- arch/x86/vdso/vdso2c.c | 20 +++++++++++--------- arch/x86/vdso/vdso2c.h | 10 +++------- 2 files changed, 14 insertions(+), 16 deletions(-)
arch/x86/vdso/vdso2c.c +11 -9
@@ -14,6 +14,8 @@#include <linux/elf.h> #include <linux/types.h> +const char *outfilename; +/* Symbols that we need in vdso2c. */ enum { sym_vvar_page,
@@ -44,6 +46,7 @@ static void fail(const char *format, ...)va_start (ap, format);fprintf (stderr,"Error: " );vfprintf (stderr, format, ap); +unlink (outfilename);exit (1 );va_end (ap); }
@@ -82,17 +85,16 @@ static void fail(const char *format, ...)#undef Elf_Sym#undef Elf_Dyn -static int go (void *addr,size_t len,FILE *outfile,const char *name) +static void go (void *addr,size_t len,FILE *outfile,const char *name) {Elf64_Ehdr *hdr = (Elf64_Ehdr *)addr;if (hdr->e_ident[EI_CLASS ] ==ELFCLASS64 ) { -return go64 (addr, len, outfile, name); +go64 (addr, len, outfile, name); }else if (hdr->e_ident[EI_CLASS ] ==ELFCLASS32 ) { -return go32 (addr, len, outfile, name); +go32 (addr, len, outfile, name); }else { -fprintf (stderr,"Error: unknown ELF class\n" ); -return 1 ; +fail ("unknown ELF class\n" ); } }
@@ -102,7 +104,6 @@ int main(int argc, char **argv)off_t len;void *addr;FILE *outfile; -int ret;char *name, *tmp;int namelen;
@@ -143,14 +144,15 @@ int main(int argc, char **argv)if (addr ==MAP_FAILED )err (1 ,"mmap" ); - outfile =fopen (argv[2 ],"w" ); + outfilename = argv[2 ]; + outfile =fopen (outfilename,"w" );if (!outfile)err (1 ,"%s" , argv[2 ]); - ret =go (addr, (size_t )len, outfile, name); +go (addr, (size_t )len, outfile, name);munmap (addr, len);fclose (outfile); -return ret; +return 0 ; }
arch/x86/vdso/vdso2c.h +3 -7
@@ -4,7 +4,7 @@* are built for 32-bit userspace. */ -static int GOFUNC (void *addr,size_t len,FILE *outfile,const char *name) +static void GOFUNC (void *addr,size_t len,FILE *outfile,const char *name) {int found_load =0 ;unsigned long load_size =-1 ;/* Work around bogus warning */
@@ -62,10 +62,8 @@ static int GOFUNC(void *addr, size_t len, FILE *outfile, const char *name) alt_sec = sh; } -if (!symtab_hdr) { +if (!symtab_hdr)fail ("no symbol table\n" ); -return 1 ; - } strtab_hdr = addr + hdr->e_shoff + hdr->e_shentsize * symtab_hdr->sh_link;
@@ -112,7 +110,7 @@ static int GOFUNC(void *addr, size_t len, FILE *outfile, const char *name)if (!name) {fwrite (addr, load_size,1 , outfile); -return 0 ; +return ; }fprintf (outfile,"/* AUTOMATICALLY GENERATED -- DO NOT EDIT */\n\n" );
@@ -152,6 +150,4 @@ static int GOFUNC(void *addr, size_t len, FILE *outfile, const char *name) required_syms[i], syms[i]); }fprintf (outfile,"};\n" ); - -return 0 ; }
Signature · 1 line
1.9.3
PATCH 2/2 x86,vdso: Fix cross-compilation from big-endian architectures
In reply to Andy LutomirskiThis adds a macro GET(x) to convert x from big-endian to little-endian. Hopefully I put it everywhere it needs to go and got all the cases needed for everyone's linux/elf.h.
--- arch/x86/vdso/vdso2c.c | 15 +++++++++++++ arch/x86/vdso/vdso2c.h | 59 ++++++++++++++++++++++++++++---------------------- 2 files changed, 48 insertions(+), 26 deletions(-)
arch/x86/vdso/vdso2c.c +15 -0
@@ -51,6 +51,21 @@ static void fail(const char *format, ...)va_end (ap); } +/* +* Evil macros to do a little-endian read. +*/ +#define __GET_TYPE (x, type, bits, ifnot) \ + __builtin_choose_expr( \ + __builtin_types_compatible_p(typeof(x), type), \ + le##bits##toh((x)), ifnot) + +extern void bad_get (uint64_t ); + +#define GET (x) \ + __GET_TYPE((x), __u32, 32, __GET_TYPE((x), __u64, 64, \ + __GET_TYPE((x), __s32, 32, __GET_TYPE((x), __s64, 64, \ + __GET_TYPE((x), __u16, 16, bad_get(x)))))) +#define NSYMS (sizeof(required_syms) / sizeof(required_syms[0]))#define BITS 64
arch/x86/vdso/vdso2c.h +33 -26
108 lines not on this page · raw message
Signature · 1 line
1.9.3
Re: [PATCH 0/2] x86,vdso: vdso build fixes and improvements
In reply to Andy LutomirskiQuoted 3 lines · Andy Lutomirski
Patch 1 causes make;make to behave similarly to make if vdso2c fails. Patch 2 hopefully fixes x86 crossbuilds on big-endian machines. I don't have a big-endian machine to test on, though.
Since the x86 builds are unconditionally failing as-is now in linux-next, perhaps Stephen [Cc'd] can layer these on the top of the tree he'll be making within the next couple of hours to give them a big-endian test.
Paul.
--
Quoted 9 lines
Andy Lutomirski (2):
x86,vdso: When vdso2c fails, unlink the output x86,vdso: Fix cross-compilation from big-endian architecturesarch/x86/vdso/vdso2c.c | 35 ++++++++++++++++++------- arch/x86/vdso/vdso2c.h | 69 ++++++++++++++++++++++++++------------------------ 2 files changed, 62 insertions(+), 42 deletions(-)
Re: [PATCH 0/2] x86,vdso: vdso build fixes and improvements
Quoted 9 lines · Paul Gortmaker
Quoted 3 lines · Andy Lutomirski
Patch 1 causes make;make to behave similarly to make if vdso2c fails. Patch 2 hopefully fixes x86 crossbuilds on big-endian machines. I don't have a big-endian machine to test on, though.
Since the x86 builds are unconditionally failing as-is now in linux-next, perhaps Stephen [Cc'd] can layer these on the top of the tree he'll be making within the next couple of hours to give them a big-endian test.
Stephen, if you do this, could you also send me some of the build outputs:
arch/x86/vdso/*.so.dbgarch/x86/vdso/*-image-*.c
I'd like to verify that the output is correct. It would be unfortunate if the cross-built kernel had some subtle error.
Thanks,
Andy
Re: [PATCH 0/2] x86,vdso: vdso build fixes and improvements
Hi Andy,
Quoted 4 lines · On Thu, 29 May 2014 15:49:52 -0700 Andy Lutomirski <[email protected]> wrote:
Quoted 1 line · Paul Gortmaker
On 14-05-29 05:57 PM, Andy Lutomirski wrote:
Quoted 8 lines
Quoted 8 lines
Quoted 3 lines
Patch 1 causes make;make to behave similarly to make if vdso2c fails. Patch 2 hopefully fixes x86 crossbuilds on big-endian machines. I don't have a big-endian machine to test on, though.
Since the x86 builds are unconditionally failing as-is now in linux-next, perhaps Stephen [Cc'd] can layer these on the top of the tree he'll be making within the next couple of hours to give them a big-endian test.
I added them just after the merge of the tip tree today and will keep them there until they (or somo other solution) turn up some other way.
Quoted 7 lines
Stephen, if you do this, could you also send me some of the build outputs:
arch/x86/vdso/*.so.dbgarch/x86/vdso/*-image-*.cI'd like to verify that the output is correct. It would be unfortunate if the cross-built kernel had some subtle error.
OK, I will send them in a separate email.
Signature · 2 lines
Cheers, Stephen Rothwell [email protected]
Re: [PATCH 0/2] x86,vdso: vdso build fixes and improvements
Quoted 21 lines · Stephen Rothwell
Hi Andy,
Quoted 4 lines · On Thu, 29 May 2014 15:49:52 -0700 Andy Lutomirski <[email protected]> wrote:
Quoted 1 line · Paul Gortmaker
On 14-05-29 05:57 PM, Andy Lutomirski wrote:
Quoted 8 lines
Quoted 8 lines
Quoted 3 lines
Patch 1 causes make;make to behave similarly to make if vdso2c fails. Patch 2 hopefully fixes x86 crossbuilds on big-endian machines. I don't have a big-endian machine to test on, though.
Since the x86 builds are unconditionally failing as-is now in linux-next, perhaps Stephen [Cc'd] can layer these on the top of the tree he'll be making within the next couple of hours to give them a big-endian test.
I added them just after the merge of the tip tree today and will keep them there until they (or somo other solution) turn up some other way.
Quoted 2 lines
Stephen, if you do this, could you also send me some of the build outputs:
Quoted 7 lines
Quoted 5 lines
arch/x86/vdso/*.so.dbgarch/x86/vdso/*-image-*.cI'd like to verify that the output is correct. It would be unfortunate if the cross-built kernel had some subtle error.
OK, I will send them in a separate email.
For the benefit of the archives: the patches are bad. New ones coming.
--Andy
Quoted 4 lines
--
Cheers,
Stephen Rothwell [email protected]
Signature · 2 lines
Andy Lutomirski AMA Capital Management, LLC
v2 cover x86,vdso: vdso build fixes and improvements
In reply to Andy LutomirskiPatch 1 causes make;make to behave similarly to make if vdso2c fails. Patch 2 hopefully fixes x86 crossbuilds on big-endian machines. I don't have a big-endian machine to test on, though.
Changes from v1: Add two missing endian fixes
Andy Lutomirski (2):
x86,vdso: When vdso2c fails, unlink the output x86,vdso: Fix cross-compilation from big-endian architectures
arch/x86/vdso/vdso2c.c | 35 +++++++++++++++++------- arch/x86/vdso/vdso2c.h | 73 ++++++++++++++++++++++++++------------------------ 2 files changed, 64 insertions(+), 44 deletions(-)
Signature · 1 line
1.9.3
PATCH v2 1/2 x86,vdso: When vdso2c fails, unlink the output
This avoids bizarre failures if make is run again.
--- arch/x86/vdso/vdso2c.c | 20 +++++++++++--------- arch/x86/vdso/vdso2c.h | 10 +++------- 2 files changed, 14 insertions(+), 16 deletions(-)
arch/x86/vdso/vdso2c.c +11 -9
@@ -14,6 +14,8 @@#include <linux/elf.h> #include <linux/types.h> +const char *outfilename; +/* Symbols that we need in vdso2c. */ enum { sym_vvar_page,
@@ -44,6 +46,7 @@ static void fail(const char *format, ...)va_start (ap, format);fprintf (stderr,"Error: " );vfprintf (stderr, format, ap); +unlink (outfilename);exit (1 );va_end (ap); }
@@ -82,17 +85,16 @@ static void fail(const char *format, ...)#undef Elf_Sym#undef Elf_Dyn -static int go (void *addr,size_t len,FILE *outfile,const char *name) +static void go (void *addr,size_t len,FILE *outfile,const char *name) {Elf64_Ehdr *hdr = (Elf64_Ehdr *)addr;if (hdr->e_ident[EI_CLASS ] ==ELFCLASS64 ) { -return go64 (addr, len, outfile, name); +go64 (addr, len, outfile, name); }else if (hdr->e_ident[EI_CLASS ] ==ELFCLASS32 ) { -return go32 (addr, len, outfile, name); +go32 (addr, len, outfile, name); }else { -fprintf (stderr,"Error: unknown ELF class\n" ); -return 1 ; +fail ("unknown ELF class\n" ); } }
@@ -102,7 +104,6 @@ int main(int argc, char **argv)off_t len;void *addr;FILE *outfile; -int ret;char *name, *tmp;int namelen;
@@ -143,14 +144,15 @@ int main(int argc, char **argv)if (addr ==MAP_FAILED )err (1 ,"mmap" ); - outfile =fopen (argv[2 ],"w" ); + outfilename = argv[2 ]; + outfile =fopen (outfilename,"w" );if (!outfile)err (1 ,"%s" , argv[2 ]); - ret =go (addr, (size_t )len, outfile, name); +go (addr, (size_t )len, outfile, name);munmap (addr, len);fclose (outfile); -return ret; +return 0 ; }
arch/x86/vdso/vdso2c.h +3 -7
@@ -4,7 +4,7 @@* are built for 32-bit userspace. */ -static int GOFUNC (void *addr,size_t len,FILE *outfile,const char *name) +static void GOFUNC (void *addr,size_t len,FILE *outfile,const char *name) {int found_load =0 ;unsigned long load_size =-1 ;/* Work around bogus warning */
@@ -62,10 +62,8 @@ static int GOFUNC(void *addr, size_t len, FILE *outfile, const char *name) alt_sec = sh; } -if (!symtab_hdr) { +if (!symtab_hdr)fail ("no symbol table\n" ); -return 1 ; - } strtab_hdr = addr + hdr->e_shoff + hdr->e_shentsize * symtab_hdr->sh_link;
@@ -112,7 +110,7 @@ static int GOFUNC(void *addr, size_t len, FILE *outfile, const char *name)if (!name) {fwrite (addr, load_size,1 , outfile); -return 0 ; +return ; }fprintf (outfile,"/* AUTOMATICALLY GENERATED -- DO NOT EDIT */\n\n" );
@@ -152,6 +150,4 @@ static int GOFUNC(void *addr, size_t len, FILE *outfile, const char *name) required_syms[i], syms[i]); }fprintf (outfile,"};\n" ); - -return 0 ; }
Signature · 1 line
1.9.3
tip-bot for Andy Lutomirski
merge bot[tip:x86/vdso] x86/vdso, build: When vdso2c fails, unlink the output
x86/vdso, build: When vdso2c fails, unlink the output
Commit-ID: 011561837dad082a92c0537db2d134e66419c6ad Gitweb: http://git.kernel.org/tip/011561837dad082a92c0537db2d134e66419c6ad Author: Andy Lutomirski <[email protected]> AuthorDate: Fri, 30 May 2014 08:48:48 -0700 Committer: H. Peter Anvin <[email protected]> CommitDate: Fri, 30 May 2014 16:58:39 -0700
x86/vdso, build: When vdso2c fails, unlink the output
This avoids bizarre failures if make is run again.
--- arch/x86/vdso/vdso2c.c | 20 +++++++++++--------- arch/x86/vdso/vdso2c.h | 10 +++------- 2 files changed, 14 insertions(+), 16 deletions(-)
arch/x86/vdso/vdso2c.c +11 -9
@@ -14,6 +14,8 @@#include <linux/elf.h> #include <linux/types.h> +const char *outfilename; +/* Symbols that we need in vdso2c. */ enum { sym_vvar_page,
@@ -44,6 +46,7 @@ static void fail(const char *format, ...)va_start (ap, format);fprintf (stderr,"Error: " );vfprintf (stderr, format, ap); +unlink (outfilename);exit (1 );va_end (ap); }
@@ -82,17 +85,16 @@ static void fail(const char *format, ...)#undef Elf_Sym#undef Elf_Dyn -static int go (void *addr,size_t len,FILE *outfile,const char *name) +static void go (void *addr,size_t len,FILE *outfile,const char *name) {Elf64_Ehdr *hdr = (Elf64_Ehdr *)addr;if (hdr->e_ident[EI_CLASS ] ==ELFCLASS64 ) { -return go64 (addr, len, outfile, name); +go64 (addr, len, outfile, name); }else if (hdr->e_ident[EI_CLASS ] ==ELFCLASS32 ) { -return go32 (addr, len, outfile, name); +go32 (addr, len, outfile, name); }else { -fprintf (stderr,"Error: unknown ELF class\n" ); -return 1 ; +fail ("unknown ELF class\n" ); } }
@@ -102,7 +104,6 @@ int main(int argc, char **argv)off_t len;void *addr;FILE *outfile; -int ret;char *name, *tmp;int namelen;
@@ -143,14 +144,15 @@ int main(int argc, char **argv)if (addr ==MAP_FAILED )err (1 ,"mmap" ); - outfile =fopen (argv[2 ],"w" ); + outfilename = argv[2 ]; + outfile =fopen (outfilename,"w" );if (!outfile)err (1 ,"%s" , argv[2 ]); - ret =go (addr, (size_t )len, outfile, name); +go (addr, (size_t )len, outfile, name);munmap (addr, len);fclose (outfile); -return ret; +return 0 ; }
arch/x86/vdso/vdso2c.h +3 -7
@@ -4,7 +4,7 @@* are built for 32-bit userspace. */ -static int GOFUNC (void *addr,size_t len,FILE *outfile,const char *name) +static void GOFUNC (void *addr,size_t len,FILE *outfile,const char *name) {int found_load =0 ;unsigned long load_size =-1 ;/* Work around bogus warning */
@@ -62,10 +62,8 @@ static int GOFUNC(void *addr, size_t len, FILE *outfile, const char *name) alt_sec = sh; } -if (!symtab_hdr) { +if (!symtab_hdr)fail ("no symbol table\n" ); -return 1 ; - } strtab_hdr = addr + hdr->e_shoff + hdr->e_shentsize * symtab_hdr->sh_link;
@@ -112,7 +110,7 @@ static int GOFUNC(void *addr, size_t len, FILE *outfile, const char *name)if (!name) {fwrite (addr, load_size,1 , outfile); -return 0 ; +return ; }fprintf (outfile,"/* AUTOMATICALLY GENERATED -- DO NOT EDIT */\n\n" );
@@ -152,6 +150,4 @@ static int GOFUNC(void *addr, size_t len, FILE *outfile, const char *name) required_syms[i], syms[i]); }fprintf (outfile,"};\n" ); - -return 0 ; }
PATCH v2 2/2 x86,vdso: Fix cross-compilation from big-endian architectures
In reply to Andy LutomirskiThis adds a macro GET(x) to convert x from big-endian to little-endian. Hopefully I put it everywhere it needs to go and got all the cases needed for everyone's linux/elf.h.
--- arch/x86/vdso/vdso2c.c | 15 ++++++++++++ arch/x86/vdso/vdso2c.h | 63 ++++++++++++++++++++++++++++---------------------- 2 files changed, 50 insertions(+), 28 deletions(-)
arch/x86/vdso/vdso2c.c +15 -0
@@ -51,6 +51,21 @@ static void fail(const char *format, ...)va_end (ap); } +/* +* Evil macros to do a little-endian read. +*/ +#define __GET_TYPE (x, type, bits, ifnot) \ + __builtin_choose_expr( \ + __builtin_types_compatible_p(typeof(x), type), \ + le##bits##toh((x)), ifnot) + +extern void bad_get (uint64_t ); + +#define GET (x) \ + __GET_TYPE((x), __u32, 32, __GET_TYPE((x), __u64, 64, \ + __GET_TYPE((x), __s32, 32, __GET_TYPE((x), __s64, 64, \ + __GET_TYPE((x), __u16, 16, bad_get(x)))))) +#define NSYMS (sizeof(required_syms) / sizeof(required_syms[0]))#define BITS 64
arch/x86/vdso/vdso2c.h +35 -28
119 lines not on this page · raw message
Signature · 1 line
1.9.3
H. Peter Anvin
reviewerRe: [PATCH v2 2/2] x86,vdso: Fix cross-compilation from big-endian architectures
Quoted 9 lines · Andy Lutomirski
This adds a macro GET(x) to convert x from big-endian to little-endian. Hopefully I put it everywhere it needs to go and got all the cases needed for everyone's
linux/elf.h.Signed-off-by Andy Lutomirski <[email protected]>--- arch/x86/vdso/vdso2c.c | 15 ++++++++++++ arch/x86/vdso/vdso2c.h | 63 ++++++++++++++++++++++++++++---------------------- 2 files changed, 50 insertions(+), 28 deletions(-)
A couple of observations:
1. We shouldn't use double-underscore in host C code.
2. It would be nice if we can take these sort of things (host-build helper macros) and move them to some common file in the Linux kernel eventually, so it would be a good thing to make the naming a little less general.
3. Even though it isn't necessary, making it work on 8-bit values so one doesn't have to worry about the type would seem like a good thing.
I came up with the following, it seems like a reasonable simplification:
Quoted 11 lines
#define _LE(x, bits, ifnot) \ __builtin_choose_expr( \ (sizeof(x) == bits/8), \ (__typeof__(x))le##bits##toh(x), ifnot)extern void
bad_le(uint64_t);#define _LAST_LE(x) \ __builtin_choose_expr(sizeof(x) == 1, (x), bad_le(x))#define LE(x) \ _LE(x, 64, _LE(x, 32, _LE(x, 16, _LAST_LE(x))))
What do you think?
-hpa
Re: [PATCH v2 2/2] x86,vdso: Fix cross-compilation from big-endian architectures
Quoted 20 lines · H. Peter Anvin
Quoted 9 lines · Andy Lutomirski
This adds a macro GET(x) to convert x from big-endian to little-endian. Hopefully I put it everywhere it needs to go and got all the cases needed for everyone's
linux/elf.h.Signed-off-by Andy Lutomirski <[email protected]>--- arch/x86/vdso/vdso2c.c | 15 ++++++++++++ arch/x86/vdso/vdso2c.h | 63 ++++++++++++++++++++++++++++---------------------- 2 files changed, 50 insertions(+), 28 deletions(-)A couple of observations:
1. We shouldn't use double-underscore in host C code.
2. It would be nice if we can take these sort of things (host-build helper macros) and move them to some common file in the Linux kernel eventually, so it would be a good thing to make the naming a little less general.
Quoted 10 lines
3. Even though it isn't necessary, making it work on 8-bit values so one doesn't have to worry about the type would seem like a good thing.
I came up with the following, it seems like a reasonable simplification:
Quoted 4 lines
#define _LE(x, bits, ifnot) \ __builtin_choose_expr( \ (sizeof(x) == bits/8), \ (__typeof__(x))le##bits##toh(x), ifnot)
This will do awful things if x is a floating-point type, and, for integers, the cast is probably unnecessary. But it should be okay.
Quoted 2 lines
Quoted 2 lines
extern void
bad_le(uint64_t);
If this ever goes in a common header, then we should do the __attribute__((error)) thing. I wonder if it would ever make sense to have __LINUX_HOSTPROG__ and make some of the basic headers work. Hmm.
Quoted 7 lines
Quoted 5 lines
#define _LAST_LE(x) \ __builtin_choose_expr(sizeof(x) == 1, (x), bad_le(x))#define LE(x) \ _LE(x, 64, _LE(x, 32, _LE(x, 16, _LAST_LE(x))))What do you think?
My only real real objection is that _LE sounds like converting *to* little-endian to me. Admittedly, that's the same thing on any remotely sane architecture, but still.
--Andy
H. Peter Anvin
reviewerRe: [PATCH v2 2/2] x86,vdso: Fix cross-compilation from big-endian architectures
Quoted 11 lines · Andy Lutomirski
Quoted 7 lines
I came up with the following, it seems like a reasonable simplification:
Quoted 4 lines
#define _LE(x, bits, ifnot) \ __builtin_choose_expr( \ (sizeof(x) == bits/8), \ (__typeof__(x))le##bits##toh(x), ifnot)This will do awful things if x is a floating-point type, and, for integers, the cast is probably unnecessary. But it should be okay.
I mostly wanted to preserve the signedness. Yes, if we care about floating-point it gets trickier.
At some point hopefully there will be a native C feature to handle this crap.
Quoted 9 lines
Quoted 1 line
Quoted 1 line
extern void
bad_le(uint64_t);If this ever goes in a common header, then we should do the __attribute__((error)) thing. I wonder if it would ever make sense to have
__LINUX_HOSTPROG__and make some of the basic headers work. Hmm.Quoted 3 lines
Quoted 3 lines
#define _LAST_LE(x) \ __builtin_choose_expr(sizeof(x) == 1, (x), bad_le(x))
Quoted 8 lines
Quoted 4 lines
Quoted 2 lines
#define LE(x) \ _LE(x, 64, _LE(x, 32, _LE(x, 16, _LAST_LE(x))))What do you think?
My only real real objection is that
_LEsounds like converting *to* little-endian to me. Admittedly, that's the same thing on any remotely sane architecture, but still.
GET_LE() then?
-hpa
Re: [PATCH v2 2/2] x86,vdso: Fix cross-compilation from big-endian architectures
Quoted 31 lines · H. Peter Anvin
Quoted 11 lines · Andy Lutomirski
Quoted 7 lines
I came up with the following, it seems like a reasonable simplification:
Quoted 4 lines
#define _LE(x, bits, ifnot) \ __builtin_choose_expr( \ (sizeof(x) == bits/8), \ (__typeof__(x))le##bits##toh(x), ifnot)This will do awful things if x is a floating-point type, and, for integers, the cast is probably unnecessary. But it should be okay.
I mostly wanted to preserve the signedness. Yes, if we care about floating-point it gets trickier.
At some point hopefully there will be a native C feature to handle this crap.
Quoted 12 lines
Quoted 1 line
Quoted 1 line
extern void
bad_le(uint64_t);If this ever goes in a common header, then we should do the __attribute__((error)) thing. I wonder if it would ever make sense to have
__LINUX_HOSTPROG__and make some of the basic headers work. Hmm.Quoted 6 lines
Quoted 5 lines
#define _LAST_LE(x) \ __builtin_choose_expr(sizeof(x) == 1, (x), bad_le(x))#define LE(x) \ _LE(x, 64, _LE(x, 32, _LE(x, 16, _LAST_LE(x))))
Quoted 7 lines
Quoted 5 lines
Quoted 1 line
What do you think?
My only real real objection is that
_LEsounds like converting *to* little-endian to me. Admittedly, that's the same thing on any remotely sane architecture, but still.
GET_LE()then?
Sounds good.
Are you planning on writing the patch?
I think my v2 is good -- the only diff I could find in my image.c files and Stephen's was in the alt_xyz output, and I think I fixed that in v2.
--Andy
H. Peter Anvin
reviewerRe: [PATCH v2 2/2] x86,vdso: Fix cross-compilation from big-endian architectures
Quoted 11 lines · Andy Lutomirski
Quoted 2 lines
GET_LE()then?Sounds good.
Are you planning on writing the patch?
I think my v2 is good -- the only diff I could find in my
image.cfiles and Stephen's was in thealt_xyzoutput, and I think I fixed that in v2.
Build testing one now.
-hpa
tip-bot for Andy Lutomirski
merge bot[tip:x86/vdso] x86/vdso, build: Fix cross-compilation from big-endian architectures
In reply to Andy Lutomirskix86/vdso, build: Fix cross-compilation from big-endian architectures
Commit-ID: add4eed0a2abea3951206f504330ee5daf8c178a Gitweb: http://git.kernel.org/tip/add4eed0a2abea3951206f504330ee5daf8c178a Author: Andy Lutomirski <[email protected]> AuthorDate: Fri, 30 May 2014 08:48:49 -0700 Committer: H. Peter Anvin <[email protected]> CommitDate: Fri, 30 May 2014 16:58:43 -0700
x86/vdso, build: Fix cross-compilation from big-endian architectures
This adds a macro GET(x) to convert x from big-endian to little-endian. Hopefully I put it everywhere it needs to go and got all the cases needed for everyone's linux/elf.h.
--- arch/x86/vdso/vdso2c.c | 15 ++++++++++++ arch/x86/vdso/vdso2c.h | 63 ++++++++++++++++++++++++++++---------------------- 2 files changed, 50 insertions(+), 28 deletions(-)
arch/x86/vdso/vdso2c.c +15 -0
@@ -51,6 +51,21 @@ static void fail(const char *format, ...)va_end (ap); } +/* +* Evil macros to do a little-endian read. +*/ +#define __GET_TYPE (x, type, bits, ifnot) \ + __builtin_choose_expr( \ + __builtin_types_compatible_p(typeof(x), type), \ + le##bits##toh((x)), ifnot) + +extern void bad_get (uint64_t ); + +#define GET (x) \ + __GET_TYPE((x), __u32, 32, __GET_TYPE((x), __u64, 64, \ + __GET_TYPE((x), __s32, 32, __GET_TYPE((x), __s64, 64, \ + __GET_TYPE((x), __u16, 16, bad_get(x)))))) +#define NSYMS (sizeof(required_syms) / sizeof(required_syms[0]))#define BITS 64
arch/x86/vdso/vdso2c.h +35 -28
119 lines not on this page · raw message
tip-bot for H. Peter Anvin
merge bot[tip:x86/vdso] x86/vdso, build: Make LE access macros clearer, host-safe
In reply to Andy Lutomirskix86/vdso, build: Make LE access macros clearer, host-safe
Commit-ID: e002e99ea4b07c8446d8e1ca892c60f44630643e Gitweb: http://git.kernel.org/tip/e002e99ea4b07c8446d8e1ca892c60f44630643e Author: H. Peter Anvin <[email protected]> AuthorDate: Fri, 30 May 2014 17:03:22 -0700 Committer: H. Peter Anvin <[email protected]> CommitDate: Fri, 30 May 2014 17:03:22 -0700
x86/vdso, build: Make LE access macros clearer, host-safe
Make it a little clearer what the littleendian access macros in vdso2c.[ch] actually do. This way they can probably also be moved to a central location (e.g. tools/include) for the benefit of other host tools.
We should avoid implementation namespace symbols when writing code that is compiling for the compiler host, so avoid names starting with double underscore or underscore-capital.
--- arch/x86/vdso/vdso2c.c | 16 ++++++------- arch/x86/vdso/vdso2c.h | 65 ++++++++++++++++++++++++++------------------------ 2 files changed, 42 insertions(+), 39 deletions(-)
arch/x86/vdso/vdso2c.c +8 -8
@@ -54,17 +54,17 @@ static void fail(const char *format, ...)/* * Evil macros to do a little-endian read. */ -#define __GET_TYPE (x, type, bits, ifnot) \ +#define GLE (x, bits, ifnot) \ __builtin_choose_expr( \ - __builtin_types_compatible_p(typeof(x), type), \ - le##bits##toh((x)), ifnot) + (sizeof(x) == bits/8), \ + (__typeof__(x))le##bits##toh(x), ifnot) -extern void bad_get (uint64_t ); +extern void bad_get_le (uint64_t ); +#define LAST_LE (x) \ + __builtin_choose_expr(sizeof(x) == 1, (x), bad_le(x)) -#define GET (x) \ - __GET_TYPE((x), __u32, 32, __GET_TYPE((x), __u64, 64, \ - __GET_TYPE((x), __s32, 32, __GET_TYPE((x), __s64, 64, \ - __GET_TYPE((x), __u16, 16, bad_get(x)))))) +#define GET_LE (x) \ + GLE(x, 64, GLE(x, 32, GLE(x, 16, LAST_LE(x))))#define NSYMS (sizeof(required_syms) / sizeof(required_syms[0]))
arch/x86/vdso/vdso2c.h +34 -31
118 lines not on this page · raw message
tip-bot for H. Peter Anvin
merge bot[tip:x86/vdso] x86/vdso, build: Make LE access macros clearer, host-safe
In reply to Andy Lutomirskix86/vdso, build: Make LE access macros clearer, host-safe
Commit-ID: c191920f737a09a7252088f018f6747f0d2f484d Gitweb: http://git.kernel.org/tip/c191920f737a09a7252088f018f6747f0d2f484d Author: H. Peter Anvin <[email protected]> AuthorDate: Fri, 30 May 2014 17:03:22 -0700 Committer: H. Peter Anvin <[email protected]> CommitDate: Sat, 31 May 2014 03:35:27 -0700
x86/vdso, build: Make LE access macros clearer, host-safe
Make it a little clearer what the littleendian access macros in vdso2c.[ch] actually do. This way they can probably also be moved to a central location (e.g. tools/include) for the benefit of other host tools.
We should avoid implementation namespace symbols when writing code that is compiling for the compiler host, so avoid names starting with double underscore or underscore-capital.
--- arch/x86/vdso/vdso2c.c | 16 ++++++------- arch/x86/vdso/vdso2c.h | 65 ++++++++++++++++++++++++++------------------------ 2 files changed, 42 insertions(+), 39 deletions(-)
arch/x86/vdso/vdso2c.c +8 -8
@@ -54,17 +54,17 @@ static void fail(const char *format, ...)/* * Evil macros to do a little-endian read. */ -#define __GET_TYPE (x, type, bits, ifnot) \ +#define GLE (x, bits, ifnot) \ __builtin_choose_expr( \ - __builtin_types_compatible_p(typeof(x), type), \ - le##bits##toh((x)), ifnot) + (sizeof(x) == bits/8), \ + (__typeof__(x))le##bits##toh(x), ifnot) -extern void bad_get (uint64_t ); +extern void bad_get_le (uint64_t ); +#define LAST_LE (x) \ + __builtin_choose_expr(sizeof(x) == 1, (x), bad_get_le(x)) -#define GET (x) \ - __GET_TYPE((x), __u32, 32, __GET_TYPE((x), __u64, 64, \ - __GET_TYPE((x), __s32, 32, __GET_TYPE((x), __s64, 64, \ - __GET_TYPE((x), __u16, 16, bad_get(x)))))) +#define GET_LE (x) \ + GLE(x, 64, GLE(x, 32, GLE(x, 16, LAST_LE(x))))#define NSYMS (sizeof(required_syms) / sizeof(required_syms[0]))
arch/x86/vdso/vdso2c.h +34 -31
118 lines not on this page · raw message
PATCH v5 5/7 x86: Move the 32-bit vdso special pages after the text
In reply to Andy LutomirskiThis unifies the vdso mapping code and teaches it how to map special pages at addresses corresponding to symbols in the vdso image. The new code is used for all vdso variants, but so far only the 32-bit variants use the new vvar page position.
--- arch/x86/include/asm/elf.h | 8 +-- arch/x86/include/asm/vdso.h | 4 ++ arch/x86/include/asm/vdso32.h | 11 ---- arch/x86/vdso/vdso-layout.lds.S | 42 ++++++++----- arch/x86/vdso/vdso2c.c | 14 +++++ arch/x86/vdso/vdso2c.h | 17 ++++++ arch/x86/vdso/vdso32-setup.c | 115 +----------------------------------- arch/x86/vdso/vma.c | 128 +++++++++++++++++++++++++++++++++------- 8 files changed, 173 insertions(+), 166 deletions(-) delete mode 100644 arch/x86/include/asm/vdso32.h
arch/x86/include/asm/elf.h +3 -5
@@ -333,11 +333,9 @@ struct linux_binprm;#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1extern int arch_setup_additional_pages (struct linux_binprm *bprm,int uses_interp); -extern int x32_setup_additional_pages (struct linux_binprm *bprm, -int uses_interp); - -extern int syscall32_setup_pages (struct linux_binprm *,int exstack); -#define compat_arch_setup_additional_pages syscall32_setup_pages +extern int compat_arch_setup_additional_pages (struct linux_binprm *bprm, +int uses_interp); +#define compat_arch_setup_additional_pages compat_arch_setup_additional_pagesextern unsigned long arch_randomize_brk (struct mm_struct *mm);#define arch_randomize_brk arch_randomize_brk
arch/x86/include/asm/vdso.h +4 -0
@@ -14,6 +14,10 @@ struct vdso_image {unsigned long alt, alt_len; +unsigned long sym_end_mapping;/* Total size of the mapping */ + +unsigned long sym_vvar_page; +unsigned long sym_hpet_page;unsigned long sym_VDSO32_NOTE_MASK;unsigned long sym___kernel_sigreturn;unsigned long sym___kernel_rt_sigreturn;
arch/x86/include/asm/vdso32.h deleted +0 -11
@@ -1,11 +0,0 @@ -#ifndef _ASM_X86_VDSO32_H -#define _ASM_X86_VDSO32_H - -#define VDSO_BASE_PAGE 0 -#define VDSO_VVAR_PAGE 1 -#define VDSO_HPET_PAGE 2 -#define VDSO_PAGES 3 -#define VDSO_PREV_PAGES 2 -#define VDSO_OFFSET (x) ((x) * PAGE_SIZE) - -#endif
arch/x86/vdso/vdso-layout.lds.S +26 -16
60 lines not on this page · raw message
arch/x86/vdso/vdso2c.c +14 -0
@@ -15,7 +15,21 @@#include <linux/types.h> /* Symbols that we need in vdso2c. */ +enum { + sym_vvar_page, + sym_hpet_page, + sym_end_mapping, +}; + +const int special_pages[] = { + sym_vvar_page, + sym_hpet_page, +}; +char const *const required_syms[] = { + [sym_vvar_page] ="vvar_page" , + [sym_hpet_page] ="hpet_page" , + [sym_end_mapping] ="end_mapping" ,"VDSO32_NOTE_MASK" ,"VDSO32_SYSENTER_RETURN" ,"__kernel_vsyscall" ,
arch/x86/vdso/vdso2c.h +17 -0
@@ -87,6 +87,23 @@ static int GOFUNC(void *addr, size_t len, FILE *outfile, const char *name) } } +/* Validate mapping addresses. */ +for (i =0 ; i <sizeof (special_pages) /sizeof (special_pages[0 ]); i++) { +if (!syms[i]) +continue ;/* The mapping isn't used; ignore it. */ + +if (syms[i] %4096 ) +fail ("%s must be a multiple of 4096\n" , + required_syms[i]); +if (syms[i] < data_size) +fail ("%s must be after the text mapping\n" , + required_syms[i]); +if (syms[sym_end_mapping] < syms[i] +4096 ) +fail ("%s overruns end_mapping\n" , required_syms[i]); + } +if (syms[sym_end_mapping] %4096 ) +fail ("end_mapping must be a multiple of 4096\n" ); +/* Remove sections. */ hdr->e_shoff =0 ; hdr->e_shentsize =0 ;
arch/x86/vdso/vdso32-setup.c +3 -112
136 lines not on this page · raw message
arch/x86/vdso/vma.c +106 -22
189 lines not on this page · raw message
Signature · 1 line
1.9.0
tip-bot for Andy Lutomirski
merge bot[tip:x86/vdso] x86, vdso: Move the 32-bit vdso special pages after the text
x86, vdso: Move the 32-bit vdso special pages after the text
Commit-ID: 18d0a6fd227177fd243993179c90e454d0638b06 Gitweb: http://git.kernel.org/tip/18d0a6fd227177fd243993179c90e454d0638b06 Author: Andy Lutomirski <[email protected]> AuthorDate: Mon, 5 May 2014 12:19:35 -0700 Committer: H. Peter Anvin <[email protected]> CommitDate: Mon, 5 May 2014 13:18:56 -0700
x86, vdso: Move the 32-bit vdso special pages after the text
This unifies the vdso mapping code and teaches it how to map special pages at addresses corresponding to symbols in the vdso image. The new code is used for all vdso variants, but so far only the 32-bit variants use the new vvar page position.
--- arch/x86/include/asm/elf.h | 8 +-- arch/x86/include/asm/vdso.h | 4 ++ arch/x86/include/asm/vdso32.h | 11 ---- arch/x86/vdso/vdso-layout.lds.S | 42 ++++++++----- arch/x86/vdso/vdso2c.c | 14 +++++ arch/x86/vdso/vdso2c.h | 17 ++++++ arch/x86/vdso/vdso32-setup.c | 115 +----------------------------------- arch/x86/vdso/vma.c | 128 +++++++++++++++++++++++++++++++++------- 8 files changed, 173 insertions(+), 166 deletions(-)
arch/x86/include/asm/elf.h +3 -5
@@ -333,11 +333,9 @@ struct linux_binprm;#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1extern int arch_setup_additional_pages (struct linux_binprm *bprm,int uses_interp); -extern int x32_setup_additional_pages (struct linux_binprm *bprm, -int uses_interp); - -extern int syscall32_setup_pages (struct linux_binprm *,int exstack); -#define compat_arch_setup_additional_pages syscall32_setup_pages +extern int compat_arch_setup_additional_pages (struct linux_binprm *bprm, +int uses_interp); +#define compat_arch_setup_additional_pages compat_arch_setup_additional_pagesextern unsigned long arch_randomize_brk (struct mm_struct *mm);#define arch_randomize_brk arch_randomize_brk
arch/x86/include/asm/vdso.h +4 -0
@@ -14,6 +14,10 @@ struct vdso_image {unsigned long alt, alt_len; +unsigned long sym_end_mapping;/* Total size of the mapping */ + +unsigned long sym_vvar_page; +unsigned long sym_hpet_page;unsigned long sym_VDSO32_NOTE_MASK;unsigned long sym___kernel_sigreturn;unsigned long sym___kernel_rt_sigreturn;
arch/x86/include/asm/vdso32.h deleted +0 -11
@@ -1,11 +0,0 @@ -#ifndef _ASM_X86_VDSO32_H -#define _ASM_X86_VDSO32_H - -#define VDSO_BASE_PAGE 0 -#define VDSO_VVAR_PAGE 1 -#define VDSO_HPET_PAGE 2 -#define VDSO_PAGES 3 -#define VDSO_PREV_PAGES 2 -#define VDSO_OFFSET (x) ((x) * PAGE_SIZE) - -#endif
arch/x86/vdso/vdso-layout.lds.S +26 -16
60 lines not on this page · raw message
arch/x86/vdso/vdso2c.c +14 -0
@@ -15,7 +15,21 @@#include <linux/types.h> /* Symbols that we need in vdso2c. */ +enum { + sym_vvar_page, + sym_hpet_page, + sym_end_mapping, +}; + +const int special_pages[] = { + sym_vvar_page, + sym_hpet_page, +}; +char const *const required_syms[] = { + [sym_vvar_page] ="vvar_page" , + [sym_hpet_page] ="hpet_page" , + [sym_end_mapping] ="end_mapping" ,"VDSO32_NOTE_MASK" ,"VDSO32_SYSENTER_RETURN" ,"__kernel_vsyscall" ,
arch/x86/vdso/vdso2c.h +17 -0
@@ -87,6 +87,23 @@ static int GOFUNC(void *addr, size_t len, FILE *outfile, const char *name) } } +/* Validate mapping addresses. */ +for (i =0 ; i <sizeof (special_pages) /sizeof (special_pages[0 ]); i++) { +if (!syms[i]) +continue ;/* The mapping isn't used; ignore it. */ + +if (syms[i] %4096 ) +fail ("%s must be a multiple of 4096\n" , + required_syms[i]); +if (syms[i] < data_size) +fail ("%s must be after the text mapping\n" , + required_syms[i]); +if (syms[sym_end_mapping] < syms[i] +4096 ) +fail ("%s overruns end_mapping\n" , required_syms[i]); + } +if (syms[sym_end_mapping] %4096 ) +fail ("end_mapping must be a multiple of 4096\n" ); +/* Remove sections. */ hdr->e_shoff =0 ; hdr->e_shentsize =0 ;
arch/x86/vdso/vdso32-setup.c +3 -112
136 lines not on this page · raw message
arch/x86/vdso/vma.c +106 -22
189 lines not on this page · raw message
PATCH v5 6/7 x86: Move the vvar and hpet mappings next to the 64-bit vDSO
In reply to Andy LutomirskiThis makes the 64-bit and x32 vdsos use the same mechanism as the 32-bit vdso. Most of the churn is deleting all the old fixmap code.
--- arch/x86/include/asm/fixmap.h | 11 ++++------- arch/x86/include/asm/vvar.h | 20 +------------------- arch/x86/include/uapi/asm/vsyscall.h | 7 +------ arch/x86/kernel/cpu/common.c | 1 + arch/x86/kernel/hpet.c | 3 --- arch/x86/kernel/vsyscall_64.c | 15 ++++----------- arch/x86/mm/fault.c | 5 +++-- arch/x86/mm/init_64.c | 10 +++++----- arch/x86/vdso/vclock_gettime.c | 22 +++++----------------- arch/x86/vdso/vdso-layout.lds.S | 2 -- arch/x86/xen/mmu.c | 8 +++----- 11 files changed, 27 insertions(+), 77 deletions(-)
arch/x86/include/asm/fixmap.h +4 -7
@@ -24,7 +24,7 @@#include <linux/threads.h> #include <asm/kmap_types.h> #else -#include <asm/vsyscall.h> +#include <uapi/asm/vsyscall.h> #endif /*
@@ -41,7 +41,8 @@extern unsigned long __FIXADDR_TOP;#define FIXADDR_TOP ((unsigned long)__FIXADDR_TOP)#else -#define FIXADDR_TOP (VSYSCALL_END-PAGE_SIZE) +#define FIXADDR_TOP (round_up(VSYSCALL_ADDR + PAGE_SIZE, 1<<PMD_SHIFT) - \ + PAGE_SIZE)#endif
@@ -68,11 +69,7 @@ enum fixed_addresses {#ifdef CONFIG_X86_32 FIX_HOLE, #else -VSYSCALL_LAST_PAGE , -VSYSCALL_FIRST_PAGE =VSYSCALL_LAST_PAGE - + ((VSYSCALL_END -VSYSCALL_START ) >>PAGE_SHIFT ) -1 , -VVAR_PAGE , -VSYSCALL_HPET , + VSYSCALL_PAGE = (FIXADDR_TOP - VSYSCALL_ADDR) >> PAGE_SHIFT,#ifdef CONFIG_PARAVIRT_CLOCK PVCLOCK_FIXMAP_BEGIN , PVCLOCK_FIXMAP_END = PVCLOCK_FIXMAP_BEGIN+PVCLOCK_VSYSCALL_NR_PAGES-1,
arch/x86/include/asm/vvar.h +1 -19
@@ -29,31 +29,13 @@#else -#ifdef BUILD_VDSO32 +extern char __vvar_page;#define DECLARE_VVAR (offset, type, name) \ extern type vvar_ ## name __attribute__((visibility("hidden")));#define VVAR (name) (vvar_ ## name) -#else - -extern char __vvar_page; - -/* Base address of vvars. This is not ABI. */ -#ifdef CONFIG_X86_64 -#define VVAR_ADDRESS (-10*1024*1024 - 4096) -#else -#define VVAR_ADDRESS (&__vvar_page) -#endif - -#define DECLARE_VVAR (offset, type, name) \ - static type const * const vvaraddr_ ## name = \ - (void *)(VVAR_ADDRESS + (offset)); - -#define VVAR (name) (*vvaraddr_ ## name) -#endif -#define DEFINE_VVAR (type, name) \ type name \ __attribute__((section(".vvar_" #name), aligned(16))) __visible
arch/x86/include/uapi/asm/vsyscall.h +1 -6
@@ -7,11 +7,6 @@ enum vsyscall_num { __NR_vgetcpu, }; -#define VSYSCALL_START (-10UL << 20) -#define VSYSCALL_SIZE 1024 -#define VSYSCALL_END (-2UL << 20) -#define VSYSCALL_MAPPED_PAGES 1 -#define VSYSCALL_ADDR (vsyscall_nr) (VSYSCALL_START+VSYSCALL_SIZE*(vsyscall_nr)) - +#define VSYSCALL_ADDR (-10UL << 20)#endif /* _UAPI_ASM_X86_VSYSCALL_H */
arch/x86/kernel/cpu/common.c +1 -0
@@ -20,6 +20,7 @@#include <asm/processor.h> #include <asm/debugreg.h> #include <asm/sections.h> +#include <asm/vsyscall.h> #include <linux/topology.h> #include <linux/cpumask.h> #include <asm/pgtable.h>
arch/x86/kernel/hpet.c +0 -3
@@ -74,9 +74,6 @@ static inline void hpet_writel(unsigned int d, unsigned int a)static inline void hpet_set_mapping (void ) { hpet_virt_address =ioremap_nocache (hpet_address,HPET_MMAP_SIZE ); -#ifdef CONFIG_X86_64 -__set_fixmap (VSYSCALL_HPET , hpet_address,PAGE_KERNEL_VVAR_NOCACHE ); -#endif }static inline void hpet_clear_mapping (void )
arch/x86/kernel/vsyscall_64.c +4 -11
@@ -91,7 +91,7 @@ static int addr_to_vsyscall_nr(unsigned long addr) {int nr; -if ((addr & ~0xC00UL ) !=VSYSCALL_START ) +if ((addr & ~0xC00UL ) !=VSYSCALL_ADDR )return -EINVAL ; nr = (addr &0xC00UL ) >>10 ;
@@ -330,24 +330,17 @@ void __init map_vsyscall(void) {extern char __vsyscall_page;unsigned long physaddr_vsyscall =__pa_symbol (&__vsyscall_page); -unsigned long physaddr_vvar_page =__pa_symbol (&__vvar_page); -__set_fixmap (VSYSCALL_FIRST_PAGE , physaddr_vsyscall, +__set_fixmap (VSYSCALL_PAGE , physaddr_vsyscall, vsyscall_mode ==NATIVE ?PAGE_KERNEL_VSYSCALL :PAGE_KERNEL_VVAR ); -BUILD_BUG_ON ((unsigned long )__fix_to_virt (VSYSCALL_FIRST_PAGE ) != - (unsigned long )VSYSCALL_START ); - -__set_fixmap (VVAR_PAGE , physaddr_vvar_page,PAGE_KERNEL_VVAR ); -BUILD_BUG_ON ((unsigned long )__fix_to_virt (VVAR_PAGE ) != - (unsigned long )VVAR_ADDRESS ); +BUILD_BUG_ON ((unsigned long )__fix_to_virt (VSYSCALL_PAGE ) != + (unsigned long )VSYSCALL_ADDR ); }static int __init vsyscall_init (void ) { -BUG_ON (VSYSCALL_ADDR (0 ) !=__fix_to_virt (VSYSCALL_FIRST_PAGE )); -cpu_notifier_register_begin ();on_each_cpu (cpu_vsyscall_init,NULL ,1 );
arch/x86/mm/fault.c +3 -2
@@ -18,7 +18,8 @@#include <asm/traps.h> /* dotraplinkage, ... */ #include <asm/pgalloc.h> /* pgd_*(), ... */ #include <asm/kmemcheck.h> /* kmemcheck_*(), ... */ -#include <asm/fixmap.h> /* VSYSCALL_START */ +#include <asm/fixmap.h> /* VSYSCALL_ADDR */ +#include <asm/vsyscall.h> /* emulate_vsyscall */ #define CREATE_TRACE_POINTS #include <asm/trace/exceptions.h>
@@ -771,7 +772,7 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code,* emulation. */ if (unlikely ((error_code &PF_INSTR ) && - ((address & ~0xfff ) ==VSYSCALL_START ))) { + ((address & ~0xfff ) ==VSYSCALL_ADDR ))) {if (emulate_vsyscall (regs, address))return ; }
arch/x86/mm/init_64.c +5 -5
@@ -1055,8 +1055,8 @@ void __init mem_init(void) after_bootmem =1 ;/* Register memory areas for /proc/kcore */ -kclist_add (&kcore_vsyscall, (void *)VSYSCALL_START , -VSYSCALL_END -VSYSCALL_START ,KCORE_OTHER ); +kclist_add (&kcore_vsyscall, (void *)VSYSCALL_ADDR , +PAGE_SIZE ,KCORE_OTHER );mem_init_print_info (NULL ); }
@@ -1186,8 +1186,8 @@ int kern_addr_valid(unsigned long addr)* not need special handling anymore: */ static struct vm_area_struct gate_vma = { - .vm_start =VSYSCALL_START , - .vm_end =VSYSCALL_START + (VSYSCALL_MAPPED_PAGES *PAGE_SIZE ), + .vm_start =VSYSCALL_ADDR , + .vm_end =VSYSCALL_ADDR +PAGE_SIZE , .vm_page_prot =PAGE_READONLY_EXEC , .vm_flags =VM_READ |VM_EXEC };
@@ -1218,7 +1218,7 @@ int in_gate_area(struct mm_struct *mm, unsigned long addr)*/ int in_gate_area_no_mm (unsigned long addr) { -return (addr >=VSYSCALL_START ) && (addr <VSYSCALL_END ); +return (addr &PAGE_MASK ) ==VSYSCALL_ADDR ; }const char *arch_vma_name (struct vm_area_struct *vma)
arch/x86/vdso/vclock_gettime.c +5 -17
@@ -30,9 +30,12 @@ extern int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz);extern time_t __vdso_time (time_t *t);#ifdef CONFIG_HPET_TIMER -static inline u32 read_hpet_counter (const volatile void *addr) +extern u8 hpet_page + __attribute__((visibility("hidden"))); + +static notrace cycle_t vread_hpet(void) { -return *(const volatile u32 *) (addr +HPET_COUNTER ); +return *(const volatile u32 *)(&hpet_page +HPET_COUNTER ); }#endif
@@ -43,11 +46,6 @@ static inline u32 read_hpet_counter(const volatile void *addr)#include <asm/fixmap.h> #include <asm/pvclock.h> -static notrace cycle_t vread_hpet(void) -{ -return read_hpet_counter ((const void *)fix_to_virt (VSYSCALL_HPET )); -} - notrace static long vdso_fallback_gettime(long clock, struct timespec *ts) {long ret;
@@ -137,16 +135,6 @@ static notrace cycle_t vread_pvclock(int *mode)#else -extern u8 hpet_page - __attribute__((visibility("hidden"))); - -#ifdef CONFIG_HPET_TIMER -static notrace cycle_t vread_hpet(void) -{ -return read_hpet_counter ((const void *)(&hpet_page)); -} -#endif - notrace static long vdso_fallback_gettime(long clock, struct timespec *ts) {long ret;
arch/x86/vdso/vdso-layout.lds.S +0 -2
@@ -47,7 +47,6 @@ SECTIONS .text : { *(.text*) } :text =0x90909090, -#ifdef BUILD_VDSO32 /* * The remainder of the vDSO consists of special pages that are * shared between the kernel and userspace. It needs to be at the
@@ -69,7 +68,6 @@ SECTIONS hpet_page = .; . = . + PAGE_SIZE; -#endif . = ALIGN(PAGE_SIZE); end_mapping = .;
arch/x86/xen/mmu.c +3 -5
@@ -1494,7 +1494,7 @@ static int xen_pgd_alloc(struct mm_struct *mm) page->private = (unsigned long )user_pgd;if (user_pgd !=NULL ) { - user_pgd[pgd_index (VSYSCALL_START )] = + user_pgd[pgd_index (VSYSCALL_ADDR )] =__pgd (__pa (level3_user_vsyscall) | _PAGE_TABLE); ret =0 ; }
@@ -2062,8 +2062,7 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot) case FIX_KMAP_BEGIN ... FIX_KMAP_END:# endif #else - case VSYSCALL_LAST_PAGE ... VSYSCALL_FIRST_PAGE: -case VVAR_PAGE : +case VSYSCALL_PAGE :#endif case FIX_TEXT_POKE0 :case FIX_TEXT_POKE1 :
@@ -2104,8 +2103,7 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot)#ifdef CONFIG_X86_64 /* Replicate changes to map the vsyscall page into the user pagetable vsyscall mapping. */ -if ((idx >=VSYSCALL_LAST_PAGE && idx <=VSYSCALL_FIRST_PAGE ) || - idx ==VVAR_PAGE ) { +if (idx ==VSYSCALL_PAGE ) {unsigned long vaddr =__fix_to_virt (idx);set_pte_vaddr_pud (level3_user_vsyscall, vaddr, pte); }
Signature · 1 line
1.9.0
tip-bot for Andy Lutomirski
merge bot[tip:x86/vdso] x86, vdso: Move the vvar and hpet mappings next to the 64-bit vDSO
x86, vdso: Move the vvar and hpet mappings next to the 64-bit vDSO
Commit-ID: f40c330091c7aa9956ab66f97a3abc8a68b67240 Gitweb: http://git.kernel.org/tip/f40c330091c7aa9956ab66f97a3abc8a68b67240 Author: Andy Lutomirski <[email protected]> AuthorDate: Mon, 5 May 2014 12:19:36 -0700 Committer: H. Peter Anvin <[email protected]> CommitDate: Mon, 5 May 2014 13:19:01 -0700
x86, vdso: Move the vvar and hpet mappings next to the 64-bit vDSO
This makes the 64-bit and x32 vdsos use the same mechanism as the 32-bit vdso. Most of the churn is deleting all the old fixmap code.
--- arch/x86/include/asm/fixmap.h | 11 ++++------- arch/x86/include/asm/vvar.h | 20 +------------------- arch/x86/include/uapi/asm/vsyscall.h | 7 +------ arch/x86/kernel/cpu/common.c | 1 + arch/x86/kernel/hpet.c | 3 --- arch/x86/kernel/vsyscall_64.c | 15 ++++----------- arch/x86/mm/fault.c | 5 +++-- arch/x86/mm/init_64.c | 10 +++++----- arch/x86/vdso/vclock_gettime.c | 22 +++++----------------- arch/x86/vdso/vdso-layout.lds.S | 2 -- arch/x86/xen/mmu.c | 8 +++----- 11 files changed, 27 insertions(+), 77 deletions(-)
arch/x86/include/asm/fixmap.h +4 -7
@@ -24,7 +24,7 @@#include <linux/threads.h> #include <asm/kmap_types.h> #else -#include <asm/vsyscall.h> +#include <uapi/asm/vsyscall.h> #endif /*
@@ -41,7 +41,8 @@extern unsigned long __FIXADDR_TOP;#define FIXADDR_TOP ((unsigned long)__FIXADDR_TOP)#else -#define FIXADDR_TOP (VSYSCALL_END-PAGE_SIZE) +#define FIXADDR_TOP (round_up(VSYSCALL_ADDR + PAGE_SIZE, 1<<PMD_SHIFT) - \ + PAGE_SIZE)#endif
@@ -68,11 +69,7 @@ enum fixed_addresses {#ifdef CONFIG_X86_32 FIX_HOLE, #else -VSYSCALL_LAST_PAGE , -VSYSCALL_FIRST_PAGE =VSYSCALL_LAST_PAGE - + ((VSYSCALL_END -VSYSCALL_START ) >>PAGE_SHIFT ) -1 , -VVAR_PAGE , -VSYSCALL_HPET , + VSYSCALL_PAGE = (FIXADDR_TOP - VSYSCALL_ADDR) >> PAGE_SHIFT,#ifdef CONFIG_PARAVIRT_CLOCK PVCLOCK_FIXMAP_BEGIN , PVCLOCK_FIXMAP_END = PVCLOCK_FIXMAP_BEGIN+PVCLOCK_VSYSCALL_NR_PAGES-1,
arch/x86/include/asm/vvar.h +1 -19
@@ -29,31 +29,13 @@#else -#ifdef BUILD_VDSO32 +extern char __vvar_page;#define DECLARE_VVAR (offset, type, name) \ extern type vvar_ ## name __attribute__((visibility("hidden")));#define VVAR (name) (vvar_ ## name) -#else - -extern char __vvar_page; - -/* Base address of vvars. This is not ABI. */ -#ifdef CONFIG_X86_64 -#define VVAR_ADDRESS (-10*1024*1024 - 4096) -#else -#define VVAR_ADDRESS (&__vvar_page) -#endif - -#define DECLARE_VVAR (offset, type, name) \ - static type const * const vvaraddr_ ## name = \ - (void *)(VVAR_ADDRESS + (offset)); - -#define VVAR (name) (*vvaraddr_ ## name) -#endif -#define DEFINE_VVAR (type, name) \ type name \ __attribute__((section(".vvar_" #name), aligned(16))) __visible
arch/x86/include/uapi/asm/vsyscall.h +1 -6
@@ -7,11 +7,6 @@ enum vsyscall_num { __NR_vgetcpu, }; -#define VSYSCALL_START (-10UL << 20) -#define VSYSCALL_SIZE 1024 -#define VSYSCALL_END (-2UL << 20) -#define VSYSCALL_MAPPED_PAGES 1 -#define VSYSCALL_ADDR (vsyscall_nr) (VSYSCALL_START+VSYSCALL_SIZE*(vsyscall_nr)) - +#define VSYSCALL_ADDR (-10UL << 20)#endif /* _UAPI_ASM_X86_VSYSCALL_H */
arch/x86/kernel/cpu/common.c +1 -0
@@ -20,6 +20,7 @@#include <asm/processor.h> #include <asm/debugreg.h> #include <asm/sections.h> +#include <asm/vsyscall.h> #include <linux/topology.h> #include <linux/cpumask.h> #include <asm/pgtable.h>
arch/x86/kernel/hpet.c +0 -3
@@ -74,9 +74,6 @@ static inline void hpet_writel(unsigned int d, unsigned int a)static inline void hpet_set_mapping (void ) { hpet_virt_address =ioremap_nocache (hpet_address,HPET_MMAP_SIZE ); -#ifdef CONFIG_X86_64 -__set_fixmap (VSYSCALL_HPET , hpet_address,PAGE_KERNEL_VVAR_NOCACHE ); -#endif }static inline void hpet_clear_mapping (void )
arch/x86/kernel/vsyscall_64.c +4 -11
@@ -91,7 +91,7 @@ static int addr_to_vsyscall_nr(unsigned long addr) {int nr; -if ((addr & ~0xC00UL ) !=VSYSCALL_START ) +if ((addr & ~0xC00UL ) !=VSYSCALL_ADDR )return -EINVAL ; nr = (addr &0xC00UL ) >>10 ;
@@ -330,24 +330,17 @@ void __init map_vsyscall(void) {extern char __vsyscall_page;unsigned long physaddr_vsyscall =__pa_symbol (&__vsyscall_page); -unsigned long physaddr_vvar_page =__pa_symbol (&__vvar_page); -__set_fixmap (VSYSCALL_FIRST_PAGE , physaddr_vsyscall, +__set_fixmap (VSYSCALL_PAGE , physaddr_vsyscall, vsyscall_mode ==NATIVE ?PAGE_KERNEL_VSYSCALL :PAGE_KERNEL_VVAR ); -BUILD_BUG_ON ((unsigned long )__fix_to_virt (VSYSCALL_FIRST_PAGE ) != - (unsigned long )VSYSCALL_START ); - -__set_fixmap (VVAR_PAGE , physaddr_vvar_page,PAGE_KERNEL_VVAR ); -BUILD_BUG_ON ((unsigned long )__fix_to_virt (VVAR_PAGE ) != - (unsigned long )VVAR_ADDRESS ); +BUILD_BUG_ON ((unsigned long )__fix_to_virt (VSYSCALL_PAGE ) != + (unsigned long )VSYSCALL_ADDR ); }static int __init vsyscall_init (void ) { -BUG_ON (VSYSCALL_ADDR (0 ) !=__fix_to_virt (VSYSCALL_FIRST_PAGE )); -cpu_notifier_register_begin ();on_each_cpu (cpu_vsyscall_init,NULL ,1 );
arch/x86/mm/fault.c +3 -2
@@ -18,7 +18,8 @@#include <asm/traps.h> /* dotraplinkage, ... */ #include <asm/pgalloc.h> /* pgd_*(), ... */ #include <asm/kmemcheck.h> /* kmemcheck_*(), ... */ -#include <asm/fixmap.h> /* VSYSCALL_START */ +#include <asm/fixmap.h> /* VSYSCALL_ADDR */ +#include <asm/vsyscall.h> /* emulate_vsyscall */ #define CREATE_TRACE_POINTS #include <asm/trace/exceptions.h>
@@ -771,7 +772,7 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code,* emulation. */ if (unlikely ((error_code &PF_INSTR ) && - ((address & ~0xfff ) ==VSYSCALL_START ))) { + ((address & ~0xfff ) ==VSYSCALL_ADDR ))) {if (emulate_vsyscall (regs, address))return ; }
arch/x86/mm/init_64.c +5 -5
@@ -1055,8 +1055,8 @@ void __init mem_init(void) after_bootmem =1 ;/* Register memory areas for /proc/kcore */ -kclist_add (&kcore_vsyscall, (void *)VSYSCALL_START , -VSYSCALL_END -VSYSCALL_START ,KCORE_OTHER ); +kclist_add (&kcore_vsyscall, (void *)VSYSCALL_ADDR , +PAGE_SIZE ,KCORE_OTHER );mem_init_print_info (NULL ); }
@@ -1186,8 +1186,8 @@ int kern_addr_valid(unsigned long addr)* not need special handling anymore: */ static struct vm_area_struct gate_vma = { - .vm_start =VSYSCALL_START , - .vm_end =VSYSCALL_START + (VSYSCALL_MAPPED_PAGES *PAGE_SIZE ), + .vm_start =VSYSCALL_ADDR , + .vm_end =VSYSCALL_ADDR +PAGE_SIZE , .vm_page_prot =PAGE_READONLY_EXEC , .vm_flags =VM_READ |VM_EXEC };
@@ -1218,7 +1218,7 @@ int in_gate_area(struct mm_struct *mm, unsigned long addr)*/ int in_gate_area_no_mm (unsigned long addr) { -return (addr >=VSYSCALL_START ) && (addr <VSYSCALL_END ); +return (addr &PAGE_MASK ) ==VSYSCALL_ADDR ; }const char *arch_vma_name (struct vm_area_struct *vma)
arch/x86/vdso/vclock_gettime.c +5 -17
@@ -30,9 +30,12 @@ extern int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz);extern time_t __vdso_time (time_t *t);#ifdef CONFIG_HPET_TIMER -static inline u32 read_hpet_counter (const volatile void *addr) +extern u8 hpet_page + __attribute__((visibility("hidden"))); + +static notrace cycle_t vread_hpet(void) { -return *(const volatile u32 *) (addr +HPET_COUNTER ); +return *(const volatile u32 *)(&hpet_page +HPET_COUNTER ); }#endif
@@ -43,11 +46,6 @@ static inline u32 read_hpet_counter(const volatile void *addr)#include <asm/fixmap.h> #include <asm/pvclock.h> -static notrace cycle_t vread_hpet(void) -{ -return read_hpet_counter ((const void *)fix_to_virt (VSYSCALL_HPET )); -} - notrace static long vdso_fallback_gettime(long clock, struct timespec *ts) {long ret;
@@ -137,16 +135,6 @@ static notrace cycle_t vread_pvclock(int *mode)#else -extern u8 hpet_page - __attribute__((visibility("hidden"))); - -#ifdef CONFIG_HPET_TIMER -static notrace cycle_t vread_hpet(void) -{ -return read_hpet_counter ((const void *)(&hpet_page)); -} -#endif - notrace static long vdso_fallback_gettime(long clock, struct timespec *ts) {long ret;
arch/x86/vdso/vdso-layout.lds.S +0 -2
@@ -47,7 +47,6 @@ SECTIONS .text : { *(.text*) } :text =0x90909090, -#ifdef BUILD_VDSO32 /* * The remainder of the vDSO consists of special pages that are * shared between the kernel and userspace. It needs to be at the
@@ -69,7 +68,6 @@ SECTIONS hpet_page = .; . = . + PAGE_SIZE; -#endif . = ALIGN(PAGE_SIZE); end_mapping = .;
arch/x86/xen/mmu.c +3 -5
@@ -1494,7 +1494,7 @@ static int xen_pgd_alloc(struct mm_struct *mm) page->private = (unsigned long )user_pgd;if (user_pgd !=NULL ) { - user_pgd[pgd_index (VSYSCALL_START )] = + user_pgd[pgd_index (VSYSCALL_ADDR )] =__pgd (__pa (level3_user_vsyscall) | _PAGE_TABLE); ret =0 ; }
@@ -2062,8 +2062,7 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot) case FIX_KMAP_BEGIN ... FIX_KMAP_END:# endif #else - case VSYSCALL_LAST_PAGE ... VSYSCALL_FIRST_PAGE: -case VVAR_PAGE : +case VSYSCALL_PAGE :#endif case FIX_TEXT_POKE0 :case FIX_TEXT_POKE1 :
@@ -2104,8 +2103,7 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot)#ifdef CONFIG_X86_64 /* Replicate changes to map the vsyscall page into the user pagetable vsyscall mapping. */ -if ((idx >=VSYSCALL_LAST_PAGE && idx <=VSYSCALL_FIRST_PAGE ) || - idx ==VVAR_PAGE ) { +if (idx ==VSYSCALL_PAGE ) {unsigned long vaddr =__fix_to_virt (idx);set_pte_vaddr_pud (level3_user_vsyscall, vaddr, pte); }
PATCH v5 7/7 x86: Remove vestiges of VDSO_PRELINK and some outdated comments
In reply to Andy LutomirskiThese definitions had no effect.
--- arch/x86/vdso/vdso.lds.S | 7 +------ arch/x86/vdso/vdso32/vdso32.lds.S | 5 +---- arch/x86/vdso/vdsox32.lds.S | 7 +------ 3 files changed, 3 insertions(+), 16 deletions(-)
arch/x86/vdso/vdso.lds.S +1 -6
@@ -1,14 +1,11 @@ /* * Linker script for 64-bit vDSO. * We #include the file to define the layout details. - * Here we only choose the prelinked virtual address. * * This file defines the version script giving the user-exported symbols in - * the DSO. We can define local symbols here called VDSO* to make their - * values visible using the asm-x86/vdso.h macros from the kernel proper. + * the DSO. */ -#define VDSO_PRELINK 0xffffffffff700000 #include "vdso-layout.lds.S" /*
@@ -28,5 +25,3 @@ VERSION { local: *; }; } - -VDSO64_PRELINK = VDSO_PRELINK;
arch/x86/vdso/vdso32/vdso32.lds.S +1 -4
@@ -1,17 +1,14 @@ /* * Linker script for 32-bit vDSO. * We #include the file to define the layout details. - * Here we only choose the prelinked virtual address. * * This file defines the version script giving the user-exported symbols in - * the DSO. We can define local symbols here called VDSO* to make their - * values visible using the asm-x86/vdso.h macros from the kernel proper. + * the DSO. */ #include <asm/page.h> #define BUILD_VDSO32 -#define VDSO_PRELINK 0 #include "../vdso-layout.lds.S"
arch/x86/vdso/vdsox32.lds.S +1 -6
@@ -1,14 +1,11 @@ /* * Linker script for x32 vDSO. * We #include the file to define the layout details. - * Here we only choose the prelinked virtual address. * * This file defines the version script giving the user-exported symbols in - * the DSO. We can define local symbols here called VDSO* to make their - * values visible using the asm-x86/vdso.h macros from the kernel proper. + * the DSO. */ -#define VDSO_PRELINK 0 #include "vdso-layout.lds.S" /*
@@ -24,5 +21,3 @@ VERSION { local: *; }; } - -VDSOX32_PRELINK = VDSO_PRELINK;
Signature · 1 line
1.9.0
tip-bot for Andy Lutomirski
merge bot[tip:x86/vdso] x86, vdso: Remove vestiges of VDSO_PRELINK and some outdated comments
x86, vdso: Remove vestiges of VDSO_PRELINK and some outdated comments
Commit-ID: 2b6f2e649f7376d9871df63a9aa0b41efd464d74 Gitweb: http://git.kernel.org/tip/2b6f2e649f7376d9871df63a9aa0b41efd464d74 Author: Andy Lutomirski <[email protected]> AuthorDate: Mon, 5 May 2014 12:19:37 -0700 Committer: H. Peter Anvin <[email protected]> CommitDate: Mon, 5 May 2014 13:19:07 -0700
x86, vdso: Remove vestiges of VDSO_PRELINK and some outdated comments
These definitions had no effect.
--- arch/x86/vdso/vdso.lds.S | 7 +------ arch/x86/vdso/vdso32/vdso32.lds.S | 5 +---- arch/x86/vdso/vdsox32.lds.S | 7 +------ 3 files changed, 3 insertions(+), 16 deletions(-)
arch/x86/vdso/vdso.lds.S +1 -6
@@ -1,14 +1,11 @@ /* * Linker script for 64-bit vDSO. * We #include the file to define the layout details. - * Here we only choose the prelinked virtual address. * * This file defines the version script giving the user-exported symbols in - * the DSO. We can define local symbols here called VDSO* to make their - * values visible using the asm-x86/vdso.h macros from the kernel proper. + * the DSO. */ -#define VDSO_PRELINK 0xffffffffff700000 #include "vdso-layout.lds.S" /*
@@ -28,5 +25,3 @@ VERSION { local: *; }; } - -VDSO64_PRELINK = VDSO_PRELINK;
arch/x86/vdso/vdso32/vdso32.lds.S +1 -4
@@ -1,17 +1,14 @@ /* * Linker script for 32-bit vDSO. * We #include the file to define the layout details. - * Here we only choose the prelinked virtual address. * * This file defines the version script giving the user-exported symbols in - * the DSO. We can define local symbols here called VDSO* to make their - * values visible using the asm-x86/vdso.h macros from the kernel proper. + * the DSO. */ #include <asm/page.h> #define BUILD_VDSO32 -#define VDSO_PRELINK 0 #include "../vdso-layout.lds.S"
arch/x86/vdso/vdsox32.lds.S +1 -6
@@ -1,14 +1,11 @@ /* * Linker script for x32 vDSO. * We #include the file to define the layout details. - * Here we only choose the prelinked virtual address. * * This file defines the version script giving the user-exported symbols in - * the DSO. We can define local symbols here called VDSO* to make their - * values visible using the asm-x86/vdso.h macros from the kernel proper. + * the DSO. */ -#define VDSO_PRELINK 0 #include "vdso-layout.lds.S" /*
@@ -24,5 +21,3 @@ VERSION { local: *; }; } - -VDSOX32_PRELINK = VDSO_PRELINK;