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 */