summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorstsp <stsp@openbsd.org>2018-01-06 21:35:45 +0000
committerstsp <stsp@openbsd.org>2018-01-06 21:35:45 +0000
commite36e7d99e64b9791877b11b1efc3ef24a1876eb7 (patch)
tree6572a864c97129a14c757b01e00338a2c829a58e /sys
parentDon't advertise L0s if the "aspm-no-l0s" property is present. Base available (diff)
downloadwireguard-openbsd-e36e7d99e64b9791877b11b1efc3ef24a1876eb7.tar.xz
wireguard-openbsd-e36e7d99e64b9791877b11b1efc3ef24a1876eb7.zip
Fix an interrupt storm condition in vldcp(8) (sparc64).
If the Rx channel goes down with pending data on the ring, toss the pending data to ensure that the firmware's rx ring head index matches the rx ring tail index. Otherwise we trigger an interrupt storm since vldcpread() never consumes pending data while the channel is down, and the firmware keeps triggering the interrupt until all data on the ring is consumed. Interrupt storm observed and fix tested on a T5220 (which can now run ldom guests; without this fix starting ldomd would trigger the problem). ok kettenis@
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/sparc64/dev/vldcp.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/sys/arch/sparc64/dev/vldcp.c b/sys/arch/sparc64/dev/vldcp.c
index c51f2220459..f8ebc731089 100644
--- a/sys/arch/sparc64/dev/vldcp.c
+++ b/sys/arch/sparc64/dev/vldcp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vldcp.c,v 1.12 2015/02/10 22:04:00 miod Exp $ */
+/* $OpenBSD: vldcp.c,v 1.13 2018/01/06 21:35:45 stsp Exp $ */
/*
* Copyright (c) 2009, 2012 Mark Kettenis
*
@@ -248,6 +248,14 @@ vldcp_rx_intr(void *arg)
switch (rx_state) {
case LDC_CHANNEL_DOWN:
DPRINTF(("Rx link down\n"));
+ if (rx_head == rx_tail)
+ break;
+ /* Discard and ack pending I/O. */
+ DPRINTF(("setting rx qhead to %lld\n", rx_tail));
+ err = hv_ldc_rx_set_qhead(lc->lc_id, rx_tail);
+ if (err == H_EOK)
+ break;
+ printf("%s: hv_ldc_rx_set_qhead %d\n", __func__, err);
break;
case LDC_CHANNEL_UP:
DPRINTF(("Rx link up\n"));