git: c4e4a7596beb - main - Add a BTI sysarch

From: Andrew Turner <andrew_at_FreeBSD.org>
Date: Thu, 22 Feb 2024 16:28:04 UTC
The branch main has been updated by andrew:

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

commit c4e4a7596beb488b4878e9fa2a67cf49e330f78b
Author:     Andrew Turner <andrew@FreeBSD.org>
AuthorDate: 2023-04-05 12:45:19 +0000
Commit:     Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2024-02-22 16:27:47 +0000

    Add a BTI sysarch
    
    This is used to enable the guard page when an elf binary is built with
    BTI instructions.
    
    Reviewed by:    markj
    Sponsored by:   Arm Ltd
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D39453
---
 sys/arm64/arm64/sys_machdep.c | 43 ++++++++++++++++++++++++++++++++++++++++++-
 sys/arm64/include/sysarch.h   |  7 +++++++
 2 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/sys/arm64/arm64/sys_machdep.c b/sys/arm64/arm64/sys_machdep.c
index 79546d29e251..eedc57f7c572 100644
--- a/sys/arm64/arm64/sys_machdep.c
+++ b/sys/arm64/arm64/sys_machdep.c
@@ -29,13 +29,54 @@
 
 #include <sys/param.h>
 #include <sys/systm.h>
+#include <sys/proc.h>
 #include <sys/sysproto.h>
 
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_map.h>
+
 #include <machine/sysarch.h>
+#include <machine/vmparam.h>
 
 int
 sysarch(struct thread *td, struct sysarch_args *uap)
 {
+	struct arm64_guard_page_args gp_args;
+	vm_offset_t eva;
+	int error;
+
+	switch (uap->op) {
+	case ARM64_GUARD_PAGE:
+		error = copyin(uap->parms, &gp_args, sizeof(gp_args));
+		if (error != 0)
+			return (error);
+
+		/* Only accept canonical addresses, no PAC or TBI */
+		if (!ADDR_IS_CANONICAL(gp_args.addr))
+			return (EINVAL);
+
+		eva = gp_args.addr + gp_args.len;
+
+		/* Check for a length overflow */
+		if (gp_args.addr > eva)
+			return (EINVAL);
+
+		/* Check in the correct address space */
+		if (eva >= VM_MAX_USER_ADDRESS)
+			return (EINVAL);
+
+		/* Nothing to do */
+		if (gp_args.len == 0)
+			return (0);
+
+		error = pmap_bti_set(vmspace_pmap(td->td_proc->p_vmspace),
+		    trunc_page(gp_args.addr), round_page(eva));
+		break;
+	default:
+		error = EINVAL;
+		break;
+	}
 
-	return (ENOTSUP);
+	return (error);
 }
diff --git a/sys/arm64/include/sysarch.h b/sys/arm64/include/sysarch.h
index 2bd45d384743..83094943423a 100644
--- a/sys/arm64/include/sysarch.h
+++ b/sys/arm64/include/sysarch.h
@@ -39,6 +39,13 @@
 #ifndef _MACHINE_SYSARCH_H_
 #define	_MACHINE_SYSARCH_H_
 
+#define	ARM64_GUARD_PAGE	0x100
+
+struct arm64_guard_page_args {
+	__uintptr_t	addr;
+	__size_t	len;
+};
+
 #ifndef _KERNEL
 
 __BEGIN_DECLS