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>
This commit is contained in:
Michael LeBeane 2016-11-29 13:04:45 -05:00
parent 4b7bc5b1e1
commit cd4b26b6ae
5 changed files with 27 additions and 9 deletions

View file

@ -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;
}

View file

@ -54,6 +54,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
*/
@ -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; }

View file

@ -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);
}

View file

@ -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);

View file

@ -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);