summaryrefslogtreecommitdiff
path: root/sys/arch/arm64
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2017-12-30 10:20:35 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2017-12-30 10:20:35 +0000
commitdd931eed7e6d283efc61139aa3183a1b53269433 (patch)
tree08ce702e04a135c6110a525008fb9f31a36dae42 /sys/arch/arm64
parenteee4a7103a668b2d75e4adffb3f96aa35b3a5289 (diff)
Add copyin32 implementation.
ok guenther@
Diffstat (limited to 'sys/arch/arm64')
-rw-r--r--sys/arch/arm64/arm64/copy.S24
1 files changed, 23 insertions, 1 deletions
diff --git a/sys/arch/arm64/arm64/copy.S b/sys/arch/arm64/arm64/copy.S
index 0a493cc16e1..af9f015ec08 100644
--- a/sys/arch/arm64/arm64/copy.S
+++ b/sys/arch/arm64/arm64/copy.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: copy.S,v 1.3 2017/02/15 21:39:50 patrick Exp $ */
+/* $OpenBSD: copy.S,v 1.4 2017/12/30 10:20:34 kettenis Exp $ */
/*
* Copyright (c) 2015 Dale Rahn <drahn@dalerahn.com>
* Copyright (c) 2014 Patrick Wildt <patrick@blueri.se>
@@ -61,6 +61,28 @@ ENTRY(copyin)
ret
/*
+ * x0 = user space address
+ * x1 = kernel space address
+ *
+ * Atomically copies a 32-bit word from user space to kernel space
+ *
+ * XXX should this assert that address spaces are correct for each address?
+ */
+ENTRY(copyin32)
+ mrs x3, tpidr_el1 // load cpuinfo
+ ldr x3, [x3, #(CI_CURPCB)]
+ ldr x4, [x3, #(PCB_ONFAULT)]
+ adr x5, .Lcopyfault
+ str x5, [x3, #(PCB_ONFAULT)] // set handler
+
+ ldtr w6, [x0]
+ str w6, [x1]
+
+ str x4, [x3, #(PCB_ONFAULT)] // clear handler
+ mov x0, xzr
+ ret
+
+/*
* x0 = kernel space address
* x1 = user space address
* x2 = length