ia64/xen-unstable

changeset 6608:b715a9f4dba0

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@watson.ibm.com>
author kaf24@firebug.cl.cam.ac.uk
date Fri Sep 02 17:52:37 2005 +0000 (2005-09-02)
parents ec11c5cca195
children 151da8f5d5f2
files tools/ioemu/hw/pcnet.c
line diff
     1.1 --- a/tools/ioemu/hw/pcnet.c	Fri Sep 02 17:02:08 2005 +0000
     1.2 +++ b/tools/ioemu/hw/pcnet.c	Fri Sep 02 17:52:37 2005 +0000
     1.3 @@ -569,6 +569,10 @@ static void pcnet_transmit(PCNetState *s
     1.4              cpu_physical_memory_read(PHYSADDR(s, tmd.tmd0.tbadr),
     1.5                      s->buffer + s->xmit_pos, 4096 - tmd.tmd1.bcnt);
     1.6              s->xmit_pos += 4096 - tmd.tmd1.bcnt;
     1.7 +
     1.8 +	    tmd.tmd1.own = 0;
     1.9 +	    TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s)));
    1.10 +
    1.11  #ifdef PCNET_DEBUG
    1.12              printf("pcnet_transmit size=%d\n", s->xmit_pos);
    1.13  #endif            
    1.14 @@ -580,10 +584,10 @@ static void pcnet_transmit(PCNetState *s
    1.15              s->csr[0] &= ~0x0008;   /* clear TDMD */
    1.16              s->csr[4] |= 0x0004;    /* set TXSTRT */
    1.17              s->xmit_pos = -1;
    1.18 -        }
    1.19 -
    1.20 -        tmd.tmd1.own = 0;
    1.21 -        TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s)));
    1.22 +        } else {
    1.23 +	    tmd.tmd1.own = 0;
    1.24 +	    TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s)));
    1.25 +	}
    1.26          if (!CSR_TOKINTD(s) || (CSR_LTINTEN(s) && tmd.tmd1.ltint))
    1.27              s->csr[0] |= 0x0200;    /* set TINT */
    1.28