From dd6595bf565b95fbb74e7d438030f48392becc20 Mon Sep 17 00:00:00 2001 From: Sascha Bischoff Date: Wed, 3 Aug 2022 17:11:30 +0100 Subject: [PATCH] mem-cache: masked writes are not whole-line writes We now explicitly check in both the cache and the MSHRs if writes are masked or not before promoting to a whole-line write. Failure to do this previously was resulting in data loss when dirty data was present in lower level caches and a coincidentally aligned and cache-line-sized masked write occured. Change-Id: I9434590d8b22e4d993167d789eb9d15a2e866bf1 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/64340 Maintainer: Jason Lowe-Power Reviewed-by: Jason Lowe-Power Tested-by: kokoro --- src/mem/cache/mshr.cc | 3 ++- src/mem/packet.hh | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/mem/cache/mshr.cc b/src/mem/cache/mshr.cc index 871125a17e..b7e9357029 100644 --- a/src/mem/cache/mshr.cc +++ b/src/mem/cache/mshr.cc @@ -140,6 +140,7 @@ MSHR::TargetList::updateWriteFlags(PacketPtr pkt) Request::MEM_SWAP_COND | Request::SECURE | Request::LOCKED_RMW; const auto &req_flags = pkt->req->getFlags(); bool compat_write = !req_flags.isSet(no_merge_flags); + bool masked_write = pkt->isMaskedWrite(); // if this is the first write, it might be a whole // line write and even if we can't merge any @@ -147,7 +148,7 @@ MSHR::TargetList::updateWriteFlags(PacketPtr pkt) // it as a whole line write (e.g., SECURE whole line // write) bool first_write = empty(); - if (first_write || compat_write) { + if (!masked_write && (first_write || compat_write)) { auto offset = pkt->getOffset(blkSize); auto begin = writesBitmap.begin() + offset; std::fill(begin, begin + pkt->getSize(), true); diff --git a/src/mem/packet.hh b/src/mem/packet.hh index a80b918798..9d720fb9a0 100644 --- a/src/mem/packet.hh +++ b/src/mem/packet.hh @@ -625,7 +625,8 @@ class Packet : public Printable bool isWholeLineWrite(unsigned blk_size) { return (cmd == MemCmd::WriteReq || cmd == MemCmd::WriteLineReq) && - getOffset(blk_size) == 0 && getSize() == blk_size; + getOffset(blk_size) == 0 && getSize() == blk_size && + !isMaskedWrite(); } //@{