diff --git a/sys/amd64/linux/linux_sysvec.c b/sys/amd64/linux/linux_sysvec.c --- a/sys/amd64/linux/linux_sysvec.c +++ b/sys/amd64/linux/linux_sysvec.c @@ -233,7 +233,7 @@ AUXARGS_ENTRY((*pos), LINUX_AT_SYSINFO_EHDR, linux_vdso_base); AUXARGS_ENTRY((*pos), LINUX_AT_HWCAP, cpu_feature); - AUXARGS_ENTRY((*pos), LINUX_AT_HWCAP2, 0); + AUXARGS_ENTRY((*pos), LINUX_AT_HWCAP2, linux_x86_elf_hwcap2()); AUXARGS_ENTRY((*pos), LINUX_AT_PLATFORM, PTROUT(linux_platform)); } diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c --- a/sys/amd64/linux32/linux32_sysvec.c +++ b/sys/amd64/linux32/linux32_sysvec.c @@ -146,7 +146,7 @@ AUXARGS_ENTRY((*pos), LINUX_AT_SYSINFO, __kernel_vsyscall); AUXARGS_ENTRY((*pos), LINUX_AT_SYSINFO_EHDR, linux_vdso_base); AUXARGS_ENTRY((*pos), LINUX_AT_HWCAP, cpu_feature); - AUXARGS_ENTRY((*pos), LINUX_AT_HWCAP2, 0); + AUXARGS_ENTRY((*pos), LINUX_AT_HWCAP2, linux_x86_elf_hwcap2()); AUXARGS_ENTRY((*pos), LINUX_AT_PLATFORM, PTROUT(linux_platform)); } diff --git a/sys/i386/linux/linux.h b/sys/i386/linux/linux.h --- a/sys/i386/linux/linux.h +++ b/sys/i386/linux/linux.h @@ -94,7 +94,7 @@ /* * Miscellaneous */ -#define LINUX_AT_COUNT 21 /* Count of used aux entry types. +#define LINUX_AT_COUNT 22 /* Count of used aux entry types. * Keep this synchronized with * linux_copyout_auxargs() code. */ diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c --- a/sys/i386/linux/linux_sysvec.c +++ b/sys/i386/linux/linux_sysvec.c @@ -145,6 +145,7 @@ AUXARGS_ENTRY((*pos), LINUX_AT_SYSINFO_EHDR, linux_vdso_base); AUXARGS_ENTRY((*pos), LINUX_AT_SYSINFO, __kernel_vsyscall); AUXARGS_ENTRY((*pos), LINUX_AT_HWCAP, cpu_feature); + AUXARGS_ENTRY((*pos), LINUX_AT_HWCAP2, linux_x86_elf_hwcap2()); AUXARGS_ENTRY((*pos), LINUX_AT_PLATFORM, PTROUT(linux_platform)); } diff --git a/sys/x86/linux/linux_x86.h b/sys/x86/linux/linux_x86.h --- a/sys/x86/linux/linux_x86.h +++ b/sys/x86/linux/linux_x86.h @@ -32,10 +32,16 @@ #define LINUX_VDSO_CPU_RDPID 1 #define LINUX_VDSO_CPU_RDTSCP 2 +/* More machine dependent hints about processor capabilities. */ +#define LINUX_HWCAP2_RING3MWAIT 0x00000001 +#define LINUX_HWCAP2_FSGSBASE 0x00000002 + int linux_vdso_tsc_selector_idx(void); int linux_vdso_cpu_selector_idx(void); int linux_translate_traps(int, int); int bsd_to_linux_trapcode(int); +u_int linux_x86_elf_hwcap2(void); + #endif /* _X86_INCLUDE_LINUX_LINUX_X86_H_ */ diff --git a/sys/x86/linux/linux_x86.c b/sys/x86/linux/linux_x86.c --- a/sys/x86/linux/linux_x86.c +++ b/sys/x86/linux/linux_x86.c @@ -31,7 +31,9 @@ #include #include +#include #include +#include #include @@ -96,4 +98,18 @@ return (code < nitems(_bsd_to_linux_trapcode) ? _bsd_to_linux_trapcode[code] : LINUX_T_UNKNOWN); -} \ No newline at end of file +} + +u_int +linux_x86_elf_hwcap2(void) +{ + static u_int elf_hwcap2 = 0; + static bool elf_hwcap2_valid = false; + + if (!elf_hwcap2_valid) { + if ((cpu_stdext_feature & CPUID_STDEXT_FSGSBASE) != 0) + elf_hwcap2 |= LINUX_HWCAP2_FSGSBASE; + elf_hwcap2_valid = true; + } + return (elf_hwcap2); +}