Page MenuHomeFreeBSD

D39837.diff
No OneTemporary

D39837.diff

diff --git a/sys/arm64/arm64/support.S b/sys/arm64/arm64/support.S
--- a/sys/arm64/arm64/support.S
+++ b/sys/arm64/arm64/support.S
@@ -55,6 +55,98 @@
ret
END(fsu_fault)
+/*
+ * int swapueword8_llsc(volatile uint8_t *, uint8_t *)
+ */
+ENTRY(swapueword8_llsc)
+ check_user_access 0, (VM_MAXUSER_ADDRESS-3), fsu_fault_nopcb
+ adr x6, fsu_fault /* Load the fault handler */
+ SET_FAULT_HANDLER(x6, x4) /* And set it */
+ ENTER_USER_ACCESS(w6, x4)
+
+ ldrb w7, [x1]
+
+ ldxrb w2, [x0]
+ stxrb w3, w7, [x0]
+ cbnz w3, 1f
+
+ strb w2, [x1] /* Stash old value in *val */
+
+1: EXIT_USER_ACCESS(w6)
+ SET_FAULT_HANDLER(xzr, x6)
+ mov w0, w3
+ ret
+END(swapueword8_llsc)
+
+/*
+ * int swapueword8_lse(volatile uint8_t *, uint8_t *)
+ */
+ENTRY(swapueword8_lse)
+ check_user_access 0, (VM_MAXUSER_ADDRESS-3), fsu_fault_nopcb
+ adr x6, fsu_fault /* Load the fault handler */
+ SET_FAULT_HANDLER(x6, x4) /* And set it */
+ ENTER_USER_ACCESS(w6, x4)
+
+ ldrb w7, [x1]
+
+ .arch_extension lse
+ swpb w7, w2, [x0]
+ .arch_extension nolse
+
+ strb w2, [x1] /* Stash old value in *val */
+
+ EXIT_USER_ACCESS(w6)
+ SET_FAULT_HANDLER(xzr, x6)
+ mov w0, #0
+ ret
+END(swapueword8_lse)
+
+/*
+ * int swapueword32_llsc(volatile uint32_t *, uint32_t *)
+ */
+ENTRY(swapueword32_llsc)
+ check_user_access 0, (VM_MAXUSER_ADDRESS-3), fsu_fault_nopcb
+ adr x6, fsu_fault /* Load the fault handler */
+ SET_FAULT_HANDLER(x6, x4) /* And set it */
+ ENTER_USER_ACCESS(w6, x4)
+
+ ldr w7, [x1]
+
+ ldxr w2, [x0] /* Stash the old value in w2 */
+ stxr w3, w7, [x0] /* Store new value */
+ cbnz w3, 1f
+
+ str w2, [x1] /* Stash old value in *val */
+
+1: EXIT_USER_ACCESS(w6)
+ SET_FAULT_HANDLER(xzr, x6)
+ mov w0, w3
+ ret
+END(swapueword32_llsc)
+
+/*
+ * int swapueword32_lse(volatile uint32_t *, uint32_t *)
+ */
+ENTRY(swapueword32_lse)
+ check_user_access 0, (VM_MAXUSER_ADDRESS-3), fsu_fault_nopcb
+ adr x6, fsu_fault /* Load the fault handler */
+ SET_FAULT_HANDLER(x6, x4) /* And set it */
+ ENTER_USER_ACCESS(w6, x4)
+
+ ldr w7, [x1]
+
+ .arch_extension lse
+ swp w7, w2, [x0]
+ .arch_extension nolse
+
+ str w2, [x1] /* Stash old value in *val */
+
+ EXIT_USER_ACCESS(w6)
+ SET_FAULT_HANDLER(xzr, x6)
+ mov w0, #0
+ ret
+END(swapueword32_llsc)
+
/*
* int casueword32_llsc(volatile uint32_t *, uint32_t, uint32_t *, uint32_t)
*/
diff --git a/sys/arm64/arm64/support_ifunc.c b/sys/arm64/arm64/support_ifunc.c
--- a/sys/arm64/arm64/support_ifunc.c
+++ b/sys/arm64/arm64/support_ifunc.c
@@ -32,6 +32,8 @@
#include <machine/atomic.h>
#include <machine/ifunc.h>
+#define _MD_WANT_SWAPWORD
+#include <machine/md_var.h>
int casueword32_llsc(volatile uint32_t *, uint32_t, uint32_t *, uint32_t);
int casueword32_lse(volatile uint32_t *, uint32_t, uint32_t *, uint32_t);
@@ -39,6 +41,12 @@
int casueword_llsc(volatile u_long *, u_long, u_long *, u_long);
int casueword_lse(volatile u_long *, u_long, u_long *, u_long);
+int swapueword8_llsc(volatile uint8_t *, uint8_t *);
+int swapueword8_lse(volatile uint8_t *, uint8_t *);
+
+int swapueword32_llsc(volatile uint32_t *, uint32_t *);
+int swapueword32_lse(volatile uint32_t *, uint32_t *);
+
DEFINE_IFUNC(, int, casueword32, (volatile uint32_t *base, uint32_t oldval,
uint32_t *oldvalp, uint32_t newval))
{
@@ -56,3 +64,19 @@
return (casueword_llsc);
}
+
+DEFINE_IFUNC(, int, swapueword8, (volatile uint8_t *base, uint8_t *val))
+{
+ if (lse_supported)
+ return (swapueword8_lse);
+
+ return (swapueword8_llsc);
+}
+
+DEFINE_IFUNC(, int, swapueword32, (volatile uint32_t *base, uint32_t *val))
+{
+ if (lse_supported)
+ return (swapueword32_lse);
+
+ return (swapueword32_llsc);
+}
diff --git a/sys/arm64/include/md_var.h b/sys/arm64/include/md_var.h
--- a/sys/arm64/include/md_var.h
+++ b/sys/arm64/include/md_var.h
@@ -57,4 +57,15 @@
void generic_bs_poke_4(void) __asm(__STRING(generic_bs_poke_4));
void generic_bs_poke_8(void) __asm(__STRING(generic_bs_poke_8));
+#ifdef _MD_WANT_SWAPWORD
+/*
+ * XXX These are implemented primarily for swp/swpb emulation at the moment, and
+ * should be used sparingly with consideration -- they aren't implemented for
+ * any other platform. If we use them anywhere else, at a minimum they need
+ * KASAN/KMSAN interceptors added.
+ */
+int swapueword8(volatile uint8_t *base, uint8_t *val);
+int swapueword32(volatile uint32_t *base, uint32_t *val);
+#endif
+
#endif /* !_MACHINE_MD_VAR_H_ */

File Metadata

Mime Type
text/plain
Expires
Tue, Feb 4, 5:02 PM (20 h, 55 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16457737
Default Alt Text
D39837.diff (4 KB)

Event Timeline