All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v7 0/9] ARM: VDSO
@ 2014-06-23  3:11 Nathan Lynch
  2014-06-23  3:11 ` [PATCH v7 1/9] clocksource: arm_arch_timer: change clocksource name if CP15 unavailable Nathan Lynch
                   ` (11 more replies)
  0 siblings, 12 replies; 76+ messages in thread
From: Nathan Lynch @ 2014-06-23  3:11 UTC (permalink / raw)
  To: linux-arm-kernel

Provide fast userspace implementations of gettimeofday and
clock_gettime on systems that implement the generic timers extension
defined in ARMv7.  This follows the example of arm64 in conception but
significantly differs in some aspects of the implementation (C vs
assembly, mainly).

Clocks supported:
- CLOCK_REALTIME
- CLOCK_MONOTONIC
- CLOCK_REALTIME_COARSE
- CLOCK_MONOTONIC_COARSE

This also provides clock_getres (as arm64 does).

getcpu support is planned but not included at this time.

Note that while the high-precision realtime and monotonic clock
support depends on the generic timers extension, support for
clock_getres and coarse clocks is independent of the timer
implementation and is provided unconditionally.

Run-time tested on OMAP5 and i.MX6, verifying that results obtained
with the vdso are consistent with those obtained from the kernel.  On
OMAP5 I observe a 3- to 4-fold speedup for gettimeofday /
CLOCK_REALTIME, with even better (if less interesting) speedups for
the coarse clock ids and clock_getres.

I've been testing and benchmarking this with some custom test code
which I have hosted here:

https://github.com/nlynch-mentor/vdsotest

If this series is applied to an already-built tree and
CONFIG_VDSO is enabled, an incremental build may fail with:

  fs/binfmt_elf.c: In function 'create_elf_tables':
  fs/binfmt_elf.c:231:35: error: 'AT_SYSINFO_EHDR' undeclared (first use
  in this function)

This can be worked around by removing
arch/arm/include/generated/asm/auxvec.h from the build tree.  I
lean toward attributing this to a Kbuild limitation/bug, but would
appreciate extra scrutiny on the patch "ARM: miscellaneous vdso
infrastructure, preparation" to see if there's anything to correct
there.

Changes since v6:
- Update to 3.16-rc1.
- Remove -lgcc from link step - need to support GCC installations
  without libgcc.
- Force -O2 compilation to prevent GCC from emitting calls to libgcc
  math routines.
- Use custom post-processing to clear the EF_ARM_ABI_FLOAT_SOFT flag
  if set in the ELF header to produce a shared object which is
  architecturally allowed to be used by both soft- and hard-float
  code.
- Consolidate common arch timer code instead of duplicating it.
- Prevent the VDSO from attempting CP15 access on memory-only
  architected timer implementations by renaming the clocksource.

Changes since v5:
- Update to 3.15-rc1.
- Place vdso at a randomized offset above the stack along with the
  sigpage.
- Properly export asm/auxvec.h.
- Split patch into series for ease of review.

Changes since v4:
- Map data page at the beginning of the VMA to prevent orphan
  sections at the end of output invalidating the calculated offset.
- Move checkundef into cmd_vdsold to avoid spurious rebuilds.
- Change vdso_init message to pr_debug.
- Add -fno-stack-protector to cflags.

Changes since v3:
- Update to 3.14-rc6.
- Record vdso base in mm context before installing mapping (for the
  sake of perf_mmap_event).
- Use a more seqcount-like API for critical sections.  Using seqcount
  API directly, however, would leak kernel pointers to userspace when
  lockdep is enabled.
- Trap instead of looping forever in division-by-zero stubs.

Changes since v2:
- Update to 3.14-rc4.
- Make vDSO configurable, depending on AEABI and MMU.
- Defer shifting of nanosecond component of timespec: fixes observed
  1ns inconsistencies for CLOCK_REALTIME, CLOCK_MONOTONIC (see
  45a7905fc48f for arm64 equivalent).
- Force reload of seq_count when spinning: without a memory clobber
  after the load of vdata->seq_count, GCC can generate code like this:
    2f8:   e59c9020        ldr     r9, [ip, #32]
    2fc:   e3190001        tst     r9, #1
    300:   1a000033        bne     3d4 <do_realtime+0x104>
    304:   f57ff05b        dmb     ish
    308:   e59c3034        ldr     r3, [ip, #52]   ; 0x34
    ...
    3d4:   eafffffe        b       3d4 <do_realtime+0x104>
- Build vdso.so with -lgcc: calls to __lshrdi3, __divsi3 sometimes
  emitted (especially with -Os).  Override certain libgcc functions to
  prevent undefined symbols.
- Do not clear PG_reserved on vdso pages.
- Remove unnecessary get_page calls.
- Simplify ELF signature check during init.
- Use volatile for asm syscall fallbacks.
- Check whether vdso_pagelist is initialized in arm_install_vdso.
- Record clocksource mask in data page.
- Reduce code duplication in do_realtime, do_monotonic.
- Reduce calculations performed in critical sections.
- Simplify coarse clock handling.
- Move datapage load to its own assembly routine.
- Tune vdso_data layout and tweak field names.
- Check vdso shared object for undefined symbols during build.

Changes since v1:
- update to 3.14-rc1
- ensure cache coherency for data page
- Document the kernel-to-userspace protocol for vdso data page updates,
  and note that the timekeeping core prevents concurrent updates.
- update wall-to-monotonic fields unconditionally
- move vdso_start, vdso_end declarations to vdso.h
- correctly build and run when CONFIG_ARM_ARCH_TIMER=n
- rearrange linker script to avoid overlapping sections when CONFIG_DEBUGINFO=n
- remove use_syscall checks from coarse clock paths
- crib BUG_INSTR (0xe7f001f2) from asm/bug.h for text fill

Nathan Lynch (9):
  clocksource: arm_arch_timer: change clocksource name if CP15
    unavailable
  clocksource: arm_arch_timer: enable counter access for 32-bit ARM
  ARM: arch_timer: remove unused functions
  arm64: arch_timer: remove unused functions
  ARM: place sigpage at a random offset above stack
  ARM: miscellaneous vdso infrastructure, preparation
  ARM: add vdso user-space code
  ARM: vdso initialization, mapping, and synchronization
  ARM: add CONFIG_VDSO Kconfig and Makefile bits

 arch/arm/include/asm/Kbuild          |   1 -
 arch/arm/include/asm/arch_timer.h    |  25 ---
 arch/arm/include/asm/elf.h           |  11 ++
 arch/arm/include/asm/mmu.h           |   3 +
 arch/arm/include/asm/vdso.h          |  47 +++++
 arch/arm/include/asm/vdso_datapage.h |  60 +++++++
 arch/arm/include/uapi/asm/Kbuild     |   1 +
 arch/arm/include/uapi/asm/auxvec.h   |   7 +
 arch/arm/kernel/Makefile             |   1 +
 arch/arm/kernel/asm-offsets.c        |   5 +
 arch/arm/kernel/process.c            |  56 +++++-
 arch/arm/kernel/vdso.c               | 168 ++++++++++++++++++
 arch/arm/kernel/vdso/.gitignore      |   1 +
 arch/arm/kernel/vdso/Makefile        |  59 +++++++
 arch/arm/kernel/vdso/checkundef.sh   |   9 +
 arch/arm/kernel/vdso/datapage.S      |  15 ++
 arch/arm/kernel/vdso/vdso.S          |  35 ++++
 arch/arm/kernel/vdso/vdso.lds.S      |  88 ++++++++++
 arch/arm/kernel/vdso/vdsomunge.c     | 193 +++++++++++++++++++++
 arch/arm/kernel/vdso/vgettimeofday.c | 320 +++++++++++++++++++++++++++++++++++
 arch/arm/mm/Kconfig                  |  15 ++
 arch/arm64/include/asm/arch_timer.h  |  31 ----
 drivers/clocksource/arm_arch_timer.c |  48 +++++-
 23 files changed, 1134 insertions(+), 65 deletions(-)
 create mode 100644 arch/arm/include/asm/vdso.h
 create mode 100644 arch/arm/include/asm/vdso_datapage.h
 create mode 100644 arch/arm/include/uapi/asm/auxvec.h
 create mode 100644 arch/arm/kernel/vdso.c
 create mode 100644 arch/arm/kernel/vdso/.gitignore
 create mode 100644 arch/arm/kernel/vdso/Makefile
 create mode 100755 arch/arm/kernel/vdso/checkundef.sh
 create mode 100644 arch/arm/kernel/vdso/datapage.S
 create mode 100644 arch/arm/kernel/vdso/vdso.S
 create mode 100644 arch/arm/kernel/vdso/vdso.lds.S
 create mode 100644 arch/arm/kernel/vdso/vdsomunge.c
 create mode 100644 arch/arm/kernel/vdso/vgettimeofday.c

-- 
1.9.3

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 1/9] clocksource: arm_arch_timer: change clocksource name if CP15 unavailable
  2014-06-23  3:11 [PATCH v7 0/9] ARM: VDSO Nathan Lynch
@ 2014-06-23  3:11 ` Nathan Lynch
  2014-06-23  3:11 ` [PATCH v7 2/9] clocksource: arm_arch_timer: enable counter access for 32-bit ARM Nathan Lynch
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 76+ messages in thread
From: Nathan Lynch @ 2014-06-23  3:11 UTC (permalink / raw)
  To: linux-arm-kernel

The arm and arm64 VDSOs need CP15 access to the architected counter.
If this is unavailable (which is allowed by ARM v7), indicate this by
changing the clocksource name to "arch_mem_counter" before registering
the clocksource.

Suggested by Stephen Boyd.

Signed-off-by: Nathan Lynch <nathan_lynch@mentor.com>
---
 drivers/clocksource/arm_arch_timer.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 5163ec13429d..c99afdf12e98 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -429,11 +429,19 @@ static void __init arch_counter_register(unsigned type)
 	u64 start_count;
 
 	/* Register the CP15 based counter if we have one */
-	if (type & ARCH_CP15_TIMER)
+	if (type & ARCH_CP15_TIMER) {
 		arch_timer_read_counter = arch_counter_get_cntvct;
-	else
+	} else {
 		arch_timer_read_counter = arch_counter_get_cntvct_mem;
 
+		/* If the clocksource name is "arch_sys_counter" the
+		 * VDSO will attempt to read the CP15-based counter.
+		 * Ensure this does not happen when CP15-based
+		 * counter is not available.
+		 */
+		clocksource_counter.name = "arch_mem_counter";
+	}
+
 	start_count = arch_timer_read_counter();
 	clocksource_register_hz(&clocksource_counter, arch_timer_rate);
 	cyclecounter.mult = clocksource_counter.mult;
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH v7 2/9] clocksource: arm_arch_timer: enable counter access for 32-bit ARM
  2014-06-23  3:11 [PATCH v7 0/9] ARM: VDSO Nathan Lynch
  2014-06-23  3:11 ` [PATCH v7 1/9] clocksource: arm_arch_timer: change clocksource name if CP15 unavailable Nathan Lynch
@ 2014-06-23  3:11 ` Nathan Lynch
  2014-06-23  3:11 ` [PATCH v7 3/9] ARM: arch_timer: remove unused functions Nathan Lynch
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 76+ messages in thread
From: Nathan Lynch @ 2014-06-23  3:11 UTC (permalink / raw)
  To: linux-arm-kernel

The only difference between arm and arm64's implementations of
arch_counter_set_user_access is that 32-bit ARM does not enable user
access to the virtual counter.  We want to enable this access for the
32-bit ARM VDSO, so copy the arm64 version to the driver itself,
giving it a slightly different name (arch_counter_set_access) to avoid
redefinition.

The arch_timer_evtstrm_enable hooks are also substantially similar,
the only difference being a CONFIG_COMPAT-conditional section which is
relevant only for arm64.  Copy the arm64 version to the driver, again
slightly renaming (arch_timer_evtstrm_enable => arch_timer_enable_evtstrm).

With this change, the arch_counter_set_user_access and
arch_timer_evtstrm_enable hooks in both arm and arm64 become unused, to
be removed in followup patches.

Signed-off-by: Nathan Lynch <nathan_lynch@mentor.com>
---
 drivers/clocksource/arm_arch_timer.c | 36 ++++++++++++++++++++++++++++++++++--
 1 file changed, 34 insertions(+), 2 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index c99afdf12e98..0188332ad24b 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -23,6 +23,7 @@
 #include <linux/sched_clock.h>
 
 #include <asm/arch_timer.h>
+#include <asm/hwcap.h>
 #include <asm/virt.h>
 
 #include <clocksource/arm_arch_timer.h>
@@ -299,6 +300,20 @@ static void __arch_timer_setup(unsigned type,
 	clockevents_config_and_register(clk, arch_timer_rate, 0xf, 0x7fffffff);
 }
 
+static void arch_timer_enable_evtstrm(int divider)
+{
+	u32 cntkctl = arch_timer_get_cntkctl();
+	cntkctl &= ~ARCH_TIMER_EVT_TRIGGER_MASK;
+	/* Set the divider and enable virtual event stream */
+	cntkctl |= (divider << ARCH_TIMER_EVT_TRIGGER_SHIFT)
+			| ARCH_TIMER_VIRT_EVT_EN;
+	arch_timer_set_cntkctl(cntkctl);
+	elf_hwcap |= HWCAP_EVTSTRM;
+#ifdef CONFIG_COMPAT
+	compat_elf_hwcap |= COMPAT_HWCAP_EVTSTRM;
+#endif
+}
+
 static void arch_timer_configure_evtstream(void)
 {
 	int evt_stream_div, pos;
@@ -309,7 +324,24 @@ static void arch_timer_configure_evtstream(void)
 	if (pos > 1 && !(evt_stream_div & (1 << (pos - 2))))
 		pos--;
 	/* enable event stream */
-	arch_timer_evtstrm_enable(min(pos, 15));
+	arch_timer_enable_evtstrm(min(pos, 15));
+}
+
+static void arch_counter_set_access(void)
+{
+	u32 cntkctl = arch_timer_get_cntkctl();
+
+	/* Disable user access to the timers and the physical counter */
+	/* Also disable virtual event stream */
+	cntkctl &= ~(ARCH_TIMER_USR_PT_ACCESS_EN
+			| ARCH_TIMER_USR_VT_ACCESS_EN
+			| ARCH_TIMER_VIRT_EVT_EN
+			| ARCH_TIMER_USR_PCT_ACCESS_EN);
+
+	/* Enable user access to the virtual counter */
+	cntkctl |= ARCH_TIMER_USR_VCT_ACCESS_EN;
+
+	arch_timer_set_cntkctl(cntkctl);
 }
 
 static int arch_timer_setup(struct clock_event_device *clk)
@@ -324,7 +356,7 @@ static int arch_timer_setup(struct clock_event_device *clk)
 			enable_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI], 0);
 	}
 
-	arch_counter_set_user_access();
+	arch_counter_set_access();
 	if (IS_ENABLED(CONFIG_ARM_ARCH_TIMER_EVTSTREAM))
 		arch_timer_configure_evtstream();
 
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH v7 3/9] ARM: arch_timer: remove unused functions
  2014-06-23  3:11 [PATCH v7 0/9] ARM: VDSO Nathan Lynch
  2014-06-23  3:11 ` [PATCH v7 1/9] clocksource: arm_arch_timer: change clocksource name if CP15 unavailable Nathan Lynch
  2014-06-23  3:11 ` [PATCH v7 2/9] clocksource: arm_arch_timer: enable counter access for 32-bit ARM Nathan Lynch
@ 2014-06-23  3:11 ` Nathan Lynch
  2014-06-23  3:11 ` [PATCH v7 4/9] arm64: " Nathan Lynch
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 76+ messages in thread
From: Nathan Lynch @ 2014-06-23  3:11 UTC (permalink / raw)
  To: linux-arm-kernel

The counter access and evtstream configuration are now done in common
code, so remove the now-unused arch_counter_set_user_access and
arch_timer_evtstrm_enable.

Signed-off-by: Nathan Lynch <nathan_lynch@mentor.com>
---
 arch/arm/include/asm/arch_timer.h | 25 -------------------------
 1 file changed, 25 deletions(-)

diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h
index 0704e0cf5571..92793ba69c40 100644
--- a/arch/arm/include/asm/arch_timer.h
+++ b/arch/arm/include/asm/arch_timer.h
@@ -99,31 +99,6 @@ static inline void arch_timer_set_cntkctl(u32 cntkctl)
 	asm volatile("mcr p15, 0, %0, c14, c1, 0" : : "r" (cntkctl));
 }
 
-static inline void arch_counter_set_user_access(void)
-{
-	u32 cntkctl = arch_timer_get_cntkctl();
-
-	/* Disable user access to both physical/virtual counters/timers */
-	/* Also disable virtual event stream */
-	cntkctl &= ~(ARCH_TIMER_USR_PT_ACCESS_EN
-			| ARCH_TIMER_USR_VT_ACCESS_EN
-			| ARCH_TIMER_VIRT_EVT_EN
-			| ARCH_TIMER_USR_VCT_ACCESS_EN
-			| ARCH_TIMER_USR_PCT_ACCESS_EN);
-	arch_timer_set_cntkctl(cntkctl);
-}
-
-static inline void arch_timer_evtstrm_enable(int divider)
-{
-	u32 cntkctl = arch_timer_get_cntkctl();
-	cntkctl &= ~ARCH_TIMER_EVT_TRIGGER_MASK;
-	/* Set the divider and enable virtual event stream */
-	cntkctl |= (divider << ARCH_TIMER_EVT_TRIGGER_SHIFT)
-			| ARCH_TIMER_VIRT_EVT_EN;
-	arch_timer_set_cntkctl(cntkctl);
-	elf_hwcap |= HWCAP_EVTSTRM;
-}
-
 #endif
 
 #endif
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH v7 4/9] arm64: arch_timer: remove unused functions
  2014-06-23  3:11 [PATCH v7 0/9] ARM: VDSO Nathan Lynch
                   ` (2 preceding siblings ...)
  2014-06-23  3:11 ` [PATCH v7 3/9] ARM: arch_timer: remove unused functions Nathan Lynch
@ 2014-06-23  3:11 ` Nathan Lynch
  2014-06-23  3:11 ` [PATCH v7 5/9] ARM: place sigpage at a random offset above stack Nathan Lynch
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 76+ messages in thread
From: Nathan Lynch @ 2014-06-23  3:11 UTC (permalink / raw)
  To: linux-arm-kernel

The counter access and evtstream configuration are now done in common
code, so remove the now-unused arch_counter_set_user_access and
arch_timer_evtstrm_enable.

Signed-off-by: Nathan Lynch <nathan_lynch@mentor.com>
---
 arch/arm64/include/asm/arch_timer.h | 31 -------------------------------
 1 file changed, 31 deletions(-)

diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
index 9400596a0f39..f19097134b02 100644
--- a/arch/arm64/include/asm/arch_timer.h
+++ b/arch/arm64/include/asm/arch_timer.h
@@ -104,37 +104,6 @@ static inline void arch_timer_set_cntkctl(u32 cntkctl)
 	asm volatile("msr	cntkctl_el1, %0" : : "r" (cntkctl));
 }
 
-static inline void arch_counter_set_user_access(void)
-{
-	u32 cntkctl = arch_timer_get_cntkctl();
-
-	/* Disable user access to the timers and the physical counter */
-	/* Also disable virtual event stream */
-	cntkctl &= ~(ARCH_TIMER_USR_PT_ACCESS_EN
-			| ARCH_TIMER_USR_VT_ACCESS_EN
-			| ARCH_TIMER_VIRT_EVT_EN
-			| ARCH_TIMER_USR_PCT_ACCESS_EN);
-
-	/* Enable user access to the virtual counter */
-	cntkctl |= ARCH_TIMER_USR_VCT_ACCESS_EN;
-
-	arch_timer_set_cntkctl(cntkctl);
-}
-
-static inline void arch_timer_evtstrm_enable(int divider)
-{
-	u32 cntkctl = arch_timer_get_cntkctl();
-	cntkctl &= ~ARCH_TIMER_EVT_TRIGGER_MASK;
-	/* Set the divider and enable virtual event stream */
-	cntkctl |= (divider << ARCH_TIMER_EVT_TRIGGER_SHIFT)
-			| ARCH_TIMER_VIRT_EVT_EN;
-	arch_timer_set_cntkctl(cntkctl);
-	elf_hwcap |= HWCAP_EVTSTRM;
-#ifdef CONFIG_COMPAT
-	compat_elf_hwcap |= COMPAT_HWCAP_EVTSTRM;
-#endif
-}
-
 static inline u64 arch_counter_get_cntvct(void)
 {
 	u64 cval;
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH v7 5/9] ARM: place sigpage at a random offset above stack
  2014-06-23  3:11 [PATCH v7 0/9] ARM: VDSO Nathan Lynch
                   ` (3 preceding siblings ...)
  2014-06-23  3:11 ` [PATCH v7 4/9] arm64: " Nathan Lynch
@ 2014-06-23  3:11 ` Nathan Lynch
  2014-06-23  3:11 ` [PATCH v7 6/9] ARM: miscellaneous vdso infrastructure, preparation Nathan Lynch
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 76+ messages in thread
From: Nathan Lynch @ 2014-06-23  3:11 UTC (permalink / raw)
  To: linux-arm-kernel

The sigpage is currently placed alongside shared libraries etc in the
address space.  Similar to what x86_64 does for its VDSO, place the
sigpage at a randomized offset above the stack so that learning the
base address of the sigpage doesn't help expose where shared libraries
are loaded in the address space (and vice versa).

This code will be used for placing the vdso as well, hence the
vdso_addr function name and npages argument.

Signed-off-by: Nathan Lynch <nathan_lynch@mentor.com>
---
 arch/arm/kernel/process.c | 33 ++++++++++++++++++++++++++++++++-
 1 file changed, 32 insertions(+), 1 deletion(-)

diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 81ef686a91ca..219a0d1d10fc 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -477,6 +477,35 @@ const char *arch_vma_name(struct vm_area_struct *vma)
 		 "[sigpage]" : NULL;
 }
 
+static unsigned long vdso_addr(const struct mm_struct *mm, unsigned int npages)
+{
+	unsigned long offset;
+	unsigned long first;
+	unsigned long last;
+	unsigned long addr;
+	unsigned int slots;
+
+	first = PAGE_ALIGN(mm->start_stack);
+
+	last = TASK_SIZE - (npages << PAGE_SHIFT);
+
+	/* No room after stack? */
+	if (first > last)
+		return 0;
+
+	/* Just enough room? */
+	if (first == last)
+		return first;
+
+	slots = ((last - first) >> PAGE_SHIFT) + 1;
+
+	offset = get_random_int() % slots;
+
+	addr = first + (offset << PAGE_SHIFT);
+
+	return addr;
+}
+
 static struct page *signal_page;
 extern struct page *get_signal_page(void);
 
@@ -484,6 +513,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 {
 	struct mm_struct *mm = current->mm;
 	unsigned long addr;
+	unsigned long hint;
 	int ret;
 
 	if (!signal_page)
@@ -492,7 +522,8 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 		return -ENOMEM;
 
 	down_write(&mm->mmap_sem);
-	addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
+	hint = vdso_addr(mm, 1);
+	addr = get_unmapped_area(NULL, hint, PAGE_SIZE, 0, 0);
 	if (IS_ERR_VALUE(addr)) {
 		ret = addr;
 		goto up_fail;
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH v7 6/9] ARM: miscellaneous vdso infrastructure, preparation
  2014-06-23  3:11 [PATCH v7 0/9] ARM: VDSO Nathan Lynch
                   ` (4 preceding siblings ...)
  2014-06-23  3:11 ` [PATCH v7 5/9] ARM: place sigpage at a random offset above stack Nathan Lynch
@ 2014-06-23  3:11 ` Nathan Lynch
  2014-06-30 10:11   ` Arnd Bergmann
  2014-06-23  3:11 ` [PATCH v7 7/9] ARM: add vdso user-space code Nathan Lynch
                   ` (5 subsequent siblings)
  11 siblings, 1 reply; 76+ messages in thread
From: Nathan Lynch @ 2014-06-23  3:11 UTC (permalink / raw)
  To: linux-arm-kernel

Define the layout of the data structure shared between kernel and
userspace.

Track the vdso address in the mm_context; needed for reporting [vdso]
via /proc/pid/maps and communicating AT_SYSINFO_EHDR to the ELF
loader.

Add declarations for vma_is_vdso, arm_install_vdso, and !CONFIG_VDSO
implementations of same.  The CONFIG_VDSO=y implementations of these
come later.

Make arch_vma_name recognize a vdso VMA, using vma_is_vdso to return
"[vdso]" when appropriate.

Define AT_SYSINFO_EHDR, and, if CONFIG_VDSO=y, report the vdso shared
object address via the ELF auxiliary vector.

Note - this adds the AT_SYSINFO_EHDR in a new user-visible header
asm/auxvec.h; this is consistent with other architectures.

Signed-off-by: Nathan Lynch <nathan_lynch@mentor.com>
---
 arch/arm/include/asm/Kbuild          |  1 -
 arch/arm/include/asm/elf.h           | 11 +++++++
 arch/arm/include/asm/mmu.h           |  3 ++
 arch/arm/include/asm/vdso.h          | 47 ++++++++++++++++++++++++++++
 arch/arm/include/asm/vdso_datapage.h | 60 ++++++++++++++++++++++++++++++++++++
 arch/arm/include/uapi/asm/Kbuild     |  1 +
 arch/arm/include/uapi/asm/auxvec.h   |  7 +++++
 arch/arm/kernel/process.c            | 14 +++++++--
 8 files changed, 140 insertions(+), 4 deletions(-)
 create mode 100644 arch/arm/include/asm/vdso.h
 create mode 100644 arch/arm/include/asm/vdso_datapage.h
 create mode 100644 arch/arm/include/uapi/asm/auxvec.h

diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild
index f5a357601983..0e70f40e04ef 100644
--- a/arch/arm/include/asm/Kbuild
+++ b/arch/arm/include/asm/Kbuild
@@ -1,6 +1,5 @@
 
 
-generic-y += auxvec.h
 generic-y += bitsperlong.h
 generic-y += cputime.h
 generic-y += current.h
diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
index f4b46d39b9cf..45d2ddff662a 100644
--- a/arch/arm/include/asm/elf.h
+++ b/arch/arm/include/asm/elf.h
@@ -1,7 +1,9 @@
 #ifndef __ASMARM_ELF_H
 #define __ASMARM_ELF_H
 
+#include <asm/auxvec.h>
 #include <asm/hwcap.h>
+#include <asm/vdso_datapage.h>
 
 /*
  * ELF register definitions..
@@ -129,6 +131,15 @@ extern unsigned long arch_randomize_brk(struct mm_struct *mm);
 #define arch_randomize_brk arch_randomize_brk
 
 #ifdef CONFIG_MMU
+#ifdef CONFIG_VDSO
+#define ARCH_DLINFO								\
+do {										\
+	/* Account for the data page at the beginning of the [vdso] VMA. */	\
+	NEW_AUX_ENT(AT_SYSINFO_EHDR,						\
+		    (elf_addr_t)current->mm->context.vdso +			\
+		    sizeof(union vdso_data_store));				\
+} while (0)
+#endif
 #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
 struct linux_binprm;
 int arch_setup_additional_pages(struct linux_binprm *, int);
diff --git a/arch/arm/include/asm/mmu.h b/arch/arm/include/asm/mmu.h
index 64fd15159b7d..a5b47421059d 100644
--- a/arch/arm/include/asm/mmu.h
+++ b/arch/arm/include/asm/mmu.h
@@ -11,6 +11,9 @@ typedef struct {
 #endif
 	unsigned int	vmalloc_seq;
 	unsigned long	sigpage;
+#ifdef CONFIG_VDSO
+	unsigned long	vdso;
+#endif
 } mm_context_t;
 
 #ifdef CONFIG_CPU_HAS_ASID
diff --git a/arch/arm/include/asm/vdso.h b/arch/arm/include/asm/vdso.h
new file mode 100644
index 000000000000..0e2a6154eceb
--- /dev/null
+++ b/arch/arm/include/asm/vdso.h
@@ -0,0 +1,47 @@
+#ifndef __ASM_VDSO_H
+#define __ASM_VDSO_H
+
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+
+#include <linux/mm_types.h>
+#include <asm/mmu.h>
+
+#ifdef CONFIG_VDSO
+
+static inline bool vma_is_vdso(struct vm_area_struct *vma)
+{
+	if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
+		return true;
+	return false;
+}
+
+void arm_install_vdso(struct mm_struct *mm, unsigned long addr);
+
+extern char vdso_start, vdso_end;
+
+extern unsigned long vdso_mapping_len;
+
+#else /* CONFIG_VDSO */
+
+static inline bool vma_is_vdso(struct vm_area_struct *vma)
+{
+	return false;
+}
+
+static inline void arm_install_vdso(struct mm_struct *mm, unsigned long addr)
+{
+}
+
+#define vdso_mapping_len 0
+
+#endif /* CONFIG_VDSO */
+
+#endif /* __ASSEMBLY__ */
+
+#define VDSO_LBASE	0x0
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_VDSO_H */
diff --git a/arch/arm/include/asm/vdso_datapage.h b/arch/arm/include/asm/vdso_datapage.h
new file mode 100644
index 000000000000..f08bdb73d3f4
--- /dev/null
+++ b/arch/arm/include/asm/vdso_datapage.h
@@ -0,0 +1,60 @@
+/*
+ * Adapted from arm64 version.
+ *
+ * Copyright (C) 2012 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef __ASM_VDSO_DATAPAGE_H
+#define __ASM_VDSO_DATAPAGE_H
+
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+
+#include <asm/page.h>
+
+/* Try to be cache-friendly on systems that don't implement the
+ * generic timer: fit the unconditionally updated fields in the first
+ * 32 bytes.
+ */
+struct vdso_data {
+	u32 seq_count;		/* sequence count - odd during updates */
+	u16 use_syscall;	/* whether to fall back to syscalls */
+	u16 cs_shift;		/* clocksource shift */
+	u32 xtime_coarse_sec;	/* coarse time */
+	u32 xtime_coarse_nsec;
+
+	u32 wtm_clock_sec;	/* wall to monotonic offset */
+	u32 wtm_clock_nsec;
+	u32 xtime_clock_sec;	/* CLOCK_REALTIME - seconds */
+	u32 cs_mult;		/* clocksource multiplier */
+
+	u64 cs_cycle_last;	/* last cycle value */
+	u64 cs_mask;		/* clocksource mask */
+
+	u64 xtime_clock_snsec;	/* CLOCK_REALTIME sub-ns base */
+	u32 tz_minuteswest;	/* timezone info for gettimeofday(2) */
+	u32 tz_dsttime;
+};
+
+union vdso_data_store {
+	struct vdso_data data;
+	u8 page[PAGE_SIZE];
+};
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_VDSO_DATAPAGE_H */
diff --git a/arch/arm/include/uapi/asm/Kbuild b/arch/arm/include/uapi/asm/Kbuild
index 70a1c9da30ca..a1c05f93d920 100644
--- a/arch/arm/include/uapi/asm/Kbuild
+++ b/arch/arm/include/uapi/asm/Kbuild
@@ -1,6 +1,7 @@
 # UAPI Header export list
 include include/uapi/asm-generic/Kbuild.asm
 
+header-y += auxvec.h
 header-y += byteorder.h
 header-y += fcntl.h
 header-y += hwcap.h
diff --git a/arch/arm/include/uapi/asm/auxvec.h b/arch/arm/include/uapi/asm/auxvec.h
new file mode 100644
index 000000000000..f56936b97ec2
--- /dev/null
+++ b/arch/arm/include/uapi/asm/auxvec.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_AUXVEC_H
+#define __ASM_AUXVEC_H
+
+/* vDSO location */
+#define AT_SYSINFO_EHDR	33
+
+#endif
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 219a0d1d10fc..40445fb71ac9 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -41,6 +41,7 @@
 #include <asm/system_misc.h>
 #include <asm/mach/time.h>
 #include <asm/tls.h>
+#include <asm/vdso.h>
 
 #ifdef CONFIG_CC_STACKPROTECTOR
 #include <linux/stackprotector.h>
@@ -472,9 +473,16 @@ int in_gate_area_no_mm(unsigned long addr)
 
 const char *arch_vma_name(struct vm_area_struct *vma)
 {
-	return is_gate_vma(vma) ? "[vectors]" :
-		(vma->vm_mm && vma->vm_start == vma->vm_mm->context.sigpage) ?
-		 "[sigpage]" : NULL;
+	if (is_gate_vma(vma))
+		return "[vectors]";
+
+	if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.sigpage)
+		return "[sigpage]";
+
+	if (vma_is_vdso(vma))
+		return "[vdso]";
+
+	return NULL;
 }
 
 static unsigned long vdso_addr(const struct mm_struct *mm, unsigned int npages)
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH v7 7/9] ARM: add vdso user-space code
  2014-06-23  3:11 [PATCH v7 0/9] ARM: VDSO Nathan Lynch
                   ` (5 preceding siblings ...)
  2014-06-23  3:11 ` [PATCH v7 6/9] ARM: miscellaneous vdso infrastructure, preparation Nathan Lynch
@ 2014-06-23  3:11 ` Nathan Lynch
  2014-06-28  9:53   ` Russell King - ARM Linux
                     ` (2 more replies)
  2014-06-23  3:11 ` [PATCH v7 8/9] ARM: vdso initialization, mapping, and synchronization Nathan Lynch
                   ` (4 subsequent siblings)
  11 siblings, 3 replies; 76+ messages in thread
From: Nathan Lynch @ 2014-06-23  3:11 UTC (permalink / raw)
  To: linux-arm-kernel

Place vdso-related user-space code in arch/arm/kernel/vdso/.

It is almost completely written in C with some assembly helpers to
load the data page address, sample the counter, and fall back to
system calls when necessary.

If CONFIG_ARM_ARCH_TIMER is not enabled, the vdso cannot service
high-resolution clocks and falls back to syscalls.  Low-resolution
clocks e.g. CLOCK_REALTIME_COARSE can be serviced regardless.

Of particular note is that a post-processing step ("vdsomunge") is
necessary to produce a shared object which is architecturally allowed
to be used by both soft- and hard-float EABI programs.

The 2012 edition of the ARM ABI defines Tag_ABI_VFP_args = 3 "Code is
compatible with both the base and VFP variants; the user did not
permit non-variadic functions to pass FP parameters/results."
Unfortunately current toolchains do not support this tag, which is
ideally what we would use.

The best available option is to ensure that both EF_ARM_ABI_FLOAT_SOFT
and EF_ARM_ABI_FLOAT_HARD are unset in the ELF header's e_flags,
indicating that the shared object is "old" and should be accepted for
backward compatibility's sake.  While binutils < 2.24 appear to
produce a vdso.so with both flags clear, 2.24 always sets
EF_ARM_ABI_FLOAT_SOFT, with no way to inhibit this behavior.  So we
have to fix things up with a custom post-processing step.

In fact, the VDSO code in glibc does much less validation (including
checking these flags) than the code for handling conventional
file-backed shared libraries, so this is a bit moot unless glibc's
VDSO code becomes more strict.

Signed-off-by: Nathan Lynch <nathan_lynch@mentor.com>
---
 arch/arm/kernel/asm-offsets.c        |   5 +
 arch/arm/kernel/vdso/.gitignore      |   1 +
 arch/arm/kernel/vdso/Makefile        |  59 +++++++
 arch/arm/kernel/vdso/checkundef.sh   |   9 +
 arch/arm/kernel/vdso/datapage.S      |  15 ++
 arch/arm/kernel/vdso/vdso.S          |  35 ++++
 arch/arm/kernel/vdso/vdso.lds.S      |  88 ++++++++++
 arch/arm/kernel/vdso/vdsomunge.c     | 193 +++++++++++++++++++++
 arch/arm/kernel/vdso/vgettimeofday.c | 320 +++++++++++++++++++++++++++++++++++
 9 files changed, 725 insertions(+)
 create mode 100644 arch/arm/kernel/vdso/.gitignore
 create mode 100644 arch/arm/kernel/vdso/Makefile
 create mode 100755 arch/arm/kernel/vdso/checkundef.sh
 create mode 100644 arch/arm/kernel/vdso/datapage.S
 create mode 100644 arch/arm/kernel/vdso/vdso.S
 create mode 100644 arch/arm/kernel/vdso/vdso.lds.S
 create mode 100644 arch/arm/kernel/vdso/vdsomunge.c
 create mode 100644 arch/arm/kernel/vdso/vgettimeofday.c

diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index 85598b5d1efd..a582bb42dc87 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -24,6 +24,7 @@
 #include <asm/memory.h>
 #include <asm/procinfo.h>
 #include <asm/suspend.h>
+#include <asm/vdso_datapage.h>
 #include <asm/hardware/cache-l2x0.h>
 #include <linux/kbuild.h>
 
@@ -200,5 +201,9 @@ int main(void)
 #endif
   DEFINE(KVM_VTTBR,		offsetof(struct kvm, arch.vttbr));
 #endif
+  BLANK();
+#ifdef CONFIG_VDSO
+  DEFINE(VDSO_DATA_SIZE,	sizeof(union vdso_data_store));
+#endif
   return 0; 
 }
diff --git a/arch/arm/kernel/vdso/.gitignore b/arch/arm/kernel/vdso/.gitignore
new file mode 100644
index 000000000000..f8b69d84238e
--- /dev/null
+++ b/arch/arm/kernel/vdso/.gitignore
@@ -0,0 +1 @@
+vdso.lds
diff --git a/arch/arm/kernel/vdso/Makefile b/arch/arm/kernel/vdso/Makefile
new file mode 100644
index 000000000000..ceb712a7626c
--- /dev/null
+++ b/arch/arm/kernel/vdso/Makefile
@@ -0,0 +1,59 @@
+hostprogs-y := vdsomunge
+
+obj-vdso := vgettimeofday.o datapage.o
+
+# Build rules
+targets := $(obj-vdso) vdso.so vdso.so.dbg vdso.so.raw vdso.lds
+obj-vdso := $(addprefix $(obj)/, $(obj-vdso))
+
+ccflags-y := -shared -fPIC -fno-common -fno-builtin -fno-stack-protector
+ccflags-y += -nostdlib -Wl,-soname=linux-vdso.so.1 \
+		$(call cc-ldoption, -Wl$(comma)--hash-style=sysv)
+
+obj-y += vdso.o
+extra-y += vdso.lds
+CPPFLAGS_vdso.lds += -P -C -U$(ARCH)
+
+CFLAGS_REMOVE_vdso.o = -pg
+
+# Force -O2 to avoid libgcc dependencies
+CFLAGS_REMOVE_vgettimeofday.o = -pg -Os
+CFLAGS_vgettimeofday.o = -O2
+
+# Disable gcov profiling for VDSO code
+GCOV_PROFILE := n
+
+# Force dependency
+$(obj)/vdso.o : $(obj)/vdso.so
+
+# Link rule for the .so file, .lds has to be first
+$(obj)/vdso.so.raw: $(src)/vdso.lds $(obj-vdso)
+	$(call if_changed,vdsold)
+
+$(obj)/vdso.so.dbg: $(obj)/vdso.so.raw $(obj)/vdsomunge FORCE
+	$(call if_changed,vdsomunge)
+
+# Strip rule for the .so file
+$(obj)/%.so: OBJCOPYFLAGS := -S
+$(obj)/%.so: $(obj)/%.so.dbg FORCE
+	$(call if_changed,objcopy)
+
+checkundef = sh $(srctree)/$(src)/checkundef.sh
+
+# Actual build commands
+quiet_cmd_vdsold = VDSOL   $@
+      cmd_vdsold = $(CC) $(c_flags) -Wl,-T $^ -o $@ && \
+		   $(checkundef) '$(NM)' $@
+
+quiet_cmd_vdsomunge = MUNGE   $@
+      cmd_vdsomunge = $(objtree)/$(obj)/vdsomunge $< $@
+
+# Install commands for the unstripped file
+quiet_cmd_vdso_install = INSTALL $@
+      cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@
+
+vdso.so: $(obj)/vdso.so.dbg
+	@mkdir -p $(MODLIB)/vdso
+	$(call cmd,vdso_install)
+
+vdso_install: vdso.so
diff --git a/arch/arm/kernel/vdso/checkundef.sh b/arch/arm/kernel/vdso/checkundef.sh
new file mode 100755
index 000000000000..185c30da202b
--- /dev/null
+++ b/arch/arm/kernel/vdso/checkundef.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+nm="$1"
+file="$2"
+"$nm" -u "$file" | ( ret=0; while read discard symbol
+do
+    echo "$file: undefined symbol $symbol"
+    ret=1
+done ; exit $ret )
+exit $?
diff --git a/arch/arm/kernel/vdso/datapage.S b/arch/arm/kernel/vdso/datapage.S
new file mode 100644
index 000000000000..fbf36d75da06
--- /dev/null
+++ b/arch/arm/kernel/vdso/datapage.S
@@ -0,0 +1,15 @@
+#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+
+	.align 2
+.L_vdso_data_ptr:
+	.long	_start - . - VDSO_DATA_SIZE
+
+ENTRY(__get_datapage)
+	.cfi_startproc
+	adr	r0, .L_vdso_data_ptr
+	ldr	r1, [r0]
+	add	r0, r0, r1
+	bx	lr
+	.cfi_endproc
+ENDPROC(__get_datapage)
diff --git a/arch/arm/kernel/vdso/vdso.S b/arch/arm/kernel/vdso/vdso.S
new file mode 100644
index 000000000000..aed16ff84c5f
--- /dev/null
+++ b/arch/arm/kernel/vdso/vdso.S
@@ -0,0 +1,35 @@
+/*
+ * Adapted from arm64 version.
+ *
+ * Copyright (C) 2012 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Will Deacon <will.deacon@arm.com>
+ */
+
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <linux/const.h>
+#include <asm/page.h>
+
+	__PAGE_ALIGNED_DATA
+
+	.globl vdso_start, vdso_end
+	.balign PAGE_SIZE
+vdso_start:
+	.incbin "arch/arm/kernel/vdso/vdso.so"
+	.balign PAGE_SIZE
+vdso_end:
+
+	.previous
diff --git a/arch/arm/kernel/vdso/vdso.lds.S b/arch/arm/kernel/vdso/vdso.lds.S
new file mode 100644
index 000000000000..b509cc12e0eb
--- /dev/null
+++ b/arch/arm/kernel/vdso/vdso.lds.S
@@ -0,0 +1,88 @@
+/*
+ * Adapted from arm64 version.
+ *
+ * GNU linker script for the VDSO library.
+ *
+ * Copyright (C) 2012 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Will Deacon <will.deacon@arm.com>
+ * Heavily based on the vDSO linker scripts for other archs.
+ */
+
+#include <linux/const.h>
+#include <asm/page.h>
+#include <asm/vdso.h>
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+
+SECTIONS
+{
+	PROVIDE(_start = .);
+
+	. = VDSO_LBASE + SIZEOF_HEADERS;
+
+	.hash		: { *(.hash) }			:text
+	.gnu.hash	: { *(.gnu.hash) }
+	.dynsym		: { *(.dynsym) }
+	.dynstr		: { *(.dynstr) }
+	.gnu.version	: { *(.gnu.version) }
+	.gnu.version_d	: { *(.gnu.version_d) }
+	.gnu.version_r	: { *(.gnu.version_r) }
+
+	.note		: { *(.note.*) }		:text	:note
+
+
+	.eh_frame_hdr	: { *(.eh_frame_hdr) }		:text	:eh_frame_hdr
+	.eh_frame	: { KEEP (*(.eh_frame)) }	:text
+
+	.dynamic	: { *(.dynamic) }		:text	:dynamic
+
+	.rodata		: { *(.rodata*) }		:text
+
+	.text		: { *(.text*) }			:text	=0xe7f001f2
+
+	.got		: { *(.got) }
+	.rel.plt	: { *(.rel.plt) }
+
+	/DISCARD/	: {
+		*(.note.GNU-stack)
+		*(.data .data.* .gnu.linkonce.d.* .sdata*)
+		*(.bss .sbss .dynbss .dynsbss)
+	}
+}
+
+/*
+ * We must supply the ELF program headers explicitly to get just one
+ * PT_LOAD segment, and set the flags explicitly to make segments read-only.
+ */
+PHDRS
+{
+	text		PT_LOAD		FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */
+	dynamic		PT_DYNAMIC	FLAGS(4);		/* PF_R */
+	note		PT_NOTE		FLAGS(4);		/* PF_R */
+	eh_frame_hdr	PT_GNU_EH_FRAME;
+}
+
+VERSION
+{
+	LINUX_3.17 {
+	global:
+		__kernel_clock_getres;
+		__kernel_clock_gettime;
+		__kernel_gettimeofday;
+	local: *;
+	};
+}
diff --git a/arch/arm/kernel/vdso/vdsomunge.c b/arch/arm/kernel/vdso/vdsomunge.c
new file mode 100644
index 000000000000..823b84d142bc
--- /dev/null
+++ b/arch/arm/kernel/vdso/vdsomunge.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright 2014 Mentor Graphics Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ * vdsomunge - Host program which produces a shared object
+ * architecturally specified to be usable by both soft- and hard-float
+ * programs.
+ *
+ * The Procedure Call Standard for the ARM Architecture (ARM IHI
+ * 0042E) says:
+ *
+ *	6.4.1 VFP and Base Standard Compatibility
+ *
+ *	Code compiled for the VFP calling standard is compatible with
+ *	the base standard (and vice-versa) if no floating-point or
+ *	containerized vector arguments or results are used.
+ *
+ * And ELF for the ARM Architecture (ARM IHI 0044E) (Table 4-2) says:
+ *
+ *	If both EF_ARM_ABI_FLOAT_XXXX bits are clear, conformance to the
+ *	base procedure-call standard is implied.
+ *
+ * The VDSO is built with -msoft-float, as with the rest of the ARM
+ * kernel, and uses no floating point arguments or results.  The build
+ * process will produce a shared object that may or may not have the
+ * EF_ARM_ABI_FLOAT_SOFT flag set (it seems to depend on the binutils
+ * version; binutils starting with 2.24 appears to set it).  The
+ * EF_ARM_ABI_FLOAT_HARD flag should definitely not be set, and this
+ * program will error out if it is.
+ *
+ * If the soft-float flag is set, this program clears it.  That's all
+ * it does.
+ */
+
+#define _GNU_SOURCE
+
+#include <byteswap.h>
+#include <elf.h>
+#include <errno.h>
+#include <error.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+#define HOST_ORDER ELFDATA2LSB
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+#define HOST_ORDER ELFDATA2MSB
+#endif
+
+static const char *outfile;
+
+static void cleanup(void)
+{
+	if (error_message_count > 0 && outfile != NULL)
+		unlink(outfile);
+}
+
+static Elf32_Word read_elf_word(Elf32_Word word, bool swap)
+{
+	return swap ? bswap_32(word) : word;
+}
+
+static Elf32_Half read_elf_half(Elf32_Half half, bool swap)
+{
+	return swap ? bswap_16(half) : half;
+}
+
+static void write_elf_word(Elf32_Word val, Elf32_Word *dst, bool swap)
+{
+	*dst = swap ? bswap_32(val) : val;
+}
+
+int main(int argc, char **argv)
+{
+	const Elf32_Ehdr *inhdr;
+	bool clear_soft_float;
+	const char *infile;
+	Elf32_Word e_flags;
+	const void *inbuf;
+	struct stat stat;
+	void *outbuf;
+	bool swap;
+	int outfd;
+	int infd;
+
+	atexit(cleanup);
+
+	if (argc != 3)
+		error(EXIT_FAILURE, 0, "Usage: %s [infile] [outfile]", argv[0]);
+
+	infile = argv[1];
+	outfile = argv[2];
+
+	infd = open(infile, O_RDONLY);
+	if (infd < 0)
+		error(EXIT_FAILURE, errno, "Cannot open %s", infile);
+
+	if (fstat(infd, &stat) != 0)
+		error(EXIT_FAILURE, errno, "Failed stat for %s", infile);
+
+	inbuf = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, infd, 0);
+	if (inbuf == MAP_FAILED)
+		error(EXIT_FAILURE, errno, "Failed to map %s", infile);
+
+	close(infd);
+
+	inhdr = inbuf;
+
+	if (memcmp(&inhdr->e_ident, ELFMAG, SELFMAG) != 0)
+		error(EXIT_FAILURE, 0, "Not an ELF file");
+
+	if (inhdr->e_ident[EI_CLASS] != ELFCLASS32)
+		error(EXIT_FAILURE, 0, "Unsupported ELF class");
+
+	swap = inhdr->e_ident[EI_DATA] != HOST_ORDER;
+
+	if (read_elf_half(inhdr->e_type, swap) != ET_DYN)
+		error(EXIT_FAILURE, 0, "Not a shared object");
+
+	if (read_elf_half(inhdr->e_machine, swap) != EM_ARM) {
+		error(EXIT_FAILURE, 0, "Unsupported architecture %#x",
+		      inhdr->e_machine);
+	}
+
+	e_flags = read_elf_word(inhdr->e_flags, swap);
+
+	if (EF_ARM_EABI_VERSION(e_flags) != EF_ARM_EABI_VER5) {
+		error(EXIT_FAILURE, 0, "Unsupported EABI version %#x",
+		      EF_ARM_EABI_VERSION(e_flags));
+	}
+
+	if (e_flags & EF_ARM_ABI_FLOAT_HARD)
+		error(EXIT_FAILURE, 0, "Unexpected hard-float flag set in "
+		      "e_flags");
+
+	clear_soft_float = !!(e_flags & EF_ARM_ABI_FLOAT_SOFT);
+
+	outfd = open(outfile, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
+	if (outfd < 0)
+		error(EXIT_FAILURE, errno, "Cannot open %s", outfile);
+
+	if (ftruncate(outfd, stat.st_size) != 0)
+		error(EXIT_FAILURE, errno, "Cannot truncate %s", outfile);
+
+	outbuf = mmap(NULL, stat.st_size, PROT_READ | PROT_WRITE, MAP_SHARED,
+		      outfd, 0);
+	if (outbuf == MAP_FAILED)
+		error(EXIT_FAILURE, errno, "Failed to map %s", outfile);
+
+	close(outfd);
+
+	memcpy(outbuf, inbuf, stat.st_size);
+
+	if (clear_soft_float) {
+		Elf32_Ehdr *outhdr;
+
+		outhdr = outbuf;
+		e_flags &= ~EF_ARM_ABI_FLOAT_SOFT;
+		write_elf_word(e_flags, &outhdr->e_flags, swap);
+
+#ifdef DEBUG
+		printf("%s: cleared soft-float bit in ELF header for %s "
+		       "(%#x => %#x)\n", program_invocation_short_name,
+		       outfile, inhdr->e_flags, outhdr->e_flags);
+#endif
+
+	}
+
+	if (msync(outbuf, stat.st_size, MS_SYNC) != 0)
+		error(EXIT_FAILURE, errno, "Failed to sync %s", outfile);
+
+	return EXIT_SUCCESS;
+}
diff --git a/arch/arm/kernel/vdso/vgettimeofday.c b/arch/arm/kernel/vdso/vgettimeofday.c
new file mode 100644
index 000000000000..7fb4c4954f8a
--- /dev/null
+++ b/arch/arm/kernel/vdso/vgettimeofday.c
@@ -0,0 +1,320 @@
+/*
+ * Copyright 2014 Mentor Graphics Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/compiler.h>
+#include <linux/hrtimer.h>
+#include <linux/time.h>
+#include <asm/arch_timer.h>
+#include <asm/barrier.h>
+#include <asm/bug.h>
+#include <asm/page.h>
+#include <asm/unistd.h>
+#include <asm/vdso_datapage.h>
+
+#ifndef CONFIG_AEABI
+#error This code depends on AEABI system call conventions
+#endif
+
+extern struct vdso_data *__get_datapage(void);
+
+static u32 __vdso_read_begin(const struct vdso_data *vdata)
+{
+	u32 seq;
+repeat:
+	seq = ACCESS_ONCE(vdata->seq_count);
+	if (seq & 1) {
+		cpu_relax();
+		goto repeat;
+	}
+	return seq;
+}
+
+static u32 vdso_read_begin(const struct vdso_data *vdata)
+{
+	u32 seq = __vdso_read_begin(vdata);
+	smp_rmb();
+	return seq;
+}
+
+static int vdso_read_retry(const struct vdso_data *vdata, u32 start)
+{
+	smp_rmb();
+	return vdata->seq_count != start;
+}
+
+static long clock_gettime_fallback(clockid_t _clkid, struct timespec *_ts)
+{
+	register struct timespec *ts asm("r1") = _ts;
+	register clockid_t clkid asm("r0") = _clkid;
+	register long ret asm ("r0");
+	register long nr asm("r7") = __NR_clock_gettime;
+
+	asm volatile(
+	"	swi #0\n"
+	: "=r" (ret)
+	: "r" (clkid), "r" (ts), "r" (nr)
+	: "memory");
+
+	return ret;
+}
+
+static int do_realtime_coarse(struct timespec *ts, struct vdso_data *vdata)
+{
+	u32 seq;
+
+	do {
+		seq = vdso_read_begin(vdata);
+
+		ts->tv_sec = vdata->xtime_coarse_sec;
+		ts->tv_nsec = vdata->xtime_coarse_nsec;
+
+	} while (vdso_read_retry(vdata, seq));
+
+	return 0;
+}
+
+static int do_monotonic_coarse(struct timespec *ts, struct vdso_data *vdata)
+{
+	struct timespec tomono;
+	u32 seq;
+
+	do {
+		seq = vdso_read_begin(vdata);
+
+		ts->tv_sec = vdata->xtime_coarse_sec;
+		ts->tv_nsec = vdata->xtime_coarse_nsec;
+
+		tomono.tv_sec = vdata->wtm_clock_sec;
+		tomono.tv_nsec = vdata->wtm_clock_nsec;
+
+	} while (vdso_read_retry(vdata, seq));
+
+	ts->tv_sec += tomono.tv_sec;
+	timespec_add_ns(ts, tomono.tv_nsec);
+
+	return 0;
+}
+
+#ifdef CONFIG_ARM_ARCH_TIMER
+
+static u64 get_ns(struct vdso_data *vdata)
+{
+	u64 cycle_delta;
+	u64 cycle_now;
+	u64 nsec;
+
+	cycle_now = arch_counter_get_cntvct();
+
+	cycle_delta = (cycle_now - vdata->cs_cycle_last) & vdata->cs_mask;
+
+	nsec = (cycle_delta * vdata->cs_mult) + vdata->xtime_clock_snsec;
+	nsec >>= vdata->cs_shift;
+
+	return nsec;
+}
+
+static int do_realtime(struct timespec *ts, struct vdso_data *vdata)
+{
+	u64 nsecs;
+	u32 seq;
+
+	do {
+		seq = vdso_read_begin(vdata);
+
+		if (vdata->use_syscall)
+			return -1;
+
+		ts->tv_sec = vdata->xtime_clock_sec;
+		nsecs = get_ns(vdata);
+
+	} while (vdso_read_retry(vdata, seq));
+
+	ts->tv_nsec = 0;
+	timespec_add_ns(ts, nsecs);
+
+	return 0;
+}
+
+static int do_monotonic(struct timespec *ts, struct vdso_data *vdata)
+{
+	struct timespec tomono;
+	u64 nsecs;
+	u32 seq;
+
+	do {
+		seq = vdso_read_begin(vdata);
+
+		if (vdata->use_syscall)
+			return -1;
+
+		ts->tv_sec = vdata->xtime_clock_sec;
+		nsecs = get_ns(vdata);
+
+		tomono.tv_sec = vdata->wtm_clock_sec;
+		tomono.tv_nsec = vdata->wtm_clock_nsec;
+
+	} while (vdso_read_retry(vdata, seq));
+
+	ts->tv_sec += tomono.tv_sec;
+	ts->tv_nsec = 0;
+	timespec_add_ns(ts, nsecs + tomono.tv_nsec);
+
+	return 0;
+}
+
+#else /* CONFIG_ARM_ARCH_TIMER */
+
+static int do_realtime(struct timespec *ts, struct vdso_data *vdata)
+{
+	return -1;
+}
+
+static int do_monotonic(struct timespec *ts, struct vdso_data *vdata)
+{
+	return -1;
+}
+
+#endif /* CONFIG_ARM_ARCH_TIMER */
+
+int __kernel_clock_gettime(clockid_t clkid, struct timespec *ts)
+{
+	struct vdso_data *vdata;
+	int ret = -1;
+
+	vdata = __get_datapage();
+
+	switch (clkid) {
+	case CLOCK_REALTIME_COARSE:
+		ret = do_realtime_coarse(ts, vdata);
+		break;
+	case CLOCK_MONOTONIC_COARSE:
+		ret = do_monotonic_coarse(ts, vdata);
+		break;
+	case CLOCK_REALTIME:
+		ret = do_realtime(ts, vdata);
+		break;
+	case CLOCK_MONOTONIC:
+		ret = do_monotonic(ts, vdata);
+		break;
+	default:
+		break;
+	}
+
+	if (ret)
+		ret = clock_gettime_fallback(clkid, ts);
+
+	return ret;
+}
+
+static long clock_getres_fallback(clockid_t _clkid, struct timespec *_ts)
+{
+	register struct timespec *ts asm("r1") = _ts;
+	register clockid_t clkid asm("r0") = _clkid;
+	register long ret asm ("r0");
+	register long nr asm("r7") = __NR_clock_getres;
+
+	asm volatile(
+	"	swi #0\n"
+	: "=r" (ret)
+	: "r" (clkid), "r" (ts), "r" (nr)
+	: "memory");
+
+	return ret;
+}
+
+int __kernel_clock_getres(clockid_t clkid, struct timespec *ts)
+{
+	int ret;
+
+	switch (clkid) {
+	case CLOCK_REALTIME:
+	case CLOCK_MONOTONIC:
+		if (ts) {
+			ts->tv_sec = 0;
+			ts->tv_nsec = MONOTONIC_RES_NSEC;
+		}
+		ret = 0;
+		break;
+	case CLOCK_REALTIME_COARSE:
+	case CLOCK_MONOTONIC_COARSE:
+		if (ts) {
+			ts->tv_sec = 0;
+			ts->tv_nsec = LOW_RES_NSEC;
+		}
+		ret = 0;
+		break;
+	default:
+		ret = clock_getres_fallback(clkid, ts);
+		break;
+	}
+
+	return ret;
+}
+
+static long gettimeofday_fallback(struct timeval *_tv, struct timezone *_tz)
+{
+	register struct timezone *tz asm("r1") = _tz;
+	register struct timeval *tv asm("r0") = _tv;
+	register long ret asm ("r0");
+	register long nr asm("r7") = __NR_gettimeofday;
+
+	asm volatile(
+	"	swi #0\n"
+	: "=r" (ret)
+	: "r" (tv), "r" (tz), "r" (nr)
+	: "memory");
+
+	return ret;
+}
+
+int __kernel_gettimeofday(struct timeval *tv, struct timezone *tz)
+{
+	struct timespec ts;
+	struct vdso_data *vdata;
+	int ret;
+
+	vdata = __get_datapage();
+
+	ret = do_realtime(&ts, vdata);
+	if (ret)
+		return gettimeofday_fallback(tv, tz);
+
+	if (tv) {
+		tv->tv_sec = ts.tv_sec;
+		tv->tv_usec = ts.tv_nsec / 1000;
+	}
+	if (tz) {
+		tz->tz_minuteswest = vdata->tz_minuteswest;
+		tz->tz_dsttime = vdata->tz_dsttime;
+	}
+
+	return ret;
+}
+
+/* Avoid unresolved references emitted by GCC */
+
+void __aeabi_unwind_cpp_pr0(void)
+{
+}
+
+void __aeabi_unwind_cpp_pr1(void)
+{
+}
+
+void __aeabi_unwind_cpp_pr2(void)
+{
+}
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH v7 8/9] ARM: vdso initialization, mapping, and synchronization
  2014-06-23  3:11 [PATCH v7 0/9] ARM: VDSO Nathan Lynch
                   ` (6 preceding siblings ...)
  2014-06-23  3:11 ` [PATCH v7 7/9] ARM: add vdso user-space code Nathan Lynch
@ 2014-06-23  3:11 ` Nathan Lynch
  2014-06-30 21:37   ` Andy Lutomirski
  2014-06-23  3:11 ` [PATCH v7 9/9] ARM: add CONFIG_VDSO Kconfig and Makefile bits Nathan Lynch
                   ` (3 subsequent siblings)
  11 siblings, 1 reply; 76+ messages in thread
From: Nathan Lynch @ 2014-06-23  3:11 UTC (permalink / raw)
  To: linux-arm-kernel

Initialize the vdso page list at boot, install the vdso mapping at
exec time, and update the data page during timer ticks.  This code is
not built if CONFIG_VDSO is not enabled.

Account for the vdso length when randomizing the offset from the
stack.  The vdso is placed immediately following the sigpage with a
separate install_special_mapping call in arm_install_vdso.

Signed-off-by: Nathan Lynch <nathan_lynch@mentor.com>
---
 arch/arm/kernel/process.c |  13 +++-
 arch/arm/kernel/vdso.c    | 168 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 179 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm/kernel/vdso.c

diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 40445fb71ac9..39b0d68aa068 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -520,6 +520,7 @@ extern struct page *get_signal_page(void);
 int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 {
 	struct mm_struct *mm = current->mm;
+	unsigned long npages;
 	unsigned long addr;
 	unsigned long hint;
 	int ret;
@@ -529,9 +530,11 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 	if (!signal_page)
 		return -ENOMEM;
 
+	npages = (vdso_mapping_len >> PAGE_SHIFT) + 1;
+
 	down_write(&mm->mmap_sem);
-	hint = vdso_addr(mm, 1);
-	addr = get_unmapped_area(NULL, hint, PAGE_SIZE, 0, 0);
+	hint = vdso_addr(mm, npages);
+	addr = get_unmapped_area(NULL, hint, npages, 0, 0);
 	if (IS_ERR_VALUE(addr)) {
 		ret = addr;
 		goto up_fail;
@@ -544,6 +547,12 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 	if (ret == 0)
 		mm->context.sigpage = addr;
 
+	/* Unlike the sigpage, failure to install the vdso is unlikely
+	 * to be fatal to the process, so no error check needed
+	 * here.
+	 */
+	arm_install_vdso(mm, addr + PAGE_SIZE);
+
  up_fail:
 	up_write(&mm->mmap_sem);
 	return ret;
diff --git a/arch/arm/kernel/vdso.c b/arch/arm/kernel/vdso.c
new file mode 100644
index 000000000000..0cfd25f09adf
--- /dev/null
+++ b/arch/arm/kernel/vdso.c
@@ -0,0 +1,168 @@
+/*
+ * Adapted from arm64 version.
+ *
+ * Copyright (C) 2012 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/timekeeper_internal.h>
+#include <linux/vmalloc.h>
+
+#include <asm/barrier.h>
+#include <asm/cacheflush.h>
+#include <asm/page.h>
+#include <asm/vdso.h>
+#include <asm/vdso_datapage.h>
+
+static struct page **vdso_pagelist;
+
+unsigned long vdso_mapping_len __read_mostly;
+
+/*
+ * The vDSO data page.
+ */
+static union vdso_data_store vdso_data_store __page_aligned_data;
+static struct vdso_data *vdso_data = &vdso_data_store.data;
+
+static int __init vdso_init(void)
+{
+	unsigned long vdso_pages;
+	int i;
+
+	if (memcmp(&vdso_start, "\177ELF", 4)) {
+		pr_err("vDSO is not a valid ELF object!\n");
+		return -ENOEXEC;
+	}
+
+	vdso_pages = (&vdso_end - &vdso_start) >> PAGE_SHIFT;
+	pr_debug("vdso: %ld code pages at base %p\n", vdso_pages, &vdso_start);
+
+	/* Allocate the vDSO pagelist, plus a page for the data. */
+	vdso_pagelist = kcalloc(vdso_pages + 1, sizeof(struct page *),
+				GFP_KERNEL);
+	if (vdso_pagelist == NULL)
+		return -ENOMEM;
+
+	/* Grab the vDSO data page. */
+	vdso_pagelist[0] = virt_to_page(vdso_data);
+
+	/* Grab the vDSO code pages. */
+	for (i = 0; i < vdso_pages; i++)
+		vdso_pagelist[i + 1] = virt_to_page(&vdso_start + i * PAGE_SIZE);
+
+	/* Precompute the mapping size */
+	vdso_mapping_len = (vdso_pages + 1) << PAGE_SHIFT;
+
+	return 0;
+}
+arch_initcall(vdso_init);
+
+/* assumes mmap_sem is write-locked */
+void arm_install_vdso(struct mm_struct *mm, unsigned long addr)
+{
+	int ret;
+
+	mm->context.vdso = ~0UL;
+
+	if (vdso_pagelist == NULL)
+		return;
+
+	/*
+	 * Put vDSO base into mm struct before calling
+	 * install_special_mapping so the perf counter mmap tracking
+	 * code will recognise it as a vDSO.
+	 */
+	mm->context.vdso = addr;
+
+	ret = install_special_mapping(mm, addr, vdso_mapping_len,
+				      VM_READ|VM_EXEC|
+				      VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
+				      vdso_pagelist);
+	if (ret) {
+		pr_notice_once("%s: install_special_mapping failed (%d)\n",
+			       __func__, ret);
+		mm->context.vdso = ~0UL;
+		return;
+	}
+}
+
+static void vdso_write_begin(struct vdso_data *vdata)
+{
+	++vdso_data->seq_count;
+	smp_wmb();
+}
+
+static void vdso_write_end(struct vdso_data *vdata)
+{
+	smp_wmb();
+	++vdso_data->seq_count;
+}
+
+/**
+ * update_vsyscall - update the vdso data page
+ *
+ * Increment the sequence counter, making it odd, indicating to
+ * userspace that an update is in progress.  Update the fields used
+ * for coarse clocks and, if the architected system timer is in use,
+ * the fields used for high precision clocks.  Increment the sequence
+ * counter again, making it even, indicating to userspace that the
+ * update is finished.
+ *
+ * Userspace is expected to sample seq_count before reading any other
+ * fields from the data page.  If seq_count is odd, userspace is
+ * expected to wait until it becomes even.  After copying data from
+ * the page, userspace must sample seq_count again; if it has changed
+ * from its previous value, userspace must retry the whole sequence.
+ *
+ * Calls to update_vsyscall are serialized by the timekeeping core.
+ */
+void update_vsyscall(struct timekeeper *tk)
+{
+	struct timespec xtime_coarse;
+	struct timespec *wtm = &tk->wall_to_monotonic;
+	bool use_syscall = strcmp(tk->clock->name, "arch_sys_counter");
+
+	vdso_write_begin(vdso_data);
+
+	xtime_coarse = __current_kernel_time();
+	vdso_data->use_syscall			= use_syscall;
+	vdso_data->xtime_coarse_sec		= xtime_coarse.tv_sec;
+	vdso_data->xtime_coarse_nsec		= xtime_coarse.tv_nsec;
+	vdso_data->wtm_clock_sec		= wtm->tv_sec;
+	vdso_data->wtm_clock_nsec		= wtm->tv_nsec;
+
+	if (!use_syscall) {
+		vdso_data->cs_cycle_last	= tk->cycle_last;
+		vdso_data->xtime_clock_sec	= tk->xtime_sec;
+		vdso_data->xtime_clock_snsec	= tk->xtime_nsec;
+		vdso_data->cs_mult		= tk->mult;
+		vdso_data->cs_shift		= tk->shift;
+		vdso_data->cs_mask		= tk->clock->mask;
+	}
+
+	vdso_write_end(vdso_data);
+
+	flush_dcache_page(virt_to_page(vdso_data));
+}
+
+void update_vsyscall_tz(void)
+{
+	vdso_data->tz_minuteswest	= sys_tz.tz_minuteswest;
+	vdso_data->tz_dsttime		= sys_tz.tz_dsttime;
+	flush_dcache_page(virt_to_page(vdso_data));
+}
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH v7 9/9] ARM: add CONFIG_VDSO Kconfig and Makefile bits
  2014-06-23  3:11 [PATCH v7 0/9] ARM: VDSO Nathan Lynch
                   ` (7 preceding siblings ...)
  2014-06-23  3:11 ` [PATCH v7 8/9] ARM: vdso initialization, mapping, and synchronization Nathan Lynch
@ 2014-06-23  3:11 ` Nathan Lynch
  2014-06-27  8:51 ` [PATCH v7 0/9] ARM: VDSO Jan Glauber
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 76+ messages in thread
From: Nathan Lynch @ 2014-06-23  3:11 UTC (permalink / raw)
  To: linux-arm-kernel

Allow users to enable the vdso in Kconfig; include the vdso in the
build if CONFIG_VDSO is enabled.

Signed-off-by: Nathan Lynch <nathan_lynch@mentor.com>
---
 arch/arm/kernel/Makefile |  1 +
 arch/arm/mm/Kconfig      | 15 +++++++++++++++
 2 files changed, 16 insertions(+)

diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 38ddd9f83d0e..87d4cdc3f3f9 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -86,6 +86,7 @@ obj-$(CONFIG_PERF_EVENTS)	+= perf_regs.o
 obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event.o perf_event_cpu.o
 AFLAGS_iwmmxt.o			:= -Wa,-mcpu=iwmmxt
 obj-$(CONFIG_ARM_CPU_TOPOLOGY)  += topology.o
+obj-$(CONFIG_VDSO)		+= vdso.o vdso/
 
 ifneq ($(CONFIG_ARCH_EBSA110),y)
   obj-y		+= io.o
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index eda0dd0ab97b..616f46794502 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -824,6 +824,21 @@ config KUSER_HELPERS
 	  Say N here only if you are absolutely certain that you do not
 	  need these helpers; otherwise, the safe option is to say Y.
 
+config VDSO
+	bool "Enable vDSO for acceleration of some system calls"
+	depends on AEABI && MMU
+	default y if ARM_ARCH_TIMER
+	select GENERIC_TIME_VSYSCALL
+	help
+	  Place in the process address space an ELF shared object
+	  providing fast implementations of several system calls,
+	  including gettimeofday and clock_gettime.  Systems that
+	  implement the ARM architected timer will receive maximum
+	  benefit.
+
+	  You must have glibc 2.20 or later for programs to seamlessly
+	  take advantage of this.
+
 config DMA_CACHE_RWFO
 	bool "Enable read/write for ownership DMA cache maintenance"
 	depends on CPU_V6K && SMP
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH v7 0/9] ARM: VDSO
  2014-06-23  3:11 [PATCH v7 0/9] ARM: VDSO Nathan Lynch
                   ` (8 preceding siblings ...)
  2014-06-23  3:11 ` [PATCH v7 9/9] ARM: add CONFIG_VDSO Kconfig and Makefile bits Nathan Lynch
@ 2014-06-27  8:51 ` Jan Glauber
  2014-06-27  8:57   ` Russell King - ARM Linux
                     ` (2 more replies)
  2014-06-30  8:12 ` Ard Biesheuvel
  2014-06-30 14:40 ` Will Deacon
  11 siblings, 3 replies; 76+ messages in thread
From: Jan Glauber @ 2014-06-27  8:51 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Jun 22, 2014 at 10:11:49PM -0500, Nathan Lynch wrote:
> Provide fast userspace implementations of gettimeofday and
> clock_gettime on systems that implement the generic timers extension
> defined in ARMv7.  This follows the example of arm64 in conception but
> significantly differs in some aspects of the implementation (C vs
> assembly, mainly).

Hi Nathan,

applying your patches I get the following compile error under Ubuntu 12.04:

  CC      arch/arm/kernel/vdso.o
  LDS     arch/arm/kernel/vdso/vdso.lds
  CC      arch/arm/kernel/vdso/vgettimeofday.o
  AS      arch/arm/kernel/vdso/datapage.o
  VDSOL   arch/arm/kernel/vdso/vdso.so.raw
  HOSTCC  arch/arm/kernel/vdso/vdsomunge
arch/arm/kernel/vdso/vdsomunge.c: In function ?main?:
arch/arm/kernel/vdso/vdsomunge.c:152:16: error: ?EF_ARM_ABI_FLOAT_HARD? undeclared (first use in this function)
arch/arm/kernel/vdso/vdsomunge.c:152:16: note: each undeclared identifier is reported only once for each function it appears in
arch/arm/kernel/vdso/vdsomunge.c:156:34: error: ?EF_ARM_ABI_FLOAT_SOFT? undeclared (first use in this function)
make[2]: *** [arch/arm/kernel/vdso/vdsomunge] Error 1
make[1]: *** [arch/arm/kernel/vdso] Error 2
make: *** [arch/arm/kernel] Error 2

Looks like the libc dev is too old (EF_ARM_ABI_FLOAT_* not in /usr/include/elf.h).
On a more recent Ubuntu it compiles fine. Not sure how to solve this, maybe disable
vdso if the libc is too old?

Regards, Jan

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 0/9] ARM: VDSO
  2014-06-27  8:51 ` [PATCH v7 0/9] ARM: VDSO Jan Glauber
@ 2014-06-27  8:57   ` Russell King - ARM Linux
  2014-06-27  9:41     ` Ard Biesheuvel
  2014-06-27 16:00   ` Nathan Lynch
  2014-06-30 16:03   ` Andy Lutomirski
  2 siblings, 1 reply; 76+ messages in thread
From: Russell King - ARM Linux @ 2014-06-27  8:57 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jun 27, 2014 at 10:51:27AM +0200, Jan Glauber wrote:
> On Sun, Jun 22, 2014 at 10:11:49PM -0500, Nathan Lynch wrote:
> > Provide fast userspace implementations of gettimeofday and
> > clock_gettime on systems that implement the generic timers extension
> > defined in ARMv7.  This follows the example of arm64 in conception but
> > significantly differs in some aspects of the implementation (C vs
> > assembly, mainly).
> 
> Hi Nathan,
> 
> applying your patches I get the following compile error under Ubuntu 12.04:
> 
>   CC      arch/arm/kernel/vdso.o
>   LDS     arch/arm/kernel/vdso/vdso.lds
>   CC      arch/arm/kernel/vdso/vgettimeofday.o
>   AS      arch/arm/kernel/vdso/datapage.o
>   VDSOL   arch/arm/kernel/vdso/vdso.so.raw
>   HOSTCC  arch/arm/kernel/vdso/vdsomunge
> arch/arm/kernel/vdso/vdsomunge.c: In function ?main?:
> arch/arm/kernel/vdso/vdsomunge.c:152:16: error: ?EF_ARM_ABI_FLOAT_HARD? undeclared (first use in this function)
> arch/arm/kernel/vdso/vdsomunge.c:152:16: note: each undeclared identifier is reported only once for each function it appears in
> arch/arm/kernel/vdso/vdsomunge.c:156:34: error: ?EF_ARM_ABI_FLOAT_SOFT? undeclared (first use in this function)
> make[2]: *** [arch/arm/kernel/vdso/vdsomunge] Error 1
> make[1]: *** [arch/arm/kernel/vdso] Error 2
> make: *** [arch/arm/kernel] Error 2
> 
> Looks like the libc dev is too old (EF_ARM_ABI_FLOAT_* not in
> /usr/include/elf.h). On a more recent Ubuntu it compiles fine.
> Not sure how to solve this, maybe disable vdso if the libc is too old?

This is what really concerns me about the VDSO.  It adds an additional
dependence on the C library in order to build the kernel.  What if you
don't have a C library in your cross-build setup (I don't.)

Until that is solved, the VDSO support is not going in, as it will
effectively render the kernel unbuildable for me.

-- 
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 0/9] ARM: VDSO
  2014-06-27  8:57   ` Russell King - ARM Linux
@ 2014-06-27  9:41     ` Ard Biesheuvel
  2014-06-27  9:46       ` Russell King - ARM Linux
  0 siblings, 1 reply; 76+ messages in thread
From: Ard Biesheuvel @ 2014-06-27  9:41 UTC (permalink / raw)
  To: linux-arm-kernel

On 27 June 2014 10:57, Russell King - ARM Linux <linux@arm.linux.org.uk> wrote:
> On Fri, Jun 27, 2014 at 10:51:27AM +0200, Jan Glauber wrote:
>> On Sun, Jun 22, 2014 at 10:11:49PM -0500, Nathan Lynch wrote:
>> > Provide fast userspace implementations of gettimeofday and
>> > clock_gettime on systems that implement the generic timers extension
>> > defined in ARMv7.  This follows the example of arm64 in conception but
>> > significantly differs in some aspects of the implementation (C vs
>> > assembly, mainly).
>>
>> Hi Nathan,
>>
>> applying your patches I get the following compile error under Ubuntu 12.04:
>>
>>   CC      arch/arm/kernel/vdso.o
>>   LDS     arch/arm/kernel/vdso/vdso.lds
>>   CC      arch/arm/kernel/vdso/vgettimeofday.o
>>   AS      arch/arm/kernel/vdso/datapage.o
>>   VDSOL   arch/arm/kernel/vdso/vdso.so.raw
>>   HOSTCC  arch/arm/kernel/vdso/vdsomunge
>> arch/arm/kernel/vdso/vdsomunge.c: In function ?main?:
>> arch/arm/kernel/vdso/vdsomunge.c:152:16: error: ?EF_ARM_ABI_FLOAT_HARD? undeclared (first use in this function)
>> arch/arm/kernel/vdso/vdsomunge.c:152:16: note: each undeclared identifier is reported only once for each function it appears in
>> arch/arm/kernel/vdso/vdsomunge.c:156:34: error: ?EF_ARM_ABI_FLOAT_SOFT? undeclared (first use in this function)
>> make[2]: *** [arch/arm/kernel/vdso/vdsomunge] Error 1
>> make[1]: *** [arch/arm/kernel/vdso] Error 2
>> make: *** [arch/arm/kernel] Error 2
>>
>> Looks like the libc dev is too old (EF_ARM_ABI_FLOAT_* not in
>> /usr/include/elf.h). On a more recent Ubuntu it compiles fine.
>> Not sure how to solve this, maybe disable vdso if the libc is too old?
>

It appears that the EF_ARM_ABI_FLOAT_[SOFT|HARD] defines are just renames of

#define EF_ARM_SOFT_FLOAT       0x200
#define EF_ARM_VFP_FLOAT        0x400

so perhaps use those instead?

> This is what really concerns me about the VDSO.  It adds an additional
> dependence on the C library in order to build the kernel.  What if you
> don't have a C library in your cross-build setup (I don't.)
>

This is a host tool, so this is about the host libc not the target libc.

-- 
Ard.


> Until that is solved, the VDSO support is not going in, as it will
> effectively render the kernel unbuildable for me.
>
> --
> FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
> improving, and getting towards what was expected from it.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 0/9] ARM: VDSO
  2014-06-27  9:41     ` Ard Biesheuvel
@ 2014-06-27  9:46       ` Russell King - ARM Linux
  2014-06-27 17:01         ` Nathan Lynch
  0 siblings, 1 reply; 76+ messages in thread
From: Russell King - ARM Linux @ 2014-06-27  9:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jun 27, 2014 at 11:41:46AM +0200, Ard Biesheuvel wrote:
> It appears that the EF_ARM_ABI_FLOAT_[SOFT|HARD] defines are just renames of
> 
> #define EF_ARM_SOFT_FLOAT       0x200
> #define EF_ARM_VFP_FLOAT        0x400
> 
> so perhaps use those instead?

Or maybe provide our own definitions so we're not reliant on the host
environment providing the correct definitions for these.

> > This is what really concerns me about the VDSO.  It adds an additional
> > dependence on the C library in order to build the kernel.  What if you
> > don't have a C library in your cross-build setup (I don't.)
> >
> 
> This is a host tool, so this is about the host libc not the target libc.

It still sounds pretty fragile.

-- 
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 0/9] ARM: VDSO
  2014-06-27  8:51 ` [PATCH v7 0/9] ARM: VDSO Jan Glauber
  2014-06-27  8:57   ` Russell King - ARM Linux
@ 2014-06-27 16:00   ` Nathan Lynch
  2014-06-30 16:03   ` Andy Lutomirski
  2 siblings, 0 replies; 76+ messages in thread
From: Nathan Lynch @ 2014-06-27 16:00 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/27/2014 03:51 AM, Jan Glauber wrote:
> On Sun, Jun 22, 2014 at 10:11:49PM -0500, Nathan Lynch wrote:
>> Provide fast userspace implementations of gettimeofday and
>> clock_gettime on systems that implement the generic timers extension
>> defined in ARMv7.  This follows the example of arm64 in conception but
>> significantly differs in some aspects of the implementation (C vs
>> assembly, mainly).
> 
> Hi Nathan,
> 
> applying your patches I get the following compile error under Ubuntu 12.04:
> 
>   CC      arch/arm/kernel/vdso.o
>   LDS     arch/arm/kernel/vdso/vdso.lds
>   CC      arch/arm/kernel/vdso/vgettimeofday.o
>   AS      arch/arm/kernel/vdso/datapage.o
>   VDSOL   arch/arm/kernel/vdso/vdso.so.raw
>   HOSTCC  arch/arm/kernel/vdso/vdsomunge
> arch/arm/kernel/vdso/vdsomunge.c: In function ?main?:
> arch/arm/kernel/vdso/vdsomunge.c:152:16: error: ?EF_ARM_ABI_FLOAT_HARD? undeclared (first use in this function)
> arch/arm/kernel/vdso/vdsomunge.c:152:16: note: each undeclared identifier is reported only once for each function it appears in
> arch/arm/kernel/vdso/vdsomunge.c:156:34: error: ?EF_ARM_ABI_FLOAT_SOFT? undeclared (first use in this function)
> make[2]: *** [arch/arm/kernel/vdso/vdsomunge] Error 1
> make[1]: *** [arch/arm/kernel/vdso] Error 2
> make: *** [arch/arm/kernel] Error 2
> 
> Looks like the libc dev is too old (EF_ARM_ABI_FLOAT_* not in /usr/include/elf.h).
> On a more recent Ubuntu it compiles fine. Not sure how to solve this, maybe disable
> vdso if the libc is too old?

We should just define some of the needed ELF constants in the tool if
the host <elf.h> lacks them.  EF_ARM_ABI_FLOAT_HARD/SOFT were added in
2012, EF_ARM_EABI_VER5 in 2009... everything else the tool uses has been
there for twelve years or more.

Thanks for the report -- please try the below?


diff --git a/arch/arm/kernel/vdso/vdsomunge.c
b/arch/arm/kernel/vdso/vdsomunge.c
index 823b84d142bc..b586ef699fb8 100644
--- a/arch/arm/kernel/vdso/vdsomunge.c
+++ b/arch/arm/kernel/vdso/vdsomunge.c
@@ -67,6 +67,21 @@
 #define HOST_ORDER ELFDATA2MSB
 #endif

+/* Some of the ELF constants we'd like to use were added to <elf.h>
+ * relatively recently.
+ */
+#ifndef EF_ARM_EABI_VER5
+#define EF_ARM_EABI_VER5 0x05000000
+#endif
+
+#ifndef EF_ARM_ABI_FLOAT_SOFT
+#define EF_ARM_ABI_FLOAT_SOFT 0x200
+#endif
+
+#ifndef EF_ARM_ABI_FLOAT_HARD
+#define EF_ARM_ABI_FLOAT_HARD 0x400
+#endif
+
 static const char *outfile;

 static void cleanup(void)

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH v7 0/9] ARM: VDSO
  2014-06-27  9:46       ` Russell King - ARM Linux
@ 2014-06-27 17:01         ` Nathan Lynch
  2014-06-28  9:42           ` Russell King - ARM Linux
  0 siblings, 1 reply; 76+ messages in thread
From: Nathan Lynch @ 2014-06-27 17:01 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/27/2014 04:46 AM, Russell King - ARM Linux wrote:
> On Fri, Jun 27, 2014 at 11:41:46AM +0200, Ard Biesheuvel wrote:
>> It appears that the EF_ARM_ABI_FLOAT_[SOFT|HARD] defines are just renames of
>>
>> #define EF_ARM_SOFT_FLOAT       0x200
>> #define EF_ARM_VFP_FLOAT        0x400
>>
>> so perhaps use those instead?
> 
> Or maybe provide our own definitions so we're not reliant on the host
> environment providing the correct definitions for these.

Right.

> 
>>> This is what really concerns me about the VDSO.  It adds an additional
>>> dependence on the C library in order to build the kernel.  What if you
>>> don't have a C library in your cross-build setup (I don't.)
>>>
>>
>> This is a host tool, so this is about the host libc not the target libc.
> 
> It still sounds pretty fragile.

Since removing -lgcc from the link (one of the changes from v6 to v7), I
believe the VDSO is not asking more of the toolchain or build
environment than the rest of the kernel does.  I have definitely built
it without a target libc.  Apart from the host program's use of
too-recent ELF constants (now fixed), I would appreciate help
identifying any remaining sources of fragility.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 0/9] ARM: VDSO
  2014-06-27 17:01         ` Nathan Lynch
@ 2014-06-28  9:42           ` Russell King - ARM Linux
  2014-06-28  9:55             ` Russell King - ARM Linux
  2014-06-30  7:43             ` Arnd Bergmann
  0 siblings, 2 replies; 76+ messages in thread
From: Russell King - ARM Linux @ 2014-06-28  9:42 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jun 27, 2014 at 12:01:12PM -0500, Nathan Lynch wrote:
> Since removing -lgcc from the link (one of the changes from v6 to v7), I
> believe the VDSO is not asking more of the toolchain or build
> environment than the rest of the kernel does.  I have definitely built
> it without a target libc.  Apart from the host program's use of
> too-recent ELF constants (now fixed), I would appreciate help
> identifying any remaining sources of fragility.

There's still something wrong:

fs/binfmt_elf.c: In function 'create_elf_tables':
fs/binfmt_elf.c:231:35: error: 'AT_SYSINFO_EHDR' undeclared (first use in this function)
fs/binfmt_elf.c:231:35: note: each undeclared identifier is reported only once for each function it appears in

The problem is the fscking generated includes.  This is going to be a
right pain - Arnd, is there anything which can be done about this?

What's happening is if you try and rebuild a kernel with these patches
applied, you already have an arch/arm/include/generated/asm/auxvec.h
which points at the empty asm-generic version.  This remains after
these patches are applied, so the new include of asm/auxvec.h in
asm/elf.h picks up on the empty version, not the newly introduced
version.

So, the way to get this to build with the minimum of disruption is to
first manually remove arch/arm/include/generated/asm/auxvec.h in the
build tree before running make.

This isn't a vdso problem - it's a kbuild problem, one obviously caused
by not thinking through properly the implications of generating include
files and how to deal with changes in the future like this very scenario.
I think I'd rather get rid of this generated include crap and instead
have explicit include files instead in the kernel tree - that way we
/know/ what the situation is at all times, and make has the proper idea
about the dependencies at all times.

-- 
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 7/9] ARM: add vdso user-space code
  2014-06-23  3:11 ` [PATCH v7 7/9] ARM: add vdso user-space code Nathan Lynch
@ 2014-06-28  9:53   ` Russell King - ARM Linux
  2014-06-28 10:03     ` Russell King - ARM Linux
  2014-06-28 15:19     ` Nathan Lynch
  2014-06-28 15:26   ` Russell King - ARM Linux
  2014-06-30 21:29   ` Andy Lutomirski
  2 siblings, 2 replies; 76+ messages in thread
From: Russell King - ARM Linux @ 2014-06-28  9:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Jun 22, 2014 at 10:11:56PM -0500, Nathan Lynch wrote:
> Place vdso-related user-space code in arch/arm/kernel/vdso/.
> 
> It is almost completely written in C with some assembly helpers to
> load the data page address, sample the counter, and fall back to
> system calls when necessary.
> 
> If CONFIG_ARM_ARCH_TIMER is not enabled, the vdso cannot service
> high-resolution clocks and falls back to syscalls.  Low-resolution
> clocks e.g. CLOCK_REALTIME_COARSE can be serviced regardless.
> 
> Of particular note is that a post-processing step ("vdsomunge") is
> necessary to produce a shared object which is architecturally allowed
> to be used by both soft- and hard-float EABI programs.
> 
> The 2012 edition of the ARM ABI defines Tag_ABI_VFP_args = 3 "Code is
> compatible with both the base and VFP variants; the user did not
> permit non-variadic functions to pass FP parameters/results."
> Unfortunately current toolchains do not support this tag, which is
> ideally what we would use.
> 
> The best available option is to ensure that both EF_ARM_ABI_FLOAT_SOFT
> and EF_ARM_ABI_FLOAT_HARD are unset in the ELF header's e_flags,
> indicating that the shared object is "old" and should be accepted for
> backward compatibility's sake.  While binutils < 2.24 appear to
> produce a vdso.so with both flags clear, 2.24 always sets
> EF_ARM_ABI_FLOAT_SOFT, with no way to inhibit this behavior.  So we
> have to fix things up with a custom post-processing step.
> 
> In fact, the VDSO code in glibc does much less validation (including
> checking these flags) than the code for handling conventional
> file-backed shared libraries, so this is a bit moot unless glibc's
> VDSO code becomes more strict.
> 
> Signed-off-by: Nathan Lynch <nathan_lynch@mentor.com>
> ---
>  arch/arm/kernel/asm-offsets.c        |   5 +
>  arch/arm/kernel/vdso/.gitignore      |   1 +
>  arch/arm/kernel/vdso/Makefile        |  59 +++++++
>  arch/arm/kernel/vdso/checkundef.sh   |   9 +
>  arch/arm/kernel/vdso/datapage.S      |  15 ++
>  arch/arm/kernel/vdso/vdso.S          |  35 ++++
>  arch/arm/kernel/vdso/vdso.lds.S      |  88 ++++++++++
>  arch/arm/kernel/vdso/vdsomunge.c     | 193 +++++++++++++++++++++
>  arch/arm/kernel/vdso/vgettimeofday.c | 320 +++++++++++++++++++++++++++++++++++
>  9 files changed, 725 insertions(+)
>  create mode 100644 arch/arm/kernel/vdso/.gitignore
>  create mode 100644 arch/arm/kernel/vdso/Makefile
>  create mode 100755 arch/arm/kernel/vdso/checkundef.sh
>  create mode 100644 arch/arm/kernel/vdso/datapage.S
>  create mode 100644 arch/arm/kernel/vdso/vdso.S
>  create mode 100644 arch/arm/kernel/vdso/vdso.lds.S
>  create mode 100644 arch/arm/kernel/vdso/vdsomunge.c
>  create mode 100644 arch/arm/kernel/vdso/vgettimeofday.c

One change I would like to see (to stop the directory tree getting soo
deep) is to move this to arch/arm/vdso - just like x86 is arch/x86/vdso.
Was there a pressing reason to have it in arch/arm/kernel ?

-- 
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 0/9] ARM: VDSO
  2014-06-28  9:42           ` Russell King - ARM Linux
@ 2014-06-28  9:55             ` Russell King - ARM Linux
  2014-06-28 14:49               ` Russell King - ARM Linux
  2014-06-30  7:43             ` Arnd Bergmann
  1 sibling, 1 reply; 76+ messages in thread
From: Russell King - ARM Linux @ 2014-06-28  9:55 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Jun 28, 2014 at 10:42:19AM +0100, Russell King - ARM Linux wrote:
> On Fri, Jun 27, 2014 at 12:01:12PM -0500, Nathan Lynch wrote:
> > Since removing -lgcc from the link (one of the changes from v6 to v7), I
> > believe the VDSO is not asking more of the toolchain or build
> > environment than the rest of the kernel does.  I have definitely built
> > it without a target libc.  Apart from the host program's use of
> > too-recent ELF constants (now fixed), I would appreciate help
> > identifying any remaining sources of fragility.
> 
> There's still something wrong:
> 
> fs/binfmt_elf.c: In function 'create_elf_tables':
> fs/binfmt_elf.c:231:35: error: 'AT_SYSINFO_EHDR' undeclared (first use in this function)
> fs/binfmt_elf.c:231:35: note: each undeclared identifier is reported only once for each function it appears in
> 
> The problem is the fscking generated includes.  This is going to be a
> right pain - Arnd, is there anything which can be done about this?

And yes, I see that you've mentioned this in the cover - but I think we
/really/ need this solved before we can merge this series, otherwise
we're likely to get lots of people asking about it.

-- 
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 7/9] ARM: add vdso user-space code
  2014-06-28  9:53   ` Russell King - ARM Linux
@ 2014-06-28 10:03     ` Russell King - ARM Linux
  2014-06-30 15:56       ` Andy Lutomirski
  2014-06-28 15:19     ` Nathan Lynch
  1 sibling, 1 reply; 76+ messages in thread
From: Russell King - ARM Linux @ 2014-06-28 10:03 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Jun 28, 2014 at 10:53:14AM +0100, Russell King - ARM Linux wrote:
> On Sun, Jun 22, 2014 at 10:11:56PM -0500, Nathan Lynch wrote:
> > Place vdso-related user-space code in arch/arm/kernel/vdso/.
> > 
> > It is almost completely written in C with some assembly helpers to
> > load the data page address, sample the counter, and fall back to
> > system calls when necessary.
> > 
> > If CONFIG_ARM_ARCH_TIMER is not enabled, the vdso cannot service
> > high-resolution clocks and falls back to syscalls.  Low-resolution
> > clocks e.g. CLOCK_REALTIME_COARSE can be serviced regardless.
> > 
> > Of particular note is that a post-processing step ("vdsomunge") is
> > necessary to produce a shared object which is architecturally allowed
> > to be used by both soft- and hard-float EABI programs.
> > 
> > The 2012 edition of the ARM ABI defines Tag_ABI_VFP_args = 3 "Code is
> > compatible with both the base and VFP variants; the user did not
> > permit non-variadic functions to pass FP parameters/results."
> > Unfortunately current toolchains do not support this tag, which is
> > ideally what we would use.
> > 
> > The best available option is to ensure that both EF_ARM_ABI_FLOAT_SOFT
> > and EF_ARM_ABI_FLOAT_HARD are unset in the ELF header's e_flags,
> > indicating that the shared object is "old" and should be accepted for
> > backward compatibility's sake.  While binutils < 2.24 appear to
> > produce a vdso.so with both flags clear, 2.24 always sets
> > EF_ARM_ABI_FLOAT_SOFT, with no way to inhibit this behavior.  So we
> > have to fix things up with a custom post-processing step.
> > 
> > In fact, the VDSO code in glibc does much less validation (including
> > checking these flags) than the code for handling conventional
> > file-backed shared libraries, so this is a bit moot unless glibc's
> > VDSO code becomes more strict.
> > 
> > Signed-off-by: Nathan Lynch <nathan_lynch@mentor.com>
> > ---
> >  arch/arm/kernel/asm-offsets.c        |   5 +
> >  arch/arm/kernel/vdso/.gitignore      |   1 +
> >  arch/arm/kernel/vdso/Makefile        |  59 +++++++
> >  arch/arm/kernel/vdso/checkundef.sh   |   9 +
> >  arch/arm/kernel/vdso/datapage.S      |  15 ++
> >  arch/arm/kernel/vdso/vdso.S          |  35 ++++
> >  arch/arm/kernel/vdso/vdso.lds.S      |  88 ++++++++++
> >  arch/arm/kernel/vdso/vdsomunge.c     | 193 +++++++++++++++++++++
> >  arch/arm/kernel/vdso/vgettimeofday.c | 320 +++++++++++++++++++++++++++++++++++
> >  9 files changed, 725 insertions(+)
> >  create mode 100644 arch/arm/kernel/vdso/.gitignore
> >  create mode 100644 arch/arm/kernel/vdso/Makefile
> >  create mode 100755 arch/arm/kernel/vdso/checkundef.sh
> >  create mode 100644 arch/arm/kernel/vdso/datapage.S
> >  create mode 100644 arch/arm/kernel/vdso/vdso.S
> >  create mode 100644 arch/arm/kernel/vdso/vdso.lds.S
> >  create mode 100644 arch/arm/kernel/vdso/vdsomunge.c
> >  create mode 100644 arch/arm/kernel/vdso/vgettimeofday.c
> 
> One change I would like to see (to stop the directory tree getting soo
> deep) is to move this to arch/arm/vdso - just like x86 is arch/x86/vdso.
> Was there a pressing reason to have it in arch/arm/kernel ?

It also looks like there's something missing for vdso_install to work.
arch/x86 has this:

PHONY += vdso_install
vdso_install:
        $(Q)$(MAKE) $(build)=arch/x86/vdso $@

but doesn't list it in the arch help.  I'm sure we can do better on ARM. :)

-- 
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 0/9] ARM: VDSO
  2014-06-28  9:55             ` Russell King - ARM Linux
@ 2014-06-28 14:49               ` Russell King - ARM Linux
  2014-06-30  7:27                 ` Arnd Bergmann
  0 siblings, 1 reply; 76+ messages in thread
From: Russell King - ARM Linux @ 2014-06-28 14:49 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Jun 28, 2014 at 10:55:04AM +0100, Russell King - ARM Linux wrote:
> On Sat, Jun 28, 2014 at 10:42:19AM +0100, Russell King - ARM Linux wrote:
> > On Fri, Jun 27, 2014 at 12:01:12PM -0500, Nathan Lynch wrote:
> > > Since removing -lgcc from the link (one of the changes from v6 to v7), I
> > > believe the VDSO is not asking more of the toolchain or build
> > > environment than the rest of the kernel does.  I have definitely built
> > > it without a target libc.  Apart from the host program's use of
> > > too-recent ELF constants (now fixed), I would appreciate help
> > > identifying any remaining sources of fragility.
> > 
> > There's still something wrong:
> > 
> > fs/binfmt_elf.c: In function 'create_elf_tables':
> > fs/binfmt_elf.c:231:35: error: 'AT_SYSINFO_EHDR' undeclared (first use in this function)
> > fs/binfmt_elf.c:231:35: note: each undeclared identifier is reported only once for each function it appears in
> > 
> > The problem is the fscking generated includes.  This is going to be a
> > right pain - Arnd, is there anything which can be done about this?
> 
> And yes, I see that you've mentioned this in the cover - but I think we
> /really/ need this solved before we can merge this series, otherwise
> we're likely to get lots of people asking about it.

Thinking about this some more - if this can't be resolved by kbuild,
then I think we should add to arch/arm/Kconfig to detect the generated
include file, print a helpful message telling the user how to fix their
build tree, and error out.

-- 
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 7/9] ARM: add vdso user-space code
  2014-06-28  9:53   ` Russell King - ARM Linux
  2014-06-28 10:03     ` Russell King - ARM Linux
@ 2014-06-28 15:19     ` Nathan Lynch
  1 sibling, 0 replies; 76+ messages in thread
From: Nathan Lynch @ 2014-06-28 15:19 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/28/2014 04:53 AM, Russell King - ARM Linux wrote:
> On Sun, Jun 22, 2014 at 10:11:56PM -0500, Nathan Lynch wrote:
>> Place vdso-related user-space code in arch/arm/kernel/vdso/.
>>
>> It is almost completely written in C with some assembly helpers to
>> load the data page address, sample the counter, and fall back to
>> system calls when necessary.
>>
>> If CONFIG_ARM_ARCH_TIMER is not enabled, the vdso cannot service
>> high-resolution clocks and falls back to syscalls.  Low-resolution
>> clocks e.g. CLOCK_REALTIME_COARSE can be serviced regardless.
>>
>> Of particular note is that a post-processing step ("vdsomunge") is
>> necessary to produce a shared object which is architecturally allowed
>> to be used by both soft- and hard-float EABI programs.
>>
>> The 2012 edition of the ARM ABI defines Tag_ABI_VFP_args = 3 "Code is
>> compatible with both the base and VFP variants; the user did not
>> permit non-variadic functions to pass FP parameters/results."
>> Unfortunately current toolchains do not support this tag, which is
>> ideally what we would use.
>>
>> The best available option is to ensure that both EF_ARM_ABI_FLOAT_SOFT
>> and EF_ARM_ABI_FLOAT_HARD are unset in the ELF header's e_flags,
>> indicating that the shared object is "old" and should be accepted for
>> backward compatibility's sake.  While binutils < 2.24 appear to
>> produce a vdso.so with both flags clear, 2.24 always sets
>> EF_ARM_ABI_FLOAT_SOFT, with no way to inhibit this behavior.  So we
>> have to fix things up with a custom post-processing step.
>>
>> In fact, the VDSO code in glibc does much less validation (including
>> checking these flags) than the code for handling conventional
>> file-backed shared libraries, so this is a bit moot unless glibc's
>> VDSO code becomes more strict.
>>
>> Signed-off-by: Nathan Lynch <nathan_lynch@mentor.com>
>> ---
>>  arch/arm/kernel/asm-offsets.c        |   5 +
>>  arch/arm/kernel/vdso/.gitignore      |   1 +
>>  arch/arm/kernel/vdso/Makefile        |  59 +++++++
>>  arch/arm/kernel/vdso/checkundef.sh   |   9 +
>>  arch/arm/kernel/vdso/datapage.S      |  15 ++
>>  arch/arm/kernel/vdso/vdso.S          |  35 ++++
>>  arch/arm/kernel/vdso/vdso.lds.S      |  88 ++++++++++
>>  arch/arm/kernel/vdso/vdsomunge.c     | 193 +++++++++++++++++++++
>>  arch/arm/kernel/vdso/vgettimeofday.c | 320 +++++++++++++++++++++++++++++++++++
>>  9 files changed, 725 insertions(+)
>>  create mode 100644 arch/arm/kernel/vdso/.gitignore
>>  create mode 100644 arch/arm/kernel/vdso/Makefile
>>  create mode 100755 arch/arm/kernel/vdso/checkundef.sh
>>  create mode 100644 arch/arm/kernel/vdso/datapage.S
>>  create mode 100644 arch/arm/kernel/vdso/vdso.S
>>  create mode 100644 arch/arm/kernel/vdso/vdso.lds.S
>>  create mode 100644 arch/arm/kernel/vdso/vdsomunge.c
>>  create mode 100644 arch/arm/kernel/vdso/vgettimeofday.c
> 
> One change I would like to see (to stop the directory tree getting soo
> deep) is to move this to arch/arm/vdso - just like x86 is arch/x86/vdso.
> Was there a pressing reason to have it in arch/arm/kernel ?

No pressing reason.  I think I was just following the example of non-x86
architectures.  I can move it to arch/arm/vdso.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 7/9] ARM: add vdso user-space code
  2014-06-23  3:11 ` [PATCH v7 7/9] ARM: add vdso user-space code Nathan Lynch
  2014-06-28  9:53   ` Russell King - ARM Linux
@ 2014-06-28 15:26   ` Russell King - ARM Linux
  2014-06-28 16:13     ` Nathan Lynch
  2014-06-30 15:59     ` Andy Lutomirski
  2014-06-30 21:29   ` Andy Lutomirski
  2 siblings, 2 replies; 76+ messages in thread
From: Russell King - ARM Linux @ 2014-06-28 15:26 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Jun 22, 2014 at 10:11:56PM -0500, Nathan Lynch wrote:
> Place vdso-related user-space code in arch/arm/kernel/vdso/.
> 
> It is almost completely written in C with some assembly helpers to
> load the data page address, sample the counter, and fall back to
> system calls when necessary.
> 
> If CONFIG_ARM_ARCH_TIMER is not enabled, the vdso cannot service
> high-resolution clocks and falls back to syscalls.  Low-resolution
> clocks e.g. CLOCK_REALTIME_COARSE can be serviced regardless.

Okay, how is this used by userspace?

It seems that on ARM, we generate a dso with these symbols:

DYNAMIC SYMBOL TABLE:
000001e4 l    d  .eh_frame_hdr	00000000              .eh_frame_hdr
00000000 g    DO *ABS*	00000000  LINUX_3.17  LINUX_3.17
000003c4 g    DF .text	00000080  LINUX_3.17  __kernel_clock_getres
00000444 g    DF .text	0000002c  LINUX_3.17  __kernel_gettimeofday
00000298 g    DF .text	0000012c  LINUX_3.17  __kernel_clock_gettime

whereas, x86-64 generates this:

DYNAMIC SYMBOL TABLE:
ffffffffff700330 l    d  .eh_frame_hdr	0000000000000000              .eh_frame_hdr
ffffffffff700600  w   DF .text	00000000000002b9  LINUX_2.6   clock_gettime
0000000000000000 g    DO *ABS*	0000000000000000  LINUX_2.6   LINUX_2.6
ffffffffff7008c0 g    DF .text	000000000000015a  LINUX_2.6   __vdso_gettimeofday
ffffffffff700a40 g    DF .text	000000000000003d  LINUX_2.6   __vdso_getcpu
ffffffffff7008c0  w   DF .text	000000000000015a  LINUX_2.6   gettimeofday
ffffffffff700a20  w   DF .text	0000000000000016  LINUX_2.6   time
ffffffffff700a40  w   DF .text	000000000000003d  LINUX_2.6   getcpu
ffffffffff700600 g    DF .text	00000000000002b9  LINUX_2.6   __vdso_clock_gettime
ffffffffff700a20 g    DF .text	0000000000000016  LINUX_2.6   __vdso_time

hence references to gettimeofday automatically get resolved to the
vdso version without needing C library updates.

Or... do we need a glibc update to make use of this?

-- 
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 7/9] ARM: add vdso user-space code
  2014-06-28 15:26   ` Russell King - ARM Linux
@ 2014-06-28 16:13     ` Nathan Lynch
  2014-06-28 18:12       ` Russell King - ARM Linux
  2014-06-30 15:59     ` Andy Lutomirski
  1 sibling, 1 reply; 76+ messages in thread
From: Nathan Lynch @ 2014-06-28 16:13 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/28/2014 10:26 AM, Russell King - ARM Linux wrote:
> On Sun, Jun 22, 2014 at 10:11:56PM -0500, Nathan Lynch wrote:
>> Place vdso-related user-space code in arch/arm/kernel/vdso/.
>>
>> It is almost completely written in C with some assembly helpers to
>> load the data page address, sample the counter, and fall back to
>> system calls when necessary.
>>
>> If CONFIG_ARM_ARCH_TIMER is not enabled, the vdso cannot service
>> high-resolution clocks and falls back to syscalls.  Low-resolution
>> clocks e.g. CLOCK_REALTIME_COARSE can be serviced regardless.
> 
> Okay, how is this used by userspace?

Primarily it's intended to be transparent to userspace applications;
glibc -- with a patch -- detects the VDSO at startup and binds the
appropriate routines to the VDSO's.

However, even an unpatched glibc makes the VDSO symbols available for
lookup via dlsym, which has been convenient for testing.


> It seems that on ARM, we generate a dso with these symbols:
> 
> DYNAMIC SYMBOL TABLE:
> 000001e4 l    d  .eh_frame_hdr	00000000              .eh_frame_hdr
> 00000000 g    DO *ABS*	00000000  LINUX_3.17  LINUX_3.17
> 000003c4 g    DF .text	00000080  LINUX_3.17  __kernel_clock_getres
> 00000444 g    DF .text	0000002c  LINUX_3.17  __kernel_gettimeofday
> 00000298 g    DF .text	0000012c  LINUX_3.17  __kernel_clock_gettime
> 
> whereas, x86-64 generates this:
> 
> DYNAMIC SYMBOL TABLE:
> ffffffffff700330 l    d  .eh_frame_hdr	0000000000000000              .eh_frame_hdr
> ffffffffff700600  w   DF .text	00000000000002b9  LINUX_2.6   clock_gettime
> 0000000000000000 g    DO *ABS*	0000000000000000  LINUX_2.6   LINUX_2.6
> ffffffffff7008c0 g    DF .text	000000000000015a  LINUX_2.6   __vdso_gettimeofday
> ffffffffff700a40 g    DF .text	000000000000003d  LINUX_2.6   __vdso_getcpu
> ffffffffff7008c0  w   DF .text	000000000000015a  LINUX_2.6   gettimeofday
> ffffffffff700a20  w   DF .text	0000000000000016  LINUX_2.6   time
> ffffffffff700a40  w   DF .text	000000000000003d  LINUX_2.6   getcpu
> ffffffffff700600 g    DF .text	00000000000002b9  LINUX_2.6   __vdso_clock_gettime
> ffffffffff700a20 g    DF .text	0000000000000016  LINUX_2.6   __vdso_time
> 
> hence references to gettimeofday automatically get resolved to the
> vdso version without needing C library updates.

Hmm, I'm not sure.  I had wondered why x86-64's vdso has the aliases
(clock_gettime --> __vdso_clock_gettime).  Most other architectures'
VDSOs don't.


> Or... do we need a glibc update to make use of this?

That is the idea, yes.  You don't have to rebuild applications but glibc
needs to be updated to dispatch its gettimeofday and clock_gettime to
the VDSO.

I'm in the process of refreshing and re-testing that patch.  I posted an
RFC to libc-alpha a few months back:

https://www.sourceware.org/ml/libc-alpha/2014-02/msg00680.html

I should have a new one posted within a couple days.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 7/9] ARM: add vdso user-space code
  2014-06-28 16:13     ` Nathan Lynch
@ 2014-06-28 18:12       ` Russell King - ARM Linux
  2014-06-28 19:45         ` Nathan Lynch
  0 siblings, 1 reply; 76+ messages in thread
From: Russell King - ARM Linux @ 2014-06-28 18:12 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Jun 28, 2014 at 11:13:42AM -0500, Nathan Lynch wrote:
> On 06/28/2014 10:26 AM, Russell King - ARM Linux wrote:
> > On Sun, Jun 22, 2014 at 10:11:56PM -0500, Nathan Lynch wrote:
> >> Place vdso-related user-space code in arch/arm/kernel/vdso/.
> >>
> >> It is almost completely written in C with some assembly helpers to
> >> load the data page address, sample the counter, and fall back to
> >> system calls when necessary.
> >>
> >> If CONFIG_ARM_ARCH_TIMER is not enabled, the vdso cannot service
> >> high-resolution clocks and falls back to syscalls.  Low-resolution
> >> clocks e.g. CLOCK_REALTIME_COARSE can be serviced regardless.
> > 
> > Okay, how is this used by userspace?
> 
> Primarily it's intended to be transparent to userspace applications;
> glibc -- with a patch -- detects the VDSO at startup and binds the
> appropriate routines to the VDSO's.
> 
> However, even an unpatched glibc makes the VDSO symbols available for
> lookup via dlsym, which has been convenient for testing.

It's a shame that the vDSO provided symbols aren't automatically
picked up in place of the glibc versions, because it means probably
many years before the vDSO seriously gets used.

I know that I'm probably many years away from it, even if Ubuntu
adopt it for something recent - I'm rather stuck with 12.04 due to
the move towards requiring 3D GPU acceleration in later versions.
It seems that the choices on ARM now are to either have a crippled
distro through lack of open GPU support, or stick with an old distro
that doesn't require GPUs.

> > hence references to gettimeofday automatically get resolved to the
> > vdso version without needing C library updates.
> 
> Hmm, I'm not sure.  I had wondered why x86-64's vdso has the aliases
> (clock_gettime --> __vdso_clock_gettime).  Most other architectures'
> VDSOs don't.

Yes, and providing them seems to have no useful benefit either, because
they aren't picked up automatically by the linker.

> > Or... do we need a glibc update to make use of this?
> 
> That is the idea, yes.  You don't have to rebuild applications but glibc
> needs to be updated to dispatch its gettimeofday and clock_gettime to
> the VDSO.

Yea, many people aren't going to rebuild glibc just because of this,
me included.  If only there was a way for automatic vdso support.

So, I'm going to have to rely on you to say "yes it works" and to
keep an eye on it in the future in case something breaks.

-- 
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 7/9] ARM: add vdso user-space code
  2014-06-28 18:12       ` Russell King - ARM Linux
@ 2014-06-28 19:45         ` Nathan Lynch
  2014-06-28 20:11           ` Russell King - ARM Linux
  0 siblings, 1 reply; 76+ messages in thread
From: Nathan Lynch @ 2014-06-28 19:45 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/28/2014 01:12 PM, Russell King - ARM Linux wrote:
> On Sat, Jun 28, 2014 at 11:13:42AM -0500, Nathan Lynch wrote:
>> On 06/28/2014 10:26 AM, Russell King - ARM Linux wrote:
>>> On Sun, Jun 22, 2014 at 10:11:56PM -0500, Nathan Lynch wrote:
>>>> Place vdso-related user-space code in arch/arm/kernel/vdso/.
>>>>
>>>> It is almost completely written in C with some assembly helpers to
>>>> load the data page address, sample the counter, and fall back to
>>>> system calls when necessary.
>>>>
>>>> If CONFIG_ARM_ARCH_TIMER is not enabled, the vdso cannot service
>>>> high-resolution clocks and falls back to syscalls.  Low-resolution
>>>> clocks e.g. CLOCK_REALTIME_COARSE can be serviced regardless.
>>>
>>> Okay, how is this used by userspace?
>>
>> Primarily it's intended to be transparent to userspace applications;
>> glibc -- with a patch -- detects the VDSO at startup and binds the
>> appropriate routines to the VDSO's.
>>
>> However, even an unpatched glibc makes the VDSO symbols available for
>> lookup via dlsym, which has been convenient for testing.
> 
> It's a shame that the vDSO provided symbols aren't automatically
> picked up in place of the glibc versions, because it means probably
> many years before the vDSO seriously gets used.
> 
> I know that I'm probably many years away from it, even if Ubuntu
> adopt it for something recent - I'm rather stuck with 12.04 due to
> the move towards requiring 3D GPU acceleration in later versions.
> It seems that the choices on ARM now are to either have a crippled
> distro through lack of open GPU support, or stick with an old distro
> that doesn't require GPUs.

Based on other messages from you on the ML I'm assuming you have an
i.MX6 system in mind?  (Forgive me if I'm wrong.)  On any Cortex-A9 or
-A8 the VDSO isn't going to be any great benefit anyway.  Those CPUs
don't implement the generic timers extension, so only clock_gettime()
with low-resolution clock ids will see a speedup.  And few programs use
those, to my knowledge.

A15, A7, and I'm pretty sure A12 and A17 all implement the timer
extension and will see full benefit.  Some Qualcomm CPUs too, I think.


>>> hence references to gettimeofday automatically get resolved to the
>>> vdso version without needing C library updates.
>>
>> Hmm, I'm not sure.  I had wondered why x86-64's vdso has the aliases
>> (clock_gettime --> __vdso_clock_gettime).  Most other architectures'
>> VDSOs don't.
> 
> Yes, and providing them seems to have no useful benefit either, because
> they aren't picked up automatically by the linker.
> 
>>> Or... do we need a glibc update to make use of this?
>>
>> That is the idea, yes.  You don't have to rebuild applications but glibc
>> needs to be updated to dispatch its gettimeofday and clock_gettime to
>> the VDSO.
> 
> Yea, many people aren't going to rebuild glibc just because of this,
> me included.  If only there was a way for automatic vdso support.
> 
> So, I'm going to have to rely on you to say "yes it works" and to
> keep an eye on it in the future in case something breaks.

Understood.  FWIW I would expect the uptake to be a little more rapid in
OE and Buildroot-type distributions.  The workload I'm interested in
accelerating -- high-volume tracing -- should show up any problems
pretty quickly and obviously.  Not to mention I've got my own set of IMO
unforgiving testcases which I'll be running regularly.

I'll wait a couple days to see what Arnd has to say about the generated
header issue and plan on posting v8 early-to-mid next week.  Thanks.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 7/9] ARM: add vdso user-space code
  2014-06-28 19:45         ` Nathan Lynch
@ 2014-06-28 20:11           ` Russell King - ARM Linux
  2014-06-28 21:35             ` Nathan Lynch
  0 siblings, 1 reply; 76+ messages in thread
From: Russell King - ARM Linux @ 2014-06-28 20:11 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Jun 28, 2014 at 02:45:41PM -0500, Nathan Lynch wrote:
> On 06/28/2014 01:12 PM, Russell King - ARM Linux wrote:
> > I know that I'm probably many years away from it, even if Ubuntu
> > adopt it for something recent - I'm rather stuck with 12.04 due to
> > the move towards requiring 3D GPU acceleration in later versions.
> > It seems that the choices on ARM now are to either have a crippled
> > distro through lack of open GPU support, or stick with an old distro
> > that doesn't require GPUs.
> 
> Based on other messages from you on the ML I'm assuming you have an
> i.MX6 system in mind?  (Forgive me if I'm wrong.)  On any Cortex-A9 or
> -A8 the VDSO isn't going to be any great benefit anyway.  Those CPUs
> don't implement the generic timers extension, so only clock_gettime()
> with low-resolution clock ids will see a speedup.  And few programs use
> those, to my knowledge.
> 
> A15, A7, and I'm pretty sure A12 and A17 all implement the timer
> extension and will see full benefit.  Some Qualcomm CPUs too, I think.

Here's the results from vdsotest... yes on iMX6 as that's the most
advanced bootable system I have:

clock-gettime-monotonic system calls per second: 1601780
clock-gettime-monotonic vdso calls per second:   1600862 (1.00x speedup)
clock-getres-monotonic system calls per second: 3001396
clock-getres-monotonic vdso calls per second:   52163259 (17.38x speedup)
clock-gettime-monotonic-coarse system calls per second: 2824631
clock-gettime-monotonic-coarse vdso calls per second:   13760820 (4.87x speedup)
clock-getres-monotonic-coarse system calls per second: 3166932
clock-getres-monotonic-coarse vdso calls per second:   52111805 (16.45x speedup)
clock-gettime-realtime system calls per second: 1596863
clock-gettime-realtime vdso calls per second:   1590424 (1.00x speedup)
clock-getres-realtime system calls per second: 2993748
clock-getres-realtime vdso calls per second:   52123753 (17.41x speedup)
clock-gettime-realtime-coarse system calls per second: 3007894
clock-gettime-realtime-coarse vdso calls per second:   17081617 (5.68x speedup)
clock-getres-realtime-coarse system calls per second: 3072073
clock-getres-realtime-coarse vdso calls per second:   49401452 (16.08x speedup)
Note: vDSO version of getcpu not found
getcpu system calls per second: 4902323
getcpu vdso calls per second:   4972290 (1.01x speedup)
Note: vDSO version of getcpu not found
Note: vDSO version of getcpu not found
gettimeofday system calls per second: 1637099
gettimeofday vdso calls per second:   1637573 (1.00x speedup)

-- 
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 7/9] ARM: add vdso user-space code
  2014-06-28 20:11           ` Russell King - ARM Linux
@ 2014-06-28 21:35             ` Nathan Lynch
  2014-06-29  8:34               ` Russell King - ARM Linux
  0 siblings, 1 reply; 76+ messages in thread
From: Nathan Lynch @ 2014-06-28 21:35 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/28/2014 03:11 PM, Russell King - ARM Linux wrote:
> On Sat, Jun 28, 2014 at 02:45:41PM -0500, Nathan Lynch wrote:
>> On 06/28/2014 01:12 PM, Russell King - ARM Linux wrote:
>>> I know that I'm probably many years away from it, even if Ubuntu
>>> adopt it for something recent - I'm rather stuck with 12.04 due to
>>> the move towards requiring 3D GPU acceleration in later versions.
>>> It seems that the choices on ARM now are to either have a crippled
>>> distro through lack of open GPU support, or stick with an old distro
>>> that doesn't require GPUs.
>>
>> Based on other messages from you on the ML I'm assuming you have an
>> i.MX6 system in mind?  (Forgive me if I'm wrong.)  On any Cortex-A9 or
>> -A8 the VDSO isn't going to be any great benefit anyway.  Those CPUs
>> don't implement the generic timers extension, so only clock_gettime()
>> with low-resolution clock ids will see a speedup.  And few programs use
>> those, to my knowledge.
>>
>> A15, A7, and I'm pretty sure A12 and A17 all implement the timer
>> extension and will see full benefit.  Some Qualcomm CPUs too, I think.
> 
> Here's the results from vdsotest... yes on iMX6 as that's the most
> advanced bootable system I have:
> 
> clock-gettime-monotonic system calls per second: 1601780
> clock-gettime-monotonic vdso calls per second:   1600862 (1.00x speedup)
> clock-getres-monotonic system calls per second: 3001396
> clock-getres-monotonic vdso calls per second:   52163259 (17.38x speedup)
> clock-gettime-monotonic-coarse system calls per second: 2824631
> clock-gettime-monotonic-coarse vdso calls per second:   13760820 (4.87x speedup)
> clock-getres-monotonic-coarse system calls per second: 3166932
> clock-getres-monotonic-coarse vdso calls per second:   52111805 (16.45x speedup)
> clock-gettime-realtime system calls per second: 1596863
> clock-gettime-realtime vdso calls per second:   1590424 (1.00x speedup)
> clock-getres-realtime system calls per second: 2993748
> clock-getres-realtime vdso calls per second:   52123753 (17.41x speedup)
> clock-gettime-realtime-coarse system calls per second: 3007894
> clock-gettime-realtime-coarse vdso calls per second:   17081617 (5.68x speedup)
> clock-getres-realtime-coarse system calls per second: 3072073
> clock-getres-realtime-coarse vdso calls per second:   49401452 (16.08x speedup)
> Note: vDSO version of getcpu not found
> getcpu system calls per second: 4902323
> getcpu vdso calls per second:   4972290 (1.01x speedup)
> Note: vDSO version of getcpu not found
> Note: vDSO version of getcpu not found
> gettimeofday system calls per second: 1637099
> gettimeofday vdso calls per second:   1637573 (1.00x speedup)

That's consistent with my results on iMX6.  The reported 1.00x "speedup"
for clock-gettime-monotonic etc indicates the VDSO is falling back to
syscall.

Thanks for testing.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 7/9] ARM: add vdso user-space code
  2014-06-28 21:35             ` Nathan Lynch
@ 2014-06-29  8:34               ` Russell King - ARM Linux
  2014-06-29 15:48                 ` Nathan Lynch
  0 siblings, 1 reply; 76+ messages in thread
From: Russell King - ARM Linux @ 2014-06-29  8:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Jun 28, 2014 at 04:35:12PM -0500, Nathan Lynch wrote:
> That's consistent with my results on iMX6.  The reported 1.00x "speedup"
> for clock-gettime-monotonic etc indicates the VDSO is falling back to
> syscall.
> 
> Thanks for testing.

Here's another issue which cropped up when I ran this patch set through
the autobuilder last night - allnoconfig's now fail with:

mm/memory.c: In function 'gate_vma_init':
mm/memory.c:3410:22: error: 'FIXADDR_USER_START' undeclared (first use in this function)
mm/memory.c:3411:20: error: 'FIXADDR_USER_END' undeclared (first use in this function)
mm/memory.c: In function 'in_gate_area_no_mm':
mm/memory.c:3432:15: error: 'FIXADDR_USER_START' undeclared (first use in this function)
mm/memory.c:3432:46: error: 'FIXADDR_USER_END' undeclared (first use in this function)
make[2]: *** [mm/memory.o] Error 1

Any ideas?

-- 
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 7/9] ARM: add vdso user-space code
  2014-06-29  8:34               ` Russell King - ARM Linux
@ 2014-06-29 15:48                 ` Nathan Lynch
  2014-06-29 16:07                   ` Russell King - ARM Linux
  0 siblings, 1 reply; 76+ messages in thread
From: Nathan Lynch @ 2014-06-29 15:48 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/29/2014 03:34 AM, Russell King - ARM Linux wrote:
> On Sat, Jun 28, 2014 at 04:35:12PM -0500, Nathan Lynch wrote:
>> That's consistent with my results on iMX6.  The reported 1.00x "speedup"
>> for clock-gettime-monotonic etc indicates the VDSO is falling back to
>> syscall.
>>
>> Thanks for testing.
> 
> Here's another issue which cropped up when I ran this patch set through
> the autobuilder last night - allnoconfig's now fail with:
> 
> mm/memory.c: In function 'gate_vma_init':
> mm/memory.c:3410:22: error: 'FIXADDR_USER_START' undeclared (first use in this function)
> mm/memory.c:3411:20: error: 'FIXADDR_USER_END' undeclared (first use in this function)
> mm/memory.c: In function 'in_gate_area_no_mm':
> mm/memory.c:3432:15: error: 'FIXADDR_USER_START' undeclared (first use in this function)
> mm/memory.c:3432:46: error: 'FIXADDR_USER_END' undeclared (first use in this function)
> make[2]: *** [mm/memory.o] Error 1

arch/arm/include/page.h:
#ifdef CONFIG_KUSER_HELPERS
#define __HAVE_ARCH_GATE_AREA 1
#endif

mm/memory.c:
#if !defined(__HAVE_ARCH_GATE_AREA)

#if defined(AT_SYSINFO_EHDR)
static struct vm_area_struct gate_vma;

static int __init gate_vma_init(void)
{
	gate_vma.vm_mm = NULL;
	gate_vma.vm_start = FIXADDR_USER_START;
	gate_vma.vm_end = FIXADDR_USER_END;
...

The vdso patches add an ARM definition for AT_SYSINFO_EHDR.  So when
CONFIG_KUSER_HELPERS=n, this code is pulled in now...

Not sure what the fix would be right now.  I don't understand why there
is this relationship between AT_SYSINFO_EHDR and gate vma code.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 7/9] ARM: add vdso user-space code
  2014-06-29 15:48                 ` Nathan Lynch
@ 2014-06-29 16:07                   ` Russell King - ARM Linux
  2014-06-29 23:04                     ` Nathan Lynch
  2014-06-30 21:33                     ` Andy Lutomirski
  0 siblings, 2 replies; 76+ messages in thread
From: Russell King - ARM Linux @ 2014-06-29 16:07 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Jun 29, 2014 at 10:48:13AM -0500, Nathan Lynch wrote:
> On 06/29/2014 03:34 AM, Russell King - ARM Linux wrote:
> > On Sat, Jun 28, 2014 at 04:35:12PM -0500, Nathan Lynch wrote:
> >> That's consistent with my results on iMX6.  The reported 1.00x "speedup"
> >> for clock-gettime-monotonic etc indicates the VDSO is falling back to
> >> syscall.
> >>
> >> Thanks for testing.
> > 
> > Here's another issue which cropped up when I ran this patch set through
> > the autobuilder last night - allnoconfig's now fail with:
> > 
> > mm/memory.c: In function 'gate_vma_init':
> > mm/memory.c:3410:22: error: 'FIXADDR_USER_START' undeclared (first use in this function)
> > mm/memory.c:3411:20: error: 'FIXADDR_USER_END' undeclared (first use in this function)
> > mm/memory.c: In function 'in_gate_area_no_mm':
> > mm/memory.c:3432:15: error: 'FIXADDR_USER_START' undeclared (first use in this function)
> > mm/memory.c:3432:46: error: 'FIXADDR_USER_END' undeclared (first use in this function)
> > make[2]: *** [mm/memory.o] Error 1
> 
> arch/arm/include/page.h:
> #ifdef CONFIG_KUSER_HELPERS
> #define __HAVE_ARCH_GATE_AREA 1
> #endif
> 
> mm/memory.c:
> #if !defined(__HAVE_ARCH_GATE_AREA)
> 
> #if defined(AT_SYSINFO_EHDR)
> static struct vm_area_struct gate_vma;
> 
> static int __init gate_vma_init(void)
> {
> 	gate_vma.vm_mm = NULL;
> 	gate_vma.vm_start = FIXADDR_USER_START;
> 	gate_vma.vm_end = FIXADDR_USER_END;
> ...
> 
> The vdso patches add an ARM definition for AT_SYSINFO_EHDR.  So when
> CONFIG_KUSER_HELPERS=n, this code is pulled in now...
> 
> Not sure what the fix would be right now.  I don't understand why there
> is this relationship between AT_SYSINFO_EHDR and gate vma code.

Me neither.  It looks like changing those tests for AT_SYSINFO_EHDR to
something like __HAVE_GATE_VMA or CONFIG_HAVE_GATE_VMA would be a good
step, so we can keep this disabled on ARM.  I don't see a need for the
gate VMA stuff just because we have a vDSO.

-- 
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 7/9] ARM: add vdso user-space code
  2014-06-29 16:07                   ` Russell King - ARM Linux
@ 2014-06-29 23:04                     ` Nathan Lynch
  2014-06-30 21:33                     ` Andy Lutomirski
  1 sibling, 0 replies; 76+ messages in thread
From: Nathan Lynch @ 2014-06-29 23:04 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/29/2014 11:07 AM, Russell King - ARM Linux wrote:
> On Sun, Jun 29, 2014 at 10:48:13AM -0500, Nathan Lynch wrote:
>> On 06/29/2014 03:34 AM, Russell King - ARM Linux wrote:
>>> On Sat, Jun 28, 2014 at 04:35:12PM -0500, Nathan Lynch wrote:
>>>> That's consistent with my results on iMX6.  The reported 1.00x "speedup"
>>>> for clock-gettime-monotonic etc indicates the VDSO is falling back to
>>>> syscall.
>>>>
>>>> Thanks for testing.
>>>
>>> Here's another issue which cropped up when I ran this patch set through
>>> the autobuilder last night - allnoconfig's now fail with:
>>>
>>> mm/memory.c: In function 'gate_vma_init':
>>> mm/memory.c:3410:22: error: 'FIXADDR_USER_START' undeclared (first use in this function)
>>> mm/memory.c:3411:20: error: 'FIXADDR_USER_END' undeclared (first use in this function)
>>> mm/memory.c: In function 'in_gate_area_no_mm':
>>> mm/memory.c:3432:15: error: 'FIXADDR_USER_START' undeclared (first use in this function)
>>> mm/memory.c:3432:46: error: 'FIXADDR_USER_END' undeclared (first use in this function)
>>> make[2]: *** [mm/memory.o] Error 1
>>
>> arch/arm/include/page.h:
>> #ifdef CONFIG_KUSER_HELPERS
>> #define __HAVE_ARCH_GATE_AREA 1
>> #endif
>>
>> mm/memory.c:
>> #if !defined(__HAVE_ARCH_GATE_AREA)
>>
>> #if defined(AT_SYSINFO_EHDR)
>> static struct vm_area_struct gate_vma;
>>
>> static int __init gate_vma_init(void)
>> {
>> 	gate_vma.vm_mm = NULL;
>> 	gate_vma.vm_start = FIXADDR_USER_START;
>> 	gate_vma.vm_end = FIXADDR_USER_END;
>> ...
>>
>> The vdso patches add an ARM definition for AT_SYSINFO_EHDR.  So when
>> CONFIG_KUSER_HELPERS=n, this code is pulled in now...
>>
>> Not sure what the fix would be right now.  I don't understand why there
>> is this relationship between AT_SYSINFO_EHDR and gate vma code.
> 
> Me neither.  It looks like changing those tests for AT_SYSINFO_EHDR to
> something like __HAVE_GATE_VMA or CONFIG_HAVE_GATE_VMA would be a good
> step, so we can keep this disabled on ARM.  I don't see a need for the
> gate VMA stuff just because we have a vDSO.

How about the following as an additonal preparatory patch?  It's not as
good as cleaning up interaction between the core mm and architecture code
with respect to the gate vma APIs, but it has the advantage of not
blocking the ARM VDSO code.

(sorry if it's mangled, I swear I'm going to stop using this mail client soon)

============

>From 4ad05345625d6f6a045ebe5ed355e3a2c2272fd4 Mon Sep 17 00:00:00 2001
From: Nathan Lynch <nathan_lynch@mentor.com>
Date: Sun, 29 Jun 2014 17:20:46 -0500
Subject: [PATCH] ARM: provide gate vma API stubs when CONFIG_KUSER_HELPERS
 disabled

If an architecture defines AT_SYSINFO_EHDR and does not define
__HAVE_ARCH_GATE_AREA, code in mm/memory.c (gate_vma_init,
get_gate_vma, etc) is enabled which is unbuildable unless the
architecure provides FIXADDR_USER_START and FIXADDR_USER_END.

This situation can arise with arch/arm with the introduction of VDSO
support, which adds a definition for AT_SYSINFO_EHDR.
__HAVE_ARCH_GATE_AREA is conditional on CONFIG_KUSER_HELPERS, so if
that config option is disabled, the ARM build fails.  We don't want to
enable this code on ARM.

Other architectures (arm64, powerpc, s390, tile) define
__HAVE_ARCH_GATE_AREA unconditionally, and provide stub
implementations of the gate vma APIs.  This avoids building the
default gate vma code in the core mm, which appears to be useful only
for ia64 and user-mode x86.

Make ARM work similarly, except we provide real implementations of the
gate APIs when the kuser helper page is enabled.  When it's disabled,
use stubs like the other architectures.  Define __HAVE_ARCH_GATE_AREA
unconditionally.

Signed-off-by: Nathan Lynch <nathan_lynch@mentor.com>
---
 arch/arm/include/asm/page.h |  2 --
 arch/arm/kernel/process.c   | 20 ++++++++++++++++++--
 2 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
index 4355f0ec44d6..6363f3d1d505 100644
--- a/arch/arm/include/asm/page.h
+++ b/arch/arm/include/asm/page.h
@@ -142,9 +142,7 @@ extern void __cpu_copy_user_highpage(struct page *to, struct page *from,
 #define clear_page(page)	memset((void *)(page), 0, PAGE_SIZE)
 extern void copy_page(void *to, const void *from);
 
-#ifdef CONFIG_KUSER_HELPERS
 #define __HAVE_ARCH_GATE_AREA 1
-#endif
 
 #ifdef CONFIG_ARM_LPAE
 #include <asm/pgtable-3level-types.h>
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 39b0d68aa068..35f4cb54bb14 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -467,9 +467,25 @@ int in_gate_area_no_mm(unsigned long addr)
 	return in_gate_area(NULL, addr);
 }
 #define is_gate_vma(vma)	((vma) == &gate_vma)
-#else
+
+#else /* !CONFIG_KUSER_HELPERS */
+
+struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
+{
+	return NULL;
+}
+
+int in_gate_area(struct mm_struct *mm, unsigned long addr)
+{
+	return 0;
+}
+
+int in_gate_area_no_mm(unsigned long addr)
+{
+	return 0;
+}
 #define is_gate_vma(vma)	0
-#endif
+#endif /* CONFIG_KUSER_HELPERS */
 
 const char *arch_vma_name(struct vm_area_struct *vma)
 {
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH v7 0/9] ARM: VDSO
  2014-06-28 14:49               ` Russell King - ARM Linux
@ 2014-06-30  7:27                 ` Arnd Bergmann
  0 siblings, 0 replies; 76+ messages in thread
From: Arnd Bergmann @ 2014-06-30  7:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Saturday 28 June 2014 15:49:04 Russell King - ARM Linux wrote:
> On Sat, Jun 28, 2014 at 10:55:04AM +0100, Russell King - ARM Linux wrote:
> > On Sat, Jun 28, 2014 at 10:42:19AM +0100, Russell King - ARM Linux wrote:
> > > On Fri, Jun 27, 2014 at 12:01:12PM -0500, Nathan Lynch wrote:
> > > > Since removing -lgcc from the link (one of the changes from v6 to v7), I
> > > > believe the VDSO is not asking more of the toolchain or build
> > > > environment than the rest of the kernel does.  I have definitely built
> > > > it without a target libc.  Apart from the host program's use of
> > > > too-recent ELF constants (now fixed), I would appreciate help
> > > > identifying any remaining sources of fragility.
> > > 
> > > There's still something wrong:
> > > 
> > > fs/binfmt_elf.c: In function 'create_elf_tables':
> > > fs/binfmt_elf.c:231:35: error: 'AT_SYSINFO_EHDR' undeclared (first use in this function)
> > > fs/binfmt_elf.c:231:35: note: each undeclared identifier is reported only once for each function it appears in
> > > 
> > > The problem is the fscking generated includes.  This is going to be a
> > > right pain - Arnd, is there anything which can be done about this?
> > 
> > And yes, I see that you've mentioned this in the cover - but I think we
> > /really/ need this solved before we can merge this series, otherwise
> > we're likely to get lots of people asking about it.
> 
> Thinking about this some more - if this can't be resolved by kbuild,
> then I think we should add to arch/arm/Kconfig to detect the generated
> include file, print a helpful message telling the user how to fix their
> build tree, and error out.

I think there is a way to flag files to be deleted on every build in the
Makefile, I'd have to read up on that. I've run into similar problems
before, also with generated files sometimes not getting removed during
'make clean'.

	Arnd

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 0/9] ARM: VDSO
  2014-06-28  9:42           ` Russell King - ARM Linux
  2014-06-28  9:55             ` Russell King - ARM Linux
@ 2014-06-30  7:43             ` Arnd Bergmann
  2014-06-30 18:27               ` Nathan Lynch
  1 sibling, 1 reply; 76+ messages in thread
From: Arnd Bergmann @ 2014-06-30  7:43 UTC (permalink / raw)
  To: linux-arm-kernel

On Saturday 28 June 2014 10:42:19 Russell King - ARM Linux wrote:
> What's happening is if you try and rebuild a kernel with these patches
> applied, you already have an arch/arm/include/generated/asm/auxvec.h
> which points at the empty asm-generic version.  This remains after
> these patches are applied, so the new include of asm/auxvec.h in
> asm/elf.h picks up on the empty version, not the newly introduced
> version.

One more piece of the puzzle: the top-level Makefile always includes
the headers from the source tree before generated headers, so in theory
this should not be happening. However, for some reason this ends up
as arch/arm/include/generated/asm/auxvec.h rather than
arch/arm/include/generated/uapi/asm/auxvec.h, and the kernel-only
headers get included before any of the uapi headers.

An easy workaround would probably be to add an
arch/arm/include/asm/auxvec.h file that contains only

#include <uapi/asm/auxvec.h>

	Arnd

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 0/9] ARM: VDSO
  2014-06-23  3:11 [PATCH v7 0/9] ARM: VDSO Nathan Lynch
                   ` (9 preceding siblings ...)
  2014-06-27  8:51 ` [PATCH v7 0/9] ARM: VDSO Jan Glauber
@ 2014-06-30  8:12 ` Ard Biesheuvel
  2014-07-01 16:34   ` Nathan Lynch
  2014-06-30 14:40 ` Will Deacon
  11 siblings, 1 reply; 76+ messages in thread
From: Ard Biesheuvel @ 2014-06-30  8:12 UTC (permalink / raw)
  To: linux-arm-kernel

On 23 June 2014 05:11, Nathan Lynch <nathan_lynch@mentor.com> wrote:
> Provide fast userspace implementations of gettimeofday and
> clock_gettime on systems that implement the generic timers extension
> defined in ARMv7.  This follows the example of arm64 in conception but
> significantly differs in some aspects of the implementation (C vs
> assembly, mainly).
>
> Clocks supported:
> - CLOCK_REALTIME
> - CLOCK_MONOTONIC
> - CLOCK_REALTIME_COARSE
> - CLOCK_MONOTONIC_COARSE
>
> This also provides clock_getres (as arm64 does).
>
> getcpu support is planned but not included at this time.
>
> Note that while the high-precision realtime and monotonic clock
> support depends on the generic timers extension, support for
> clock_getres and coarse clocks is independent of the timer
> implementation and is provided unconditionally.
>
> Run-time tested on OMAP5 and i.MX6, verifying that results obtained
> with the vdso are consistent with those obtained from the kernel.  On
> OMAP5 I observe a 3- to 4-fold speedup for gettimeofday /
> CLOCK_REALTIME, with even better (if less interesting) speedups for
> the coarse clock ids and clock_getres.
>
> I've been testing and benchmarking this with some custom test code
> which I have hosted here:
>
> https://github.com/nlynch-mentor/vdsotest
>
> If this series is applied to an already-built tree and
> CONFIG_VDSO is enabled, an incremental build may fail with:
>
>   fs/binfmt_elf.c: In function 'create_elf_tables':
>   fs/binfmt_elf.c:231:35: error: 'AT_SYSINFO_EHDR' undeclared (first use
>   in this function)
>
> This can be worked around by removing
> arch/arm/include/generated/asm/auxvec.h from the build tree.  I
> lean toward attributing this to a Kbuild limitation/bug, but would
> appreciate extra scrutiny on the patch "ARM: miscellaneous vdso
> infrastructure, preparation" to see if there's anything to correct
> there.
>

Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

On Exynos-5250 (Cortex-A15):

clock-gettime-monotonic system calls per second: 1759517
clock-gettime-monotonic vdso calls per second:   6027915 (3.43x speedup)
clock-getres-monotonic system calls per second: 2144055
clock-getres-monotonic vdso calls per second:   82783103 (38.61x speedup)
clock-gettime-monotonic-coarse system calls per second: 1971433
clock-gettime-monotonic-coarse vdso calls per second:   10710734 (5.43x speedup)
clock-getres-monotonic-coarse system calls per second: 2182380
clock-getres-monotonic-coarse vdso calls per second:   76710594 (35.15x speedup)
clock-gettime-realtime system calls per second: 1722524
clock-gettime-realtime vdso calls per second:   6309212 (3.66x speedup)
clock-getres-realtime system calls per second: 2182357
clock-getres-realtime vdso calls per second:   83120713 (38.09x speedup)
clock-gettime-realtime-coarse system calls per second: 2085498
clock-gettime-realtime-coarse vdso calls per second:   11326069 (5.43x speedup)
clock-getres-realtime-coarse system calls per second: 2178266
clock-getres-realtime-coarse vdso calls per second:   76731175 (35.23x speedup)
Note: vDSO version of getcpu not found
getcpu system calls per second: 2645300
getcpu vdso calls per second:   2612154 (0.99x speedup)
Note: vDSO version of getcpu not found
Note: vDSO version of getcpu not found
gettimeofday system calls per second: 1707745
gettimeofday vdso calls per second:   6474501 (3.79x speedup)


Regards,
Ard.


> Changes since v6:
> - Update to 3.16-rc1.
> - Remove -lgcc from link step - need to support GCC installations
>   without libgcc.
> - Force -O2 compilation to prevent GCC from emitting calls to libgcc
>   math routines.
> - Use custom post-processing to clear the EF_ARM_ABI_FLOAT_SOFT flag
>   if set in the ELF header to produce a shared object which is
>   architecturally allowed to be used by both soft- and hard-float
>   code.
> - Consolidate common arch timer code instead of duplicating it.
> - Prevent the VDSO from attempting CP15 access on memory-only
>   architected timer implementations by renaming the clocksource.
>
> Changes since v5:
> - Update to 3.15-rc1.
> - Place vdso at a randomized offset above the stack along with the
>   sigpage.
> - Properly export asm/auxvec.h.
> - Split patch into series for ease of review.
>
> Changes since v4:
> - Map data page at the beginning of the VMA to prevent orphan
>   sections at the end of output invalidating the calculated offset.
> - Move checkundef into cmd_vdsold to avoid spurious rebuilds.
> - Change vdso_init message to pr_debug.
> - Add -fno-stack-protector to cflags.
>
> Changes since v3:
> - Update to 3.14-rc6.
> - Record vdso base in mm context before installing mapping (for the
>   sake of perf_mmap_event).
> - Use a more seqcount-like API for critical sections.  Using seqcount
>   API directly, however, would leak kernel pointers to userspace when
>   lockdep is enabled.
> - Trap instead of looping forever in division-by-zero stubs.
>
> Changes since v2:
> - Update to 3.14-rc4.
> - Make vDSO configurable, depending on AEABI and MMU.
> - Defer shifting of nanosecond component of timespec: fixes observed
>   1ns inconsistencies for CLOCK_REALTIME, CLOCK_MONOTONIC (see
>   45a7905fc48f for arm64 equivalent).
> - Force reload of seq_count when spinning: without a memory clobber
>   after the load of vdata->seq_count, GCC can generate code like this:
>     2f8:   e59c9020        ldr     r9, [ip, #32]
>     2fc:   e3190001        tst     r9, #1
>     300:   1a000033        bne     3d4 <do_realtime+0x104>
>     304:   f57ff05b        dmb     ish
>     308:   e59c3034        ldr     r3, [ip, #52]   ; 0x34
>     ...
>     3d4:   eafffffe        b       3d4 <do_realtime+0x104>
> - Build vdso.so with -lgcc: calls to __lshrdi3, __divsi3 sometimes
>   emitted (especially with -Os).  Override certain libgcc functions to
>   prevent undefined symbols.
> - Do not clear PG_reserved on vdso pages.
> - Remove unnecessary get_page calls.
> - Simplify ELF signature check during init.
> - Use volatile for asm syscall fallbacks.
> - Check whether vdso_pagelist is initialized in arm_install_vdso.
> - Record clocksource mask in data page.
> - Reduce code duplication in do_realtime, do_monotonic.
> - Reduce calculations performed in critical sections.
> - Simplify coarse clock handling.
> - Move datapage load to its own assembly routine.
> - Tune vdso_data layout and tweak field names.
> - Check vdso shared object for undefined symbols during build.
>
> Changes since v1:
> - update to 3.14-rc1
> - ensure cache coherency for data page
> - Document the kernel-to-userspace protocol for vdso data page updates,
>   and note that the timekeeping core prevents concurrent updates.
> - update wall-to-monotonic fields unconditionally
> - move vdso_start, vdso_end declarations to vdso.h
> - correctly build and run when CONFIG_ARM_ARCH_TIMER=n
> - rearrange linker script to avoid overlapping sections when CONFIG_DEBUGINFO=n
> - remove use_syscall checks from coarse clock paths
> - crib BUG_INSTR (0xe7f001f2) from asm/bug.h for text fill
>
> Nathan Lynch (9):
>   clocksource: arm_arch_timer: change clocksource name if CP15
>     unavailable
>   clocksource: arm_arch_timer: enable counter access for 32-bit ARM
>   ARM: arch_timer: remove unused functions
>   arm64: arch_timer: remove unused functions
>   ARM: place sigpage at a random offset above stack
>   ARM: miscellaneous vdso infrastructure, preparation
>   ARM: add vdso user-space code
>   ARM: vdso initialization, mapping, and synchronization
>   ARM: add CONFIG_VDSO Kconfig and Makefile bits
>
>  arch/arm/include/asm/Kbuild          |   1 -
>  arch/arm/include/asm/arch_timer.h    |  25 ---
>  arch/arm/include/asm/elf.h           |  11 ++
>  arch/arm/include/asm/mmu.h           |   3 +
>  arch/arm/include/asm/vdso.h          |  47 +++++
>  arch/arm/include/asm/vdso_datapage.h |  60 +++++++
>  arch/arm/include/uapi/asm/Kbuild     |   1 +
>  arch/arm/include/uapi/asm/auxvec.h   |   7 +
>  arch/arm/kernel/Makefile             |   1 +
>  arch/arm/kernel/asm-offsets.c        |   5 +
>  arch/arm/kernel/process.c            |  56 +++++-
>  arch/arm/kernel/vdso.c               | 168 ++++++++++++++++++
>  arch/arm/kernel/vdso/.gitignore      |   1 +
>  arch/arm/kernel/vdso/Makefile        |  59 +++++++
>  arch/arm/kernel/vdso/checkundef.sh   |   9 +
>  arch/arm/kernel/vdso/datapage.S      |  15 ++
>  arch/arm/kernel/vdso/vdso.S          |  35 ++++
>  arch/arm/kernel/vdso/vdso.lds.S      |  88 ++++++++++
>  arch/arm/kernel/vdso/vdsomunge.c     | 193 +++++++++++++++++++++
>  arch/arm/kernel/vdso/vgettimeofday.c | 320 +++++++++++++++++++++++++++++++++++
>  arch/arm/mm/Kconfig                  |  15 ++
>  arch/arm64/include/asm/arch_timer.h  |  31 ----
>  drivers/clocksource/arm_arch_timer.c |  48 +++++-
>  23 files changed, 1134 insertions(+), 65 deletions(-)
>  create mode 100644 arch/arm/include/asm/vdso.h
>  create mode 100644 arch/arm/include/asm/vdso_datapage.h
>  create mode 100644 arch/arm/include/uapi/asm/auxvec.h
>  create mode 100644 arch/arm/kernel/vdso.c
>  create mode 100644 arch/arm/kernel/vdso/.gitignore
>  create mode 100644 arch/arm/kernel/vdso/Makefile
>  create mode 100755 arch/arm/kernel/vdso/checkundef.sh
>  create mode 100644 arch/arm/kernel/vdso/datapage.S
>  create mode 100644 arch/arm/kernel/vdso/vdso.S
>  create mode 100644 arch/arm/kernel/vdso/vdso.lds.S
>  create mode 100644 arch/arm/kernel/vdso/vdsomunge.c
>  create mode 100644 arch/arm/kernel/vdso/vgettimeofday.c
>
> --
> 1.9.3
>

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 6/9] ARM: miscellaneous vdso infrastructure, preparation
  2014-06-23  3:11 ` [PATCH v7 6/9] ARM: miscellaneous vdso infrastructure, preparation Nathan Lynch
@ 2014-06-30 10:11   ` Arnd Bergmann
  2014-06-30 12:27     ` Nathan Lynch
  0 siblings, 1 reply; 76+ messages in thread
From: Arnd Bergmann @ 2014-06-30 10:11 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 23 June 2014, Nathan Lynch wrote:
> +struct vdso_data {
> +       u32 seq_count;          /* sequence count - odd during updates */
> +       u16 use_syscall;        /* whether to fall back to syscalls */
> +       u16 cs_shift;           /* clocksource shift */
> +       u32 xtime_coarse_sec;   /* coarse time */
> +       u32 xtime_coarse_nsec;

Note that we will at some point have to introduce 64-bit time_t in user space
in some form. We will have to add new system calls for anything dealing with
time on the kernel boundary, but it would be good to be prepared here.

Is vdso_data an ABI-relevant data structure? If so, I think all you need here
is to make xtime_coarse_sec a u64 type for now, so we can add the other functions
later. The code can of course for now access only the lower half (keeping
endianess in mind), so there should not be any performance impact.

If the structure is not part of the ABI, there probably isn't much we can
do here.

	Arnd

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 6/9] ARM: miscellaneous vdso infrastructure, preparation
  2014-06-30 10:11   ` Arnd Bergmann
@ 2014-06-30 12:27     ` Nathan Lynch
  2014-06-30 13:06       ` Arnd Bergmann
  0 siblings, 1 reply; 76+ messages in thread
From: Nathan Lynch @ 2014-06-30 12:27 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/30/2014 05:11 AM, Arnd Bergmann wrote:
> On Monday 23 June 2014, Nathan Lynch wrote:
>> +struct vdso_data {
>> +       u32 seq_count;          /* sequence count - odd during updates */
>> +       u16 use_syscall;        /* whether to fall back to syscalls */
>> +       u16 cs_shift;           /* clocksource shift */
>> +       u32 xtime_coarse_sec;   /* coarse time */
>> +       u32 xtime_coarse_nsec;
> 
> Note that we will at some point have to introduce 64-bit time_t in user space
> in some form. We will have to add new system calls for anything dealing with
> time on the kernel boundary, but it would be good to be prepared here.
> 
> Is vdso_data an ABI-relevant data structure? If so, I think all you need here
> is to make xtime_coarse_sec a u64 type for now, so we can add the other functions
> later. The code can of course for now access only the lower half (keeping
> endianess in mind), so there should not be any performance impact.
> 
> If the structure is not part of the ABI, there probably isn't much we can
> do here.

In short, no, vdso_data is not ABI-relevant.

The vdso_data structure may be accessed legitimately only through the
entry points (gettimeofday, clock_gettime) that the VDSO provides, and
it is my intent that we should be able to change the structure as
needed, just like other architectures.  vdso_data should not show up in
any exported header and I'll double-check to make sure it does not.

So, when the time comes, we should be able to change it to accommodate
64-bit time_t by (I imagine) making any field that stores seconds 64
bits and adding new entry points (clock_gettime64 or whatever).

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 6/9] ARM: miscellaneous vdso infrastructure, preparation
  2014-06-30 12:27     ` Nathan Lynch
@ 2014-06-30 13:06       ` Arnd Bergmann
  0 siblings, 0 replies; 76+ messages in thread
From: Arnd Bergmann @ 2014-06-30 13:06 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 30 June 2014 07:27:59 Nathan Lynch wrote:
> On 06/30/2014 05:11 AM, Arnd Bergmann wrote:
> > On Monday 23 June 2014, Nathan Lynch wrote:
> >> +struct vdso_data {
> >> +       u32 seq_count;          /* sequence count - odd during updates */
> >> +       u16 use_syscall;        /* whether to fall back to syscalls */
> >> +       u16 cs_shift;           /* clocksource shift */
> >> +       u32 xtime_coarse_sec;   /* coarse time */
> >> +       u32 xtime_coarse_nsec;
> > 
> > Note that we will at some point have to introduce 64-bit time_t in user space
> > in some form. We will have to add new system calls for anything dealing with
> > time on the kernel boundary, but it would be good to be prepared here.
> > 
> > Is vdso_data an ABI-relevant data structure? If so, I think all you need here
> > is to make xtime_coarse_sec a u64 type for now, so we can add the other functions
> > later. The code can of course for now access only the lower half (keeping
> > endianess in mind), so there should not be any performance impact.
> > 
> > If the structure is not part of the ABI, there probably isn't much we can
> > do here.
> 
> In short, no, vdso_data is not ABI-relevant.
> 
> The vdso_data structure may be accessed legitimately only through the
> entry points (gettimeofday, clock_gettime) that the VDSO provides, and
> it is my intent that we should be able to change the structure as
> needed, just like other architectures.  vdso_data should not show up in
> any exported header and I'll double-check to make sure it does not.
> 
> So, when the time comes, we should be able to change it to accommodate
> 64-bit time_t by (I imagine) making any field that stores seconds 64
> bits and adding new entry points (clock_gettime64 or whatever).

Ok, very good.

	Arnd

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 0/9] ARM: VDSO
  2014-06-23  3:11 [PATCH v7 0/9] ARM: VDSO Nathan Lynch
                   ` (10 preceding siblings ...)
  2014-06-30  8:12 ` Ard Biesheuvel
@ 2014-06-30 14:40 ` Will Deacon
  2014-06-30 15:42   ` Nathan Lynch
  11 siblings, 1 reply; 76+ messages in thread
From: Will Deacon @ 2014-06-30 14:40 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Nathan,

On Mon, Jun 23, 2014 at 04:11:49AM +0100, Nathan Lynch wrote:
> Provide fast userspace implementations of gettimeofday and
> clock_gettime on systems that implement the generic timers extension
> defined in ARMv7.  This follows the example of arm64 in conception but
> significantly differs in some aspects of the implementation (C vs
> assembly, mainly).

[...]

This series is starting to gain traction now, so it's probably time to start
thinking about implementing this for CONFIG_COMPAT on arm64. We currently
map a fake vectors page there, but this would be much more flexible,
particularly as its written in C (and so we would magically get any new
functions added to the 32-bit version).

So, there are a couple of questions that spring to mind:

  - How difficult is it to share the vdso code with arm64 to build a compat
    vdso? (getting the Makefile to work will be hard, as we'll need an arm
    toolchain...).

  - If we use your code to build an arm64 vdso, how much slower is it than
    the handcrafted asm we currently have?

Will

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 0/9] ARM: VDSO
  2014-06-30 14:40 ` Will Deacon
@ 2014-06-30 15:42   ` Nathan Lynch
  2014-06-30 21:56     ` Andy Lutomirski
  0 siblings, 1 reply; 76+ messages in thread
From: Nathan Lynch @ 2014-06-30 15:42 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/30/2014 09:40 AM, Will Deacon wrote:
> Hi Nathan,
> 
> On Mon, Jun 23, 2014 at 04:11:49AM +0100, Nathan Lynch wrote:
>> Provide fast userspace implementations of gettimeofday and
>> clock_gettime on systems that implement the generic timers extension
>> defined in ARMv7.  This follows the example of arm64 in conception but
>> significantly differs in some aspects of the implementation (C vs
>> assembly, mainly).
> 
> [...]
> 
> This series is starting to gain traction now, so it's probably time to start
> thinking about implementing this for CONFIG_COMPAT on arm64. We currently
> map a fake vectors page there, but this would be much more flexible,
> particularly as its written in C (and so we would magically get any new
> functions added to the 32-bit version).
> 
> So, there are a couple of questions that spring to mind:
> 
>   - How difficult is it to share the vdso code with arm64 to build a compat
>     vdso? (getting the Makefile to work will be hard, as we'll need an arm
>     toolchain...).

Not sure.  x86 might be the best example to work from here, although it
has the advantage of everything living under arch/x86.  64-bit powerpc
kernels provide a 32-bit VDSO for compat tasks but I think it doesn't
really share code with the 64-bit VDSO.

> 
>   - If we use your code to build an arm64 vdso, how much slower is it than
>     the handcrafted asm we currently have?

Someone with access to 64-bit hardware (i.e. not me) would have to find
this out, but I would not be surprised if the C code could be tightened
up -- I have not spent much time on optimizing it.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 7/9] ARM: add vdso user-space code
  2014-06-28 10:03     ` Russell King - ARM Linux
@ 2014-06-30 15:56       ` Andy Lutomirski
  0 siblings, 0 replies; 76+ messages in thread
From: Andy Lutomirski @ 2014-06-30 15:56 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/28/2014 03:03 AM, Russell King - ARM Linux wrote:
> On Sat, Jun 28, 2014 at 10:53:14AM +0100, Russell King - ARM Linux wrote:
>> On Sun, Jun 22, 2014 at 10:11:56PM -0500, Nathan Lynch wrote:
>>> Place vdso-related user-space code in arch/arm/kernel/vdso/.
>>>
>>> It is almost completely written in C with some assembly helpers to
>>> load the data page address, sample the counter, and fall back to
>>> system calls when necessary.
>>>
>>> If CONFIG_ARM_ARCH_TIMER is not enabled, the vdso cannot service
>>> high-resolution clocks and falls back to syscalls.  Low-resolution
>>> clocks e.g. CLOCK_REALTIME_COARSE can be serviced regardless.
>>>
>>> Of particular note is that a post-processing step ("vdsomunge") is
>>> necessary to produce a shared object which is architecturally allowed
>>> to be used by both soft- and hard-float EABI programs.
>>>
>>> The 2012 edition of the ARM ABI defines Tag_ABI_VFP_args = 3 "Code is
>>> compatible with both the base and VFP variants; the user did not
>>> permit non-variadic functions to pass FP parameters/results."
>>> Unfortunately current toolchains do not support this tag, which is
>>> ideally what we would use.
>>>
>>> The best available option is to ensure that both EF_ARM_ABI_FLOAT_SOFT
>>> and EF_ARM_ABI_FLOAT_HARD are unset in the ELF header's e_flags,
>>> indicating that the shared object is "old" and should be accepted for
>>> backward compatibility's sake.  While binutils < 2.24 appear to
>>> produce a vdso.so with both flags clear, 2.24 always sets
>>> EF_ARM_ABI_FLOAT_SOFT, with no way to inhibit this behavior.  So we
>>> have to fix things up with a custom post-processing step.
>>>
>>> In fact, the VDSO code in glibc does much less validation (including
>>> checking these flags) than the code for handling conventional
>>> file-backed shared libraries, so this is a bit moot unless glibc's
>>> VDSO code becomes more strict.
>>>
>>> Signed-off-by: Nathan Lynch <nathan_lynch@mentor.com>
>>> ---
>>>   arch/arm/kernel/asm-offsets.c        |   5 +
>>>   arch/arm/kernel/vdso/.gitignore      |   1 +
>>>   arch/arm/kernel/vdso/Makefile        |  59 +++++++
>>>   arch/arm/kernel/vdso/checkundef.sh   |   9 +
>>>   arch/arm/kernel/vdso/datapage.S      |  15 ++
>>>   arch/arm/kernel/vdso/vdso.S          |  35 ++++
>>>   arch/arm/kernel/vdso/vdso.lds.S      |  88 ++++++++++
>>>   arch/arm/kernel/vdso/vdsomunge.c     | 193 +++++++++++++++++++++
>>>   arch/arm/kernel/vdso/vgettimeofday.c | 320 +++++++++++++++++++++++++++++++++++
>>>   9 files changed, 725 insertions(+)
>>>   create mode 100644 arch/arm/kernel/vdso/.gitignore
>>>   create mode 100644 arch/arm/kernel/vdso/Makefile
>>>   create mode 100755 arch/arm/kernel/vdso/checkundef.sh
>>>   create mode 100644 arch/arm/kernel/vdso/datapage.S
>>>   create mode 100644 arch/arm/kernel/vdso/vdso.S
>>>   create mode 100644 arch/arm/kernel/vdso/vdso.lds.S
>>>   create mode 100644 arch/arm/kernel/vdso/vdsomunge.c
>>>   create mode 100644 arch/arm/kernel/vdso/vgettimeofday.c
>>
>> One change I would like to see (to stop the directory tree getting soo
>> deep) is to move this to arch/arm/vdso - just like x86 is arch/x86/vdso.
>> Was there a pressing reason to have it in arch/arm/kernel ?
>
> It also looks like there's something missing for vdso_install to work.
> arch/x86 has this:
>
> PHONY += vdso_install
> vdso_install:
>          $(Q)$(MAKE) $(build)=arch/x86/vdso $@
>
> but doesn't list it in the arch help.  I'm sure we can do better on ARM. :)

In 3.16-rc3 this is rather improved, albeit still undocumented.  It's 
probably worth matching x86's behavior for gdb's benefit.

--Andy

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 7/9] ARM: add vdso user-space code
  2014-06-28 15:26   ` Russell King - ARM Linux
  2014-06-28 16:13     ` Nathan Lynch
@ 2014-06-30 15:59     ` Andy Lutomirski
  2014-06-30 16:50       ` Nathan Lynch
  1 sibling, 1 reply; 76+ messages in thread
From: Andy Lutomirski @ 2014-06-30 15:59 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/28/2014 08:26 AM, Russell King - ARM Linux wrote:
> On Sun, Jun 22, 2014 at 10:11:56PM -0500, Nathan Lynch wrote:
>> Place vdso-related user-space code in arch/arm/kernel/vdso/.
>>
>> It is almost completely written in C with some assembly helpers to
>> load the data page address, sample the counter, and fall back to
>> system calls when necessary.
>>
>> If CONFIG_ARM_ARCH_TIMER is not enabled, the vdso cannot service
>> high-resolution clocks and falls back to syscalls.  Low-resolution
>> clocks e.g. CLOCK_REALTIME_COARSE can be serviced regardless.
>
> Okay, how is this used by userspace?
>
> It seems that on ARM, we generate a dso with these symbols:
>
> DYNAMIC SYMBOL TABLE:
> 000001e4 l    d  .eh_frame_hdr	00000000              .eh_frame_hdr
> 00000000 g    DO *ABS*	00000000  LINUX_3.17  LINUX_3.17
> 000003c4 g    DF .text	00000080  LINUX_3.17  __kernel_clock_getres
> 00000444 g    DF .text	0000002c  LINUX_3.17  __kernel_gettimeofday
> 00000298 g    DF .text	0000012c  LINUX_3.17  __kernel_clock_gettime

Sorry, late to the thread.

I think that, if your function signatures match, you should give them 
the same names and versions as for x86 (i.e. LINUX_2.6, 
__vdso_clock_gettime).  Userspace will thank you.

Don't do the weak clock_gettime, etc aliases, though.  That was never a 
good idea to begin with.

--Andy

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 0/9] ARM: VDSO
  2014-06-27  8:51 ` [PATCH v7 0/9] ARM: VDSO Jan Glauber
  2014-06-27  8:57   ` Russell King - ARM Linux
  2014-06-27 16:00   ` Nathan Lynch
@ 2014-06-30 16:03   ` Andy Lutomirski
  2 siblings, 0 replies; 76+ messages in thread
From: Andy Lutomirski @ 2014-06-30 16:03 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/27/2014 01:51 AM, Jan Glauber wrote:
> On Sun, Jun 22, 2014 at 10:11:49PM -0500, Nathan Lynch wrote:
>> Provide fast userspace implementations of gettimeofday and
>> clock_gettime on systems that implement the generic timers extension
>> defined in ARMv7.  This follows the example of arm64 in conception but
>> significantly differs in some aspects of the implementation (C vs
>> assembly, mainly).

Sorry for replying to the wrong email in the thread -- my gmane feed 
missed the original.

One thing that might be nice to add is AT_VDSO_FINDSYM [1].  A lot of 
userspace implementations (especially for static, embedded things) might 
significantly prefer that style of entry point.

If you want to use vdso2c for vdso image post-processing, I'd be happy 
to try to make it available outside arch/x86 and to make it more 
configurable as needed.

Please use _install_special_mapping instead of install_special_mapping. 
  AFAICS it's basically impossible to use install_special_mapping correctly.

[1] 
https://git.kernel.org/cgit/linux/kernel/git/luto/linux.git/log/?h=x86/vdso_findsym

--Andy

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 7/9] ARM: add vdso user-space code
  2014-06-30 15:59     ` Andy Lutomirski
@ 2014-06-30 16:50       ` Nathan Lynch
  0 siblings, 0 replies; 76+ messages in thread
From: Nathan Lynch @ 2014-06-30 16:50 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/30/2014 10:59 AM, Andy Lutomirski wrote:
> On 06/28/2014 08:26 AM, Russell King - ARM Linux wrote:
>> On Sun, Jun 22, 2014 at 10:11:56PM -0500, Nathan Lynch wrote:
>>> Place vdso-related user-space code in arch/arm/kernel/vdso/.
>>>
>>> It is almost completely written in C with some assembly helpers to
>>> load the data page address, sample the counter, and fall back to
>>> system calls when necessary.
>>>
>>> If CONFIG_ARM_ARCH_TIMER is not enabled, the vdso cannot service
>>> high-resolution clocks and falls back to syscalls.  Low-resolution
>>> clocks e.g. CLOCK_REALTIME_COARSE can be serviced regardless.
>>
>> Okay, how is this used by userspace?
>>
>> It seems that on ARM, we generate a dso with these symbols:
>>
>> DYNAMIC SYMBOL TABLE:
>> 000001e4 l    d  .eh_frame_hdr    00000000              .eh_frame_hdr
>> 00000000 g    DO *ABS*    00000000  LINUX_3.17  LINUX_3.17
>> 000003c4 g    DF .text    00000080  LINUX_3.17  __kernel_clock_getres
>> 00000444 g    DF .text    0000002c  LINUX_3.17  __kernel_gettimeofday
>> 00000298 g    DF .text    0000012c  LINUX_3.17  __kernel_clock_gettime
> 
> Sorry, late to the thread.
> 
> I think that, if your function signatures match, you should give them
> the same names and versions as for x86 (i.e. LINUX_2.6,
> __vdso_clock_gettime).  Userspace will thank you.

I don't care strongly about it, but I was following arm64's example with
the naming, and I thought the version should match the Linux version in
which the VDSO symbols were introduced.  I can see that about half the
vdso-providing architectures (e.g. arm64, powerpc, s390) follow that
version convention instead of using LINUX_2.6.  However, looking through
git history I see that when people add new symbols to their VDSOs they
don't mark them with the current Linux version -- for example, when
powerpc added getcpu -- so I'm left thinking the version is not that
meaningful.

In other words, I'm inclined to make the changes you suggest, unless
someone knows why I shouldn't.


> Don't do the weak clock_gettime, etc aliases, though.  That was never a
> good idea to begin with.

OK, that was my suspicion, thanks for confirming.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 0/9] ARM: VDSO
  2014-06-30  7:43             ` Arnd Bergmann
@ 2014-06-30 18:27               ` Nathan Lynch
  0 siblings, 0 replies; 76+ messages in thread
From: Nathan Lynch @ 2014-06-30 18:27 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/30/2014 02:43 AM, Arnd Bergmann wrote:
> On Saturday 28 June 2014 10:42:19 Russell King - ARM Linux wrote:
>> What's happening is if you try and rebuild a kernel with these patches
>> applied, you already have an arch/arm/include/generated/asm/auxvec.h
>> which points at the empty asm-generic version.  This remains after
>> these patches are applied, so the new include of asm/auxvec.h in
>> asm/elf.h picks up on the empty version, not the newly introduced
>> version.
> 
> One more piece of the puzzle: the top-level Makefile always includes
> the headers from the source tree before generated headers, so in theory
> this should not be happening. However, for some reason this ends up
> as arch/arm/include/generated/asm/auxvec.h rather than
> arch/arm/include/generated/uapi/asm/auxvec.h, and the kernel-only
> headers get included before any of the uapi headers.
> 
> An easy workaround would probably be to add an
> arch/arm/include/asm/auxvec.h file that contains only
> 
> #include <uapi/asm/auxvec.h>

Thanks Arnd, that seems to do the trick.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 7/9] ARM: add vdso user-space code
  2014-06-23  3:11 ` [PATCH v7 7/9] ARM: add vdso user-space code Nathan Lynch
  2014-06-28  9:53   ` Russell King - ARM Linux
  2014-06-28 15:26   ` Russell King - ARM Linux
@ 2014-06-30 21:29   ` Andy Lutomirski
  2014-07-01  9:00     ` Will Deacon
  2014-07-01 13:28     ` Nathan Lynch
  2 siblings, 2 replies; 76+ messages in thread
From: Andy Lutomirski @ 2014-06-30 21:29 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/22/2014 08:11 PM, Nathan Lynch wrote:
> Place vdso-related user-space code in arch/arm/kernel/vdso/.
> 
> It is almost completely written in C with some assembly helpers to
> load the data page address, sample the counter, and fall back to
> system calls when necessary.
> 
> If CONFIG_ARM_ARCH_TIMER is not enabled, the vdso cannot service
> high-resolution clocks and falls back to syscalls.  Low-resolution
> clocks e.g. CLOCK_REALTIME_COARSE can be serviced regardless.
> 
> Of particular note is that a post-processing step ("vdsomunge") is
> necessary to produce a shared object which is architecturally allowed
> to be used by both soft- and hard-float EABI programs.
> 
> The 2012 edition of the ARM ABI defines Tag_ABI_VFP_args = 3 "Code is
> compatible with both the base and VFP variants; the user did not
> permit non-variadic functions to pass FP parameters/results."
> Unfortunately current toolchains do not support this tag, which is
> ideally what we would use.
> 
> The best available option is to ensure that both EF_ARM_ABI_FLOAT_SOFT
> and EF_ARM_ABI_FLOAT_HARD are unset in the ELF header's e_flags,
> indicating that the shared object is "old" and should be accepted for
> backward compatibility's sake.  While binutils < 2.24 appear to
> produce a vdso.so with both flags clear, 2.24 always sets
> EF_ARM_ABI_FLOAT_SOFT, with no way to inhibit this behavior.  So we
> have to fix things up with a custom post-processing step.
> 
> In fact, the VDSO code in glibc does much less validation (including
> checking these flags) than the code for handling conventional
> file-backed shared libraries, so this is a bit moot unless glibc's
> VDSO code becomes more strict.
> 
> Signed-off-by: Nathan Lynch <nathan_lynch@mentor.com>

> diff --git a/arch/arm/kernel/vdso/Makefile b/arch/arm/kernel/vdso/Makefile
> new file mode 100644
> index 000000000000..ceb712a7626c
> --- /dev/null
> +++ b/arch/arm/kernel/vdso/Makefile
> @@ -0,0 +1,59 @@
> +hostprogs-y := vdsomunge
> +
> +obj-vdso := vgettimeofday.o datapage.o
> +
> +# Build rules
> +targets := $(obj-vdso) vdso.so vdso.so.dbg vdso.so.raw vdso.lds
> +obj-vdso := $(addprefix $(obj)/, $(obj-vdso))
> +
> +ccflags-y := -shared -fPIC -fno-common -fno-builtin -fno-stack-protector
> +ccflags-y += -nostdlib -Wl,-soname=linux-vdso.so.1 \
> +		$(call cc-ldoption, -Wl$(comma)--hash-style=sysv)

Does this need -DDISABLE_BRANCH_PROFILING?

> diff --git a/arch/arm/kernel/vdso/checkundef.sh b/arch/arm/kernel/vdso/checkundef.sh
> new file mode 100755
> index 000000000000..185c30da202b
> --- /dev/null
> +++ b/arch/arm/kernel/vdso/checkundef.sh
> @@ -0,0 +1,9 @@
> +#!/bin/sh
> +nm="$1"
> +file="$2"
> +"$nm" -u "$file" | ( ret=0; while read discard symbol
> +do
> +    echo "$file: undefined symbol $symbol"
> +    ret=1
> +done ; exit $ret )
> +exit $?

This is just as buggy as the x86 version.  make;make malfunctions.

Can you rely on a new enough toolchain to use -Wl,--no-undefined?

> diff --git a/arch/arm/kernel/vdso/datapage.S b/arch/arm/kernel/vdso/datapage.S
> new file mode 100644
> index 000000000000..fbf36d75da06
> --- /dev/null
> +++ b/arch/arm/kernel/vdso/datapage.S
> @@ -0,0 +1,15 @@
> +#include <linux/linkage.h>
> +#include <asm/asm-offsets.h>
> +
> +	.align 2
> +.L_vdso_data_ptr:
> +	.long	_start - . - VDSO_DATA_SIZE
> +
> +ENTRY(__get_datapage)
> +	.cfi_startproc
> +	adr	r0, .L_vdso_data_ptr
> +	ldr	r1, [r0]
> +	add	r0, r0, r1
> +	bx	lr
> +	.cfi_endproc
> +ENDPROC(__get_datapage)

Can you translate this into English for the non-ARM-speakers here?

> +
> +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
> +#define HOST_ORDER ELFDATA2LSB
> +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
> +#define HOST_ORDER ELFDATA2MSB
> +#endif
> +
> +static const char *outfile;
> +
> +static void cleanup(void)
> +{
> +	if (error_message_count > 0 && outfile != NULL)
> +		unlink(outfile);
> +}
> +
> +static Elf32_Word read_elf_word(Elf32_Word word, bool swap)
> +{
> +	return swap ? bswap_32(word) : word;
> +}
> +
> +static Elf32_Half read_elf_half(Elf32_Half half, bool swap)
> +{
> +	return swap ? bswap_16(half) : half;
> +}
> +
> +static void write_elf_word(Elf32_Word val, Elf32_Word *dst, bool swap)
> +{
> +	*dst = swap ? bswap_32(val) : val;
> +}

The macros in arch/x86/vdso/vdso2c.c are IMO much nicer.

--Andy

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 7/9] ARM: add vdso user-space code
  2014-06-29 16:07                   ` Russell King - ARM Linux
  2014-06-29 23:04                     ` Nathan Lynch
@ 2014-06-30 21:33                     ` Andy Lutomirski
  1 sibling, 0 replies; 76+ messages in thread
From: Andy Lutomirski @ 2014-06-30 21:33 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/29/2014 09:07 AM, Russell King - ARM Linux wrote:
> On Sun, Jun 29, 2014 at 10:48:13AM -0500, Nathan Lynch wrote:
>> On 06/29/2014 03:34 AM, Russell King - ARM Linux wrote:
>>> On Sat, Jun 28, 2014 at 04:35:12PM -0500, Nathan Lynch wrote:
>>>> That's consistent with my results on iMX6.  The reported 1.00x "speedup"
>>>> for clock-gettime-monotonic etc indicates the VDSO is falling back to
>>>> syscall.
>>>>
>>>> Thanks for testing.
>>>
>>> Here's another issue which cropped up when I ran this patch set through
>>> the autobuilder last night - allnoconfig's now fail with:
>>>
>>> mm/memory.c: In function 'gate_vma_init':
>>> mm/memory.c:3410:22: error: 'FIXADDR_USER_START' undeclared (first use in this function)
>>> mm/memory.c:3411:20: error: 'FIXADDR_USER_END' undeclared (first use in this function)
>>> mm/memory.c: In function 'in_gate_area_no_mm':
>>> mm/memory.c:3432:15: error: 'FIXADDR_USER_START' undeclared (first use in this function)
>>> mm/memory.c:3432:46: error: 'FIXADDR_USER_END' undeclared (first use in this function)
>>> make[2]: *** [mm/memory.o] Error 1
>>
>> arch/arm/include/page.h:
>> #ifdef CONFIG_KUSER_HELPERS
>> #define __HAVE_ARCH_GATE_AREA 1
>> #endif
>>
>> mm/memory.c:
>> #if !defined(__HAVE_ARCH_GATE_AREA)
>>
>> #if defined(AT_SYSINFO_EHDR)
>> static struct vm_area_struct gate_vma;
>>
>> static int __init gate_vma_init(void)
>> {
>> 	gate_vma.vm_mm = NULL;
>> 	gate_vma.vm_start = FIXADDR_USER_START;
>> 	gate_vma.vm_end = FIXADDR_USER_END;
>> ...
>>
>> The vdso patches add an ARM definition for AT_SYSINFO_EHDR.  So when
>> CONFIG_KUSER_HELPERS=n, this code is pulled in now...
>>
>> Not sure what the fix would be right now.  I don't understand why there
>> is this relationship between AT_SYSINFO_EHDR and gate vma code.
> 
> Me neither.  It looks like changing those tests for AT_SYSINFO_EHDR to
> something like __HAVE_GATE_VMA or CONFIG_HAVE_GATE_VMA would be a good
> step, so we can keep this disabled on ARM.  I don't see a need for the
> gate VMA stuff just because we have a vDSO.
> 

The code you're running into is mostly bogus.  I'm planning on resending
a real fix in about five minutes.  I'll see if I can get hpa to pick it
up in a couple days (or to tell me whos tree it should live in).

I'd actually prefer if you rebase on top of it, because otherwise I'll
have to undo whatever hack you add.

--Andy

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 8/9] ARM: vdso initialization, mapping, and synchronization
  2014-06-23  3:11 ` [PATCH v7 8/9] ARM: vdso initialization, mapping, and synchronization Nathan Lynch
@ 2014-06-30 21:37   ` Andy Lutomirski
  2014-07-01  9:03     ` Will Deacon
  2014-07-01 14:01     ` Nathan Lynch
  0 siblings, 2 replies; 76+ messages in thread
From: Andy Lutomirski @ 2014-06-30 21:37 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/22/2014 08:11 PM, Nathan Lynch wrote:
> Initialize the vdso page list at boot, install the vdso mapping at
> exec time, and update the data page during timer ticks.  This code is
> not built if CONFIG_VDSO is not enabled.
> 
> Account for the vdso length when randomizing the offset from the
> stack.  The vdso is placed immediately following the sigpage with a
> separate install_special_mapping call in arm_install_vdso.
> 
> Signed-off-by: Nathan Lynch <nathan_lynch@mentor.com>
> ---
>  arch/arm/kernel/process.c |  13 +++-
>  arch/arm/kernel/vdso.c    | 168 ++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 179 insertions(+), 2 deletions(-)
>  create mode 100644 arch/arm/kernel/vdso.c
> 
> diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
> index 40445fb71ac9..39b0d68aa068 100644
> --- a/arch/arm/kernel/process.c
> +++ b/arch/arm/kernel/process.c
> @@ -520,6 +520,7 @@ extern struct page *get_signal_page(void);
>  int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
>  {
>  	struct mm_struct *mm = current->mm;
> +	unsigned long npages;
>  	unsigned long addr;
>  	unsigned long hint;
>  	int ret;
> @@ -529,9 +530,11 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
>  	if (!signal_page)
>  		return -ENOMEM;
>  
> +	npages = (vdso_mapping_len >> PAGE_SHIFT) + 1;
> +
>  	down_write(&mm->mmap_sem);
> -	hint = vdso_addr(mm, 1);
> -	addr = get_unmapped_area(NULL, hint, PAGE_SIZE, 0, 0);
> +	hint = vdso_addr(mm, npages);
> +	addr = get_unmapped_area(NULL, hint, npages, 0, 0);
>  	if (IS_ERR_VALUE(addr)) {
>  		ret = addr;
>  		goto up_fail;
> @@ -544,6 +547,12 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
>  	if (ret == 0)
>  		mm->context.sigpage = addr;
>  
> +	/* Unlike the sigpage, failure to install the vdso is unlikely
> +	 * to be fatal to the process, so no error check needed
> +	 * here.
> +	 */
> +	arm_install_vdso(mm, addr + PAGE_SIZE);
> +
>   up_fail:
>  	up_write(&mm->mmap_sem);
>  	return ret;
> diff --git a/arch/arm/kernel/vdso.c b/arch/arm/kernel/vdso.c
> new file mode 100644
> index 000000000000..0cfd25f09adf
> --- /dev/null
> +++ b/arch/arm/kernel/vdso.c
> @@ -0,0 +1,168 @@
> +/*
> + * Adapted from arm64 version.
> + *
> + * Copyright (C) 2012 ARM Limited
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <linux/err.h>
> +#include <linux/kernel.h>
> +#include <linux/mm.h>
> +#include <linux/slab.h>
> +#include <linux/timekeeper_internal.h>
> +#include <linux/vmalloc.h>
> +
> +#include <asm/barrier.h>
> +#include <asm/cacheflush.h>
> +#include <asm/page.h>
> +#include <asm/vdso.h>
> +#include <asm/vdso_datapage.h>
> +
> +static struct page **vdso_pagelist;
> +
> +unsigned long vdso_mapping_len __read_mostly;
> +
> +/*
> + * The vDSO data page.
> + */
> +static union vdso_data_store vdso_data_store __page_aligned_data;
> +static struct vdso_data *vdso_data = &vdso_data_store.data;
> +
> +static int __init vdso_init(void)
> +{
> +	unsigned long vdso_pages;
> +	int i;
> +
> +	if (memcmp(&vdso_start, "\177ELF", 4)) {
> +		pr_err("vDSO is not a valid ELF object!\n");
> +		return -ENOEXEC;
> +	}
> +
> +	vdso_pages = (&vdso_end - &vdso_start) >> PAGE_SHIFT;
> +	pr_debug("vdso: %ld code pages at base %p\n", vdso_pages, &vdso_start);
> +
> +	/* Allocate the vDSO pagelist, plus a page for the data. */
> +	vdso_pagelist = kcalloc(vdso_pages + 1, sizeof(struct page *),
> +				GFP_KERNEL);
> +	if (vdso_pagelist == NULL)
> +		return -ENOMEM;
> +
> +	/* Grab the vDSO data page. */
> +	vdso_pagelist[0] = virt_to_page(vdso_data);
> +
> +	/* Grab the vDSO code pages. */
> +	for (i = 0; i < vdso_pages; i++)
> +		vdso_pagelist[i + 1] = virt_to_page(&vdso_start + i * PAGE_SIZE);
> +
> +	/* Precompute the mapping size */
> +	vdso_mapping_len = (vdso_pages + 1) << PAGE_SHIFT;
> +
> +	return 0;
> +}
> +arch_initcall(vdso_init);
> +
> +/* assumes mmap_sem is write-locked */
> +void arm_install_vdso(struct mm_struct *mm, unsigned long addr)
> +{
> +	int ret;
> +
> +	mm->context.vdso = ~0UL;
> +
> +	if (vdso_pagelist == NULL)
> +		return;
> +
> +	/*
> +	 * Put vDSO base into mm struct before calling
> +	 * install_special_mapping so the perf counter mmap tracking
> +	 * code will recognise it as a vDSO.
> +	 */
> +	mm->context.vdso = addr;
> +
> +	ret = install_special_mapping(mm, addr, vdso_mapping_len,
> +				      VM_READ|VM_EXEC|
> +				      VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
> +				      vdso_pagelist);

Eek.  You're mapping the shared data VM_MAYWRITE.  This will cause
bizarre and confusing failures if ptrace pokes at it.  You also seem to
be sticking it *before* the vdso in the same vma.  This will severely
piss off all the tools that assume that "[vdso]" points to an ELF object.

x86 calls this thing "[vvar]" and sticks it after the vdso.  You might
not want to have the complexity of sticking it after the vdso (it's
distinctly nontrivial), but I see nothing wrong with giving it its own
vma just before the vdso.  The new _install_special_mapping function
makes it considerably easier to do.

(Don't use any version of x86's code before 3.16-rc3 as a reference.)

--Andy

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 0/9] ARM: VDSO
  2014-06-30 15:42   ` Nathan Lynch
@ 2014-06-30 21:56     ` Andy Lutomirski
  2014-07-01  9:04       ` Will Deacon
  0 siblings, 1 reply; 76+ messages in thread
From: Andy Lutomirski @ 2014-06-30 21:56 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/30/2014 08:42 AM, Nathan Lynch wrote:
> On 06/30/2014 09:40 AM, Will Deacon wrote:
>> Hi Nathan,
>>
>> On Mon, Jun 23, 2014 at 04:11:49AM +0100, Nathan Lynch wrote:
>>> Provide fast userspace implementations of gettimeofday and
>>> clock_gettime on systems that implement the generic timers extension
>>> defined in ARMv7.  This follows the example of arm64 in conception but
>>> significantly differs in some aspects of the implementation (C vs
>>> assembly, mainly).
>>
>> [...]
>>
>> This series is starting to gain traction now, so it's probably time to start
>> thinking about implementing this for CONFIG_COMPAT on arm64. We currently
>> map a fake vectors page there, but this would be much more flexible,
>> particularly as its written in C (and so we would magically get any new
>> functions added to the 32-bit version).
>>
>> So, there are a couple of questions that spring to mind:
>>
>>   - How difficult is it to share the vdso code with arm64 to build a compat
>>     vdso? (getting the Makefile to work will be hard, as we'll need an arm
>>     toolchain...).
> 
> Not sure.  x86 might be the best example to work from here, although it
> has the advantage of everything living under arch/x86.  64-bit powerpc
> kernels provide a 32-bit VDSO for compat tasks but I think it doesn't
> really share code with the 64-bit VDSO.

Heh.  x86 was not a shining example of how to share code.  It's a little
bit better now (3.16-rc3 and up).

> 
>>
>>   - If we use your code to build an arm64 vdso, how much slower is it than
>>     the handcrafted asm we currently have?
> 
> Someone with access to 64-bit hardware (i.e. not me) would have to find
> this out, but I would not be surprised if the C code could be tightened
> up -- I have not spent much time on optimizing it.
> 

I can't comment on ARM specifically, but the only assembly in the x86
vclock_gettime is an asm volatile (""), which causes gcc to emit more
optimal code.  I doubt I could shave off more than a cycle or two by
rewriting it in assembly.

--Andy

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 7/9] ARM: add vdso user-space code
  2014-06-30 21:29   ` Andy Lutomirski
@ 2014-07-01  9:00     ` Will Deacon
  2014-07-01 13:34       ` Nathan Lynch
  2014-07-01 13:28     ` Nathan Lynch
  1 sibling, 1 reply; 76+ messages in thread
From: Will Deacon @ 2014-07-01  9:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jun 30, 2014 at 10:29:28PM +0100, Andy Lutomirski wrote:
> On 06/22/2014 08:11 PM, Nathan Lynch wrote:
> > diff --git a/arch/arm/kernel/vdso/datapage.S b/arch/arm/kernel/vdso/datapage.S
> > new file mode 100644
> > index 000000000000..fbf36d75da06
> > --- /dev/null
> > +++ b/arch/arm/kernel/vdso/datapage.S
> > @@ -0,0 +1,15 @@
> > +#include <linux/linkage.h>
> > +#include <asm/asm-offsets.h>
> > +
> > +	.align 2
> > +.L_vdso_data_ptr:
> > +	.long	_start - . - VDSO_DATA_SIZE
> > +
> > +ENTRY(__get_datapage)
> > +	.cfi_startproc
> > +	adr	r0, .L_vdso_data_ptr
> > +	ldr	r1, [r0]
> > +	add	r0, r0, r1
> > +	bx	lr
> > +	.cfi_endproc
> > +ENDPROC(__get_datapage)
> 
> Can you translate this into English for the non-ARM-speakers here?

Also, I'm not sure .cfi directives are the right things to use for AArch32.
ARM has special .fnstart, .fnend, .movsp diretives for its own unwind
format.

Maybe GDB works with both -- have you tried unwinding out of this with
anything?

Will

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 8/9] ARM: vdso initialization, mapping, and synchronization
  2014-06-30 21:37   ` Andy Lutomirski
@ 2014-07-01  9:03     ` Will Deacon
  2014-07-01 14:11       ` Nathan Lynch
  2014-07-01 14:01     ` Nathan Lynch
  1 sibling, 1 reply; 76+ messages in thread
From: Will Deacon @ 2014-07-01  9:03 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jun 30, 2014 at 10:37:48PM +0100, Andy Lutomirski wrote:
> On 06/22/2014 08:11 PM, Nathan Lynch wrote:
> > Initialize the vdso page list at boot, install the vdso mapping at
> > exec time, and update the data page during timer ticks.  This code is
> > not built if CONFIG_VDSO is not enabled.
> > 
> > Account for the vdso length when randomizing the offset from the
> > stack.  The vdso is placed immediately following the sigpage with a
> > separate install_special_mapping call in arm_install_vdso.

[...]

> > +/* assumes mmap_sem is write-locked */
> > +void arm_install_vdso(struct mm_struct *mm, unsigned long addr)
> > +{
> > +	int ret;
> > +
> > +	mm->context.vdso = ~0UL;
> > +
> > +	if (vdso_pagelist == NULL)
> > +		return;
> > +
> > +	/*
> > +	 * Put vDSO base into mm struct before calling
> > +	 * install_special_mapping so the perf counter mmap tracking
> > +	 * code will recognise it as a vDSO.
> > +	 */
> > +	mm->context.vdso = addr;
> > +
> > +	ret = install_special_mapping(mm, addr, vdso_mapping_len,
> > +				      VM_READ|VM_EXEC|
> > +				      VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
> > +				      vdso_pagelist);
> 
> Eek.  You're mapping the shared data VM_MAYWRITE.  This will cause
> bizarre and confusing failures if ptrace pokes at it.

Hmm, but how else can we support software breakpoints on the vdso?

Will

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 0/9] ARM: VDSO
  2014-06-30 21:56     ` Andy Lutomirski
@ 2014-07-01  9:04       ` Will Deacon
  0 siblings, 0 replies; 76+ messages in thread
From: Will Deacon @ 2014-07-01  9:04 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jun 30, 2014 at 10:56:49PM +0100, Andy Lutomirski wrote:
> On 06/30/2014 08:42 AM, Nathan Lynch wrote:
> > On 06/30/2014 09:40 AM, Will Deacon wrote:
> >>   - If we use your code to build an arm64 vdso, how much slower is it than
> >>     the handcrafted asm we currently have?
> > 
> > Someone with access to 64-bit hardware (i.e. not me) would have to find
> > this out, but I would not be surprised if the C code could be tightened
> > up -- I have not spent much time on optimizing it.
> > 
> 
> I can't comment on ARM specifically, but the only assembly in the x86
> vclock_gettime is an asm volatile (""), which causes gcc to emit more
> optimal code.  I doubt I could shave off more than a cycle or two by
> rewriting it in assembly.

The arm64 version avoids the stack completely (we have lots of registers),
so I'd expect a significant win over a C version. However, I'd be interested
to see a comparison as the C version is clearly more maintainable.

Will

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 7/9] ARM: add vdso user-space code
  2014-06-30 21:29   ` Andy Lutomirski
  2014-07-01  9:00     ` Will Deacon
@ 2014-07-01 13:28     ` Nathan Lynch
  2014-07-01 14:56       ` Andy Lutomirski
  1 sibling, 1 reply; 76+ messages in thread
From: Nathan Lynch @ 2014-07-01 13:28 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/30/2014 04:29 PM, Andy Lutomirski wrote:
> On 06/22/2014 08:11 PM, Nathan Lynch wrote:
>> +
>> +# Build rules
>> +targets := $(obj-vdso) vdso.so vdso.so.dbg vdso.so.raw vdso.lds
>> +obj-vdso := $(addprefix $(obj)/, $(obj-vdso))
>> +
>> +ccflags-y := -shared -fPIC -fno-common -fno-builtin -fno-stack-protector
>> +ccflags-y += -nostdlib -Wl,-soname=linux-vdso.so.1 \
>> +		$(call cc-ldoption, -Wl$(comma)--hash-style=sysv)
> 
> Does this need -DDISABLE_BRANCH_PROFILING?

Yes, thanks.


>> diff --git a/arch/arm/kernel/vdso/checkundef.sh b/arch/arm/kernel/vdso/checkundef.sh
>> new file mode 100755
>> index 000000000000..185c30da202b
>> --- /dev/null
>> +++ b/arch/arm/kernel/vdso/checkundef.sh
>> @@ -0,0 +1,9 @@
>> +#!/bin/sh
>> +nm="$1"
>> +file="$2"
>> +"$nm" -u "$file" | ( ret=0; while read discard symbol
>> +do
>> +    echo "$file: undefined symbol $symbol"
>> +    ret=1
>> +done ; exit $ret )
>> +exit $?
> 
> This is just as buggy as the x86 version.  make;make malfunctions.
> 
> Can you rely on a new enough toolchain to use -Wl,--no-undefined?

Looks like relying on --no-undefined should be okay.


>> diff --git a/arch/arm/kernel/vdso/datapage.S b/arch/arm/kernel/vdso/datapage.S
>> new file mode 100644
>> index 000000000000..fbf36d75da06
>> --- /dev/null
>> +++ b/arch/arm/kernel/vdso/datapage.S
>> @@ -0,0 +1,15 @@
>> +#include <linux/linkage.h>
>> +#include <asm/asm-offsets.h>
>> +
>> +	.align 2
>> +.L_vdso_data_ptr:
>> +	.long	_start - . - VDSO_DATA_SIZE
>> +
>> +ENTRY(__get_datapage)
>> +	.cfi_startproc
>> +	adr	r0, .L_vdso_data_ptr
>> +	ldr	r1, [r0]
>> +	add	r0, r0, r1
>> +	bx	lr
>> +	.cfi_endproc
>> +ENDPROC(__get_datapage)
> 
> Can you translate this into English for the non-ARM-speakers here?

It's a PC-relative load of the data page.  If someone knows how to make
this happen in the C portion of the vdso, it would might get us a little
speedup.


>> +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
>> +#define HOST_ORDER ELFDATA2LSB
>> +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
>> +#define HOST_ORDER ELFDATA2MSB
>> +#endif
>> +
>> +static const char *outfile;
>> +
>> +static void cleanup(void)
>> +{
>> +	if (error_message_count > 0 && outfile != NULL)
>> +		unlink(outfile);
>> +}
>> +
>> +static Elf32_Word read_elf_word(Elf32_Word word, bool swap)
>> +{
>> +	return swap ? bswap_32(word) : word;
>> +}
>> +
>> +static Elf32_Half read_elf_half(Elf32_Half half, bool swap)
>> +{
>> +	return swap ? bswap_16(half) : half;
>> +}
>> +
>> +static void write_elf_word(Elf32_Word val, Elf32_Word *dst, bool swap)
>> +{
>> +	*dst = swap ? bswap_32(val) : val;
>> +}
> 
> The macros in arch/x86/vdso/vdso2c.c are IMO much nicer.

Respectfully, I think I'd disagree, but more importantly, vdso2c.c seems
to assume a little-endian target.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 7/9] ARM: add vdso user-space code
  2014-07-01  9:00     ` Will Deacon
@ 2014-07-01 13:34       ` Nathan Lynch
  2014-07-01 14:11         ` Andy Lutomirski
  0 siblings, 1 reply; 76+ messages in thread
From: Nathan Lynch @ 2014-07-01 13:34 UTC (permalink / raw)
  To: linux-arm-kernel

On 07/01/2014 04:00 AM, Will Deacon wrote:
> On Mon, Jun 30, 2014 at 10:29:28PM +0100, Andy Lutomirski wrote:
>> On 06/22/2014 08:11 PM, Nathan Lynch wrote:
>>> diff --git a/arch/arm/kernel/vdso/datapage.S b/arch/arm/kernel/vdso/datapage.S
>>> new file mode 100644
>>> index 000000000000..fbf36d75da06
>>> --- /dev/null
>>> +++ b/arch/arm/kernel/vdso/datapage.S
>>> @@ -0,0 +1,15 @@
>>> +#include <linux/linkage.h>
>>> +#include <asm/asm-offsets.h>
>>> +
>>> +	.align 2
>>> +.L_vdso_data_ptr:
>>> +	.long	_start - . - VDSO_DATA_SIZE
>>> +
>>> +ENTRY(__get_datapage)
>>> +	.cfi_startproc
>>> +	adr	r0, .L_vdso_data_ptr
>>> +	ldr	r1, [r0]
>>> +	add	r0, r0, r1
>>> +	bx	lr
>>> +	.cfi_endproc
>>> +ENDPROC(__get_datapage)
>>
>> Can you translate this into English for the non-ARM-speakers here?
> 
> Also, I'm not sure .cfi directives are the right things to use for AArch32.
> ARM has special .fnstart, .fnend, .movsp diretives for its own unwind
> format.
> 
> Maybe GDB works with both -- have you tried unwinding out of this with
> anything?

Not since it stopped crashing, which was months ago :-)

I think it worked with GDB 7.5 at least.

I'll revisit this.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 8/9] ARM: vdso initialization, mapping, and synchronization
  2014-06-30 21:37   ` Andy Lutomirski
  2014-07-01  9:03     ` Will Deacon
@ 2014-07-01 14:01     ` Nathan Lynch
  2014-07-01 14:09       ` Andy Lutomirski
  1 sibling, 1 reply; 76+ messages in thread
From: Nathan Lynch @ 2014-07-01 14:01 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/30/2014 04:37 PM, Andy Lutomirski wrote:
> On 06/22/2014 08:11 PM, Nathan Lynch wrote:
>> +void arm_install_vdso(struct mm_struct *mm, unsigned long addr)
>> +{
>> +	int ret;
>> +
>> +	mm->context.vdso = ~0UL;
>> +
>> +	if (vdso_pagelist == NULL)
>> +		return;
>> +
>> +	/*
>> +	 * Put vDSO base into mm struct before calling
>> +	 * install_special_mapping so the perf counter mmap tracking
>> +	 * code will recognise it as a vDSO.
>> +	 */
>> +	mm->context.vdso = addr;
>> +
>> +	ret = install_special_mapping(mm, addr, vdso_mapping_len,
>> +				      VM_READ|VM_EXEC|
>> +				      VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
>> +				      vdso_pagelist);
> 
> Eek.  You're mapping the shared data VM_MAYWRITE.  This will cause
> bizarre and confusing failures if ptrace pokes at it.

I'm aware of that.  One could argue (as does the author of the
equivalent code in powerpc) that this is a "well, don't do that"
situation.  But I tend to agree that it would be nicer to prevent this
failure mode.


> You also seem to
> be sticking it *before* the vdso in the same vma.  This will severely
> piss off all the tools that assume that "[vdso]" points to an ELF object.

Hmm, which tools?  Shouldn't they be consulting AT_SYSINFO_EHDR in the
auxiliary vector instead?


> x86 calls this thing "[vvar]" and sticks it after the vdso.  You might
> not want to have the complexity of sticking it after the vdso (it's
> distinctly nontrivial), but I see nothing wrong with giving it its own
> vma just before the vdso.  The new _install_special_mapping function
> makes it considerably easier to do.

I'll give this a shot, thanks.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 8/9] ARM: vdso initialization, mapping, and synchronization
  2014-07-01 14:01     ` Nathan Lynch
@ 2014-07-01 14:09       ` Andy Lutomirski
  2014-07-01 14:14         ` Russell King - ARM Linux
  0 siblings, 1 reply; 76+ messages in thread
From: Andy Lutomirski @ 2014-07-01 14:09 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 1, 2014 at 7:01 AM, Nathan Lynch <Nathan_Lynch@mentor.com> wrote:
> On 06/30/2014 04:37 PM, Andy Lutomirski wrote:
>> On 06/22/2014 08:11 PM, Nathan Lynch wrote:
>>> +void arm_install_vdso(struct mm_struct *mm, unsigned long addr)
>>> +{
>>> +    int ret;
>>> +
>>> +    mm->context.vdso = ~0UL;
>>> +
>>> +    if (vdso_pagelist == NULL)
>>> +            return;
>>> +
>>> +    /*
>>> +     * Put vDSO base into mm struct before calling
>>> +     * install_special_mapping so the perf counter mmap tracking
>>> +     * code will recognise it as a vDSO.
>>> +     */
>>> +    mm->context.vdso = addr;
>>> +
>>> +    ret = install_special_mapping(mm, addr, vdso_mapping_len,
>>> +                                  VM_READ|VM_EXEC|
>>> +                                  VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
>>> +                                  vdso_pagelist);
>>
>> Eek.  You're mapping the shared data VM_MAYWRITE.  This will cause
>> bizarre and confusing failures if ptrace pokes at it.
>
> I'm aware of that.  One could argue (as does the author of the
> equivalent code in powerpc) that this is a "well, don't do that"
> situation.  But I tend to agree that it would be nicer to prevent this
> failure mode.
>
>
>> You also seem to
>> be sticking it *before* the vdso in the same vma.  This will severely
>> piss off all the tools that assume that "[vdso]" points to an ELF object.
>
> Hmm, which tools?  Shouldn't they be consulting AT_SYSINFO_EHDR in the
> auxiliary vector instead?
>

There were a bunch of random things written before getauxvec(3) was
introduced that look for "[vdso]"

gdb is also a bit weird.  I think it's changed a couple times, but
IIRC it looks for a vma that has a start address that matches
AT_SYSINFO_EDHR, and then it parses the ELF header and *section*
headers (sigh) in that vma.  So if I'm remembering correctly, it just
won't notice the vdso at all of AT_SYSINFO_EHDR and the vma start
aren't the same.

>
>> x86 calls this thing "[vvar]" and sticks it after the vdso.  You might
>> not want to have the complexity of sticking it after the vdso (it's
>> distinctly nontrivial), but I see nothing wrong with giving it its own
>> vma just before the vdso.  The new _install_special_mapping function
>> makes it considerably easier to do.
>
> I'll give this a shot, thanks.
>

--Andy

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 8/9] ARM: vdso initialization, mapping, and synchronization
  2014-07-01  9:03     ` Will Deacon
@ 2014-07-01 14:11       ` Nathan Lynch
  2014-07-01 14:15         ` Will Deacon
  0 siblings, 1 reply; 76+ messages in thread
From: Nathan Lynch @ 2014-07-01 14:11 UTC (permalink / raw)
  To: linux-arm-kernel

On 07/01/2014 04:03 AM, Will Deacon wrote:
> On Mon, Jun 30, 2014 at 10:37:48PM +0100, Andy Lutomirski wrote:
>> On 06/22/2014 08:11 PM, Nathan Lynch wrote:
>>> Initialize the vdso page list at boot, install the vdso mapping at
>>> exec time, and update the data page during timer ticks.  This code is
>>> not built if CONFIG_VDSO is not enabled.
>>>
>>> Account for the vdso length when randomizing the offset from the
>>> stack.  The vdso is placed immediately following the sigpage with a
>>> separate install_special_mapping call in arm_install_vdso.
> 
> [...]
> 
>>> +/* assumes mmap_sem is write-locked */
>>> +void arm_install_vdso(struct mm_struct *mm, unsigned long addr)
>>> +{
>>> +	int ret;
>>> +
>>> +	mm->context.vdso = ~0UL;
>>> +
>>> +	if (vdso_pagelist == NULL)
>>> +		return;
>>> +
>>> +	/*
>>> +	 * Put vDSO base into mm struct before calling
>>> +	 * install_special_mapping so the perf counter mmap tracking
>>> +	 * code will recognise it as a vDSO.
>>> +	 */
>>> +	mm->context.vdso = addr;
>>> +
>>> +	ret = install_special_mapping(mm, addr, vdso_mapping_len,
>>> +				      VM_READ|VM_EXEC|
>>> +				      VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
>>> +				      vdso_pagelist);
>>
>> Eek.  You're mapping the shared data VM_MAYWRITE.  This will cause
>> bizarre and confusing failures if ptrace pokes at it.
> 
> Hmm, but how else can we support software breakpoints on the vdso?

I believe Andy is suggesting separate VMAs (with different VM flags) for
the VDSO's data and code.  So, breakpoints in code would work, but
attempts to modify the data page via ptrace() would fail outright
instead of silently COWing.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 7/9] ARM: add vdso user-space code
  2014-07-01 13:34       ` Nathan Lynch
@ 2014-07-01 14:11         ` Andy Lutomirski
  0 siblings, 0 replies; 76+ messages in thread
From: Andy Lutomirski @ 2014-07-01 14:11 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 1, 2014 at 6:34 AM, Nathan Lynch <Nathan_Lynch@mentor.com> wrote:
> On 07/01/2014 04:00 AM, Will Deacon wrote:
>> On Mon, Jun 30, 2014 at 10:29:28PM +0100, Andy Lutomirski wrote:
>>> On 06/22/2014 08:11 PM, Nathan Lynch wrote:
>>>> diff --git a/arch/arm/kernel/vdso/datapage.S b/arch/arm/kernel/vdso/datapage.S
>>>> new file mode 100644
>>>> index 000000000000..fbf36d75da06
>>>> --- /dev/null
>>>> +++ b/arch/arm/kernel/vdso/datapage.S
>>>> @@ -0,0 +1,15 @@
>>>> +#include <linux/linkage.h>
>>>> +#include <asm/asm-offsets.h>
>>>> +
>>>> +   .align 2
>>>> +.L_vdso_data_ptr:
>>>> +   .long   _start - . - VDSO_DATA_SIZE
>>>> +
>>>> +ENTRY(__get_datapage)
>>>> +   .cfi_startproc
>>>> +   adr     r0, .L_vdso_data_ptr
>>>> +   ldr     r1, [r0]
>>>> +   add     r0, r0, r1
>>>> +   bx      lr
>>>> +   .cfi_endproc
>>>> +ENDPROC(__get_datapage)
>>>
>>> Can you translate this into English for the non-ARM-speakers here?
>>
>> Also, I'm not sure .cfi directives are the right things to use for AArch32.
>> ARM has special .fnstart, .fnend, .movsp diretives for its own unwind
>> format.
>>
>> Maybe GDB works with both -- have you tried unwinding out of this with
>> anything?
>
> Not since it stopped crashing, which was months ago :-)
>
> I think it worked with GDB 7.5 at least.

Keep in mind that gdb might not be noticing your unwind information at
all, and it might be unwinding correctly by dumb luck.

FWIW, on all x86 targets, -fPIC and a symbol in the linker script do
exactly the right thing.  Well, almost: x86_32 doesn't have real
PC-relative addressing, so gcc ends up storing the GOT address in a
register instead of the actual target in a register, but that doesn't
seem to make a big difference.  Maybe ARM can get away with the same
thing.

--Andy

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 8/9] ARM: vdso initialization, mapping, and synchronization
  2014-07-01 14:09       ` Andy Lutomirski
@ 2014-07-01 14:14         ` Russell King - ARM Linux
  0 siblings, 0 replies; 76+ messages in thread
From: Russell King - ARM Linux @ 2014-07-01 14:14 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 01, 2014 at 07:09:46AM -0700, Andy Lutomirski wrote:
> On Tue, Jul 1, 2014 at 7:01 AM, Nathan Lynch <Nathan_Lynch@mentor.com> wrote:
> > Hmm, which tools?  Shouldn't they be consulting AT_SYSINFO_EHDR in the
> > auxiliary vector instead?
> >
> 
> There were a bunch of random things written before getauxvec(3) was
> introduced that look for "[vdso]"
> 
> gdb is also a bit weird.  I think it's changed a couple times, but
> IIRC it looks for a vma that has a start address that matches
> AT_SYSINFO_EDHR, and then it parses the ELF header and *section*
> headers (sigh) in that vma.  So if I'm remembering correctly, it just
> won't notice the vdso at all of AT_SYSINFO_EHDR and the vma start
> aren't the same.

Hmm, that would explain the weird error I got when trying gdb with the
vdso in place.

-- 
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 8/9] ARM: vdso initialization, mapping, and synchronization
  2014-07-01 14:11       ` Nathan Lynch
@ 2014-07-01 14:15         ` Will Deacon
  2014-07-01 14:17           ` Andy Lutomirski
  0 siblings, 1 reply; 76+ messages in thread
From: Will Deacon @ 2014-07-01 14:15 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 01, 2014 at 03:11:04PM +0100, Nathan Lynch wrote:
> On 07/01/2014 04:03 AM, Will Deacon wrote:
> > On Mon, Jun 30, 2014 at 10:37:48PM +0100, Andy Lutomirski wrote:
> >> On 06/22/2014 08:11 PM, Nathan Lynch wrote:
> >>> Initialize the vdso page list at boot, install the vdso mapping at
> >>> exec time, and update the data page during timer ticks.  This code is
> >>> not built if CONFIG_VDSO is not enabled.
> >>>
> >>> Account for the vdso length when randomizing the offset from the
> >>> stack.  The vdso is placed immediately following the sigpage with a
> >>> separate install_special_mapping call in arm_install_vdso.
> > 
> > [...]
> > 
> >>> +/* assumes mmap_sem is write-locked */
> >>> +void arm_install_vdso(struct mm_struct *mm, unsigned long addr)
> >>> +{
> >>> +	int ret;
> >>> +
> >>> +	mm->context.vdso = ~0UL;
> >>> +
> >>> +	if (vdso_pagelist == NULL)
> >>> +		return;
> >>> +
> >>> +	/*
> >>> +	 * Put vDSO base into mm struct before calling
> >>> +	 * install_special_mapping so the perf counter mmap tracking
> >>> +	 * code will recognise it as a vDSO.
> >>> +	 */
> >>> +	mm->context.vdso = addr;
> >>> +
> >>> +	ret = install_special_mapping(mm, addr, vdso_mapping_len,
> >>> +				      VM_READ|VM_EXEC|
> >>> +				      VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
> >>> +				      vdso_pagelist);
> >>
> >> Eek.  You're mapping the shared data VM_MAYWRITE.  This will cause
> >> bizarre and confusing failures if ptrace pokes at it.
> > 
> > Hmm, but how else can we support software breakpoints on the vdso?
> 
> I believe Andy is suggesting separate VMAs (with different VM flags) for
> the VDSO's data and code.  So, breakpoints in code would work, but
> attempts to modify the data page via ptrace() would fail outright
> instead of silently COWing.

Ah, yes. That makes a lot of sense for the data page -- we should do
something similar on arm64 too, since the CoW will break everything for the
task being debugged. We could also drop the EXEC flags too.

Thanks for the explanation,

Will

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 8/9] ARM: vdso initialization, mapping, and synchronization
  2014-07-01 14:15         ` Will Deacon
@ 2014-07-01 14:17           ` Andy Lutomirski
  2014-07-01 17:27             ` Christopher Covington
  2014-07-02 14:40             ` Will Deacon
  0 siblings, 2 replies; 76+ messages in thread
From: Andy Lutomirski @ 2014-07-01 14:17 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 1, 2014 at 7:15 AM, Will Deacon <will.deacon@arm.com> wrote:
> On Tue, Jul 01, 2014 at 03:11:04PM +0100, Nathan Lynch wrote:
>> On 07/01/2014 04:03 AM, Will Deacon wrote:
>> > On Mon, Jun 30, 2014 at 10:37:48PM +0100, Andy Lutomirski wrote:
>> >> On 06/22/2014 08:11 PM, Nathan Lynch wrote:
>> >>> Initialize the vdso page list at boot, install the vdso mapping at
>> >>> exec time, and update the data page during timer ticks.  This code is
>> >>> not built if CONFIG_VDSO is not enabled.
>> >>>
>> >>> Account for the vdso length when randomizing the offset from the
>> >>> stack.  The vdso is placed immediately following the sigpage with a
>> >>> separate install_special_mapping call in arm_install_vdso.
>> >
>> > [...]
>> >
>> >>> +/* assumes mmap_sem is write-locked */
>> >>> +void arm_install_vdso(struct mm_struct *mm, unsigned long addr)
>> >>> +{
>> >>> + int ret;
>> >>> +
>> >>> + mm->context.vdso = ~0UL;
>> >>> +
>> >>> + if (vdso_pagelist == NULL)
>> >>> +         return;
>> >>> +
>> >>> + /*
>> >>> +  * Put vDSO base into mm struct before calling
>> >>> +  * install_special_mapping so the perf counter mmap tracking
>> >>> +  * code will recognise it as a vDSO.
>> >>> +  */
>> >>> + mm->context.vdso = addr;
>> >>> +
>> >>> + ret = install_special_mapping(mm, addr, vdso_mapping_len,
>> >>> +                               VM_READ|VM_EXEC|
>> >>> +                               VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
>> >>> +                               vdso_pagelist);
>> >>
>> >> Eek.  You're mapping the shared data VM_MAYWRITE.  This will cause
>> >> bizarre and confusing failures if ptrace pokes at it.
>> >
>> > Hmm, but how else can we support software breakpoints on the vdso?
>>
>> I believe Andy is suggesting separate VMAs (with different VM flags) for
>> the VDSO's data and code.  So, breakpoints in code would work, but
>> attempts to modify the data page via ptrace() would fail outright
>> instead of silently COWing.
>
> Ah, yes. That makes a lot of sense for the data page -- we should do
> something similar on arm64 too, since the CoW will break everything for the
> task being debugged. We could also drop the EXEC flags too.

If you do this, I have a slight preference for the new vma being
called "[vvar]" to match x86.  It'll make the CRIU people happy if and
when they port it to ARM.

--Andy

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 7/9] ARM: add vdso user-space code
  2014-07-01 13:28     ` Nathan Lynch
@ 2014-07-01 14:56       ` Andy Lutomirski
  0 siblings, 0 replies; 76+ messages in thread
From: Andy Lutomirski @ 2014-07-01 14:56 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 1, 2014 at 6:28 AM, Nathan Lynch <Nathan_Lynch@mentor.com> wrote:
> On 06/30/2014 04:29 PM, Andy Lutomirski wrote:
>> On 06/22/2014 08:11 PM, Nathan Lynch wrote:
>>> +
>>> +# Build rules
>>> +targets := $(obj-vdso) vdso.so vdso.so.dbg vdso.so.raw vdso.lds
>>> +obj-vdso := $(addprefix $(obj)/, $(obj-vdso))
>>> +
>>> +ccflags-y := -shared -fPIC -fno-common -fno-builtin -fno-stack-protector
>>> +ccflags-y += -nostdlib -Wl,-soname=linux-vdso.so.1 \
>>> +            $(call cc-ldoption, -Wl$(comma)--hash-style=sysv)
>>
>> Does this need -DDISABLE_BRANCH_PROFILING?
>
> Yes, thanks.
>
>
>>> diff --git a/arch/arm/kernel/vdso/checkundef.sh b/arch/arm/kernel/vdso/checkundef.sh
>>> new file mode 100755
>>> index 000000000000..185c30da202b
>>> --- /dev/null
>>> +++ b/arch/arm/kernel/vdso/checkundef.sh
>>> @@ -0,0 +1,9 @@
>>> +#!/bin/sh
>>> +nm="$1"
>>> +file="$2"
>>> +"$nm" -u "$file" | ( ret=0; while read discard symbol
>>> +do
>>> +    echo "$file: undefined symbol $symbol"
>>> +    ret=1
>>> +done ; exit $ret )
>>> +exit $?
>>
>> This is just as buggy as the x86 version.  make;make malfunctions.
>>
>> Can you rely on a new enough toolchain to use -Wl,--no-undefined?
>
> Looks like relying on --no-undefined should be okay.
>
>
>>> diff --git a/arch/arm/kernel/vdso/datapage.S b/arch/arm/kernel/vdso/datapage.S
>>> new file mode 100644
>>> index 000000000000..fbf36d75da06
>>> --- /dev/null
>>> +++ b/arch/arm/kernel/vdso/datapage.S
>>> @@ -0,0 +1,15 @@
>>> +#include <linux/linkage.h>
>>> +#include <asm/asm-offsets.h>
>>> +
>>> +    .align 2
>>> +.L_vdso_data_ptr:
>>> +    .long   _start - . - VDSO_DATA_SIZE
>>> +
>>> +ENTRY(__get_datapage)
>>> +    .cfi_startproc
>>> +    adr     r0, .L_vdso_data_ptr
>>> +    ldr     r1, [r0]
>>> +    add     r0, r0, r1
>>> +    bx      lr
>>> +    .cfi_endproc
>>> +ENDPROC(__get_datapage)
>>
>> Can you translate this into English for the non-ARM-speakers here?
>
> It's a PC-relative load of the data page.  If someone knows how to make
> this happen in the C portion of the vdso, it would might get us a little
> speedup.
>
>
>>> +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
>>> +#define HOST_ORDER ELFDATA2LSB
>>> +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
>>> +#define HOST_ORDER ELFDATA2MSB
>>> +#endif
>>> +
>>> +static const char *outfile;
>>> +
>>> +static void cleanup(void)
>>> +{
>>> +    if (error_message_count > 0 && outfile != NULL)
>>> +            unlink(outfile);
>>> +}
>>> +
>>> +static Elf32_Word read_elf_word(Elf32_Word word, bool swap)
>>> +{
>>> +    return swap ? bswap_32(word) : word;
>>> +}
>>> +
>>> +static Elf32_Half read_elf_half(Elf32_Half half, bool swap)
>>> +{
>>> +    return swap ? bswap_16(half) : half;
>>> +}
>>> +
>>> +static void write_elf_word(Elf32_Word val, Elf32_Word *dst, bool swap)
>>> +{
>>> +    *dst = swap ? bswap_32(val) : val;
>>> +}
>>
>> The macros in arch/x86/vdso/vdso2c.c are IMO much nicer.
>
> Respectfully, I think I'd disagree, but more importantly, vdso2c.c seems
> to assume a little-endian target.
>

That would be easy enough to fix.

The real reason that I went with the macroized approach is that x86
needs to support 32-bit and 64-bit targets with the same host code.
ELF has lots of odd types, and using the macros means that I can't
screw up the width of the integer that I'm converting.

--Andy

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 0/9] ARM: VDSO
  2014-06-30  8:12 ` Ard Biesheuvel
@ 2014-07-01 16:34   ` Nathan Lynch
  2014-07-01 20:08     ` Ard Biesheuvel
  0 siblings, 1 reply; 76+ messages in thread
From: Nathan Lynch @ 2014-07-01 16:34 UTC (permalink / raw)
  To: linux-arm-kernel

On 06/30/2014 03:12 AM, Ard Biesheuvel wrote:
> On 23 June 2014 05:11, Nathan Lynch <nathan_lynch@mentor.com> wrote:
>> Provide fast userspace implementations of gettimeofday and
>> clock_gettime on systems that implement the generic timers extension
>> defined in ARMv7.

...

> Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> 
> On Exynos-5250 (Cortex-A15):
> 
> clock-gettime-monotonic system calls per second: 1759517
> clock-gettime-monotonic vdso calls per second:   6027915 (3.43x speedup)
> clock-getres-monotonic system calls per second: 2144055
> clock-getres-monotonic vdso calls per second:   82783103 (38.61x speedup)
> clock-gettime-monotonic-coarse system calls per second: 1971433
> clock-gettime-monotonic-coarse vdso calls per second:   10710734 (5.43x speedup)
> clock-getres-monotonic-coarse system calls per second: 2182380
> clock-getres-monotonic-coarse vdso calls per second:   76710594 (35.15x speedup)
> clock-gettime-realtime system calls per second: 1722524
> clock-gettime-realtime vdso calls per second:   6309212 (3.66x speedup)
> clock-getres-realtime system calls per second: 2182357
> clock-getres-realtime vdso calls per second:   83120713 (38.09x speedup)
> clock-gettime-realtime-coarse system calls per second: 2085498
> clock-gettime-realtime-coarse vdso calls per second:   11326069 (5.43x speedup)
> clock-getres-realtime-coarse system calls per second: 2178266
> clock-getres-realtime-coarse vdso calls per second:   76731175 (35.23x speedup)
> Note: vDSO version of getcpu not found
> getcpu system calls per second: 2645300
> getcpu vdso calls per second:   2612154 (0.99x speedup)
> Note: vDSO version of getcpu not found
> Note: vDSO version of getcpu not found
> gettimeofday system calls per second: 1707745
> gettimeofday vdso calls per second:   6474501 (3.79x speedup)

Thank you very much for testing (especially on a platform I don't have).

These results match up with what I get on OMAP5 (also Cortex-A15).

Since it looks like I will need to make some significant changes for the
next version, I think I can't in good conscience carry your Tested-by on
to v8 (although I'm open to different opinions).  But I still very much
appreciate it.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 8/9] ARM: vdso initialization, mapping, and synchronization
  2014-07-01 14:17           ` Andy Lutomirski
@ 2014-07-01 17:27             ` Christopher Covington
  2014-07-02 14:40             ` Will Deacon
  1 sibling, 0 replies; 76+ messages in thread
From: Christopher Covington @ 2014-07-01 17:27 UTC (permalink / raw)
  To: linux-arm-kernel

On 07/01/2014 10:17 AM, Andy Lutomirski wrote:
> On Tue, Jul 1, 2014 at 7:15 AM, Will Deacon <will.deacon@arm.com> wrote:
>> On Tue, Jul 01, 2014 at 03:11:04PM +0100, Nathan Lynch wrote:
>>> On 07/01/2014 04:03 AM, Will Deacon wrote:
>>>> On Mon, Jun 30, 2014 at 10:37:48PM +0100, Andy Lutomirski wrote:
>>>>> On 06/22/2014 08:11 PM, Nathan Lynch wrote:
>>>>>> Initialize the vdso page list at boot, install the vdso mapping at
>>>>>> exec time, and update the data page during timer ticks.  This code is
>>>>>> not built if CONFIG_VDSO is not enabled.
>>>>>>
>>>>>> Account for the vdso length when randomizing the offset from the
>>>>>> stack.  The vdso is placed immediately following the sigpage with a
>>>>>> separate install_special_mapping call in arm_install_vdso.
>>>>
>>>> [...]
>>>>
>>>>>> +/* assumes mmap_sem is write-locked */
>>>>>> +void arm_install_vdso(struct mm_struct *mm, unsigned long addr)
>>>>>> +{
>>>>>> + int ret;
>>>>>> +
>>>>>> + mm->context.vdso = ~0UL;
>>>>>> +
>>>>>> + if (vdso_pagelist == NULL)
>>>>>> +         return;
>>>>>> +
>>>>>> + /*
>>>>>> +  * Put vDSO base into mm struct before calling
>>>>>> +  * install_special_mapping so the perf counter mmap tracking
>>>>>> +  * code will recognise it as a vDSO.
>>>>>> +  */
>>>>>> + mm->context.vdso = addr;
>>>>>> +
>>>>>> + ret = install_special_mapping(mm, addr, vdso_mapping_len,
>>>>>> +                               VM_READ|VM_EXEC|
>>>>>> +                               VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
>>>>>> +                               vdso_pagelist);
>>>>>
>>>>> Eek.  You're mapping the shared data VM_MAYWRITE.  This will cause
>>>>> bizarre and confusing failures if ptrace pokes at it.
>>>>
>>>> Hmm, but how else can we support software breakpoints on the vdso?
>>>
>>> I believe Andy is suggesting separate VMAs (with different VM flags) for
>>> the VDSO's data and code.  So, breakpoints in code would work, but
>>> attempts to modify the data page via ptrace() would fail outright
>>> instead of silently COWing.
>>
>> Ah, yes. That makes a lot of sense for the data page -- we should do
>> something similar on arm64 too, since the CoW will break everything for the
>> task being debugged. We could also drop the EXEC flags too.
> 
> If you do this, I have a slight preference for the new vma being
> called "[vvar]" to match x86.  It'll make the CRIU people happy if and
> when they port it to ARM.

CRIU is functional on AArch32 and AArch64. I use norandmaps and identical
kernels so I've not needed explicit VDSO support (on A64), but it'd certainly
be nice for whoever does need it for things to be as much the same as
possible. Here is some description of it:

http://git.criu.org/?p=criu.git;a=commit;h=fe7b8aeb8c65e11e190282aae8db2d2bebd4f6e9

Christopher

-- 
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by the Linux Foundation.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 0/9] ARM: VDSO
  2014-07-01 16:34   ` Nathan Lynch
@ 2014-07-01 20:08     ` Ard Biesheuvel
  2014-07-01 22:44       ` Russell King - ARM Linux
  0 siblings, 1 reply; 76+ messages in thread
From: Ard Biesheuvel @ 2014-07-01 20:08 UTC (permalink / raw)
  To: linux-arm-kernel

On 1 July 2014 18:34, Nathan Lynch <Nathan_Lynch@mentor.com> wrote:
> On 06/30/2014 03:12 AM, Ard Biesheuvel wrote:
>> On 23 June 2014 05:11, Nathan Lynch <nathan_lynch@mentor.com> wrote:
>>> Provide fast userspace implementations of gettimeofday and
>>> clock_gettime on systems that implement the generic timers extension
>>> defined in ARMv7.
>
> ...
>
>> Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>>
>> On Exynos-5250 (Cortex-A15):
>>
>> clock-gettime-monotonic system calls per second: 1759517
>> clock-gettime-monotonic vdso calls per second:   6027915 (3.43x speedup)
>> clock-getres-monotonic system calls per second: 2144055
>> clock-getres-monotonic vdso calls per second:   82783103 (38.61x speedup)
>> clock-gettime-monotonic-coarse system calls per second: 1971433
>> clock-gettime-monotonic-coarse vdso calls per second:   10710734 (5.43x speedup)
>> clock-getres-monotonic-coarse system calls per second: 2182380
>> clock-getres-monotonic-coarse vdso calls per second:   76710594 (35.15x speedup)
>> clock-gettime-realtime system calls per second: 1722524
>> clock-gettime-realtime vdso calls per second:   6309212 (3.66x speedup)
>> clock-getres-realtime system calls per second: 2182357
>> clock-getres-realtime vdso calls per second:   83120713 (38.09x speedup)
>> clock-gettime-realtime-coarse system calls per second: 2085498
>> clock-gettime-realtime-coarse vdso calls per second:   11326069 (5.43x speedup)
>> clock-getres-realtime-coarse system calls per second: 2178266
>> clock-getres-realtime-coarse vdso calls per second:   76731175 (35.23x speedup)
>> Note: vDSO version of getcpu not found
>> getcpu system calls per second: 2645300
>> getcpu vdso calls per second:   2612154 (0.99x speedup)
>> Note: vDSO version of getcpu not found
>> Note: vDSO version of getcpu not found
>> gettimeofday system calls per second: 1707745
>> gettimeofday vdso calls per second:   6474501 (3.79x speedup)
>
> Thank you very much for testing (especially on a platform I don't have).
>
> These results match up with what I get on OMAP5 (also Cortex-A15).
>

Good.

> Since it looks like I will need to make some significant changes for the
> next version, I think I can't in good conscience carry your Tested-by on
> to v8 (although I'm open to different opinions).  But I still very much
> appreciate it.
>

We (at Linaro) had independently identified VDSO for ARM as a topic of
interest after seeing gettimeofday() turn up in a couple of benchmarks
(which btw seem to be the primary users of gettimeofday() at such a
high rate), so of course, when someone else steps up and does the
work, i am happy to at least spend some time testing it. Therefore, I
would be happy to test your new version either before or after you
(re)post it, whichever you prefer.

Regards,
Ard.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 0/9] ARM: VDSO
  2014-07-01 20:08     ` Ard Biesheuvel
@ 2014-07-01 22:44       ` Russell King - ARM Linux
  0 siblings, 0 replies; 76+ messages in thread
From: Russell King - ARM Linux @ 2014-07-01 22:44 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 01, 2014 at 10:08:07PM +0200, Ard Biesheuvel wrote:
> We (at Linaro) had independently identified VDSO for ARM as a topic of
> interest after seeing gettimeofday() turn up in a couple of benchmarks
> (which btw seem to be the primary users of gettimeofday() at such a
> high rate), so of course, when someone else steps up and does the
> work, i am happy to at least spend some time testing it. Therefore, I
> would be happy to test your new version either before or after you
> (re)post it, whichever you prefer.

As has been covered by Nathan in a previous reply - the VDSO is only
of real benefit on CPUs with the architected timer.  Those without
this do not have access from userspace to an appropriate timer to
allow the VDSO to compute the current time.

Hence, the VDSO will just call into the kernel via the standard (and
very same) syscalls that glibc would otherwise have used.

This is illustrated nicely by the results posted for iMX6, which
reflects how the VDSO is going to affect platforms without the
architected timer.

-- 
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 8/9] ARM: vdso initialization, mapping, and synchronization
  2014-07-01 14:17           ` Andy Lutomirski
  2014-07-01 17:27             ` Christopher Covington
@ 2014-07-02 14:40             ` Will Deacon
  2014-07-02 15:54               ` Andy Lutomirski
  1 sibling, 1 reply; 76+ messages in thread
From: Will Deacon @ 2014-07-02 14:40 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Andy,

On Tue, Jul 01, 2014 at 03:17:23PM +0100, Andy Lutomirski wrote:
> On Tue, Jul 1, 2014 at 7:15 AM, Will Deacon <will.deacon@arm.com> wrote:
> > On Tue, Jul 01, 2014 at 03:11:04PM +0100, Nathan Lynch wrote:
> >> I believe Andy is suggesting separate VMAs (with different VM flags) for
> >> the VDSO's data and code.  So, breakpoints in code would work, but
> >> attempts to modify the data page via ptrace() would fail outright
> >> instead of silently COWing.
> >
> > Ah, yes. That makes a lot of sense for the data page -- we should do
> > something similar on arm64 too, since the CoW will break everything for the
> > task being debugged. We could also drop the EXEC flags too.
> 
> If you do this, I have a slight preference for the new vma being
> called "[vvar]" to match x86.  It'll make the CRIU people happy if and
> when they port it to ARM.

I quickly hacked something (see below) and now I see the following in
/proc/$$/maps:

7fa1574000-7fa1575000 r-xp 00000000 00:00 0                              [vdso]
7fa1575000-7fa1576000 r--p 00000000 00:00 0                              [vvar]

Is that what you're after?

Will

--->8

diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index 50384fec56c4..84cafbc3eb54 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -138,11 +138,12 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
 				int uses_interp)
 {
 	struct mm_struct *mm = current->mm;
-	unsigned long vdso_base, vdso_mapping_len;
+	unsigned long vdso_base, vdso_text_len, vdso_mapping_len;
 	int ret;
 
+	vdso_text_len = vdso_pages << PAGE_SHIFT;
 	/* Be sure to map the data page */
-	vdso_mapping_len = (vdso_pages + 1) << PAGE_SHIFT;
+	vdso_mapping_len = vdso_text_len + PAGE_SIZE;
 
 	down_write(&mm->mmap_sem);
 	vdso_base = get_unmapped_area(NULL, 0, vdso_mapping_len, 0, 0);
@@ -152,35 +153,52 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
 	}
 	mm->context.vdso = (void *)vdso_base;
 
-	ret = install_special_mapping(mm, vdso_base, vdso_mapping_len,
+	ret = install_special_mapping(mm, vdso_base, vdso_text_len,
 				      VM_READ|VM_EXEC|
 				      VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
 				      vdso_pagelist);
-	if (ret) {
-		mm->context.vdso = NULL;
+	if (ret)
+		goto up_fail;
+
+	vdso_base += vdso_text_len;
+	ret = install_special_mapping(mm, vdso_base, PAGE_SIZE,
+				      VM_READ|VM_MAYREAD,
+				      vdso_pagelist + vdso_pages);
+	if (ret)
 		goto up_fail;
-	}
 
-up_fail:
 	up_write(&mm->mmap_sem);
+	return 0;
 
+up_fail:
+	mm->context.vdso = NULL;
+	up_write(&mm->mmap_sem);
 	return ret;
 }
 
 const char *arch_vma_name(struct vm_area_struct *vma)
 {
+	unsigned long vdso_text;
+
+	if (!vma->vm_mm)
+		return NULL;
+
+	vdso_text = (unsigned long)vma->vm_mm->context.vdso;
+
 	/*
 	 * We can re-use the vdso pointer in mm_context_t for identifying
 	 * the vectors page for compat applications. The vDSO will always
 	 * sit above TASK_UNMAPPED_BASE and so we don't need to worry about
 	 * it conflicting with the vectors base.
 	 */
-	if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) {
+	if (vma->vm_start == vdso_text) {
 #ifdef CONFIG_COMPAT
 		if (vma->vm_start == AARCH32_VECTORS_BASE)
 			return "[vectors]";
 #endif
 		return "[vdso]";
+	} else if (vma->vm_start == (vdso_text + (vdso_pages << PAGE_SHIFT))) {
+		return "[vvar]";
 	}
 
 	return NULL;

^ permalink raw reply related	[flat|nested] 76+ messages in thread

* [PATCH v7 8/9] ARM: vdso initialization, mapping, and synchronization
  2014-07-02 14:40             ` Will Deacon
@ 2014-07-02 15:54               ` Andy Lutomirski
  2014-07-02 16:18                 ` Nathan Lynch
  0 siblings, 1 reply; 76+ messages in thread
From: Andy Lutomirski @ 2014-07-02 15:54 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jul 2, 2014 at 7:40 AM, Will Deacon <will.deacon@arm.com> wrote:
> Hi Andy,
>
> On Tue, Jul 01, 2014 at 03:17:23PM +0100, Andy Lutomirski wrote:
>> On Tue, Jul 1, 2014 at 7:15 AM, Will Deacon <will.deacon@arm.com> wrote:
>> > On Tue, Jul 01, 2014 at 03:11:04PM +0100, Nathan Lynch wrote:
>> >> I believe Andy is suggesting separate VMAs (with different VM flags) for
>> >> the VDSO's data and code.  So, breakpoints in code would work, but
>> >> attempts to modify the data page via ptrace() would fail outright
>> >> instead of silently COWing.
>> >
>> > Ah, yes. That makes a lot of sense for the data page -- we should do
>> > something similar on arm64 too, since the CoW will break everything for the
>> > task being debugged. We could also drop the EXEC flags too.
>>
>> If you do this, I have a slight preference for the new vma being
>> called "[vvar]" to match x86.  It'll make the CRIU people happy if and
>> when they port it to ARM.
>
> I quickly hacked something (see below) and now I see the following in
> /proc/$$/maps:
>
> 7fa1574000-7fa1575000 r-xp 00000000 00:00 0                              [vdso]
> 7fa1575000-7fa1576000 r--p 00000000 00:00 0                              [vvar]
>
> Is that what you're after?

Yes, with caveats.

Caveat 1: (minor) if you use _install_special_mapping, then you'll fix
an mremap bug and most of arch_vma_name can go away.

Caveat 2: (major) I'm kind of surprised that this, or the current
code, works reliably.  You're doing something that I tried briefly for
x86_64:

        _end = .;
        PROVIDE(end = .);

        . = ALIGN(PAGE_SIZE);
        PROVIDE(_vdso_data = .);

This sounds great, except that you're assuming that vdso_end -
vdso_start == ALIGN(_end, PAGE_SIZE) - (vdso base address).

If you *fully* strip the vdso (eu-strip --strip-sections), then this
is true: eu-strip --strip-sections outputs just the PT_LOAD piece of
the vdso.  But any binutils-generated incompletely stripped ELF image
contains a section table and possible non-allocatable sections at the
end.  If these exceed the amount of unused space in the last PT_LOAD
page, then they'll spill into the next page, and _vdso_data in the
vdso will no longer match the address at which vdso.c loads it.  Boom!

I bet you're getting away with this because the whole arm64 vdso seems
to be written in assembly, so it seems extremely unlikely to exceed
one page minus a few hundred bytes.  But if you start adding
complexity, you might get unlucky.

The x86_32 solution in v3.15 was to simply reverse the order: stick
the data page before the vdso instead of after it.  This seems to work
fine.

The x86 (all variants) solution in v3.16-rc1 was to fully strip the
vdso.  This broke gdb (and Go, but you won't have that particular
problem on ARM).  In v3.16-rc3, we're using a hack that moves the
section table into an actual allocated section -- this works, and if
the kernel builds then it's guaranteed to work, but I'm now fighting
with weird output from various binutils versions, and at least one
version of binutils can't build 3.16-rc3 for x86_64.

Anyway, all solutions are messy, but the arm64 one has the particular
disadvantage of failing silently.  I think I just got lucky on x86_64
in that I happened to trigger the failure myself before I ever sent
out the patches.

--Andy

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 8/9] ARM: vdso initialization, mapping, and synchronization
  2014-07-02 15:54               ` Andy Lutomirski
@ 2014-07-02 16:18                 ` Nathan Lynch
  2014-07-02 16:27                   ` Will Deacon
  0 siblings, 1 reply; 76+ messages in thread
From: Nathan Lynch @ 2014-07-02 16:18 UTC (permalink / raw)
  To: linux-arm-kernel

On 07/02/2014 10:54 AM, Andy Lutomirski wrote:
> Caveat 2: (major) I'm kind of surprised that this, or the current
> code, works reliably.  You're doing something that I tried briefly for
> x86_64:
> 
>         _end = .;
>         PROVIDE(end = .);
> 
>         . = ALIGN(PAGE_SIZE);
>         PROVIDE(_vdso_data = .);
> 
> This sounds great, except that you're assuming that vdso_end -
> vdso_start == ALIGN(_end, PAGE_SIZE) - (vdso base address).
> 
> If you *fully* strip the vdso (eu-strip --strip-sections), then this
> is true: eu-strip --strip-sections outputs just the PT_LOAD piece of
> the vdso.  But any binutils-generated incompletely stripped ELF image
> contains a section table and possible non-allocatable sections at the
> end.  If these exceed the amount of unused space in the last PT_LOAD
> page, then they'll spill into the next page, and _vdso_data in the
> vdso will no longer match the address at which vdso.c loads it.  Boom!
> 
> I bet you're getting away with this because the whole arm64 vdso seems
> to be written in assembly, so it seems extremely unlikely to exceed
> one page minus a few hundred bytes.  But if you start adding
> complexity, you might get unlucky.

This is why I switched (in v5) the proposed 32-bit ARM VDSO to place the
data page before the code -- adding -frecord-gcc-switches to the
compiler flags was enough to break it.

I meant to call Will's attention to it at the time for arm64's sake, but
I guess it slipped my mind... sorry.

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 8/9] ARM: vdso initialization, mapping, and synchronization
  2014-07-02 16:18                 ` Nathan Lynch
@ 2014-07-02 16:27                   ` Will Deacon
  2014-07-02 16:47                     ` Andy Lutomirski
  0 siblings, 1 reply; 76+ messages in thread
From: Will Deacon @ 2014-07-02 16:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jul 02, 2014 at 05:18:59PM +0100, Nathan Lynch wrote:
> On 07/02/2014 10:54 AM, Andy Lutomirski wrote:
> > Caveat 2: (major) I'm kind of surprised that this, or the current
> > code, works reliably.  You're doing something that I tried briefly for
> > x86_64:
> > 
> >         _end = .;
> >         PROVIDE(end = .);
> > 
> >         . = ALIGN(PAGE_SIZE);
> >         PROVIDE(_vdso_data = .);
> > 
> > This sounds great, except that you're assuming that vdso_end -
> > vdso_start == ALIGN(_end, PAGE_SIZE) - (vdso base address).
> > 
> > If you *fully* strip the vdso (eu-strip --strip-sections), then this
> > is true: eu-strip --strip-sections outputs just the PT_LOAD piece of
> > the vdso.  But any binutils-generated incompletely stripped ELF image
> > contains a section table and possible non-allocatable sections at the
> > end.  If these exceed the amount of unused space in the last PT_LOAD
> > page, then they'll spill into the next page, and _vdso_data in the
> > vdso will no longer match the address at which vdso.c loads it.  Boom!
> > 
> > I bet you're getting away with this because the whole arm64 vdso seems
> > to be written in assembly, so it seems extremely unlikely to exceed
> > one page minus a few hundred bytes.  But if you start adding
> > complexity, you might get unlucky.
> 
> This is why I switched (in v5) the proposed 32-bit ARM VDSO to place the
> data page before the code -- adding -frecord-gcc-switches to the
> compiler flags was enough to break it.
> 
> I meant to call Will's attention to it at the time for arm64's sake, but
> I guess it slipped my mind... sorry.

Hmm, so I could definitely look at doing the same thing, but I don't know if
we actually need to for arm64. As Andy points out, we're written entirely in
assembly and we objcopy -S to create the vdso.so. I've dumped the headers
below and everything appears to be PT_LOAD.

Will

--->8

arch/arm64/kernel/vdso/vdso.so:     file format elf64-littleaarch64
arch/arm64/kernel/vdso/vdso.so
architecture: aarch64, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
start address 0x00000000000002d0

Program Header:
    LOAD off    0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**4
         filesz 0x00000000000006e8 memsz 0x00000000000006e8 flags r-x
 DYNAMIC off    0x00000000000005d8 vaddr 0x00000000000005d8 paddr 0x00000000000005d8 align 2**3
         filesz 0x00000000000000f0 memsz 0x00000000000000f0 flags r--
    NOTE off    0x00000000000002b8 vaddr 0x00000000000002b8 paddr 0x00000000000002b8 align 2**2
         filesz 0x0000000000000018 memsz 0x0000000000000018 flags r--
EH_FRAME off    0x00000000000004f0 vaddr 0x00000000000004f0 paddr 0x00000000000004f0 align 2**2
         filesz 0x0000000000000034 memsz 0x0000000000000034 flags r--

Dynamic Section:
  SONAME               linux-vdso.so.1
  HASH                 0x0000000000000120
  STRTAB               0x00000000000001f8
  SYMTAB               0x0000000000000150
  STRSZ                0x0000000000000077
  SYMENT               0x0000000000000018
  VERDEF               0x0000000000000280
  VERDEFNUM            0x0000000000000002
  VERSYM               0x0000000000000270

Version definitions:
1 0x01 0x0deebfa1 linux-vdso.so.1
2 0x00 0x075fcb89 LINUX_2.6.39
private flags = 0:

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .hash         00000030  0000000000000120  0000000000000120  00000120  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  1 .dynsym       000000a8  0000000000000150  0000000000000150  00000150  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  2 .dynstr       00000077  00000000000001f8  00000000000001f8  000001f8  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .gnu.version  0000000e  0000000000000270  0000000000000270  00000270  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .gnu.version_d 00000038  0000000000000280  0000000000000280  00000280  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 .note         00000018  00000000000002b8  00000000000002b8  000002b8  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA, LINK_ONCE_SAME_CONTENTS
  6 .text         00000220  00000000000002d0  00000000000002d0  000002d0  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  7 .eh_frame_hdr 00000034  00000000000004f0  00000000000004f0  000004f0  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  8 .eh_frame     000000b0  0000000000000528  0000000000000528  00000528  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  9 .dynamic      000000f0  00000000000005d8  00000000000005d8  000005d8  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 10 .got          00000008  00000000000006c8  00000000000006c8  000006c8  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 11 .got.plt      00000018  00000000000006d0  00000000000006d0  000006d0  2**3
                  CONTENTS, ALLOC, LOAD, DATA
SYMBOL TABLE:
no symbols

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 8/9] ARM: vdso initialization, mapping, and synchronization
  2014-07-02 16:27                   ` Will Deacon
@ 2014-07-02 16:47                     ` Andy Lutomirski
  2014-07-02 17:24                       ` Will Deacon
  0 siblings, 1 reply; 76+ messages in thread
From: Andy Lutomirski @ 2014-07-02 16:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jul 2, 2014 at 9:27 AM, Will Deacon <will.deacon@arm.com> wrote:
> On Wed, Jul 02, 2014 at 05:18:59PM +0100, Nathan Lynch wrote:
>> On 07/02/2014 10:54 AM, Andy Lutomirski wrote:
>> > Caveat 2: (major) I'm kind of surprised that this, or the current
>> > code, works reliably.  You're doing something that I tried briefly for
>> > x86_64:
>> >
>> >         _end = .;
>> >         PROVIDE(end = .);
>> >
>> >         . = ALIGN(PAGE_SIZE);
>> >         PROVIDE(_vdso_data = .);
>> >
>> > This sounds great, except that you're assuming that vdso_end -
>> > vdso_start == ALIGN(_end, PAGE_SIZE) - (vdso base address).
>> >
>> > If you *fully* strip the vdso (eu-strip --strip-sections), then this
>> > is true: eu-strip --strip-sections outputs just the PT_LOAD piece of
>> > the vdso.  But any binutils-generated incompletely stripped ELF image
>> > contains a section table and possible non-allocatable sections at the
>> > end.  If these exceed the amount of unused space in the last PT_LOAD
>> > page, then they'll spill into the next page, and _vdso_data in the
>> > vdso will no longer match the address at which vdso.c loads it.  Boom!
>> >
>> > I bet you're getting away with this because the whole arm64 vdso seems
>> > to be written in assembly, so it seems extremely unlikely to exceed
>> > one page minus a few hundred bytes.  But if you start adding
>> > complexity, you might get unlucky.
>>
>> This is why I switched (in v5) the proposed 32-bit ARM VDSO to place the
>> data page before the code -- adding -frecord-gcc-switches to the
>> compiler flags was enough to break it.
>>
>> I meant to call Will's attention to it at the time for arm64's sake, but
>> I guess it slipped my mind... sorry.
>
> Hmm, so I could definitely look at doing the same thing, but I don't know if
> we actually need to for arm64. As Andy points out, we're written entirely in
> assembly and we objcopy -S to create the vdso.so. I've dumped the headers
> below and everything appears to be PT_LOAD.

Your dump doesn't show the location of the section and section string
tables themselves.  Try:

eu-readelf -l -h -S whatever.so

--Andy

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 8/9] ARM: vdso initialization, mapping, and synchronization
  2014-07-02 16:47                     ` Andy Lutomirski
@ 2014-07-02 17:24                       ` Will Deacon
  2014-07-02 18:34                         ` Andy Lutomirski
  0 siblings, 1 reply; 76+ messages in thread
From: Will Deacon @ 2014-07-02 17:24 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jul 02, 2014 at 05:47:08PM +0100, Andy Lutomirski wrote:
> On Wed, Jul 2, 2014 at 9:27 AM, Will Deacon <will.deacon@arm.com> wrote:
> > On Wed, Jul 02, 2014 at 05:18:59PM +0100, Nathan Lynch wrote:
> >> On 07/02/2014 10:54 AM, Andy Lutomirski wrote:
> >> > Caveat 2: (major) I'm kind of surprised that this, or the current
> >> > code, works reliably.  You're doing something that I tried briefly for
> >> > x86_64:
> >> >
> >> >         _end = .;
> >> >         PROVIDE(end = .);
> >> >
> >> >         . = ALIGN(PAGE_SIZE);
> >> >         PROVIDE(_vdso_data = .);
> >> >
> >> > This sounds great, except that you're assuming that vdso_end -
> >> > vdso_start == ALIGN(_end, PAGE_SIZE) - (vdso base address).
> >> >
> >> > If you *fully* strip the vdso (eu-strip --strip-sections), then this
> >> > is true: eu-strip --strip-sections outputs just the PT_LOAD piece of
> >> > the vdso.  But any binutils-generated incompletely stripped ELF image
> >> > contains a section table and possible non-allocatable sections at the
> >> > end.  If these exceed the amount of unused space in the last PT_LOAD
> >> > page, then they'll spill into the next page, and _vdso_data in the
> >> > vdso will no longer match the address at which vdso.c loads it.  Boom!
> >> >
> >> > I bet you're getting away with this because the whole arm64 vdso seems
> >> > to be written in assembly, so it seems extremely unlikely to exceed
> >> > one page minus a few hundred bytes.  But if you start adding
> >> > complexity, you might get unlucky.
> >>
> >> This is why I switched (in v5) the proposed 32-bit ARM VDSO to place the
> >> data page before the code -- adding -frecord-gcc-switches to the
> >> compiler flags was enough to break it.
> >>
> >> I meant to call Will's attention to it at the time for arm64's sake, but
> >> I guess it slipped my mind... sorry.
> >
> > Hmm, so I could definitely look at doing the same thing, but I don't know if
> > we actually need to for arm64. As Andy points out, we're written entirely in
> > assembly and we objcopy -S to create the vdso.so. I've dumped the headers
> > below and everything appears to be PT_LOAD.
> 
> Your dump doesn't show the location of the section and section string
> tables themselves.  Try:
> 
> eu-readelf -l -h -S whatever.so

Thanks. See below.

Will

--->8

ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              DYN (Shared object file)
  Machine:                           AArch64
  Version:                           0x1
  Entry point address:               0x2d0
  Start of program headers:          64 (bytes into file)
  Start of section headers:          1888 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         4
  Size of section headers:           64 (bytes)
  Number of section headers:         14
  Section header string table index: 13

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .hash             HASH             0000000000000120  00000120
       0000000000000030  0000000000000004   A       2     0     8
  [ 2] .dynsym           DYNSYM           0000000000000150  00000150
       00000000000000a8  0000000000000018   A       3     2     8
  [ 3] .dynstr           STRTAB           00000000000001f8  000001f8
       0000000000000077  0000000000000000   A       0     0     1
  [ 4] .gnu.version      VERSYM           0000000000000270  00000270
       000000000000000e  0000000000000002   A       2     0     2
  [ 5] .gnu.version_d    VERDEF           0000000000000280  00000280
       0000000000000038  0000000000000000   A       3     2     8
  [ 6] .note             NOTE             00000000000002b8  000002b8
       0000000000000018  0000000000000000   A       0     0     4
  [ 7] .text             PROGBITS         00000000000002d0  000002d0
       0000000000000220  0000000000000000  AX       0     0     16
  [ 8] .eh_frame_hdr     PROGBITS         00000000000004f0  000004f0
       0000000000000034  0000000000000000   A       0     0     4
  [ 9] .eh_frame         PROGBITS         0000000000000528  00000528
       00000000000000b0  0000000000000000   A       0     0     8
  [10] .dynamic          DYNAMIC          00000000000005d8  000005d8
       00000000000000f0  0000000000000010  WA       3     0     8
  [11] .got              PROGBITS         00000000000006c8  000006c8
       0000000000000008  0000000000000008  WA       0     0     8
  [12] .got.plt          PROGBITS         00000000000006d0  000006d0
       0000000000000018  0000000000000008  WA       0     0     8
  [13] .shstrtab         STRTAB           0000000000000000  000006e8
       0000000000000078  0000000000000000           0     0     1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  LOAD           0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x00000000000006e8 0x00000000000006e8  R E    10
  DYNAMIC        0x00000000000005d8 0x00000000000005d8 0x00000000000005d8
                 0x00000000000000f0 0x00000000000000f0  R      8
  NOTE           0x00000000000002b8 0x00000000000002b8 0x00000000000002b8
                 0x0000000000000018 0x0000000000000018  R      4
  GNU_EH_FRAME   0x00000000000004f0 0x00000000000004f0 0x00000000000004f0
                 0x0000000000000034 0x0000000000000034  R      4

 Section to Segment mapping:
  Segment Sections...
   00     .hash .dynsym .dynstr .gnu.version .gnu.version_d .note .text .eh_frame_hdr .eh_frame .dynamic .got .got.plt 
   01     .dynamic 
   02     .note 
   03     .eh_frame_hdr 

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 8/9] ARM: vdso initialization, mapping, and synchronization
  2014-07-02 17:24                       ` Will Deacon
@ 2014-07-02 18:34                         ` Andy Lutomirski
  2014-07-02 18:54                           ` Will Deacon
  0 siblings, 1 reply; 76+ messages in thread
From: Andy Lutomirski @ 2014-07-02 18:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jul 2, 2014 at 10:24 AM, Will Deacon <will.deacon@arm.com> wrote:
> On Wed, Jul 02, 2014 at 05:47:08PM +0100, Andy Lutomirski wrote:
>> On Wed, Jul 2, 2014 at 9:27 AM, Will Deacon <will.deacon@arm.com> wrote:
>> > On Wed, Jul 02, 2014 at 05:18:59PM +0100, Nathan Lynch wrote:
>> >> On 07/02/2014 10:54 AM, Andy Lutomirski wrote:
>> >
>> > Hmm, so I could definitely look at doing the same thing, but I don't know if
>> > we actually need to for arm64. As Andy points out, we're written entirely in
>> > assembly and we objcopy -S to create the vdso.so. I've dumped the headers
>> > below and everything appears to be PT_LOAD.
>>
>> Your dump doesn't show the location of the section and section string
>> tables themselves.  Try:
>>
>> eu-readelf -l -h -S whatever.so
>
> Thanks. See below.
>
> Will
>
> --->8
>
> ELF Header:
>   Start of section headers:          1888 (bytes into file)
>   Size of section headers:           64 (bytes)
>   Number of section headers:         14

That's 896 bytes for the section table, starting at offset 1888.

>   Section header string table index: 13


>
> Section Headers:
>   [13] .shstrtab         STRTAB           0000000000000000  000006e8
>        0000000000000078  0000000000000000           0     0     1

120 bytes of section headers strings, starting at offset 1768 (and not
allocatable -- no 'A' here).

>
> Program Headers:
>   Type           Offset             VirtAddr           PhysAddr
>                  FileSiz            MemSiz              Flags  Align
>   LOAD           0x0000000000000000 0x0000000000000000 0x0000000000000000
>                  0x00000000000006e8 0x00000000000006e8  R E    10

The loadable segment is 1768 bytes long, starting at the beginning of
the file (and therefore the beginning of the mapping).

So you have a total of 1016 bytes of non-allocatable stuff at the end
that I've accounted for.  I assume that the whole file is 2784 bytes.

If you added text or data to bring PT_LOAD to between 3081 and 4095
bytes, then the section headers and/or section string table would
cross a page boundary.

--Andy

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 8/9] ARM: vdso initialization, mapping, and synchronization
  2014-07-02 18:34                         ` Andy Lutomirski
@ 2014-07-02 18:54                           ` Will Deacon
  2014-07-22  0:14                             ` Andy Lutomirski
  0 siblings, 1 reply; 76+ messages in thread
From: Will Deacon @ 2014-07-02 18:54 UTC (permalink / raw)
  To: linux-arm-kernel

Cheers for this, Andy.

On Wed, Jul 02, 2014 at 07:34:22PM +0100, Andy Lutomirski wrote:
> On Wed, Jul 2, 2014 at 10:24 AM, Will Deacon <will.deacon@arm.com> wrote:
> > ELF Header:
> >   Start of section headers:          1888 (bytes into file)
> >   Size of section headers:           64 (bytes)
> >   Number of section headers:         14
> 
> That's 896 bytes for the section table, starting at offset 1888.
> 
> >   Section header string table index: 13
> 
> 
> >
> > Section Headers:
> >   [13] .shstrtab         STRTAB           0000000000000000  000006e8
> >        0000000000000078  0000000000000000           0     0     1
> 
> 120 bytes of section headers strings, starting at offset 1768 (and not
> allocatable -- no 'A' here).
> 
> >
> > Program Headers:
> >   Type           Offset             VirtAddr           PhysAddr
> >                  FileSiz            MemSiz              Flags  Align
> >   LOAD           0x0000000000000000 0x0000000000000000 0x0000000000000000
> >                  0x00000000000006e8 0x00000000000006e8  R E    10
> 
> The loadable segment is 1768 bytes long, starting at the beginning of
> the file (and therefore the beginning of the mapping).
> 
> So you have a total of 1016 bytes of non-allocatable stuff at the end
> that I've accounted for.  I assume that the whole file is 2784 bytes.

Correct.

> If you added text or data to bring PT_LOAD to between 3081 and 4095
> bytes, then the section headers and/or section string table would
> cross a page boundary.

Ok, so that explains why things are working at the moment and it sounds like
we have some wiggle room too. I'll look at moving the datapage anyway, since
having these artificial limits is error-prone and fragile, but I don't think
it's something we need to panic about immediately.

Also, if you get to the bottom of your binutils issues with the section
allocation, that might work for us since we don't really have any legacy
binutils supporting arm64.

Will

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 8/9] ARM: vdso initialization, mapping, and synchronization
  2014-07-02 18:54                           ` Will Deacon
@ 2014-07-22  0:14                             ` Andy Lutomirski
  2014-07-22  8:13                               ` Will Deacon
  0 siblings, 1 reply; 76+ messages in thread
From: Andy Lutomirski @ 2014-07-22  0:14 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jul 2, 2014 at 11:54 AM, Will Deacon <will.deacon@arm.com> wrote:
> Cheers for this, Andy.
>
> On Wed, Jul 02, 2014 at 07:34:22PM +0100, Andy Lutomirski wrote:
>> On Wed, Jul 2, 2014 at 10:24 AM, Will Deacon <will.deacon@arm.com> wrote:
>> > ELF Header:
>> >   Start of section headers:          1888 (bytes into file)
>> >   Size of section headers:           64 (bytes)
>> >   Number of section headers:         14
>>
>> That's 896 bytes for the section table, starting at offset 1888.
>>
>> >   Section header string table index: 13
>>
>>
>> >
>> > Section Headers:
>> >   [13] .shstrtab         STRTAB           0000000000000000  000006e8
>> >        0000000000000078  0000000000000000           0     0     1
>>
>> 120 bytes of section headers strings, starting at offset 1768 (and not
>> allocatable -- no 'A' here).
>>
>> >
>> > Program Headers:
>> >   Type           Offset             VirtAddr           PhysAddr
>> >                  FileSiz            MemSiz              Flags  Align
>> >   LOAD           0x0000000000000000 0x0000000000000000 0x0000000000000000
>> >                  0x00000000000006e8 0x00000000000006e8  R E    10
>>
>> The loadable segment is 1768 bytes long, starting at the beginning of
>> the file (and therefore the beginning of the mapping).
>>
>> So you have a total of 1016 bytes of non-allocatable stuff at the end
>> that I've accounted for.  I assume that the whole file is 2784 bytes.
>
> Correct.
>
>> If you added text or data to bring PT_LOAD to between 3081 and 4095
>> bytes, then the section headers and/or section string table would
>> cross a page boundary.
>
> Ok, so that explains why things are working at the moment and it sounds like
> we have some wiggle room too. I'll look at moving the datapage anyway, since
> having these artificial limits is error-prone and fragile, but I don't think
> it's something we need to panic about immediately.
>
> Also, if you get to the bottom of your binutils issues with the section
> allocation, that might work for us since we don't really have any legacy
> binutils supporting arm64.

Just in case anyone still cares about this thread, moving the vvar
area back before the vdso text is queued up for 3.17.  I gave up on
reliably keeping binutils happy with my ugly hack.

--Andy

^ permalink raw reply	[flat|nested] 76+ messages in thread

* [PATCH v7 8/9] ARM: vdso initialization, mapping, and synchronization
  2014-07-22  0:14                             ` Andy Lutomirski
@ 2014-07-22  8:13                               ` Will Deacon
  0 siblings, 0 replies; 76+ messages in thread
From: Will Deacon @ 2014-07-22  8:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 22, 2014 at 01:14:35AM +0100, Andy Lutomirski wrote:
> On Wed, Jul 2, 2014 at 11:54 AM, Will Deacon <will.deacon@arm.com> wrote:
> > Ok, so that explains why things are working at the moment and it sounds like
> > we have some wiggle room too. I'll look at moving the datapage anyway, since
> > having these artificial limits is error-prone and fragile, but I don't think
> > it's something we need to panic about immediately.
> >
> > Also, if you get to the bottom of your binutils issues with the section
> > allocation, that might work for us since we don't really have any legacy
> > binutils supporting arm64.
> 
> Just in case anyone still cares about this thread, moving the vvar
> area back before the vdso text is queued up for 3.17.  I gave up on
> reliably keeping binutils happy with my ugly hack.

The same change is also queued for arm64.

Thanks Andy,

Will

^ permalink raw reply	[flat|nested] 76+ messages in thread

end of thread, other threads:[~2014-07-22  8:13 UTC | newest]

Thread overview: 76+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-06-23  3:11 [PATCH v7 0/9] ARM: VDSO Nathan Lynch
2014-06-23  3:11 ` [PATCH v7 1/9] clocksource: arm_arch_timer: change clocksource name if CP15 unavailable Nathan Lynch
2014-06-23  3:11 ` [PATCH v7 2/9] clocksource: arm_arch_timer: enable counter access for 32-bit ARM Nathan Lynch
2014-06-23  3:11 ` [PATCH v7 3/9] ARM: arch_timer: remove unused functions Nathan Lynch
2014-06-23  3:11 ` [PATCH v7 4/9] arm64: " Nathan Lynch
2014-06-23  3:11 ` [PATCH v7 5/9] ARM: place sigpage at a random offset above stack Nathan Lynch
2014-06-23  3:11 ` [PATCH v7 6/9] ARM: miscellaneous vdso infrastructure, preparation Nathan Lynch
2014-06-30 10:11   ` Arnd Bergmann
2014-06-30 12:27     ` Nathan Lynch
2014-06-30 13:06       ` Arnd Bergmann
2014-06-23  3:11 ` [PATCH v7 7/9] ARM: add vdso user-space code Nathan Lynch
2014-06-28  9:53   ` Russell King - ARM Linux
2014-06-28 10:03     ` Russell King - ARM Linux
2014-06-30 15:56       ` Andy Lutomirski
2014-06-28 15:19     ` Nathan Lynch
2014-06-28 15:26   ` Russell King - ARM Linux
2014-06-28 16:13     ` Nathan Lynch
2014-06-28 18:12       ` Russell King - ARM Linux
2014-06-28 19:45         ` Nathan Lynch
2014-06-28 20:11           ` Russell King - ARM Linux
2014-06-28 21:35             ` Nathan Lynch
2014-06-29  8:34               ` Russell King - ARM Linux
2014-06-29 15:48                 ` Nathan Lynch
2014-06-29 16:07                   ` Russell King - ARM Linux
2014-06-29 23:04                     ` Nathan Lynch
2014-06-30 21:33                     ` Andy Lutomirski
2014-06-30 15:59     ` Andy Lutomirski
2014-06-30 16:50       ` Nathan Lynch
2014-06-30 21:29   ` Andy Lutomirski
2014-07-01  9:00     ` Will Deacon
2014-07-01 13:34       ` Nathan Lynch
2014-07-01 14:11         ` Andy Lutomirski
2014-07-01 13:28     ` Nathan Lynch
2014-07-01 14:56       ` Andy Lutomirski
2014-06-23  3:11 ` [PATCH v7 8/9] ARM: vdso initialization, mapping, and synchronization Nathan Lynch
2014-06-30 21:37   ` Andy Lutomirski
2014-07-01  9:03     ` Will Deacon
2014-07-01 14:11       ` Nathan Lynch
2014-07-01 14:15         ` Will Deacon
2014-07-01 14:17           ` Andy Lutomirski
2014-07-01 17:27             ` Christopher Covington
2014-07-02 14:40             ` Will Deacon
2014-07-02 15:54               ` Andy Lutomirski
2014-07-02 16:18                 ` Nathan Lynch
2014-07-02 16:27                   ` Will Deacon
2014-07-02 16:47                     ` Andy Lutomirski
2014-07-02 17:24                       ` Will Deacon
2014-07-02 18:34                         ` Andy Lutomirski
2014-07-02 18:54                           ` Will Deacon
2014-07-22  0:14                             ` Andy Lutomirski
2014-07-22  8:13                               ` Will Deacon
2014-07-01 14:01     ` Nathan Lynch
2014-07-01 14:09       ` Andy Lutomirski
2014-07-01 14:14         ` Russell King - ARM Linux
2014-06-23  3:11 ` [PATCH v7 9/9] ARM: add CONFIG_VDSO Kconfig and Makefile bits Nathan Lynch
2014-06-27  8:51 ` [PATCH v7 0/9] ARM: VDSO Jan Glauber
2014-06-27  8:57   ` Russell King - ARM Linux
2014-06-27  9:41     ` Ard Biesheuvel
2014-06-27  9:46       ` Russell King - ARM Linux
2014-06-27 17:01         ` Nathan Lynch
2014-06-28  9:42           ` Russell King - ARM Linux
2014-06-28  9:55             ` Russell King - ARM Linux
2014-06-28 14:49               ` Russell King - ARM Linux
2014-06-30  7:27                 ` Arnd Bergmann
2014-06-30  7:43             ` Arnd Bergmann
2014-06-30 18:27               ` Nathan Lynch
2014-06-27 16:00   ` Nathan Lynch
2014-06-30 16:03   ` Andy Lutomirski
2014-06-30  8:12 ` Ard Biesheuvel
2014-07-01 16:34   ` Nathan Lynch
2014-07-01 20:08     ` Ard Biesheuvel
2014-07-01 22:44       ` Russell King - ARM Linux
2014-06-30 14:40 ` Will Deacon
2014-06-30 15:42   ` Nathan Lynch
2014-06-30 21:56     ` Andy Lutomirski
2014-07-01  9:04       ` Will Deacon

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.