summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Edmondson <dme@sun.com>2008-09-24 01:06:43 -0700
committerDavid Edmondson <dme@sun.com>2008-09-24 01:06:43 -0700
commita8e7f9274679c8d5db23e2fabf94acf69d081e32 (patch)
tree81d751694874daa0a7ab93eb3b482ba1f42b5c96
parent186f7fbf5e07d046b50e4e15c32b21f109b76c80 (diff)
downloadillumos-joyent-a8e7f9274679c8d5db23e2fabf94acf69d081e32.tar.gz
6746240 dom0 panic on winpv driver resume
-rw-r--r--usr/src/uts/common/xen/io/xnb.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/usr/src/uts/common/xen/io/xnb.c b/usr/src/uts/common/xen/io/xnb.c
index 2ec72a9b8d..fba00900a7 100644
--- a/usr/src/uts/common/xen/io/xnb.c
+++ b/usr/src/uts/common/xen/io/xnb.c
@@ -1507,6 +1507,27 @@ finished:
start = xnbp->xnb_tx_ring.req_cons;
end = xnbp->xnb_tx_ring.sring->req_prod;
+ if ((end - start) > NET_TX_RING_SIZE) {
+ /*
+ * This usually indicates that the frontend driver is
+ * misbehaving, as it's not possible to have more than
+ * NET_TX_RING_SIZE ring elements in play at any one
+ * time.
+ *
+ * We reset the ring pointers to the state declared by
+ * the frontend and try to carry on.
+ */
+ cmn_err(CE_WARN, "xnb_from_peer: domain %d tried to give us %u "
+ "items in the ring, resetting and trying to recover.",
+ xnbp->xnb_peer, (end - start));
+
+ /* LINTED: constant in conditional context */
+ BACK_RING_ATTACH(&xnbp->xnb_tx_ring,
+ (netif_tx_sring_t *)xnbp->xnb_tx_ring_addr, PAGESIZE);
+
+ goto around;
+ }
+
for (loop = start, mop = xnbp->xnb_tx_mop, txpp = xnbp->xnb_tx_bufp;
loop != end;
loop++, mop++, txpp++) {