linux(4): Fixup the vDSO initialization order.

The vDSO initialisation order should be as follows:
- native abi init via exec_sysvec_init();
- vDSO symbols queued to the linux_vdso_syms list;
- linux_vdso_install();
- linux_exec_sysvec_init();

As the exec_sysvec_init() called with SI_ORDER_ANY (last) at SI_SUB_EXEC
order, move linux_vdso_install() and linux_exec_sysvec_init() to the
SI_SUB_EXEC+1 order.

Reviewed by:		trasz
Differential Revision:	https://reviews.freebsd.org/D30902
MFC after		2 weeks
This commit is contained in:
Dmitry Chagin 2021-07-20 10:02:34 +03:00
parent a543556c81
commit 09cffde975
4 changed files with 29 additions and 8 deletions

View File

@ -804,6 +804,10 @@ linux_on_exec_vmspace(struct proc *p, struct image_params *imgp)
return (error);
}
/*
* linux_vdso_install() and linux_exec_sysvec_init() must be called
* after exec_sysvec_init() which is SI_SUB_EXEC (SI_ORDER_ANY).
*/
static void
linux_exec_sysvec_init(void *param)
{
@ -826,7 +830,7 @@ linux_exec_sysvec_init(void *param)
if (bootverbose)
printf("Linux x86-64 vDSO tsc_selector: %lu\n", *ktsc_selector);
}
SYSINIT(elf_linux_exec_sysvec_init, SI_SUB_EXEC, SI_ORDER_ANY,
SYSINIT(elf_linux_exec_sysvec_init, SI_SUB_EXEC + 1, SI_ORDER_ANY,
linux_exec_sysvec_init, &elf_linux_sysvec);
static void
@ -850,7 +854,7 @@ linux_vdso_install(const void *param)
linux_vdso_reloc(linux_vdso_mapping, linux_vdso_base);
}
SYSINIT(elf_linux_vdso_init, SI_SUB_EXEC, SI_ORDER_FIRST,
SYSINIT(elf_linux_vdso_init, SI_SUB_EXEC + 1, SI_ORDER_FIRST,
linux_vdso_install, NULL);
static void

View File

@ -970,6 +970,10 @@ linux_on_exec_vmspace(struct proc *p, struct image_params *imgp)
return (error);
}
/*
* linux_vdso_install() and linux_exec_sysvec_init() must be called
* after exec_sysvec_init() which is SI_SUB_EXEC (SI_ORDER_ANY).
*/
static void
linux_exec_sysvec_init(void *param)
{
@ -991,7 +995,7 @@ linux_exec_sysvec_init(void *param)
if (bootverbose)
printf("Linux i386 vDSO tsc_selector: %u\n", *ktsc_selector);
}
SYSINIT(elf_linux_exec_sysvec_init, SI_SUB_EXEC, SI_ORDER_ANY,
SYSINIT(elf_linux_exec_sysvec_init, SI_SUB_EXEC + 1, SI_ORDER_ANY,
linux_exec_sysvec_init, &elf_linux_sysvec);
static void
@ -1013,7 +1017,7 @@ linux_vdso_install(const void *param)
linux_vdso_reloc(linux_vdso_mapping, linux_vdso_base);
}
SYSINIT(elf_linux_vdso_init, SI_SUB_EXEC, SI_ORDER_FIRST,
SYSINIT(elf_linux_vdso_init, SI_SUB_EXEC + 1, SI_ORDER_FIRST,
linux_vdso_install, NULL);
static void

View File

@ -476,6 +476,10 @@ linux_on_exec_vmspace(struct proc *p, struct image_params *imgp)
return (error);
}
/*
* linux_vdso_install() and linux_exec_sysvec_init() must be called
* after exec_sysvec_init() which is SI_SUB_EXEC (SI_ORDER_ANY).
*/
static void
linux_exec_sysvec_init(void *param)
{
@ -491,7 +495,7 @@ linux_exec_sysvec_init(void *param)
ktimekeep_base = (l_uintptr_t *)(linux_vdso_mapping + tkoff);
*ktimekeep_base = sv->sv_timekeep_base;
}
SYSINIT(elf_linux_exec_sysvec_init, SI_SUB_EXEC, SI_ORDER_ANY,
SYSINIT(elf_linux_exec_sysvec_init, SI_SUB_EXEC + 1, SI_ORDER_ANY,
linux_exec_sysvec_init, &elf_linux_sysvec);
static void
@ -513,7 +517,7 @@ linux_vdso_install(const void *param)
linux_vdso_reloc(linux_vdso_mapping, linux_vdso_base);
}
SYSINIT(elf_linux_vdso_init, SI_SUB_EXEC, SI_ORDER_FIRST,
SYSINIT(elf_linux_vdso_init, SI_SUB_EXEC + 1, SI_ORDER_FIRST,
linux_vdso_install, NULL);
static void

View File

@ -915,6 +915,10 @@ linux_on_exec_vmspace(struct proc *p, struct image_params *imgp)
return (error);
}
/*
* linux_vdso_install() and linux_exec_sysvec_init() must be called
* after exec_sysvec_init() which is SI_SUB_EXEC (SI_ORDER_ANY).
*/
static void
linux_exec_sysvec_init(void *param)
{
@ -936,7 +940,7 @@ linux_exec_sysvec_init(void *param)
if (bootverbose)
printf("Linux i386 vDSO tsc_selector: %u\n", *ktsc_selector);
}
SYSINIT(elf_linux_exec_sysvec_init, SI_SUB_EXEC, SI_ORDER_ANY,
SYSINIT(elf_linux_exec_sysvec_init, SI_SUB_EXEC + 1, SI_ORDER_ANY,
linux_exec_sysvec_init, &elf_linux_sysvec);
static void
@ -958,7 +962,7 @@ linux_vdso_install(const void *param)
linux_vdso_reloc(linux_vdso_mapping, linux_vdso_base);
}
SYSINIT(elf_linux_vdso_init, SI_SUB_EXEC, SI_ORDER_FIRST,
SYSINIT(elf_linux_vdso_init, SI_SUB_EXEC + 1, SI_ORDER_FIRST,
linux_vdso_install, NULL);
static void
@ -1169,3 +1173,8 @@ static moduledata_t linux_elf_mod = {
DECLARE_MODULE_TIED(linuxelf, linux_elf_mod, SI_SUB_EXEC, SI_ORDER_ANY);
FEATURE(linux, "Linux 32bit support");
/*
* linux_vdso_install() and linux_exec_sysvec_init() must be called
* after exec_sysvec_init() which is SI_SUB_EXEC (SI_ORDER_ANY).
*/