summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorriastradh <riastradh@NetBSD.org>2023-02-23 14:55:24 +0000
committerriastradh <riastradh@NetBSD.org>2023-02-23 14:55:24 +0000
commitf7bcfe7a6d92db4057151038d4b50bcdf4e51530 (patch)
tree0e1a5f6f0cb1d6a9a29ef558494ac9d03941fb70 /sys
parent9d265a177a27bfdc509e2b1e65cc0f5be5905a6d (diff)
arm32: Add missing barriers in cpu_switchto.
Details in comments. PR kern/57240 XXX pullup-8 XXX pullup-9 XXX pullup-10
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/arm/arm/armv6_start.S7
-rw-r--r--sys/arch/arm/arm32/cpuswitch.S40
2 files changed, 41 insertions, 6 deletions
diff --git a/sys/arch/arm/arm/armv6_start.S b/sys/arch/arm/arm/armv6_start.S
index 150704305a7..ae60a1fd7cd 100644
--- a/sys/arch/arm/arm/armv6_start.S
+++ b/sys/arch/arm/arm/armv6_start.S
@@ -1,4 +1,4 @@
-/* $NetBSD: armv6_start.S,v 1.37 2021/11/14 16:56:32 riastradh Exp $ */
+/* $NetBSD: armv6_start.S,v 1.38 2023/02/23 14:55:24 riastradh Exp $ */
/*-
* Copyright (c) 2012, 2017, 2018 The NetBSD Foundation, Inc.
@@ -943,6 +943,11 @@ armv7_mpcontinuation:
#else
#error either TPIDRPRW_IS_CURCPU or TPIDRPRW_IS_CURLWP must be defined
#endif
+ /*
+ * No membar needed because we're not switching from a
+ * previous lwp, and the idle lwp we're switching to can't be
+ * holding locks already; see cpu_switchto.
+ */
str r6, [r5, #CI_CURLWP] // and note we are running on it
mov r0, r5 // pass cpu_info
diff --git a/sys/arch/arm/arm32/cpuswitch.S b/sys/arch/arm/arm32/cpuswitch.S
index 1ffda42dbd8..e84650e6924 100644
--- a/sys/arch/arm/arm32/cpuswitch.S
+++ b/sys/arch/arm/arm32/cpuswitch.S
@@ -1,4 +1,4 @@
-/* $NetBSD: cpuswitch.S,v 1.105 2021/05/30 06:53:15 dholland Exp $ */
+/* $NetBSD: cpuswitch.S,v 1.106 2023/02/23 14:55:25 riastradh Exp $ */
/*
* Copyright 2003 Wasabi Systems, Inc.
@@ -87,7 +87,7 @@
#include <arm/asm.h>
#include <arm/locore.h>
- RCSID("$NetBSD: cpuswitch.S,v 1.105 2021/05/30 06:53:15 dholland Exp $")
+ RCSID("$NetBSD: cpuswitch.S,v 1.106 2023/02/23 14:55:25 riastradh Exp $")
/* LINTSTUB: include <sys/param.h> */
@@ -189,11 +189,32 @@ ENTRY(cpu_switchto)
mcr p15, 0, r6, c13, c0, 4 /* set current lwp */
#endif
+ /*
+ * Issue barriers to coordinate mutex_exit on this CPU with
+ * mutex_vector_enter on another CPU.
+ *
+ * 1. Any prior mutex_exit by oldlwp must be visible to other
+ * CPUs before we set ci_curlwp := newlwp on this one,
+ * requiring a store-before-store barrier.
+ *
+ * 2. ci_curlwp := newlwp must be visible on all other CPUs
+ * before any subsequent mutex_exit by newlwp can even test
+ * whether there might be waiters, requiring a
+ * store-before-load barrier.
+ *
+ * See kern_mutex.c for details -- this is necessary for
+ * adaptive mutexes to detect whether the lwp is on the CPU in
+ * order to safely block without requiring atomic r/m/w in
+ * mutex_exit.
+ */
+
/* We have a new curlwp now so make a note of it */
+#ifdef _ARM_ARCH_7
+ dmb /* store-before-store */
+#endif
str r6, [r5, #(CI_CURLWP)]
-
#ifdef _ARM_ARCH_7
- dmb /* see comments in kern_mutex.c */
+ dmb /* store-before-load */
#endif
/* Get the new pcb */
@@ -392,9 +413,12 @@ ENTRY_NP(softint_switch)
#if defined(TPIDRPRW_IS_CURLWP)
mcr p15, 0, r5, c13, c0, 4 /* save new lwp */
#endif
+#ifdef _ARM_ARCH_7
+ dmb /* for mutex_enter; see cpu_switchto */
+#endif
str r5, [r7, #(CI_CURLWP)] /* save new lwp */
#ifdef _ARM_ARCH_7
- dmb /* see comments in kern_mutex.c */
+ dmb /* for mutex_enter; see cpu_switchto */
#endif
#ifdef KASAN
@@ -428,7 +452,13 @@ ENTRY_NP(softint_switch)
#if defined(TPIDRPRW_IS_CURLWP)
mcr p15, 0, r4, c13, c0, 4 /* restore pinned lwp */
#endif
+#ifdef _ARM_ARCH_7
+ dmb /* for mutex_enter; see cpu_switchto */
+#endif
str r4, [r7, #(CI_CURLWP)] /* restore pinned lwp */
+#ifdef _ARM_ARCH_7
+ dmb /* for mutex_enter; see cpu_switchto */
+#endif
ldr sp, [r2, #(PCB_KSP)] /* now running on the old stack. */
/* At this point we can allow IRQ's again. */