aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--meta/recipes-devtools/qemu/qemu/smc91c111_fix.patch77
-rw-r--r--meta/recipes-devtools/qemu/qemu_2.4.0.bb1
2 files changed, 78 insertions, 0 deletions
diff --git a/meta/recipes-devtools/qemu/qemu/smc91c111_fix.patch b/meta/recipes-devtools/qemu/qemu/smc91c111_fix.patch
new file mode 100644
index 0000000000..e69af94476
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/smc91c111_fix.patch
@@ -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];
diff --git a/meta/recipes-devtools/qemu/qemu_2.4.0.bb b/meta/recipes-devtools/qemu/qemu_2.4.0.bb
index 5e5f786b10..d545b60f64 100644
--- a/meta/recipes-devtools/qemu/qemu_2.4.0.bb
+++ b/meta/recipes-devtools/qemu/qemu_2.4.0.bb
@@ -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"