Module Name:    src
Committed By:   riastradh
Date:           Thu Feb 23 14:54:57 UTC 2023

Modified Files:
        src/sys/arch/aarch64/aarch64: cpuswitch.S locore.S

Log Message:
aarch64: Add missing barriers in cpu_switchto.

Details in comments.

Note: This is a conservative change that inserts a barrier where
there was a comment saying none is needed, which is probably correct.
The goal of this change is to systematically add barriers to be
confident in correctness; subsequent changes may remove some bariers,
as an optimization, with an explanation of why each barrier is not
needed.

PR kern/57240

XXX pullup-9
XXX pullup-10


To generate a diff of this commit:
cvs rdiff -u -r1.39 -r1.40 src/sys/arch/aarch64/aarch64/cpuswitch.S
cvs rdiff -u -r1.90 -r1.91 src/sys/arch/aarch64/aarch64/locore.S

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/aarch64/aarch64/cpuswitch.S
diff -u src/sys/arch/aarch64/aarch64/cpuswitch.S:1.39 src/sys/arch/aarch64/aarch64/cpuswitch.S:1.40
--- src/sys/arch/aarch64/aarch64/cpuswitch.S:1.39	Mon Sep 19 17:23:14 2022
+++ src/sys/arch/aarch64/aarch64/cpuswitch.S	Thu Feb 23 14:54:57 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: cpuswitch.S,v 1.39 2022/09/19 17:23:14 ryo Exp $ */
+/* $NetBSD: cpuswitch.S,v 1.40 2023/02/23 14:54:57 riastradh Exp $ */
 
 /*-
  * Copyright (c) 2014, 2020 The NetBSD Foundation, Inc.
@@ -38,7 +38,7 @@
 #include "opt_ddb.h"
 #include "opt_kasan.h"
 
-RCSID("$NetBSD: cpuswitch.S,v 1.39 2022/09/19 17:23:14 ryo Exp $")
+RCSID("$NetBSD: cpuswitch.S,v 1.40 2023/02/23 14:54:57 riastradh Exp $")
 
 	ARMV8_DEFINE_OPTIONS
 
@@ -125,8 +125,29 @@ ENTRY_NP(cpu_switchto)
 
 	msr	tpidr_el1, x1		/* switch curlwp to new lwp */
 	ldr	x3, [x1, #L_CPU]
+
+	/*
+	 * 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.
+	 */
+	dmb	ishst			/* store-before-store */
 	str	x1, [x3, #CI_CURLWP]	/* switch curlwp to new lwp */
-	dmb	ishst			/* see comments in kern_mutex.c */
+	dmb	ish			/* store-before-load */
+
 	ENABLE_INTERRUPT
 
 	/*
@@ -201,8 +222,9 @@ ENTRY_NP(cpu_switchto_softint)
 	/* onto new stack */
 	sub	sp, x4, #TF_SIZE	/* new sp := softlwp->l_md_utf - 1 */
 	msr	tpidr_el1, x0		/* curlwp = softlwp; */
+	dmb	ishst			/* for mutex_enter; see cpu_switchto */
 	str	x0, [x20, #CI_CURLWP]	/* curcpu()->ci_curlwp = softlwp; */
-					/* no need for memory barrier here */
+	dmb	ish			/* for mutex_enter; see cpu_switchto */
 
 	mov	x5, #CPACR_FPEN_NONE
 	msr	cpacr_el1, x5		/* cpacr_el1 = CPACR_FPEN_NONE */
@@ -244,8 +266,9 @@ ENTRY_NP(cpu_switchto_softint)
 	DISABLE_INTERRUPT
 	msr	tpidr_el1, x19		/* curlwp = pinned_lwp */
 	ldr	x3, [x19, #L_CPU]	/* x3 = curlwp->l_cpu */
+	dmb	ishst			/* for mutex_enter; see cpu_switchto */
 	str	x19, [x3, #CI_CURLWP]	/* curlwp->l_cpu->ci_curlwp := x19 */
-	dmb	ishst			/* see comments in kern_mutex.c */
+	dmb	ish			/* for mutex_enter; see cpu_switchto */
 
 	mov	sp, x4			/* restore pinned_lwp sp */
 	msr	cpacr_el1, x5		/* restore pinned_lwp cpacr */

Index: src/sys/arch/aarch64/aarch64/locore.S
diff -u src/sys/arch/aarch64/aarch64/locore.S:1.90 src/sys/arch/aarch64/aarch64/locore.S:1.91
--- src/sys/arch/aarch64/aarch64/locore.S:1.90	Fri Feb 17 06:24:26 2023
+++ src/sys/arch/aarch64/aarch64/locore.S	Thu Feb 23 14:54:57 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: locore.S,v 1.90 2023/02/17 06:24:26 skrll Exp $	*/
+/*	$NetBSD: locore.S,v 1.91 2023/02/23 14:54:57 riastradh Exp $	*/
 
 /*
  * Copyright (c) 2017 Ryo Shimizu <r...@nerv.org>
@@ -38,7 +38,7 @@
 #include <aarch64/hypervisor.h>
 #include "assym.h"
 
-RCSID("$NetBSD: locore.S,v 1.90 2023/02/17 06:24:26 skrll Exp $")
+RCSID("$NetBSD: locore.S,v 1.91 2023/02/23 14:54:57 riastradh Exp $")
 
 #ifdef AARCH64_DEVICE_MEM_NONPOSTED
 #define	MAIR_DEVICE_MEM		MAIR_DEVICE_nGnRnE
@@ -529,6 +529,11 @@ mp_vstart:
 	 */
 	ldr	x1, [x0, #CI_IDLELWP]	/* x0 = curcpu()->ci_idlelwp */
 	msr	tpidr_el1, x1		/* tpidr_el1 = curlwp = x1 */
+	/*
+	 * 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	x1, [x0, #CI_CURLWP]	/* curlwp is idlelwp */
 
 	/* get my stack from lwp */

Reply via email to