ruby: fixes functional writes to RubyRequest
The functional write code was assuming that all writes are block sized, which may not be true for Ruby Requests. This bug can lead to a buffer overflow. Committed by: Nilay Vaish <nilay@cs.wisc.edu>
This commit is contained in:
parent
a4e8512afa
commit
af8eb67fb4
2 changed files with 17 additions and 13 deletions
|
@ -39,19 +39,19 @@ RubyRequest::functionalWrite(Packet *pkt)
|
||||||
// has to overwrite the data for the timing request, even if the
|
// has to overwrite the data for the timing request, even if the
|
||||||
// timing request has still not been ordered globally.
|
// timing request has still not been ordered globally.
|
||||||
|
|
||||||
Address pktLineAddr(pkt->getAddr());
|
Addr wBase = pkt->getAddr();
|
||||||
pktLineAddr.makeLineAddress();
|
Addr wTail = wBase + pkt->getSize();
|
||||||
|
Addr mBase = m_PhysicalAddress.getAddress();
|
||||||
|
Addr mTail = mBase + m_Size;
|
||||||
|
|
||||||
if (pktLineAddr == m_LineAddress) {
|
|
||||||
uint8_t * pktData = pkt->getPtr<uint8_t>(true);
|
uint8_t * pktData = pkt->getPtr<uint8_t>(true);
|
||||||
unsigned int size_in_bytes = pkt->getSize();
|
|
||||||
unsigned startByte = pkt->getAddr() - m_LineAddress.getAddress();
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < size_in_bytes; ++i) {
|
Addr cBase = std::max(wBase, mBase);
|
||||||
data[i + startByte] = pktData[i];
|
Addr cTail = std::min(wTail, mTail);
|
||||||
|
|
||||||
|
for (Addr i = cBase; i < cTail; ++i) {
|
||||||
|
data[i - mBase] = pktData[i - wBase];
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return cBase < cTail;
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -536,13 +536,18 @@ RubySystem::functionalWrite(PacketPtr pkt)
|
||||||
unsigned int size_in_bytes = pkt->getSize();
|
unsigned int size_in_bytes = pkt->getSize();
|
||||||
unsigned startByte = addr.getAddress() - line_addr.getAddress();
|
unsigned startByte = addr.getAddress() - line_addr.getAddress();
|
||||||
|
|
||||||
|
uint32_t M5_VAR_USED num_functional_writes = 0;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < num_controllers;++i) {
|
for (unsigned int i = 0; i < num_controllers;++i) {
|
||||||
|
num_functional_writes +=
|
||||||
m_abs_cntrl_vec[i]->functionalWriteBuffers(pkt);
|
m_abs_cntrl_vec[i]->functionalWriteBuffers(pkt);
|
||||||
|
|
||||||
access_perm = m_abs_cntrl_vec[i]->getAccessPermission(line_addr);
|
access_perm = m_abs_cntrl_vec[i]->getAccessPermission(line_addr);
|
||||||
if (access_perm != AccessPermission_Invalid &&
|
if (access_perm != AccessPermission_Invalid &&
|
||||||
access_perm != AccessPermission_NotPresent) {
|
access_perm != AccessPermission_NotPresent) {
|
||||||
|
|
||||||
|
num_functional_writes++;
|
||||||
|
|
||||||
DataBlock& block = m_abs_cntrl_vec[i]->getDataBlock(line_addr);
|
DataBlock& block = m_abs_cntrl_vec[i]->getDataBlock(line_addr);
|
||||||
DPRINTF(RubySystem, "%s\n",block);
|
DPRINTF(RubySystem, "%s\n",block);
|
||||||
for (unsigned j = 0; j < size_in_bytes; ++j) {
|
for (unsigned j = 0; j < size_in_bytes; ++j) {
|
||||||
|
@ -552,7 +557,6 @@ RubySystem::functionalWrite(PacketPtr pkt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t M5_VAR_USED num_functional_writes = 0;
|
|
||||||
for (unsigned int i = 0; i < m_memory_controller_vec.size() ;++i) {
|
for (unsigned int i = 0; i < m_memory_controller_vec.size() ;++i) {
|
||||||
num_functional_writes +=
|
num_functional_writes +=
|
||||||
m_memory_controller_vec[i]->functionalWriteBuffers(pkt);
|
m_memory_controller_vec[i]->functionalWriteBuffers(pkt);
|
||||||
|
|
Loading…
Reference in a new issue