diff --git a/sys/amd64/amd64/elf_machdep.c b/sys/amd64/amd64/elf_machdep.c --- a/sys/amd64/amd64/elf_machdep.c +++ b/sys/amd64/amd64/elf_machdep.c @@ -170,11 +170,13 @@ { if ((imgp->proc->p_md.md_flags & P_MD_LA57) != 0) return (true); + if (fctl0 != NULL && (*fctl0 & NT_FREEBSD_FCTL_LA57) != 0) + return (true); if (fctl0 == NULL || (*fctl0 & NT_FREEBSD_FCTL_LA48) != 0) return (false); if ((imgp->proc->p_md.md_flags & P_MD_LA48) != 0) return (false); - return (true); + return (!prefer_uva_la48); } static Elf64_Brandinfo freebsd_brand_info_la48 = { diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -431,6 +431,15 @@ &la57, 0, "5-level paging for host is enabled"); +/* + * The default value is needed in order to preserve compatibility with + * some userspace programs that put tags into sign-extended bits. + */ +int prefer_uva_la48 = 1; +SYSCTL_INT(_vm_pmap, OID_AUTO, prefer_uva_la48, CTLFLAG_RDTUN, + &prefer_uva_la48, 0, + "Userspace maps are limited to LA48 unless otherwise configured"); + static bool pmap_is_la57(pmap_t pmap) { diff --git a/sys/amd64/include/md_var.h b/sys/amd64/include/md_var.h --- a/sys/amd64/include/md_var.h +++ b/sys/amd64/include/md_var.h @@ -51,6 +51,7 @@ extern vm_paddr_t intel_graphics_stolen_size; extern int la57; +extern int prefer_uva_la48; extern vm_paddr_t kernphys; extern vm_paddr_t KERNend; diff --git a/sys/sys/elf_common.h b/sys/sys/elf_common.h --- a/sys/sys/elf_common.h +++ b/sys/sys/elf_common.h @@ -824,6 +824,7 @@ #define NT_FREEBSD_FCTL_WXNEEDED 0x00000008 #define NT_FREEBSD_FCTL_LA48 0x00000010 /* was ASG_DISABLE, do not reuse 0x00000020 */ +#define NT_FREEBSD_FCTL_LA57 0x00000040 /* Values for n_type. Used in core files. */ #define NT_PRSTATUS 1 /* Process status. */ diff --git a/usr.bin/elfctl/elfctl.1 b/usr.bin/elfctl/elfctl.1 --- a/usr.bin/elfctl/elfctl.1 +++ b/usr.bin/elfctl/elfctl.1 @@ -95,6 +95,20 @@ .Bd -literal -offset indent elfctl -e =0x5 file .Ed +.Sh NOTES +On amd64, on a machine with LA57 (5-level paging) mode supported and +enabled, if both +.Va la57 +and +.Va la48 +feature flags are specified, the +.Va la57 +feature has priority over +.Va la48 . +The +.Va vm.pmap.prefer_uva_la48 +sysctl MIB defines the default user address space size for binaries +which do not set either of these flags. .Sh SEE ALSO .Xr mitigations 7 .Sh HISTORY diff --git a/usr.bin/elfctl/elfctl.c b/usr.bin/elfctl/elfctl.c --- a/usr.bin/elfctl/elfctl.c +++ b/usr.bin/elfctl/elfctl.c @@ -67,7 +67,10 @@ "Disable implicit PROT_MAX" }, { "nostackgap", NT_FREEBSD_FCTL_STKGAP_DISABLE, "Disable stack gap" }, { "wxneeded", NT_FREEBSD_FCTL_WXNEEDED, "Requires W+X mappings" }, - { "la48", NT_FREEBSD_FCTL_LA48, "amd64: Limit user VA to 48bit" }, + { "la48", NT_FREEBSD_FCTL_LA48, + "amd64: Limit user virtual addresses to 48bits" }, + { "la57", NT_FREEBSD_FCTL_LA57, + "amd64: Allow the use of 57-bit virtual addresses when available" }, }; static struct option long_opts[] = {