summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Purdie <richard.purdie@linuxfoundation.org>2015-09-07 15:35:49 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2015-09-09 14:27:44 +0100
commitfa2f7f996457cb1c506be5584178db250a3b1a2c (patch)
tree7fecad49c78f18ee14360b4348e065336adbc763
parentee428e27fed0da8651184cf3ac4a0dd39c4e9d9d (diff)
downloadpoky-fa2f7f996457cb1c506be5584178db250a3b1a2c.tar.gz
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>
-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 @@
1The smc91c111.c driver appears to have several issues. The can_receive()
2function can return that the driver is ready when rx_fifo has not been
3freed yet. There is also no sanity check of rx_fifo() in _receive() which
4can lead to corruption of the rx_fifo array.
5
6release_packet() can also call qemu_flush_queued_packets() before rx_fifo
7has been cleaned up, resulting in cases where packets are submitted
8for which there is not yet any space.
9
10This patch therefore:
11
12* fixes the logic in can_receive()
13* adds logic to receive() as a sanity check
14* moves the flush() calls to the correct places where data is ready
15 to be received
16
17Upstream-Status: Pending [discussion in progress on mailing list]
18RP 2015/9/7
19
20Index: qemu-2.4.0/hw/net/smc91c111.c
21===================================================================
22--- qemu-2.4.0.orig/hw/net/smc91c111.c
23+++ qemu-2.4.0/hw/net/smc91c111.c
24@@ -185,7 +185,6 @@ static void smc91c111_release_packet(smc
25 s->allocated &= ~(1 << packet);
26 if (s->tx_alloc == 0x80)
27 smc91c111_tx_alloc(s);
28- qemu_flush_queued_packets(qemu_get_queue(s->nic));
29 }
30
31 /* Flush the TX FIFO. */
32@@ -237,9 +236,11 @@ static void smc91c111_do_tx(smc91c111_st
33 }
34 }
35 #endif
36- if (s->ctr & CTR_AUTO_RELEASE)
37+ if (s->ctr & CTR_AUTO_RELEASE) {
38 /* Race? */
39 smc91c111_release_packet(s, packetnum);
40+ qemu_flush_queued_packets(qemu_get_queue(s->nic));
41+ }
42 else if (s->tx_fifo_done_len < NUM_PACKETS)
43 s->tx_fifo_done[s->tx_fifo_done_len++] = packetnum;
44 qemu_send_packet(qemu_get_queue(s->nic), p, len);
45@@ -379,9 +380,11 @@ static void smc91c111_writeb(void *opaqu
46 smc91c111_release_packet(s, s->rx_fifo[0]);
47 }
48 smc91c111_pop_rx_fifo(s);
49+ qemu_flush_queued_packets(qemu_get_queue(s->nic));
50 break;
51 case 5: /* Release. */
52 smc91c111_release_packet(s, s->packet_num);
53+ qemu_flush_queued_packets(qemu_get_queue(s->nic));
54 break;
55 case 6: /* Add to TX FIFO. */
56 smc91c111_queue_tx(s, s->packet_num);
57@@ -642,7 +642,7 @@ static int smc91c111_can_receive(NetClie
58
59 if ((s->rcr & RCR_RXEN) == 0 || (s->rcr & RCR_SOFT_RST))
60 return 1;
61- if (s->allocated == (1 << NUM_PACKETS) - 1)
62+ if ((s->allocated == (1 << NUM_PACKETS) - 1) || (s->rx_fifo_len == NUM_PACKETS))
63 return 0;
64 return 1;
65 }
66@@ -671,9 +671,11 @@ static ssize_t smc91c111_receive(NetClie
67 /* TODO: Flag overrun and receive errors. */
68 if (packetsize > 2048)
69 return -1;
70+ if (s->rx_fifo_len == NUM_PACKETS)
71+ return -1;
72 packetnum = smc91c111_allocate_packet(s);
73 if (packetnum == 0x80)
74 return -1;
75 s->rx_fifo[s->rx_fifo_len++] = packetnum;
76
77 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 \
6SRC_URI += "file://configure-fix-Darwin-target-detection.patch \ 6SRC_URI += "file://configure-fix-Darwin-target-detection.patch \
7 file://qemu-enlarge-env-entry-size.patch \ 7 file://qemu-enlarge-env-entry-size.patch \
8 file://Qemu-Arm-versatilepb-Add-memory-size-checking.patch \ 8 file://Qemu-Arm-versatilepb-Add-memory-size-checking.patch \
9 file://smc91c111_fix.patch \
9 " 10 "
10SRC_URI_prepend = "http://wiki.qemu-project.org/download/${BP}.tar.bz2" 11SRC_URI_prepend = "http://wiki.qemu-project.org/download/${BP}.tar.bz2"
11SRC_URI[md5sum] = "186ee8194140a484a455f8e3c74589f4" 12SRC_URI[md5sum] = "186ee8194140a484a455f8e3c74589f4"