Skip to content

Commit

Permalink
linux(4): Add elf_hwcap2 to x86
Browse files Browse the repository at this point in the history
On x86 Linux via AT_HWCAP2 the user controlled (by tunables) processor
capabilities are exposed.

Reviewed by:
Differential Revision:	https://reviews.freebsd.org/D41165
MFC after:		2 weeks
  • Loading branch information
lemul committed Jul 28, 2023
1 parent 5440e70 commit 4281dab
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 4 deletions.
2 changes: 1 addition & 1 deletion sys/amd64/linux/linux_sysvec.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ linux64_arch_copyout_auxargs(struct image_params *imgp, Elf_Auxinfo **pos)

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));
}

Expand Down
2 changes: 1 addition & 1 deletion sys/amd64/linux32/linux32_sysvec.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ linux32_arch_copyout_auxargs(struct image_params *imgp, Elf_Auxinfo **pos)
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));
}

Expand Down
2 changes: 1 addition & 1 deletion sys/i386/linux/linux.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ typedef struct {
/*
* 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.
*/
Expand Down
1 change: 1 addition & 0 deletions sys/i386/linux/linux_sysvec.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ linux32_arch_copyout_auxargs(struct image_params *imgp, Elf_Auxinfo **pos)
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));
}

Expand Down
18 changes: 17 additions & 1 deletion sys/x86/linux/linux_x86.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ __FBSDID("$FreeBSD$");

#include <sys/param.h>
#include <sys/signal.h>
#include <x86/specialreg.h>
#include <x86/trap.h>
#include <x86/x86_var.h>

#include <x86/linux/linux_x86.h>

Expand Down Expand Up @@ -96,4 +98,18 @@ bsd_to_linux_trapcode(int code)

return (code < nitems(_bsd_to_linux_trapcode) ?
_bsd_to_linux_trapcode[code] : LINUX_T_UNKNOWN);
}
}

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);
}
6 changes: 6 additions & 0 deletions sys/x86/linux/linux_x86.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_ */

0 comments on commit 4281dab

Please sign in to comment.