# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID b715a9f4dba0352a260bd8dc7aeaa7a9e9a7e6f6
# Parent ec11c5cca195bd6a671a9813d4610d8847e01eee
Qemu-dm dumps core with the pcnet device. This patches fixes it.
When pcnet_receive calls pcnet_poll, which polls the receive and the send
rings. Whenever there is an element in the send ring that is owned by
the Lance chip it will call pcnet_transmit and send it. When the element
is the endp(acket), pcnet_transmit will copy it out, send the packet
(qemu_send_packet) and then clear the owner bit. Somewherer along the
qemu_send_packet execution path, pcnet_recieve is called again, which
calls pcnet_poll and starts this whole process again. This very rapidly
leads to a stack overflow and crashes qemu.
The fix is simple, stop the recursion. Once the packet is copied into
qemu datatstructure (before qemu_send_packet is called!), the owner bit
on the ring element should be cleared.
Signed-Off-By: Leendert van Doorn <leendert@xxxxxxxxxxxxxx>
diff -r ec11c5cca195 -r b715a9f4dba0 tools/ioemu/hw/pcnet.c
--- a/tools/ioemu/hw/pcnet.c Fri Sep 2 17:02:08 2005
+++ b/tools/ioemu/hw/pcnet.c Fri Sep 2 17:52:37 2005
@@ -569,6 +569,10 @@
cpu_physical_memory_read(PHYSADDR(s, tmd.tmd0.tbadr),
s->buffer + s->xmit_pos, 4096 - tmd.tmd1.bcnt);
s->xmit_pos += 4096 - tmd.tmd1.bcnt;
+
+ tmd.tmd1.own = 0;
+ TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s)));
+
#ifdef PCNET_DEBUG
printf("pcnet_transmit size=%d\n", s->xmit_pos);
#endif
@@ -580,10 +584,10 @@
s->csr[0] &= ~0x0008; /* clear TDMD */
s->csr[4] |= 0x0004; /* set TXSTRT */
s->xmit_pos = -1;
- }
-
- tmd.tmd1.own = 0;
- TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s)));
+ } else {
+ tmd.tmd1.own = 0;
+ TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s)));
+ }
if (!CSR_TOKINTD(s) || (CSR_LTINTEN(s) && tmd.tmd1.ltint))
s->csr[0] |= 0x0200; /* set TINT */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|