Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 340e01248478ba8b78a6d4d1809b1eff > files > 135

kvm-83-270.el5_11.src.rpm

From de61985994637ce4c16ad5df3ab12d5c62265793 Mon Sep 17 00:00:00 2001
From: Eduardo Habkost <ehabkost@redhat.com>
Date: Mon, 21 Sep 2009 14:25:15 -0300
Subject: [PATCH 2/2] Fix for Bug 510706: qemu-kvm segfault when using i82551 vnic
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit

RH-Author: Naphtali Sprei <nsprei@redhat.com>
Message-id: <4AAD16FD.2070404@redhat.com>
Patchwork-id: 3399
O-Subject: [PATCH] Fix for Bug 510706: qemu-kvm segfault when using i82551 vnic
Bugzilla: 510706
RH-Acked-by: Juan Quintela <quintela@redhat.com>
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>

Changes are mainly commit 24e6f3551f3c8ea7cc7524a3e64e84beca59618f
by Reimar Döffinger <Reimar.Doeffinger@gmx.de> on qemu upstream.

Allocate big enough buffer, and limit copy size.
Also use extended TBD only where applicable.

Signed-off-by: Naphtali Sprei <nsprei@redhat.com>
---
 qemu/hw/eepro100.c |   17 +++++++++++++----
 1 files changed, 13 insertions(+), 4 deletions(-)

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 qemu/hw/eepro100.c |   17 +++++++++++++----
 1 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/qemu/hw/eepro100.c b/qemu/hw/eepro100.c
index ae2b411..4860aab 100644
--- a/qemu/hw/eepro100.c
+++ b/qemu/hw/eepro100.c
@@ -601,6 +601,11 @@ static uint16_t eepro100_read_command(EEPRO100State * s)
 }
 #endif
 
+static bool device_supports_eTxCB(EEPRO100State * s)
+{
+    return (s->device != i82557B && s->device != i82557C);
+}
+
 /* Commands that can be put in a command list entry. */
 enum commands {
     CmdNOp = 0,
@@ -720,7 +725,8 @@ static void eepro100_cu_command(EEPRO100State * s, uint8_t val)
                 logout
                     ("illegal values of TBD array address and TCB byte count!\n");
             }
-            uint8_t buf[MAX_ETH_FRAME_SIZE + 4];
+            // sends larger than MAX_ETH_FRAME_SIZE are allowed, up to 2600 bytes
+            uint8_t buf[2600];
             uint16_t size = 0;
             uint32_t tbd_address = cb_address + 0x10;
             assert(tcb_bytes <= sizeof(buf));
@@ -732,6 +738,7 @@ static void eepro100_cu_command(EEPRO100State * s, uint8_t val)
                 logout
                     ("TBD (simplified mode): buffer address 0x%08x, size 0x%04x\n",
                      tx_buffer_address, tx_buffer_size);
+                tx_buffer_size = MIN(tx_buffer_size, sizeof(buf) - size);
                 cpu_physical_memory_read(tx_buffer_address, &buf[size],
                                          tx_buffer_size);
                 size += tx_buffer_size;
@@ -741,8 +748,8 @@ static void eepro100_cu_command(EEPRO100State * s, uint8_t val)
             } else {
                 /* Flexible mode. */
                 uint8_t tbd_count = 0;
-                if (!(s->configuration[6] & BIT(4))) {
-                    /* Extended TCB. */
+                if (device_supports_eTxCB(s) && !(s->configuration[6] & BIT(4))) {
+                    /* Extended Flexible TCB. */
                     assert(tcb_bytes == 0);
                     for (; tbd_count < 2; tbd_count++) {
                         uint32_t tx_buffer_address = ldl_phys(tbd_address);
@@ -750,8 +757,9 @@ static void eepro100_cu_command(EEPRO100State * s, uint8_t val)
                         uint16_t tx_buffer_el = lduw_phys(tbd_address + 6);
                         tbd_address += 8;
                         logout
-                            ("TBD (extended mode): buffer address 0x%08x, size 0x%04x\n",
+                            ("TBD (extended flexible mode): buffer address 0x%08x, size 0x%04x\n",
                              tx_buffer_address, tx_buffer_size);
+                        tx_buffer_size = MIN(tx_buffer_size, sizeof(buf) - size);
                         cpu_physical_memory_read(tx_buffer_address, &buf[size],
                                                  tx_buffer_size);
                         size += tx_buffer_size;
@@ -769,6 +777,7 @@ static void eepro100_cu_command(EEPRO100State * s, uint8_t val)
                     logout
                         ("TBD (flexible mode): buffer address 0x%08x, size 0x%04x\n",
                          tx_buffer_address, tx_buffer_size);
+                    tx_buffer_size = MIN(tx_buffer_size, sizeof(buf) - size);
                     cpu_physical_memory_read(tx_buffer_address, &buf[size],
                                              tx_buffer_size);
                     size += tx_buffer_size;
-- 
1.6.3.rc4.29.g8146