/* * close() is called for munmap() but also for mremap(). In the mremap() * case the vdso pointer has already been updated by the mremap() hook * above, so it must not be set to NULL here.
*/ if (vma->vm_start != (unsignedlong)mm->context.vdso) return;
/* * This is called from binfmt_elf, we create the special vma for the * vDSO and insert it into the mm struct tree
*/ staticint __arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
{ unsignedlong vdso_size, vdso_base, mappings_size; struct vm_special_mapping *vdso_spec; unsignedlong vvar_size = VDSO_NR_PAGES * PAGE_SIZE; struct mm_struct *mm = current->mm; struct vm_area_struct *vma;
/* * Pick a base address for the vDSO in process space. * Add enough to the size so that the result can be aligned.
*/
vdso_base = get_unmapped_area(NULL, 0, mappings_size, 0, 0); if (IS_ERR_VALUE(vdso_base)) return vdso_base;
vma = vdso_install_vvar_mapping(mm, vdso_base); if (IS_ERR(vma)) return PTR_ERR(vma);
/* * our vma flags don't have VM_WRITE so by default, the process isn't * allowed to write those pages. * gdb can break that with ptrace interface, and thus trigger COW on * those pages but it's then your responsibility to never do that on * the "data" page of the vDSO or you'll stop getting kernel updates * and your nice userland gettimeofday will be totally dead. * It's fine to use that for setting breakpoints in the vDSO code * pages though.
*/
vma = _install_special_mapping(mm, vdso_base + vvar_size, vdso_size,
VM_READ | VM_EXEC | VM_MAYREAD |
VM_MAYWRITE | VM_MAYEXEC, vdso_spec); if (IS_ERR(vma)) {
do_munmap(mm, vdso_base, vvar_size, NULL); return PTR_ERR(vma);
}
// Now that the mappings are in place, set the mm VDSO pointer
mm->context.vdso = (void __user *)vdso_base + vvar_size;
return 0;
}
int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
{ struct mm_struct *mm = current->mm; int rc;
/* * Called from setup_arch to initialize the bitmap of available * syscalls in the systemcfg page
*/ staticvoid __init vdso_setup_syscall_map(void)
{ unsignedint i;
for (i = 0; i < NR_syscalls; i++) { if (sys_call_table[i] != (void *)&sys_ni_syscall)
vdso_k_arch_data->syscall_map[i >> 5] |= 0x80000000UL >> (i & 0x1f); if (IS_ENABLED(CONFIG_COMPAT) &&
compat_sys_call_table[i] != (void *)&sys_ni_syscall)
vdso_k_arch_data->compat_syscall_map[i >> 5] |= 0x80000000UL >> (i & 0x1f);
}
}
#ifdef CONFIG_PPC64 int vdso_getcpu_init(void)
{ unsignedlong cpu, node, val;
/* * SPRG_VDSO contains the CPU in the bottom 16 bits and the NUMA node * in the next 16 bits. The VDSO uses this to implement getcpu().
*/
cpu = get_cpu();
WARN_ON_ONCE(cpu > 0xffff);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.