Changeset View
Changeset View
Standalone View
Standalone View
sys/amd64/linux32/linux32_sysvec.c
Show First 20 Lines • Show All 960 Lines • ▼ Show 20 Lines | linux_on_exec_vmspace(struct proc *p, struct image_params *imgp) | ||||
error = linux_map_vdso(p, linux_vdso_obj, linux_vdso_base, | error = linux_map_vdso(p, linux_vdso_obj, linux_vdso_base, | ||||
LINUX32_VDSOPAGE_SIZE, imgp); | LINUX32_VDSOPAGE_SIZE, imgp); | ||||
if (error == 0) | if (error == 0) | ||||
linux_on_exec(p, imgp); | linux_on_exec(p, imgp); | ||||
return (error); | 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 | static void | ||||
linux_exec_sysvec_init(void *param) | linux_exec_sysvec_init(void *param) | ||||
{ | { | ||||
l_uintptr_t *ktimekeep_base, *ktsc_selector; | l_uintptr_t *ktimekeep_base, *ktsc_selector; | ||||
struct sysentvec *sv; | struct sysentvec *sv; | ||||
ptrdiff_t tkoff; | ptrdiff_t tkoff; | ||||
sv = param; | sv = param; | ||||
/* Fill timekeep_base */ | /* Fill timekeep_base */ | ||||
exec_sysvec_init_abi(sv); | exec_sysvec_init_abi(sv); | ||||
tkoff = kern_timekeep_base - linux_vdso_base; | tkoff = kern_timekeep_base - linux_vdso_base; | ||||
ktimekeep_base = (l_uintptr_t *)(linux_vdso_mapping + tkoff); | ktimekeep_base = (l_uintptr_t *)(linux_vdso_mapping + tkoff); | ||||
*ktimekeep_base = sv->sv_timekeep_base; | *ktimekeep_base = sv->sv_timekeep_base; | ||||
tkoff = kern_tsc_selector - linux_vdso_base; | tkoff = kern_tsc_selector - linux_vdso_base; | ||||
ktsc_selector = (l_uintptr_t *)(linux_vdso_mapping + tkoff); | ktsc_selector = (l_uintptr_t *)(linux_vdso_mapping + tkoff); | ||||
*ktsc_selector = linux_vdso_tsc_selector_idx(); | *ktsc_selector = linux_vdso_tsc_selector_idx(); | ||||
if (bootverbose) | if (bootverbose) | ||||
printf("Linux i386 vDSO tsc_selector: %u\n", *ktsc_selector); | 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); | linux_exec_sysvec_init, &elf_linux_sysvec); | ||||
static void | static void | ||||
linux_vdso_install(const void *param) | linux_vdso_install(const void *param) | ||||
{ | { | ||||
char *vdso_start = &_binary_linux32_vdso_so_o_start; | char *vdso_start = &_binary_linux32_vdso_so_o_start; | ||||
char *vdso_end = &_binary_linux32_vdso_so_o_end; | char *vdso_end = &_binary_linux32_vdso_so_o_end; | ||||
linux_szsigcode = vdso_end - vdso_start; | linux_szsigcode = vdso_end - vdso_start; | ||||
MPASS(linux_szsigcode <= LINUX32_VDSOPAGE_SIZE); | MPASS(linux_szsigcode <= LINUX32_VDSOPAGE_SIZE); | ||||
linux_vdso_base = LINUX32_VDSOPAGE; | linux_vdso_base = LINUX32_VDSOPAGE; | ||||
__elfN(linux_vdso_fixup)(vdso_start, linux_vdso_base); | __elfN(linux_vdso_fixup)(vdso_start, linux_vdso_base); | ||||
linux_vdso_obj = __elfN(linux_shared_page_init) | linux_vdso_obj = __elfN(linux_shared_page_init) | ||||
(&linux_vdso_mapping, LINUX32_VDSOPAGE_SIZE); | (&linux_vdso_mapping, LINUX32_VDSOPAGE_SIZE); | ||||
bcopy(vdso_start, linux_vdso_mapping, linux_szsigcode); | bcopy(vdso_start, linux_vdso_mapping, linux_szsigcode); | ||||
linux_vdso_reloc(linux_vdso_mapping, linux_vdso_base); | 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); | linux_vdso_install, NULL); | ||||
static void | static void | ||||
linux_vdso_deinstall(const void *param) | linux_vdso_deinstall(const void *param) | ||||
{ | { | ||||
__elfN(linux_shared_page_fini)(linux_vdso_obj, | __elfN(linux_shared_page_fini)(linux_vdso_obj, | ||||
linux_vdso_mapping, LINUX32_VDSOPAGE_SIZE); | linux_vdso_mapping, LINUX32_VDSOPAGE_SIZE); | ||||
▲ Show 20 Lines • Show All 196 Lines • Show Last 20 Lines |