diff options
author | Joel Hestness <jthestness@gmail.com> | 2015-09-29 09:28:26 -0500 |
---|---|---|
committer | Joel Hestness <jthestness@gmail.com> | 2015-09-29 09:28:26 -0500 |
commit | c05d268cfabbe26d032d73abcea6dc921c49e549 (patch) | |
tree | 9a868b284e3e7e1a45dfdb6d31338e0139fa048e | |
parent | 0ecaab4ea8039f707a95f5e3efcc68591dbcd407 (diff) | |
download | gem5-c05d268cfabbe26d032d73abcea6dc921c49e549.tar.xz |
ruby: Fix CacheMemory allocate leak
If a cache entry permission was previously set to NotPresent, but the entry was
not deleted, a following cache allocation can cause the entry to be leaked by
setting the entry pointer to a newly allocated entry. To eliminate this
possibility, check if the new entry is different from the old one, and if so,
delete the old one.
-rw-r--r-- | src/mem/ruby/structures/CacheMemory.cc | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/src/mem/ruby/structures/CacheMemory.cc b/src/mem/ruby/structures/CacheMemory.cc index b0e54ec99..6e4022ea6 100644 --- a/src/mem/ruby/structures/CacheMemory.cc +++ b/src/mem/ruby/structures/CacheMemory.cc @@ -263,6 +263,13 @@ CacheMemory::allocate(Addr address, AbstractCacheEntry *entry, bool touch) std::vector<AbstractCacheEntry*> &set = m_cache[cacheSet]; for (int i = 0; i < m_cache_assoc; i++) { if (!set[i] || set[i]->m_Permission == AccessPermission_NotPresent) { + if (set[i] && (set[i] != entry)) { + warn_once("This protocol contains a cache entry handling bug: " + "Entries in the cache should never be NotPresent! If\n" + "this entry (%#x) is not tracked elsewhere, it will memory " + "leak here. Fix your protocol to eliminate these!", + address); + } set[i] = entry; // Init entry set[i]->m_Address = address; set[i]->m_Permission = AccessPermission_Invalid; |