summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael LeBeane <michael.lebeane@amd.com>2016-11-29 13:04:45 -0500
committerMichael LeBeane <michael.lebeane@amd.com>2016-11-29 13:04:45 -0500
commitcd4b26b6ae984a75e16f4d71152d99b6c063d366 (patch)
tree33248f61326415ea11ff30dce527ed8fa5121231 /src
parent4b7bc5b1e1915915a746af16d36de1d006db8700 (diff)
downloadgem5-cd4b26b6ae984a75e16f4d71152d99b6c063d366.tar.xz
dev: Fix buffer length when unserializing an eth pkt
Changeset 11701 only serialized the useful portion of of an ethernet packets' payload. However, the device models expect each ethernet packet to contain a 16KB buffer, even if there is no data in it. This patch adds a 'bufLength' field to EthPacketData so the original size of the packet buffer can always be unserialized. Reported-by: Gabor Dozsa <Gabor.Dozsa@arm.com>
Diffstat (limited to 'src')
-rw-r--r--src/dev/net/etherpkt.cc21
-rw-r--r--src/dev/net/etherpkt.hh9
-rw-r--r--src/dev/net/i8254xGBe.cc2
-rw-r--r--src/dev/net/ns_gige.cc2
-rw-r--r--src/dev/net/sinic.cc2
5 files changed, 27 insertions, 9 deletions
diff --git a/src/dev/net/etherpkt.cc b/src/dev/net/etherpkt.cc
index 446e44e46..22c0156d0 100644
--- a/src/dev/net/etherpkt.cc
+++ b/src/dev/net/etherpkt.cc
@@ -42,6 +42,7 @@ void
EthPacketData::serialize(const string &base, CheckpointOut &cp) const
{
paramOut(cp, base + ".simLength", simLength);
+ paramOut(cp, base + ".bufLength", bufLength);
paramOut(cp, base + ".length", length);
arrayParamOut(cp, base + ".data", data, length);
}
@@ -50,11 +51,23 @@ void
EthPacketData::unserialize(const string &base, CheckpointIn &cp)
{
paramIn(cp, base + ".length", length);
- if (length) {
- assert(data == nullptr);
- data = new uint8_t[length];
- arrayParamIn(cp, base + ".data", data, length);
+ unsigned chkpt_buf_length;
+ if (optParamIn(cp, base + ".bufLength", chkpt_buf_length)) {
+ // If bufLength is in the checkpoint, make sure that the current buffer
+ // is unallocated or that the checkpoint requested size is smaller than
+ // the current buffer.
+ assert(!data || chkpt_buf_length <= bufLength);
+ bufLength = chkpt_buf_length;
+ } else {
+ // If bufLength is not in the checkpoint, try to use the existing
+ // buffer or use length to size the buffer
+ if (!data)
+ bufLength = length;
}
+ assert(length <= bufLength);
+ if (!data)
+ data = new uint8_t[bufLength];
+ arrayParamIn(cp, base + ".data", data, length);
if (!optParamIn(cp, base + ".simLength", simLength))
simLength = length;
}
diff --git a/src/dev/net/etherpkt.hh b/src/dev/net/etherpkt.hh
index f84c03a4c..a9cc79b80 100644
--- a/src/dev/net/etherpkt.hh
+++ b/src/dev/net/etherpkt.hh
@@ -55,6 +55,11 @@ class EthPacketData
uint8_t *data;
/**
+ * Total size of the allocated data buffer.
+ */
+ unsigned bufLength;
+
+ /**
* Amount of space occupied by the payload in the data buffer
*/
unsigned length;
@@ -69,11 +74,11 @@ class EthPacketData
unsigned simLength;
EthPacketData()
- : data(nullptr), length(0), simLength(0)
+ : data(nullptr), bufLength(0), length(0), simLength(0)
{ }
explicit EthPacketData(unsigned size)
- : data(new uint8_t[size]), length(0), simLength(0)
+ : data(new uint8_t[size]), bufLength(size), length(0), simLength(0)
{ }
~EthPacketData() { if (data) delete [] data; }
diff --git a/src/dev/net/i8254xGBe.cc b/src/dev/net/i8254xGBe.cc
index 11f017a21..baca0138f 100644
--- a/src/dev/net/i8254xGBe.cc
+++ b/src/dev/net/i8254xGBe.cc
@@ -2522,7 +2522,7 @@ IGbE::unserialize(CheckpointIn &cp)
bool txPktExists;
UNSERIALIZE_SCALAR(txPktExists);
if (txPktExists) {
- txPacket = std::make_shared<EthPacketData>();
+ txPacket = std::make_shared<EthPacketData>(16384);
txPacket->unserialize("txpacket", cp);
}
diff --git a/src/dev/net/ns_gige.cc b/src/dev/net/ns_gige.cc
index 91a0da7a9..50bb6ed17 100644
--- a/src/dev/net/ns_gige.cc
+++ b/src/dev/net/ns_gige.cc
@@ -2352,7 +2352,7 @@ NSGigE::unserialize(CheckpointIn &cp)
bool txPacketExists;
UNSERIALIZE_SCALAR(txPacketExists);
if (txPacketExists) {
- txPacket = make_shared<EthPacketData>();
+ txPacket = make_shared<EthPacketData>(16384);
txPacket->unserialize("txPacket", cp);
uint32_t txPktBufPtr;
UNSERIALIZE_SCALAR(txPktBufPtr);
diff --git a/src/dev/net/sinic.cc b/src/dev/net/sinic.cc
index de8d4e98a..e86e1abe2 100644
--- a/src/dev/net/sinic.cc
+++ b/src/dev/net/sinic.cc
@@ -1496,7 +1496,7 @@ Device::unserialize(CheckpointIn &cp)
UNSERIALIZE_SCALAR(txPacketExists);
txPacket = 0;
if (txPacketExists) {
- txPacket = make_shared<EthPacketData>();
+ txPacket = make_shared<EthPacketData>(16384);
txPacket->unserialize("txPacket", cp);
UNSERIALIZE_SCALAR(txPacketOffset);
UNSERIALIZE_SCALAR(txPacketBytes);