aboutsummaryrefslogtreecommitdiff
path: root/sys/arm64/arm64/sys_machdep.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arm64/arm64/sys_machdep.c')
-rw-r--r--sys/arm64/arm64/sys_machdep.c43
1 files changed, 42 insertions, 1 deletions
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);
}