diff options
author | Stefani Seibold <stefani@seibold.net> | 2014-03-17 23:22:09 +0100 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2014-03-18 12:52:37 -0700 |
commit | 7a59ed415f5b57469e22e41fc4188d5399e0b194 (patch) | |
tree | fb57bae076853fbcbd44af62fb07d77d3c44125b /arch/x86/vdso/vdso32-setup.c | |
parent | b4b541a610c4db8643b36030ee5012203ca65778 (diff) |
x86, vdso: Add 32 bit VDSO time support for 32 bit kernel
This patch add the time support for 32 bit a VDSO to a 32 bit kernel.
For 32 bit programs running on a 32 bit kernel, the same mechanism is
used as for 64 bit programs running on a 64 bit kernel.
Reviewed-by: Andy Lutomirski <luto@amacapital.net>
Signed-off-by: Stefani Seibold <stefani@seibold.net>
Link: http://lkml.kernel.org/r/1395094933-14252-10-git-send-email-stefani@seibold.net
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Diffstat (limited to 'arch/x86/vdso/vdso32-setup.c')
-rw-r--r-- | arch/x86/vdso/vdso32-setup.c | 47 |
1 files changed, 43 insertions, 4 deletions
diff --git a/arch/x86/vdso/vdso32-setup.c b/arch/x86/vdso/vdso32-setup.c index e0fc767bcad..e10abdf4cc1 100644 --- a/arch/x86/vdso/vdso32-setup.c +++ b/arch/x86/vdso/vdso32-setup.c @@ -25,6 +25,9 @@ #include <asm/tlbflush.h> #include <asm/vdso.h> #include <asm/proto.h> +#include <asm/fixmap.h> +#include <asm/hpet.h> +#include <asm/vvar.h> #ifdef CONFIG_COMPAT_VDSO #define VDSO_DEFAULT 0 @@ -141,6 +144,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) struct mm_struct *mm = current->mm; unsigned long addr; int ret = 0; + struct vm_area_struct *vma; #ifdef CONFIG_X86_X32_ABI if (test_thread_flag(TIF_X32)) @@ -163,14 +167,49 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) /* * MAYWRITE to allow gdb to COW and set breakpoints */ - ret = install_special_mapping(mm, addr, PAGE_SIZE, - VM_READ|VM_EXEC| - VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC, - vdso32_pages); + ret = install_special_mapping(mm, + addr, + VDSO_OFFSET(VDSO_PAGES - VDSO_PREV_PAGES), + VM_READ|VM_EXEC| + VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC, + vdso32_pages); if (ret) goto up_fail; + vma = _install_special_mapping(mm, + addr - VDSO_OFFSET(VDSO_PREV_PAGES), + VDSO_OFFSET(VDSO_PREV_PAGES), + VM_READ, + NULL); + + if (IS_ERR(vma)) { + ret = PTR_ERR(vma); + goto up_fail; + } + + ret = remap_pfn_range(vma, + addr - VDSO_OFFSET(VDSO_VVAR_PAGE), + __pa_symbol(&__vvar_page) >> PAGE_SHIFT, + PAGE_SIZE, + PAGE_READONLY); + + if (ret) + goto up_fail; + +#ifdef CONFIG_HPET_TIMER + if (hpet_address) { + ret = io_remap_pfn_range(vma, + addr - VDSO_OFFSET(VDSO_HPET_PAGE), + hpet_address >> PAGE_SHIFT, + PAGE_SIZE, + pgprot_noncached(PAGE_READONLY)); + + if (ret) + goto up_fail; + } +#endif + current_thread_info()->sysenter_return = VDSO32_SYMBOL(addr, SYSENTER_RETURN); |