qemu: Add fixes for smc91c11 qemu segfaults on arm

The smc91c111.c driver appears to have several issues. The can_receive()
function can return that the driver is ready when rx_fifo has not been
freed yet. There is also no sanity check of rx_fifo() in _receive() which
can lead to corruption of the rx_fifo array.

release_packet() can also call qemu_flush_queued_packets() before rx_fifo
has been cleaned up, resulting in cases where packets are submitted
for which there is not yet any space.

This patch therefore:

* fixes the logic in can_receive()
* adds logic to receive() as a sanity check
* moves the flush() calls to the correct places where data is ready
  to be received

Its currently undergoing discussion upstream about exactly which pieces
are the correct fix but for now, this stops the segfaults OE is seeing
which has to be an improvement.

[YOCTO #8234]

(From OE-Core rev: 414a5256d6f00d5682ce226ee4bc49674ee6c614)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Richard Purdie
2015-09-07 15:35:49 +01:00
parent ee428e27fe
commit fa2f7f9964
2 changed files with 78 additions and 0 deletions

View File

@@ -0,0 +1,77 @@
The smc91c111.c driver appears to have several issues. The can_receive()
function can return that the driver is ready when rx_fifo has not been
freed yet. There is also no sanity check of rx_fifo() in _receive() which
can lead to corruption of the rx_fifo array.
release_packet() can also call qemu_flush_queued_packets() before rx_fifo
has been cleaned up, resulting in cases where packets are submitted
for which there is not yet any space.
This patch therefore:
* fixes the logic in can_receive()
* adds logic to receive() as a sanity check
* moves the flush() calls to the correct places where data is ready
to be received
Upstream-Status: Pending [discussion in progress on mailing list]
RP 2015/9/7
Index: qemu-2.4.0/hw/net/smc91c111.c
===================================================================
--- qemu-2.4.0.orig/hw/net/smc91c111.c
+++ qemu-2.4.0/hw/net/smc91c111.c
@@ -185,7 +185,6 @@ static void smc91c111_release_packet(smc
s->allocated &= ~(1 << packet);
if (s->tx_alloc == 0x80)
smc91c111_tx_alloc(s);
- qemu_flush_queued_packets(qemu_get_queue(s->nic));
}
/* Flush the TX FIFO. */
@@ -237,9 +236,11 @@ static void smc91c111_do_tx(smc91c111_st
}
}
#endif
- if (s->ctr & CTR_AUTO_RELEASE)
+ if (s->ctr & CTR_AUTO_RELEASE) {
/* Race? */
smc91c111_release_packet(s, packetnum);
+ qemu_flush_queued_packets(qemu_get_queue(s->nic));
+ }
else if (s->tx_fifo_done_len < NUM_PACKETS)
s->tx_fifo_done[s->tx_fifo_done_len++] = packetnum;
qemu_send_packet(qemu_get_queue(s->nic), p, len);
@@ -379,9 +380,11 @@ static void smc91c111_writeb(void *opaqu
smc91c111_release_packet(s, s->rx_fifo[0]);
}
smc91c111_pop_rx_fifo(s);
+ qemu_flush_queued_packets(qemu_get_queue(s->nic));
break;
case 5: /* Release. */
smc91c111_release_packet(s, s->packet_num);
+ qemu_flush_queued_packets(qemu_get_queue(s->nic));
break;
case 6: /* Add to TX FIFO. */
smc91c111_queue_tx(s, s->packet_num);
@@ -642,7 +642,7 @@ static int smc91c111_can_receive(NetClie
if ((s->rcr & RCR_RXEN) == 0 || (s->rcr & RCR_SOFT_RST))
return 1;
- if (s->allocated == (1 << NUM_PACKETS) - 1)
+ if ((s->allocated == (1 << NUM_PACKETS) - 1) || (s->rx_fifo_len == NUM_PACKETS))
return 0;
return 1;
}
@@ -671,9 +671,11 @@ static ssize_t smc91c111_receive(NetClie
/* TODO: Flag overrun and receive errors. */
if (packetsize > 2048)
return -1;
+ if (s->rx_fifo_len == NUM_PACKETS)
+ return -1;
packetnum = smc91c111_allocate_packet(s);
if (packetnum == 0x80)
return -1;
s->rx_fifo[s->rx_fifo_len++] = packetnum;
p = &s->data[packetnum][0];

View File

@@ -6,6 +6,7 @@ LIC_FILES_CHKSUM = "file://COPYING;md5=441c28d2cf86e15a37fa47e15a72fbac \
SRC_URI += "file://configure-fix-Darwin-target-detection.patch \
file://qemu-enlarge-env-entry-size.patch \
file://Qemu-Arm-versatilepb-Add-memory-size-checking.patch \
file://smc91c111_fix.patch \
"
SRC_URI_prepend = "http://wiki.qemu-project.org/download/${BP}.tar.bz2"
SRC_URI[md5sum] = "186ee8194140a484a455f8e3c74589f4"