diff options
author | Chris Metcalf <cmetcalf@tilera.com> | 2013-08-07 15:33:32 -0400 |
---|---|---|
committer | Chris Metcalf <cmetcalf@tilera.com> | 2013-08-13 16:26:21 -0400 |
commit | 4a556f4f56da3110b27e265b79f0e7582115445c (patch) | |
tree | f5af0b865c867160855e4722b49d7e850dddf944 /arch/tile/mm | |
parent | 0c1d1917c547c8e787fb58e20e2de577453c980c (diff) |
tile: implement gettimeofday() via vDSO
This change creates the framework for vDSO calls, makes the existing
rt_sigreturn() mechanism use it, and adds a fast gettimeofday().
Now that we need to expose the vDSO address to userspace, we add
AT_SYSINFO_EHDR to the set of aux entries provided to userspace.
(You can disable any extra vDSO support by booting with vdso=0,
but the rt_sigreturn vDSO page will still be provided.)
Note that glibc has supported the tile vDSO since release 2.17.
Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
Diffstat (limited to 'arch/tile/mm')
-rw-r--r-- | arch/tile/mm/elf.c | 37 |
1 files changed, 2 insertions, 35 deletions
diff --git a/arch/tile/mm/elf.c b/arch/tile/mm/elf.c index 1691b81b2b0c..23f044e8a7ab 100644 --- a/arch/tile/mm/elf.c +++ b/arch/tile/mm/elf.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <asm/pgtable.h> | 21 | #include <asm/pgtable.h> |
22 | #include <asm/pgalloc.h> | 22 | #include <asm/pgalloc.h> |
23 | #include <asm/sections.h> | 23 | #include <asm/sections.h> |
24 | #include <asm/vdso.h> | ||
24 | #include <arch/sim.h> | 25 | #include <arch/sim.h> |
25 | 26 | ||
26 | /* Notify a running simulator, if any, that an exec just occurred. */ | 27 | /* Notify a running simulator, if any, that an exec just occurred. */ |
@@ -102,37 +103,10 @@ static void sim_notify_interp(unsigned long load_addr) | |||
102 | } | 103 | } |
103 | 104 | ||
104 | 105 | ||
105 | /* Kernel address of page used to map read-only kernel data into userspace. */ | ||
106 | static void *vdso_page; | ||
107 | |||
108 | /* One-entry array used for install_special_mapping. */ | ||
109 | static struct page *vdso_pages[1]; | ||
110 | |||
111 | static int __init vdso_setup(void) | ||
112 | { | ||
113 | vdso_page = (void *)get_zeroed_page(GFP_ATOMIC); | ||
114 | memcpy(vdso_page, __rt_sigreturn, __rt_sigreturn_end - __rt_sigreturn); | ||
115 | vdso_pages[0] = virt_to_page(vdso_page); | ||
116 | return 0; | ||
117 | } | ||
118 | device_initcall(vdso_setup); | ||
119 | |||
120 | const char *arch_vma_name(struct vm_area_struct *vma) | ||
121 | { | ||
122 | if (vma->vm_private_data == vdso_pages) | ||
123 | return "[vdso]"; | ||
124 | #ifndef __tilegx__ | ||
125 | if (vma->vm_start == MEM_USER_INTRPT) | ||
126 | return "[intrpt]"; | ||
127 | #endif | ||
128 | return NULL; | ||
129 | } | ||
130 | |||
131 | int arch_setup_additional_pages(struct linux_binprm *bprm, | 106 | int arch_setup_additional_pages(struct linux_binprm *bprm, |
132 | int executable_stack) | 107 | int executable_stack) |
133 | { | 108 | { |
134 | struct mm_struct *mm = current->mm; | 109 | struct mm_struct *mm = current->mm; |
135 | unsigned long vdso_base; | ||
136 | int retval = 0; | 110 | int retval = 0; |
137 | 111 | ||
138 | down_write(&mm->mmap_sem); | 112 | down_write(&mm->mmap_sem); |
@@ -145,14 +119,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, | |||
145 | if (!notify_exec(mm)) | 119 | if (!notify_exec(mm)) |
146 | sim_notify_exec(bprm->filename); | 120 | sim_notify_exec(bprm->filename); |
147 | 121 | ||
148 | /* | 122 | retval = setup_vdso_pages(); |
149 | * MAYWRITE to allow gdb to COW and set breakpoints | ||
150 | */ | ||
151 | vdso_base = VDSO_BASE; | ||
152 | retval = install_special_mapping(mm, vdso_base, PAGE_SIZE, | ||
153 | VM_READ|VM_EXEC| | ||
154 | VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC, | ||
155 | vdso_pages); | ||
156 | 123 | ||
157 | #ifndef __tilegx__ | 124 | #ifndef __tilegx__ |
158 | /* | 125 | /* |