diff options
author | Blake Hechtman ext:(%2C%20Nilay%20Vaish%20%3Cnilay%40cs.wisc.edu%3E) <bah13@duke.edu> | 2013-03-02 23:12:55 -0600 |
---|---|---|
committer | Blake Hechtman ext:(%2C%20Nilay%20Vaish%20%3Cnilay%40cs.wisc.edu%3E) <bah13@duke.edu> | 2013-03-02 23:12:55 -0600 |
commit | af8eb67fb44f7ab1831d6651ea4a079f2ebc99ff (patch) | |
tree | be47b181058c782c9bfc654aac034b2f243fcb6d /src | |
parent | a4e8512afa8fa5b09ee9f34ba256254eb012d628 (diff) | |
download | gem5-af8eb67fb44f7ab1831d6651ea4a079f2ebc99ff.tar.xz |
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>
Diffstat (limited to 'src')
-rw-r--r-- | src/mem/ruby/slicc_interface/RubyRequest.cc | 22 | ||||
-rw-r--r-- | src/mem/ruby/system/System.cc | 8 |
2 files changed, 17 insertions, 13 deletions
diff --git a/src/mem/ruby/slicc_interface/RubyRequest.cc b/src/mem/ruby/slicc_interface/RubyRequest.cc index 7ff2b75d8..ca0ab059f 100644 --- a/src/mem/ruby/slicc_interface/RubyRequest.cc +++ b/src/mem/ruby/slicc_interface/RubyRequest.cc @@ -39,19 +39,19 @@ RubyRequest::functionalWrite(Packet *pkt) // has to overwrite the data for the timing request, even if the // timing request has still not been ordered globally. - Address pktLineAddr(pkt->getAddr()); - pktLineAddr.makeLineAddress(); + Addr wBase = pkt->getAddr(); + 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); - unsigned int size_in_bytes = pkt->getSize(); - unsigned startByte = pkt->getAddr() - m_LineAddress.getAddress(); + uint8_t * pktData = pkt->getPtr<uint8_t>(true); - for (unsigned i = 0; i < size_in_bytes; ++i) { - data[i + startByte] = pktData[i]; - } + Addr cBase = std::max(wBase, mBase); + Addr cTail = std::min(wTail, mTail); - return true; + for (Addr i = cBase; i < cTail; ++i) { + data[i - mBase] = pktData[i - wBase]; } - return false; + + return cBase < cTail; } diff --git a/src/mem/ruby/system/System.cc b/src/mem/ruby/system/System.cc index f1a6a91b8..0e52df2ec 100644 --- a/src/mem/ruby/system/System.cc +++ b/src/mem/ruby/system/System.cc @@ -536,13 +536,18 @@ RubySystem::functionalWrite(PacketPtr pkt) unsigned int size_in_bytes = pkt->getSize(); 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) { - m_abs_cntrl_vec[i]->functionalWriteBuffers(pkt); + num_functional_writes += + m_abs_cntrl_vec[i]->functionalWriteBuffers(pkt); access_perm = m_abs_cntrl_vec[i]->getAccessPermission(line_addr); if (access_perm != AccessPermission_Invalid && access_perm != AccessPermission_NotPresent) { + num_functional_writes++; + DataBlock& block = m_abs_cntrl_vec[i]->getDataBlock(line_addr); DPRINTF(RubySystem, "%s\n",block); 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) { num_functional_writes += m_memory_controller_vec[i]->functionalWriteBuffers(pkt); |