diff options
| -rw-r--r-- | meta/recipes-devtools/qemu/qemu/smc91c111_fix.patch | 77 | ||||
| -rw-r--r-- | meta/recipes-devtools/qemu/qemu_2.4.0.bb | 1 |
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 @@ | |||
| 1 | The smc91c111.c driver appears to have several issues. The can_receive() | ||
| 2 | function can return that the driver is ready when rx_fifo has not been | ||
| 3 | freed yet. There is also no sanity check of rx_fifo() in _receive() which | ||
| 4 | can lead to corruption of the rx_fifo array. | ||
| 5 | |||
| 6 | release_packet() can also call qemu_flush_queued_packets() before rx_fifo | ||
| 7 | has been cleaned up, resulting in cases where packets are submitted | ||
| 8 | for which there is not yet any space. | ||
| 9 | |||
| 10 | This 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 | |||
| 17 | Upstream-Status: Pending [discussion in progress on mailing list] | ||
| 18 | RP 2015/9/7 | ||
| 19 | |||
| 20 | Index: 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 \ | |||
| 6 | SRC_URI += "file://configure-fix-Darwin-target-detection.patch \ | 6 | SRC_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 | " |
| 10 | SRC_URI_prepend = "http://wiki.qemu-project.org/download/${BP}.tar.bz2" | 11 | SRC_URI_prepend = "http://wiki.qemu-project.org/download/${BP}.tar.bz2" |
| 11 | SRC_URI[md5sum] = "186ee8194140a484a455f8e3c74589f4" | 12 | SRC_URI[md5sum] = "186ee8194140a484a455f8e3c74589f4" |
