ARM: vDSO gettimeofday using generic timer architecture
Subsystems (3)
PATCH v2 1/1 ARM: vDSO gettimeofday using generic timer architecture
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).
Tested on OMAP5, i.MX6, and qemu/versatilepb using a LD_PRELOAD shim to redirect system calls to the vDSO. I plan to undertake adding proper support to glibc if the overall approach is acceptable.
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.
---
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
arch/arm/Kconfig | 1 + arch/arm/include/asm/arch_timer.h | 7 +- arch/arm/include/asm/auxvec.h | 7 + arch/arm/include/asm/elf.h | 6 + arch/arm/include/asm/mmu.h | 1 + arch/arm/include/asm/vdso.h | 28 ++++ arch/arm/include/asm/vdso_datapage.h | 45 +++++ arch/arm/kernel/Makefile | 3 +- arch/arm/kernel/process.c | 16 +- arch/arm/kernel/vdso.c | 177 ++++++++++++++++++++ arch/arm/kernel/vdso/.gitignore | 1 + arch/arm/kernel/vdso/Makefile | 46 ++++++ arch/arm/kernel/vdso/vdso.S | 35 ++++ arch/arm/kernel/vdso/vdso.lds.S | 87 ++++++++++ arch/arm/kernel/vdso/vgettimeofday.c | 312 +++++++++++++++++++++++++++++++++++ 15 files changed, 766 insertions(+), 6 deletions(-) create mode 100644 arch/arm/include/asm/auxvec.h create mode 100644 arch/arm/include/asm/vdso.h create mode 100644 arch/arm/include/asm/vdso_datapage.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 100644 arch/arm/kernel/vdso/vdso.S create mode 100644 arch/arm/kernel/vdso/vdso.lds.S create mode 100644 arch/arm/kernel/vdso/vgettimeofday.c
arch/arm/Kconfig +1 -0
@@ -23,6 +23,7 @@ config ARM select GENERIC_SMP_IDLE_THREAD select GENERIC_STRNCPY_FROM_USER select GENERIC_STRNLEN_USER + select GENERIC_TIME_VSYSCALL select HARDIRQS_SW_RESEND select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL select HAVE_ARCH_KGDB
arch/arm/include/asm/arch_timer.h +5 -2
@@ -103,13 +103,16 @@ static inline void arch_counter_set_user_access(void) {u32 cntkctl =arch_timer_get_cntkctl (); -/* Disable user access to both physical/virtual counters/timers */ +/* 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_VCT_ACCESS_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); }
arch/arm/include/asm/auxvec.h new file +7 -0
@@ -0,0 +1,7 @@ +#ifndef __ASM_AUXVEC_H +#define __ASM_AUXVEC_H + +/* vDSO location */ +#define AT_SYSINFO_EHDR 33 + +#endif
arch/arm/include/asm/elf.h +6 -0
@@ -1,6 +1,7 @@#ifndef __ASMARM_ELF_H#define __ASMARM_ELF_H +#include <asm/auxvec.h> #include <asm/hwcap.h> /*
@@ -129,6 +130,11 @@ extern unsigned long arch_randomize_brk(struct mm_struct *mm);#define arch_randomize_brk arch_randomize_brk#ifdef CONFIG_MMU +#define ARCH_DLINFO \ +do { \ + NEW_AUX_ENT(AT_SYSINFO_EHDR, \ + (elf_addr_t)current->mm->context.vdso); \ +} while (0)#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1struct linux_binprm ;int arch_setup_additional_pages (struct linux_binprm *,int );
arch/arm/include/asm/mmu.h +1 -0
@@ -11,6 +11,7 @@ typedef struct {#endif unsigned int vmalloc_seq;unsigned long sigpage; +unsigned long vdso; } mm_context_t;#ifdef CONFIG_CPU_HAS_ASID
arch/arm/include/asm/vdso.h new file +28 -0
@@ -0,0 +1,28 @@ +#ifndef __ASM_VDSO_H +#define __ASM_VDSO_H + +#ifdef __KERNEL__ + +#ifndef __ASSEMBLY__ + +#include <linux/mm_types.h> +#include <asm/mmu.h> + +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 (void ); + +extern char vdso_start, vdso_end; + +#endif /* __ASSEMBLY__ */ + +#define VDSO_LBASE 0x0 + +#endif /* __KERNEL__ */ + +#endif /* __ASM_VDSO_H */
arch/arm/include/asm/vdso_datapage.h new file +45 -0
45 lines not on this page · raw message
arch/arm/kernel/Makefile +2 -1
@@ -18,7 +18,8 @@ CFLAGS_REMOVE_return_address.o = -pg obj-y := elf.o entry-common.o irq.o opcodes.o \ process.o ptrace.o return_address.o \ setup.o signal.o sigreturn_codes.o \ - stacktrace.o sys_arm.o time.o traps.o + stacktrace.o sys_arm.o time.o traps.o \ + vdso.o vdso/ obj-$(CONFIG_ATAGS) += atags_parse.o obj-$(CONFIG_ATAGS_PROC) += atags_proc.o
arch/arm/kernel/process.c +13 -3
@@ -41,6 +41,7 @@#include <asm/stacktrace.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 struct page *signal_page;
@@ -505,6 +513,8 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)if (ret ==0 ) mm->context.sigpage = addr; +arm_install_vdso (); + up_fail:up_write (&mm->mmap_sem);return ret;
arch/arm/kernel/vdso.c new file +177 -0
177 lines not on this page · raw message
arch/arm/kernel/vdso/.gitignore new file +1 -0
@@ -0,0 +1 @@ +vdso.lds
arch/arm/kernel/vdso/Makefile new file +46 -0
46 lines not on this page · raw message
arch/arm/kernel/vdso/vdso.S new file +35 -0
@@ -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 <[email protected]> + */ + +#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
arch/arm/kernel/vdso/vdso.lds.S new file +87 -0
87 lines not on this page · raw message
arch/arm/kernel/vdso/vgettimeofday.c new file +312 -0
312 lines not on this page · raw message
Signature · 1 line
1.8.3.1
PATCH v2 1/1 ARM: vDSO gettimeofday using generic timer architecture
arch/arm/kernel/vdso.c line 68
Quoted 7 lines · Nathan Lynch
arch/arm/kernel/vdso.c new file +7
-0+/* Grab the vDSO code pages. */ +for (i =0 ; i < vdso_pages; i++) { + pg =virt_to_page (&vdso_start + i*PAGE_SIZE ); +ClearPageReserved (pg); +get_page (pg); + vdso_pagelist[i] = pg; + }
Why do we want to clear the reserved status? This looks over complicated to me.
arch/arm/kernel/vdso.c line 79
Quoted 11 lines
arch/arm/kernel/vdso.c new file +11
-0+ +/* Sanity check the shared object header. */ + vbase =vmap (vdso_pagelist,1 ,0 ,PAGE_KERNEL ); +if (vbase ==NULL ) { +pr_err ("Failed to map vDSO pagelist!\n" ); +return -ENOMEM ; + }else if (memcmp (vbase,"\177ELF" ,4 )) { +pr_err ("vDSO is not a valid ELF object!\n" ); + ret = -EINVAL ; + goto unmap; + }
Why do we need to vmap() pages which are already accessible - vdso_start must be part of the kernel image, and therefore will be accessible via standard mappings.
arch/arm/kernel/vdso.c line 84
Quoted 5 lines
arch/arm/kernel/vdso.c new file +5
-0+ +/* Grab the vDSO data page. */ + pg =virt_to_page (vdso_data); +get_page (pg); + vdso_pagelist[i] = pg;
Same goes for this.
arch/arm/kernel/vdso/vgettimeofday.c line 65
Quoted 8 lines
arch/arm/kernel/vdso/vgettimeofday.c new file +8
-0+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; + registerlong ret asm ("r0" ); + register long nr asm("r7") = __NR_clock_gettime; + + asm("swi #0" :"=r" (ret) :"r" (clkid),"r" (ts),"r" (nr) :"memory" );
This isn't compatible with OABI, so either this must not be enabled when AEABI is disabled, or this needs to be fixed.
arch/arm/kernel/vdso/vgettimeofday.c line 244
Quoted 12 lines
arch/arm/kernel/vdso/vgettimeofday.c new file +12
-0+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; + registerlong ret asm ("r0" ); + register long nr asm("r7") = __NR_clock_getres; + + asmvolatile ( +"swi #0" : +"=r" (ret) : +"r" (clkid),"r" (ts),"r" (nr) : +"memory" );
Same here.
arch/arm/kernel/vdso/vgettimeofday.c line 285
Quoted 8 lines
arch/arm/kernel/vdso/vgettimeofday.c new file +8
-0+static long gettimeofday_fallback (struct timeval *_tv,struct timezone *_tz) +{ + register struct timezone *tz asm("r1") = _tz; + register struct timeval *tv asm("r0") = _tv; + registerlong ret asm ("r0" ); + register long nr asm("r7") = __NR_gettimeofday; + + asm("swi #0" :"=r" (ret) :"r" (tv),"r" (tz),"r" (nr) :"memory" );
and here.
Signature · 3 lines
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up. Estimation in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad. Estimate before purchase was "up to 13.2Mbit".
PATCH v2 1/1 ARM: vDSO gettimeofday using generic timer architecture
Hi Russell,
Quoted 12 lines · Russell King - ARM Linux
arch/arm/kernel/vdso.c line 68
Quoted 7 lines · Nathan Lynch
arch/arm/kernel/vdso.c new file +7
-0+/* Grab the vDSO code pages. */ +for (i =0 ; i < vdso_pages; i++) { + pg =virt_to_page (&vdso_start + i*PAGE_SIZE ); +ClearPageReserved (pg); +get_page (pg); + vdso_pagelist[i] = pg; + }Why do we want to clear the reserved status? This looks over complicated to me.
This looks like it was inherited from the PowerPC code where the behaviour of set_pte_at would change dependent on whether or not the page was reserved (set_pte_at->set_pte_filter->maybe_pte_to_page). I think we can safely remove this from ARM and ARM64.
Quoted 7 lines
Quoted 7 lines
arch/arm/kernel/vdso.c new file +7
-0+ +/* Sanity check the shared object header. */ + vbase =vmap (vdso_pagelist,1 ,0 ,PAGE_KERNEL ); +if (vbase ==NULL ) { +pr_err ("Failed to map vDSO pagelist!\n" ); +return -ENOMEM ; + }else if (memcmp (vbase,"\177ELF" ,4 )) {
Quoted 9 lines
arch/arm/kernel/vdso.c line 79
Quoted 4 lines
arch/arm/kernel/vdso.c new file +4
-0+pr_err ("vDSO is not a valid ELF object!\n" ); + ret = -EINVAL ; + goto unmap; + }Why do we need to
vmap()pages which are already accessible -vdso_startmust be part of the kernel image, and therefore will be accessible via standard mappings.
This is a dress rehersal for install_special_mapping more than anything. If we map the page, and look at the first 4 bytes, are they what we expect?
Quoted 8 lines
arch/arm/kernel/vdso.c line 84
Quoted 5 lines
arch/arm/kernel/vdso.c new file +5
-0+ +/* Grab the vDSO data page. */ + pg =virt_to_page (vdso_data); +get_page (pg); + vdso_pagelist[i] = pg;Same goes for this.
We need the data page so we can remap it into user space via install_special_mapping.
Cheers,
Signature · 1 line
Steve
PATCH v2 1/1 ARM: vDSO gettimeofday using generic timer architecture
Quoted 16 lines · Steve Capper
Hi Russell,
Quoted 12 lines · Russell King - ARM Linux
arch/arm/kernel/vdso.c line 68
Quoted 7 lines · Nathan Lynch
arch/arm/kernel/vdso.c new file +7
-0+/* Grab the vDSO code pages. */ +for (i =0 ; i < vdso_pages; i++) { + pg =virt_to_page (&vdso_start + i*PAGE_SIZE ); +ClearPageReserved (pg); +get_page (pg); + vdso_pagelist[i] = pg; + }Why do we want to clear the reserved status? This looks over complicated to me.
Quoted 4 lines
This looks like it was inherited from the PowerPC code where the behaviour of
set_pte_atwould change dependent on whether or not the page was reserved (set_pte_at->set_pte_filter->maybe_pte_to_page). I think we can safely remove this from ARM and ARM64.
Great, so we can get rid of that and the get_page() on the vdso data page below.
Quoted 17 lines
Quoted 7 lines
Quoted 7 lines
arch/arm/kernel/vdso.c new file +7
-0+ +/* Sanity check the shared object header. */ + vbase =vmap (vdso_pagelist,1 ,0 ,PAGE_KERNEL ); +if (vbase ==NULL ) { +pr_err ("Failed to map vDSO pagelist!\n" ); +return -ENOMEM ; + }else if (memcmp (vbase,"\177ELF" ,4 )) {Quoted 9 lines
arch/arm/kernel/vdso.c line 79
Quoted 4 lines
arch/arm/kernel/vdso.c new file +4
-0+pr_err ("vDSO is not a valid ELF object!\n" ); + ret = -EINVAL ; + goto unmap; + }Why do we need to
vmap()pages which are already accessible -vdso_startmust be part of the kernel image, and therefore will be accessible via standard mappings.
Quoted 3 lines
This is a dress rehersal for
install_special_mappingmore than anything. If we map the page, and look at the first 4 bytes, are they what we expect?
My point is that we can already view this page directly by dereferencing vdso_start - do we really need to perform this apparant test of the MMU? If the MMU isn't working in this way, we have much bigger and more fundamental problems...
Signature · 3 lines
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up. Estimation in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad. Estimate before purchase was "up to 13.2Mbit".
PATCH v2 1/1 ARM: vDSO gettimeofday using generic timer architecture
Quoted 42 lines · Russell King - ARM Linux
Quoted 16 lines · Steve Capper
Hi Russell,
Quoted 12 lines · Russell King - ARM Linux
arch/arm/kernel/vdso.c line 68
Quoted 7 lines · Nathan Lynch
arch/arm/kernel/vdso.c new file +7
-0+/* Grab the vDSO code pages. */ +for (i =0 ; i < vdso_pages; i++) { + pg =virt_to_page (&vdso_start + i*PAGE_SIZE ); +ClearPageReserved (pg); +get_page (pg); + vdso_pagelist[i] = pg; + }Why do we want to clear the reserved status? This looks over complicated to me.
Quoted 4 lines
This looks like it was inherited from the PowerPC code where the behaviour of
set_pte_atwould change dependent on whether or not the page was reserved (set_pte_at->set_pte_filter->maybe_pte_to_page). I think we can safely remove this from ARM and ARM64.Great, so we can get rid of that and the
get_page()on the vdso data page below.Quoted 17 lines
Quoted 16 lines
arch/arm/kernel/vdso.c line 79
Quoted 11 lines
arch/arm/kernel/vdso.c new file +11
-0+ +/* Sanity check the shared object header. */ + vbase =vmap (vdso_pagelist,1 ,0 ,PAGE_KERNEL ); +if (vbase ==NULL ) { +pr_err ("Failed to map vDSO pagelist!\n" ); +return -ENOMEM ; + }else if (memcmp (vbase,"\177ELF" ,4 )) { +pr_err ("vDSO is not a valid ELF object!\n" ); + ret = -EINVAL ; + goto unmap; + }Why do we need to
vmap()pages which are already accessible -vdso_startmust be part of the kernel image, and therefore will be accessible via standard mappings.
Quoted 9 lines
Quoted 3 lines
This is a dress rehersal for
install_special_mappingmore than anything. If we map the page, and look at the first 4 bytes, are they what we expect?My point is that we can already view this page directly by dereferencing
vdso_start- do we really need to perform this apparant test of the MMU? If the MMU isn't working in this way, we have much bigger and more fundamental problems...
I see, yes I think people would notice the MMU not working :-). This code also tests the alignment of vdso_start in a roundabout way. I'm not sure whether or not an explicit alignment check to PAGE_SIZE would be beneficial instead of the test mapping.
Cheers,
Signature · 1 line
Steve
PATCH v2 1/1 ARM: vDSO gettimeofday using generic timer architecture
In reply to Russell King - ARM LinuxQuoted 12 lines · Russell King - ARM Linux
arch/arm/kernel/vdso.c line 68
Quoted 7 lines · Nathan Lynch
arch/arm/kernel/vdso.c new file +7
-0+/* Grab the vDSO code pages. */ +for (i =0 ; i < vdso_pages; i++) { + pg =virt_to_page (&vdso_start + i*PAGE_SIZE ); +ClearPageReserved (pg); +get_page (pg); + vdso_pagelist[i] = pg; + }Why do we want to clear the reserved status? This looks over complicated to me.
Quoted 15 lines
arch/arm/kernel/vdso.c line 79
Quoted 11 lines
arch/arm/kernel/vdso.c new file +11
-0+ +/* Sanity check the shared object header. */ + vbase =vmap (vdso_pagelist,1 ,0 ,PAGE_KERNEL ); +if (vbase ==NULL ) { +pr_err ("Failed to map vDSO pagelist!\n" ); +return -ENOMEM ; + }else if (memcmp (vbase,"\177ELF" ,4 )) { +pr_err ("vDSO is not a valid ELF object!\n" ); + ret = -EINVAL ; + goto unmap; + }Why do we need to
vmap()pages which are already accessible -vdso_startmust be part of the kernel image, and therefore will be accessible via standard mappings.
Right, this stuff doesn't appear to be necessary. Removed the vmap, get_page, and ClearPageReserved calls for v3.
Quoted 11 lines
arch/arm/kernel/vdso/vgettimeofday.c line 65
Quoted 8 lines
arch/arm/kernel/vdso/vgettimeofday.c new file +8
-0+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; + registerlong ret asm ("r0" ); + register long nr asm("r7") = __NR_clock_gettime; + + asm("swi #0" :"=r" (ret) :"r" (clkid),"r" (ts),"r" (nr) :"memory" );This isn't compatible with OABI, so either this must not be enabled when AEABI is disabled, or this needs to be fixed.
Okay. I'll plan on making the vdso code depend on CONFIG_AEABI, likely indirectly via a CONFIG_VDSO Kconfig option. Since you'll need an updated C library to actually benefit from the vdso, I doubt any OABI support in this code would get any use.
Thanks for reviewing.
PATCH v2 1/1 ARM: vDSO gettimeofday using generic timer architecture
Quoted 29 lines · Nathan Lynch
Quoted 12 lines · Russell King - ARM Linux
arch/arm/kernel/vdso.c line 68
Quoted 7 lines · Nathan Lynch
arch/arm/kernel/vdso.c new file +7
-0+/* Grab the vDSO code pages. */ +for (i =0 ; i < vdso_pages; i++) { + pg =virt_to_page (&vdso_start + i*PAGE_SIZE ); +ClearPageReserved (pg); +get_page (pg); + vdso_pagelist[i] = pg; + }Why do we want to clear the reserved status? This looks over complicated to me.
Quoted 15 lines
arch/arm/kernel/vdso.c line 79
Quoted 11 lines
arch/arm/kernel/vdso.c new file +11
-0+ +/* Sanity check the shared object header. */ + vbase =vmap (vdso_pagelist,1 ,0 ,PAGE_KERNEL ); +if (vbase ==NULL ) { +pr_err ("Failed to map vDSO pagelist!\n" ); +return -ENOMEM ; + }else if (memcmp (vbase,"\177ELF" ,4 )) { +pr_err ("vDSO is not a valid ELF object!\n" ); + ret = -EINVAL ; + goto unmap; + }Why do we need to
vmap()pages which are already accessible -vdso_startmust be part of the kernel image, and therefore will be accessible via standard mappings.
Quoted 2 lines
Right, this stuff doesn't appear to be necessary. Removed the vmap,
get_page, and ClearPageReserved calls for v3.
Can you make the corresponding change for arm64 too, please?
Quoted 8 lines
Quoted 8 lines
arch/arm/kernel/vdso/vgettimeofday.c line 65
Quoted 8 lines
arch/arm/kernel/vdso/vgettimeofday.c new file +8
-0+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; + registerlong ret asm ("r0" ); + register long nr asm("r7") = __NR_clock_gettime; + + asm("swi #0" :"=r" (ret) :"r" (clkid),"r" (ts),"r" (nr) :"memory" );
Might be worth making this volatile, rather than depend on the use of ret.
Also, placing both _clkid and ret into "r0" worries me slightly -- is GCC smart enough to realise that writing to ret kills _clkid?
Will
PATCH v2 1/1 ARM: vDSO gettimeofday using generic timer architecture
Quoted 6 lines · Will Deacon
Quoted 3 lines · Nathan Lynch
Right, this stuff doesn't appear to be necessary. Removed the vmap,
get_page, and ClearPageReserved calls for v3.Can you make the corresponding change for arm64 too, please?
Yes, will do.
Quoted 10 lines
Quoted 8 lines
Quoted 8 lines
arch/arm/kernel/vdso/vgettimeofday.c line 65
Quoted 8 lines
arch/arm/kernel/vdso/vgettimeofday.c new file +8
-0+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; + registerlong ret asm ("r0" ); + register long nr asm("r7") = __NR_clock_gettime; + + asm("swi #0" :"=r" (ret) :"r" (clkid),"r" (ts),"r" (nr) :"memory" );Might be worth making this volatile, rather than depend on the use of ret.
Okay.
Quoted 2 lines
Also, placing both
_clkidand ret into "r0" worries me slightly -- is GCC smart enough to realise that writing to ret kills_clkid?
I pretty much lifted this from an example in the GCC manual:
register int *p1 asm ("r0") = ...;
register int *p2 asm ("r1") = ...;
register int *result asm ("r0");
asm ("sysint" : "=r" (result) : "0" (p1), "r" (p2));http://gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/Extended-Asm.html
I guess it doesn't directly answer your concern, but it's an indication that GCC developers have this use case in mind.