Skip to content

Commit 389b246

Browse files
Pull up following revision(s) (requested by riastradh in ticket #60):
sys/arch/sparc/sparc/locore.s: revision 1.287 share/man/man9/Makefile: revision 1.475 sys/arch/mips/mips/cpu_subr.c: revision 1.65 sys/arch/mips/mips/cpu_subr.c: revision 1.66 sys/arch/amd64/amd64/cpufunc.S: revision 1.70 sys/arch/hppa/hppa/support.S: revision 1.9 sys/arch/alpha/alpha/locore.s: revision 1.145 share/man/man9/paravirt_membar_sync.9: revision 1.1 sys/arch/sparc64/sparc64/locore.s: revision 1.436 distrib/sets/lists/comp/mi: revision 1.2499 sys/arch/i386/i386/cpufunc.S: revision 1.54 sys/sys/paravirt_membar.h: revision 1.1 sys/arch/arm/arm/cpu_subr.c: revision 1.6 (all via patch) paravirt_membar_sync(9): New memory barrier. For use in paravirtualized drivers which require store-before-load ordering -- irrespective of whether the kernel is built for a single processor, or whether the (virtual) machine is booted with a single processor. This is even required on architectures that don't even have a store-before-load ordering barrier, like m68k; adding, e.g., a virtio bus is _as if_ the architecture has been extended with relaxed memory ordering when talking with that new bus. Such architectures need some way to request the hypervisor enforce that ordering -- on m68k, that's done by issuing a CASL instruction, which qemu maps to an atomic r/m/w with sequential consistency ordering in the host. PR kern/59618: occasional virtio block device lock ups/hangs mips: Fix asm arch options in new paravirt_membar_sync. Need to explicitly enable mips2 (MIPS-II) instructions in order to use sync. Fixes: /tmp/ccxgOmXc.s: Assembler messages: /tmp/ccxgOmXc.s:3576: Error: opcode not supported on this processor: mips1 (mips1) `sync' --- cpu_subr.o --- *** Failed target: cpu_subr.o PR kern/59618: occasional virtio block device lock ups/hangs
1 parent f42278f commit 389b246

File tree

13 files changed

+411
-17
lines changed

13 files changed

+411
-17
lines changed

distrib/sets/lists/comp/mi

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# $NetBSD: mi,v 1.2278.2.9 2024/10/11 17:35:46 martin Exp $
1+
# $NetBSD: mi,v 1.2278.2.10 2025/10/19 10:44:32 martin Exp $
22
#
33
# Note: don't delete entries from here - mark them as "obsolete" instead.
44
./etc/mtree/set.comp comp-sys-root
@@ -11438,6 +11438,7 @@
1143811438
./usr/share/man/cat9/optstr_get.0 comp-sys-catman .cat
1143911439
./usr/share/man/cat9/p_find.0 comp-obsolete obsolete
1144011440
./usr/share/man/cat9/panic.0 comp-sys-catman .cat
11441+
./usr/share/man/cat9/paravirt_membar_sync.0 comp-sys-catman .cat
1144111442
./usr/share/man/cat9/pathbuf.0 comp-sys-catman .cat
1144211443
./usr/share/man/cat9/pci.0 comp-sys-catman .cat
1144311444
./usr/share/man/cat9/pci_conf_hook.0 comp-sys-catman .cat
@@ -19364,6 +19365,7 @@
1936419365
./usr/share/man/html9/optstr_get.html comp-sys-htmlman html
1936519366
./usr/share/man/html9/p_find.html comp-obsolete obsolete
1936619367
./usr/share/man/html9/panic.html comp-sys-htmlman html
19368+
./usr/share/man/html9/paravirt_membar_sync.html comp-sys-htmlman html
1936719369
./usr/share/man/html9/pathbuf.html comp-sys-htmlman html
1936819370
./usr/share/man/html9/pci.html comp-sys-htmlman html
1936919371
./usr/share/man/html9/pci_conf_hook.html comp-sys-htmlman html
@@ -27449,6 +27451,7 @@
2744927451
./usr/share/man/man9/optstr_get.9 comp-sys-man .man
2745027452
./usr/share/man/man9/p_find.9 comp-obsolete obsolete
2745127453
./usr/share/man/man9/panic.9 comp-sys-man .man
27454+
./usr/share/man/man9/paravirt_membar_sync.9 comp-sys-man .man
2745227455
./usr/share/man/man9/pathbuf.9 comp-sys-man .man
2745327456
./usr/share/man/man9/pci.9 comp-sys-man .man
2745427457
./usr/share/man/man9/pci_conf_hook.9 comp-sys-man .man

share/man/man9/Makefile

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# $NetBSD: Makefile,v 1.437.2.4 2024/07/20 16:57:51 martin Exp $
1+
# $NetBSD: Makefile,v 1.437.2.5 2025/10/19 10:44:31 martin Exp $
22

33
# Makefile for section 9 (kernel function and variable) manual pages.
44

@@ -39,7 +39,12 @@ MAN= accept_filter.9 accf_data.9 accf_http.9 \
3939
microseq.9 microtime.9 microuptime.9 mi_switch.9 module.9 \
4040
mstohz.9 mutex.9 m_tag.9 namecache.9 \
4141
namei.9 nullop.9 opencrypto.9 optstr.9 \
42-
panic.9 pathbuf.9 pci.9 pci_configure_bus.9 pci_intr.9 \
42+
panic.9 \
43+
paravirt_membar_sync.9 \
44+
pathbuf.9 \
45+
pci.9 \
46+
pci_configure_bus.9 \
47+
pci_intr.9 \
4348
pci_msi.9 pckbport.9 pcmcia.9 pcq.9 pcu.9 \
4449
percpu.9 pfil.9 physio.9 pmap.9 pmatch.9 pmf.9 pool.9 \
4550
pool_cache.9 powerhook_establish.9 ppsratecheck.9 preempt.9 \
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
.\" $NetBSD: paravirt_membar_sync.9,v 1.1.6.2 2025/10/19 10:44:31 martin Exp $
2+
.\"
3+
.\" Copyright (c) 2025 The NetBSD Foundation
4+
.\" All rights reserved.
5+
.\"
6+
.\" Redistribution and use in source and binary forms, with or without
7+
.\" modification, are permitted provided that the following conditions
8+
.\" are met:
9+
.\" 1. Redistributions of source code must retain the above copyright
10+
.\" notice, this list of conditions and the following disclaimer.
11+
.\" 2. Redistributions in binary form must reproduce the above copyright
12+
.\" notice, this list of conditions and the following disclaimer in the
13+
.\" documentation and/or other materials provided with the distribution.
14+
.\"
15+
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
16+
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17+
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18+
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
19+
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20+
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21+
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22+
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23+
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24+
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25+
.\" POSSIBILITY OF SUCH DAMAGE.
26+
.\"
27+
.Dd August 31, 2025
28+
.Dt PARAVIRT_MEMBAR_SYNC 9
29+
.Os
30+
.Sh NAME
31+
.Nm paravirt_membar_sync
32+
.Nd memory barrier for paravirtualized device drivers
33+
.Sh SYNOPSIS
34+
.In sys/paravirt_membar.h
35+
.Ft void
36+
.Fn paravirt_membar_sync "void"
37+
.Sh DESCRIPTION
38+
The
39+
.Nm
40+
function issues a store-before-load barrier for coordination with a
41+
paravirtualized device.
42+
.Pp
43+
This function has the same ordering semantics as
44+
.Xr membar_sync 3 ,
45+
but
46+
.Xr membar_sync 3
47+
can only coordinate with other CPUs that
48+
.Nx
49+
is running on.
50+
In a virtual machine,
51+
.Nx
52+
may be running on a single
53+
.Em virtual
54+
CPU, and patch
55+
.Xr membar_sync 3
56+
to be a no-op, while the host side of a paravirtualized device may be
57+
running on a different
58+
.Em physical
59+
CPU requiring a barrier that
60+
.Xr membar_sync 3
61+
does not issue.
62+
.Sh EXAMPLES
63+
Submit a request to the host device, and notify the host to process
64+
it\(embut elide the notification, which is expensive, if the host is
65+
already reading requests anyway:
66+
.Bd -literal
67+
/*
68+
* Write the request into the ring buffer.
69+
*/
70+
memcpy(cputodev_ring->buffer[sc->sc_cputodev_idx], request,
71+
sizeof(*request));
72+
73+
/*
74+
* Publish the request to the host device side.
75+
*/
76+
cputodev_ring->header->producer_tail = ++sc->sc_cputodev_idx;
77+
78+
/*
79+
* Ensure we have published it _before_ we check whether the
80+
* host needs notification.
81+
*/
82+
paravirt_membar_sync();
83+
84+
/*
85+
* Notify the host, if needed. Notifying the host is usually
86+
* expensive (trap to hypervisor), so we try to avoid it if not
87+
* needed.
88+
*/
89+
if (cputodev_ring->header->needs_notification)
90+
notify_host();
91+
.Ed
92+
.Pp
93+
Enable interrupts from the host and check whether any were pending
94+
while interrupts were disabled:
95+
.Bd -literal
96+
/*
97+
* Tell the host device to deliver interrupts after this
98+
* point.
99+
*/
100+
restart:
101+
devtocpu_ring->header->needs_notification = true;
102+
103+
/*
104+
* Ensure we have requested interrupts _before_ we check
105+
* whether we missed any notifications.
106+
*/
107+
paravirt_membar_sync();
108+
109+
/*
110+
* Check whether there were any pending notifications while
111+
* interrupts were blocked. If not, stop here.
112+
*/
113+
idx = devtocpu_ring->header->producer_idx;
114+
if (sc->sc_devtocpu_idx == idx)
115+
return;
116+
117+
/*
118+
* Process the notifications.
119+
*/
120+
devtocpu_ring->header->needs_notification = false;
121+
while (sc->sc_devtocpu_idx != idx) {
122+
struct buffer *buf =
123+
devtocpu_ring->buffer[sc->sc_devtocpu_idx];
124+
process_notification(buf);
125+
sc->sc_devtocpu_idx++;
126+
sc->sc_devtocpu_idx %= ringlen;
127+
}
128+
goto restart;
129+
.Ed
130+
.Pp
131+
.Sy "N.B.:"
132+
Other ordering or bouncing may be required with
133+
.Xr bus_dmamap_sync 9 ;
134+
this is independent of
135+
.Nm ,
136+
which is needed
137+
.Em in addition to
138+
.Xr bus_dmamap_sync 9
139+
to guarantee store-before-load ordering when there is no intervening
140+
I/O doorbell trigger for a DMA operation, nor interrupt delivery for a
141+
DMA completion.
142+
.Sh SEE ALSO
143+
.Xr membar_ops 3 ,
144+
.Xr bus_dma 9 ,
145+
.Xr bus_space 9
146+
.Sh HISTORY
147+
These atomic operations first appeared in
148+
.Nx 12.0 .

sys/arch/aarch64/aarch64/aarch64_machdep.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $NetBSD: aarch64_machdep.c,v 1.28.4.4 2021/06/04 14:00:17 martin Exp $ */
1+
/* $NetBSD: aarch64_machdep.c,v 1.28.4.5 2025/10/19 10:44:33 martin Exp $ */
22

33
/*-
44
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
3030
*/
3131

3232
#include <sys/cdefs.h>
33-
__KERNEL_RCSID(1, "$NetBSD: aarch64_machdep.c,v 1.28.4.4 2021/06/04 14:00:17 martin Exp $");
33+
__KERNEL_RCSID(1, "$NetBSD: aarch64_machdep.c,v 1.28.4.5 2025/10/19 10:44:33 martin Exp $");
3434

3535
#include "opt_arm_debug.h"
3636
#include "opt_ddb.h"
@@ -49,6 +49,7 @@ __KERNEL_RCSID(1, "$NetBSD: aarch64_machdep.c,v 1.28.4.4 2021/06/04 14:00:17 mar
4949
#include <sys/kcore.h>
5050
#include <sys/module.h>
5151
#include <sys/msgbuf.h>
52+
#include <sys/paravirt_membar.h>
5253
#include <sys/reboot.h>
5354
#include <sys/sysctl.h>
5455

@@ -845,3 +846,21 @@ cpu_dumpconf(void)
845846
bad:
846847
dumpsize = 0;
847848
}
849+
850+
void
851+
paravirt_membar_sync(void)
852+
{
853+
854+
/*
855+
* Store-before-load ordering with respect to matching logic
856+
* on the hypervisor side.
857+
*
858+
* This is the same as membar_sync, but guaranteed never to be
859+
* conditionalized or hotpatched away even on uniprocessor
860+
* builds and boots -- because under virtualization, we still
861+
* have to coordinate with a `device' backed by a hypervisor
862+
* that is potentially on another physical CPU even if we
863+
* observe only one virtual CPU as the guest.
864+
*/
865+
__asm __volatile("dmb ish" ::: "memory");
866+
}

sys/arch/alpha/alpha/locore.s

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $NetBSD: locore.s,v 1.123.4.1 2023/07/31 17:59:23 martin Exp $ */
1+
/* $NetBSD: locore.s,v 1.123.4.2 2025/10/19 10:44:31 martin Exp $ */
22

33
/*-
44
* Copyright (c) 1999, 2000, 2019 The NetBSD Foundation, Inc.
@@ -67,7 +67,7 @@
6767

6868
#include <machine/asm.h>
6969

70-
__KERNEL_RCSID(0, "$NetBSD: locore.s,v 1.123.4.1 2023/07/31 17:59:23 martin Exp $");
70+
__KERNEL_RCSID(0, "$NetBSD: locore.s,v 1.123.4.2 2025/10/19 10:44:31 martin Exp $");
7171

7272
#include "assym.h"
7373

@@ -1381,3 +1381,19 @@ LEAF(alpha_write_fpcr, 1); f30save = 0; fpcrtmp = 8; framesz = 16
13811381
lda sp, framesz(sp)
13821382
RET
13831383
END(alpha_write_fpcr)
1384+
1385+
LEAF(paravirt_membar_sync, 0)
1386+
/*
1387+
* Store-before-load ordering with respect to matching logic
1388+
* on the hypervisor side.
1389+
*
1390+
* This is the same as membar_sync, but without hotpatching
1391+
* away the MB instruction on uniprocessor boots -- because
1392+
* under virtualization, we still have to coordinate with a
1393+
* `device' backed by a hypervisor that is potentially on
1394+
* another physical CPU even if we observe only one virtual CPU
1395+
* as the guest.
1396+
*/
1397+
mb
1398+
RET
1399+
END(paravirt_membar_sync)

sys/arch/amd64/amd64/cpufunc.S

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $NetBSD: cpufunc.S,v 1.43 2019/07/05 17:08:55 maxv Exp $ */
1+
/* $NetBSD: cpufunc.S,v 1.43.2.1 2025/10/19 10:44:31 martin Exp $ */
22

33
/*
44
* Copyright (c) 1998, 2007, 2008 The NetBSD Foundation, Inc.
@@ -64,6 +64,27 @@ ENTRY(x86_mfence)
6464
ret
6565
END(x86_mfence)
6666

67+
ENTRY(paravirt_membar_sync)
68+
/*
69+
* Store-before-load ordering with respect to matching logic
70+
* on the hypervisor side.
71+
*
72+
* This is the same as membar_sync, but without hotpatching
73+
* away the LOCK prefix on uniprocessor boots -- because under
74+
* virtualization, we still have to coordinate with a `device'
75+
* backed by a hypervisor that is potentially on another
76+
* physical CPU even if we observe only one virtual CPU as the
77+
* guest.
78+
*
79+
* See common/lib/libc/arch/x86_64/atomic/atomic.S for
80+
* rationale and keep this in sync with the implementation
81+
* of membar_sync there.
82+
*/
83+
lock
84+
addq $0,-8(%rsp)
85+
ret
86+
END(paravirt_membar_sync)
87+
6788
#ifndef XENPV
6889
ENTRY(invlpg)
6990
#ifdef SVS

sys/arch/arm/arm32/arm32_machdep.c

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $NetBSD: arm32_machdep.c,v 1.128.2.1 2020/02/12 20:10:09 martin Exp $ */
1+
/* $NetBSD: arm32_machdep.c,v 1.128.2.2 2025/10/19 10:44:33 martin Exp $ */
22

33
/*
44
* Copyright (c) 1994-1998 Mark Brinicombe.
@@ -42,7 +42,7 @@
4242
*/
4343

4444
#include <sys/cdefs.h>
45-
__KERNEL_RCSID(0, "$NetBSD: arm32_machdep.c,v 1.128.2.1 2020/02/12 20:10:09 martin Exp $");
45+
__KERNEL_RCSID(0, "$NetBSD: arm32_machdep.c,v 1.128.2.2 2025/10/19 10:44:33 martin Exp $");
4646

4747
#include "opt_arm_debug.h"
4848
#include "opt_arm_start.h"
@@ -71,6 +71,7 @@ __KERNEL_RCSID(0, "$NetBSD: arm32_machdep.c,v 1.128.2.1 2020/02/12 20:10:09 mart
7171
#include <sys/atomic.h>
7272
#include <sys/xcall.h>
7373
#include <sys/ipi.h>
74+
#include <sys/paravirt_membar.h>
7475

7576
#include <uvm/uvm_extern.h>
7677

@@ -879,3 +880,36 @@ cpu_kernel_vm_init(paddr_t memory_start, psize_t memory_size)
879880
}
880881
#endif
881882

883+
#if defined _ARM_ARCH_6 || defined _ARM_ARCH_7 /* see below regarding armv<6 */
884+
void
885+
paravirt_membar_sync(void)
886+
{
887+
888+
/*
889+
* Store-before-load ordering with respect to matching logic
890+
* on the hypervisor side.
891+
*
892+
* This is the same as membar_sync, but guaranteed never to be
893+
* conditionalized or hotpatched away even on uniprocessor
894+
* builds and boots -- because under virtualization, we still
895+
* have to coordinate with a `device' backed by a hypervisor
896+
* that is potentially on another physical CPU even if we
897+
* observe only one virtual CPU as the guest.
898+
*
899+
* Prior to armv6, there was no data memory barrier
900+
* instruction. Such CPUs presumably don't exist in
901+
* multiprocessor configurations. But what if we're running a
902+
* _kernel_ built for a uniprocessor armv5 CPU, as a virtual
903+
* machine guest of a _host_ with a newer multiprocessor CPU?
904+
* How do we enforce store-before-load ordering for a
905+
* paravirtualized device driver, coordinating with host
906+
* software `device' potentially on another CPU? You'll have
907+
* to answer that before you can use virtio drivers!
908+
*/
909+
#ifdef _ARM_ARCH_7
910+
__asm __volatile("dmb ish" ::: "memory");
911+
#else
912+
__asm __volatile("mcr p15, 0, %0, c7, c10, 5" :: "r"(0) : "memory");
913+
#endif
914+
}
915+
#endif /* defined _ARM_ARCH_6 || defined _ARM_ARCH_7 */

sys/arch/hppa/hppa/support.S

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $NetBSD: support.S,v 1.7 2019/04/15 20:45:08 skrll Exp $ */
1+
/* $NetBSD: support.S,v 1.7.4.1 2025/10/19 10:44:31 martin Exp $ */
22

33
/* $OpenBSD: locore.S,v 1.46 2001/09/20 18:33:03 mickey Exp $ */
44

@@ -304,3 +304,18 @@ LEAF_ENTRY(longjmp)
304304
copy %arg1,%ret0 /* Move return value to where it belongs. */
305305
EXIT(longjmp)
306306

307+
LEAF_ENTRY(paravirt_membar_sync)
308+
/*
309+
* Store-before-load ordering with respect to matching logic
310+
* on the hypervisor side.
311+
*
312+
* This is the same as membar_sync, but guaranteed never to be
313+
* conditionalized or hotpatched away even on uniprocessor
314+
* builds and boots -- because under virtualization, we still
315+
* have to coordinate with a `device' backed by a hypervisor
316+
* that is potentially on another physical CPU even if we
317+
* observe only one virtual CPU as the guest.
318+
*/
319+
bv %r0(%rp)
320+
sync
321+
EXIT(paravirt_membar_sync)

0 commit comments

Comments
 (0)