aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2023-10-25 01:03:09 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2023-11-10 12:15:46 +0000
commit0dc8af9dae2ca5419a0d3313d0dcb42c6b5d6d38 (patch)
tree6217a953c3b49b3837a2cac39692694729e1420c
parentbd7dceb27c085c0014f5a09b5d92c6a060d16f23 (diff)
downloadsrc-0dc8af9dae2ca5419a0d3313d0dcb42c6b5d6d38.tar.gz
src-0dc8af9dae2ca5419a0d3313d0dcb42c6b5d6d38.zip
arm64: improve UVA layout for 32bit processes
PR: 274705 (cherry picked from commit 967022aa5aa60a18764a668ae0fb78e39e16fa8e)
-rw-r--r--sys/arm64/arm64/elf32_machdep.c54
1 files changed, 52 insertions, 2 deletions
diff --git a/sys/arm64/arm64/elf32_machdep.c b/sys/arm64/arm64/elf32_machdep.c
index 4161f9d44ae7..733aaf40541a 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>
@@ -61,6 +62,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[];
@@ -74,12 +78,26 @@ static void freebsd32_set_syscall_retval(struct thread *, int);
static bool 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,
@@ -284,3 +302,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;
+ }
+}