Skip to contentSkip to conversation

Clean up and unify the vDSO

PATCH In review Andy Lutomirski 6 participants 39 messages May 5, 2014 – May 31, 2014

Subsystems (8)
lore
Share & tools
lore
#0 lore raw

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
#1 lore raw

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
index 597ac15..6ef98c5 100644
@@ -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
index c96314a..5f8bdda 100644
@@ -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
#2 lore raw

[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
index 597ac15..6ef98c5 100644
@@ -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
index c96314a..5f8bdda 100644
@@ -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
 }
 
#3 lore raw

PATCH v5 2/7 x86: Clean up 32-bit vs 64-bit vdso params

In reply to Andy Lutomirski

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
index 2c71182..e96df2c 100644
@@ -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
index af91901..916cda4 100644
@@ -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
index 0034898..5a657d9 100644
@@ -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
index 1ad1026..8b79039 100644
@@ -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
index 74f5b58..420d77a 100644
@@ -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
#4 lore raw

[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
index 2c71182..e96df2c 100644
@@ -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
index af91901..916cda4 100644
@@ -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
index 0034898..5a657d9 100644
@@ -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
index 1ad1026..8b79039 100644
@@ -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
index 74f5b58..420d77a 100644
@@ -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,
#5 lore raw

PATCH v5 3/7 x86: Move syscall and sysenter setup into kernel/cpu/common.c

In reply to Andy Lutomirski

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
index 6fd3fd7..a90f897 100644
@@ -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
index a135239..7c65b46 100644
@@ -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
index 5a657d9..9c78d5b 100644
@@ -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
#6 lore raw

[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
index 6fd3fd7..a90f897 100644
@@ -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
index a135239..7c65b46 100644
@@ -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
index 5a657d9..9c78d5b 100644
@@ -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)
#7 lore raw

PATCH v5 4/7 x86: Reimplement vdso.so preparation in build-time C

In reply to Andy Lutomirski

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(-)
 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
index 2206757..f9e181a 100644
@@ -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
index e96df2c..65b21bc 100644
@@ -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
index 5f55e69..876e74e 100644
@@ -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
index 9e5de68..a0da58d 100644
@@ -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
index f35c66c..5638496 100644
@@ -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
index 3282874..aae8ffd 100644
@@ -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
index 16d6861..091554c 100644
@@ -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
deleted file mode 100644
index be3f23b..0000000
@@ -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
deleted file mode 100644
index 018bcd9..0000000
@@ -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
index aadb8b9..f072095 100644
@@ -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
deleted file mode 100644
index f4aa34e..0000000
@@ -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
index 0982233..7225a95 100644
@@ -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
#8 lore raw

[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
index 2206757..f9e181a 100644
@@ -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
index e96df2c..65b21bc 100644
@@ -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
index 5f55e69..876e74e 100644
@@ -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
index 9e5de68..a0da58d 100644
@@ -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
index f35c66c..5638496 100644
@@ -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
index 3282874..aae8ffd 100644
@@ -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
index 16d6861..091554c 100644
@@ -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
deleted file mode 100644
index be3f23b..0000000
@@ -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
deleted file mode 100644
index 018bcd9..0000000
@@ -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
index aadb8b9..f072095 100644
@@ -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
deleted file mode 100644
index f4aa34e..0000000
@@ -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
index 0982233..7225a95 100644
@@ -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
 }
#9 lore raw

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 -0700

x86, 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/vdso2c
arch/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 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.)

---

#10 lore raw

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 -0700

x86, 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 fault arch/x86/vdso/vdso2c
arch/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/

Egads. This wouldn't be a big-endian host by any chance?

--Andy

#11 lore raw

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 -0700

x86, 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/vdso2c
arch/x86/vdso/vdso64.so.dbg arch/x86/vdso/vdso-image-64.c make[3]: *** [arch/x86/vdso/vdso-image-64.c] Error 139

Quoted 4 lines
Quoted 2 lines

http://kisskb.ellerman.id.au/kisskb/buildresult/11265454/

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

#12 lore raw

Re: [tip:x86/vdso] x86, vdso: Reimplement vdso.so preparation in build-time C

In reply to Andy Lutomirski
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 -0700

x86, 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/vdso2c
arch/x86/vdso/vdso64.so.dbg arch/x86/vdso/vdso-image-64.c make[3]: *** [arch/x86/vdso/vdso-image-64.c] Error 139

Quoted 5 lines
Quoted 2 lines

http://kisskb.ellerman.id.au/kisskb/buildresult/11265454/

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

#13 lore raw

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 -0700

x86, 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/vdso2c
arch/x86/vdso/vdso64.so.dbg arch/x86/vdso/vdso-image-64.c make[3]: *** [arch/x86/vdso/vdso-image-64.c] Error 139

Quoted 9 lines
Quoted 5 lines
Quoted 2 lines

http://kisskb.ellerman.id.au/kisskb/buildresult/11265454/

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

#14 lore raw

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
#15 lore raw

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
index 81edd1e..fe8bfbf 100644
@@ -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
index 3dcc61e..26a7c1f 100644
@@ -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
#16 lore raw

PATCH 2/2 x86,vdso: Fix cross-compilation from big-endian architectures

In reply to 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.

---
 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
index fe8bfbf..de19ced 100644
@@ -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
#17 lore raw

Re: [PATCH 0/2] x86,vdso: vdso build fixes and improvements

In reply to Andy Lutomirski
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.

Paul.
--

Quoted 9 lines

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(-)
#18 lore raw

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.dbg
arch/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

#19 lore raw

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.dbg
arch/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.

OK, I will send them in a separate email.

Signature · 2 lines
Cheers,
Stephen Rothwell                    [email protected]
#20 lore raw

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.dbg
arch/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.

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
#21 lore raw

v2 cover x86,vdso: vdso build fixes and improvements

In reply to 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.

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
#22 lore raw

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
index 81edd1e..fe8bfbf 100644
@@ -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
index 3dcc61e..26a7c1f 100644
@@ -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
#23 lore raw

[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
index 81edd1e..fe8bfbf 100644
@@ -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
index 3dcc61e..26a7c1f 100644
@@ -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;
 }
#24 lore raw

PATCH v2 2/2 x86,vdso: Fix cross-compilation from big-endian architectures

In reply to 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.

---
 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
index fe8bfbf..de19ced 100644
@@ -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
#25 lore raw

Re: [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.

---
 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

#26 lore raw

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.

---
 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

#27 lore raw

Re: [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 _LE sounds like converting *to* little-endian to me. Admittedly, that's the same thing on any remotely sane architecture, but still.

GET_LE() then?

-hpa

#28 lore raw

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 _LE sounds 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

#29 lore raw

Re: [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.c files and Stephen's was in the alt_xyz output, and I think I fixed that in v2.

Build testing one now.

-hpa

#30 lore raw

[tip:x86/vdso] x86/vdso, build: Fix cross-compilation from big-endian architectures

In reply to Andy Lutomirski
x86/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
index fe8bfbf..de19ced 100644
@@ -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

#31 lore raw

[tip:x86/vdso] x86/vdso, build: Make LE access macros clearer, host-safe

In reply to Andy Lutomirski
x86/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
index de19ced..a09d5a8 100644
@@ -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

#32 lore raw

[tip:x86/vdso] x86/vdso, build: Make LE access macros clearer, host-safe

In reply to Andy Lutomirski
x86/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
index de19ced..deabaf5 100644
@@ -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

#33 lore raw

PATCH v5 5/7 x86: Move the 32-bit vdso special pages after the text

In reply to Andy Lutomirski

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(-)
 delete mode 100644 arch/x86/include/asm/vdso32.h
arch/x86/include/asm/elf.h +3 -5
index 65b21bc..1a055c8 100644
@@ -333,11 +333,9 @@ struct linux_binprm;
 #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
 extern 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_pages
 
 extern unsigned long arch_randomize_brk(struct mm_struct *mm);
 #define arch_randomize_brk arch_randomize_brk
arch/x86/include/asm/vdso.h +4 -0
index 389fe2c..d0a2c90 100644
@@ -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
deleted file mode 100644
index 7efb701..0000000
@@ -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
index 976e8e4..81edd1e 100644
@@ -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
index 9276e52..ed2e894 100644
@@ -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
#34 lore raw

[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
index 65b21bc..1a055c8 100644
@@ -333,11 +333,9 @@ struct linux_binprm;
 #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
 extern 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_pages
 
 extern unsigned long arch_randomize_brk(struct mm_struct *mm);
 #define arch_randomize_brk arch_randomize_brk
arch/x86/include/asm/vdso.h +4 -0
index 389fe2c..d0a2c90 100644
@@ -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
deleted file mode 100644
index 7efb701..0000000
@@ -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
index 976e8e4..81edd1e 100644
@@ -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
index 9276e52..ed2e894 100644
@@ -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

#35 lore raw

PATCH v5 6/7 x86: Move the vvar and hpet mappings next to the 64-bit vDSO

In reply to Andy Lutomirski

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
index 43f482a..b0910f9 100644
@@ -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
index 081d909..5d2b9ad 100644
@@ -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
index 85dc1b3..b97dd6e 100644
@@ -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
index 7c65b46..2cbbf88 100644
@@ -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
index 8d80ae0..bbc15a0 100644
@@ -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
index 8b3b3eb..ea5b570 100644
@@ -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
index 8e57229..858b47b 100644
@@ -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
index 5638496..6f88184 100644
@@ -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
index 091554c..b2e4f49 100644
@@ -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
index e177c08..2ec72f6 100644
@@ -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
index 86e02ea..3060568 100644
@@ -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
#36 lore raw

[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
index 43f482a..b0910f9 100644
@@ -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
index 081d909..5d2b9ad 100644
@@ -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
index 85dc1b3..b97dd6e 100644
@@ -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
index 7c65b46..2cbbf88 100644
@@ -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
index 8d80ae0..bbc15a0 100644
@@ -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
index 8b3b3eb..ea5b570 100644
@@ -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
index 8e57229..858b47b 100644
@@ -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
index 5638496..6f88184 100644
@@ -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
index 091554c..b2e4f49 100644
@@ -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
index e177c08..2ec72f6 100644
@@ -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
index 86e02ea..3060568 100644
@@ -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);
 	}
#37 lore raw

PATCH v5 7/7 x86: Remove vestiges of VDSO_PRELINK and some outdated comments

In reply to Andy Lutomirski

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
index b96b267..75e3404 100644
@@ -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
index f072095..31056cf 100644
@@ -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
index 62272aa..46b991b 100644
@@ -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
#38 lore raw

[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
index b96b267..75e3404 100644
@@ -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
index f072095..31056cf 100644
@@ -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
index 62272aa..46b991b 100644
@@ -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;