git: 9e1efa0f8835 - stable/13 - arm64: improve UVA layout for 32bit processes

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Sat, 11 Nov 2023 00:40:48 UTC
The branch stable/13 has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=9e1efa0f88356747d88e310209e57ba8f689fa4e

commit 9e1efa0f88356747d88e310209e57ba8f689fa4e
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2023-10-25 01:03:09 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2023-11-11 00:40:25 +0000

    arm64: improve UVA layout for 32bit processes
    
    PR:     274705
    
    (cherry picked from commit 967022aa5aa60a18764a668ae0fb78e39e16fa8e)
---
 sys/arm64/arm64/elf32_machdep.c | 54 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 52 insertions(+), 2 deletions(-)

diff --git a/sys/arm64/arm64/elf32_machdep.c b/sys/arm64/arm64/elf32_machdep.c
index c59571808cd3..3668d2a3c444 100644
--- a/sys/arm64/arm64/elf32_machdep.c
+++ b/sys/arm64/arm64/elf32_machdep.c
@@ -43,6 +43,7 @@
 #include <sys/linker.h>
 #include <sys/proc.h>
 #include <sys/reg.h>
+#include <sys/sysctl.h>
 #include <sys/sysent.h>
 #include <sys/imgact_elf.h>
 #include <sys/syscall.h>
@@ -60,6 +61,9 @@
 #define	FREEBSD32_MAXUSER	((1ul << 32) - PAGE_SIZE)
 #define	FREEBSD32_SHAREDPAGE	(FREEBSD32_MAXUSER - PAGE_SIZE)
 #define	FREEBSD32_USRSTACK	FREEBSD32_SHAREDPAGE
+#define	AARCH32_MAXDSIZ		(512 * 1024 *n1024)
+#define	AARCH32_MAXSSIZ		(64 * 1024 * 1024)
+#define	AARCH32_MAXVMEM		0
 
 extern const char *freebsd32_syscallnames[];
 
@@ -73,12 +77,26 @@ static void freebsd32_set_syscall_retval(struct thread *, int);
 
 static boolean_t elf32_arm_abi_supported(struct image_params *, int32_t *,
     uint32_t *);
+static void elf32_fixlimit(struct rlimit *rl, int which);
 
 extern void freebsd32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask);
 
 u_long __read_frequently elf32_hwcap;
 u_long __read_frequently elf32_hwcap2;
 
+static SYSCTL_NODE(_compat, OID_AUTO, aarch32, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
+    "aarch32 mode");
+
+static u_long aarch32_maxdsiz = AARCH32_MAXDSIZ;
+SYSCTL_ULONG(_compat_aarch32, OID_AUTO, maxdsiz, CTLFLAG_RWTUN,
+    &aarch32_maxdsiz, 0, "");
+u_long aarch32_maxssiz = AARCH32_MAXSSIZ;
+SYSCTL_ULONG(_compat_aarch32, OID_AUTO, maxssiz, CTLFLAG_RWTUN,
+    &aarch32_maxssiz, 0, "");
+static u_long aarch32_maxvmem = AARCH32_MAXVMEM;
+SYSCTL_ULONG(_compat_aarch32, OID_AUTO, maxvmem, CTLFLAG_RWTUN,
+    &aarch32_maxvmem, 0, "");
+
 static struct sysentvec elf32_freebsd_sysvec = {
 	.sv_size	= SYS_MAXSYSCALL,
 	.sv_table	= freebsd32_sysent,
@@ -102,8 +120,8 @@ static struct sysentvec elf32_freebsd_sysvec = {
 	.sv_copyout_auxargs = elf32_freebsd_copyout_auxargs,
 	.sv_copyout_strings = freebsd32_copyout_strings,
 	.sv_setregs	= freebsd32_setregs,
-	.sv_fixlimit	= NULL, // XXX
-	.sv_maxssiz	= NULL,
+	.sv_fixlimit	= elf32_fixlimit,
+	.sv_maxssiz	= &aarch32_maxssiz,
 	.sv_flags	= SV_ABI_FREEBSD | SV_ILP32 | SV_SHP | SV_TIMEKEEP |
 	    SV_RNG_SEED_VER | SV_SIGSYS,
 	.sv_set_syscall_retval = freebsd32_set_syscall_retval,
@@ -283,3 +301,35 @@ void
 elf32_dump_thread(struct thread *td, void *dst, size_t *off)
 {
 }
+
+static void
+elf32_fixlimit(struct rlimit *rl, int which)
+{
+
+	switch (which) {
+	case RLIMIT_DATA:
+		if (aarch32_maxdsiz != 0) {
+			if (rl->rlim_cur > aarch32_maxdsiz)
+				rl->rlim_cur = aarch32_maxdsiz;
+			if (rl->rlim_max > aarch32_maxdsiz)
+				rl->rlim_max = aarch32_maxdsiz;
+		}
+		break;
+	case RLIMIT_STACK:
+		if (aarch32_maxssiz != 0) {
+			if (rl->rlim_cur > aarch32_maxssiz)
+				rl->rlim_cur = aarch32_maxssiz;
+			if (rl->rlim_max > aarch32_maxssiz)
+				rl->rlim_max = aarch32_maxssiz;
+		}
+		break;
+	case RLIMIT_VMEM:
+		if (aarch32_maxvmem != 0) {
+			if (rl->rlim_cur > aarch32_maxvmem)
+				rl->rlim_cur = aarch32_maxvmem;
+			if (rl->rlim_max > aarch32_maxvmem)
+				rl->rlim_max = aarch32_maxvmem;
+		}
+		break;
+	}
+}